StringBuilder similarityContext = new StringBuilder();
//the field used for the @similarity special property
HashSet<String> similarityFields = new LinkedHashSet<String>();
for (Entry<ReconcileProperty,Collection<ReconcileValue>> propertyEntry : rQuery.getProperties()) {
ReconcileProperty property = propertyEntry.getKey();
// collect the properties
for (ReconcileValue value : propertyEntry.getValue()) {
if (value.getId() != null) {
ids.add(value.getId());
}
if (value.getValue() instanceof String) {
texts.add((String) value.getValue());
} else {
values.add(value.getValue());
}
}
//handle supported special properties
if(property.isSpecial()){
if(property.getName().equalsIgnoreCase("references")){
//Note that multiple "references" properties might be present
//if Users do parse parameters - so we need to collect all values
if(property.getParameter() != null){
log.warn("parameters are not supported for @references -> ignore '{}'",property.getParameter());
}
if(ids.isEmpty()){
log.warn("No URI values present for parsed @references property! (values: "
+propertyEntry.getValue());
}
for(String id : ids){
references.add(id);
}
} else if(property.getName().equalsIgnoreCase("fulltext")){
//Note that multiple "fullText" properties might be present
//if Users do parse parameters - so we need to collect all values
if(property.getParameter() != null){
log.warn("parameters are not supported for @fullText -> ignore '{}'",property.getParameter());
}
for(String text : texts){ //add the values
fullText.add(text);
}
} else if(property.getName().equalsIgnoreCase("similarity")){
String propUri = property.getParameter() != null ?
nsPrefixService.getFullName(property.getParameter()) :
SpecialFieldEnum.fullText.getUri();
if(propUri != null){
similarityFields.add(propUri);
} else {
//TODO: maybe throw an Exception instead
log.warn("Unknown prefix '{}' used by Google Refine query parameter of property '{}'! "
+ "Will use the full text field as fallback",
NamespaceMappingUtils.getPrefix(property.getParameter()),property);
similarityFields.add(SpecialFieldEnum.fullText.getUri());
}
for(String text : texts){ //Append the text values to the context
similarityContext.append(text).append(' ');
}
} else {
//TODO: implement LDPATH support
log.warn("ignore unsupported special property {}",property);
}
} else { //no special property
// 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.getName(), new ReferenceConstraint(ids));
if (ids.size() != propertyEntry.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.getName(), new TextConstraint(texts));
if (ids.size() != propertyEntry.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.getName(), new ValueConstraint(values));
} //else no values ... ignore property
}
//clean up
ids.clear();
texts.clear();