/*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and Cambridge Semantics Incorporated.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* File: $Source: /cvsroot/slrp/boca/com.ibm.adtech.boca.model/src/com/ibm/adtech/boca/glitter/predicates/Attic/TextLikePredicate.java,v $
* Created by: Wing Yung (<a href="mailto:wingyung@us.ibm.com">wingyung@us.ibm.com</a>)
* Created on: 12/18/2006
* Revision: $Id: TextLikePredicate.java 229 2007-08-07 15:22:00Z mroy $
*
* Contributors:
* IBM Corporation - initial API and implementation
* Cambridge Semantics Incorporated - Fork to Anzo
*******************************************************************************/
package org.openanzo.datasource.nodecentric.query.predicates;
import java.util.ArrayList;
import java.util.List;
import org.openanzo.datasource.nodecentric.query.ServerSolutionGenerator;
import org.openanzo.glitter.exception.FunctionalPredicateInvocationException;
import org.openanzo.glitter.exception.GlitterException;
import org.openanzo.glitter.query.FunctionalPredicate;
import org.openanzo.glitter.query.NodeCostModel;
import org.openanzo.glitter.query.PatternSolution;
import org.openanzo.glitter.query.PatternSolutionImpl;
import org.openanzo.glitter.query.QueryInformation;
import org.openanzo.glitter.query.SolutionGenerator;
import org.openanzo.glitter.query.SolutionList;
import org.openanzo.glitter.query.SolutionSet;
import org.openanzo.glitter.util.TypeConversions;
import org.openanzo.indexer.IndexerException;
import org.openanzo.jdbc.container.sql.NodeSQL;
import org.openanzo.jdbc.utils.ClosableIterator;
import org.openanzo.jdbc.utils.RdbException;
import org.openanzo.rdf.Bindable;
import org.openanzo.rdf.TriplePattern;
import org.openanzo.rdf.URI;
import org.openanzo.rdf.Variable;
import org.openanzo.rdf.vocabulary.XMLSchema;
/**
* Special predicate that allows one to use a SQL like query to match literal values. <li>Example: SELECT ?S WHERE {?s <http:/openanzo.org/predicates/textlike>
* 'test%'}</li>
*
* @author Matthew Roy ( <a href="mailto:mroy@cambridgesemantics.com">mroy@cambridgesemantics.com </a>)
*
*/
public class TextLikePredicate implements FunctionalPredicate {
private Variable var;
private String textMatch;
private final List<TriplePattern> patterns = new ArrayList<TriplePattern>();
private QueryInformation queryInformation;
private TriplePattern functionalTriplePattern = null;
public void initialize(QueryInformation qi) {
this.queryInformation = qi;
}
public boolean canBindGraphVariables() {
return false;
}
/**
* Get the variable
*
* @return the variable
*/
public Variable getVariable() {
return var;
}
/**
* Get the query text
*
* @return the textMatch
*/
public String getTextQuery() {
return textMatch;
}
public SolutionSet generateSolutions(URI namedGraph, Variable namedGraphVariable, SolutionSet bindingConstraints) throws GlitterException {
// Massage the match text to include other variables.
// For now, only support one pattern; not clear what multiple
// patterns mean.
SolutionGenerator sg = queryInformation.getSolutionGenerator();
SolutionSet ss = new SolutionList();
if (sg instanceof ServerSolutionGenerator) {
ServerSolutionGenerator bssg = (ServerSolutionGenerator) sg;
if (bssg.getContext().getNodeLayout().getLiteralIndexer() != null) {
try {
List<Long> ids = bssg.getContext().getNodeLayout().getLiteralIndexer().query(textMatch);
for (Long id : ids) {
PatternSolution sol = new PatternSolutionImpl();
sol.setBinding(var, bssg.getContext().getNodeLayout().getNodeConverter().getGlitterNode(id, bssg.getContext().getConnection()));
ss.add(sol);
}
} catch (IndexerException ie) {
throw new GlitterException(ie);
}
} else {
ClosableIterator<Long> results = null;
try {
Long id = bssg.getContext().getNodeLayout().getDatatypeLayout().store(XMLSchema.STRING.toString(), bssg.getContext().getConnection());
results = NodeSQL.findNodeID(bssg.getContext().getStatementProvider(), bssg.getContext().getConnection(), (id != null) ? id.longValue() : 0, textMatch, bssg.getContext().getNodeLayout().getLiteralTableName(), bssg.getContext().getConfiguration().getOptimizationString());
} catch (RdbException e) {
throw new GlitterException(e);
}
try {
while (results.hasNext()) {
long id = results.next();
PatternSolution sol = new PatternSolutionImpl();
sol.setBinding(var, bssg.getContext().getNodeLayout().getNodeConverter().getGlitterNode(id, bssg.getContext().getConnection()));
ss.add(sol);
}
} finally {
results.close();
}
}
} else {
throw new GlitterException("SolutionGenerator must be a ServerSolutionGenerator to generate TextLikePredicate solutions");
}
return ss;
}
public boolean handlesTriplePattern(TriplePattern pattern) throws FunctionalPredicateInvocationException {
if (pattern.getObject().equals(var)) {
patterns.add(pattern);
return false;
}
return false;
}
public void setFunctionalTriplePattern(TriplePattern pattern) throws FunctionalPredicateInvocationException {
if (!(pattern.getSubject() instanceof Bindable))
throw new FunctionalPredicateInvocationException("Subject of textmatch must be a bindable");
if (!TypeConversions.isSimpleLiteral(pattern.getObject()))
throw new FunctionalPredicateInvocationException("Object of textmatch must be a simple literal");
this.var = (Variable) pattern.getSubject();
this.textMatch = pattern.getObject().toString();
this.textMatch = this.textMatch.substring(1, this.textMatch.length() - 1);
functionalTriplePattern = pattern;
}
public boolean usesDataFromGraphs() {
return false;
}
public double getCost(NodeCostModel costModel) {
return 0;
}
public TriplePattern getFunctionalTriplePattern() {
return functionalTriplePattern;
}
}