Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensured all calls to the service are properly configured. #1226

Open
wants to merge 2 commits into
base: 2.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
package org.restlet.ext.odata;

import static org.restlet.ext.odata.internal.edm.TypeUtils.dateTimeFormats;
import static org.restlet.ext.odata.internal.edm.TypeUtils.decimalFormat;
import static org.restlet.ext.odata.internal.edm.TypeUtils.doubleFormat;
import static org.restlet.ext.odata.internal.edm.TypeUtils.singleFormat;
import static org.restlet.ext.odata.internal.edm.TypeUtils.timeFormat;
import static org.restlet.ext.odata.internal.edm.TypeUtils.toEdmBinary;
import static org.restlet.ext.odata.internal.edm.TypeUtils.toEdmBoolean;
import static org.restlet.ext.odata.internal.edm.TypeUtils.toEdmByte;
import static org.restlet.ext.odata.internal.edm.TypeUtils.toEdmDateTime;
import static org.restlet.ext.odata.internal.edm.TypeUtils.toEdmDecimal;
import static org.restlet.ext.odata.internal.edm.TypeUtils.toEdmDouble;
import static org.restlet.ext.odata.internal.edm.TypeUtils.toEdmInt16;
import static org.restlet.ext.odata.internal.edm.TypeUtils.toEdmInt32;
import static org.restlet.ext.odata.internal.edm.TypeUtils.toEdmInt64;
import static org.restlet.ext.odata.internal.edm.TypeUtils.toEdmSingle;
import static org.restlet.ext.odata.internal.edm.TypeUtils.toEdmTime;

import java.util.Date;

import org.restlet.Context;
import org.restlet.engine.util.Base64;
import org.restlet.engine.util.DateUtils;
import org.restlet.ext.odata.internal.edm.Type;

