use of org.apache.stanbol.entityhub.servicesapi.query.RangeConstraint in project stanbol by apache.
the class SparqlQueryUtils method addFieldConstraint.
/**
* Adds the WHERE clause of the SPARQL query.
* <p>
* If the {@link SparqlEndpointTypeEnum SPARQL endpoint} supports SPARQL 1.1 subqueries, than this adds also the
* LIMIT and OFFSET to in inner SELECT that only selects the id.
*
* @param queryString
* the SPARQL query string to add the WHERE
* @param query
* the query
* @param selectedFields
* the selected fields
* @param endpointType
* The type of the endpoint (used to write optimised queries for endpoint type specific
* extensions
*/
private static void addFieldConstraint(final StringBuilder queryString, SparqlFieldQuery query, Map<String, String> selectedFields, SparqlEndpointTypeEnum endpointType) {
// we need temporary variables with unique names
String varPrefix = "tmp";
int[] varNum = new int[] { 1 };
// used to open brackets for the select part of the constraints
boolean first = true;
// determine if sub-selects are supported and if we need a sub-select
// (more than the id is selected)
boolean subSelectState = isSubSelectState(endpointType, selectedFields);
log.trace("add field constraints is in a sub-select-state [{}].", (subSelectState ? "yes" : "no"));
// if we uses a sub query to select the ids, we need to add the graph
// pattern
// of all selected fields outside of the sub query
Map<String, String> tmpSelectedFields = subSelectState ? new HashMap<String, String>(selectedFields) : null;
String intend;
if (subSelectState) {
// additional intend because of sub query (3*2)
intend = " ";
} else {
// normal intend (2*2)
intend = " ";
}
Iterator<Entry<String, Constraint>> constraintIterator = query.iterator();
while (constraintIterator.hasNext()) {
Entry<String, Constraint> fieldConstraint = constraintIterator.next();
if (first) {
queryString.append(" { \n");
if (subSelectState) {
String rootVarName = selectedFields.get(null);
queryString.append(" SELECT ?").append(rootVarName).append(" \n");
queryString.append(" WHERE { \n");
}
first = false;
}
String field = fieldConstraint.getKey();
Constraint constraint = fieldConstraint.getValue();
log.trace("adding a constraint [type :: {}][field :: {}][prefix :: {}][intent :: {}].", new Object[] { constraint.getType(), field, varPrefix, intend });
boolean added = true;
switch(constraint.getType()) {
case value:
addValueConstraint(queryString, field, (ValueConstraint) constraint, selectedFields, varPrefix, varNum, intend);
break;
case text:
String var = addFieldGraphPattern(queryString, field, selectedFields, varPrefix, varNum, intend);
addTextConstraint(queryString, var, (TextConstraint) constraint, endpointType, intend);
break;
case range:
var = addFieldGraphPattern(queryString, field, selectedFields, varPrefix, varNum, intend);
addRangeConstriant(queryString, var, (RangeConstraint) constraint, intend);
break;
default:
log.warn("Constraint Type '{}' not supported in SPARQL! Constriant {} " + "will be not included in the query!", fieldConstraint.getValue().getType(), fieldConstraint.getValue());
added = false;
break;
}
if (added) {
queryString.append(" . \n");
}
}
// rank the graph selected by the query
if (subSelectState) {
addRankingConstraints(endpointType, queryString, selectedFields.get(null));
}
if (!first) {
if (subSelectState) {
queryString.append(" } \n");
// re-add all selected fields to be added as selects because in
// the sub-query we only select the ID!
selectedFields = tmpSelectedFields;
// ranking needs also to be added to the sub-query (to correctly
// process LIMIT and OFFSET
addRankingOrder(endpointType, queryString, selectedFields.get(null), " ");
// add LIMIT and OFFSET to the sub-query!
// TODO: add link to the email
queryString.append(" ");
addLimit(query.getLimit(), queryString);
queryString.append(" ");
addOffset(query, queryString);
queryString.append(" ");
}
queryString.append(" } \n");
}
// if no subqueries are used we need now to add the ranking constraints
if (!subSelectState) {
addRankingConstraints(endpointType, queryString, selectedFields.get(null));
}
// root variable
while (selectedFields.size() > 1) {
// if this is the only left element
// we are done
Iterator<String> it = selectedFields.keySet().iterator();
// we need to get a non null value from the map
String actField;
do {
// the outer while ensures an non null value so we need not to
// use hasNext
actField = it.next();
} while (actField == null);
queryString.append(" OPTIONAL { ");
// NOTE the following Method removes the written mapping from the
// Map
addFieldGraphPattern(queryString, actField, selectedFields, varPrefix, varNum, "");
queryString.append(". } \n");
}
}
use of org.apache.stanbol.entityhub.servicesapi.query.RangeConstraint in project stanbol by apache.
the class FieldQueryReader method parseRangeConstraint.
/**
* @param jConstraint
* @return
* @throws JSONException
*/
private static Constraint parseRangeConstraint(JSONObject jConstraint, NamespacePrefixService nsPrefixService) throws JSONException {
Constraint constraint;
boolean inclusive;
if (jConstraint.has("inclusive")) {
inclusive = jConstraint.getBoolean("inclusive");
} else {
log.debug("RangeConstraint does not define the field 'inclusive'. Use false as default!");
inclusive = false;
}
Object upperBound = jConstraint.opt("upperBound");
Object lowerBound = jConstraint.opt("lowerBound");
Collection<String> datatypes = parseDatatypeProperty(jConstraint, nsPrefixService);
if (datatypes != null && !datatypes.isEmpty()) {
Iterator<String> it = datatypes.iterator();
String datatype = it.next();
if (datatypes.size() > 1) {
// write warning in case of multiple values
log.warn("Multiple datatypes are not supported by RangeConstriants!");
log.warn(" used: {}", datatype);
while (it.hasNext()) {
log.warn(" ignored: {}", it.next());
}
}
StringBuilder convertingError = null;
if (upperBound != null) {
Object convertedUpperBound = converterFactory.convert(upperBound, datatype, valueFactory);
if (convertedUpperBound == null) {
log.warn("Unable to convert upper bound {} to data type {}", upperBound, datatype);
convertingError = new StringBuilder();
convertingError.append("Unable to convert the parsed upper bound value ").append(upperBound).append(" to data type ").append(datatype);
} else {
// set the converted upper bound
upperBound = convertedUpperBound;
}
}
if (lowerBound != null) {
Object convertedLowerBound = converterFactory.convert(lowerBound, datatype, valueFactory);
if (convertedLowerBound == null) {
log.warn("Unable to convert lower bound {} to data type {}", lowerBound, datatype);
if (convertingError == null) {
convertingError = new StringBuilder();
} else {
convertingError.append('\n');
}
convertingError.append("Unable to convert the parsed value ").append(lowerBound).append(" to data type ").append(datatype);
} else {
// set the converted lower bound
lowerBound = convertedLowerBound;
}
}
if (convertingError != null) {
// if there was an error throw an exception
convertingError.append("Parsed Constraint: \n");
convertingError.append(jConstraint.toString(4));
throw new IllegalArgumentException(convertingError.toString());
}
}
if (upperBound == null && lowerBound == null) {
log.warn("Range Constraint does not define an 'upperBound' nor an 'lowerBound'! " + "At least one of the two MUST BE parsed for a valid RangeConstraint.");
StringBuilder message = new StringBuilder();
message.append("Range Constraint does not define an 'upperBound' nor an 'lowerBound'!");
message.append(" At least one of the two MUST BE parsed for a valid RangeConstraint.\n");
message.append("Parsed Constraint: \n");
message.append(jConstraint.toString(4));
throw new IllegalArgumentException(message.toString());
} else {
constraint = new RangeConstraint(lowerBound, upperBound, inclusive);
}
return constraint;
}
use of org.apache.stanbol.entityhub.servicesapi.query.RangeConstraint in project stanbol by apache.
the class YardTest method testFindMultipleConstraints.
/**
* Tests simple {@link RangeConstraint}
*/
@Test
public void testFindMultipleConstraints() {
// init the test data
FieldQueryTestData data = getFieldQueryTestData();
// Integer Range and reference query
FieldQuery query = getYard().getQueryFactory().createFieldQuery();
// selects r2, r2en, r2de, r5
query.setConstraint(data.intField, new RangeConstraint(data.intValue2, data.intValue5, true));
// selects r1, r1en, r1de, r5
query.setConstraint(data.refField, new ReferenceConstraint(data.refValue1.getReference()));
query.addSelectedField(data.intField);
query.addSelectedField(data.refField);
validateQueryResults(query, getYard().find(query), Arrays.asList(data.r5.getId()), Arrays.asList(data.intField, data.refField));
// text and reference
query = getYard().getQueryFactory().createFieldQuery();
// selects r1en and r2en
String wildcard = data.textValue1.getText();
wildcard = wildcard.substring(0, wildcard.length() - 1) + "*";
query.setConstraint(data.textField, new TextConstraint(wildcard, PatternType.wildcard, false, "en"));
// selects r1, r1en, r1de, r5
query.setConstraint(data.refField, new ReferenceConstraint(data.refValue1.getReference()));
query.addSelectedField(data.refField);
query.addSelectedField(data.textField);
validateQueryResults(query, getYard().find(query), Arrays.asList(data.r1en.getId()), Arrays.asList(data.refField, data.textField));
// text and value
query = getYard().getQueryFactory().createFieldQuery();
// selects r1de and r2de
query.setConstraint(data.textField, new TextConstraint(wildcard, PatternType.wildcard, false, "de"));
// selects r2, r2en, r2de
query.setConstraint(data.intField, new ValueConstraint(data.intValue2));
query.addSelectedField(data.refField);
query.addSelectedField(data.textField);
validateQueryResults(query, getYard().find(query), Arrays.asList(data.r2de.getId()), Arrays.asList(data.refField, data.textField));
}
use of org.apache.stanbol.entityhub.servicesapi.query.RangeConstraint in project stanbol by apache.
the class SolrQueryFactory method initRangeConstraint.
/**
* @param indexConstraint
* @param rangeConstraint
*/
private void initRangeConstraint(IndexConstraint indexConstraint) {
RangeConstraint rangeConstraint = (RangeConstraint) indexConstraint.getConstraint();
// we need to find the Index DataType for the range query
IndexDataType dataType = null;
ConstraintValue lowerBound = new ConstraintValue();
ConstraintValue upperBound = new ConstraintValue();
// init the boosts
addBoost(lowerBound, rangeConstraint);
addBoost(upperBound, rangeConstraint);
// init IndexValues and check for the dataType
if (rangeConstraint.getLowerBound() != null) {
IndexValue value = indexValueFactory.createIndexValue(rangeConstraint.getLowerBound());
lowerBound.getValues().add(value);
dataType = value.getType();
}
if (rangeConstraint.getUpperBound() != null) {
IndexValue value = indexValueFactory.createIndexValue(rangeConstraint.getUpperBound());
upperBound.getValues().add(value);
IndexDataType upperDataType = value.getType();
if (dataType == null) {
dataType = upperDataType;
} else {
if (!dataType.equals(upperDataType)) {
indexConstraint.setInvalid(String.format("A Range Query MUST use the same data type for the upper " + "and lover Bound! (lower:[value=%s|datatype=%s] | " + "upper:[value=%s|datatype=%s])", rangeConstraint.getLowerBound(), dataType, rangeConstraint.getUpperBound(), upperDataType));
}
}
}
if (dataType == null) {
indexConstraint.setInvalid("A Range Constraint MUST define at least a lower or an upper bound!");
} else {
// set the DATATYPE and FIED using an IndexField
indexConstraint.setIndexFieldConstraints(new IndexField(indexConstraint.getPath(), dataType));
}
// set the value range
if (rangeConstraint.isInclusive()) {
indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.LE, upperBound);
indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.GE, lowerBound);
} else {
indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.LT, upperBound);
indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.GT, lowerBound);
}
}
use of org.apache.stanbol.entityhub.servicesapi.query.RangeConstraint in project stanbol by apache.
the class YardTest method testFindRange.
/**
* Tests simple {@link RangeConstraint}
*/
@Test
public void testFindRange() {
// init the test data
FieldQueryTestData data = getFieldQueryTestData();
// query for all languages and value1
FieldQuery query = getYard().getQueryFactory().createFieldQuery();
query.setConstraint(data.intField, new RangeConstraint(data.intValue2, data.intValue5, true));
query.addSelectedField(data.intField);
query.addSelectedField(data.refField);
validateQueryResults(query, getYard().find(query), Arrays.asList(data.r2.getId(), data.r2en.getId(), data.r2de.getId(), data.r5.getId()), Arrays.asList(data.intField, data.refField));
// same for value2
query = getYard().getQueryFactory().createFieldQuery();
query.setConstraint(data.intField, new RangeConstraint(data.intValue2, data.intValue10, false));
query.addSelectedField(data.intField);
query.addSelectedField(data.textField);
validateQueryResults(query, getYard().find(query), Arrays.asList(data.r5.getId()), Arrays.asList(data.intField, data.textField));
}
Aggregations