/* * Copyright 2009 DuraSpace. * * Licensed 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.mulgara.query.xpath; import java.net.URI; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.xml.xpath.XPathFunctionException; import org.jrdf.graph.BlankNode; import org.jrdf.graph.Literal; import org.mulgara.query.QueryException; import org.mulgara.query.filter.value.SimpleLiteral; import org.mulgara.query.functions.MulgaraFunction; import org.mulgara.query.functions.MulgaraFunctionGroup; /** * Container for functions in the SPARQL domain. * * @created Oct 5, 2009 * @author Paula Gearon * @copyright © 2009 <a href="http://www.duraspace.org/">DuraSpace</a> */ public class SparqlFunctionGroup implements MulgaraFunctionGroup { /** The prefix for the sparql: namespace */ static final String PREFIX = "sparql"; /** The sparql: namespace */ static final String NAMESPACE = "http://www.w3.org/2006/sparql-functions#"; /** * Get the prefix used for the namespace of these operations. * @return The short string used for a prefix in a QName. */ public String getPrefix() { return PREFIX; } /** * Get the namespace of these operations. * @return The string of the namespace URI. */ public String getNamespace() { return NAMESPACE; } /** * Get the set of SPARQL functions. * @return A set of MulgaraFunction for this entire group. */ public Set<MulgaraFunction> getAllFunctions() { Set<MulgaraFunction> functions = new HashSet<MulgaraFunction>(); functions.add(new Bound()); functions.add(new IsIRI()); functions.add(new IsURI()); functions.add(new IsBlank()); functions.add(new IsLiteral()); functions.add(new Str()); functions.add(new Lang()); functions.add(new Datatype()); functions.add(new LangMatches()); functions.add(new LogicalOr()); functions.add(new LogicalAnd()); return functions; } /** Function to evaluate if a parameter is bound. */ static private class Bound extends MulgaraFunction { public Object eval(List<?> args) { return args.get(0) != null; } } /** Function to evaluate if a parameter is an IRI. */ static private class IsIRI extends MulgaraFunction { public Object eval(List<?> args) { return args.get(0) instanceof URI; } } /** Function to evaluate if a parameter is a URI. */ static private class IsURI extends MulgaraFunction { public Object eval(List<?> args) { return args.get(0) instanceof URI; } } /** Function to evaluate if a parameter is a blank node. */ static private class IsBlank extends MulgaraFunction { public Object eval(List<?> args) { return args.get(0) instanceof BlankNode; } } /** Function to evaluate if a parameter is a literal. */ static private class IsLiteral extends MulgaraFunction { public Object eval(List<?> args) { Object o = args.get(0); return o instanceof Literal || o instanceof String || o instanceof Number; } } /** Function to convert a value to a string. */ static private class Str extends MulgaraFunction { public Object eval(List<?> args) { return args.get(0).toString(); } } /** Function to get the language of a literal. This information is probably not available for this implementation. */ static private class Lang extends MulgaraFunction { public Object eval(List<?> args) { Object o = args.get(0); return o instanceof Literal ? ((Literal)o).getLanguage() : ""; } } /** Function to get the datatype of a literal. This information is probably not available for this implementation. */ static private class Datatype extends MulgaraFunction { public Object eval(List<?> args) { Object o = args.get(0); return o instanceof Literal ? ((Literal)o).getDatatype() : null; } } /** * Function to test if a language code matches a pattern. * This information is probably not available for this implementation. */ static private class LangMatches extends MulgaraFunction { protected int getArity() { return 2; } public Object eval(List<?> args) throws XPathFunctionException { Object o = args.get(0); if (o instanceof Literal) { Literal l = (Literal)o; if (l.getLanguage() == null || l.getLanguage().length() == 0) return false; org.mulgara.query.filter.LangMatches match = new org.mulgara.query.filter.LangMatches(new SimpleLiteral(l.getLexicalForm(), l.getLanguage()), new SimpleLiteral((String)args.get(1))); try { return match.getValue(); } catch (QueryException e) { throw new XPathFunctionException("Unable to get data from lang matching test: " + e.getMessage()); } } return false; } } /** Common operations required for a logical operation. */ static private abstract class LogicOp extends MulgaraFunction { protected int getArity() { return 2; } protected abstract boolean op(Object left, Object right) throws XPathFunctionException; public Object eval(List<?> args) throws XPathFunctionException { return op(args.get(0), args.get(1)); } } /** Function to perform a logical OR between 2 operands. */ static private class LogicalOr extends LogicOp { public String getName() { return "logical-or"; } public boolean op(Object left, Object right) throws XPathFunctionException { return toBool(left) || toBool(right); } } /** Function to perform a logical AND between 2 operands. */ static private class LogicalAnd extends LogicOp { public String getName() { return "logical-and"; } public boolean op(Object left, Object right) throws XPathFunctionException { return toBool(left) && toBool(right); } } }