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 2012/05/03 14:47:20 UTC
svn commit: r1333433 [1/2] - in /incubator/stanbol/trunk:
commons/web/base/src/main/java/org/apache/stanbol/commons/web/base/utils/
entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/mapping/
entityhub/generic/servicesapi/src/main/j...
Author: rwesten
Date: Thu May 3 12:47:18 2012
New Revision: 1333433
URL: http://svn.apache.org/viewvc?rev=1333433&view=rev
Log:
STANBOL-594: First working version of the Stanbol Entityhub based implementation for the Google Refine Reconciliation API
* supports Entityhub, ReferencedSiteManager and ReferencedSites
* URI: {serviceendpoint}/reconcile (e.g. http://localhost:8080/entityhub/site/dbpedia/reconcile)
* supports reconciliation based on name, types and properties
fixes STANBOL-595: ReferenceConstraints and ValueConstraints do now support multiple values
* Adapted interfaces (incompatible API change): decided against keeping the old Object getValue() method
* Added support for JSON serialisation/parsing
* Implementation for SPARQL and Solr (SolrYard)
Added:
incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/
incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/ReconcileQuery.java (with props)
incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/Utils.java (with props)
incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/
incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/BaseGoogleRefineReconcileResource.java (with props)
incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/EntityhubReconcileResource.java (with props)
incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/ReferencedSiteReconcileResource.java (with props)
incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/SiteManagerReconcileResource.java (with props)
incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/
incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/google_refine_reconciliation-add_service.png (with props)
incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/google_refine_reconciliation-open_dialog.png (with props)
incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/google_refine_reconciliation-use_service.png (with props)
incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/reconcile/
incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/reconcile/BaseGoogleRefineReconcileResource/
Modified:
incubator/stanbol/trunk/commons/web/base/src/main/java/org/apache/stanbol/commons/web/base/utils/MediaTypeUtil.java
incubator/stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/mapping/DefaultFieldMapperImpl.java
incubator/stanbol/trunk/entityhub/generic/servicesapi/src/main/java/org/apache/stanbol/entityhub/servicesapi/query/ReferenceConstraint.java
incubator/stanbol/trunk/entityhub/generic/servicesapi/src/main/java/org/apache/stanbol/entityhub/servicesapi/query/ValueConstraint.java
incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/fragment/EntityhubWebFragment.java
incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/parsers/FieldQueryReader.java
incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/writers/FieldQueryToJSON.java
incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/EntityhubRootResource/index.ftl
incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/ReferencedSiteRootResource/index.ftl
incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/SiteManagerRootResource/index.ftl
incubator/stanbol/trunk/entityhub/query/clerezza/src/main/java/org/apache/stanbol/entityhub/query/clerezza/SparqlQueryUtils.java
incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrQueryFactory.java
incubator/stanbol/trunk/integration-tests/src/test/java/org/apache/stanbol/entityhub/it/query/DbpediaQueryTest.java
Modified: incubator/stanbol/trunk/commons/web/base/src/main/java/org/apache/stanbol/commons/web/base/utils/MediaTypeUtil.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/commons/web/base/src/main/java/org/apache/stanbol/commons/web/base/utils/MediaTypeUtil.java?rev=1333433&r1=1333432&r2=1333433&view=diff
==============================================================================
--- incubator/stanbol/trunk/commons/web/base/src/main/java/org/apache/stanbol/commons/web/base/utils/MediaTypeUtil.java (original)
+++ incubator/stanbol/trunk/commons/web/base/src/main/java/org/apache/stanbol/commons/web/base/utils/MediaTypeUtil.java Thu May 3 12:47:18 2012
@@ -99,7 +99,29 @@ public final class MediaTypeUtil {
}
return acceptedMediaType;
}
-
+ /**
+ * Checks if the parse mediaType is compatible with one of the Accept headers.
+ * Fully supports wildcard for both parsed Accept headers AND the parsed
+ * {@link MediaType}
+ * @param headers
+ * @param mediaType
+ * @return
+ */
+ public static boolean isAcceptableMediaType(HttpHeaders headers, MediaType mediaType){
+ if (!headers.getAcceptableMediaTypes().isEmpty()) {
+ for (MediaType accepted : headers.getAcceptableMediaTypes()) {
+ //if one of the types is wildcard or types are equals AND
+ // one of the subtypes is wildcard or subtypes are equals
+ if ((accepted.isWildcardType() || mediaType.isWildcardType() ||
+ accepted.getType().equals(mediaType.getType())) &&
+ (accepted.isWildcardSubtype() || mediaType.isWildcardSubtype() ||
+ accepted.getSubtype().equals(mediaType.getSubtype()))){
+ return true;
+ }
+ }
+ }
+ return false;
+ }
public static boolean isAcceptableMediaType(MediaType mediaType, Collection<String> supported){
if(supported == null || mediaType == null){
return true;
Modified: incubator/stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/mapping/DefaultFieldMapperImpl.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/mapping/DefaultFieldMapperImpl.java?rev=1333433&r1=1333432&r2=1333433&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/mapping/DefaultFieldMapperImpl.java (original)
+++ incubator/stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/mapping/DefaultFieldMapperImpl.java Thu May 3 12:47:18 2012
@@ -397,7 +397,7 @@ public class DefaultFieldMapperImpl impl
* @return
*/
private Collection<Object> processFilter(ValueConstraint valueConstraint, Collection<Object> values,ValueFactory valueFactory) {
- if(valueConstraint.getValue() != null){
+ if(valueConstraint.getValues() != null){
log.warn("Filtering based on values is not yet implemented");
}
//1) collect all active dataTypes
Modified: incubator/stanbol/trunk/entityhub/generic/servicesapi/src/main/java/org/apache/stanbol/entityhub/servicesapi/query/ReferenceConstraint.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/generic/servicesapi/src/main/java/org/apache/stanbol/entityhub/servicesapi/query/ReferenceConstraint.java?rev=1333433&r1=1333432&r2=1333433&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/generic/servicesapi/src/main/java/org/apache/stanbol/entityhub/servicesapi/query/ReferenceConstraint.java (original)
+++ incubator/stanbol/trunk/entityhub/generic/servicesapi/src/main/java/org/apache/stanbol/entityhub/servicesapi/query/ReferenceConstraint.java Thu May 3 12:47:18 2012
@@ -17,26 +17,52 @@
package org.apache.stanbol.entityhub.servicesapi.query;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
import org.apache.stanbol.entityhub.servicesapi.defaults.DataTypeEnum;
public class ReferenceConstraint extends ValueConstraint {
-
+ /**
+ * The references. Same as returned by {@link ValueConstraint#getValues()}
+ * but in a Set of generic type string
+ */
+ private Set<String> references;
+
public ReferenceConstraint(String reference) {
- super(reference,Arrays.asList(DataTypeEnum.Reference.getUri()));
- if(reference == null){
- throw new IllegalArgumentException("Parsed Reference MUST NOT be NULL");
+ this(reference != null ? Collections.singleton(reference) : null);
+ }
+ public ReferenceConstraint(Collection<String> references) {
+ super(references,Arrays.asList(DataTypeEnum.Reference.getUri()));
+ if(references == null){
+ throw new IllegalArgumentException("Parsed Reference(s) MUST NOT be NULL");
+ }
+ //we need to copy the values over, because in Java one can not cast
+ //Set<Object> to Set<String>
+ Set<String> r = new LinkedHashSet<String>(getValues().size());
+ for(Object value : getValues()){
+ r.add((String)value);
}
+ this.references = Collections.unmodifiableSet(r);
}
+// /**
+// * Getter for the first parsed Reference
+// * @return the reference
+// */
+// public String getReference() {
+// return (String)getValue();
+// }
/**
* Getter for the Reference
* @return the reference
*/
- public String getReference() {
- return (String)getValue();
+ public Set<String> getReferences() {
+ return references;
}
Modified: incubator/stanbol/trunk/entityhub/generic/servicesapi/src/main/java/org/apache/stanbol/entityhub/servicesapi/query/ValueConstraint.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/generic/servicesapi/src/main/java/org/apache/stanbol/entityhub/servicesapi/query/ValueConstraint.java?rev=1333433&r1=1333432&r2=1333433&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/generic/servicesapi/src/main/java/org/apache/stanbol/entityhub/servicesapi/query/ValueConstraint.java (original)
+++ incubator/stanbol/trunk/entityhub/generic/servicesapi/src/main/java/org/apache/stanbol/entityhub/servicesapi/query/ValueConstraint.java Thu May 3 12:47:18 2012
@@ -17,7 +17,10 @@
package org.apache.stanbol.entityhub.servicesapi.query;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedHashSet;
+import java.util.Set;
/**
* A constraint the filters/selects based on the value and/or the parsed
@@ -32,7 +35,7 @@ import java.util.LinkedHashSet;
public class ValueConstraint extends Constraint {
- private final Object value;
+ private final Set<Object> values;
private final Collection<String> dataTypeUris;
public ValueConstraint(Object value) {
@@ -40,7 +43,25 @@ public class ValueConstraint extends Con
}
public ValueConstraint(Object value,Iterable<String> dataTypes) {
super(ConstraintType.value);
- this.value = value;
+ if(value == null){
+ this.values = null;
+ } else if(value instanceof Iterable<?>){
+ Set<Object> v = new LinkedHashSet<Object>();
+ @SuppressWarnings("unchecked")
+ Iterable<Object> values = (Iterable<Object>)value;
+ for(Object val : values){
+ if(val != null){
+ v.add(val);
+ }
+ }
+ if(v.isEmpty()){
+ throw new IllegalArgumentException("The values MUST BE NULL or " +
+ "contain at least a single NOT NULL value MUST BE parsed!");
+ }
+ this.values = Collections.unmodifiableSet(v);
+ } else { //single value
+ this.values = Collections.singleton(value);
+ }
/*
* Implementation NOTE:
* We need to use a LinkedHashSet here to
@@ -53,16 +74,21 @@ public class ValueConstraint extends Con
* that values that need to be converted are preferable converted to
* the datatype specified as first)
*/
- this.dataTypeUris = new LinkedHashSet<String>();
if(dataTypes != null){
+ Set<String> dataTypeUris = new LinkedHashSet<String>();
for(String dataType : dataTypes){
if(dataType != null && !dataType.isEmpty()){
dataTypeUris.add(dataType);
}
}
- }
- if(value == null && dataTypeUris.isEmpty()){
- throw new IllegalArgumentException("A value constraint MUST define at least a value or a valid - NOT NULL, NOT empty - data type uri!");
+ if(dataTypeUris.isEmpty()){
+ throw new IllegalArgumentException("At least a single NOT NULL and " +
+ "not empty data type uri MUST BE parsed (NULL will trigger " +
+ "detection of the data type based on the parsed value(s))!");
+ }
+ this.dataTypeUris = Collections.unmodifiableSet(dataTypeUris);
+ } else {
+ this.dataTypeUris = null;
}
//it's questionable if we should do that at this position, because
//components that process that constraint might have better ways to
@@ -75,11 +101,18 @@ public class ValueConstraint extends Con
// }
}
/**
+ * Getter for the first parsed value
+ * @return the value or <code>null</code> if the value is not constraint
+ */
+// public final Object getValue() {
+// return values.iterator().next();
+// }
+ /**
* Getter for the value
* @return the value or <code>null</code> if the value is not constraint
*/
- public final Object getValue() {
- return value;
+ public final Set<Object> getValues() {
+ return values;
}
/**
* Getter for the list of the parsed data types URIs
@@ -90,6 +123,6 @@ public class ValueConstraint extends Con
}
@Override
public String toString() {
- return String.format("ValueConstraint[value=%s|types:%s]",value,dataTypeUris);
+ return String.format("ValueConstraint[values=%s|types:%s]",values,dataTypeUris);
}
}
Modified: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/fragment/EntityhubWebFragment.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/fragment/EntityhubWebFragment.java?rev=1333433&r1=1333432&r2=1333433&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/fragment/EntityhubWebFragment.java (original)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/fragment/EntityhubWebFragment.java Thu May 3 12:47:18 2012
@@ -34,6 +34,9 @@ import org.apache.stanbol.entityhub.jers
import org.apache.stanbol.entityhub.jersey.resource.EntityhubRootResource;
import org.apache.stanbol.entityhub.jersey.resource.ReferencedSiteRootResource;
import org.apache.stanbol.entityhub.jersey.resource.SiteManagerRootResource;
+import org.apache.stanbol.entityhub.jersey.resource.reconcile.EntityhubReconcileResource;
+import org.apache.stanbol.entityhub.jersey.resource.reconcile.ReferencedSiteReconcileResource;
+import org.apache.stanbol.entityhub.jersey.resource.reconcile.SiteManagerReconcileResource;
import org.apache.stanbol.entityhub.jersey.writers.JettisonWriter;
import org.apache.stanbol.entityhub.jersey.writers.QueryResultListWriter;
import org.apache.stanbol.entityhub.jersey.writers.RepresentationWriter;
@@ -74,6 +77,10 @@ public class EntityhubWebFragment implem
//classes.add(EntityMappingResource.class);
classes.add(ReferencedSiteRootResource.class);
classes.add(SiteManagerRootResource.class);
+ //Google Refine Reconciliation API support
+ classes.add(ReferencedSiteReconcileResource.class);
+ classes.add(EntityhubReconcileResource.class);
+ classes.add(SiteManagerReconcileResource.class);
//classes.add(SymbolResource.class);
// message body readers and writers
classes.add(FieldQueryReader.class);
Added: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/ReconcileQuery.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/ReconcileQuery.java?rev=1333433&view=auto
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/ReconcileQuery.java (added)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/ReconcileQuery.java Thu May 3 12:47:18 2012
@@ -0,0 +1,409 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.stanbol.entityhub.jersey.grefine;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+import org.apache.stanbol.entityhub.core.model.InMemoryValueFactory;
+import org.apache.stanbol.entityhub.servicesapi.defaults.NamespaceEnum;
+import org.apache.stanbol.entityhub.servicesapi.model.ValueFactory;
+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;
+
+/**
+ * Java Representation for <a href="http://code.google.com/p/google-refine/wiki/ReconciliationServiceApi#Query_Request">
+ * Google Refine Reconciliation queries</a>.<p>
+ * {@link #getTypes()} and {@link Value#getId()} do support 'prefix:localname'
+ * syntax for prefixes defined in the {@link NamespaceEnum}.
+ * Also defines methods for parsing single and multiple request strings.
+ *
+ * @author Rupert Westenthaler
+ *
+ */
+public class ReconcileQuery {
+
+ private static final Logger log = LoggerFactory.getLogger(ReconcileQuery.class);
+
+ public static final Integer DEFAULT_LIMIT = 5;
+
+ public static final TYPE_STRICT DEFAULT_TYPE_STRICT = TYPE_STRICT.any;
+
+ private final String query;
+
+ private final Set<String> types;
+
+ private Integer limit;
+
+ private final Map<String,Collection<Value>> properties = new HashMap<String,Collection<Value>>();
+
+ private TYPE_STRICT typeStrict;
+
+ protected static final ValueFactory vf = InMemoryValueFactory.getInstance();
+
+ /**
+ * @return the limit
+ */
+ public final Integer getLimit() {
+ return limit;
+ }
+
+ /**
+ * @param limit the limit to set
+ */
+ public final void setLimit(Integer limit) {
+ this.limit = limit;
+ }
+
+ /**
+ * @return the typeStrict
+ */
+ public final TYPE_STRICT getTypeStrict() {
+ return typeStrict;
+ }
+
+ /**
+ * @param typeStrict the typeStrict to set
+ */
+ public final void setTypeStrict(TYPE_STRICT typeStrict) {
+ this.typeStrict = typeStrict;
+ }
+
+ /**
+ * @return the query
+ */
+ public final String getQuery() {
+ return query;
+ }
+
+ /**
+ * @return the types
+ */
+ public final Set<String> getTypes() {
+ return types;
+ }
+
+
+ public static enum TYPE_STRICT {any,all,should};
+
+
+ public ReconcileQuery(String query,Collection<String> types) {
+ if(query == null || query.isEmpty()){
+ throw new IllegalArgumentException("The parsed query string MUST NOT be NULL nor empty!");
+ }
+ this.query = query;
+ if(types == null || types.isEmpty()){
+ this.types = Collections.emptySet();
+ } else {
+ Set<String> t = new HashSet<String>(types.size());
+ for(String type : types){
+ if(type != null && !type.isEmpty()){
+ t.add(type);
+ }
+ }
+ this.types = Collections.unmodifiableSet(t);
+ }
+ }
+
+ public Collection<Value> putProperty(String field, Collection<Value> values){
+ if(field == null || field.isEmpty()){
+ throw new IllegalArgumentException("The field for an property MUST NOT be NULL!");
+ }
+ if(values == null || values.isEmpty()){
+ return properties.remove(values);
+ } else {
+ return properties.put(field, values);
+ }
+ }
+ public Collection<Value> removeProperty(String field){
+ return properties.remove(field);
+ }
+ public Collection<Value> getProperty(String field){
+ return properties.get(field);
+ }
+ public Iterable<Entry<String,Collection<Value>>> getProperties(){
+ return properties.entrySet();
+ }
+ /**
+ * Values can be simple JSON values or JSON objects with an 'id' and a
+ * 'name'. This is mapped to {@link Value} objects with an optional
+ * {@link #getId()} and a required {@link #getValue()}.<p>
+ * The 'id' supports prefix:localname syntax for prefixes defined within the
+ * {@link NamespaceEnum}
+ * @author Rupert Westenthaler
+ *
+ */
+ public static class Value {
+ private final String id;
+ private final Object value;
+
+ private Value(Object value){
+ this(null,value);
+ }
+ private Value(String id, Object value){
+ this.id = id == null ? null : NamespaceEnum.getFullName(id);
+ if(value == null){
+ throw new IllegalArgumentException("The parsed value MUST NOT be NULL!");
+ }
+ this.value = value;
+ }
+
+ /**
+ * The getter for the value of the 'id' property of the 'v' object
+ * if present. This represents the value of fields that are already
+ * successfully linked (reconciled) with some entity.
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * @return the value
+ */
+ public Object getValue() {
+ return value;
+ }
+ /**
+ * Calls the {@link #toString()} method of the {@link #getValue()}
+ */
+ @Override
+ public String toString() {
+ return value.toString();
+ }
+ @Override
+ public int hashCode() {
+ return id != null ? id.hashCode() : value.hashCode();
+ }
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof Value && ( //other is value
+ (id != null && id.equals(((Value) o).id)) || //ids are equals or
+ (id == null && ((Value)o).id == null //ids are null and
+ && value.equals(((Value)o).value))); //values are equals
+
+ }
+ }
+
+ public static Map<String,ReconcileQuery> parseQueries(String queriesString) throws WebApplicationException {
+ JSONObject jQueries;
+ try {
+ jQueries = new JSONObject(queriesString);
+ }catch (JSONException e) {
+ throw new WebApplicationException(
+ Response.status(Response.Status.BAD_REQUEST).entity(
+ "The parsed query is illegal formatted! \n query: \n"+queriesString+"\n").build());
+ }
+ @SuppressWarnings("unchecked")
+ Iterator<String> keys = jQueries.keys();
+ Map<String,ReconcileQuery> queries = new HashMap<String,ReconcileQuery>();
+ while(keys.hasNext()){
+ String key = keys.next();
+ try {
+ ReconcileQuery query = parseQuery(jQueries.getJSONObject(key));
+ queries.put(key, query);
+ } catch (JSONException e) {
+ throw new WebApplicationException(
+ Response.status(Response.Status.BAD_REQUEST).entity(
+ "The query of key '"+key+"is illegal formatted! \n query: \n"
+ + queriesString+"\n").build());
+ }
+ }
+ return queries;
+ }
+ /**
+ * Parses a Google Refine Reconcile Query from the parsed String.
+ * @param queryString the string representation of the reconcile query
+ * @return the parsed {@link ReconcileQuery} object
+ * @throws WebApplicationException {@link Response.Status#BAD_REQUEST} in
+ * case of the parsed string is not a well formated query. Unsupported
+ * Properties are silently ignored (warnings are still logged).
+ */
+ public static ReconcileQuery parseQuery(String queryString) throws WebApplicationException {
+ JSONObject jQuery;
+ try {
+ if(queryString.charAt(0) == '{') {
+ jQuery = new JSONObject(queryString);
+ } else {
+ jQuery = new JSONObject();
+ jQuery.put("query", queryString);
+ //simple string query
+ }
+ }catch (JSONException e) {
+ throw new WebApplicationException(
+ Response.status(Response.Status.BAD_REQUEST).entity(
+ "The parsed query is illegal formatted! \n query: \n"+queryString+"\n").build());
+ }
+ return parseQuery(jQuery);
+ }
+
+ private static ReconcileQuery parseQuery(JSONObject jQuery) throws WebApplicationException {
+ //query (string)
+ //limit (integer), optional
+ //type (string| [string]), optional
+ //type_strict ("any","all","should"), optional
+ //properties ([Property]), optional
+ // Property:
+ // p (string) -> ignore
+ // pid (string) -> uri
+ // v (string/Value, [string/Value]), required
+ // Value
+ // id (uri)
+ String value = jQuery.optString("query");
+ if(value == null || value.isEmpty()){
+ throw new WebApplicationException(
+ Response.status(Response.Status.BAD_REQUEST).entity(
+ "The parsed query is illegal formatted! \n query: \n"+jQuery.toString()+"\n").build());
+ }
+ JSONArray jTypes = null;
+ Collection<String> types;
+ if(!jQuery.has("type")){
+ types = Collections.emptySet();
+ } else if((jTypes = jQuery.optJSONArray("type")) != null){
+ types = new HashSet<String>(jTypes.length());
+ for(int i=0;i<jTypes.length();i++){
+ String type = NamespaceEnum.getFullName(jTypes.optString(i));
+ if(type != null && !type.isEmpty()){
+ types.add(type);
+ }
+ }
+ } else {
+ String type = jQuery.optString("type");
+ if(type != null && !type.isEmpty()){
+ types = Collections.singleton(type);
+ } else {
+ types = Collections.emptySet();
+ }
+ }
+ ReconcileQuery reconcileQuery = new ReconcileQuery(value,types);
+ //TYPE_STRICT typeStrict = null;
+ String jTypeStrict = jQuery.optString("type_strict");
+ if(jTypeStrict != null){
+ try {
+ reconcileQuery.setTypeStrict(TYPE_STRICT.valueOf(jTypeStrict));
+ } catch (RuntimeException e) {
+ log.warn("Unknown \"type_strict\" value in Google Refine Reconcile" +
+ " Request (use default '{}')\n {}",DEFAULT_TYPE_STRICT,jQuery.toString());
+ reconcileQuery.setTypeStrict(DEFAULT_TYPE_STRICT);
+ }
+ } else {
+ reconcileQuery.setTypeStrict(DEFAULT_TYPE_STRICT);
+ }
+ reconcileQuery.setLimit(jQuery.optInt("limit", DEFAULT_LIMIT));
+ JSONArray jProperties = jQuery.optJSONArray("properties");
+ if(jProperties != null){
+ for(int i=0;i<jProperties.length();i++){
+ parseProperty(reconcileQuery, jProperties.optJSONObject(i));
+ }
+ }
+ return reconcileQuery;
+ }
+
+
+ /**
+ * Internally used to parse a Property of a Google Refine Reconcile Query
+ * @param reconcileQuery the query to add the property
+ * @param jProperty the JSON formatted property
+ */
+ private static void parseProperty(ReconcileQuery reconcileQuery,JSONObject jProperty) {
+ if(jProperty != null){
+ //parse property
+ String property = NamespaceEnum.getFullName(jProperty.optString("pid"));
+ if(property == null){
+ log.warn("Ignore Property because of missing 'pid'! \n{}",jProperty.toString());
+ } else {
+ //property keys may appear multiple times in queries
+ //so we need to initialise the property values with already
+ //existing values
+ Collection<Value> values = reconcileQuery.getProperty(property);
+ if(values == null){ //if not create a new Set
+ //maybe the order is important (e.g. for similarity alg)
+ // ... so try to keep it
+ values = new LinkedHashSet<Value>();
+ }
+ //parse the value
+ Object jValue = jProperty.opt("v");
+ if(jValue == null){
+ log.warn("Ignore Property '{}' because it has no value! \n {}",property,jProperty.toString());
+ } else if(jValue instanceof JSONObject){
+ //Reconciliation data available!
+ Value value = parseValueFromV(jValue);
+ if(value != null){
+ values.add(value);
+ } else {
+ log.warn("ignore value for property {} because no name is present (value: {})!",
+ property,jValue.toString());
+ }
+ } else if(jValue instanceof JSONArray){
+ //parse value list
+ JSONArray jValueArray = (JSONArray)jValue;
+ for(int j=0;j<jValueArray.length();j++){
+ jValue = jValueArray.opt(j);
+ if(jValue instanceof JSONObject){
+ //Reconciliation data available!
+ Value value = parseValueFromV(jValue);
+ if(value != null){
+ values.add(value);
+ } else {
+ log.warn("ignore value for property {} because no name is present (value: {})!",
+ property,jValue.toString());
+ }
+ } else if(jValue != null){
+ values.add(new Value(jValue));
+ }
+ }
+ if(values.isEmpty()){
+ log.warn("Ignore Property '{}' because it does not define a valid value! \n {}",
+ property,jProperty.toString());
+ }
+ } else { //number or String
+ values.add(new Value(jValue)); //directly use the value
+ }
+
+ if(!values.isEmpty()){
+ reconcileQuery.putProperty(property, values);
+ }
+ }
+ }
+ }
+
+ /**
+ * Parses a Value from a JSON Object by reading the 'id' and 'name' keys
+ * @param jValue
+ * @return The value or <code>null</code> if the parsed json object does not
+ * contain the required information.
+ */
+ private static Value parseValueFromV(Object jValue) {
+ String id = ((JSONObject)jValue).optString("id");
+ String value = ((JSONObject)jValue).optString("name");
+ return value != null ? new Value(id,value) : null;
+ }
+
+}
Propchange: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/ReconcileQuery.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/Utils.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/Utils.java?rev=1333433&view=auto
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/Utils.java (added)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/Utils.java Thu May 3 12:47:18 2012
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.stanbol.entityhub.jersey.grefine;
+
+import static org.apache.commons.lang.StringUtils.getLevenshteinDistance;
+
+import org.apache.commons.lang.StringUtils;
+
+public class Utils {
+
+
+ /**
+ * Compares two strings (after {@link StringUtils#trim(String) trimming}
+ * by using the Levenshtein's Edit Distance of the two
+ * strings. Does not return the {@link Integer} number of changes but
+ * <code>1-(changes/maxStringSizeAfterTrim)</code><p>
+ * @param s1 the first string
+ * @param s2 the second string
+ * @return the distance
+ * @throws IllegalArgumentException if any of the two parsed strings is NULL
+ */
+ public static double levenshtein(String s1, String s2) {
+ if(s1 == null || s2 == null){
+ throw new IllegalArgumentException("NONE of the parsed String MUST BE NULL!");
+ }
+ s1 = StringUtils.trim(s1);
+ s2 = StringUtils.trim(s2);
+ return s1.isEmpty() || s2.isEmpty() ? 0 :
+ 1.0 - (((double)getLevenshteinDistance(s1, s2)) / ((double)(Math.max(s1.length(), s2.length()))));
+ }
+}
Propchange: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/grefine/Utils.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/parsers/FieldQueryReader.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/parsers/FieldQueryReader.java?rev=1333433&r1=1333432&r2=1333433&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/parsers/FieldQueryReader.java (original)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/parsers/FieldQueryReader.java Thu May 3 12:47:18 2012
@@ -497,7 +497,36 @@ public class FieldQueryReader implements
Constraint constraint;
Collection<String> dataTypes = parseDatatypeProperty(jConstraint);
if(jConstraint.has("value") && !jConstraint.isNull("value")){
- constraint = new ValueConstraint(jConstraint.get("value"), dataTypes);
+ Object value = jConstraint.get("value");
+ final List<Object> valueList;
+ if(value instanceof JSONArray){
+ valueList = new ArrayList<Object>(((JSONArray)value).length());
+ for(int i=0;i<((JSONArray)value).length();i++){
+ Object v = ((JSONArray)value).get(i);
+ if(v == null || v instanceof JSONArray || v instanceof JSONObject){
+ log.warn("Parsed ValueConstraint does define illegal values (values={})!",value);
+ StringBuilder message = new StringBuilder();
+ message.append("Parsed ValueConstraint does define illegal values for field 'value'" +
+ "(value MUST NOT contain NULL, JSONObject nor JSONArray values)!\n");
+ message.append("Parsed Constraint: \n");
+ message.append(jConstraint.toString(4));
+ throw new IllegalArgumentException(message.toString());
+ }
+ valueList.add(v);
+ }
+ } else if(value instanceof JSONObject){
+ log.warn("Parsed ValueConstraint does define illegal values (values={})!",value);
+ StringBuilder message = new StringBuilder();
+ message.append("Parsed ValueConstraint does define illegal value for field 'value'" +
+ "(value MUST NOT be an JSON object. Only values and JSONArray to parse" +
+ "multiple values are allowed)!\n");
+ message.append("Parsed Constraint: \n");
+ message.append(jConstraint.toString(4));
+ throw new IllegalArgumentException(message.toString());
+ } else {
+ valueList = Collections.singletonList(jConstraint.get("value"));
+ }
+ constraint = new ValueConstraint(valueList,dataTypes);
} else {
log.warn("Parsed ValueConstraint does not define the required field \"value\"!");
StringBuilder message = new StringBuilder();
@@ -559,7 +588,26 @@ public class FieldQueryReader implements
private static Constraint parseReferenceConstraint(JSONObject jConstraint) throws JSONException {
Constraint constraint;
if(jConstraint.has("value") && !jConstraint.isNull("value")){
- constraint = new ReferenceConstraint(jConstraint.getString("value"));
+ Object value = jConstraint.get("value");
+ final List<String> refList;
+ if(value instanceof JSONArray){
+ refList = new ArrayList<String>(((JSONArray)value).length());
+ for(int i=0;i<((JSONArray)value).length();i++){
+ refList.add(NamespaceEnum.getFullName(((JSONArray)value).getString(i)));
+ }
+ } else if(value instanceof JSONObject){
+ log.warn("Parsed ValueConstraint does define illegal values (values={})!",value);
+ StringBuilder message = new StringBuilder();
+ message.append("Parsed ValueConstraint does define illegal value for field 'value'" +
+ "(value MUST NOT be an JSON object. Only values and JSONArray to parse" +
+ "multiple values are allowed)!\n");
+ message.append("Parsed Constraint: \n");
+ message.append(jConstraint.toString(4));
+ throw new IllegalArgumentException(message.toString());
+ } else {
+ refList = Collections.singletonList(NamespaceEnum.getFullName(jConstraint.getString("value")));
+ }
+ constraint = new ReferenceConstraint(refList);
} else {
log.warn("Parsed ReferenceConstraint does not define the required field \"value\"!");
StringBuilder message = new StringBuilder();
Added: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/BaseGoogleRefineReconcileResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/BaseGoogleRefineReconcileResource.java?rev=1333433&view=auto
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/BaseGoogleRefineReconcileResource.java (added)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/BaseGoogleRefineReconcileResource.java Thu May 3 12:47:18 2012
@@ -0,0 +1,374 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.stanbol.entityhub.jersey.resource.reconcile;
+
+import static javax.ws.rs.core.MediaType.TEXT_HTML;
+import static org.apache.stanbol.commons.web.base.CorsHelper.addCORSOrigin;
+import static org.apache.stanbol.commons.web.base.CorsHelper.enableCORS;
+import static org.apache.stanbol.entityhub.servicesapi.model.rdf.RdfResourceEnum.resultScore;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.OPTIONS;
+import javax.ws.rs.POST;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+
+import org.apache.stanbol.commons.web.base.CorsHelper;
+import org.apache.stanbol.commons.web.base.resource.BaseStanbolResource;
+import org.apache.stanbol.commons.web.base.utils.MediaTypeUtil;
+import org.apache.stanbol.entityhub.jersey.grefine.ReconcileQuery;
+import org.apache.stanbol.entityhub.jersey.grefine.Utils;
+import org.apache.stanbol.entityhub.jersey.grefine.ReconcileQuery.Value;
+import org.apache.stanbol.entityhub.servicesapi.EntityhubException;
+import org.apache.stanbol.entityhub.servicesapi.defaults.NamespaceEnum;
+import org.apache.stanbol.entityhub.servicesapi.model.Reference;
+import org.apache.stanbol.entityhub.servicesapi.model.Representation;
+import org.apache.stanbol.entityhub.servicesapi.model.Text;
+import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
+import org.apache.stanbol.entityhub.servicesapi.query.QueryResultList;
+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.site.ReferencedSiteException;
+import org.apache.stanbol.entityhub.servicesapi.util.ModelUtils;
+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;
+
+import com.sun.jersey.api.view.Viewable;
+
+/**
+ * Implementation of the <a href="http://code.google.com/p/google-refine/wiki/ReconciliationServiceApi">
+ * Google Refine Reconciliation API</a>
+ * This base class is used to support this API for the Entityhub, ReferencedSites
+ * and the ReferencedSiteManager.
+ *
+ * @author Rupert Westenthaler
+ *
+ */
+public abstract class BaseGoogleRefineReconcileResource extends BaseStanbolResource {
+
+ private final Logger log = LoggerFactory.getLogger(BaseGoogleRefineReconcileResource.class);
+
+ private static final String NAME_FIELD = NamespaceEnum.rdfs+"label";
+ private static final String TYPE_FIELD = NamespaceEnum.rdf+"type";
+ private static final Collection<String> SELECTED_FIELDS = Collections.unmodifiableList(
+ Arrays.asList(NAME_FIELD,TYPE_FIELD));
+
+
+ protected BaseGoogleRefineReconcileResource(){
+ super();
+ }
+
+ @OPTIONS
+ public final Response handleCorsPreflight(@Context HttpHeaders headers){
+ ResponseBuilder res = Response.ok();
+ enableCORS(servletContext, res, headers);
+ return res.build();
+ }
+
+ @POST
+ public final Response queryPOST(@FormParam(value="query") String query,
+ @FormParam(value="queries")String queries,
+ @FormParam(value="callback")String callback,
+ @Context HttpHeaders header) throws WebApplicationException {
+ return query(query,queries,callback,header);
+ }
+ @GET
+ public final Response query(@QueryParam(value="query") String query,
+ @QueryParam(value="queries")String queries,
+ @QueryParam(value="callback")String callback,
+ @Context HttpHeaders header) throws WebApplicationException {
+ if(callback != null){
+ log.info("callback: {}",callback);
+ try {
+ return sendMetadata(callback,header);
+ } catch (JSONException e) {
+ throw new WebApplicationException(e);
+ }
+ }
+ JSONObject jResult;
+ if(query != null){
+ log.debug("query: {}",query);
+ try {
+ jResult = reconcile(ReconcileQuery.parseQuery(query));
+ } catch (JSONException e) {
+ throw new WebApplicationException(
+ Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
+ String.format("Error while writing Reconcilation results (%s: %s)",
+ JSONException.class.getSimpleName(),e.getMessage())).build());
+ } catch (EntityhubException e) {
+ throw new WebApplicationException(
+ Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
+ String.format("Error while searching on %s (%s: %s)",
+ getSiteName(),ReferencedSiteException.class.getSimpleName(),e.getMessage())).build());
+ }
+ } else if(queries != null){
+ log.debug("multi-query: {}",queries);
+ try {
+ jResult = reoncile(ReconcileQuery.parseQueries(queries));
+ } catch (JSONException e) {
+ throw new WebApplicationException(
+ Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
+ String.format("Error while writing Reconcilation results (%s: %s)",
+ JSONException.class.getSimpleName(),e.getMessage())).build());
+ } catch (EntityhubException e) {
+ throw new WebApplicationException(
+ Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
+ String.format("Error while searching on %s (%s: %s)",
+ getSiteName(),ReferencedSiteException.class.getSimpleName(),e.getMessage())).build());
+ }
+ } else {
+ if(MediaTypeUtil.isAcceptableMediaType(header,MediaType.TEXT_HTML_TYPE)){
+ ResponseBuilder rb = Response.ok(new Viewable("index", this));
+ rb.header(HttpHeaders.CONTENT_TYPE, TEXT_HTML+"; charset=utf-8");
+ addCORSOrigin(servletContext, rb, header);
+ return rb.build();
+ }
+ throw new WebApplicationException(
+ Response.status(Response.Status.BAD_REQUEST).entity(
+ "One of the 'query' or 'querues' or 'callback=jsonp' parameter MUST BE present!").build());
+ }
+ //return the results and enable Cors
+ ResponseBuilder rb = Response.ok(jResult.toString()).type(MediaType.APPLICATION_JSON_TYPE);
+ CorsHelper.addCORSOrigin(servletContext, rb, header);
+ return rb.build();
+
+ }
+
+
+ private JSONObject reoncile(Map<String,ReconcileQuery> parsedQueries) throws JSONException, EntityhubException {
+ JSONObject container = new JSONObject();
+ for(Entry<String,ReconcileQuery> query : parsedQueries.entrySet()){
+ container.put(query.getKey(), reconcile(query.getValue()));
+ }
+ return container;
+ }
+
+ private JSONObject reconcile(ReconcileQuery rQuery) throws JSONException, EntityhubException {
+ FieldQuery query = createFieldQuery();
+ query.addSelectedFields(SELECTED_FIELDS);
+ addNameConstraint(rQuery, query);
+ addTypeConstraint(rQuery, query);
+ addPropertyConstraints(rQuery, query);
+ query.setLimit(query.getLimit());
+ QueryResultList<Representation> results = performQuery(query);
+ JSONArray jResultList = new JSONArray();
+ //we need to know the highest score to normalise between [0..1]
+ double maxQueryScore = -1;
+ if(!results.isEmpty()){
+ for(Representation r : results){
+ if(maxQueryScore < 0){
+ maxQueryScore = r.getFirst(resultScore.getUri(),Number.class).doubleValue();
+ }
+ JSONObject jResult = new JSONObject();
+ jResult.put("id", r.getId());
+ double similarity = 0.0;
+ String name = null; //the name returned for the entity
+ for(Iterator<Text> labels = r.getText(NAME_FIELD);labels.hasNext();){
+ Text label = labels.next();
+ if(label.getText().equalsIgnoreCase(rQuery.getQuery())){
+ name = label.getText();
+ similarity = 1.0;
+ break;
+ }
+ double curSimilarity = Utils.levenshtein(rQuery.getQuery(), label.getText());
+ if(similarity < curSimilarity){
+ name = label.getText();
+ similarity = curSimilarity;
+ }
+ }
+ //set the selected name
+ jResult.put("name", name);
+ Iterator<Reference> types = r.getReferences(TYPE_FIELD);
+ if(types != null && types.hasNext()) {
+ jResult.put("type", new JSONArray(ModelUtils.asCollection(types)));
+ }
+ double normalisedScore = r.getFirst(resultScore.getUri(),Number.class).doubleValue();
+ normalisedScore = normalisedScore*similarity/maxQueryScore;
+ jResult.put("score", normalisedScore);
+ jResult.put("match", similarity >= 0);
+ jResultList.put(jResult);
+ }
+ } //else no results ... nothing todo
+ JSONObject jResultContainer = new JSONObject();
+ jResultContainer.put("result", jResultList);
+ return jResultContainer;
+ }
+ /**
+ * @param query
+ * @return
+ * @throws ReferencedSiteException
+ */
+ protected abstract QueryResultList<Representation> performQuery(FieldQuery query) throws EntityhubException;
+
+ /**
+ * Getter for the name of the Site as used for logging
+ * @return
+ */
+ protected abstract String getSiteName();
+
+ /**
+ * Creates a new FieldQuery
+ * @return
+ */
+ protected abstract FieldQuery createFieldQuery();
+
+ /**
+ * @param rQuery
+ * @param query
+ */
+ private void addPropertyConstraints(ReconcileQuery rQuery, FieldQuery query) {
+ Collection<String> ids = new HashSet<String>();
+ List<String> texts = new ArrayList<String>(); // keep order for texts
+ Collection<Object> values = new HashSet<Object>();
+ for (Entry<String,Collection<Value>> property : rQuery.getProperties()) {
+ // collect the properties
+ for (Value value : property.getValue()) {
+ if (value.getId() != null) {
+ ids.add(value.getId());
+ }
+ if (value.getValue() instanceof String) {
+ texts.add((String) value.getValue());
+ } else {
+ values.add(value.getValue());
+ }
+ }
+ // add the Constraint to the FieldQuery
+ // TODO: how to deal with values of different types
+ // * currently References > Text > Datatype. First present value
+ // is used
+ // * non Reference |Â Text | Datatype values are ignored
+ if (!ids.isEmpty()) {
+ // only references -> create reference constraint
+ query.setConstraint(property.getKey(), new ReferenceConstraint(ids));
+ if (ids.size() != property.getValue().size()) {
+ log.info("Only some of the parsed values of the field {} contain"
+ + "references -> will ignore values with missing references");
+ }
+ } else if (!texts.isEmpty()) {
+ // NOTE: This will use OR over all texts. To enforce AND one
+ // would need to parse a single string with all values e.g. by
+ // using StringUtils.join(texts," ")
+ query.setConstraint(property.getKey(), new TextConstraint(texts));
+ if (ids.size() != property.getValue().size()) {
+ log.info("Only some of the parsed values of the field {} are"
+ + "of type String -> will ignore non-string values");
+ }
+ } else if(!values.isEmpty()){
+ query.setConstraint(property.getKey(), new ValueConstraint(values));
+ } //else no values ... ignore property
+ //clean up
+ ids.clear();
+ texts.clear();
+ values.clear();
+ }
+ }
+ /**
+ * @param rQuery
+ * @param query
+ */
+ private void addTypeConstraint(ReconcileQuery rQuery, FieldQuery query) {
+ //maybe an other column was also mapped to the TYPE_FIELD property
+ Collection<Value> additionalTypes = rQuery.removeProperty(TYPE_FIELD);
+ Set<String> queryTypes = rQuery.getTypes();
+ Set<String> types = null;
+ if(additionalTypes == null){
+ if(queryTypes != null){
+ types = queryTypes;
+ }
+ } else {
+ types = new HashSet<String>();
+ if(queryTypes != null){
+ types.add(rQuery.getQuery());
+ }
+ for(Value value : additionalTypes){
+ if(value != null){
+ if(value.getId() != null){
+ types.add(value.getId());
+ } else if (value.getValue() instanceof String){
+ //TODO: check if the assumption that String values are
+ //good for types is valid
+ types.add((String)value.getValue());
+ }
+ } //else null -> ignore
+ }
+ }
+ if (!types.isEmpty()) {
+ query.setConstraint(TYPE_FIELD, new ReferenceConstraint(types));
+ }
+ }
+ /**
+ * @param rQuery
+ * @param query
+ */
+ private void addNameConstraint(ReconcileQuery rQuery, FieldQuery query) {
+ //maybe an other column was also mapped to the NAME_FIELD property
+ Collection<Value> additionalValues = rQuery.removeProperty(NAME_FIELD);
+ List<String> values;
+ if(additionalValues == null){
+ values = Collections.singletonList(rQuery.getQuery());
+ } else {
+ values = new ArrayList<String>(additionalValues.size()+1);
+ values.add(rQuery.getQuery());
+ for(Value value : additionalValues){
+ if(value != null && value.getValue() instanceof String){
+ values.add((String)value.getValue());
+ }
+ }
+ }
+ query.setConstraint(NAME_FIELD, new TextConstraint(values));
+ }
+ /**
+ * Called on requests for the Metadata for the Reconciliation service
+ * @param callback
+ * @param header
+ * @return
+ * @throws JSONException
+ */
+ protected Response sendMetadata(String callback, HttpHeaders header) throws JSONException {
+ //TODO: implement!!
+ JSONObject jMetadata = new JSONObject();
+ jMetadata.put("name", "Stanbol Entityhub: "+getSiteName());
+ StringBuilder callbackString = new StringBuilder(callback);
+ callbackString.append('(');
+ callbackString.append(jMetadata.toString());
+ callbackString.append(')');
+ ResponseBuilder rb = Response.ok(callbackString.toString()).type(MediaType.APPLICATION_JSON_TYPE);
+ CorsHelper.addCORSOrigin(servletContext, rb, header);
+ return rb.build();
+ }
+}
Propchange: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/BaseGoogleRefineReconcileResource.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/EntityhubReconcileResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/EntityhubReconcileResource.java?rev=1333433&view=auto
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/EntityhubReconcileResource.java (added)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/EntityhubReconcileResource.java Thu May 3 12:47:18 2012
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.stanbol.entityhub.jersey.resource.reconcile;
+
+import javax.ws.rs.Path;
+
+import org.apache.stanbol.commons.web.base.ContextHelper;
+import org.apache.stanbol.entityhub.servicesapi.Entityhub;
+import org.apache.stanbol.entityhub.servicesapi.EntityhubException;
+import org.apache.stanbol.entityhub.servicesapi.model.Representation;
+import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
+import org.apache.stanbol.entityhub.servicesapi.query.QueryResultList;
+
+@Path("/entityhub/reconcile")
+public class EntityhubReconcileResource extends BaseGoogleRefineReconcileResource {
+
+ private Entityhub _entityhub;
+
+ public EntityhubReconcileResource() {
+ super();
+ }
+ private Entityhub getEntityhub(){
+ if(_entityhub == null){
+ _entityhub = ContextHelper.getServiceFromContext(Entityhub.class, servletContext);
+ if(_entityhub == null){
+ throw new IllegalArgumentException("The Entityhub service is currently not available!");
+ }
+ }
+ return _entityhub;
+ }
+
+ @Override
+ protected QueryResultList<Representation> performQuery(FieldQuery query) throws EntityhubException {
+ return getEntityhub().find(query);
+ }
+
+ @Override
+ protected String getSiteName() {
+ return "Entityhub (local managed Entities)";
+ }
+
+ @Override
+ protected FieldQuery createFieldQuery() {
+ return getEntityhub().getQueryFactory().createFieldQuery();
+ }
+
+}
Propchange: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/EntityhubReconcileResource.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/ReferencedSiteReconcileResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/ReferencedSiteReconcileResource.java?rev=1333433&view=auto
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/ReferencedSiteReconcileResource.java (added)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/ReferencedSiteReconcileResource.java Thu May 3 12:47:18 2012
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.stanbol.entityhub.jersey.resource.reconcile;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.stanbol.commons.web.base.ContextHelper;
+import org.apache.stanbol.entityhub.servicesapi.model.Representation;
+import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
+import org.apache.stanbol.entityhub.servicesapi.query.QueryResultList;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Path("/entityhub/site/{site}/reconcile")
+public class ReferencedSiteReconcileResource extends BaseGoogleRefineReconcileResource {
+
+ private final Logger log = LoggerFactory.getLogger(ReferencedSiteReconcileResource.class);
+ private ReferencedSiteManager _siteManager;
+ private final String siteId;
+
+
+
+ public ReferencedSiteReconcileResource(@PathParam(value = "site") String siteId) {
+ super();
+ if (siteId == null || siteId.isEmpty()) {
+ log.error("Missing path parameter site={}", siteId);
+ throw new WebApplicationException(Response.Status.NOT_FOUND);
+ }
+ this.siteId = siteId;
+ }
+ private ReferencedSite getSite() throws WebApplicationException {
+ if(_siteManager == null){
+ _siteManager = ContextHelper.getServiceFromContext(
+ ReferencedSiteManager.class, servletContext);
+ if(_siteManager == null){
+ throw new IllegalStateException("Unable to lookup ReferencedSite '"
+ +siteId+"' because ReferencedSiteManager service is unavailable!");
+ }
+ }
+ ReferencedSite site = _siteManager.getReferencedSite(siteId);
+ if (site == null) {
+ String message = String.format("ReferencedSite '%s' not acitve!",siteId);
+ log.error(message);
+ throw new WebApplicationException(
+ Response.status(Status.NOT_FOUND).entity(message).build());
+ }
+ return site;
+ }
+ /**
+ * @param query
+ * @return
+ * @throws ReferencedSiteException
+ */
+ protected QueryResultList<Representation> performQuery(FieldQuery query) throws ReferencedSiteException {
+ return getSite().find(query);
+ }
+ @Override
+ protected String getSiteName() {
+ return getSite().getId() + "Referenced Site";
+ }
+ @Override
+ protected FieldQuery createFieldQuery() {
+ return getSite().getQueryFactory().createFieldQuery();
+ }
+
+}
Propchange: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/ReferencedSiteReconcileResource.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/SiteManagerReconcileResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/SiteManagerReconcileResource.java?rev=1333433&view=auto
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/SiteManagerReconcileResource.java (added)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/SiteManagerReconcileResource.java Thu May 3 12:47:18 2012
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.stanbol.entityhub.jersey.resource.reconcile;
+
+import javax.ws.rs.Path;
+
+import org.apache.stanbol.commons.web.base.ContextHelper;
+import org.apache.stanbol.entityhub.core.query.DefaultQueryFactory;
+import org.apache.stanbol.entityhub.servicesapi.model.Representation;
+import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
+import org.apache.stanbol.entityhub.servicesapi.query.QueryResultList;
+import org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteException;
+import org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteManager;
+
+@Path("/entityhub/sites/reconcile")
+public class SiteManagerReconcileResource extends BaseGoogleRefineReconcileResource {
+
+ ReferencedSiteManager _siteManager;
+
+ public SiteManagerReconcileResource() {
+ super();
+ }
+
+ private ReferencedSiteManager getSiteManager(){
+ if(_siteManager == null){
+ _siteManager = ContextHelper.getServiceFromContext(
+ ReferencedSiteManager.class, servletContext);
+ if(_siteManager == null){
+ throw new IllegalStateException("ReferencedSiteManager service is unavailable!");
+ }
+ }
+ return _siteManager;
+ }
+ @Override
+ protected QueryResultList<Representation> performQuery(FieldQuery query) throws ReferencedSiteException {
+ return getSiteManager().find(query);
+ }
+
+ @Override
+ protected String getSiteName() {
+ return "Referenced Site Manager (all sites)";
+ }
+
+ @Override
+ protected FieldQuery createFieldQuery() {
+ return DefaultQueryFactory.getInstance().createFieldQuery();
+ }
+
+}
Propchange: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/resource/reconcile/SiteManagerReconcileResource.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
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=1333433&r1=1333432&r2=1333433&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 Thu May 3 12:47:18 2012
@@ -88,8 +88,12 @@ final class FieldQueryToJSON {
switch (constraint.getType()) {
case value: //both ValueConstraint and ReferenceConstraint
ValueConstraint valueConstraint = ((ValueConstraint) constraint);
- if (valueConstraint.getValue() != null) {
- jConstraint.put("value", valueConstraint.getValue());
+ if (valueConstraint.getValues() != null) {
+ if(valueConstraint.getValues().size() == 1){
+ jConstraint.put("value", valueConstraint.getValues().iterator().next());
+ } else {
+ jConstraint.put("value", new JSONArray(valueConstraint.getValues()));
+ }
}
if(constraint instanceof ReferenceConstraint){
//the type "reference" is not present in the ConstraintType
Added: incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/google_refine_reconciliation-add_service.png
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/google_refine_reconciliation-add_service.png?rev=1333433&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/google_refine_reconciliation-add_service.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/google_refine_reconciliation-open_dialog.png
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/google_refine_reconciliation-open_dialog.png?rev=1333433&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/google_refine_reconciliation-open_dialog.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/google_refine_reconciliation-use_service.png
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/google_refine_reconciliation-use_service.png?rev=1333433&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/static/images/google_refine_reconciliation-use_service.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/EntityhubRootResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/EntityhubRootResource/index.ftl?rev=1333433&r1=1333432&r2=1333433&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/EntityhubRootResource/index.ftl (original)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/EntityhubRootResource/index.ftl Thu May 3 12:47:18 2012
@@ -79,6 +79,10 @@
<li>LDPath @<a href="${it.publicBaseUri}entityhub/ldpath">/entityhub/ldpath</a>:
Allows to execute LDPath programs on locally managed Entities.
</li>
+ <li>Reconciliation @<a href="${it.publicBaseUri}entityhub/reconcile">/entityhub/reconcile</a>:
+ Implements the <a href="http://code.google.com/p/google-refine/">
+ Google Refine</a> Reconciliation API
+ </li>
</ul>
<hr>
<#include "inc_entity.ftl">
Modified: incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/ReferencedSiteRootResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/ReferencedSiteRootResource/index.ftl?rev=1333433&r1=1333432&r2=1333433&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/ReferencedSiteRootResource/index.ftl (original)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/ReferencedSiteRootResource/index.ftl Thu May 3 12:47:18 2012
@@ -24,6 +24,11 @@
<li><a href="find">/entityhub/site/{siteId}/find</a></li>
<li><a href="query">/entityhub/site/{siteId}/query</a></li>
<li><a href="ldpath">/entityhub/site/{siteId}/ldpath</a></li>
+ <li><a href="reconcile">/entityhub/site/{siteId}/reconcile</a>:
+ Implements the <a href="http://code.google.com/p/google-refine/">
+ Google Refine</a> Reconciliation API
+ </li>
+
</ul>
<hr>
<#include "inc_metadata.ftl">
Modified: incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/SiteManagerRootResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/SiteManagerRootResource/index.ftl?rev=1333433&r1=1333432&r2=1333433&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/SiteManagerRootResource/index.ftl (original)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/resources/org/apache/stanbol/entityhub/jersey/templates/org/apache/stanbol/entityhub/jersey/resource/SiteManagerRootResource/index.ftl Thu May 3 12:47:18 2012
@@ -25,6 +25,10 @@
<li><a href="${it.publicBaseUri}entityhub/sites/find">/entityhub/sites/find</a></li>
<li><a href="${it.publicBaseUri}entityhub/sites/query">/entityhub/sites/query</a></li>
<li><a href="${it.publicBaseUri}entityhub/sites/ldpath">/entityhub/sites/ldpath</a></li>
+ <li><a href="reconcile">/entityhub/sites/reconcile</a>:
+ Implements the <a href="http://code.google.com/p/google-refine/">
+ Google Refine</a> Reconciliation API over all referenced sites.
+ </li>
</ul>
<hr>
Modified: incubator/stanbol/trunk/entityhub/query/clerezza/src/main/java/org/apache/stanbol/entityhub/query/clerezza/SparqlQueryUtils.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/query/clerezza/src/main/java/org/apache/stanbol/entityhub/query/clerezza/SparqlQueryUtils.java?rev=1333433&r1=1333432&r2=1333433&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/query/clerezza/src/main/java/org/apache/stanbol/entityhub/query/clerezza/SparqlQueryUtils.java (original)
+++ incubator/stanbol/trunk/entityhub/query/clerezza/src/main/java/org/apache/stanbol/entityhub/query/clerezza/SparqlQueryUtils.java Thu May 3 12:47:18 2012
@@ -40,6 +40,7 @@ import org.apache.stanbol.entityhub.serv
import org.apache.stanbol.entityhub.servicesapi.model.rdf.RdfResourceEnum;
import org.apache.stanbol.entityhub.servicesapi.query.Constraint;
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.TextConstraint.PatternType;
@@ -500,22 +501,22 @@ public final class SparqlQueryUtils {
//see http://www.w3.org/TR/rdf-sparql-query/#QSynLiterals
dataTypes = Collections.emptySet();
}
- if(constraint.getValue() != null){
+ if(constraint.getValues() != null){
if(dataTypes.size()<=1){
addDataTypeValueConstraint(queryString, rootVarName, field,
dataTypes.isEmpty()?null:dataTypes.iterator().next(),
- constraint.getValue(),intend);
+ constraint.getValues(),intend);
} else { //we have multiple dataTypes -> ned to use union!
boolean first = true;
for(Iterator<String> it = dataTypes.iterator();it.hasNext();){
String dataType = it.next();
if(first){
- queryString.append(intend);
+ //queryString.append(intend);
first = false;
} else {
- queryString.append(" UNION \n ").append(intend);
+ queryString.append(" UNION \n");
}
- addDataTypeValueConstraint(queryString, rootVarName, field, dataType, constraint.getValue(),"");
+ addDataTypeValueConstraint(queryString, rootVarName, field, dataType, constraint.getValues(),intend);
}
//queryString.append('}');
}
@@ -564,15 +565,33 @@ public final class SparqlQueryUtils {
* @param dataType the dataType constraint or <code>null</code> if none
* @param value the value. MUST NOT be <code>null</code>.
*/
- private static void addDataTypeValueConstraint(StringBuilder queryString, String rootVarName, String field, String dataType, Object value, String intend) {
- if(DataTypeEnum.Reference.getUri().equals(dataType) ||
- value instanceof Reference){
- queryString.append(String.format("%s?%s <%s> <%s>",
- intend,rootVarName,field,value));
- } else {
- queryString.append(String.format("%s?%s <%s> \"%s\"%s",
- intend, rootVarName,field,value,
- dataType!=null?String.format("^^<%s>",dataType):""));
+ private static void addDataTypeValueConstraint(StringBuilder queryString, String rootVarName, String field, String dataType, Collection<Object> values, String intend) {
+ String addIntend = intend;
+ queryString.append(intend);
+ if(values.size() > 1){
+ queryString.append("{ ");
+ addIntend = intend+" ";
+ }
+ boolean first = true;
+ for(Object value : values){
+ if(first){
+ //queryString.append(intend);
+ first = false;
+ } else {
+ queryString.append(" UNION\n").append(addIntend);
+ }
+ if(DataTypeEnum.Reference.getUri().equals(dataType) ||
+ value instanceof Reference){
+ queryString.append(String.format("?%s <%s> <%s>",
+ rootVarName,field,value));
+ } else {
+ queryString.append(String.format("?%s <%s> \"%s\"%s",
+ rootVarName,field,value,
+ dataType!=null?String.format("^^<%s>",dataType):""));
+ }
+ }
+ if(values.size() > 1){
+ queryString.append(" }");
}
}
/**
@@ -857,19 +876,26 @@ public final class SparqlQueryUtils {
public static void main(String[] args) {
SparqlFieldQuery query = SparqlFieldQueryFactory.getInstance().createFieldQuery();
// query.setConstraint("urn:field1", new ReferenceConstraint("urn:testReference"));
+ query.setConstraint("urn:field1", new ReferenceConstraint(
+ Arrays.asList("urn:testReference","urn:testReference1","urn:testReference3")));
// query.setConstraint("urn:field1a", new ValueConstraint(null, Arrays.asList(
// DataTypeEnum.Float.getUri())));
// query.addSelectedField("urn:field1a");
+
// query.setConstraint("urn:field1b", new ValueConstraint(9, Arrays.asList(
// DataTypeEnum.Float.getUri())));
+// query.setConstraint("urn:field1b", new ValueConstraint(Arrays.asList(9,10,11), Arrays.asList(
+// DataTypeEnum.Float.getUri())));
// query.setConstraint("urn:field1c", new ValueConstraint(null, Arrays.asList(
// DataTypeEnum.Float.getUri(),DataTypeEnum.Double.getUri(),DataTypeEnum.Decimal.getUri())));
// query.addSelectedField("urn:field1c");
// query.setConstraint("urn:field1d", new ValueConstraint(9, Arrays.asList(
// DataTypeEnum.Float.getUri(),DataTypeEnum.Double.getUri(),DataTypeEnum.Decimal.getUri())));
+// query.setConstraint("urn:field1d", new ValueConstraint(Arrays.asList(9,10,11), Arrays.asList(
+// DataTypeEnum.Float.getUri(),DataTypeEnum.Double.getUri(),DataTypeEnum.Decimal.getUri())));
// query.setConstraint("urn:field2", new TextConstraint("test value"));
- query.setConstraint("urn:field3", new TextConstraint(Arrays.asList(
- "text value","anothertest","some more values"),true));
+// query.setConstraint("urn:field3", new TextConstraint(Arrays.asList(
+// "text value","anothertest","some more values"),true));
// query.setConstraint("urn:field2a", new TextConstraint(":-]")); //tests escaping of REGEX
// query.setConstraint("urn:field3", new TextConstraint("language text","en"));
// query.setConstraint("urn:field4", new TextConstraint("multi language text","en","de",null));