Skip to content

Commit

Permalink
[ADD] XQuery, Utility Module. Closes #1274.
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianGruen committed Mar 3, 2016
1 parent 842bfb1 commit 8c8acfa
Show file tree
Hide file tree
Showing 27 changed files with 229 additions and 161 deletions.
25 changes: 12 additions & 13 deletions basex-api/src/main/java/org/basex/http/restxq/RestXqFunction.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.basex.query.expr.path.*;
import org.basex.query.expr.path.Test.*;
import org.basex.query.func.*;
import org.basex.query.util.*;
import org.basex.query.value.*;
import org.basex.query.value.item.*;
import org.basex.query.value.seq.*;
Expand Down Expand Up @@ -128,9 +127,10 @@ boolean parse(final Context ctx) throws Exception {
if(sig == null) continue;

found |= eq(sig.uri, QueryText.REST_URI);
final Item[] args = ann.args();
if(sig == _REST_PATH) {
try {
path = new RestXqPath(toString(ann.args[0]), ann.info);
path = new RestXqPath(toString(args[0]), ann.info);
} catch(final IllegalArgumentException ex) {
throw error(ann.info, ex.getMessage());
}
Expand All @@ -152,14 +152,14 @@ boolean parse(final Context ctx) throws Exception {
} else if(sig == _REST_ERROR_PARAM) {
errorParams.add(param(ann, declared));
} else if(sig == _REST_METHOD) {
final String mth = toString(ann.args[0]).toUpperCase(Locale.ENGLISH);
final Item body = ann.args.length > 1 ? ann.args[1] : null;
final String mth = toString(args[0]).toUpperCase(Locale.ENGLISH);
final Item body = args.length > 1 ? args[1] : null;
addMethod(mth, body, declared, ann.info);
} else if(sig == _REST_SINGLE) {
key = "\u0000" + (ann.args.length > 0 ? toString(ann.args[0]) :
key = "\u0000" + (args.length > 0 ? toString(args[0]) :
(function.info.path() + ':' + function.info.line()));
} else if(eq(sig.uri, QueryText.REST_URI)) {
final Item body = ann.args.length == 0 ? null : ann.args[0];
final Item body = args.length == 0 ? null : args[0];
addMethod(string(sig.local()), body, declared, ann.info);
} else if(sig == _INPUT_CSV) {
final CsvParserOptions opts = new CsvParserOptions(options.get(MainOptions.CSVPARSER));
Expand All @@ -176,7 +176,7 @@ boolean parse(final Context ctx) throws Exception {
} else if(eq(sig.uri, QueryText.OUTPUT_URI)) {
// serialization parameters
try {
output.assign(string(sig.local()), toString(ann.args[0]));
output.assign(string(sig.local()), toString(args[0]));
} catch(final BaseXException ex) {
throw error(ann.info, UNKNOWN_SER, sig.local());
}
Expand Down Expand Up @@ -205,7 +205,7 @@ boolean parse(final Context ctx) throws Exception {
* @throws Exception any exception
*/
private static <O extends Options> O parse(final O opts, final Ann ann) throws Exception {
for(final Item arg : ann.args) opts.assign(string(arg.string(ann.info)));
for(final Item arg : ann.args()) opts.assign(string(arg.string(ann.info)));
return opts;
}

Expand Down Expand Up @@ -491,7 +491,7 @@ private static String toString(final Item item) {
* @param list list to add values to
*/
private static void strings(final Ann ann, final ArrayList<MediaType> list) {
for(final Item it : ann.args) list.add(new MediaType(toString(it)));
for(final Item it : ann.args()) list.add(new MediaType(toString(it)));
}

/**
Expand All @@ -503,7 +503,7 @@ private static void strings(final Ann ann, final ArrayList<MediaType> list) {
*/
private RestXqParam param(final Ann ann, final boolean... declared) throws QueryException {
// name of parameter
final Item[] args = ann.args;
final Item[] args = ann.args();
final String name = toString(args[0]);
// variable template
final QNm var = checkVariable(toString(args[1]), declared);
Expand All @@ -523,10 +523,9 @@ private void error(final Ann ann) throws QueryException {
if(error == null) error = new RestXqError();

// name of parameter
final int al = ann.args.length;
NameTest last = error.get(0);
for(int a = 0; a < al; a++) {
final String err = toString(ann.args[a]);
for(final Item arg : ann.args()) {
final String err = toString(arg);
final Kind kind;
QNm qnm = null;
if(err.equals("*")) {
Expand Down
4 changes: 4 additions & 0 deletions basex-core/src/main/java/org/basex/query/QueryText.java
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,8 @@ public interface QueryText {
byte[] REPO_PREFIX = token("repo");
/** User token. */
byte[] USER_PREFIX = token("user");
/** Util token. */
byte[] UTIL_PREFIX = token("util");
/** Validate token. */
byte[] VALIDATE_PREFIX = token("validate");
/** Web token. */
Expand Down Expand Up @@ -683,6 +685,8 @@ public interface QueryText {
byte[] UNIT_URI = token(BXMODULES_URI + "unit");
/** User module URI. */
byte[] USER_URI = token(BXMODULES_URI + "user");
/** Utility module URI. */
byte[] UTIL_URI = token(BXMODULES_URI + "util");
/** Validate module URI. */
byte[] VALIDATE_URI = token(BXMODULES_URI + "validate");
/** Web module URI. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package org.basex.query.util;
package org.basex.query.ann;

import static org.basex.query.QueryText.*;

import org.basex.query.ann.*;
import org.basex.query.value.item.*;
import org.basex.util.*;

Expand All @@ -18,9 +17,9 @@ public final class Ann {
/** Annotation signature (is {@code null} if {@link #name} is assigned). */
public final Annotation sig;
/** No-standard annotation (is {@code null} if {@link #sig} is assigned). */
public final QNm name;
private final QNm name;
/** Arguments. */
public final Item[] args;
private final Item[] args;

/**
* Constructor.
Expand Down Expand Up @@ -63,6 +62,22 @@ public boolean eq(final Ann ann) {
return true;
}

/**
* Returns the name of the annotation.
* @return name
*/
public QNm name() {
return name != null ? name : sig.qname();
}

/**
* Returns the value of the annotation.
* @return value
*/
public Item[] args() {
return args;
}

@Override
public String toString() {
final TokenBuilder tb = new TokenBuilder().add('%');
Expand Down
12 changes: 10 additions & 2 deletions basex-core/src/main/java/org/basex/query/ann/Annotation.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,6 @@ public enum Annotation {
/** XQuery annotation. */
_UNIT_TEST("test(['expected',error])", arg(STR, STR), UNIT_URI);

/** Descriptions. */
public final String desc;
/** Argument types. */
public final SeqType[] args;
/** URI. */
Expand All @@ -157,6 +155,8 @@ public enum Annotation {
public final int[] minMax;
/** Annotation must only occur once. */
public final boolean single;
/** Descriptions. */
private final String desc;

/** Cached enums (faster). */
public static final Annotation[] VALUES = values();
Expand Down Expand Up @@ -217,6 +217,14 @@ public byte[] local() {
return new TokenBuilder(desc.substring(0, desc.indexOf('('))).finish();
}

/**
* Returns the QName of the annotation.
* @return QName
*/
public QNm qname() {
return new QNm(id(), uri);
}

/**
* Returns the prefixed name of the annotation.
* @return name
Expand Down
8 changes: 4 additions & 4 deletions basex-core/src/main/java/org/basex/query/expr/Filter.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public final Expr optimize(final QueryContext qc, final VarScope scp) throws Que
e = FnSubsequence.eval((Value) e, e.size(), 1);
} else {
// rewrite positional predicate to basex:last-from
e = Function._BASEX_LAST_FROM.get(null, info, e);
e = Function._UTIL_LAST_FROM.get(null, info, e);
}
opt = true;
} else if(pos != null) {
Expand All @@ -161,18 +161,18 @@ public final Expr optimize(final QueryContext qc, final VarScope scp) throws Que
e = FnSubsequence.eval((Value) e, pos.min, pos.max - pos.min + 1);
} else if(pos.min == pos.max) {
// example: expr[pos] -> basex:item-at(expr, pos.min)
e = Function._BASEX_ITEM_AT.get(null, info, e, Int.get(pos.min));
e = Function._UTIL_ITEM_AT.get(null, info, e, Int.get(pos.min));
} else {
// example: expr[pos] -> basex:item-range(expr, pos.min, pos.max)
e = Function._BASEX_ITEM_RANGE.get(null, info, e, Int.get(pos.min), Int.get(pos.max));
e = Function._UTIL_ITEM_RANGE.get(null, info, e, Int.get(pos.min), Int.get(pos.max));
}
opt = true;
} else if(num(pred)) {
/* - rewrite positional predicate to basex:item-at
* example: expr[pos] -> basex:item-at(expr, pos)
* - only choose deterministic and context-independent offsets.
* example: (1 to 10)[random:integer(10)] or (1 to 10)[.] */
e = Function._BASEX_ITEM_AT.get(null, info, e, pred);
e = Function._UTIL_ITEM_AT.get(null, info, e, pred);
opt = true;
} else {
// rebuild filter if no optimization can be applied
Expand Down
31 changes: 17 additions & 14 deletions basex-core/src/main/java/org/basex/query/func/Function.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import org.basex.query.func.archive.*;
import org.basex.query.func.array.*;
import org.basex.query.func.async.*;
import org.basex.query.func.basex.*;
import org.basex.query.func.bin.*;
import org.basex.query.func.client.*;
import org.basex.query.func.convert.*;
Expand Down Expand Up @@ -44,6 +43,7 @@
import org.basex.query.func.strings.*;
import org.basex.query.func.unit.*;
import org.basex.query.func.user.*;
import org.basex.query.func.util.*;
import org.basex.query.func.validate.*;
import org.basex.query.func.web.*;
import org.basex.query.func.xquery.*;
Expand Down Expand Up @@ -607,19 +607,6 @@ ITEM_ZM, flag(HOF)),
_ASYNC_FORK_JOIN(AsyncForkJoin.class, "fork-join(functions[,options])",
arg(FUN_ZM, MAP_O), ITEM_ZM, flag(HOF), ASYNC_URI),

/* BaseX Module. */

/** XQuery function. */
_BASEX_DEEP_EQUAL(BaseXDeepEqual.class, "deep-equal(items1,items2[,options])",
arg(ITEM_ZM, ITEM_ZM, ITEM), BLN, BASEX_URI),
/** XQuery function. */
_BASEX_ITEM_AT(BaseXItemAt.class, "item-at(items,pos)", arg(ITEM_ZM, DBL), ITEM_ZO, BASEX_URI),
/** XQuery function. */
_BASEX_ITEM_RANGE(BaseXItemRange.class, "item-range(items,first,last)",
arg(ITEM_ZM, DBL, DBL), ITEM_ZM, BASEX_URI),
/** XQuery function. */
_BASEX_LAST_FROM(BaseXLastFrom.class, "last-from(items)", arg(ITEM_ZM), ITEM_ZO, BASEX_URI),

/* Binary Module. */

/** XQuery function. */
Expand Down Expand Up @@ -1241,6 +1228,22 @@ ITEM_ZM, flag(HOF)),
_USER_PASSWORD(UserPassword.class, "password(name,password)",
arg(STR, STR), EMP, flag(UPD), USER_URI),

/* Utility Module. */

/** XQuery function. */
_UTIL_DEEP_EQUAL(UtilDeepEqual.class, "deep-equal(items1,items2[,options])",
arg(ITEM_ZM, ITEM_ZM, ITEM), BLN, UTIL_URI),
/** XQuery function. */
_UTIL_ITEM_AT(UtilItemAt.class, "item-at(items,pos)", arg(ITEM_ZM, DBL), ITEM_ZO, UTIL_URI),
/** XQuery function. */
_UTIL_ITEM_RANGE(UtilItemRange.class, "item-range(items,first,last)",
arg(ITEM_ZM, DBL, DBL), ITEM_ZM, UTIL_URI),
/** XQuery function. */
_UTIL_LAST_FROM(UtilLastFrom.class, "last-from(items)", arg(ITEM_ZM), ITEM_ZO, UTIL_URI),
/** XQuery function. */
_UTIL_FUNCTION_ANNOTATIONS(UtilFunctionAnnotations.class, "function-annotations(function)",
arg(FUN_O), MAP_ZO, UTIL_URI),

/* Validate Module. */

/** XQuery function. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import org.basex.query.ann.*;
import org.basex.query.expr.*;
import org.basex.query.expr.Expr.Flag;
import org.basex.query.util.*;
import org.basex.query.util.list.*;
import org.basex.query.value.item.*;
import org.basex.query.value.type.*;
Expand Down
10 changes: 7 additions & 3 deletions basex-core/src/main/java/org/basex/query/func/StaticFunc.java
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,13 @@ public Expr inlineExpr(final Expr[] exprs, final QueryContext qc, final VarScope
*/
public static boolean inline(final QueryContext qc, final AnnList anns, final Expr expr) {
final Ann ann = anns.get(Annotation._BASEX_INLINE);
final long limit = ann != null
? ann.args.length > 0 ? ((ANum) ann.args[0]).itr() : Long.MAX_VALUE
: qc.context.options.get(MainOptions.INLINELIMIT);
final long limit;
if(ann == null) {
limit = qc.context.options.get(MainOptions.INLINELIMIT);;
} else {
final Item[] args = ann.args();
limit = args.length > 0 ? ((ANum) args[0]).itr() : Long.MAX_VALUE;
}
return expr.isValue() || expr.exprSize() < limit;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import org.basex.query.*;
import org.basex.query.expr.*;
import org.basex.query.func.*;
import org.basex.query.func.basex.*;
import org.basex.query.func.util.*;
import org.basex.query.iter.*;
import org.basex.query.value.*;
import org.basex.query.value.item.*;
Expand Down Expand Up @@ -117,7 +117,7 @@ private long[] range(final QueryContext qc) throws QueryException {
if(min) return len == Long.MAX_VALUE ? ALL : null;

// end flag: compute length
if(this instanceof BaseXItemRange && len != Long.MAX_VALUE) len -= start - 1;
if(this instanceof UtilItemRange && len != Long.MAX_VALUE) len -= start - 1;
return new long[] { start, len };
}

Expand Down
17 changes: 6 additions & 11 deletions basex-core/src/main/java/org/basex/query/func/inspect/Inspect.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import org.basex.core.*;
import org.basex.io.*;
import org.basex.query.*;
import org.basex.query.util.*;
import org.basex.query.ann.*;
import org.basex.query.util.list.*;
import org.basex.query.value.item.*;
import org.basex.query.value.node.*;
Expand Down Expand Up @@ -93,17 +93,12 @@ final void annotation(final AnnList anns, final FElem parent, final boolean uri)

for(final Ann ann : anns) {
final FElem annotation = elem("annotation", parent);
if(ann.sig != null) {
annotation.add("name", ann.sig.id());
if(uri) annotation.add("uri", ann.sig.uri);
} else {
annotation.add("name", ann.name.string());
if(uri) annotation.add("uri", ann.name.uri());
}
final QNm name = ann.name();
annotation.add("name", name.string());
if(uri) annotation.add("uri", name.uri());

for(final Item it : ann.args) {
final FElem literal = elem("literal", annotation);
literal.add("type", it.type.toString()).add(it.string(null));
for(final Item item : ann.args()) {
elem("literal", annotation).add("type", item.type.toString()).add(item.string(null));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import org.basex.io.*;
import org.basex.query.*;
import org.basex.query.ann.*;
import org.basex.query.func.*;
import org.basex.query.util.*;
import org.basex.query.util.list.*;
Expand Down Expand Up @@ -155,10 +156,8 @@ private void comment(final StaticScope scope, final FElem parent) {
*/
private void annotations(final AnnList anns, final FElem parent) throws QueryException {
if(!anns.isEmpty()) annotation(anns, elem("annotations", parent), false);
final int al = anns.size();
for(int a = 0; a < al; a++) {
final Ann ann = anns.get(a);
final byte[] uri = ann.sig != null ? ann.sig.uri : ann.name.uri();
for(final Ann ann : anns) {
final byte[] uri = ann.name().uri();
if(uri.length > 0) nsCache.put(NSGlobal.prefix(uri), uri);
}
}
Expand Down
Loading

0 comments on commit 8c8acfa

Please sign in to comment.