[Mulgara-svn] r891 - trunk/src/jar/query/java/org/mulgara/query/filter/value
pag at mulgara.org
pag at mulgara.org
Thu May 1 18:08:14 UTC 2008
Author: pag
Date: 2008-05-01 11:08:13 -0700 (Thu, 01 May 2008)
New Revision: 891
Modified:
trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java
Log:
Added casting functions, but no XPath fn: functions yet
Modified: trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java 2008-05-01 18:07:20 UTC (rev 890)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java 2008-05-01 18:08:13 UTC (rev 891)
@@ -11,12 +11,16 @@
*/
package org.mulgara.query.filter.value;
+import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
+import org.jrdf.vocabulary.RDF;
+import org.mulgara.parser.MulgaraParserException;
import org.mulgara.query.QueryException;
import org.mulgara.query.filter.RDFTerm;
+import org.mulgara.query.rdf.XSD;
/**
* Executes a function that isn't defined in these packages.
@@ -33,22 +37,50 @@
/** The logger */
private final static Logger logger = Logger.getLogger(ExternalFn.class.getName());
+
+ /** A URI containing the namespace for XSD */
+ private final static URI XSD_URI = URI.create(XSD.NAMESPACE);
+ /** The scheme for XSD */
+ private final static String XSD_SCHEME = XSD_URI.getScheme();
+
+ /** The scheme-specific part for XSD */
+ private final static String XSD_PART = XSD_URI.getSchemeSpecificPart();
+
/** The function to be run. This will be mapped to a functor or reflection code. */
- private IRI fn;
+ private URI fnUri;
- /** The arguments of the function. */
- private RDFTerm[] operands;
+ /** This is a constructor function. */
+ private boolean isConstructor = false;
/**
* Create a new function instance.
* @param fn The function to run.
* @param operands The arguments of the function.
*/
- public ExternalFn(IRI fn, RDFTerm... operands) {
+ public ExternalFn(IRI fn, RDFTerm... operands) throws MulgaraParserException {
super(operands);
+ fnUri = fn.getValue();
+ if (isCast(fnUri)) {
+ if (operands.length != 1) throw new MulgaraParserException("Cast operation can only take a single parameter");
+ isConstructor = true;
+ } else {
+ logger.error("Unknown function URI: " + fn);
+ }
}
+ /**
+ * Tests if the URI is used for casting a literal. Anything that is in the XSD namespace,
+ * or the rdf:XMLLiteral type, is considered to be a construction operation.
+ * @param u The URI to test.
+ * @return <code>true</code> If the URI is a known type for casting.
+ */
+ private boolean isCast(URI u) {
+ if (XSD_SCHEME.equals(fnUri.getScheme()) && XSD_PART.equals(fnUri.getSchemeSpecificPart())) return true;
+ if (RDF.XML_LITERAL.equals(u)) return true;
+ return false;
+ }
+
// The ValueLiteral interface
/**
@@ -58,7 +90,7 @@
public String getLexical() throws QueryException {
RDFTerm result = resolve();
if (result.isLiteral()) return ((ValueLiteral)result).getLexical();
- throw new QueryException("Not valid to ask the lexical form of a: " + result.getClass().getSimpleName());
+ throw new QueryException("Type Error: Not valid to ask the lexical form of a: " + result.getClass().getSimpleName());
}
/**
@@ -68,7 +100,7 @@
public SimpleLiteral getLang() throws QueryException {
RDFTerm result = resolve();
if (result.isLiteral()) return ((ValueLiteral)result).getLang();
- throw new QueryException("Not valid to ask the language of a: " + result.getClass().getSimpleName());
+ throw new QueryException("Type Error: Not valid to ask the language of a: " + result.getClass().getSimpleName());
}
/**
@@ -78,14 +110,14 @@
public IRI getType() throws QueryException {
RDFTerm result = resolve();
if (result.isLiteral()) return ((ValueLiteral)result).getType();
- throw new QueryException("Not valid to ask the type of a: " + result.getClass().getSimpleName());
+ throw new QueryException("Type Error: Not valid to ask the type of a: " + result.getClass().getSimpleName());
}
/** @see org.mulgara.query.filter.AbstractFilterValue#isSimple() */
public boolean isSimple() throws QueryException {
RDFTerm result = resolve();
if (result.isLiteral()) return ((ValueLiteral)result).isSimple();
- throw new QueryException("Not valid to check if a non-literal is a simple literal: " + result.getClass().getSimpleName());
+ throw new QueryException("Type Error: Not valid to check if a non-literal is a simple literal: " + result.getClass().getSimpleName());
}
// The RDFTerm interface
@@ -112,10 +144,18 @@
* Resolve the value of the function.
* @return The resolution of the function
* @throws QueryException if the function does not resolve
- * TODO: call the appropriate function. This just returns the boolean TRUE for the moment.
*/
protected RDFTerm resolve() throws QueryException {
- logger.warn("Attempting to execute an unsupported function: " + fn + "(" + resolveArgs() + ")");
+ if (isConstructor) {
+ List<Object> args = resolveArgs();
+ assert args.size() == 1;
+ Object value = args.get(0);
+ // being a cast we'll have to resort to the lowest common denominator of "string"
+ // and let the TypedLiteral work it out for us
+ if (XSD.isNumericType(fnUri) && value instanceof Number) return new NumericLiteral(NumericLiteral.getValueFor((Number)value, fnUri), fnUri);
+ return TypedLiteral.newLiteral(value.toString(), fnUri, null);
+ }
+ logger.warn("Attempting to execute an unsupported function: " + fnUri + "(" + resolveArgs() + ")");
return Bool.TRUE;
}
@@ -126,7 +166,11 @@
*/
private List<Object> resolveArgs() throws QueryException {
List<Object> result = new ArrayList<Object>(operands.length);
- for (int i = 0; i < operands.length; i++) result.add(operands[i].getValue());
+ for (int i = 0; i < operands.length; i++) {
+ RDFTerm op = operands[i];
+ if (isConstructor && op.isBlank()) throw new QueryException("Type Error: Cannot cast a blank node.");
+ result.add(op.getValue());
+ }
return result;
}
}
More information about the Mulgara-svn
mailing list