package eu.fbk.knowledgestore.data; import java.util.List; import javax.xml.datatype.XMLGregorianCalendar; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import org.jaxen.Context; import org.jaxen.Function; import org.jaxen.FunctionCallException; import org.jaxen.XPathFunctionContext; import org.jaxen.function.BooleanFunction; import org.jaxen.function.CeilingFunction; import org.jaxen.function.ConcatFunction; import org.jaxen.function.ContainsFunction; import org.jaxen.function.CountFunction; import org.jaxen.function.FalseFunction; import org.jaxen.function.FloorFunction; import org.jaxen.function.IdFunction; import org.jaxen.function.LangFunction; import org.jaxen.function.LastFunction; import org.jaxen.function.LocalNameFunction; import org.jaxen.function.NameFunction; import org.jaxen.function.NamespaceUriFunction; import org.jaxen.function.NormalizeSpaceFunction; import org.jaxen.function.NotFunction; import org.jaxen.function.NumberFunction; import org.jaxen.function.PositionFunction; import org.jaxen.function.RoundFunction; import org.jaxen.function.StartsWithFunction; import org.jaxen.function.StringFunction; import org.jaxen.function.StringLengthFunction; import org.jaxen.function.SubstringAfterFunction; import org.jaxen.function.SubstringBeforeFunction; import org.jaxen.function.SubstringFunction; import org.jaxen.function.SumFunction; import org.jaxen.function.TranslateFunction; import org.jaxen.function.TrueFunction; import org.jaxen.function.ext.EndsWithFunction; import org.jaxen.function.ext.EvaluateFunction; import org.jaxen.function.ext.LowerFunction; import org.jaxen.function.ext.UpperFunction; import org.openrdf.model.URI; // TODO add subject(), predicate(), object(), context() functions to extract statement components abstract class XPathFunction implements Function { static final XPathFunctionContext CONTEXT; static { CONTEXT = new XPathFunctionContext(); // Functions on nodes and context CONTEXT.registerFunction(null, "position", new PositionFunction()); // xpath1 CONTEXT.registerFunction(null, "last", new LastFunction()); // xpath1 CONTEXT.registerFunction(null, "id", new IdFunction()); // xpath1 CONTEXT.registerFunction(null, "name", new NameFunction()); // xpath1 CONTEXT.registerFunction(null, "local-name", new LocalNameFunction()); // xpath1 CONTEXT.registerFunction(null, "namespace-uri", new NamespaceUriFunction()); // xpath1 CONTEXT.registerFunction(null, "lang", new LangFunction()); // xpath1 CONTEXT.registerFunction(null, "evaluate", new EvaluateFunction()); // xpath2 jaxen // Function on RDF Values CONTEXT.registerFunction(null, "uri", new URIFunction()); CONTEXT.registerFunction(null, "escape-uri", new EscapeURIFunction()); CONTEXT.registerFunction(null, "str", new StrFunction()); CONTEXT.registerFunction(null, "strdt", new StrdtFunction()); CONTEXT.registerFunction(null, "strlang", new StrlangFunction()); // Functions on booleans CONTEXT.registerFunction(null, "boolean", new BooleanFunction()); // xpath1 CONTEXT.registerFunction(null, "true", new TrueFunction()); // xpath1 CONTEXT.registerFunction(null, "false", new FalseFunction()); // xpath1 CONTEXT.registerFunction(null, "not", new NotFunction()); // xpath1 CONTEXT.registerFunction(null, "abs", new AbsFunction()); CONTEXT.registerFunction(null, "power", new PowerFunction()); // Functions on numbers CONTEXT.registerFunction(null, "number", new NumberFunction()); // xpath1 CONTEXT.registerFunction(null, "ceiling", new CeilingFunction()); // xpath1 CONTEXT.registerFunction(null, "floor", new FloorFunction()); // xpath1 CONTEXT.registerFunction(null, "round", new RoundFunction()); // xpath1 // Functions on strings CONTEXT.registerFunction(null, "concat", new ConcatFunction()); // xpath1 CONTEXT.registerFunction(null, "contains", new ContainsFunction()); // xpath1 CONTEXT.registerFunction(null, "normalize-space", new NormalizeSpaceFunction()); // xpath1 CONTEXT.registerFunction(null, "starts-with", new StartsWithFunction()); // xpath1 CONTEXT.registerFunction(null, "string", new StringFunction()); // xpath1 CONTEXT.registerFunction(null, "string-length", new StringLengthFunction()); // xpath1 CONTEXT.registerFunction(null, "substring-after", new SubstringAfterFunction()); // xpath1 CONTEXT.registerFunction(null, "substring-before", new SubstringBeforeFunction()); // xpath1 CONTEXT.registerFunction(null, "substring", new SubstringFunction()); // xpath1 CONTEXT.registerFunction(null, "translate", new TranslateFunction()); // xpath1 CONTEXT.registerFunction(null, "ends-with", new EndsWithFunction()); // xpath2 jaxen CONTEXT.registerFunction(null, "lower-case", new LowerFunction()); // xpath2 jaxen CONTEXT.registerFunction(null, "upper-case", new UpperFunction()); // xpath2 jaxen CONTEXT.registerFunction(null, "compare", new CompareFunction()); CONTEXT.registerFunction(null, "string-join", new StringJoinFunction()); CONTEXT.registerFunction(null, "matches", new MatchesFunction()); CONTEXT.registerFunction(null, "replace", new ReplaceFunction()); CONTEXT.registerFunction(null, "tokenize", new TokenizeFunction()); // Functions on dates CONTEXT.registerFunction(null, "dateTime", new DateTimeFunction()); CONTEXT.registerFunction(null, "current-dateTime", new CurrentDateTimeFunction()); CONTEXT.registerFunction(null, "year-from-dateTime", new YearFromDateTimeFunction()); CONTEXT.registerFunction(null, "month-from-dateTime", new MonthFromDateTimeFunction()); CONTEXT.registerFunction(null, "day-from-dateTime", new DayFromDateTimeFunction()); CONTEXT.registerFunction(null, "hours-from-dateTime", new HoursFromDateTimeFunction()); CONTEXT.registerFunction(null, "minutes-from-dateTime", new MinutesFromDateTimeFunction()); CONTEXT.registerFunction(null, "seconds-from-dateTime", new SecondsFromDateTimeFunction()); CONTEXT.registerFunction(null, "timezone-from-dateTime", new TimeZoneFromDateTimeFunction()); // Functions on sequences CONTEXT.registerFunction(null, "count", new CountFunction()); // xpath1 CONTEXT.registerFunction(null, "sum", new SumFunction()); // xpath1 CONTEXT.registerFunction(null, "sequence", new SequenceFunction()); CONTEXT.registerFunction(null, "subsequence", new SubsequenceFunction()); CONTEXT.registerFunction(null, "index-of", new IndexOfFunction()); CONTEXT.registerFunction(null, "insert-before", new InsertBeforeFunction()); CONTEXT.registerFunction(null, "remove", new RemoveFunction()); CONTEXT.registerFunction(null, "reverse", new ReverseFunction()); CONTEXT.registerFunction(null, "distinct-values", new DistinctValuesFunction()); CONTEXT.registerFunction(null, "exists", new ExistsFunction()); CONTEXT.registerFunction(null, "empty", new EmptyFunction()); CONTEXT.registerFunction(null, "avg", new AvgFunction()); CONTEXT.registerFunction(null, "max", new MaxFunction()); CONTEXT.registerFunction(null, "min", new MinFunction()); } // FUNCTIONS ON URIS private static final class URIFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { if (args.size() != 1) { throw new FunctionCallException("uri() requires one argument"); } final String string = StringFunction.evaluate(args.get(0), context.getNavigator()); return Data.getValueFactory().createURI(string); } } private static final class StrFunction extends XPathFunction { @SuppressWarnings("rawtypes") @Override public Object call(final Context context, final List args) throws FunctionCallException { if (args.size() != 1) { throw new FunctionCallException("str() requires one argument"); } final String label = StringFunction.evaluate(args.get(0), context.getNavigator()); return Data.getValueFactory().createLiteral(label); } } private static final class StrdtFunction extends XPathFunction { @SuppressWarnings("rawtypes") @Override public Object call(final Context context, final List args) throws FunctionCallException { if (args.size() != 2) { throw new FunctionCallException("strdt() requires two arguments"); } final String label = StringFunction.evaluate(args.get(0), context.getNavigator()); final URI dt = args.get(1) instanceof URI ? (URI) args.get(1) : Data.getValueFactory() .createURI(StringFunction.evaluate(args.get(1), context.getNavigator())); return Data.getValueFactory().createLiteral(label, dt); } } private static final class StrlangFunction extends XPathFunction { @SuppressWarnings("rawtypes") @Override public Object call(final Context context, final List args) throws FunctionCallException { if (args.size() != 2) { throw new FunctionCallException("strlang() requires two arguments"); } final String label = StringFunction.evaluate(args.get(0), context.getNavigator()); final String lang = StringFunction.evaluate(args.get(1), context.getNavigator()); return Data.getValueFactory().createLiteral(label, lang); } } private static final class EscapeURIFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } // FUNCTIONS ON NUMBERS private static final class AbsFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class PowerFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } // FUNCTIONS ON STRINGS private static final class CompareFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class StringJoinFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class MatchesFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class ReplaceFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class TokenizeFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } // FUNCTIONS ON DATES private static final class DateTimeFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { return Data.convert(args.get(0), XMLGregorianCalendar.class); } } private static final class CurrentDateTimeFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class YearFromDateTimeFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class MonthFromDateTimeFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class DayFromDateTimeFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class HoursFromDateTimeFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class MinutesFromDateTimeFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class SecondsFromDateTimeFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class TimeZoneFromDateTimeFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } // FUNCTIONS ON SEQUENCES private static final class SequenceFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { final List<Object> result = Lists.newArrayList(); for (final Object arg : args) { if (arg instanceof Iterable<?>) { Iterables.addAll(result, (Iterable<?>) arg); } else { result.add(arg); } } return result; } } private static final class SubsequenceFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class IndexOfFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class InsertBeforeFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class RemoveFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class ReverseFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class DistinctValuesFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class ExistsFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class EmptyFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class AvgFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class MaxFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } private static final class MinFunction extends XPathFunction { @Override @SuppressWarnings("rawtypes") public Object call(final Context context, final List args) throws FunctionCallException { throw new UnsupportedOperationException(); // TODO } } }