/**
* Util class used to convert values to and from Edm types.<br>
* Can be overriden to extends basic behaviour.
*/
public class EdmConverter {

/**
* Converts the String representation of the target WCF type to its
* corresponding value.
*
* @param value
* The value to convert.
* @param adoNetType
* The target WCF type.
* @return The converted value.
*/
public Object fromEdm(String value, String adoNetType) {
if (value == null) {
return null;
}

Object result = null;
try {
if (adoNetType.endsWith("Binary")) {
result = Base64.decode(value);
} else if (adoNetType.endsWith("Boolean")) {
result = Boolean.valueOf(value);
} else if (adoNetType.endsWith("DateTime")) {
result = DateUtils.parse(value, dateTimeFormats);
} else if (adoNetType.endsWith("DateTimeOffset")) {
result = DateUtils.parse(value, dateTimeFormats);
} else if (adoNetType.endsWith("Time")) {
result = timeFormat.parseObject(value);
} else if (adoNetType.endsWith("Decimal")) {
result = decimalFormat.parseObject(value);
} else if (adoNetType.endsWith("Single")) {
result = singleFormat.parseObject(value);
} else if (adoNetType.endsWith("Double")) {
result = doubleFormat.parseObject(value);
} else if (adoNetType.endsWith("Guid")) {
result = value;
} else if (adoNetType.endsWith("Int16")) {
result = Short.valueOf(value);
} else if (adoNetType.endsWith("Int32")) {
result = Integer.valueOf(value);
} else if (adoNetType.endsWith("Int64")) {
result = Long.valueOf(value);
} else if (adoNetType.endsWith("Byte")) {
result = Byte.valueOf(value);
} else if (adoNetType.endsWith("String")) {
result = value;
}
} catch (Exception e) {
Context.getCurrentLogger().warning(
"Cannot convert " + value + " from this EDM type "
+ adoNetType);
}

return result;
}

/**
* Returns the literal form of the given value.
*
* @param value
* The value to convert.
* @param adoNetType
* The type of the value.
* @return The literal form of the given value.
* @see <a href="http://www.odata.org/docs/%5BMC-APDSU%5D.htm#z61934eae311a4af4b8f882c112248651">Abstract Type
* System</a>
*/
public String getLiteralForm(String value, String adoNetType) {
if (value == null) {
return null;
}

String result = null;
try {
if (adoNetType.endsWith("Binary")) {
result = "'" + value + "'";
} else if (adoNetType.endsWith("DateTime")) {
result = "datetime'" + value + "'";
} else if (adoNetType.endsWith("DateTimeOffset")) {
result = "datetimeoffset'" + value + "'";
} else if (adoNetType.endsWith("Time")) {
result = "time'" + value + "'";
} else if (adoNetType.endsWith("Guid")) {
result = "guid'" + value + "'";
} else if (adoNetType.endsWith("String")) {
result = "'" + value + "'";
}
} catch (Exception e) {
Context.getCurrentLogger().warning(
"Cannot convert " + value + " from this EDM type "
+ adoNetType);
}

return result;
}

/**
* Converts a value to the String representation of the target WCF type.
*
* @param value
* The value to convert.
* @param type
* The target WCF type.
* @return The converted value.
*/
public String toEdm(Object value, Type type) {
String adoNetType = type.getName();
if (value == null || adoNetType == null) {
return null;
}

String result = null;
if (adoNetType.endsWith("Binary")) {
if ((byte[].class).isAssignableFrom(value.getClass())) {
result = toEdmBinary((byte[]) value);
}
} else if (adoNetType.endsWith("Boolean")) {
if ((Boolean.class).isAssignableFrom(value.getClass())) {
result = toEdmBoolean((Boolean) value);
}
} else if (adoNetType.endsWith("DateTime")) {
if ((Date.class).isAssignableFrom(value.getClass())) {
result = toEdmDateTime((Date) value);
}
} else if (adoNetType.endsWith("DateTimeOffset")) {
if ((Date.class).isAssignableFrom(value.getClass())) {
result = toEdmDateTime((Date) value);
}
} else if (adoNetType.endsWith("Time")) {
if ((Long.class).isAssignableFrom(value.getClass())) {
result = toEdmTime((Long) value);
}
} else if (adoNetType.endsWith("Decimal")) {
if ((Double.class).isAssignableFrom(value.getClass())) {
result = toEdmDecimal((Double) value);
}
} else if (adoNetType.endsWith("Single")) {
if ((Float.class).isAssignableFrom(value.getClass())) {
result = toEdmSingle((Float) value);
} else if ((Double.class).isAssignableFrom(value.getClass())) {
result = toEdmSingle((Double) value);
}
} else if (adoNetType.endsWith("Double")) {
if ((Double.class).isAssignableFrom(value.getClass())) {
result = toEdmDouble((Double) value);
}
} else if (adoNetType.endsWith("Guid")) {
result = value.toString();
} else if (adoNetType.endsWith("Int16")) {
if ((Short.class).isAssignableFrom(value.getClass())) {
result = toEdmInt16((Short) value);
}
} else if (adoNetType.endsWith("Int32")) {
if ((Integer.class).isAssignableFrom(value.getClass())) {
result = toEdmInt32((Integer) value);
}
} else if (adoNetType.endsWith("Int64")) {
if ((Long.class).isAssignableFrom(value.getClass())) {
result = toEdmInt64((Long) value);
}
} else if (adoNetType.endsWith("Byte")) {
if ((Byte.class).isAssignableFrom(value.getClass())) {
result = toEdmByte((Byte) value);
}
} else if (adoNetType.endsWith("String")) {
result = value.toString();
}

if (result == null) {
result = value.toString();
}

return result;
}

/**
* Converts a value to the String representation of the target WCF type when
* used a key in the URIs.
*
* @param value
* The value to convert.
* @param type
* The target WCF type.
* @return The converted value.
*/
public String toEdmKey(Object value, Type type) {
String adoNetType = type.getName();
if (value == null || adoNetType == null) {
return null;
}

String result = null;
if (adoNetType.endsWith("Binary")) {
if ((byte[].class).isAssignableFrom(value.getClass())) {
result = toEdmBinary((byte[]) value);
}
} else if (adoNetType.endsWith("Boolean")) {
if ((Boolean.class).isAssignableFrom(value.getClass())) {
result = toEdmBoolean((Boolean) value);
}
} else if (adoNetType.endsWith("DateTime")) {
if ((Date.class).isAssignableFrom(value.getClass())) {
result = toEdmDateTime((Date) value);
}
} else if (adoNetType.endsWith("DateTimeOffset")) {
if ((Date.class).isAssignableFrom(value.getClass())) {
result = toEdmDateTime((Date) value);
}
} else if (adoNetType.endsWith("Time")) {
if ((Long.class).isAssignableFrom(value.getClass())) {
result = toEdmTime((Long) value);
}
} else if (adoNetType.endsWith("Decimal")) {
if ((Double.class).isAssignableFrom(value.getClass())) {
result = toEdmDecimal((Double) value);
}
} else if (adoNetType.endsWith("Single")) {
if ((Float.class).isAssignableFrom(value.getClass())) {
result = toEdmSingle((Float) value);
} else if ((Double.class).isAssignableFrom(value.getClass())) {
result = toEdmSingle((Double) value);
}
} else if (adoNetType.endsWith("Double")) {
if ((Double.class).isAssignableFrom(value.getClass())) {
result = toEdmDouble((Double) value);
}
} else if (adoNetType.endsWith("Guid")) {
result = value.toString();
} else if (adoNetType.endsWith("Int16")) {
if ((Short.class).isAssignableFrom(value.getClass())) {
result = toEdmInt16((Short) value);
}
} else if (adoNetType.endsWith("Int32")) {
if ((Integer.class).isAssignableFrom(value.getClass())) {
result = toEdmInt32((Integer) value);
}
} else if (adoNetType.endsWith("Int64")) {
if ((Long.class).isAssignableFrom(value.getClass())) {
result = toEdmInt64((Long) value);
}
} else if (adoNetType.endsWith("Byte")) {
if ((Byte.class).isAssignableFrom(value.getClass())) {
result = toEdmByte((Byte) value);
}
} else if (adoNetType.endsWith("String")) {
result = "'" + value.toString() + "'";
}

if (result == null) {
result = value.toString();
}

return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.HashMap;
import java.util.Map;

import org.restlet.data.ChallengeResponse;
import org.restlet.data.CharacterSet;
import org.restlet.data.MediaType;
import org.restlet.data.Reference;
Expand All @@ -48,6 +49,8 @@

import freemarker.template.Configuration;

import static org.restlet.engine.util.CollectionsUtils.isNullOrEmpty;

/**
* Code generator for accessing OData services. The generator use metadata
* exposed by an online service to generate client-side artifacts facilitating
Expand All @@ -61,8 +64,7 @@ public class Generator {
* Takes two (or three) parameters:<br>
* <ol>
* <li>The URI of the OData service</li>
* <li>The output directory (optional, used the current directory by
* default)</li>
* <li>The output directory (optional, used the current directory by default)</li>
* <li>The name of the generated service class name (optional)</li>
* </ol>
*
Expand Down Expand Up @@ -164,6 +166,9 @@ public static void main(String[] args) {
/** The name of the service class (in case there is only one in the schema). */
private String serviceClassName;

/** The credentials used to request the OData service. */
private ChallengeResponse serviceCredentials;

/** The URI of the target data service. */
private Reference serviceRef;

Expand Down Expand Up @@ -231,6 +236,7 @@ public Generator(String serviceUri, String serviceClassName) {
*/
public void generate(File outputDir) throws Exception {
Service service = new Service(serviceRef);
service.setCredentials(serviceCredentials);
Metadata metadata = (Metadata) service.getMetadata();
if (metadata == null) {
throw new Exception("Can't get the metadata for this service: "
Expand All @@ -253,13 +259,9 @@ public void generate(File outputDir) throws Exception {
.getText());

for (Schema schema : metadata.getSchemas()) {
if ((schema.getEntityTypes() != null && !schema.getEntityTypes()
.isEmpty())
|| (schema.getComplexTypes() != null && !schema
.getComplexTypes().isEmpty())) {
if (!isNullOrEmpty(schema.getEntityTypes()) || !isNullOrEmpty(schema.getComplexTypes())) {
String packageName = TypeUtils.getPackageName(schema);
File packageDir = new File(outputDir, packageName.replace(".",
System.getProperty("file.separator")));
File packageDir = new File(outputDir, packageName.replace(".", System.getProperty("file.separator")));
packageDir.mkdirs();

// For each entity type
Expand All @@ -272,13 +274,11 @@ public void generate(File outputDir) throws Exception {
dataModel.put("className", className);
dataModel.put("packageName", packageName);

TemplateRepresentation templateRepresentation = new TemplateRepresentation(
entityTmpl, fmc, dataModel, MediaType.TEXT_PLAIN);
TemplateRepresentation templateRepresentation = new TemplateRepresentation(entityTmpl, fmc, dataModel, MediaType.TEXT_PLAIN);
templateRepresentation.setCharacterSet(CharacterSet.UTF_8);

// Write the template representation as a Java class
OutputStream fos = new FileOutputStream(new File(
packageDir, type.getClassName() + ".java"));
OutputStream fos = new FileOutputStream(new File(packageDir, type.getClassName() + ".java"));
templateRepresentation.write(fos);
fos.flush();
}
Expand All @@ -304,8 +304,7 @@ public void generate(File outputDir) throws Exception {
}
}
}
if (metadata.getContainers() != null
&& !metadata.getContainers().isEmpty()) {
if (!isNullOrEmpty(metadata.getContainers())) {
for (EntityContainer entityContainer : metadata.getContainers()) {
Schema schema = entityContainer.getSchema();
// Generate Service subclass
Expand Down Expand Up @@ -345,8 +344,7 @@ public void generate(File outputDir) throws Exception {
templateRepresentation.setCharacterSet(CharacterSet.UTF_8);

// Write the template representation as a Java class
OutputStream fos = new FileOutputStream(new File(outputDir,
className + ".java"));
OutputStream fos = new FileOutputStream(new File(outputDir, className + ".java"));
templateRepresentation.write(fos);
fos.flush();
}
Expand All @@ -363,4 +361,14 @@ public void generate(File outputDir) throws Exception {
public void generate(String outputDir) throws Exception {
generate(new File(outputDir));
}

/**
* Set the credentials used to request the OData service.
*
* @param serviceCredentials
* The credentials.
*/
public void setServiceCredentials(ChallengeResponse serviceCredentials) {
this.serviceCredentials = serviceCredentials;
}
}
Loading