aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Pitschke2012-07-14 16:15:44 (EDT)
committerSteve Pitschke2012-07-14 16:15:44 (EDT)
commit07c8d92a75e0b4361fc73ba21181c5015c3a3cd4 (patch)
tree86595bf7db5faeabac24cca86a019a753e875310
parenta9a35f91a676e2e755ada7201e3b1c325f22ca73 (diff)
downloadorg.eclipse.lyo.core-07c8d92a75e0b4361fc73ba21181c5015c3a3cd4.zip
org.eclipse.lyo.core-07c8d92a75e0b4361fc73ba21181c5015c3a3cd4.tar.gz
org.eclipse.lyo.core-07c8d92a75e0b4361fc73ba21181c5015c3a3cd4.tar.bz2
Bug 385080: Enhance Lyo Core to Support New Query Facilityrefs/changes/88/6788/1
The Jena and JSON @Providers can be passed optional representations of the oslc.properties or oslc.select clauses to limit what properties and nested properties are output. Change-Id: I3550a46b27d30cc81342001ec226c31be1d788ae Signed-off-by: Steve Pitschke <pitschke@us.ibm.com>
-rw-r--r--OSLC4J/src/org/eclipse/lyo/oslc4j/core/NestedWildcardProperties.java33
-rw-r--r--OSLC4J/src/org/eclipse/lyo/oslc4j/core/OSLC4JConstants.java9
-rw-r--r--OSLC4J/src/org/eclipse/lyo/oslc4j/core/SingletonWildcardProperties.java (renamed from org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/PropertyList.java)11
-rw-r--r--OSLC4JJenaProvider/src/org/eclipse/lyo/oslc4j/provider/jena/AbstractOslcRdfXmlProvider.java9
-rw-r--r--OSLC4JJenaProvider/src/org/eclipse/lyo/oslc4j/provider/jena/JenaModelHelper.java253
-rw-r--r--OSLC4JJson4JProvider/src/org/eclipse/lyo/oslc4j/provider/json4j/AbstractOslcRdfJsonProvider.java11
-rw-r--r--OSLC4JJson4JProvider/src/org/eclipse/lyo/oslc4j/provider/json4j/JsonHelper.java207
-rw-r--r--org.eclipse.lyo.core.query/pom.xml5
-rw-r--r--org.eclipse.lyo.core.query/src/main/antlr3/org/eclipse/lyo/core/query/OslcSelect.g17
-rw-r--r--org.eclipse.lyo.core.query/src/main/antlr3/org/eclipse/lyo/core/query/OslcWhere.g1
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/NestedProperty.java3
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/ParseException.java8
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Properties.java10
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/PropertiesClause.java1
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Property.java2
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/QueryUtils.java343
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Wildcard.java2
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/BooleanValueInvocationHandler.java2
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/DecimalValueInvocationHandler.java2
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/IndentifierInvocationHandler.java55
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/LangedStringValueInvocationHandler.java2
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/NestedPropertyInvocationHandler.java63
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertiesInvocationHandler.java149
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertyInvocationHandler.java27
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertyListInvocationHandler.java130
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/SimpleSortTermInvocationHandler.java1
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/StringValueInvocationHandler.java2
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/TypedValueInvocationHandler.java2
-rw-r--r--org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/WildcardInvocationHandler.java7
-rw-r--r--org.eclipse.lyo.core.query/src/test/java/org/eclipse/lyo/core/query/test/BasicSelectTest.java3
30 files changed, 984 insertions, 386 deletions
diff --git a/OSLC4J/src/org/eclipse/lyo/oslc4j/core/NestedWildcardProperties.java b/OSLC4J/src/org/eclipse/lyo/oslc4j/core/NestedWildcardProperties.java
new file mode 100644
index 0000000..6b77d94
--- /dev/null
+++ b/OSLC4J/src/org/eclipse/lyo/oslc4j/core/NestedWildcardProperties.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
+ *
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *
+ * Steve Pitschke - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.lyo.oslc4j.core;
+
+import java.util.Map;
+
+/**
+ * Marker interface applied to {@link Map}<String, Object> to
+ * indicate that when selecting properties for output all immediate,
+ * resource properties of the resource should be output with entries
+ * in the {@link NestedWildcardProperties#commonNestedProperties()}
+ */
+public interface NestedWildcardProperties
+{
+ /**
+ * @return map of all member properties of nested resources to be
+ * output
+ */
+ Map<String, Object> commonNestedProperties();
+}
diff --git a/OSLC4J/src/org/eclipse/lyo/oslc4j/core/OSLC4JConstants.java b/OSLC4J/src/org/eclipse/lyo/oslc4j/core/OSLC4JConstants.java
index 3c3cbe3..f8ddaaf 100644
--- a/OSLC4J/src/org/eclipse/lyo/oslc4j/core/OSLC4JConstants.java
+++ b/OSLC4J/src/org/eclipse/lyo/oslc4j/core/OSLC4JConstants.java
@@ -16,9 +16,16 @@
*******************************************************************************/
package org.eclipse.lyo.oslc4j.core;
+import java.util.HashMap;
+import java.util.Map;
+
public interface OSLC4JConstants {
public static String OSLC4J_PUBLIC_URI = "org.eclipse.lyo.oslc4j.publicURI";
public static String OSLC4J_DISABLE_HOST_RESOLUTION = "org.eclipse.lyo.oslc4j.disableHostResolution";
-
+
+ public static final Map<String, Object> OSL4J_PROPERTY_SINGLETON =
+ new HashMap<String, Object>(0);
+
+ public static String OSLC4J_SELECTED_PROPERTIES = "selected.properties";
}
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/PropertyList.java b/OSLC4J/src/org/eclipse/lyo/oslc4j/core/SingletonWildcardProperties.java
index 908c150..358e9f4 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/PropertyList.java
+++ b/OSLC4J/src/org/eclipse/lyo/oslc4j/core/SingletonWildcardProperties.java
@@ -13,14 +13,15 @@
*
* Steve Pitschke - initial API and implementation
*******************************************************************************/
-package org.eclipse.lyo.core.query;
+package org.eclipse.lyo.oslc4j.core;
-import java.util.List;
+import java.util.Map;
/**
- * Property list from olsc.select of oslc.properties clause
+ * Marker interface applied to {@link Map}<String, Object> to
+ * indicate that when selecting properties for output all immediate,
+ * properties of the resource should be output
*/
-public interface PropertyList extends Properties
+public interface SingletonWildcardProperties
{
- List<Property> children();
}
diff --git a/OSLC4JJenaProvider/src/org/eclipse/lyo/oslc4j/provider/jena/AbstractOslcRdfXmlProvider.java b/OSLC4JJenaProvider/src/org/eclipse/lyo/oslc4j/provider/jena/AbstractOslcRdfXmlProvider.java
index b07646f..3a7f3f2 100644
--- a/OSLC4JJenaProvider/src/org/eclipse/lyo/oslc4j/provider/jena/AbstractOslcRdfXmlProvider.java
+++ b/OSLC4JJenaProvider/src/org/eclipse/lyo/oslc4j/provider/jena/AbstractOslcRdfXmlProvider.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.util.List;
+import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Produces;
@@ -34,6 +35,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.ext.Providers;
+import org.eclipse.lyo.oslc4j.core.OSLC4JConstants;
import org.eclipse.lyo.oslc4j.core.OSLC4JUtils;
import org.eclipse.lyo.oslc4j.core.annotation.OslcResourceShape;
import org.eclipse.lyo.oslc4j.core.model.Error;
@@ -151,11 +153,16 @@ public abstract class AbstractOslcRdfXmlProvider
serializationLanguage = FileUtils.langXMLAbbrev;
}
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> properties =
+ (Map<String, Object>)httpServletRequest.getAttribute(OSLC4JConstants.OSLC4J_SELECTED_PROPERTIES);
+
try
{
final Model model = JenaModelHelper.createJenaModel(descriptionURI,
responseInfoURI,
- objects);
+ objects,
+ properties);
final RDFWriter writer = model.getWriter(serializationLanguage);
writer.setProperty("showXmlDeclaration",
diff --git a/OSLC4JJenaProvider/src/org/eclipse/lyo/oslc4j/provider/jena/JenaModelHelper.java b/OSLC4JJenaProvider/src/org/eclipse/lyo/oslc4j/provider/jena/JenaModelHelper.java
index d0b8a56..61e558b 100644
--- a/OSLC4JJenaProvider/src/org/eclipse/lyo/oslc4j/provider/jena/JenaModelHelper.java
+++ b/OSLC4JJenaProvider/src/org/eclipse/lyo/oslc4j/provider/jena/JenaModelHelper.java
@@ -52,6 +52,9 @@ import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.namespace.QName;
+import org.eclipse.lyo.oslc4j.core.OSLC4JConstants;
+import org.eclipse.lyo.oslc4j.core.NestedWildcardProperties;
+import org.eclipse.lyo.oslc4j.core.SingletonWildcardProperties;
import org.eclipse.lyo.oslc4j.core.annotation.OslcName;
import org.eclipse.lyo.oslc4j.core.annotation.OslcNamespaceDefinition;
import org.eclipse.lyo.oslc4j.core.annotation.OslcPropertyDefinition;
@@ -64,6 +67,7 @@ import org.eclipse.lyo.oslc4j.core.exception.OslcCoreMissingSetMethodException;
import org.eclipse.lyo.oslc4j.core.exception.OslcCoreMisusedOccursException;
import org.eclipse.lyo.oslc4j.core.exception.OslcCoreRelativeURIException;
import org.eclipse.lyo.oslc4j.core.model.AbstractResource;
+import org.eclipse.lyo.oslc4j.core.model.AnyResource;
import org.eclipse.lyo.oslc4j.core.model.IExtendedResource;
import org.eclipse.lyo.oslc4j.core.model.IReifiedResource;
import org.eclipse.lyo.oslc4j.core.model.IResource;
@@ -71,7 +75,6 @@ import org.eclipse.lyo.oslc4j.core.model.InheritedMethodAnnotationHelper;
import org.eclipse.lyo.oslc4j.core.model.OslcConstants;
import org.eclipse.lyo.oslc4j.core.model.TypeFactory;
import org.eclipse.lyo.oslc4j.core.model.ValueType;
-import org.eclipse.lyo.oslc4j.core.model.AnyResource;
import com.hp.hpl.jena.datatypes.BaseDatatype;
import com.hp.hpl.jena.datatypes.DatatypeFormatException;
@@ -122,12 +125,14 @@ public final class JenaModelHelper
{
return createJenaModel(null,
null,
- objects);
+ objects,
+ null);
}
- static Model createJenaModel(final String descriptionAbout,
- final String responseInfoAbout,
- final Object[] objects)
+ static Model createJenaModel(final String descriptionAbout,
+ final String responseInfoAbout,
+ final Object[] objects,
+ final Map<String, Object> properties)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -159,7 +164,8 @@ public final class JenaModelHelper
handleSingleResource(descriptionResource,
object,
model,
- namespaceMappings);
+ namespaceMappings,
+ properties);
}
if (descriptionAbout != null)
@@ -193,10 +199,11 @@ public final class JenaModelHelper
return model;
}
- private static void handleSingleResource(final Resource descriptionResource,
- final Object object,
- final Model model,
- final Map<String, String> namespaceMappings)
+ private static void handleSingleResource(final Resource descriptionResource,
+ final Object object,
+ final Model model,
+ final Map<String, String> namespaceMappings,
+ final Map<String, Object> properties)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -242,7 +249,8 @@ public final class JenaModelHelper
buildResource(object,
objectClass,
model,
- mainResource);
+ mainResource,
+ properties);
if (descriptionResource != null)
{
@@ -888,13 +896,19 @@ public final class JenaModelHelper
private static void buildResource(final Object object,
final Class<?> resourceClass,
final Model model,
- final Resource mainResource)
+ final Resource mainResource,
+ final Map<String, Object> properties)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException,
OslcCoreApplicationException
{
+ if (properties == OSLC4JConstants.OSL4J_PROPERTY_SINGLETON)
+ {
+ return;
+ }
+
for (final Method method : resourceClass.getMethods())
{
if (method.getParameterTypes().length == 0)
@@ -912,15 +926,45 @@ public final class JenaModelHelper
if (oslcPropertyDefinitionAnnotation != null)
{
final Object value = method.invoke(object);
-
+
if (value != null)
{
+ Map<String, Object> nestedProperties = null;
+ boolean onlyNested = false;
+
+ if (properties != null)
+ {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> map = (Map<String, Object>)properties.get(oslcPropertyDefinitionAnnotation.value());
+
+ if (map != null)
+ {
+ nestedProperties = map;
+ }
+ else if (properties instanceof SingletonWildcardProperties &&
+ ! (properties instanceof NestedWildcardProperties))
+ {
+ nestedProperties = OSLC4JConstants.OSL4J_PROPERTY_SINGLETON;
+ }
+ else if (properties instanceof NestedWildcardProperties)
+ {
+ nestedProperties = ((NestedWildcardProperties)properties).commonNestedProperties();
+ onlyNested = ! (properties instanceof SingletonWildcardProperties);
+ }
+ else
+ {
+ continue;
+ }
+ }
+
buildAttributeResource(resourceClass,
method,
oslcPropertyDefinitionAnnotation,
model,
mainResource,
- value);
+ value,
+ nestedProperties,
+ onlyNested);
}
}
}
@@ -934,14 +978,16 @@ public final class JenaModelHelper
handleExtendedProperties(resourceClass,
model,
mainResource,
- extendedResource);
+ extendedResource,
+ properties);
}
}
protected static void handleExtendedProperties(final Class<?> resourceClass,
final Model model,
final Resource mainResource,
- final IExtendedResource extendedResource)
+ final IExtendedResource extendedResource,
+ final Map<String, Object> properties)
throws DatatypeConfigurationException,
IllegalAccessException,
InvocationTargetException,
@@ -949,7 +995,18 @@ public final class JenaModelHelper
{
for (final URI type : extendedResource.getTypes())
{
- final Resource typeResource = model.createResource(type.toString());
+ final String propertyName = type.toString();
+
+ if (properties != null &&
+ properties.get(propertyName) == null &&
+ ! (properties instanceof NestedWildcardProperties) &&
+ ! (properties instanceof SingletonWildcardProperties))
+ {
+ continue;
+ }
+
+ final Resource typeResource = model.createResource(propertyName);
+
if (!mainResource.hasProperty(RDF.type, typeResource))
{
mainResource.addProperty(RDF.type, typeResource);
@@ -959,19 +1016,61 @@ public final class JenaModelHelper
for (final Map.Entry<QName, ?> extendedProperty : extendedResource.getExtendedProperties().entrySet())
{
final QName qName = extendedProperty.getKey();
- final Property property = model.createProperty(qName.getNamespaceURI() + qName.getLocalPart());
+ final String propertyName = qName.getNamespaceURI() + qName.getLocalPart();
+ Map<String, Object> nestedProperties = null;
+ boolean onlyNested = false;
+
+ if (properties != null)
+ {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> map = (Map<String, Object>)properties.get(propertyName);
+
+ if (map != null)
+ {
+ nestedProperties = map;
+ }
+ else if (properties instanceof SingletonWildcardProperties &&
+ ! (properties instanceof NestedWildcardProperties))
+ {
+ nestedProperties = OSLC4JConstants.OSL4J_PROPERTY_SINGLETON;
+ }
+ else if (properties instanceof NestedWildcardProperties)
+ {
+ nestedProperties = ((NestedWildcardProperties)properties).commonNestedProperties();
+ onlyNested = ! (properties instanceof SingletonWildcardProperties);
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ final Property property = model.createProperty(propertyName);
final Object value = extendedProperty.getValue();
+
if (value instanceof Collection)
{
final Collection<?> collection = (Collection<?>) value;
for (Object next : collection)
{
- handleExtendedValue(resourceClass, next, model, mainResource, property);
+ handleExtendedValue(resourceClass,
+ next,
+ model,
+ mainResource,
+ property,
+ nestedProperties,
+ onlyNested);
}
}
else
{
- handleExtendedValue(resourceClass, value, model, mainResource, property);
+ handleExtendedValue(resourceClass,
+ value,
+ model,
+ mainResource,
+ property,
+ nestedProperties,
+ onlyNested);
}
}
}
@@ -980,7 +1079,9 @@ public final class JenaModelHelper
final Object value,
final Model model,
final Resource resource,
- final Property property)
+ final Property property,
+ final Map<String, Object> nestedProperties,
+ final boolean onlyNested)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -1010,26 +1111,52 @@ public final class JenaModelHelper
for (final URI type : any.getTypes())
{
- nestedResource.addProperty(RDF.type, model.createResource(type.toString()));
+ final String propertyName = type.toString();
+
+ if (nestedProperties == null ||
+ nestedProperties.get(propertyName) != null ||
+ nestedProperties instanceof NestedWildcardProperties ||
+ nestedProperties instanceof SingletonWildcardProperties)
+ {
+ nestedResource.addProperty(RDF.type, model.createResource(propertyName));
+ }
}
- handleExtendedProperties(AnyResource.class, model, nestedResource, any);
+ handleExtendedProperties(AnyResource.class, model, nestedResource, any, nestedProperties);
resource.addProperty(property, nestedResource);
}
else if (value.getClass().getAnnotation(OslcResourceShape.class) != null || value instanceof URI)
{
//TODO: Until we handle XMLLiteral for incoming unknown resources, need to assume it is not XMLLiteral
boolean xmlliteral = false;
- handleLocalResource(objectClass, null, xmlliteral, value, model, resource, property);
+ handleLocalResource(objectClass,
+ null,
+ xmlliteral,
+ value,
+ model,
+ resource,
+ property,
+ nestedProperties,
+ onlyNested);
}
else if (value instanceof Date)
{
+ if (onlyNested)
+ {
+ return;
+ }
+
final Calendar cal = Calendar.getInstance();
cal.setTime((Date) value);
resource.addProperty(property, model.createTypedLiteral(cal));
}
else
{
+ if (onlyNested)
+ {
+ return;
+ }
+
resource.addProperty(property, model.createTypedLiteral(value));
}
}
@@ -1039,7 +1166,9 @@ public final class JenaModelHelper
final OslcPropertyDefinition propertyDefinitionAnnotation,
final Model model,
final Resource resource,
- final Object value)
+ final Object value,
+ final Map<String, Object> nestedProperties,
+ final boolean onlyNested)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -1100,7 +1229,9 @@ public final class JenaModelHelper
object,
model,
resource,
- attribute);
+ attribute,
+ nestedProperties,
+ onlyNested);
}
}
else if (Collection.class.isAssignableFrom(returnType))
@@ -1116,7 +1247,9 @@ public final class JenaModelHelper
object,
model,
resource,
- attribute);
+ attribute,
+ nestedProperties,
+ onlyNested);
}
}
else
@@ -1127,17 +1260,21 @@ public final class JenaModelHelper
value,
model,
resource,
- attribute);
+ attribute,
+ nestedProperties,
+ onlyNested);
}
}
- private static void handleLocalResource(final Class<?> resourceClass,
- final Method method,
- final boolean xmlLiteral,
- final Object object,
- final Model model,
- final Resource resource,
- final Property attribute)
+ private static void handleLocalResource(final Class<?> resourceClass,
+ final Method method,
+ final boolean xmlLiteral,
+ final Object object,
+ final Model model,
+ final Resource resource,
+ final Property attribute,
+ final Map<String, Object> nestedProperties,
+ final boolean onlyNested)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -1152,6 +1289,11 @@ public final class JenaModelHelper
if (value instanceof String)
{
+ if (onlyNested)
+ {
+ return;
+ }
+
if (xmlLiteral)
{
statement = model.createStatement(resource,
@@ -1167,10 +1309,20 @@ public final class JenaModelHelper
else if ((value instanceof Boolean) ||
(value instanceof Number))
{
+ if (onlyNested)
+ {
+ return;
+ }
+
statement = model.createStatement(resource, attribute, value.toString());
}
else if (value instanceof URI)
{
+ if (onlyNested)
+ {
+ return;
+ }
+
final URI uri = (URI) value;
if (!uri.isAbsolute())
@@ -1180,12 +1332,16 @@ public final class JenaModelHelper
uri);
}
-
// URIs represent references to other resources identified by their IDs, so they need to be managed as such
statement = model.createStatement(resource, attribute, model.createResource(value.toString()));
}
else if (value instanceof Date)
{
+ if (onlyNested)
+ {
+ return;
+ }
+
final GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime((Date) value);
@@ -1223,20 +1379,22 @@ public final class JenaModelHelper
nestedResource = model.createResource(model.createProperty(namespace,
name));
}
-
+
buildResource(value,
objectClass,
model,
- nestedResource);
+ nestedResource,
+ nestedProperties);
statement = model.createStatement(resource, attribute, nestedResource);
}
if (statement != null)
{
- if (reifiedResource != null)
+ if (reifiedResource != null &&
+ nestedProperties != OSLC4JConstants.OSL4J_PROPERTY_SINGLETON)
{
- addReifiedStatements(model, statement, reifiedResource);
+ addReifiedStatements(model, statement, reifiedResource, nestedProperties);
}
// Finally, add the statement to the model.
@@ -1244,9 +1402,10 @@ public final class JenaModelHelper
}
}
- private static void addReifiedStatements(final Model model,
- final Statement statement,
- final IReifiedResource<?> reifiedResource)
+ private static void addReifiedStatements(final Model model,
+ final Statement statement,
+ final IReifiedResource<?> reifiedResource,
+ final Map<String, Object> nestedProperties)
throws IllegalArgumentException,
IllegalAccessException,
InvocationTargetException,
@@ -1254,8 +1413,12 @@ public final class JenaModelHelper
OslcCoreApplicationException
{
ReifiedStatement reifiedStatement = statement.createReifiedStatement();
- buildResource(reifiedResource, reifiedResource.getClass(), model,
- reifiedStatement);
+
+ buildResource(reifiedResource,
+ reifiedResource.getClass(),
+ model,
+ reifiedStatement,
+ nestedProperties);
}
private static String getDefaultPropertyName(final Method method)
diff --git a/OSLC4JJson4JProvider/src/org/eclipse/lyo/oslc4j/provider/json4j/AbstractOslcRdfJsonProvider.java b/OSLC4JJson4JProvider/src/org/eclipse/lyo/oslc4j/provider/json4j/AbstractOslcRdfJsonProvider.java
index 864ca77..14768cb 100644
--- a/OSLC4JJson4JProvider/src/org/eclipse/lyo/oslc4j/provider/json4j/AbstractOslcRdfJsonProvider.java
+++ b/OSLC4JJson4JProvider/src/org/eclipse/lyo/oslc4j/provider/json4j/AbstractOslcRdfJsonProvider.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.util.List;
+import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Produces;
@@ -35,6 +36,7 @@ import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.ext.Providers;
import org.apache.wink.json4j.JSONObject;
+import org.eclipse.lyo.oslc4j.core.OSLC4JConstants;
import org.eclipse.lyo.oslc4j.core.OSLC4JUtils;
import org.eclipse.lyo.oslc4j.core.annotation.OslcResourceShape;
import org.eclipse.lyo.oslc4j.core.model.Error;
@@ -122,11 +124,16 @@ public abstract class AbstractOslcRdfJsonProvider
final JSONObject jsonObject;
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> properties =
+ (Map<String, Object>)httpServletRequest.getAttribute(OSLC4JConstants.OSLC4J_SELECTED_PROPERTIES);
+
try
{
jsonObject = JsonHelper.createJSON(descriptionURI,
responseInfoURI,
- objects);
+ objects,
+ properties);
jsonObject.write(outputStream,
true);
@@ -140,7 +147,7 @@ public abstract class AbstractOslcRdfJsonProvider
}
}
- protected static boolean isReadable(final Class<?> type,
+ protected static boolean isReadable(final Class<?> type,
final MediaType requiredMediaType,
final MediaType actualMediaType)
{
diff --git a/OSLC4JJson4JProvider/src/org/eclipse/lyo/oslc4j/provider/json4j/JsonHelper.java b/OSLC4JJson4JProvider/src/org/eclipse/lyo/oslc4j/provider/json4j/JsonHelper.java
index 4c692ec..4d59e76 100644
--- a/OSLC4JJson4JProvider/src/org/eclipse/lyo/oslc4j/provider/json4j/JsonHelper.java
+++ b/OSLC4JJson4JProvider/src/org/eclipse/lyo/oslc4j/provider/json4j/JsonHelper.java
@@ -56,6 +56,9 @@ import javax.xml.namespace.QName;
import org.apache.wink.json4j.JSONArray;
import org.apache.wink.json4j.JSONException;
import org.apache.wink.json4j.JSONObject;
+import org.eclipse.lyo.oslc4j.core.NestedWildcardProperties;
+import org.eclipse.lyo.oslc4j.core.OSLC4JConstants;
+import org.eclipse.lyo.oslc4j.core.SingletonWildcardProperties;
import org.eclipse.lyo.oslc4j.core.annotation.OslcName;
import org.eclipse.lyo.oslc4j.core.annotation.OslcNamespaceDefinition;
import org.eclipse.lyo.oslc4j.core.annotation.OslcPropertyDefinition;
@@ -106,9 +109,10 @@ final class JsonHelper
super();
}
- public static JSONObject createJSON(final String descriptionAbout,
- final String responseInfoAbout,
- final Object[] objects)
+ public static JSONObject createJSON(final String descriptionAbout,
+ final String responseInfoAbout,
+ final Object[] objects,
+ final Map<String, Object> properties)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -130,7 +134,8 @@ final class JsonHelper
final JSONObject jsonObject = handleSingleResource(object,
new JSONObject(),
namespaceMappings,
- reverseNamespaceMappings);
+ reverseNamespaceMappings,
+ properties);
if (jsonObject != null)
{
@@ -193,7 +198,8 @@ final class JsonHelper
handleSingleResource(objects[0],
resultJSONObject,
namespaceMappings,
- reverseNamespaceMappings);
+ reverseNamespaceMappings,
+ properties);
}
// Set the namespace prefixes
@@ -338,7 +344,9 @@ final class JsonHelper
final Method method,
final OslcPropertyDefinition propertyDefinitionAnnotation,
final JSONObject jsonObject,
- final Object value)
+ final Object value,
+ final Map<String, Object> nestedProperties,
+ final boolean onlyNested)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -391,7 +399,9 @@ final class JsonHelper
reverseNamespaceMappings,
resourceClass,
method,
- object);
+ object,
+ nestedProperties,
+ onlyNested);
if (localResource != null)
{
jsonArray.add(localResource);
@@ -420,7 +430,9 @@ final class JsonHelper
reverseNamespaceMappings,
resourceClass,
method,
- object);
+ object,
+ nestedProperties,
+ onlyNested);
if (localResource != null)
{
jsonArray.add(localResource);
@@ -442,7 +454,9 @@ final class JsonHelper
reverseNamespaceMappings,
resourceClass,
method,
- value);
+ value,
+ nestedProperties,
+ onlyNested);
}
if (localResourceValue != null)
@@ -466,7 +480,8 @@ final class JsonHelper
final Map<String, String> reverseNamespaceMappings,
final Object object,
final Class<?> objectClass,
- final JSONObject jsonObject)
+ final JSONObject jsonObject,
+ final Map<String, Object> properties)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -478,7 +493,8 @@ final class JsonHelper
reverseNamespaceMappings,
object,
objectClass,
- jsonObject);
+ jsonObject,
+ properties);
// For JSON, we have to save array of rdf:type
@@ -540,14 +556,20 @@ final class JsonHelper
final Map<String, String> reverseNamespaceMappings,
final Object object,
final Class<?> objectClass,
- final JSONObject jsonObject)
+ final JSONObject jsonObject,
+ final Map<String, Object> properties)
throws IllegalAccessException,
InvocationTargetException,
DatatypeConfigurationException,
JSONException,
OslcCoreApplicationException
{
- for (final Method method : objectClass.getMethods())
+ if (properties == OSLC4JConstants.OSL4J_PROPERTY_SINGLETON)
+ {
+ return;
+ }
+
+ for (final Method method : objectClass.getMethods())
{
if (method.getParameterTypes().length == 0)
{
@@ -566,13 +588,43 @@ final class JsonHelper
if (value != null)
{
+ Map<String, Object> nestedProperties = null;
+ boolean onlyNested = false;
+
+ if (properties != null)
+ {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> map = (Map<String, Object>)properties.get(oslcPropertyDefinitionAnnotation.value());
+
+ if (map != null)
+ {
+ nestedProperties = map;
+ }
+ else if (properties instanceof SingletonWildcardProperties &&
+ ! (properties instanceof NestedWildcardProperties))
+ {
+ nestedProperties = OSLC4JConstants.OSL4J_PROPERTY_SINGLETON;
+ }
+ else if (properties instanceof NestedWildcardProperties)
+ {
+ nestedProperties = ((NestedWildcardProperties)properties).commonNestedProperties();
+ onlyNested = ! (properties instanceof SingletonWildcardProperties);
+ }
+ else
+ {
+ continue;
+ }
+ }
+
buildAttributeResource(namespaceMappings,
reverseNamespaceMappings,
objectClass,
method,
oslcPropertyDefinitionAnnotation,
jsonObject,
- value);
+ value,
+ nestedProperties,
+ onlyNested);
}
}
}
@@ -582,17 +634,20 @@ final class JsonHelper
if (object instanceof IExtendedResource)
{
final IExtendedResource extendedResource = (IExtendedResource) object;
+
addExtendedProperties(namespaceMappings,
reverseNamespaceMappings,
jsonObject,
- extendedResource);
+ extendedResource,
+ properties);
}
}
protected static void addExtendedProperties(final Map<String, String> namespaceMappings,
final Map<String, String> reverseNamespaceMappings,
final JSONObject jsonObject,
- final IExtendedResource extendedResource)
+ final IExtendedResource extendedResource,
+ final Map<String, Object> properties)
throws JSONException,
DatatypeConfigurationException,
IllegalAccessException,
@@ -601,30 +656,65 @@ final class JsonHelper
{
for (Map.Entry<QName, Object> extendedProperty : extendedResource.getExtendedProperties().entrySet())
{
- final Object value = getExtendedPropertyJsonValue(namespaceMappings, reverseNamespaceMappings, extendedProperty.getValue());
- if (value == null)
+ final String namespace = extendedProperty.getKey().getNamespaceURI();
+ final String localName = extendedProperty.getKey().getLocalPart();
+ Map<String, Object> nestedProperties = null;
+ boolean onlyNested = false;
+
+ if (properties != null)
+ {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> map = (Map<String, Object>)properties.get(namespace + localName);
+
+ if (map != null)
+ {
+ nestedProperties = map;
+ }
+ else if (properties instanceof SingletonWildcardProperties &&
+ ! (properties instanceof NestedWildcardProperties))
+ {
+ nestedProperties = OSLC4JConstants.OSL4J_PROPERTY_SINGLETON;
+ }
+ else if (properties instanceof NestedWildcardProperties)
+ {
+ nestedProperties = ((NestedWildcardProperties)properties).commonNestedProperties();
+ onlyNested = ! (properties instanceof SingletonWildcardProperties);
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ final Object value = getExtendedPropertyJsonValue(namespaceMappings,
+ reverseNamespaceMappings,
+ extendedProperty.getValue(),
+ nestedProperties,
+ onlyNested);
+
+ if (value == null && ! onlyNested)
{
logger.warning("Could not add extended property " + extendedProperty.getKey() + " for resource " + extendedResource.getAbout());
}
else
{
- final String prefix = extendedProperty.getKey().getPrefix();
- final String namespace = extendedProperty.getKey().getNamespaceURI();
- final String localName = extendedProperty.getKey().getLocalPart();
-
- // Add the prefix to the JSON namespace mappings.
- namespaceMappings.put(prefix, namespace);
- reverseNamespaceMappings.put(namespace, prefix);
+ final String prefix = extendedProperty.getKey().getPrefix();
+
+ // Add the prefix to the JSON namespace mappings.
+ namespaceMappings.put(prefix, namespace);
+ reverseNamespaceMappings.put(namespace, prefix);
- // Add the value to the JSON object.
- jsonObject.put(prefix + JSON_PROPERTY_DELIMITER + localName, value);
+ // Add the value to the JSON object.
+ jsonObject.put(prefix + JSON_PROPERTY_DELIMITER + localName, value);
}
}
}
private static Object getExtendedPropertyJsonValue(final Map<String, String> namespaceMappings,
final Map<String, String> reverseNamespaceMappings,
- final Object object)
+ final Object object,
+ final Map<String, Object> nestedProperties,
+ final boolean onlyNested)
throws JSONException,
DatatypeConfigurationException,
IllegalArgumentException,
@@ -640,7 +730,11 @@ final class JsonHelper
final Collection<Object> c = (Collection<Object>) object;
for (final Object next : c)
{
- final Object nextJson = getExtendedPropertyJsonValue(namespaceMappings, reverseNamespaceMappings, next);
+ final Object nextJson = getExtendedPropertyJsonValue(namespaceMappings,
+ reverseNamespaceMappings,
+ next,
+ nestedProperties,
+ onlyNested);
if (nextJson != null)
{
jsonArray.add(nextJson);
@@ -653,10 +747,20 @@ final class JsonHelper
(object instanceof Boolean) ||
(object instanceof Number))
{
+ if (onlyNested)
+ {
+ return null;
+ }
+
return object;
}
else if (object instanceof Date)
{
+ if (onlyNested)
+ {
+ return null;
+ }
+
final GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime((Date) object);
@@ -664,6 +768,11 @@ final class JsonHelper
}
else if (object instanceof URI)
{
+ if (onlyNested)
+ {
+ return null;
+ }
+
return handleResourceReference(namespaceMappings,
reverseNamespaceMappings,
resourceClass,
@@ -675,7 +784,8 @@ final class JsonHelper
return handleSingleResource(object,
new JSONObject(),
namespaceMappings,
- reverseNamespaceMappings);
+ reverseNamespaceMappings,
+ nestedProperties);
}
return null;
@@ -704,7 +814,9 @@ final class JsonHelper
final Map<String, String> reverseNamespaceMappings,
final Class<?> resourceClass,
final Method method,
- final Object object)
+ final Object object,
+ final Map<String, Object> nestedProperties,
+ final boolean onlyNested)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -716,10 +828,20 @@ final class JsonHelper
(object instanceof Boolean) ||
(object instanceof Number))
{
+ if (onlyNested)
+ {
+ return null;
+ }
+
return object;
}
else if (object instanceof URI)
{
+ if (onlyNested)
+ {
+ return null;
+ }
+
return handleResourceReference(namespaceMappings,
reverseNamespaceMappings,
resourceClass,
@@ -728,6 +850,11 @@ final class JsonHelper
}
else if (object instanceof Date)
{
+ if (onlyNested)
+ {
+ return null;
+ }
+
final GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime((Date) object);
@@ -739,20 +866,23 @@ final class JsonHelper
reverseNamespaceMappings,
object.getClass(),
method,
- (IReifiedResource<?>) object);
+ (IReifiedResource<?>) object,
+ nestedProperties);
}
return handleSingleResource(object,
new JSONObject(),
namespaceMappings,
- reverseNamespaceMappings);
+ reverseNamespaceMappings,
+ nestedProperties);
}
private static Object handleReifiedResource(final Map<String, String> namespaceMappings,
final Map<String, String> reverseNamespaceMappings,
final Class<?> resourceClass,
final Method method,
- final IReifiedResource<?> reifiedResource)
+ final IReifiedResource<?> reifiedResource,
+ final Map<String, Object> properties)
throws OslcCoreInvalidPropertyTypeException,
OslcCoreRelativeURIException,
JSONException,
@@ -790,7 +920,8 @@ final class JsonHelper
reverseNamespaceMappings,
reifiedResource,
resourceClass,
- jsonObject);
+ jsonObject,
+ properties);
return jsonObject;
}
@@ -828,7 +959,8 @@ final class JsonHelper
private static JSONObject handleSingleResource(final Object object,
final JSONObject jsonObject,
final Map<String, String> namespaceMappings,
- final Map<String, String> reverseNamespaceMappings)
+ final Map<String, String> reverseNamespaceMappings,
+ final Map<String, Object> properties)
throws DatatypeConfigurationException,
IllegalAccessException,
IllegalArgumentException,
@@ -857,7 +989,8 @@ final class JsonHelper
reverseNamespaceMappings,
object,
objectClass,
- jsonObject);
+ jsonObject,
+ properties);
return jsonObject;
}
diff --git a/org.eclipse.lyo.core.query/pom.xml b/org.eclipse.lyo.core.query/pom.xml
index ab96b45..679de6f 100644
--- a/org.eclipse.lyo.core.query/pom.xml
+++ b/org.eclipse.lyo.core.query/pom.xml
@@ -14,6 +14,11 @@
<artifactId>slf4j-simple</artifactId>
<version>1.6.4</version>
</dependency>
+ <dependency>
+ <groupId>org.eclipse.lyo.oslc4j.core</groupId>
+ <artifactId>oslc4j-core</artifactId>
+ <version>0.1.1-SNAPSHOT</version>
+ </dependency>
</dependencies>
<build>
<outputDirectory>target/classes</outputDirectory>
diff --git a/org.eclipse.lyo.core.query/src/main/antlr3/org/eclipse/lyo/core/query/OslcSelect.g b/org.eclipse.lyo.core.query/src/main/antlr3/org/eclipse/lyo/core/query/OslcSelect.g
index 74b2f7e..5fd0d37 100644
--- a/org.eclipse.lyo.core.query/src/main/antlr3/org/eclipse/lyo/core/query/OslcSelect.g
+++ b/org.eclipse.lyo.core.query/src/main/antlr3/org/eclipse/lyo/core/query/OslcSelect.g
@@ -57,22 +57,17 @@ package org.eclipse.lyo.core.query;
oslc_select : properties
;
-property : identifier | nested_property
+properties : property ( ',' property )* -> ^( 'properties' property (property)* )
;
-property_list : property ( ',' property )* -> ^( 'properties' property (property)* )
- ;
-
-properties : ( wildcard | property_list )
- ;
-
-nested_property : identifier OPEN_CURLY_BRACE properties CLOSE_CURLY_BRACE -> ^( 'nested_property' identifier properties )
- ;
+property : identifier | nested_property
+ ;
-identifier : prefixedName -> ^( 'prefixed_name' prefixedName )
+nested_property : identifier OPEN_CURLY_BRACE properties CLOSE_CURLY_BRACE -> ^( 'nested_property' identifier properties )
;
-wildcard : ASTERISK -> ^( 'wildcard' )
+identifier : prefixedName -> ^( 'prefixed_name' prefixedName )
+ | ASTERISK -> ^( 'wildcard' )
;
prefixedName
diff --git a/org.eclipse.lyo.core.query/src/main/antlr3/org/eclipse/lyo/core/query/OslcWhere.g b/org.eclipse.lyo.core.query/src/main/antlr3/org/eclipse/lyo/core/query/OslcWhere.g
index 64956b0..dacafb8 100644
--- a/org.eclipse.lyo.core.query/src/main/antlr3/org/eclipse/lyo/core/query/OslcWhere.g
+++ b/org.eclipse.lyo.core.query/src/main/antlr3/org/eclipse/lyo/core/query/OslcWhere.g
@@ -181,6 +181,7 @@ BOOLEAN
DECIMAL
: (MINUS | PLUS)? DIGIT+ DOT DIGIT*
| (MINUS | PLUS)? DOT DIGIT+
+ | (MINUS | PLUS)? DIGIT+
;
STRING_LITERAL
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/NestedProperty.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/NestedProperty.java
index b7d9515..68d908e 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/NestedProperty.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/NestedProperty.java
@@ -18,7 +18,6 @@ package org.eclipse.lyo.core.query;
/**
* Nested property from olsc.select of oslc.properties clause
*/
-public interface NestedProperty extends Property
+public interface NestedProperty extends Property, Properties
{
- Properties properties();
}
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/ParseException.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/ParseException.java
index 78c0941..8624db8 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/ParseException.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/ParseException.java
@@ -23,13 +23,15 @@ import org.antlr.runtime.RecognitionException;
*/
public class ParseException extends Exception
{
- /**
- * @param cause
- */
ParseException(RecognitionException cause)
{
super(cause);
}
+ ParseException(String msg)
+ {
+ super(msg);
+ }
+
private static final long serialVersionUID = 2373494371127406191L;
}
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Properties.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Properties.java
index d11420d..88dec16 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Properties.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Properties.java
@@ -15,16 +15,12 @@
*******************************************************************************/
package org.eclipse.lyo.core.query;
+import java.util.List;
+
/**
* Properties from olsc.select of oslc.properties clause
*/
public interface Properties
{
- enum Type
- {
- WILDCARD,
- PROPERTY_LIST;
- }
-
- Type type();
+ List<Property> children();
}
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/PropertiesClause.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/PropertiesClause.java
index 19a11b8..b10085b 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/PropertiesClause.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/PropertiesClause.java
@@ -15,7 +15,6 @@
*******************************************************************************/
package org.eclipse.lyo.core.query;
-import java.beans.PropertyEditor;
/**
* Top-level properties from oslc.Properties clause
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Property.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Property.java
index 053d434..35f3c26 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Property.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Property.java
@@ -28,5 +28,7 @@ public interface Property
Type type();
+ boolean isWildcard();
+
PName identifier();
}
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/QueryUtils.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/QueryUtils.java
index 888c456..2a0fd8e 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/QueryUtils.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/QueryUtils.java
@@ -28,9 +28,11 @@ import org.antlr.runtime.tree.CommonErrorNode;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.Tree;
import org.eclipse.lyo.core.query.impl.CompoundTermInvocationHandler;
-import org.eclipse.lyo.core.query.impl.PropertyListInvocationHandler;
+import org.eclipse.lyo.core.query.impl.PropertiesInvocationHandler;
import org.eclipse.lyo.core.query.impl.SortTermsInvocationHandler;
-import org.eclipse.lyo.core.query.impl.WildcardInvocationHandler;
+import org.eclipse.lyo.oslc4j.core.OSLC4JConstants;
+import org.eclipse.lyo.oslc4j.core.NestedWildcardProperties;
+import org.eclipse.lyo.oslc4j.core.SingletonWildcardProperties;
/**
* Utility methods for parsing various OSLC HTTP query
@@ -39,6 +41,14 @@ import org.eclipse.lyo.core.query.impl.WildcardInvocationHandler;
public class QueryUtils
{
/**
+ * A property list that selects all properties
+ */
+ static public final Properties WILDCARD_PROPERTY_LIST = (Properties)
+ Proxy.newProxyInstance(Properties.class.getClassLoader(),
+ new Class<?>[] { Properties.class },
+ new PropertiesInvocationHandler());
+
+ /**
* Parse a oslc.prefix clause into a map between prefixes
* and corresponding URIs
*
@@ -56,12 +66,19 @@ public class QueryUtils
String prefixExpression
) throws ParseException
{
+ if (prefixExpression == null) {
+ return new HashMap<String, String>();
+ }
+
OslcPrefixParser parser = new OslcPrefixParser(prefixExpression);
try {
CommonTree rawTree =
(CommonTree)parser.oslc_prefixes().getTree();
+
+ checkErrors(parser.getErrors());;
+
@SuppressWarnings("unchecked")
List<CommonTree> rawPrefixes = rawTree.getChildren();
PrefixMap prefixMap =
@@ -111,7 +128,10 @@ public class QueryUtils
try {
OslcWhereParser.oslc_where_return resultTree =
- parser.oslc_where();
+ parser.oslc_where();
+
+ checkErrors(parser.getErrors());;
+
CommonTree rawTree = (CommonTree)resultTree.getTree();
Tree child = rawTree.getChild(0);
@@ -154,25 +174,21 @@ public class QueryUtils
OslcSelectParser.oslc_select_return resultTree =
parser.oslc_select();
+
+ checkErrors(parser.getErrors());;
+
CommonTree rawTree = (CommonTree)resultTree.getTree();
if (rawTree.getType() == Token.INVALID_TOKEN_TYPE) {
throw ((CommonErrorNode)rawTree).trappedException;
}
- if (rawTree.getType() == OslcSelectParser.PROPERTIES) {
- return (SelectClause)
- Proxy.newProxyInstance(SelectClause.class.getClassLoader(),
- new Class<?>[] { SelectClause.class, PropertyList.class },
- new PropertyListInvocationHandler(
- (CommonTree)resultTree.getTree(),
- prefixMap));
- } else {
- return (SelectClause)
- Proxy.newProxyInstance(SelectClause.class.getClassLoader(),
- new Class<?>[] { SelectClause.class, Wildcard.class },
- new WildcardInvocationHandler());
- }
+ return (SelectClause)
+ Proxy.newProxyInstance(SelectClause.class.getClassLoader(),
+ new Class<?>[] { SelectClause.class, Properties.class },
+ new PropertiesInvocationHandler(
+ (CommonTree)resultTree.getTree(),
+ prefixMap));
} catch (RecognitionException e) {
throw new ParseException(e);
@@ -203,25 +219,21 @@ public class QueryUtils
OslcSelectParser.oslc_select_return resultTree =
parser.oslc_select();
+
+ checkErrors(parser.getErrors());;
+
CommonTree rawTree = (CommonTree)resultTree.getTree();
if (rawTree.getType() == Token.INVALID_TOKEN_TYPE) {
throw ((CommonErrorNode)rawTree).trappedException;
}
- if (rawTree.getType() == OslcSelectParser.PROPERTIES) {
- return (PropertiesClause)
- Proxy.newProxyInstance(SelectClause.class.getClassLoader(),
- new Class<?>[] { PropertiesClause.class, PropertyList.class },
- new PropertyListInvocationHandler(
- (CommonTree)resultTree.getTree(),
- prefixMap));
- } else {
- return (PropertiesClause)
- Proxy.newProxyInstance(SelectClause.class.getClassLoader(),
- new Class<?>[] { PropertiesClause.class, Wildcard.class },
- new WildcardInvocationHandler());
- }
+ return (PropertiesClause)
+ Proxy.newProxyInstance(PropertiesClause.class.getClassLoader(),
+ new Class<?>[] { PropertiesClause.class, Properties.class },
+ new PropertiesInvocationHandler(
+ (CommonTree)resultTree.getTree(),
+ prefixMap));
} catch (RecognitionException e) {
throw new ParseException(e);
@@ -252,6 +264,9 @@ public class QueryUtils
OslcOrderByParser.oslc_order_by_return resultTree =
parser.oslc_order_by();
+
+ checkErrors(parser.getErrors());;
+
CommonTree rawTree = (CommonTree)resultTree.getTree();
Tree child = rawTree.getChild(0);
@@ -270,6 +285,127 @@ public class QueryUtils
}
/**
+ * Create a map representation of the {@link Properties} returned
+ * from parsing oslc.properties or olsc.select URL query
+ * parameters suitable for generating a property result from an
+ * HTTP GET request.<p>
+ *
+ * The map keys are the property names; i.e. the local name of the
+ * property concatenated to the XML namespace of the property. The
+ * values of the map are:<p>
+ *
+ * <ul>
+ * <li> {@link OSLC4JConstants.OSL4J_PROPERTY_WILDCARD} - if all
+ * properties at this level are to be output. No recursion
+ * below this level is to be done.</li>
+ * <li> {@link OSLC4JConstants.OSL4J_PROPERTY_SINGLETON} - if only
+ * the named property is to be output, without recursion</li>
+ * <li> a nested property list to recurse through</li>
+ * </ul>
+ *
+ * @param properties
+ *
+ * @return the property map
+ */
+ public static Map<String, Object>
+ invertSelectedProperties(final Properties properties)
+ {
+ List<Property> children = properties.children();
+ Map<String, Object> result = new HashMap<String, Object>(children.size());
+
+ for (Property property : children) {
+
+ PName pname = null;
+ String propertyName = null;
+
+ if (! property.isWildcard()) {
+ pname = property.identifier();
+ propertyName = pname.namespace + pname.local;
+ }
+
+ switch (property.type()) {
+ case IDENTIFIER:
+ if (property.isWildcard()) {
+
+ if (result instanceof SingletonWildcardProperties) {
+ break;
+ }
+
+ if (result instanceof NestedWildcardProperties) {
+ result = new BothWildcardPropertiesImpl(
+ (NestedWildcardPropertiesImpl)result);
+ } else {
+ result = new SingletonWildcardPropertiesImpl();
+ }
+
+ break;
+
+ } else {
+
+ if (result instanceof SingletonWildcardProperties) {
+ break;
+ }
+ }
+
+ result.put(propertyName,
+ OSLC4JConstants.OSL4J_PROPERTY_SINGLETON);
+
+ break;
+
+ case NESTED_PROPERTY:
+ if (property.isWildcard()) {
+
+ if (! (result instanceof NestedWildcardProperties)) {
+ if (result instanceof SingletonWildcardProperties) {
+ result = new BothWildcardPropertiesImpl();
+ } else {
+ result = new NestedWildcardPropertiesImpl(result);
+ }
+
+ ((NestedWildcardPropertiesImpl)result).commonNestedProperties =
+ invertSelectedProperties((NestedProperty)property);
+
+ } else {
+ mergePropertyMaps(
+ ((NestedWildcardProperties)result).commonNestedProperties(),
+ invertSelectedProperties((NestedProperty)property));
+ }
+
+ break;
+ }
+
+ result.put(propertyName,
+ invertSelectedProperties(
+ (NestedProperty)property));
+
+ break;
+ }
+ }
+
+ if (! (result instanceof NestedWildcardProperties)) {
+ return result;
+ }
+
+ Map<String, Object> commonNestedProperties =
+ ((NestedWildcardProperties)result).commonNestedProperties();
+
+ for (Map.Entry<String, Object> propertyMapping : result.entrySet()) {
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> nestedProperties =
+ (Map<String, Object>)propertyMapping.getValue();
+
+ if (nestedProperties == OSLC4JConstants.OSL4J_PROPERTY_SINGLETON) {
+ result.put(propertyMapping.getKey(), commonNestedProperties);
+ } else {
+ mergePropertyMaps(nestedProperties, commonNestedProperties);
+ }
+ }
+
+ return result;
+ }
+
+ /**
* Parse a oslc.searchTerms expression
*
* <p><b>Note</b>: {@link Object#toString()} of result has been overridden to
@@ -293,6 +429,9 @@ public class QueryUtils
OslcSearchTermsParser.oslc_search_terms_return resultTree =
parser.oslc_search_terms();
+
+ checkErrors(parser.getErrors());;
+
CommonTree rawTree = (CommonTree)resultTree.getTree();
Tree child = rawTree.getChild(0);
@@ -321,7 +460,7 @@ public class QueryUtils
/**
* Implementation of a {@link SearchTermsClause} interface
*/
- static class StringList extends ArrayList<String>
+ private static class StringList extends ArrayList<String>
implements SearchTermsClause
{
public
@@ -358,7 +497,7 @@ public class QueryUtils
/**
* Implementation of a Map<String, String> prefixMap
*/
- static class PrefixMap extends HashMap<String, String>
+ private static class PrefixMap extends HashMap<String, String>
{
public
PrefixMap(int size)
@@ -395,4 +534,146 @@ public class QueryUtils
private static final long serialVersionUID = 1943909246265711359L;
}
+ /**
+ * Implementation of {@link SingletonWildcardProperties}
+ */
+ private static class SingletonWildcardPropertiesImpl
+ extends HashMap<String, Object>
+ implements SingletonWildcardProperties
+ {
+ public
+ SingletonWildcardPropertiesImpl()
+ {
+ super(0);
+ }
+
+ private static final long serialVersionUID = -5490896670186283412L;
+ }
+
+ /**
+ * Implementation of {@link NestedWildcardProperties}
+ */
+ private static class NestedWildcardPropertiesImpl
+ extends HashMap<String, Object>
+ implements NestedWildcardProperties
+ {
+ public
+ NestedWildcardPropertiesImpl(Map<String, Object> accumulated)
+ {
+ super(accumulated);
+ }
+
+ protected
+ NestedWildcardPropertiesImpl()
+ {
+ super(0);
+ }
+
+ public Map<String, Object>
+ commonNestedProperties()
+ {
+ return commonNestedProperties;
+ }
+
+ protected Map<String, Object> commonNestedProperties =
+ new HashMap<String, Object>();
+ private static final long serialVersionUID = -938983371894966574L;
+ }
+
+ /**
+ * Implementation of both {@link SingletonWildcardProperties} and
+ * {@link NestedWildcardProperties}
+ */
+ private static class BothWildcardPropertiesImpl
+ extends NestedWildcardPropertiesImpl
+ implements SingletonWildcardProperties
+ {
+ public
+ BothWildcardPropertiesImpl()
+ {
+ }
+
+ public
+ BothWildcardPropertiesImpl(NestedWildcardPropertiesImpl accumulated)
+ {
+ this();
+
+ commonNestedProperties = accumulated.commonNestedProperties();
+ }
+
+ private static final long serialVersionUID = 654939845613307220L;
+ }
+
+ /**
+ * Merge into {@link #lhs} properties those of {@link #rhs} property
+ * map, merging any common, nested property maps
+ *
+ * @param lhs target of property map merge
+ * @param rhs source of property map merge
+ */
+ private static void
+ mergePropertyMaps(
+ Map<String, Object> lhs,
+ Map<String, Object> rhs
+ )
+ {
+ Iterator<String> propertyNames = rhs.keySet().iterator();
+
+ while (propertyNames.hasNext()) {
+
+ String propertyName = propertyNames.next();
+ @SuppressWarnings("unchecked")
+ Map<String, Object> lhsNestedProperties =
+ (Map<String, Object>)lhs.get(propertyName);
+ @SuppressWarnings("unchecked")
+ Map<String, Object> rhsNestedProperties =
+ (Map<String, Object>)rhs.get(propertyName);
+
+ if (lhsNestedProperties == rhsNestedProperties) {
+ continue;
+ }
+
+ if (lhsNestedProperties == null ||
+ lhsNestedProperties == OSLC4JConstants.OSL4J_PROPERTY_SINGLETON) {
+
+ lhs.put(propertyName, rhsNestedProperties);
+
+ continue;
+ }
+
+ mergePropertyMaps(lhsNestedProperties, rhsNestedProperties);
+ }
+ }
+
+ /**
+ * Check list of errors from parsing some expression, generating
+ * @{link {@link ParseException} if there are any.
+ *
+ * @param errors list of errors, hopefully empty
+ *
+ * @throws ParseException
+ */
+ private static void
+ checkErrors(List<String> errors) throws ParseException
+ {
+ if (errors.isEmpty()) {
+ return;
+ }
+
+ StringBuffer buffer = new StringBuffer();
+ boolean first = true;
+
+ for (String error : errors) {
+
+ if (first) {
+ first = false;
+ } else {
+ buffer.append('\n');
+ }
+
+ buffer.append(error);
+ }
+
+ throw new ParseException(buffer.toString());
+ }
}
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Wildcard.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Wildcard.java
index f88a60f..9f2786c 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Wildcard.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/Wildcard.java
@@ -18,6 +18,6 @@ package org.eclipse.lyo.core.query;
/**
* Wildcard property from olsc.select of oslc.properties clause
*/
-public interface Wildcard extends Properties
+public interface Wildcard extends Property
{
}
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/BooleanValueInvocationHandler.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/BooleanValueInvocationHandler.java
index 27d402d..3fc9e03 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/BooleanValueInvocationHandler.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/BooleanValueInvocationHandler.java
@@ -49,7 +49,7 @@ class BooleanValueInvocationHandler extends ValueInvocationHandler
if (! isValue &&
! methodName.equals("toString")) {
- super.invoke(proxy, method, args);
+ return super.invoke(proxy, method, args);
}
if (value == null) {
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/DecimalValueInvocationHandler.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/DecimalValueInvocationHandler.java
index 429c133..1d40fff 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/DecimalValueInvocationHandler.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/DecimalValueInvocationHandler.java
@@ -49,7 +49,7 @@ class DecimalValueInvocationHandler extends ValueInvocationHandler
if (! isValue &&
! methodName.equals("toString")) {
- super.invoke(proxy, method, args);
+ return super.invoke(proxy, method, args);
}
if (value == null) {
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/IndentifierInvocationHandler.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/IndentifierInvocationHandler.java
deleted file mode 100644
index e2ee0f8..0000000
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/IndentifierInvocationHandler.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 IBM Corporation.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
- *
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *
- * Steve Pitschke - initial API and implementation
- *******************************************************************************/
-package org.eclipse.lyo.core.query.impl;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import org.antlr.runtime.tree.CommonTree;
-import org.eclipse.lyo.core.query.Identifier;
-import org.eclipse.lyo.core.query.Property.Type;
-
-/**
- * Proxy implementation of {@link Indentifier} interface
- */
-public class IndentifierInvocationHandler extends PropertyInvocationHandler
-{
- public
- IndentifierInvocationHandler(
- CommonTree tree,
- Map<String, String> prefixMap
- )
- {
- super(tree, Type.IDENTIFIER, prefixMap);
- }
-
- /**
- * @see org.eclipse.lyo.core.query.impl.PropertiesInvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
- */
- @Override
- public Object invoke(
- Object proxy,
- Method method,
- Object[] args
- ) throws Throwable
- {
- if (! method.getName().equals("toString")) {
- return super.invoke(proxy, method, args);
- }
-
- return ((Identifier)proxy).identifier().toString();
- }
-}
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/LangedStringValueInvocationHandler.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/LangedStringValueInvocationHandler.java
index 286a0ab..9a47be6 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/LangedStringValueInvocationHandler.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/LangedStringValueInvocationHandler.java
@@ -50,7 +50,7 @@ class LangedStringValueInvocationHandler extends ValueInvocationHandler
if (! isValue &&
! methodName.equals("langTag")&&
! methodName.equals("toString")) {
- super.invoke(proxy, method, args);
+ return super.invoke(proxy, method, args);
}
if (isValue) {
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/NestedPropertyInvocationHandler.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/NestedPropertyInvocationHandler.java
index 5031d90..533bae8 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/NestedPropertyInvocationHandler.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/NestedPropertyInvocationHandler.java
@@ -16,16 +16,14 @@
package org.eclipse.lyo.core.query.impl;
import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
+import java.util.List;
import java.util.Map;
import org.antlr.runtime.tree.CommonTree;
import org.eclipse.lyo.core.query.NestedProperty;
import org.eclipse.lyo.core.query.OslcSelectParser;
-import org.eclipse.lyo.core.query.Properties;
+import org.eclipse.lyo.core.query.Property;
import org.eclipse.lyo.core.query.Property.Type;
-import org.eclipse.lyo.core.query.PropertyList;
-import org.eclipse.lyo.core.query.Wildcard;
/**
* Proxy implementation of {@link NestedProperty} interface
@@ -39,7 +37,7 @@ class NestedPropertyInvocationHandler extends PropertyInvocationHandler
)
{
super((CommonTree)tree.getChild(0).getChild(0), Type.NESTED_PROPERTY,
- prefixMap);
+ prefixMap, tree.getChild(0).getType() == OslcSelectParser.WILDCARD);
this.tree = tree;
}
@@ -48,49 +46,46 @@ class NestedPropertyInvocationHandler extends PropertyInvocationHandler
* @see org.eclipse.lyo.core.query.impl.PropertyInvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
@Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable
+ public Object invoke(
+ Object proxy,
+ Method method,
+ Object[] args
+ ) throws Throwable
{
String methodName = method.getName();
- boolean isProperties = methodName.equals("properties");
+ boolean isChildren = methodName.equals("children");
- if (! isProperties &&
+ if (! isChildren &&
! methodName.equals("toString")) {
return super.invoke(proxy, method, args);
}
- if (isProperties && properties != null) {
- return properties;
+ if (isChildren && children != null) {
+ return children;
}
- CommonTree treeProperties = (CommonTree)tree.getChild(1);
+ children = PropertiesInvocationHandler.createChildren(
+ (CommonTree)tree.getChild(1), prefixMap);
- switch (treeProperties.getType())
- {
- case OslcSelectParser.WILDCARD:
- properties = (Properties)
- Proxy.newProxyInstance(Wildcard.class.getClassLoader(),
- new Class<?>[] { Wildcard.class },
- new WildcardInvocationHandler());
- break;
- default:
- case OslcSelectParser.PROPERTIES:
- properties = (Properties)
- Proxy.newProxyInstance(PropertyList.class.getClassLoader(),
- new Class<?>[] { PropertyList.class },
- new PropertyListInvocationHandler(treeProperties,
- prefixMap));
- break;
+ if (isChildren) {
+ return children;
}
- if (isProperties) {
- return properties;
- }
+ NestedProperty nestedProperty = ((NestedProperty)proxy);
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(nestedProperty.isWildcard() ?
+ "*" :
+ nestedProperty.identifier().toString());
+ buffer.append('{');
+
+ PropertiesInvocationHandler.childrenToString(buffer, children);
+
+ buffer.append('}');
- return ((NestedProperty)proxy).identifier().toString() + '{' +
- properties.toString() + '}';
+ return buffer.toString();
}
private final CommonTree tree;
- private Properties properties = null;
+ private List<Property> children = null;
}
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertiesInvocationHandler.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertiesInvocationHandler.java
index e7713d3..5d992bb 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertiesInvocationHandler.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertiesInvocationHandler.java
@@ -17,22 +17,55 @@ package org.eclipse.lyo.core.query.impl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.antlr.runtime.tree.CommonTree;
+import org.eclipse.lyo.core.query.Identifier;
+import org.eclipse.lyo.core.query.NestedProperty;
+import org.eclipse.lyo.core.query.OslcSelectParser;
import org.eclipse.lyo.core.query.Properties;
-import org.eclipse.lyo.core.query.Properties.Type;
+import org.eclipse.lyo.core.query.Property;
+import org.eclipse.lyo.core.query.Property.Type;
+import org.eclipse.lyo.core.query.Wildcard;
/**
* Proxy implementation of {@link Properties} interface
*/
-class PropertiesInvocationHandler implements InvocationHandler
+public class PropertiesInvocationHandler implements InvocationHandler
{
- protected
- PropertiesInvocationHandler(Type type)
+ public
+ PropertiesInvocationHandler(
+ CommonTree tree,
+ Map<String, String> prefixMap
+ )
{
- this.type = type;
+ this.tree = tree;
+ this.prefixMap = prefixMap;
}
/**
+ * Construct a {@link Properties} proxy that has a single
+ * {@link Wildcard} child
+ */
+ public
+ PropertiesInvocationHandler()
+ {
+ this.tree = null;
+ this.prefixMap = null;
+
+ children = new ArrayList<Property>(1);
+
+ children.add((Property)Proxy.newProxyInstance(
+ Wildcard.class.getClassLoader(),
+ new Class<?>[] { Wildcard.class },
+ new WildcardInvocationHandler()));
+ }
+
+ /**
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
@Override
@@ -42,8 +75,110 @@ class PropertiesInvocationHandler implements InvocationHandler
Object[] args
) throws Throwable
{
- return type;
+ boolean isChildren = method.getName().equals("children");
+
+ if (isChildren && children != null) {
+ return children;
+ }
+
+ children = createChildren(tree, prefixMap);
+
+ if (isChildren) {
+ return children;
+ }
+
+ StringBuffer buffer = childrenToString(new StringBuffer(), children);
+
+ return buffer.toString();
+ }
+
+ /**
+ * Generate a list of property children from a parse tree node
+ *
+ * @param tree
+ * @param prefixMap
+ *
+ * @return the resulting property list
+ */
+ static List<Property>
+ createChildren(
+ CommonTree tree,
+ Map<String, String> prefixMap
+ )
+ {
+ @SuppressWarnings("unchecked")
+ List<CommonTree> treeChildren = tree.getChildren();
+ List<Property> children = new ArrayList<Property>(treeChildren.size());
+
+ for (CommonTree treeChild : treeChildren) {
+
+ Property property;
+
+ switch (treeChild.getType())
+ {
+ case OslcSelectParser.WILDCARD:
+ property = (Property)
+ Proxy.newProxyInstance(Wildcard.class.getClassLoader(),
+ new Class<?>[] { Wildcard.class },
+ new WildcardInvocationHandler());
+ break;
+ case OslcSelectParser.PREFIXED_NAME:
+ property = (Property)
+ Proxy.newProxyInstance(Identifier.class.getClassLoader(),
+ new Class<?>[] { Identifier.class },
+ new PropertyInvocationHandler(
+ (CommonTree)treeChild.getChild(0),
+ Type.IDENTIFIER, prefixMap, false));
+ break;
+ default:
+ case OslcSelectParser.NESTED_PROPERTIES:
+ property = (Property)
+ Proxy.newProxyInstance(NestedProperty.class.getClassLoader(),
+ new Class<?>[] { NestedProperty.class },
+ new NestedPropertyInvocationHandler(treeChild,
+ prefixMap));
+ break;
+ }
+
+ children.add(property);
+ }
+
+ children = Collections.unmodifiableList(children);
+
+ return children;
+ }
+
+ /**
+ * Generate string representation of a children property list
+ *
+ * @param buffer
+ * @param children
+ *
+ * @return the buffer representation of the property list
+ */
+ static StringBuffer
+ childrenToString(
+ StringBuffer buffer,
+ List<Property> children
+ )
+ {
+ boolean first = true;
+
+ for (Property property : children) {
+
+ if (first) {
+ first = false;
+ } else {
+ buffer.append(',');
+ }
+
+ buffer.append(property.toString());
+ }
+
+ return buffer;
}
- private final Type type;
+ private final CommonTree tree;
+ protected final Map<String, String> prefixMap;
+ private List<Property> children = null;
}
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertyInvocationHandler.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertyInvocationHandler.java
index 0743673..c42cace 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertyInvocationHandler.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertyInvocationHandler.java
@@ -33,12 +33,14 @@ class PropertyInvocationHandler implements InvocationHandler
PropertyInvocationHandler(
CommonTree tree,
Type type,
- Map<String, String> prefixMap
+ Map<String, String> prefixMap,
+ boolean isWildcard
)
{
this.tree = tree;
this.type = type;
this.prefixMap = prefixMap;
+ this.isWildcard = isWildcard;
}
/**
@@ -51,11 +53,23 @@ class PropertyInvocationHandler implements InvocationHandler
Object[] args
) throws Throwable
{
- if (method.getName().equals("type")) {
+ String methodName = method.getName();
+
+ if (methodName.equals("type")) {
return type;
}
- if (identifier != null) {
+ if (methodName.equals("isWildcard")) {
+ return isWildcard;
+ }
+
+ boolean isIdentifier = methodName.equals("identifier");
+
+ if (isIdentifier && isWildcard) {
+ throw new IllegalStateException("wildcard has no identifier");
+ }
+
+ if (isIdentifier && identifier != null) {
return identifier;
}
@@ -75,11 +89,16 @@ class PropertyInvocationHandler implements InvocationHandler
identifier.local = rawIdentifier.substring(colon + 1);
}
- return identifier;
+ if (isIdentifier) {
+ return identifier;
+ }
+
+ return identifier.toString();
}
private final CommonTree tree;
private final Type type;
protected final Map<String, String> prefixMap;
+ private final Boolean isWildcard;
private PName identifier = null;
}
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertyListInvocationHandler.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertyListInvocationHandler.java
deleted file mode 100644
index 36c0806..0000000
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/PropertyListInvocationHandler.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 IBM Corporation.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
- *
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *
- * Steve Pitschke - initial API and implementation
- *******************************************************************************/
-package org.eclipse.lyo.core.query.impl;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.antlr.runtime.tree.CommonTree;
-import org.eclipse.lyo.core.query.Identifier;
-import org.eclipse.lyo.core.query.NestedProperty;
-import org.eclipse.lyo.core.query.OslcSelectParser;
-import org.eclipse.lyo.core.query.Properties.Type;
-import org.eclipse.lyo.core.query.Property;
-
-/**
- * Proxy implementation of {@link PropertyList} interface
- */
-public class PropertyListInvocationHandler extends PropertiesInvocationHandler
-{
- public
- PropertyListInvocationHandler(
- CommonTree tree,
- Map<String, String> prefixMap
- )
- {
- super(Type.PROPERTY_LIST);
-
- this.tree = tree;
- this.prefixMap = prefixMap;
- }
-
- /**
- * @see PropertiesInvocationHandler#invoke(Object, Method, Object[])
- */
- @Override
- public Object invoke(
- Object proxy,
- Method method,
- Object[] args
- ) throws Throwable
- {
- String methodName = method.getName();
- boolean isChildren = methodName.equals("children");
-
- if (! isChildren &&
- ! methodName.equals("toString")) {
- return super.invoke(proxy, method, args);
- }
-
- if (isChildren && children != null) {
- return children;
- }
-
- @SuppressWarnings("unchecked")
- List<CommonTree> treeChildren = tree.getChildren();
-
- children = new ArrayList<Property>(treeChildren.size());
-
- for (CommonTree treeChild : treeChildren) {
-
- Property property;
-
- switch (treeChild.getType())
- {
- case OslcSelectParser.PREFIXED_NAME:
- property = (Property)
- Proxy.newProxyInstance(Identifier.class.getClassLoader(),
- new Class<?>[] { Identifier.class },
- new IndentifierInvocationHandler(
- (CommonTree)treeChild.getChild(0),
- prefixMap));
- break;
- default:
- case OslcSelectParser.NESTED_PROPERTIES:
- property = (Property)
- Proxy.newProxyInstance(NestedProperty.class.getClassLoader(),
- new Class<?>[] { NestedProperty.class },
- new NestedPropertyInvocationHandler(treeChild,
- prefixMap));
- break;
- }
-
- children.add(property);
- }
-
- children = Collections.unmodifiableList(children);
-
- if (isChildren) {
- return children;
- }
-
- boolean first = true;
- StringBuffer buffer = new StringBuffer();
-
- for (Property property : children) {
-
- if (first) {
- first = false;
- } else {
- buffer.append(',');
- }
-
- buffer.append(property.toString());
- }
-
- return buffer.toString();
- }
-
- private final CommonTree tree;
- private Map<String, String> prefixMap;
- private List<Property> children = null;
-}
- \ No newline at end of file
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/SimpleSortTermInvocationHandler.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/SimpleSortTermInvocationHandler.java
index 43a031b..1306828 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/SimpleSortTermInvocationHandler.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/SimpleSortTermInvocationHandler.java
@@ -19,7 +19,6 @@ import java.lang.reflect.Method;
import java.util.Map;
import org.antlr.runtime.tree.CommonTree;
-import org.eclipse.lyo.core.query.OslcOrderByLexer;
import org.eclipse.lyo.core.query.SimpleSortTerm;
import org.eclipse.lyo.core.query.SortTerm.Type;
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/StringValueInvocationHandler.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/StringValueInvocationHandler.java
index de34926..a75b3b4 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/StringValueInvocationHandler.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/StringValueInvocationHandler.java
@@ -49,7 +49,7 @@ class StringValueInvocationHandler extends ValueInvocationHandler
if (! isValue &&
! methodName.equals("toString")) {
- super.invoke(proxy, method, args);
+ return super.invoke(proxy, method, args);
}
if (value == null) {
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/TypedValueInvocationHandler.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/TypedValueInvocationHandler.java
index c4aa1e8..823d762 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/TypedValueInvocationHandler.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/TypedValueInvocationHandler.java
@@ -57,7 +57,7 @@ class TypedValueInvocationHandler extends ValueInvocationHandler
if (! isValue &&
! methodName.equals("prefixedName") &&
! methodName.equals("toString")) {
- super.invoke(proxy, method, args);
+ return super.invoke(proxy, method, args);
}
if (isValue) {
diff --git a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/WildcardInvocationHandler.java b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/WildcardInvocationHandler.java
index de6f9c1..700753e 100644
--- a/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/WildcardInvocationHandler.java
+++ b/org.eclipse.lyo.core.query/src/main/java/org/eclipse/lyo/core/query/impl/WildcardInvocationHandler.java
@@ -17,17 +17,18 @@ package org.eclipse.lyo.core.query.impl;
import java.lang.reflect.Method;
-import org.eclipse.lyo.core.query.Properties.Type;
+import org.eclipse.lyo.core.query.Property.Type;
+
/**
* Proxy implementation of {@link Wildcard} interface
*/
-public class WildcardInvocationHandler extends PropertiesInvocationHandler
+public class WildcardInvocationHandler extends PropertyInvocationHandler
{
public
WildcardInvocationHandler()
{
- super(Type.WILDCARD);
+ super(null, Type.IDENTIFIER, null, true);
}
/**
diff --git a/org.eclipse.lyo.core.query/src/test/java/org/eclipse/lyo/core/query/test/BasicSelectTest.java b/org.eclipse.lyo.core.query/src/test/java/org/eclipse/lyo/core/query/test/BasicSelectTest.java
index 4f18139..d7ababd 100644
--- a/org.eclipse.lyo.core.query/src/test/java/org/eclipse/lyo/core/query/test/BasicSelectTest.java
+++ b/org.eclipse.lyo.core.query/src/test/java/org/eclipse/lyo/core/query/test/BasicSelectTest.java
@@ -32,11 +32,14 @@ public class BasicSelectTest
"olsc=<http://open-services.net/ns/core#>";
String[] expressions = {
+ "*{*}",
"qm:testcase",
"*",
"oslc:create,qm:verified",
"qm:state{oslc:verified_by{oslc:owner,qm:duration}}",
"qm:submitted{*}",
+ "qm:testcase,*",
+ "*,qm:state{*}",
"XXX"
};