You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by rw...@apache.org on 2011/02/12 10:04:35 UTC

svn commit: r1070047 - in /incubator/stanbol/trunk/entityhub: ./ jersey/src/main/java/org/apache/stanbol/entityhub/jersey/parsers/ jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/ jersey/src/main/java/org/apache/stanbol/entityhub/jers...

Author: rwesten
Date: Sat Feb 12 09:04:35 2011
New Revision: 1070047

URL: http://svn.apache.org/viewvc?rev=1070047&view=rev
Log:
Fixes STANBOL-81 and STANBOL-80: 
Added Support for 
 - the field property for /find request
 - /query requests that allow to parsed JSON serialised FieldQuery requests
 see the updated README.TXT for details
 
 In addition the SolrYard now also replaces ' ' with '+' for Wildcard constraints (this brings it in line with a similar change for Equals requests.  

Added:
    incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/parsers/JSONToFieldQuery.java   (with props)
Modified:
    incubator/stanbol/trunk/entityhub/README.TXT
    incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/ReferencedSiteRootResource.java
    incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/SiteManagerRootResource.java
    incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/SymbolResource.java
    incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/writers/FieldQueryToJSON.java
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/constraintEncoders/WildcardEncoder.java

Modified: incubator/stanbol/trunk/entityhub/README.TXT
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/README.TXT?rev=1070047&r1=1070046&r2=1070047&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/README.TXT (original)
+++ incubator/stanbol/trunk/entityhub/README.TXT Sat Feb 12 09:04:35 2011
@@ -183,10 +183,12 @@ Example:
     /sites/find?name={query}
 
 Request: 
-    GET /sites/find?name={query}&lang={lang}&limit={limit}&offset={offset}
-    POST -d "name={query}&lang={lang}&limit={limit}&offset={offset}" /sites/find
+    GET /sites/find?name={query}&field={field}&lang={lang}&limit={limit}&offset={offset}
+    POST -d "name={query}&field={field}&lang={lang}&limit={limit}&offset={offset}" /sites/find
 Parameter:
     name: the name of the entity (supports wildcards e.g. "Frankf*")
+    field: the name of the field used for the query. One MUST parse the full
+           name. Namespace prefixes are not supported yet. (default is rdfs:label)
     lang: optionally the language of the parsed name can be defined
     limit: optionally the maximum number of results
     offset: optionally the offset of first result
@@ -196,6 +198,28 @@ Example:
    curl -X POST -d "name=Bischofsh*&lang=de&limit=10&offset=0" http://localhost:8080/entityhub/sites/find
 
 
+    /sites/query&query={query}
+
+Allows to parse JSON serialzed FieldQueries to the sites endpoint.
+
+Request:
+    POST -d "query={query}" /sites/query
+Parameter:
+    query: the JSON serialized FieldQuery (see section "FieldQuery JSON format" 
+           below)
+Example:
+   curl -X POST -F "query=@fieldQuery.json" http://localhost:8080/entityhub/site/dbPedia/query
+Note: that "@fieldQuery.json" links to a local file that contains the parsed
+    Fieldquery (see ection "FieldQuery JSON format" for examples)
+Note: This method suffers form very bad performance on SPARQL Endpoints that do 
+    not support extensions for full text searches. On Virtuoso Endpoints do 
+    performance well under normal conditions
+Note: Optional selects suffers form very bad performance on any SPRQL Endpoint.
+    It is recommended to select only fields that are used for constraints. If
+    more data are required it is recommended to dereference found entities after
+    recieving initial results of the query.
+
+
 SITE Service Endpoint "/site/{siteID}"
 --------------------------------------------
 
@@ -218,11 +242,13 @@ Example
     /site/{site}/find?name={name}
 
 Request:
-    GET /site/{site}/find?name={name}&lang={lang}&limit={limit}&offset={offset}
-    POST -d "name={query}&lang={lang}&limit={limit}&offset={offset}" /site/{site}/find
+    GET /site/{site}/find?name={name}&field={field}&lang={lang}&limit={limit}&offset={offset}
+    POST -d "name={query}&field={field}&lang={lang}&limit={limit}&offset={offset}" /site/{site}/find
 Parameter:
     site: is the ID configured for the referenced site (e.g. "dbPedia")
     name: the name of the entity (supports wildcards e.g. "Frankf*")
+    field: the name of the field used for the query. One MUST parse the full
+           name. Namespace prefixes are not supported yet. (default is rdfs:label)
     lang: optionally the language of the parsed name can be defined
     limit: optionally the maximum number of results
     offset: optionally the offset of first result
@@ -233,6 +259,29 @@ Example:
    curl -X POST -d "name=Frankf*&lang=de&limit=10&offset=0" http://localhost:8080/entityhub/site/dbPedia/find
 
 
+    /site/{site}/query&query={query}
+
+Allows to parse JSON serialzed FieldQueries to the site endpoint.
+
+Request:
+    POST -d "query={query}" /site/{site}/query
+Parameter:
+    site: is the ID configured for the referenced site (e.g. "dbPedia")
+    query: the JSON serialized FieldQuery (see section "FieldQuery JSON format" 
+           below)
+Example:
+   curl -X POST -F "query=@fieldQuery.json" http://localhost:8080/entityhub/site/dbPedia/query
+Note: that "@fieldQuery.json" links to a local file that contains the parsed
+    Fieldquery (see ection "FieldQuery JSON format" for examples)
+Note: This method suffers form very bad performance on SPARQL Endpoints that do 
+    not support extensions for full text searches. On Virtuoso Endpoints do 
+    performance well under normal conditions
+Note: Optional selects suffers form very bad performance on any SPRQL Endpoint.
+    It is recommended to select only fields that are used for constraints. If
+    more data are required it is recommended to dereference found entities after
+    recieving initial results of the query.
+
+
 Entityhub Endpoint ("/symbol" and "/mapping")
 --------------------------------------------
 
@@ -299,6 +348,40 @@ In this case a new Symbol and EntityMapp
 created if not already present in the Apache Stanbol Entityhub.
 
 
+    /symbol/find&name={name}
+
+Finds Symbols (Entities managed by the Entityhub) based on the parsed arguments
+
+Request:
+    GET /symbol/find?name={name}&field={field}&lang={lang}&limit={limit}&offset={offset}
+    POST -d "name={query}&field={field}&lang={lang}&limit={limit}&offset={offset}" /symbol/find
+Parameter:
+    name: the name of the entity (supports wildcards e.g. "Frankf*")
+    field: the name of the field used for the query. One MUST parse the full
+           name. Namespace prefixes are not supported yet. The default is the 
+           symbol name (http://www.iks-project.eu/ontology/rick/model/name)
+    lang: optionally the language of the parsed name can be defined
+    limit: optionally the maximum number of results
+    offset: optionally the offset of first result
+Example:
+   curl -X POST -d "name=Frankf*&lang=de&limit=10&offset=0" http://localhost:8080/entityhub/symbol/find
+
+
+    /symbol/query&query={query}
+
+Allows to parse JSON serialzed FieldQueries to the Symbol endpoint.
+
+Request:
+    POST -d "query={query}" /symbol/query
+Parameter:
+    query: the JSON serialized FieldQuery (see section "FieldQuery JSON format" 
+           below)
+Example:
+   curl -X POST -F "query=@fieldQuery.json" http://localhost:8080/entityhub/symbol/query
+Note that "@fieldQuery.json" links to a local file that contains the parsed
+Fieldquery (see ection "FieldQuery JSON format" for examples)
+    
+    
     /mapping?id={uri}
 
 Request: GET /mapping?id={uri}
@@ -407,3 +490,105 @@ Response:
 
 Note that the response contains a Json Object with the key "results" as root 
 that has a Json Array containing all EntityMappings for the parsed Symbol.
+
+
+FieldQuery JSON format
+----------------------
+
+The FieldQuery is part of the java API defined in the bundle 
+    org.apache.stanbol.entityhub.servicesapi
+see http://svn.apache.org/repos/asf/incubator/stanbol/trunk/entityhub/generic/servicesapi/src/main/java/org/apache/stanbol/entityhub/servicesapi/query/FieldQuery.java
+
+To enable to parse FieldQueries also via the RESTful interface of the Entityhub
+a JSON serilisazion for queries defined by this this interface is used.
+This section describes this interface and provides some examples
+
+Note that the FieldQuery as used for the Query is included in the Response.
+
+Root Element Keys: 
+
+    "selected": json array with the name of the fields selected by this query 
+    "offset": the offset of the first result returned by this query 
+    "limit": the maximum number of results returned 
+    "constraints": json array holding all the constraints of the query 
+
+Example:
+{
+    "selected": [ 
+        "http:\/\/www.w3.org\/2000\/01\/rdf-schema#label", 
+        "http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#type"], 
+    "offset": "0", 
+    "limit": "3", 
+    "constraints": [...]
+}
+
+Constraints:
+
+Constraints are always applied to a field. Currently the implementation is
+limited to a single constraint/field. This is an limitation of the implementation
+and not a theoretical one.
+There are 3+1 different constraint types.
+The three main types are
+ - ValueConstraint: Checks if the value of the field is equals to the parsed
+    value and data type
+ - TextConstraint: Checks if the value of the field is equals to the parsed
+    value, language. It supports also wildcard and regex searches.
+ - RangeConstraint: Checks if the value of the field is within the parsed range
+ - ReferenceConstraint: A special form of the ValueConstraint that defaults the
+    data type to references (links to other entities)
+      
+Keys required by all Constraint types:
+ - field: the field to apply the constraint 
+ - type: the type of the constraint. One of "reference", "value", "text" or "range" 
+
+Reference Constraint keys: 
+ - value: the value (usually an URI) (required) 
+Example:
+Search for instances of the type Place as defined in the dbPedia ontology
+    { 
+        "type": "reference", 
+        "field": "http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#type", 
+        "value": "http:\/\/dbpedia.org\/ontology\/Place", 
+    } 
+
+Value Constraint keys 
+ - value: the value (required)
+ - dataTypes: json array with the data types of the value (by default the 
+     dataType is defined by the type of the parsed value) 
+Example:
+Search for entities with the rdfs:label "Paris". (Note: one could also use a
+TextConstraint for this
+    { 
+        "type": "value", 
+        "field": "http:\/\/www.w3.org\/2000\/01\/rdf-schema#label", 
+        "value": "Paris", 
+    } 
+
+Text Constraint: 
+ - text: the text to search (required)
+ - languages: json array with the languages to search (default is all languages) 
+ - patternType: one of "wildcard", "regex" or "none" (default is "none") 
+ - caseSensitive: boolean (default is "false") 
+Example:
+Searches for entities with an german rdfs:label starting with "Frankf"
+    { 
+       "type": "text", 
+       "languages": ["de"], 
+       "patternType": "wildcard", 
+       "text": "Frankf*", 
+       "field": "http:\/\/www.w3.org\/2000\/01\/rdf-schema#label" 
+    }, 
+
+Range Constraint: 
+ - lowerBound: The lower bound of the range (one of lower and upper bound MUST BE defined) 
+ - upperBound: The upper bound of the range (one of lower and upper bound MUST BE defined) 
+ - inclusive: used for both upper and lower bound (default is "false") 
+Example:
+Searches for entities with a population over 1 million. Note that the data type
+is automatically detected based on the parsed value (integer in that case)
+    { 
+        "type": "range", 
+        "field": "http:\/\/dbpedia.org\/ontology\/populationTotal", 
+        "lowerBound": 1000000, 
+        "inclusive": true, 
+    }

Added: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/parsers/JSONToFieldQuery.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/parsers/JSONToFieldQuery.java?rev=1070047&view=auto
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/parsers/JSONToFieldQuery.java (added)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/parsers/JSONToFieldQuery.java Sat Feb 12 09:04:35 2011
@@ -0,0 +1,247 @@
+package org.apache.stanbol.entityhub.jersey.parsers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.stanbol.entityhub.core.query.DefaultQueryFactory;
+import org.apache.stanbol.entityhub.servicesapi.query.Constraint;
+import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
+import org.apache.stanbol.entityhub.servicesapi.query.RangeConstraint;
+import org.apache.stanbol.entityhub.servicesapi.query.ReferenceConstraint;
+import org.apache.stanbol.entityhub.servicesapi.query.TextConstraint;
+import org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint;
+import org.apache.stanbol.entityhub.servicesapi.query.Constraint.ConstraintType;
+import org.apache.stanbol.entityhub.servicesapi.query.TextConstraint.PatternType;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Parses a FieldQuery from its JSON representation.
+ * @author Rupert Westenthaler
+ *
+ */
+public class JSONToFieldQuery {
+    private static final Logger log = LoggerFactory.getLogger(JSONToFieldQuery.class);
+    
+    public static FieldQuery fromJSON(String jsonQueryString) throws JSONException{
+        if(jsonQueryString == null){
+            throw new NullPointerException("The parsed JSON object MUST NOT be NULL!");
+        }
+        JSONObject jQuery = new JSONObject(jsonQueryString);
+        FieldQuery query = DefaultQueryFactory.getInstance().createFieldQuery();
+        if(!jQuery.has("constraints")){
+            throw new IllegalArgumentException("The parsed JSON object MUST contain the required key \"constraints\"");
+        }
+        JSONArray constraints = jQuery.getJSONArray("constraints");
+        for(int i=0;i<constraints.length();i++){
+            JSONObject jConstraint = constraints.getJSONObject(i);
+            if(jConstraint.has("field")){
+                String field = jConstraint.getString("field");
+                //check if there is already a constraint for that field
+                if(field == null || field.isEmpty()){
+                    log.warn("The value of the key \"field\" MUST NOT be NULL nor emtpy!");
+                    log.warn(String.format("Constraint:\n %s",jConstraint.toString(4)));
+                } else if(query.isConstraint(field)){
+                    log.warn(String.format("Multiple constraints for field %s in parsed FieldQuery!",field));
+                    log.warn(String.format(" - all Constraints:\n", constraints.toString(4)));
+                    log.warn(String.format(" - ignore Constraint:\n %s",jConstraint.toString(4)));
+                } else {
+                    Constraint constraint = parseConstraint(jConstraint);
+                    if(constraint != null){
+                        query.setConstraint(field, parseConstraint(jConstraint));
+                    } else { 
+                        // log unparseable constraint (specific warning already
+                        // given by the parseConstraint method
+                        log.warn(String.format(" - ignore Constraint:\n %s",jConstraint.toString(4)));
+                    }
+                }
+            } else { //no field defined -> ignroe and write warning!
+                log.warn("Earch Constraint of a FieldQuery MUST define the key \"field\"!");
+                log.warn(String.format("Constraint:\n %s",jConstraint.toString(4)));
+            }
+        }
+        //parse selected fields
+        JSONArray selected = jQuery.optJSONArray("selected");
+        if(selected != null){
+            for(int i=0;i<selected.length();i++){
+                String selectedField = selected.getString(i);
+                if(selectedField != null && !selectedField.isEmpty()){
+                    query.addSelectedField(selectedField);
+                }
+            }
+        } //else no selected fields -> funny but maybe someone do need only the ids
+        //parse limit and offset
+        if(jQuery.has("limit") && !jQuery.isNull("limit")){
+            query.setLimit(jQuery.getInt("limit"));
+        }
+        if(jQuery.has("offset") && !jQuery.isNull("offset")){
+            query.setOffset(jQuery.getInt("offset"));
+        }
+        return query;
+    }
+
+    private static Constraint parseConstraint(JSONObject jConstraint) throws JSONException {
+        if(jConstraint.has("type") && !jConstraint.isNull("type")) {
+            String type = jConstraint.getString("type");
+            //Event that internally "reference" is not part of the
+            //ConstraintType enum it is still present in the serialisation
+            //ant the Java API (see ReferenceConstraint class)
+            //Value constraints with the dataType Reference and AnyURI are
+            //considered to represent reference constraints
+            if(type.equals("reference")){
+                return parseReferenceConstraint(jConstraint);
+            } else if (type.equals(ConstraintType.value.name())){
+                return parseValueConstraint(jConstraint);
+            } else if (type.equals(ConstraintType.text.name())){
+                return parseTextConstraint(jConstraint);
+            } else if (type.equals(ConstraintType.range.name())){
+                return parseRangeConstraint(jConstraint);
+            } else {
+                log.warn(String.format("Unknown Constraint Type %s. Supported values are %s",               
+                    Arrays.asList("reference",ConstraintType.values())));
+                return null;
+            }
+        } else {
+            log.warn(String.format("Earch Constraint MUST HAVE the \"type\" key set to one of the values %s",
+                Arrays.asList("reference",ConstraintType.values())));
+            return null;
+        }
+    }
+
+    /**
+     * @param jConstraint
+     * @return
+     * @throws JSONException
+     */
+    private static Constraint parseRangeConstraint(JSONObject jConstraint) throws JSONException {
+        Constraint constraint;
+        boolean inclusive;
+        if(jConstraint.has("inclusive")){
+            inclusive = jConstraint.getBoolean("inclusive");
+        } else {
+            log.info("RangeConstraint does not define the field \"inclusive\". Use false as default!");
+            inclusive = false;
+        }
+        Object upperBound = jConstraint.opt("upperBound");
+        Object lowerBound = jConstraint.opt("lowerBound");
+        if(upperBound == null && lowerBound == null){
+            log.warn("Range Constraint does not define an \"upperBound\" nor an \"lowerBound\"! At least MUST BE parsed for a valid RangeConstraint.");
+            constraint = null;
+        } else {
+            constraint = new RangeConstraint(lowerBound, upperBound, inclusive);
+        }
+        return constraint;
+    }
+
+    /**
+     * @param jConstraint
+     * @return
+     * @throws JSONException
+     */
+    private static Constraint parseTextConstraint(JSONObject jConstraint) throws JSONException {
+        Constraint constraint;
+        boolean caseSensitive = jConstraint.optBoolean("caseSensitive", false);
+        //parse patternType
+        PatternType patternType;
+        String jPatternType = jConstraint.optString("patternType");
+        if(jPatternType == null){
+            patternType = PatternType.none;
+        } else {
+            try {
+                patternType = PatternType.valueOf(jPatternType);
+            } catch (IllegalArgumentException e) {
+                log.warn(String.format("Encountered unknown patternType for TextConstraint! Will use default value %s (allowed values are: %s)",
+                    jPatternType,PatternType.none,Arrays.toString(PatternType.values())));
+                patternType = PatternType.none;
+            }
+        }
+        //parse languages
+        Collection<String> languages;
+        JSONArray jLanguages = jConstraint.optJSONArray("languages");
+        if(jLanguages != null && jLanguages.length()>0){
+            languages = new ArrayList<String>(jLanguages.length());
+            for(int i=0;i<jLanguages.length();i++){
+                String lang = jLanguages.getString(i);
+                if(lang != null && !lang.isEmpty()){
+                    languages.add(lang);
+                }
+            }
+            if(languages.isEmpty()){
+                languages = null; //if no one was successfully added set the list back to null
+            }
+        } else {
+            languages = null;
+        }
+        //parse text and create constraint
+        if(jConstraint.has("text") && !jConstraint.isNull("text")){
+            constraint = new TextConstraint(jConstraint.getString("text"),
+                patternType,caseSensitive,
+                languages == null?null:languages.toArray(new String[languages.size()]));
+        } else {
+            log.warn("Parsed TextConstraint doese not define the required field \"text\"!");
+            constraint = null;
+        }
+        
+        TextConstraint textConstraint = (TextConstraint) constraint;
+        if (textConstraint.getLanguages() != null && !textConstraint.getLanguages().isEmpty()) {
+            jConstraint.put("languages", new JSONArray(textConstraint.getLanguages()));
+        }
+        jConstraint.put("patternType", textConstraint.getPatternType().name());
+        if (textConstraint.getText() != null && !textConstraint.getText().isEmpty()) {
+            jConstraint.put("text", textConstraint.getText());
+        }
+        return constraint;
+    }
+
+    /**
+     * @param jConstraint
+     * @return
+     * @throws JSONException
+     */
+    private static Constraint parseValueConstraint(JSONObject jConstraint) throws JSONException {
+        Constraint constraint;
+        Collection<String> dataTypes;
+        JSONArray jDataTypes = jConstraint.optJSONArray("dataTypes");
+        if(jDataTypes != null && jDataTypes.length()>0){
+            dataTypes = new ArrayList<String>(jDataTypes.length());
+            for(int i=0;i<jDataTypes.length();i++){
+                String dataType = jDataTypes.getString(i);
+                if(dataType != null && !dataType.isEmpty()){
+                    dataTypes.add(dataType);
+                }
+            }
+            if(dataTypes.isEmpty()){
+                dataTypes = null; //if no one was successfully added set the list back to null
+            }
+        } else {
+            dataTypes = null;
+        }
+        if(jConstraint.has("value") && !jConstraint.isNull("value")){
+            constraint = new ValueConstraint(jConstraint.get("value"), dataTypes);
+        } else {
+            log.warn("Parsed ValueConstraint doese not define the required field \"value\"!");
+            constraint = null;
+        }
+        return constraint;
+    }
+
+    /**
+     * @param jConstraint
+     * @return
+     * @throws JSONException
+     */
+    private static Constraint parseReferenceConstraint(JSONObject jConstraint) throws JSONException {
+        Constraint constraint;
+        if(jConstraint.has("value") && !jConstraint.isNull("value")){
+            constraint = new ReferenceConstraint(jConstraint.getString("value"));
+        } else {
+            log.warn("Parsed ValueConstraint doese not define the required field \"value\"!");
+            constraint = null;
+        }
+        return constraint;
+    }
+}

Propchange: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/parsers/JSONToFieldQuery.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/ReferencedSiteRootResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/ReferencedSiteRootResource.java?rev=1070047&r1=1070046&r2=1070047&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/ReferencedSiteRootResource.java (original)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/ReferencedSiteRootResource.java Sat Feb 12 09:04:35 2011
@@ -1,5 +1,10 @@
 package org.apache.stanbol.entityhub.jersey.resource;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED;
+import static javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA;
+
+import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -7,6 +12,7 @@ import java.util.Set;
 import java.util.TreeSet;
 
 import javax.servlet.ServletContext;
+import javax.ws.rs.Consumes;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.FormParam;
 import javax.ws.rs.GET;
@@ -24,7 +30,9 @@ import javax.ws.rs.core.Response;
 import org.apache.clerezza.rdf.core.serializedform.Serializer;
 import org.apache.clerezza.rdf.core.serializedform.SupportedFormat;
 import org.apache.clerezza.rdf.ontologies.RDFS;
+import org.apache.commons.io.FileUtils;
 import org.apache.stanbol.entityhub.core.query.FieldQueryImpl;
+import org.apache.stanbol.entityhub.jersey.parsers.JSONToFieldQuery;
 import org.apache.stanbol.entityhub.jersey.utils.JerseyUtils;
 import org.apache.stanbol.entityhub.servicesapi.model.Sign;
 import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
@@ -34,6 +42,7 @@ import org.apache.stanbol.entityhub.serv
 import org.apache.stanbol.entityhub.servicesapi.site.ReferencedSite;
 import org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteException;
 import org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteManager;
+import org.codehaus.jettison.json.JSONException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -52,7 +61,9 @@ public class ReferencedSiteRootResource 
 
     /**
      * The Field used for find requests if not specified
-     * TODO: Make configurable via the {@link ConfiguredSite} interface!
+     * TODO: This will be replaced by the EntitySearch. With this search the
+     *       Site is responsible to decide what properties to use for label
+     *       based searches.
      */
     private static final String DEFAULT_FIND_FIELD = RDFS.label.getUnicodeString();
     /**
@@ -140,17 +151,17 @@ public class ReferencedSiteRootResource 
     @GET
     @Path("/find")
     public Response findEntitybyGet(@QueryParam(value = "name") String name,
-            //@QueryParam(value="field") String field,
+            @QueryParam(value="field") String field,
             @QueryParam(value = "lang") String language,
             //@QueryParam(value="select") String select,
             @QueryParam(value = "limit") @DefaultValue(value = "-1") int limit, @QueryParam(value = "offset") @DefaultValue(value = "0") int offset, @Context HttpHeaders headers) {
-        return findEntity(name, language, limit, offset, headers);
+        return findEntity(name, field,language, limit, offset, headers);
     }
 
     @POST
     @Path("/find")
     public Response findEntity(@FormParam(value = "name") String name,
-            //@FormParam(value="field") String field,
+            @FormParam(value="field") String field,
             @FormParam(value = "lang") String language,
             //@FormParam(value="select") String select,
             @FormParam(value = "limit") @DefaultValue(value = "-1") int limit, @FormParam(value = "offset") @DefaultValue(value = "0") int offset, @Context HttpHeaders headers) {
@@ -160,10 +171,19 @@ public class ReferencedSiteRootResource 
         log.info("  > limit : " + limit);
         log.info("  > offset: " + offset);
         log.info("  > accept: " + headers.getAcceptableMediaTypes());
-        if (name == null || name.isEmpty()) {
+        if (name == null || name.trim().isEmpty()) {
             log.error("/find Request with invalied name={}!", name);
+        } else {
+            name = name.trim();
+        }
+        if(field == null){
+            field = DEFAULT_FIND_FIELD;
+        } else {
+            field = field.trim();
+            if(field.isEmpty()){
+                field = DEFAULT_FIND_FIELD;
+            }
         }
-        String field = DEFAULT_FIND_FIELD;
         FieldQuery query = new FieldQueryImpl();
         if (language == null) {
             query.setConstraint(field, new TextConstraint(name, PatternType.wildcard, false));
@@ -195,4 +215,64 @@ public class ReferencedSiteRootResource 
             throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
         }
     }
+    /**
+     * Allows to parse any kind of {@link FieldQuery} in its JSON Representation.
+     * Note that the maximum number of results (limit) and the offset of the
+     * first result (offset) are parsed as seperate parameters and are not
+     * part of the field query as in the java API.<p>
+     * TODO: as soon as the entityhub supports multiple query types this need
+     *       to be refactored. The idea is that this dynamically detects query
+     *       types and than redirects them to the referenced site implementation.
+     * @param query The field query in JSON format
+     * @param limit the maximum number of results starting at offset
+     * @param offset the offset of the first result
+     * @param headers the header information of the request
+     * @return the results of the query
+     */
+    @POST
+    @Path("/query")
+    @Consumes( { APPLICATION_FORM_URLENCODED + ";qs=1.0",
+            MULTIPART_FORM_DATA + ";qs=0.9" })
+    public Response queryEntities(
+            @FormParam("query") String query,
+            @FormParam("query") File file,
+            @Context HttpHeaders headers) {
+        if(query == null && file == null) {
+            throw new WebApplicationException(new IllegalArgumentException("Query Requests MUST define the \"query\" parameter"), Response.Status.BAD_REQUEST);
+        }
+        FieldQuery fieldQuery = null;
+        JSONException exception = null;
+        if(query != null){
+            try {
+                fieldQuery = JSONToFieldQuery.fromJSON(query);
+            } catch (JSONException e) {
+                log.warn("unable to parse FieldQuery from \"application/x-www-form-urlencoded\" encoded query string "+query);
+                fieldQuery = null;
+                exception = e;
+            }
+        } //else no query via application/x-www-form-urlencoded parsed
+        if(fieldQuery == null && file != null){
+            try {
+                query = FileUtils.readFileToString(file);
+                fieldQuery = JSONToFieldQuery.fromJSON(query);
+            } catch (IOException e) {
+                throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
+            } catch (JSONException e) {
+                log.warn("unable to parse FieldQuery from \"multipart/form-data\" encoded query string "+query);
+                exception = e;
+            }
+        }//fieldquery already initialised or no query via multipart/form-data parsed
+        if(fieldQuery == null){
+            throw new WebApplicationException(new IllegalArgumentException("Unable to parse FieldQuery for the parsed query\n"+query, exception),Response.Status.BAD_REQUEST);
+        }
+        final MediaType acceptedMediaType = JerseyUtils.getAcceptableMediaType(headers, MediaType.APPLICATION_JSON_TYPE);
+        try {
+            return Response.ok(site.find(fieldQuery), acceptedMediaType).build();
+        } catch (ReferencedSiteException e) {
+            log.error("ReferencedSiteException while accessing Site " + site.getName() + " (id=" + site.getId() + ")", e);
+            throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
+        }
+        
+    }
+
 }

Modified: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/SiteManagerRootResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/SiteManagerRootResource.java?rev=1070047&r1=1070046&r2=1070047&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/SiteManagerRootResource.java (original)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/SiteManagerRootResource.java Sat Feb 12 09:04:35 2011
@@ -1,7 +1,9 @@
 package org.apache.stanbol.entityhub.jersey.resource;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA;
 import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
 import static javax.ws.rs.core.Response.Status.NOT_FOUND;
 import static org.apache.clerezza.rdf.core.serializedform.SupportedFormat.N3;
@@ -11,6 +13,8 @@ import static org.apache.clerezza.rdf.co
 import static org.apache.clerezza.rdf.core.serializedform.SupportedFormat.TURTLE;
 import static org.apache.clerezza.rdf.core.serializedform.SupportedFormat.X_TURTLE;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -18,6 +22,7 @@ import java.util.Set;
 import java.util.TreeSet;
 
 import javax.servlet.ServletContext;
+import javax.ws.rs.Consumes;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.FormParam;
 import javax.ws.rs.GET;
@@ -34,7 +39,9 @@ import javax.ws.rs.core.UriInfo;
 
 import org.apache.clerezza.rdf.core.serializedform.Serializer;
 import org.apache.clerezza.rdf.ontologies.RDFS;
+import org.apache.commons.io.FileUtils;
 import org.apache.stanbol.entityhub.core.query.FieldQueryImpl;
+import org.apache.stanbol.entityhub.jersey.parsers.JSONToFieldQuery;
 import org.apache.stanbol.entityhub.jersey.utils.JerseyUtils;
 import org.apache.stanbol.entityhub.servicesapi.model.Sign;
 import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
@@ -42,6 +49,7 @@ import org.apache.stanbol.entityhub.serv
 import org.apache.stanbol.entityhub.servicesapi.query.TextConstraint.PatternType;
 import org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteManager;
 import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -143,19 +151,19 @@ public class SiteManagerRootResource ext
     @GET
     @Path("/find")
     public Response findEntityfromGet(@QueryParam(value = "name") String name,
-            //@FormParam(value="field") String field,
+            @FormParam(value="field") String field,
             @QueryParam(value = "lang") String language,
             //@FormParam(value="select") String select,
             @QueryParam(value = "limit") @DefaultValue(value = "-1") int limit,
             @QueryParam(value = "offset") @DefaultValue(value = "0") int offset,
             @Context HttpHeaders headers) {
-        return findEntity(name, language, limit, offset, headers);
+        return findEntity(name, field,language, limit, offset, headers);
     }
 
     @POST
     @Path("/find")
     public Response findEntity(@FormParam(value = "name") String name,
-            //@FormParam(value="field") String field,
+            @FormParam(value="field") String field,
             @FormParam(value = "lang") String language,
             //@FormParam(value="select") String select,
             @FormParam(value = "limit") @DefaultValue(value = "-1") int limit,
@@ -167,10 +175,19 @@ public class SiteManagerRootResource ext
         log.info("  > limit : " + limit);
         log.info("  > offset: " + offset);
         log.info("  > accept: " + headers.getAcceptableMediaTypes());
-        if (name == null || name.isEmpty()) {
-            log.error("/find Request with invalid name={}!", name);
+        if (name == null || name.trim().isEmpty()) {
+            log.error("/find Request with invalied name={}!", name);
+        } else {
+            name = name.trim();
+        }
+        if(field == null){
+            field = DEFAULT_FIND_FIELD;
+        } else {
+            field = field.trim();
+            if(field.isEmpty()){
+                field = DEFAULT_FIND_FIELD;
+            }
         }
-        String field = DEFAULT_FIND_FIELD;
         FieldQuery query = new FieldQueryImpl();
         if (language == null) {
             query.setConstraint(field, new TextConstraint(name, PatternType.wildcard, false));
@@ -195,11 +212,60 @@ public class SiteManagerRootResource ext
         query.setLimit(limit);
         query.setOffset(offset);
         final MediaType acceptedMediaType = JerseyUtils.getAcceptableMediaType(headers, APPLICATION_JSON_TYPE);
-//        try {
         return Response.ok(referencedSiteManager.find(query), acceptedMediaType).build();
-//        } catch (IOException e) {
-//            log.error("IOException while accessing Referenced Site Manager",e);
-//            throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
-//        }
     }
+    /**
+     * Allows to parse any kind of {@link FieldQuery} in its JSON Representation.
+     * Note that the maximum number of results (limit) and the offset of the
+     * first result (offset) are parsed as seperate parameters and are not
+     * part of the field query as in the java API.<p>
+     * TODO: as soon as the entityhub supports multiple query types this need
+     *       to be refactored. The idea is that this dynamically detects query
+     *       types and than redirects them to the referenced site implementation.
+     * @param query The field query in JSON format
+     * @param limit the maximum number of results starting at offset
+     * @param offset the offset of the first result
+     * @param headers the header information of the request
+     * @return the results of the query
+     */
+    @POST
+    @Path("/query")
+    @Consumes( { APPLICATION_FORM_URLENCODED + ";qs=1.0",
+            MULTIPART_FORM_DATA + ";qs=0.9" })
+    public Response queryEntities(
+            @FormParam("query") String query,
+            @FormParam("query") File file,
+            @Context HttpHeaders headers) {
+        if(query == null && file == null) {
+            throw new WebApplicationException(new IllegalArgumentException("Query Requests MUST define the \"query\" parameter"), Response.Status.BAD_REQUEST);
+        }
+        FieldQuery fieldQuery = null;
+        JSONException exception = null;
+        if(query != null){
+            try {
+                fieldQuery = JSONToFieldQuery.fromJSON(query);
+            } catch (JSONException e) {
+                log.warn("unable to parse FieldQuery from \"application/x-www-form-urlencoded\" encoded query string "+query);
+                fieldQuery = null;
+                exception = e;
+            }
+        } //else no query via application/x-www-form-urlencoded parsed
+        if(fieldQuery == null && file != null){
+            try {
+                query = FileUtils.readFileToString(file);
+                fieldQuery = JSONToFieldQuery.fromJSON(query);
+            } catch (IOException e) {
+                throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
+            } catch (JSONException e) {
+                log.warn("unable to parse FieldQuery from \"multipart/form-data\" encoded query string "+query);
+                exception = e;
+            }
+        }//fieldquery already initialised or no query via multipart/form-data parsed
+        if(fieldQuery == null){
+            throw new WebApplicationException(new IllegalArgumentException("Unable to parse FieldQuery for the parsed query\n"+query, exception),Response.Status.BAD_REQUEST);
+        }
+        final MediaType acceptedMediaType = JerseyUtils.getAcceptableMediaType(headers, MediaType.APPLICATION_JSON_TYPE);
+        return Response.ok(referencedSiteManager.find(fieldQuery), acceptedMediaType).build();
+    }
+    
 }

Modified: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/SymbolResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/SymbolResource.java?rev=1070047&r1=1070046&r2=1070047&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/SymbolResource.java (original)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/SymbolResource.java Sat Feb 12 09:04:35 2011
@@ -1,7 +1,9 @@
 package org.apache.stanbol.entityhub.jersey.resource;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA;
 import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
 import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
 import static javax.ws.rs.core.Response.Status.NOT_FOUND;
@@ -12,11 +14,14 @@ import static org.apache.clerezza.rdf.co
 import static org.apache.clerezza.rdf.core.serializedform.SupportedFormat.TURTLE;
 import static org.apache.clerezza.rdf.core.serializedform.SupportedFormat.X_TURTLE;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 
 import javax.servlet.ServletContext;
+import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.FormParam;
 import javax.ws.rs.GET;
@@ -33,7 +38,9 @@ import javax.ws.rs.core.Response;
 import org.apache.clerezza.rdf.core.TripleCollection;
 import org.apache.clerezza.rdf.core.access.TcManager;
 import org.apache.clerezza.rdf.core.serializedform.Serializer;
+import org.apache.commons.io.FileUtils;
 import org.apache.stanbol.entityhub.core.query.FieldQueryImpl;
+import org.apache.stanbol.entityhub.jersey.parsers.JSONToFieldQuery;
 import org.apache.stanbol.entityhub.jersey.utils.JerseyUtils;
 import org.apache.stanbol.entityhub.servicesapi.Entityhub;
 import org.apache.stanbol.entityhub.servicesapi.EntityhubException;
@@ -42,6 +49,7 @@ import org.apache.stanbol.entityhub.serv
 import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
 import org.apache.stanbol.entityhub.servicesapi.query.TextConstraint;
 import org.apache.stanbol.entityhub.servicesapi.query.TextConstraint.PatternType;
+import org.codehaus.jettison.json.JSONException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -64,7 +72,6 @@ public class SymbolResource extends Navi
      */
     private static final Collection<? extends String> DEFAULT_FIND_SELECTED_FIELDS = Arrays.asList(RdfResourceEnum.label.getUri(), RdfResourceEnum.description.getUri());
 
-
     private final Logger log = LoggerFactory.getLogger(getClass());
 
     protected Entityhub entityhub;
@@ -139,8 +146,11 @@ public class SymbolResource extends Navi
     @POST
     @Path("/find")
     @Produces({APPLICATION_JSON, RDF_XML, N3, TURTLE, X_TURTLE, RDF_JSON, N_TRIPLE})
-    public Response findEntity(@FormParam(value = "name") String name, @FormParam(value = "field") String field,
-            @FormParam(value = "lang") String language, @FormParam(value = "select") String select, @Context HttpHeaders headers) {
+    public Response findEntity(@FormParam(value = "name") String name, 
+            @FormParam(value = "field") String field,
+            @FormParam(value = "lang") String language, 
+            @FormParam(value = "select") String select, 
+            @Context HttpHeaders headers) {
         log.info("symbol/find Request");
         log.info("  > name  : " + name);
         log.info("  > field : " + field);
@@ -148,11 +158,15 @@ public class SymbolResource extends Navi
         log.info("  > select: " + select);
         log.info("  > accept: " + headers.getAcceptableMediaTypes());
         //TODO: Implement by using EntityQuery as soon as implemented
-        if (name == null || name.isEmpty()) {
+        if (name == null || name.trim().isEmpty()) {
             log.error("/find Request with invalied name={}!", name);
+        } else {
+            name = name.trim();
         }
-        if (field == null || field.isEmpty()) {
+        if (field == null || field.trim().isEmpty()) {
             field = DEFAULT_FIND_FIELD;
+        } else {
+            field = field.trim();
         }
         FieldQuery query = new FieldQueryImpl();
         if (language == null) {
@@ -187,4 +201,64 @@ public class SymbolResource extends Navi
     public Response removeSymbol() {
         return null;
     }
+    /**
+     * Allows to parse any kind of {@link FieldQuery} in its JSON Representation.
+     * Note that the maximum number of results (limit) and the offset of the
+     * first result (offset) are parsed as seperate parameters and are not
+     * part of the field query as in the java API.<p>
+     * TODO: as soon as the entityhub supports multiple query types this need
+     *       to be refactored. The idea is that this dynamically detects query
+     *       types and than redirects them to the referenced site implementation.
+     * @param query The field query in JSON format
+     * @param limit the maximum number of results starting at offset
+     * @param offset the offset of the first result
+     * @param headers the header information of the request
+     * @return the results of the query
+     */
+    @POST
+    @Path("/query")
+    @Consumes( { APPLICATION_FORM_URLENCODED + ";qs=1.0",
+            MULTIPART_FORM_DATA + ";qs=0.9" })
+    public Response queryEntities(
+            @FormParam("query") String query,
+            @FormParam("query") File file,
+            @Context HttpHeaders headers) {
+        if(query == null && file == null) {
+            throw new WebApplicationException(new IllegalArgumentException("Query Requests MUST define the \"query\" parameter"), Response.Status.BAD_REQUEST);
+        }
+        FieldQuery fieldQuery = null;
+        JSONException exception = null;
+        if(query != null){
+            try {
+                fieldQuery = JSONToFieldQuery.fromJSON(query);
+            } catch (JSONException e) {
+                log.warn("unable to parse FieldQuery from \"application/x-www-form-urlencoded\" encoded query string "+query);
+                fieldQuery = null;
+                exception = e;
+            }
+        } //else no query via application/x-www-form-urlencoded parsed
+        if(fieldQuery == null && file != null){
+            try {
+                query = FileUtils.readFileToString(file);
+                fieldQuery = JSONToFieldQuery.fromJSON(query);
+            } catch (IOException e) {
+                throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
+            } catch (JSONException e) {
+                log.warn("unable to parse FieldQuery from \"multipart/form-data\" encoded query string "+query);
+                exception = e;
+            }
+        }//fieldquery already initialised or no query via multipart/form-data parsed
+        if(fieldQuery == null){
+            throw new WebApplicationException(new IllegalArgumentException("Unable to parse FieldQuery for the parsed query\n"+query, exception),Response.Status.BAD_REQUEST);
+        }
+        final MediaType acceptedMediaType = JerseyUtils.getAcceptableMediaType(headers, MediaType.APPLICATION_JSON_TYPE);
+        try {
+            return Response.ok(entityhub.find(fieldQuery), acceptedMediaType).build();
+        } catch (EntityhubException e) {
+            log.error("Exception while performing the parsed query on the EntityHub", e);
+            log.error("Query:\n"+query);
+            throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
+        }
+        
+    }
 }

Modified: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/writers/FieldQueryToJSON.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/writers/FieldQueryToJSON.java?rev=1070047&r1=1070046&r2=1070047&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/writers/FieldQueryToJSON.java (original)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/writers/FieldQueryToJSON.java Sat Feb 12 09:04:35 2011
@@ -1,7 +1,9 @@
 package org.apache.stanbol.entityhub.jersey.writers;
 
+import java.util.Collection;
 import java.util.Map.Entry;
 
+import org.apache.stanbol.entityhub.servicesapi.defaults.DataTypeEnum;
 import org.apache.stanbol.entityhub.servicesapi.query.Constraint;
 import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
 import org.apache.stanbol.entityhub.servicesapi.query.RangeConstraint;
@@ -36,6 +38,12 @@ final class FieldQueryToJSON {
             jFieldConstraint.put("field", fieldConstraint.getKey()); //add the field
             constraints.put(jFieldConstraint); //add fieldConstraint
         }
+        if(query.getLimit() != null){
+            jQuery.put("limit", query.getLimit());
+        }
+        if(query.getOffset() != 0){
+            jQuery.put("offset", query.getOffset());
+        }
         return jQuery;
     }
 
@@ -53,10 +61,23 @@ final class FieldQueryToJSON {
             case value:
                 ValueConstraint valueConstraint = ((ValueConstraint) constraint);
                 if (valueConstraint.getValue() != null) {
-                    jConstraint.put("vakue", valueConstraint.getValue());
+                    jConstraint.put("value", valueConstraint.getValue());
                 }
-                if (valueConstraint.getDataTypes() != null && !valueConstraint.getDataTypes().isEmpty()) {
+                Collection<String> dataTypes = valueConstraint.getDataTypes();
+                if (dataTypes != null && !dataTypes.isEmpty()) {
+                    //in case of type = reference we do not need to add any dataTypes!
                     jConstraint.put("dataTypes", valueConstraint.getDataTypes());
+                    //Event that internally "reference" is not part of the
+                    //ConstraintType enum it is still present in the serialisation
+                    //ant the Java API (see ReferenceConstraint class)
+                    //Value constraints with the dataType Reference and AnyURI are
+                    //considered to represent reference constraints
+                    if(dataTypes.size() == 1 && 
+                            (dataTypes.contains(DataTypeEnum.Reference.getUri()) || 
+                                    dataTypes.contains(DataTypeEnum.AnyUri.getUri()))){
+                        jConstraint.remove("type");
+                        jConstraint.put("type", "reference");
+                    }
                 }
                 break;
             case text:
@@ -68,14 +89,17 @@ final class FieldQueryToJSON {
                 if (textConstraint.getText() != null && !textConstraint.getText().isEmpty()) {
                     jConstraint.put("text", textConstraint.getText());
                 }
+                if(textConstraint.isCaseSensitive()){
+                    jConstraint.put("caseSensitive", true);
+                } //else default is false
                 break;
             case range:
                 RangeConstraint rangeConstraint = (RangeConstraint) constraint;
                 if (rangeConstraint.getLowerBound() != null) {
-                    jConstraint.put("lowerBound", rangeConstraint.getLowerBound().toString());
+                    jConstraint.put("lowerBound", rangeConstraint.getLowerBound());
                 }
                 if (rangeConstraint.getUpperBound() != null) {
-                    jConstraint.put("upperBound", rangeConstraint.getUpperBound().toString());
+                    jConstraint.put("upperBound", rangeConstraint.getUpperBound());
                 }
                 jConstraint.put("inclusive", rangeConstraint.isInclusive());
             default:

Modified: incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/constraintEncoders/WildcardEncoder.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/constraintEncoders/WildcardEncoder.java?rev=1070047&r1=1070046&r2=1070047&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/constraintEncoders/WildcardEncoder.java (original)
+++ incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/constraintEncoders/WildcardEncoder.java Sat Feb 12 09:04:35 2011
@@ -22,7 +22,14 @@ public class WildcardEncoder implements 
             //TODO: Use toLoverCase here, because I had problems with Solr that
             //     Queries where not converted to lower case even that the
             //     LowerCaseFilterFactory was present in the query analyser :(
-            constraint.addEncoded(POS, value.toLowerCase());
+            value = value.toLowerCase();
+            /* NOTE:
+             *   When searching for multiple words we assume that we need to find
+             *   the exact pattern e.g. "best pract*" because of that we replace
+             *   spaces with '+'
+             */
+            value = value.replace(' ', '+');
+            constraint.addEncoded(POS, value);
         }
     }