summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabiana G. Rocha2013-07-26 09:10:41 (EDT)
committer Samuel Padgett2013-07-26 14:48:57 (EDT)
commit5028974a8b610ff23afd11df3bb04091e3081466 (patch)
tree4058965af5c7586329c28ffc540f3fd4bf7b07ba
parent2cb8007c3c14084850a562be9d6c499abf89bfb9 (diff)
downloadorg.eclipse.lyo.core-5028974a8b610ff23afd11df3bb04091e3081466.zip
org.eclipse.lyo.core-5028974a8b610ff23afd11df3bb04091e3081466.tar.gz
org.eclipse.lyo.core-5028974a8b610ff23afd11df3bb04091e3081466.tar.bz2
Bug 412789: Infer extended properties types from resource shapesrefs/changes/86/14886/5
Add system property to create the right Java type for extended property values based on what is in a resource shape. Change-Id: I5a7fc8a0bf2f9971aa1ed069c4d9334bf974145d Signed-off-by: Fabiana G. Rocha <fgrocha@br.ibm.com> Also-by: Samuel Padgett <spadgett@us.ibm.com>
-rw-r--r--org.eclipse.lyo.oslc4j.core/pom.xml5
-rw-r--r--org.eclipse.lyo.oslc4j.core/src/org/eclipse/lyo/oslc4j/core/OSLC4JConstants.java5
-rw-r--r--org.eclipse.lyo.oslc4j.core/src/org/eclipse/lyo/oslc4j/core/OSLC4JUtils.java210
-rw-r--r--org.eclipse.lyo.oslc4j.provider.jena/src/org/eclipse/lyo/oslc4j/provider/jena/JenaModelHelper.java84
-rw-r--r--org.eclipse.lyo.oslc4j.provider.json4j/src/org/eclipse/lyo/oslc4j/provider/json4j/JsonHelper.java137
5 files changed, 409 insertions, 32 deletions
diff --git a/org.eclipse.lyo.oslc4j.core/pom.xml b/org.eclipse.lyo.oslc4j.core/pom.xml
index 802ac1d..09ac291 100644
--- a/org.eclipse.lyo.oslc4j.core/pom.xml
+++ b/org.eclipse.lyo.oslc4j.core/pom.xml
@@ -26,6 +26,11 @@
<version>3.1-b33</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.jena</groupId>
+ <artifactId>jena-core</artifactId>
+ <version>2.7.1</version>
+ </dependency>
</dependencies>
<build>
<sourceDirectory>${basedir}/src/</sourceDirectory>
diff --git a/org.eclipse.lyo.oslc4j.core/src/org/eclipse/lyo/oslc4j/core/OSLC4JConstants.java b/org.eclipse.lyo.oslc4j.core/src/org/eclipse/lyo/oslc4j/core/OSLC4JConstants.java
index 62c7e00..453a422 100644
--- a/org.eclipse.lyo.oslc4j.core/src/org/eclipse/lyo/oslc4j/core/OSLC4JConstants.java
+++ b/org.eclipse.lyo.oslc4j.core/src/org/eclipse/lyo/oslc4j/core/OSLC4JConstants.java
@@ -24,11 +24,10 @@ public interface OSLC4JConstants {
public static final String OSLC4J_PUBLIC_URI = "org.eclipse.lyo.oslc4j.publicURI";
public static final String OSLC4J_DISABLE_HOST_RESOLUTION = "org.eclipse.lyo.oslc4j.disableHostResolution";
public static final String OSLC4J_DISABLE_RELATIVE_URIS = "org.eclipse.lyo.oslc4j.disableRelativeURIs";
-
public static final String OSLC4J_USE_BEAN_CLASS_FOR_PARSING = "org.eclipse.lyo.oslc4j.useBeanClassForParsing";
+ public static final String OSLC4J_INFER_TYPE_FROM_SHAPE = "org.eclipse.lyo.oslc4j.inferTypeFromResourceShape";
- public static final Map<String, Object> OSL4J_PROPERTY_SINGLETON =
- new HashMap<String, Object>(0);
+ public static final Map<String, Object> OSL4J_PROPERTY_SINGLETON = new HashMap<String, Object>(0);
public static final String OSLC4J_SELECTED_PROPERTIES = "org.eclipse.lyo.oslc4j.selected.properties";
public static final String OSLC4J_NEXT_PAGE = "org.eclipse.lyo.oslc4j.next.page";
diff --git a/org.eclipse.lyo.oslc4j.core/src/org/eclipse/lyo/oslc4j/core/OSLC4JUtils.java b/org.eclipse.lyo.oslc4j.core/src/org/eclipse/lyo/oslc4j/core/OSLC4JUtils.java
index abc4b8c..63b84f0 100644
--- a/org.eclipse.lyo.oslc4j.core/src/org/eclipse/lyo/oslc4j/core/OSLC4JUtils.java
+++ b/org.eclipse.lyo.oslc4j.core/src/org/eclipse/lyo/oslc4j/core/OSLC4JUtils.java
@@ -16,17 +16,32 @@
*******************************************************************************/
package org.eclipse.lyo.oslc4j.core;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashSet;
+import java.util.List;
import java.util.logging.Logger;
-import javax.ws.rs.core.UriBuilder;
import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.UriBuilder;
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.namespace.QName;
+
+import org.eclipse.lyo.oslc4j.core.model.ResourceShape;
+import org.eclipse.lyo.oslc4j.core.model.XMLLiteral;
-import org.eclipse.lyo.oslc4j.core.OSLC4JConstants;
+import com.hp.hpl.jena.datatypes.RDFDatatype;
+import com.hp.hpl.jena.datatypes.TypeMapper;
+import com.hp.hpl.jena.datatypes.xsd.XSDDateTime;
+import com.hp.hpl.jena.datatypes.xsd.impl.XMLLiteralType;
public class OSLC4JUtils {
@@ -39,6 +54,22 @@ public class OSLC4JUtils {
*/
private static String useBeanClassForParsing = System.getProperty(OSLC4JConstants.OSLC4J_USE_BEAN_CLASS_FOR_PARSING);
+ /**
+ * This constant should be set to true when the property type is not
+ * explicitly passed and it should be inferred from the resource shape. By
+ * default this is set to false. This is part of the the fix for defect
+ * 412789.
+ */
+ private static String inferTypeFromShape = System.getProperty(OSLC4JConstants.OSLC4J_INFER_TYPE_FROM_SHAPE);
+
+ /**
+ * List of available ResourceShapes. This list will be used to infer the
+ * property type from the resource shape and it will only be considered if
+ * the property inferTypeFromShape is set to true. This is part of the the
+ * fix for defect 412789.
+ */
+ private static List<ResourceShape> shapes = new ArrayList<ResourceShape>();
+
private static final Logger logger = Logger.getLogger(OSLC4JUtils.class.getName());
/**
* Returns the value of org.eclipse.lyo.oslc4j.publicURI or null if not set.
@@ -83,6 +114,45 @@ public class OSLC4JUtils {
OSLC4JUtils.useBeanClassForParsing = useBeanClassForParsing;
}
+ public static boolean inferTypeFromShape() {
+ boolean result = false;
+ if (null != inferTypeFromShape) {
+ result = Boolean.parseBoolean(inferTypeFromShape);
+ }
+ return result;
+ }
+
+ public static String getInferTypeFromShape() {
+ return inferTypeFromShape;
+ }
+
+ public static void setInferTypeFromShape(String inferTypeFromShape) {
+ OSLC4JUtils.inferTypeFromShape = inferTypeFromShape;
+ }
+
+ /**
+ * Returns a list of Resource Shapes to be used when inferring a property
+ * type from the Resource Shape. This method should only be used when the
+ * property inferTypeFromShape is set to true.
+ *
+ * @return List of Resource Shapes
+ */
+ public static List<ResourceShape> getShapes() {
+ return shapes;
+ }
+
+ /**
+ * Sets a list of Resource Shapes to be used when inferring a property type
+ * from the Resource Shape. This method should only be used when the
+ * property inferTypeFromShape is set to true.
+ *
+ * @param shapes
+ * List of Resource Shapes
+ */
+ public static void setShapes(List<ResourceShape> shapes) {
+ OSLC4JUtils.shapes = shapes;
+ }
+
/**
* Returns the boolean value of org.eclipse.lyo.oslc4j.disableHostResolution
* Default is false if not set or invalid (hostname resolution will take place)
@@ -209,4 +279,140 @@ public class OSLC4JUtils {
{
return "true".equals(System.getProperty(OSLC4JConstants.OSLC4J_QUERY_RESULT_LIST_AS_CONTAINER, "false"));
}
+
+ /**
+ * This method returns true if the given Resource Shape describes array
+ * matches the list of RDF types.
+ *
+ * @param shape
+ * Resource Shape
+ * @param rdfTypesList
+ * List of rdf:types
+ *
+ * @return True if the ResourceShape type is in the list of rdf:types,
+ * otherwise returns false.
+ */
+ private static boolean doesResourceShapeMatchRdfTypes(final ResourceShape shape,
+ final HashSet<String> rdfTypesList)
+ {
+ if (null != shape)
+ {
+ final URI[] describes = shape.getDescribes();
+ for (URI describeUri : describes)
+ {
+ final String describeUriStr = describeUri.toASCIIString();
+ if (rdfTypesList.contains(describeUriStr))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * This method receives the property name and the property value and tries
+ * to infer the property type from the pre-defined list of Resource Shapes.
+ * Then returns the corresponding java object for the given object value.
+ * Returns a null object when it was not possible to infer the property type
+ * from the list of Resource Shapes.
+ *
+ * @param rdfTypesList
+ * @param propertyQName
+ * Property information
+ * @param originalValue
+ * Property value
+ * @return Java object related to the Resource Shape type.
+ * @throws DatatypeConfigurationException
+ * , IllegalArgumentException, InstantiationException,
+ * InvocationTargetException
+ on
+ *
+ */
+ public static Object getValueBasedOnResourceShapeType(final HashSet<String> rdfTypesList,
+ final QName propertyQName,
+ final Object originalValue)
+ throws DatatypeConfigurationException,
+ IllegalArgumentException,
+ InstantiationException,
+ InvocationTargetException
+ {
+ if (null != rdfTypesList && !rdfTypesList.isEmpty() && null != propertyQName && null != originalValue)
+ {
+ try {
+ // get the pre-defined list of ResourceShapes
+ List<ResourceShape> shapes = OSLC4JUtils.getShapes();
+
+ if (null != shapes && !shapes.isEmpty()) {
+
+ // try to find the attribute type in the list of
+ // resource shapes
+ String propertyName = propertyQName.getNamespaceURI()
+ + propertyQName.getLocalPart();
+
+ TypeMapper typeMapper = TypeMapper.getInstance();
+
+ for (ResourceShape shape : shapes) {
+
+ // ensure that the current resource shape matches the resource rdf:type
+ if (doesResourceShapeMatchRdfTypes(shape, rdfTypesList)) {
+
+ org.eclipse.lyo.oslc4j.core.model.Property[] props = shape.getProperties();
+
+ for (org.eclipse.lyo.oslc4j.core.model.Property prop : props) {
+ URI propDefinition = prop.getPropertyDefinition();
+
+ if (propertyName.equals(propDefinition.toString())) {
+ URI propValueType = prop.getValueType();
+
+ if (null == propValueType) {
+ continue;
+ }
+
+ RDFDatatype dataTypeFromShape = typeMapper.getTypeByName(propValueType.toString());
+
+ // this is a literal type
+ if (null != dataTypeFromShape) {
+
+ // special treatment for XMLLiteral
+ if (XMLLiteralType.theXMLLiteralType.getURI().equals(propValueType.toString())) {
+ return new XMLLiteral(originalValue.toString());
+ }
+
+ // special treatment for Date
+ Class<?> objClass = dataTypeFromShape.getJavaClass();
+ if (objClass.getCanonicalName().equals(XSDDateTime.class.getCanonicalName())) {
+ String dateStr = originalValue.toString();
+ Calendar calendar;
+ calendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(dateStr).toGregorianCalendar();
+ final XSDDateTime xsdDateTime = new XSDDateTime(calendar);
+ return xsdDateTime.asCalendar().getTime();
+ }
+
+ Constructor<?> cons = objClass.getConstructor(String.class);
+ return cons.newInstance(originalValue.toString());
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (NoSuchMethodException e) {
+ // if there is any error while creating the new object, return null,
+ // i.e use the original value and not the new one.
+ logger.warning("Could not create extended value <" + propertyQName + " +> based on shape: " + e.getLocalizedMessage());
+ return null;
+ } catch (IllegalAccessException e) {
+ // if there is any error while creating the new object, return null,
+ // i.e use the original value and not the new one.
+ // if there is any error while creating the new object, return null,
+ // i.e use the original value and not the new one.
+ logger.warning("Could not create extended value <" + propertyQName + " +> based on shape: " + e.getLocalizedMessage());
+ return null;
+ }
+ }
+
+ return null;
+ }
}
diff --git a/org.eclipse.lyo.oslc4j.provider.jena/src/org/eclipse/lyo/oslc4j/provider/jena/JenaModelHelper.java b/org.eclipse.lyo.oslc4j.provider.jena/src/org/eclipse/lyo/oslc4j/provider/jena/JenaModelHelper.java
index 48a0673..e3ad4b2 100644
--- a/org.eclipse.lyo.oslc4j.provider.jena/src/org/eclipse/lyo/oslc4j/provider/jena/JenaModelHelper.java
+++ b/org.eclipse.lyo.oslc4j.provider.jena/src/org/eclipse/lyo/oslc4j/provider/jena/JenaModelHelper.java
@@ -91,6 +91,7 @@ import org.eclipse.lyo.oslc4j.core.model.XMLLiteral;
import org.w3c.dom.Element;
import com.hp.hpl.jena.datatypes.DatatypeFormatException;
+import com.hp.hpl.jena.datatypes.RDFDatatype;
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
import com.hp.hpl.jena.datatypes.xsd.XSDDateTime;
import com.hp.hpl.jena.datatypes.xsd.impl.XMLLiteralType;
@@ -326,12 +327,14 @@ public final class JenaModelHelper
final Object newInstance = beanClass.newInstance();
final Map<Class<?>, Map<String, Method>> classPropertyDefinitionsToSetMethods = new HashMap<Class<?>, Map<String, Method>>();
final Map<String,Object> visitedResources = new HashMap<String, Object>();
-
+ final HashSet<String> rdfTypes = new HashSet<String>();
+
fromResource(classPropertyDefinitionsToSetMethods,
beanClass,
newInstance,
resource,
- visitedResources);
+ visitedResources,
+ rdfTypes);
return newInstance;
}
@@ -407,12 +410,14 @@ public final class JenaModelHelper
for (final Resource resource : listSubjects) {
final Object newInstance = beanClass.newInstance();
final Map<String,Object> visitedResources = new HashMap<String, Object>();
-
+ final HashSet<String> rdfTypes = new HashSet<String>();
+
fromResource(classPropertyDefinitionsToSetMethods,
beanClass,
newInstance,
resource,
- visitedResources);
+ visitedResources,
+ rdfTypes);
results.add(newInstance);
}
@@ -426,7 +431,8 @@ public final class JenaModelHelper
final Class<?> beanClass,
final Object bean,
final Resource resource,
- Map<String,Object> visitedResources)
+ Map<String,Object> visitedResources,
+ HashSet<String> rdfTypes)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -494,6 +500,9 @@ public final class JenaModelHelper
extendedProperties = null;
}
+ // get the list of resource rdf type
+ rdfTypes = getTypesFromResource(resource, rdfTypes);
+
while (listProperties.hasNext())
{
final Statement statement = listProperties.next();
@@ -530,7 +539,7 @@ public final class JenaModelHelper
prefix = generatePrefix(resource.getModel(), predicate.getNameSpace());
}
final QName key = new QName(predicate.getNameSpace(), predicate.getLocalName(), prefix);
- final Object value = handleExtendedPropertyValue(beanClass, object, visitedResources);
+ final Object value = handleExtendedPropertyValue(beanClass, object, visitedResources, key, rdfTypes);
final Object previous = extendedProperties.get(key);
if (previous == null)
{
@@ -762,7 +771,8 @@ public final class JenaModelHelper
setMethodComponentParameterClass,
nestedBean,
nestedResource,
- visitedResources);
+ visitedResources,
+ rdfTypes);
parameter = nestedBean;
}
@@ -800,7 +810,8 @@ public final class JenaModelHelper
reifiedClass,
reifiedResource,
reifiedStatement,
- visitedResources);
+ visitedResources,
+ rdfTypes);
}
parameter = reifiedResource;
@@ -912,6 +923,35 @@ public final class JenaModelHelper
}
}
+ /**
+ * Returns a hash set of rdf:types for a given resource object. If the set
+ * was populated before, returns the given list. This list will only be
+ * populated if the property inferTypeFromShape is set to true.
+ *
+ * @param resource
+ * @param types
+ * @return List of rdf:types
+ */
+ private static HashSet<String> getTypesFromResource(final Resource resource, HashSet<String> types) {
+ // The list of rdf:types will be populated only if the property
+ // inferTypeFromShape is set and if the list was not populated before.
+ // This is necessary because for an inline resource, the retuned
+ // rdf:type is not from the parent resource, it is from the actual
+ // resource.
+ if (OSLC4JUtils.inferTypeFromShape() && types.isEmpty()) {
+ StmtIterator rdfTypesIterator = resource.listProperties(RDF.type);
+ while (rdfTypesIterator.hasNext()) {
+ Statement rdfTypeStmt = rdfTypesIterator.next();
+ RDFNode object = rdfTypeStmt.getObject();
+ if (object.isResource()) {
+ String rdfType = object.asResource().getURI();
+ types.add(rdfType);
+ }
+ }
+ }
+ return types;
+ }
+
private static boolean isRdfCollectionResource(Model model, RDFNode object)
{
if (object.isResource())
@@ -954,7 +994,9 @@ public final class JenaModelHelper
private static Object handleExtendedPropertyValue(final Class<?> beanClass,
final RDFNode object,
- Map<String,Object> visitedResources)
+ Map<String,Object> visitedResources,
+ final QName propertyQName,
+ final HashSet<String> rdfTypes)
throws URISyntaxException,
IllegalArgumentException,
SecurityException,
@@ -970,6 +1012,27 @@ public final class JenaModelHelper
try
{
final Literal literal = object.asLiteral();
+
+ // fix for Bug 412789
+ if (OSLC4JUtils.inferTypeFromShape()) {
+
+ // get property data type
+ RDFDatatype dataType = literal.getDatatype();
+
+ // infer the data type from the Resource Shape only if the
+ // data type was not explicit passed in the original request
+ if (null == dataType) {
+ Object newObject = OSLC4JUtils.getValueBasedOnResourceShapeType(rdfTypes, propertyQName, literal.getString());
+
+ // return the value only if the type was really inferred
+ // from the resource shape, otherwise keep the same
+ // behavior, i.e., return a String value
+ if (null != newObject) {
+ return newObject;
+ }
+ }
+ }
+
final Object literalValue = literal.getValue();
if (literalValue instanceof XSDDateTime)
{
@@ -1002,7 +1065,8 @@ public final class JenaModelHelper
AnyResource.class,
any,
nestedResource,
- visitedResources);
+ visitedResources,
+ rdfTypes);
return any;
}
diff --git a/org.eclipse.lyo.oslc4j.provider.json4j/src/org/eclipse/lyo/oslc4j/provider/json4j/JsonHelper.java b/org.eclipse.lyo.oslc4j.provider.json4j/src/org/eclipse/lyo/oslc4j/provider/json4j/JsonHelper.java
index 9ec2d4b..18e26cd 100644
--- a/org.eclipse.lyo.oslc4j.provider.json4j/src/org/eclipse/lyo/oslc4j/provider/json4j/JsonHelper.java
+++ b/org.eclipse.lyo.oslc4j.provider.json4j/src/org/eclipse/lyo/oslc4j/provider/json4j/JsonHelper.java
@@ -23,6 +23,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
@@ -390,13 +391,15 @@ public final class JsonHelper
final JSONObject resourceJSONObject = (JSONObject) object;
final Object bean = beanClass.newInstance();
-
+ HashSet<String> rdfTypes = new HashSet<String>();
+
fromJSON(rdfPrefix,
namespaceMappings,
classPropertyDefinitionsToSetMethods,
resourceJSONObject,
beanClass,
- bean);
+ bean,
+ rdfTypes);
beans.add(bean);
}
@@ -405,13 +408,15 @@ public final class JsonHelper
else
{
final Object bean = beanClass.newInstance();
-
+ HashSet<String> rdfTypes = new HashSet<String>();
+
fromJSON(rdfPrefix,
namespaceMappings,
classPropertyDefinitionsToSetMethods,
jsonObject,
beanClass,
- bean);
+ bean,
+ rdfTypes);
beans.add(bean);
}
@@ -1363,12 +1368,49 @@ public final class JsonHelper
}
}
+ /**
+ * Returns a list of rdf:types for a given json object. If the list was
+ * populated before, returns the given list. This list will only be
+ * populated if the property inferTypeFromShape is set to true.
+ *
+ * @param jsonObject
+ * @param rdfPrefix
+ * @param types
+ * @return List of rdf:types
+ */
+ private static HashSet<String> getRdfTypesFromJsonObject(JSONObject jsonObject, String rdfPrefix, HashSet<String> types) {
+ // The list of rdf:types will be populated only if the property
+ // inferTypeFromShape is set and if the list was not populated before.
+ // This is necessary because for an inline object, the retuned
+ // rdf:type is not from the parent object, it is from the actual
+ // resource.
+ if (OSLC4JUtils.inferTypeFromShape() && types.isEmpty()) {
+ final String typeProperty = rdfPrefix + JSON_PROPERTY_DELIMITER + JSON_PROPERTY_SUFFIX_TYPE;
+ if (jsonObject.has(typeProperty)) {
+ try {
+ JSONArray array = jsonObject.getJSONArray(typeProperty);
+ for (int i = 0; i < array.size(); ++i) {
+ final JSONObject typeObj = array.getJSONObject(i);
+ String resTypePropertyValue = typeObj.getString(rdfPrefix + JSON_PROPERTY_DELIMITER + JSON_PROPERTY_SUFFIX_RESOURCE);
+ types.add(resTypePropertyValue);
+ }
+ }
+ catch (JSONException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ }
+ return types;
+ }
+
private static void fromJSON(final String rdfPrefix,
final Map<String, String> jsonNamespaceMappings,
final Map<Class<?>, Map<String, Method>> classPropertyDefinitionsToSetMethods,
final JSONObject jsonObject,
final Class<?> beanClass,
- final Object bean)
+ final Object bean,
+ HashSet<String> rdfTypes)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -1446,6 +1488,9 @@ public final class JsonHelper
extendedProperties = null;
}
+ // get the list of rdf types
+ rdfTypes = getRdfTypesFromJsonObject(jsonObject, rdfPrefix, rdfTypes);
+
@SuppressWarnings("unchecked")
final Set<Map.Entry<String, Object>> entrySet = jsonObject.entrySet();
@@ -1508,14 +1553,16 @@ public final class JsonHelper
}
else
{
+ final QName qName = new QName(namespace,
+ name,
+ namespacePrefix);
+
final Object value = fromExtendedJSONValue(jsonValue,
rdfPrefix,
jsonNamespaceMappings,
- beanClass);
- final QName qName = new QName(namespace,
- name,
- namespacePrefix);
-
+ beanClass,
+ qName,
+ rdfTypes);
extendedProperties.put(qName, value);
}
}
@@ -1555,7 +1602,8 @@ public final class JsonHelper
setMethod,
setMethodParameterClass,
setMethodComponentParameterClass,
- jsonValue);
+ jsonValue,
+ rdfTypes);
if (parameter != null)
{
@@ -1575,7 +1623,9 @@ public final class JsonHelper
private static Object fromExtendedJSONValue(final Object jsonValue,
final String rdfPrefix,
final Map<String, String> jsonNamespaceMappings,
- final Class<?> beanClass)
+ final Class<?> beanClass,
+ final QName propertyQName,
+ HashSet<String> rdfTypes)
throws DatatypeConfigurationException,
URISyntaxException,
IllegalArgumentException,
@@ -1591,7 +1641,7 @@ public final class JsonHelper
final Iterator<?> i = jsonArray.iterator();
while (i.hasNext())
{
- collection.add(fromExtendedJSONValue(i.next(), rdfPrefix, jsonNamespaceMappings, beanClass));
+ collection.add(fromExtendedJSONValue(i.next(), rdfPrefix, jsonNamespaceMappings, beanClass, propertyQName, rdfTypes));
}
return collection;
@@ -1622,12 +1672,33 @@ public final class JsonHelper
new HashMap<Class<?>, Map<String, Method>>(),
o,
AnyResource.class,
- any);
+ any,
+ rdfTypes);
return any;
}
else if (jsonValue instanceof String)
{
+
+ // fix for Bug 412789
+ // try to infer the data type from resource shapes for Strings
+ if (OSLC4JUtils.inferTypeFromShape()) {
+
+ Object newObject = OSLC4JUtils.getValueBasedOnResourceShapeType(rdfTypes, propertyQName, jsonValue);
+
+ // return the value only if the type was really inferred from
+ // the resource shape, otherwise keep the same behavior
+ if (null != newObject) {
+
+ // return the new value only for ambiguous case
+ if ((newObject instanceof String)
+ || (newObject instanceof XMLLiteral)
+ || (newObject instanceof Date)) {
+ return newObject;
+ }
+ }
+ }
+
// Check if it's in the OSLC date format.
try
{
@@ -1641,6 +1712,35 @@ public final class JsonHelper
return jsonValue;
}
}
+ else if (jsonValue instanceof Integer) {
+
+ // fix for Bug 412789
+ // There is no need to infer data type from resource shapes as
+ // integer values do not have ambiguity cases
+ return jsonValue;
+
+ }
+ else if (jsonValue instanceof Double) {
+
+ // fix for Bug 412789
+ // try to infer data type from resource shapes for Double
+ if (OSLC4JUtils.inferTypeFromShape()) {
+ Object newObject = OSLC4JUtils.getValueBasedOnResourceShapeType(rdfTypes, propertyQName, jsonValue);
+
+ // return the value only if the type was really inferred from
+ // the resource shape, otherwise keep the same behavior
+ if (null != newObject) {
+
+ // return the new value only for ambiguous case
+ if ((newObject instanceof Double)
+ || (newObject instanceof Float)
+ || (newObject instanceof BigDecimal)) {
+ return newObject;
+ }
+ }
+ }
+
+ }
return jsonValue;
}
@@ -1734,7 +1834,8 @@ public final class JsonHelper
final Method setMethod,
final Class<?> setMethodParameterClass,
final Class<?> setMethodComponentParameterClass,
- final Object jsonValue)
+ final Object jsonValue,
+ HashSet<String> rdfTypes)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -1806,7 +1907,8 @@ public final class JsonHelper
classPropertyDefinitionsToSetMethods,
nestedJSONObject,
setMethodComponentParameterClass,
- nestedBean);
+ nestedBean,
+ rdfTypes);
return nestedBean;
}
@@ -1857,7 +1959,8 @@ public final class JsonHelper
setMethod,
setMethodComponentParameterClass,
setMethodComponentParameterClass,
- jsonArrayEntryObject);
+ jsonArrayEntryObject,
+ rdfTypes);
tempList.add(parameterArrayObject);
}