From: <pm_...@us...> - 2011-05-24 13:32:31
|
Revision: 4366 http://mxquery.svn.sourceforge.net/mxquery/?rev=4366&view=rev Author: pm_fischer Date: 2011-05-24 13:32:19 +0000 (Tue, 24 May 2011) Log Message: ----------- annotation (e..g, %private, %updating) support: definitions, tests and helper structures Modified Paths: -------------- trunk/MXQuery/android/src/ch/ethz/mxquery/query/parser/SchemaParser.java trunk/MXQuery/midp_src/ch/ethz/mxquery/query/webservice/WSDLHandler.java trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/Context.java trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/XQStaticContext.java trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/TypeInfo.java trunk/MXQuery/src/ch/ethz/mxquery/functions/FGPopulator.java trunk/MXQuery/src/ch/ethz/mxquery/functions/Function.java trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionSignature.java trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Filter.java trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Fold.java trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Map.java trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/MapPairs.java trunk/MXQuery/src/ch/ethz/mxquery/iterators/SequenceTypeIterator.java trunk/MXQuery/src/ch/ethz/mxquery/model/VariableHolder.java trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java trunk/MXQuery/src/ch/ethz/mxquery/query/parser/SchemaParser.java trunk/MXQuery/src/ch/ethz/mxquery/query/webservice/WSDLHandler.java trunk/MXQuery/src/examples/ExternalFunctionExample.java trunk/MXQuery/xqib_src/ch/ethz/mxquery/functions/FGPopulator.java trunk/MXQuery/xqib_src/ch/ethz/mxquery/functions/Function.java trunk/MXQuery_Testing/src/ch/ethz/mxquery/test/xq11streaming/MiscTests.java Added Paths: ----------- trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-func.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-import-default.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-import-defaultvar.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-import-private.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-import-privatevar.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-import-public.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-import-publicvar.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-missing-literal.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-module.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-nondet-UDT.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-nondet-func.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-nondet-sequential-func.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-privateprivatefunc.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-privatepublicfunc.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-publicpublicfunc.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-unknown-namespace.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-var.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/functest-deterministic-builtin.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/functest-deterministic-external-nondet-coercion.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/functest-deterministic-external-nondet-partial.xq trunk/MXQuery_Testing/XQTests/Queries/xquery11/functest-deterministic-external-nondet.xq Modified: trunk/MXQuery/android/src/ch/ethz/mxquery/query/parser/SchemaParser.java =================================================================== --- trunk/MXQuery/android/src/ch/ethz/mxquery/query/parser/SchemaParser.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/android/src/ch/ethz/mxquery/query/parser/SchemaParser.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -48,6 +48,7 @@ import ch.ethz.mxquery.functions.xs.XSConstructorIterator; import ch.ethz.mxquery.model.XDMIterator; import ch.ethz.mxquery.util.URIUtils; +import ch.ethz.mxquery.util.Hashtable; public class SchemaParser implements DOMErrorHandler { /** @@ -287,7 +288,7 @@ Type.OCCURRENCE_IND_ZERO_OR_MORE); FunctionSignature signature = new FunctionSignature(qn, paramTypes, FunctionSignature.SYSTEM_FUNCTION, - XDMIterator.EXPR_CATEGORY_SIMPLE, false, true); + new Hashtable()); XDMIterator it = XSConstructorIterator.getBaseTypeConstructor(ctx, Type.getTypeFootprint( qn, dict), dict); if (it != null) { Modified: trunk/MXQuery/midp_src/ch/ethz/mxquery/query/webservice/WSDLHandler.java =================================================================== --- trunk/MXQuery/midp_src/ch/ethz/mxquery/query/webservice/WSDLHandler.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/midp_src/ch/ethz/mxquery/query/webservice/WSDLHandler.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -200,7 +200,9 @@ // only function name and arity params[i] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE); } - FunctionSignature signature = new FunctionSignature(functionName,params,FunctionSignature.EXTERNAL_FUNCTION,XDMIterator.EXPR_CATEGORY_SEQUENTIAL,true,false); + Hashtable annotations = new Hashtable(); + annotations.put(FunctionSignature.NONDETERMINISTIC_ANNOTATION, new XDMIterator[]{}); + FunctionSignature signature = new FunctionSignature(functionName,params,FunctionSignature.EXTERNAL_FUNCTION,annotations); Function function = new Function(null,signature,wf,null,null); context.addFunction(function, true, true); Modified: trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/Context.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/Context.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/Context.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -395,33 +395,33 @@ public void registerVariable(QName qname, boolean isFFLWOR) throws MXQueryException { - registerVariable(qname, false, isFFLWOR, null, false); + registerVariable(qname, false, isFFLWOR, null, new Hashtable()); } public void registerVariable(QName qname, boolean isFFLWOR, - XDMIterator seqTypeIter, boolean assignable) + XDMIterator seqTypeIter, Hashtable annotations) throws MXQueryException { - registerVariable(qname, false, isFFLWOR, seqTypeIter, assignable); + registerVariable(qname, false, isFFLWOR, seqTypeIter, annotations); } public void registerNewContextItem() throws MXQueryException { - registerVariable(CONTEXT_ITEM, false, null, false); + registerVariable(CONTEXT_ITEM, false, null, new Hashtable()); } public void registerNewContextItem(XDMIterator seqTypeIter) throws MXQueryException { - registerVariable(CONTEXT_ITEM, false, seqTypeIter, false); + registerVariable(CONTEXT_ITEM, false, seqTypeIter, new Hashtable()); } public void registerVariable(QName qname, boolean external, - boolean isFFLWOR, XDMIterator seqTypeIter, boolean assignable) + boolean isFFLWOR, XDMIterator seqTypeIter, Hashtable annotations) throws MXQueryException { registerVariable(qname, external, isFFLWOR, seqTypeIter, true, - assignable, true); + annotations, true); } public void registerVariable(QName qname, boolean external, boolean isFFLWOR, XDMIterator seqTypeIter, boolean resolve, - boolean assignable, boolean declared) throws MXQueryException { + Hashtable annotations, boolean declared) throws MXQueryException { XQName resolvedQName = qname; if (resolve && qname.getNamespaceURI() == null) resolvedQName = qname.resolveQNameNamespace(this, false); @@ -442,18 +442,17 @@ holder.setDeclared(declared); } } else { - holder = new VariableHolder(this, external,variableMap.size()); + holder = new VariableHolder(this, external,variableMap.size(),annotations); holder.setDeclared(declared); variableMap.put(resolvedQName, holder); } holder.setSeqTypeIt(seqTypeIter); - holder.setAssignable(assignable); } public QName registerAnonymousVariable() { QName qname = new QName(ANONYM_VARIABLE_PREFIX, ANONYM_VARIABLE_PREFIX + ++anonymVariableCounter); - variableMap.put(qname, new VariableHolder(this, false,variableMap.size())); + variableMap.put(qname, new VariableHolder(this, false,variableMap.size(),new Hashtable())); return qname; } @@ -522,7 +521,7 @@ throws MXQueryException { VariableHolder holder = getVariable(qname); if (holder == null) { - registerVariable(qname, true,false,null,true,false,false); + registerVariable(qname, true,false,null,true,new Hashtable(),false); holder = getVariable(qname); } Modified: trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/XQStaticContext.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/XQStaticContext.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/XQStaticContext.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -458,11 +458,11 @@ * @param qname * @param isFFLWOR * @param seqTypeIter - * @param assignable + * @param annotations * @throws MXQueryException */ public void registerVariable(QName qname, boolean isFFLWOR, XDMIterator seqTypeIter, - boolean assignable) throws MXQueryException; + Hashtable annotations) throws MXQueryException; /** * Registers a new context item in this scope * @throws MXQueryException @@ -483,11 +483,11 @@ * @param external * @param isFFLWOR * @param seqTypeIter - * @param assignable + * @param annotations * @throws MXQueryException */ public void registerVariable(QName qname, boolean external, boolean isFFLWOR, - XDMIterator seqTypeIter, boolean assignable) throws MXQueryException; + XDMIterator seqTypeIter, Hashtable annotations) throws MXQueryException; /** * Registers a new variable. If the variable already exists, an error is thrown. @@ -496,12 +496,12 @@ * @param isFFLWOR * @param seqTypeIter * @param resolve - * @param assignable + * @param annotations * @param declared TODO * @throws MXQueryException */ public void registerVariable(QName qname, boolean external, boolean isFFLWOR, - XDMIterator seqTypeIter, boolean resolve, boolean assignable, boolean declared) throws MXQueryException; + XDMIterator seqTypeIter, boolean resolve, Hashtable annotations, boolean declared) throws MXQueryException; /** * Registers a new "anonymous" (=internal) variable * @return the QName of the registered variable Modified: trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/TypeInfo.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/TypeInfo.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/TypeInfo.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -20,6 +20,7 @@ package ch.ethz.mxquery.datamodel.types; import ch.ethz.mxquery.datamodel.XQName; +import ch.ethz.mxquery.util.Hashtable; /** Some of node kind types (e.g. element, attribute, PI) might have name part in the type definition. * It's not possible to represent type with integer number in these cases. @@ -33,6 +34,7 @@ private int typeAnnotation =UNDEFINED; private TypeInfo [] paramTypes = null; private TypeInfo returnType=null; + private Hashtable annotations=null; private final static int MASK_GET_START_TAG = Integer.parseInt("0001100000000000000000000000000", 2); private final static int MASK_CLEAN_START_TAG = Integer.parseInt("1110011111111111111111111111111", 2); @@ -59,11 +61,12 @@ this.typeAnnotation = typeAn; } - public TypeInfo(int type, int occurIndID, TypeInfo[] params,TypeInfo retType) { + public TypeInfo(int type, int occurIndID, TypeInfo[] params,TypeInfo retType, Hashtable annotations) { this.type = type; this.occurID = occurIndID; this.paramTypes = params; this.returnType = retType; + this.annotations = annotations; } @@ -164,11 +167,15 @@ return returnType; } + public Hashtable getAnnotations() { + return annotations; + } + public TypeInfo copy() { if (typeAnnotation != UNDEFINED) return new TypeInfo(type,occurID,qn,typeAnnotation); else if (type ==Type.FUNCTION_ITEM) - return new TypeInfo(type, occurID, paramTypes, returnType); + return new TypeInfo(type, occurID, paramTypes, returnType,annotations); else return new TypeInfo(type, occurID,qn); } Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/FGPopulator.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/functions/FGPopulator.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/functions/FGPopulator.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -16,7 +16,7 @@ import ch.ethz.mxquery.exceptions.ErrorCodes; import ch.ethz.mxquery.exceptions.MXQueryException; import ch.ethz.mxquery.exceptions.QueryLocation; -import ch.ethz.mxquery.model.XDMIterator; +import ch.ethz.mxquery.util.Hashtable; import ch.ethz.mxquery.util.IOLib; class FGPopulator { @@ -133,7 +133,7 @@ for (int i=0;i<paramTypes.length;i++) paramTypes[i] = new TypeInfo(FunctionGallery.getType(parameters[i],ctx),FunctionGallery.getOccur(parameters[i])); - FunctionSignature signature = new FunctionSignature(qn, paramTypes, FunctionSignature.SYSTEM_FUNCTION, XDMIterator.EXPR_CATEGORY_SIMPLE, false, false); + FunctionSignature signature = new FunctionSignature(qn, paramTypes, FunctionSignature.SYSTEM_FUNCTION, new Hashtable()); Function function = new Function(baseLoc+loc+"."+funcDesc[2],signature, null, operation, type ); fg.add(function); Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/Function.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/functions/Function.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/functions/Function.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -26,6 +26,7 @@ import ch.ethz.mxquery.exceptions.StaticException; import ch.ethz.mxquery.iterators.UserdefFuncCall; import ch.ethz.mxquery.model.XDMIterator; +import ch.ethz.mxquery.util.Hashtable; /** * Holds information on the function metadata and methods to retrieve the @@ -79,9 +80,10 @@ public Function getAsExternalFunction(String prefix) { QName fName = new QName(signature.getName().getNamespaceURI(), prefix, signature.getName().getLocalPart()); + Hashtable annotations = signature.getAllAnnotations(); + annotations.put(FunctionSignature.PRIVATE_ANNOTATION,new XDMIterator[]{}); FunctionSignature newSig = new FunctionSignature(fName, signature.paramTypes - , FunctionSignature.EXTERNAL_FUNCTION, - signature.getExpressionCategory(), false, true); + , FunctionSignature.EXTERNAL_FUNCTION,annotations); Function func = new Function(className, newSig, iter, operation, returnType); return func; } Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionSignature.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionSignature.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionSignature.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -15,12 +15,15 @@ package ch.ethz.mxquery.functions; +import java.util.Enumeration; + import ch.ethz.mxquery.contextConfig.XQStaticContext; import ch.ethz.mxquery.datamodel.QName; import ch.ethz.mxquery.datamodel.XQName; import ch.ethz.mxquery.datamodel.types.Type; import ch.ethz.mxquery.datamodel.types.TypeInfo; import ch.ethz.mxquery.model.XDMIterator; +import ch.ethz.mxquery.util.Hashtable; /** * Holds information on the signature (Name, parameters, classification) of an XQuery function @@ -30,6 +33,14 @@ public class FunctionSignature { + public static final QName PRIVATE_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","private"); + public static final QName PUBLIC_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","public"); + public static final QName DETERMINISTIC_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","deterministic"); + public static final QName NONDETERMINISTIC_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","nondeterministic"); + public static final QName SIMPLE_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","simple"); + public static final QName UPDATING_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","updating"); + public static final QName SEQUENTIAL_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","sequential"); + protected QName qname; TypeInfo [] paramTypes; @@ -37,13 +48,9 @@ int arity = 0; protected int type; - - protected int expressionType; - - protected boolean nondet; - - protected boolean privateScope; - + + Hashtable annotations; + //Undefined is just for locking up values private static final int UNDEFINED_TYPE=0; @@ -53,18 +60,16 @@ //public static final int LOCAL_SCOPE_FUNCTION=4; FunctionSignature(QName qname, TypeInfo [] parameterType){ - this(qname, parameterType, UNDEFINED_TYPE, XDMIterator.EXPR_CATEGORY_SIMPLE, false, false); + this(qname, parameterType, UNDEFINED_TYPE, new Hashtable()); } - public FunctionSignature(QName qname, TypeInfo[] parameterType, int type, int exprType, boolean nondeterministic, boolean isPrivate){ + public FunctionSignature(QName qname, TypeInfo[] parameterType, int type, Hashtable annotations){ this.qname = qname; this.paramTypes = parameterType; this.type = type; - expressionType = exprType; - nondet = nondeterministic; - privateScope = isPrivate; if (this.paramTypes != null) arity = paramTypes.length; + this.annotations = annotations; } /** * Checks the equality of Function Signatures. @@ -128,28 +133,43 @@ * @return The expression type of this function: SIMPLE, UPDATING, SCRIPTING */ public int getExpressionCategory() { - return expressionType; + if (annotations.containsKey(UPDATING_ANNOTATION)) + return XDMIterator.EXPR_CATEGORY_UPDATING; + if (annotations.containsKey(SEQUENTIAL_ANNOTATION)) + return XDMIterator.EXPR_CATEGORY_SEQUENTIAL; + return XDMIterator.EXPR_CATEGORY_SIMPLE; } /** * Is this a deterministic or non-deterministic functions (as defined in XQuery 1.1) * @return true if the function is non-deterministic */ public boolean isNonDeterministic() { - return nondet; + return annotations.containsKey(NONDETERMINISTIC_ANNOTATION); } /** * Is this a private function (XQuery 1.1, exempt from module import) * @return true if this is a private function */ public boolean isPrivateFunction() { - return privateScope; + return annotations.containsKey(PRIVATE_ANNOTATION); } + public Hashtable getAllAnnotations() { + Hashtable ht = new Hashtable(); + Enumeration keys = annotations.keys(); + while (keys.hasMoreElements()) { + Object key = keys.nextElement(); + Object val = annotations.get(key); + ht.put(key, val); + } + return ht; + } + public FunctionSignature copy() { QName qn = null; if (qname != null) qn = qname.copy(); - FunctionSignature fs = new FunctionSignature(qn, paramTypes, type, expressionType, nondet, privateScope); + FunctionSignature fs = new FunctionSignature(qn, paramTypes, type, annotations); fs.arity = arity; return fs; } Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -17,6 +17,7 @@ import ch.ethz.mxquery.exceptions.StaticException; import ch.ethz.mxquery.iterators.NativeFuncCall; import ch.ethz.mxquery.model.XDMIterator; +import ch.ethz.mxquery.util.Hashtable; public class NativeFunctionImporter { @@ -181,7 +182,10 @@ while (allFuncts.hasNext()) { MethodData md = (MethodData)allFuncts.next(); QName qn = new QName("java:"+className,"javamethod",md.methodName); - FunctionSignature fs = new FunctionSignature(qn, md.paramTypes,FunctionSignature.EXTERNAL_FUNCTION,XDMIterator.EXPR_CATEGORY_SEQUENTIAL,true,false); + Hashtable annotations = new Hashtable(); + annotations.put(FunctionSignature.SEQUENTIAL_ANNOTATION,new XDMIterator[]{}); + annotations.put(FunctionSignature.NONDETERMINISTIC_ANNOTATION,new XDMIterator[]{}); + FunctionSignature fs = new FunctionSignature(qn, md.paramTypes,FunctionSignature.EXTERNAL_FUNCTION,annotations); Function fn = new Function(null, fs, new NativeFuncCall(ctx, md.paramTypes, toImport, md.methodName, md.returnType, null, XDMIterator.EXPR_CATEGORY_SIMPLE, QueryLocation.OUTSIDE_QUERY_LOC), null, null); ctx.addFunction(fn); } @@ -220,4 +224,4 @@ public static boolean isNativeUri(String uri) { return uri.startsWith("java:"); } -} \ No newline at end of file +} Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Filter.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Filter.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Filter.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -15,6 +15,7 @@ import ch.ethz.mxquery.model.CurrentBasedIterator; import ch.ethz.mxquery.model.Iterator; import ch.ethz.mxquery.model.XDMIterator; +import ch.ethz.mxquery.util.Hashtable; public class Filter extends CurrentBasedIterator { @@ -31,7 +32,7 @@ // if (!(predicate instanceof FFLWORIterator)) TypeInfo [] params = new TypeInfo[1]; params[0] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_EXACTLY_ONE); - TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.BOOLEAN,Type.OCCURRENCE_IND_EXACTLY_ONE)); + TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.BOOLEAN,Type.OCCURRENCE_IND_EXACTLY_ONE), new Hashtable()); SequenceTypeIterator st = new SequenceTypeIterator(tInfo, true, true, context, loc, true); st.setSubIters(subIters[0]); Iterator[] its = null; Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Fold.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Fold.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Fold.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -20,6 +20,7 @@ import ch.ethz.mxquery.model.VariableHolder; import ch.ethz.mxquery.model.Window; import ch.ethz.mxquery.model.XDMIterator; +import ch.ethz.mxquery.util.Hashtable; public class Fold extends CurrentBasedIterator implements RequestTypeMulti{ @@ -38,7 +39,7 @@ TypeInfo [] params = new TypeInfo[2]; params[0] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE); params[1] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE); - TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE)); + TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE), new Hashtable()); SequenceTypeIterator st = new SequenceTypeIterator(tInfo, true, true, context, loc, true); st.setSubIters(subIters[0]); st.setResettable(true); Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Map.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Map.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Map.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -15,6 +15,7 @@ import ch.ethz.mxquery.model.CurrentBasedIterator; import ch.ethz.mxquery.model.Iterator; import ch.ethz.mxquery.model.XDMIterator; +import ch.ethz.mxquery.util.Hashtable; public class Map extends CurrentBasedIterator { @@ -31,7 +32,7 @@ // if (!(predicate instanceof FFLWORIterator)) TypeInfo [] params = new TypeInfo[1]; params[0] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE); - TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE)); + TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE), new Hashtable()); SequenceTypeIterator st = new SequenceTypeIterator(tInfo, true, true, context, loc, true); st.setSubIters(subIters[0]); Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/MapPairs.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/MapPairs.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/MapPairs.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -18,6 +18,7 @@ import ch.ethz.mxquery.model.VariableHolder; import ch.ethz.mxquery.model.Window; import ch.ethz.mxquery.model.XDMIterator; +import ch.ethz.mxquery.util.Hashtable; public class MapPairs extends CurrentBasedIterator { Window wnd1, wnd2; @@ -34,7 +35,7 @@ params[0] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_EXACTLY_ONE); params[1] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_EXACTLY_ONE); - TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE)); + TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE), new Hashtable()); st = new SequenceTypeIterator(tInfo, true, true, context, loc, true); st.setSubIters(subIters[0]); st.setResettable(true); Modified: trunk/MXQuery/src/ch/ethz/mxquery/iterators/SequenceTypeIterator.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/iterators/SequenceTypeIterator.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/iterators/SequenceTypeIterator.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -39,6 +39,7 @@ import ch.ethz.mxquery.model.CurrentBasedIterator; import ch.ethz.mxquery.model.XDMIterator; import ch.ethz.mxquery.util.KXmlSerializer; +import ch.ethz.mxquery.util.Hashtable; public class SequenceTypeIterator extends CurrentBasedIterator { @@ -343,8 +344,8 @@ if (tok.getEventType()!=Type.FUNCTION_ITEM) return false; TypeInfo [] params = tInfo.getParameterTypes(); + FunctionSignature fs = ((FunctionItemToken)tok).getFunction().getFunctionSignature(); if (params != null) { - FunctionSignature fs = ((FunctionItemToken)tok).getFunction().getFunctionSignature(); if (fs.getArity() != params.length) return false; for (int i=0;i<params.length;i++) { @@ -359,6 +360,21 @@ !Type.isOccCompatible(retType.getOccurID(),tInfo.getReturnType().getOccurID())) return false; } + if (tInfo.getAnnotations().size() > 0) { + Hashtable annToCheck = tInfo.getAnnotations(); + if (annToCheck.containsKey(FunctionSignature.DETERMINISTIC_ANNOTATION) && + fs.isNonDeterministic()) + return false; + if (annToCheck.containsKey(FunctionSignature.SIMPLE_ANNOTATION) && + fs.getExpressionCategory() != XDMIterator.EXPR_CATEGORY_SIMPLE) + return false; + if (annToCheck.contains(FunctionSignature.UPDATING_ANNOTATION) && + fs.getExpressionCategory() != XDMIterator.EXPR_CATEGORY_SEQUENTIAL) + return false; + if (annToCheck.contains(FunctionSignature.SEQUENTIAL_ANNOTATION) && + fs.getExpressionCategory() != XDMIterator.EXPR_CATEGORY_UPDATING) + return false; + } return true; } @@ -391,7 +407,7 @@ FunctionSignature origSig = tok.getFunction().getFunctionSignature(); if (origSig.getArity() != targetType.getParameterTypes().length) throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE,"Wrong arity for function item",loc); - FunctionSignature fs = new FunctionSignature(tok.getQNameTokenValue(), targetType.getParameterTypes(), FunctionSignature.USER_DEFINED_FUNCTION, origSig.getExpressionCategory(), origSig.isNonDeterministic(), origSig.isPrivateFunction()); + FunctionSignature fs = new FunctionSignature(tok.getQNameTokenValue(), targetType.getParameterTypes(), FunctionSignature.USER_DEFINED_FUNCTION, origSig.getAllAnnotations()); Function fun = new Function(null,fs,tok.getFunction().getFunctionImplementation(getContext()),null,targetType.getReturnType()); return tok.coerce(fun); } Modified: trunk/MXQuery/src/ch/ethz/mxquery/model/VariableHolder.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/model/VariableHolder.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/model/VariableHolder.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -21,6 +21,7 @@ import ch.ethz.mxquery.bindings.WindowFactory; import ch.ethz.mxquery.contextConfig.Context; import ch.ethz.mxquery.contextConfig.XQStaticContext; +import ch.ethz.mxquery.datamodel.QName; import ch.ethz.mxquery.datamodel.Source; import ch.ethz.mxquery.datamodel.types.Type; import ch.ethz.mxquery.datamodel.types.TypeInfo; @@ -29,14 +30,19 @@ import ch.ethz.mxquery.exceptions.QueryLocation; import ch.ethz.mxquery.exceptions.StaticException; import ch.ethz.mxquery.iterators.VariableIterator; +import ch.ethz.mxquery.util.Hashtable; public class VariableHolder { + + public static final QName ASSIGNABLE_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","assignable"); + public static final QName UNASSIGNABLE_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","assignable"); + private XDMIterator iter; private boolean external; private boolean declared=false; private int useCounter=0; private boolean resetable=false; - private boolean assignable=true; + private Hashtable annotations; private int requriedOptions = 0; private int contextPos; private Context ctx; @@ -48,19 +54,20 @@ this.seqTypeIt = seqTypeIt; } - public VariableHolder(Context ctx, boolean external, int pos){ - this(ctx, null, external,pos); + public VariableHolder(Context ctx, boolean external, int pos, Hashtable ann){ + this(ctx, null, external,pos, ann); } // public VariableHolder(Context ctx, XDMIterator iter){ // this(ctx, iter, false); // } - public VariableHolder(Context ctx, XDMIterator iter, boolean external, int pos){ + public VariableHolder(Context ctx, XDMIterator iter, boolean external, int pos, Hashtable ann){ this.external = external; this.iter = iter; this.ctx = ctx; contextPos = pos; + annotations = ann; } public void setIter(XDMIterator iter) throws MXQueryException { @@ -113,13 +120,12 @@ } public boolean isAssignable() { - return assignable; + if (annotations.containsKey(ASSIGNABLE_ANNOTATION)) + return true; + else + return false; } - public void setAssignable(boolean assignable) { - this.assignable = assignable; - } - public TypeInfo getType() { if (seqTypeIt != null) return seqTypeIt.getStaticType(); @@ -196,7 +202,7 @@ VariableHolder copy = new VariableHolder( context, iter==null?null:iter.copy(context, null, false, nestedPredCtxStack), - external,contextPos); + external,contextPos, annotations); copy.setResetable(resetable); copy.useCounter = useCounter; if (seqTypeIt != null) @@ -242,5 +248,7 @@ return requriedOptions; } - + public Hashtable getAnnotations(){ + return annotations; + } } Modified: trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -294,30 +294,30 @@ Set pendingVars; } - private class FunctionOptions { +// private class FunctionOptions { +// +// public FunctionOptions(int expCategory, int visbility, int execution) { +// super(); +// this.expCategory = expCategory; +// if (visbility == VISIBILITY_PRIVATE) +// this.privateVisbility = true; +// else +// privateVisbility = false; +// if (execution == EXECUTION_NONDET) +// this.nondeterministic = true; +// else +// this.nondeterministic = false; +// } +// +// public static final int VISIBILITY_PUBLIC = 0; +// public static final int VISIBILITY_PRIVATE = 1; +// public static final int EXECUTION_DET = 0; +// public static final int EXECUTION_NONDET = 1; +// int expCategory; +// boolean privateVisbility; +// boolean nondeterministic; +// } - public FunctionOptions(int expCategory, int visbility, int execution) { - super(); - this.expCategory = expCategory; - if (visbility == VISIBILITY_PRIVATE) - this.privateVisbility = true; - else - privateVisbility = false; - if (execution == EXECUTION_NONDET) - this.nondeterministic = true; - else - this.nondeterministic = false; - } - - public static final int VISIBILITY_PUBLIC = 0; - public static final int VISIBILITY_PRIVATE = 1; - public static final int EXECUTION_DET = 0; - public static final int EXECUTION_NONDET = 1; - int expCategory; - boolean privateVisbility; - boolean nondeterministic; - } - /** * Used for static checking of continue and break<br/> * They can only appear in loop => during parsing of a break/coninue must be @@ -1498,6 +1498,8 @@ continue; VariableHolder vh = (VariableHolder) ht.get(qn); + if (vh.getAnnotations().containsKey(FunctionSignature.PRIVATE_ANNOTATION)) + continue; if (!vh.isExternal()) { // all variables need to be in the // target namespace of the module @@ -1510,8 +1512,10 @@ // getCurrentContext().registerExternalVariable(qn, // vh.getIter(), false); QName newQn = new QName(ns_uri, temp, qn.getLocalPart()); + Hashtable annotations = new Hashtable(); + annotations.put(FunctionSignature.PRIVATE_ANNOTATION, new XDMIterator[]{}); getCurrentContext().registerVariable(newQn, true, false, null, - false, false, true); + false, annotations, true); XDMIterator varVal; if (!(vh.getIter() instanceof Window)) { varVal = vh.getIter().copy(vh.getIter().getContext(),vh.getIter().getContext(),false,new Vector()); @@ -1539,10 +1543,75 @@ // boolean isCopy = false; if (parseKeyword("declare")) { int declareIndex = index; - boolean assignable = false; boolean expectVar = false; + if (co.isXquery11() + && (parseStringGetResult("context", true)) != null) { + + if (!parseString("item", true, false)) { + generateStaticError( + ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT, + "Error while parsing: 'item' expected (for context item)!"); + } + + TypeInfo typeInfo = new TypeInfo(); + if (parseKeyword("as")) { + typeInfo = SequenceType(); + seqTypeIt = new SequenceTypeIterator(typeInfo, true, false, + getCurrentContext(), getCurrentLoc(), false); + } + + boolean external = false; + Iterator expr = null; + if (parseKeyword("external")) { + external = true; + } + + if (parseString(":=", true, false)) { + createNewContextScope(); + expr = ExprSingle(); + checkingPrologInitializer(expr, Context.CONTEXT_ITEM); + removeContextScope(); + } else if (!external) + generateStaticError( + ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT, + "Variable declared in a prolog need to either have an initializing expression or marked external"); + + if (!parseString(";", true, false)) { + generateStaticError( + ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT, + "Error while parsing: ';' expected!"); + } + + if (contextItemDefined) + generateStaticError( + ErrorCodes.E0099_STATIC_CTXITEM_LATE_DUPLICATE, + "Duplicate context item definition"); + else + contextItemDefined = true; + + if (!getCurrentContext().checkVariableLocal( + Context.CONTEXT_ITEM)) + getCurrentContext().registerNewContextItem(); + + VariableHolder vh = getCurrentContext().getVariable( + Context.CONTEXT_ITEM); + if (seqTypeIt != null) { + vh.setSeqTypeIt(seqTypeIt); + } + + if (expr != null) { + getCurrentContext().setVariableValue(Context.CONTEXT_ITEM, + expr); + } + return true; + } else { + index = declareIndex; + } + + Hashtable annotations = Annotation(); + declareIndex = index; if (parseKeyword("assignable")) { - assignable = true; + annotations.put(VariableHolder.ASSIGNABLE_ANNOTATION, new XDMIterator[]{}); expectVar = true; } else if (parseKeyword("unassignable")) { expectVar = true; @@ -1560,9 +1629,7 @@ // skippingAllowed = true; if (qname == null) { - generateStaticError( - ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT, - "Error while parsing: 'QName' expected!"); + generateParseError("QName"); } TypeInfo typeInfo = new TypeInfo(); @@ -1597,10 +1664,10 @@ } if (external) { getCurrentContext().registerVariable(qname, external, - false, seqTypeIt, assignable); + false, seqTypeIt, annotations); } else { getCurrentContext().registerVariable(qname, external, - false, null, assignable); + false, null, annotations); } // In the web service case: exposing the global variables @@ -1612,9 +1679,10 @@ qname.getNamespacePrefix(), "get" + qname.getLocalPart()); TypeInfo getterTypeInfo[] = new TypeInfo[0]; + annotations.put(FunctionSignature.NONDETERMINISTIC_ANNOTATION, new XDMIterator[]{}); getterSignature = new FunctionSignature(getterFunctionName, getterTypeInfo, FunctionSignature.SYSTEM_FUNCTION, - XDMIterator.EXPR_CATEGORY_SIMPLE, true, false); + annotations); VariableIterator vIter = new VariableIterator( getCurrentContext(), qname, false, getCurrentLoc()); vIter.setReturnType(typeInfo.getType()); @@ -1648,71 +1716,8 @@ index = declareIndex; } - if (co.isXquery11() - && (parseStringGetResult("context", true)) != null) { - if (!parseString("item", true, false)) { - generateStaticError( - ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT, - "Error while parsing: 'item' expected (for context item)!"); - } - - TypeInfo typeInfo = new TypeInfo(); - if (parseKeyword("as")) { - typeInfo = SequenceType(); - seqTypeIt = new SequenceTypeIterator(typeInfo, true, false, - getCurrentContext(), getCurrentLoc(), false); - } - - boolean external = false; - Iterator expr = null; - if (parseKeyword("external")) { - external = true; - } - - if (parseString(":=", true, false)) { - createNewContextScope(); - expr = ExprSingle(); - checkingPrologInitializer(expr, Context.CONTEXT_ITEM); - removeContextScope(); - } else if (!external) - generateStaticError( - ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT, - "Variable declared in a prolog need to either have an initializing expression or marked external"); - - if (!parseString(";", true, false)) { - generateStaticError( - ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT, - "Error while parsing: ';' expected!"); - } - - if (contextItemDefined) - generateStaticError( - ErrorCodes.E0099_STATIC_CTXITEM_LATE_DUPLICATE, - "Duplicate context item definition"); - else - contextItemDefined = true; - - if (!getCurrentContext().checkVariableLocal( - Context.CONTEXT_ITEM)) - getCurrentContext().registerNewContextItem(); - - VariableHolder vh = getCurrentContext().getVariable( - Context.CONTEXT_ITEM); - if (seqTypeIt != null) { - vh.setSeqTypeIt(seqTypeIt); - } - - if (expr != null) { - getCurrentContext().setVariableValue(Context.CONTEXT_ITEM, - expr); - } - return true; - } else { - index = declareIndex; - } - - FunctionOptions funOpts = functionOptions(); + annotations = functionOptions(annotations); if (parseKeyword("function")) { @@ -1731,7 +1736,7 @@ .getDefaultFunctionNamespace()); // skippingAllowed = true; - Function fn = parseFunctionDef(funOpts, qname,true); + Function fn = parseFunctionDef(annotations, qname,true); if (!parseString(";", true, false)) { generateStaticError( ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT, @@ -1803,7 +1808,68 @@ return false; } - private Function parseFunctionDef(FunctionOptions funOpts, QName qname, boolean allowExternal) + private Hashtable Annotation() throws MXQueryException { + Hashtable annotations = new Hashtable(); + while (co.isXquery30() && parseString("%",true,false)) { + QName annName = EQName(); + if (annName == null) + generateParseError("EQName"); + + if (annName.getNamespaceURI() == null) + if (annName.getNamespacePrefix() == null + || annName.getNamespacePrefix().equals("")) { + annName.setNamespaceURI(getCurrentContext() + .getDefaultFunctionNamespace()); + } else { + annName = (QName)annName.resolveQNameNamespace(getCurrentContext(), + false); + } + Vector literals = new Vector(); + if (parseString("(",true,false)) { + XDMIterator lit = Literal(); + if (lit == null) + generateParseError("Literal"); + else + literals.addElement(lit); + while (parseString(",", true, false)) { + lit = Literal(); + if (lit == null) + generateParseError("Literal"); + literals.addElement(lit); + } + parseKeywordYieldError(")"); + + } + XDMIterator [] annotationLiterals = new XDMIterator[literals.size()]; + literals.copyInto(annotationLiterals); + if (annotations.containsKey(annName)) { + if (annName.equals(FunctionSignature.DETERMINISTIC_ANNOTATION)|| + annName.equals(FunctionSignature.NONDETERMINISTIC_ANNOTATION)|| + annName.equals(FunctionSignature.PRIVATE_ANNOTATION)|| + annName.equals(FunctionSignature.PUBLIC_ANNOTATION)) + generateStaticError(ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION, + "Duplicate annotation "+annName); + else + generateStaticError(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, + "Duplicate annotation "+annName); + } + if (annName.equals(FunctionSignature.PRIVATE_ANNOTATION)|| + annName.equals(FunctionSignature.PUBLIC_ANNOTATION)) + checkVisibilityAnnotation(annotations); + if (annName.equals(FunctionSignature.DETERMINISTIC_ANNOTATION)|| + annName.equals(FunctionSignature.NONDETERMINISTIC_ANNOTATION)) + checkDeterministicAnnotation(annotations); + if (annName.equals(FunctionSignature.SIMPLE_ANNOTATION)|| + annName.equals(FunctionSignature.UPDATING_ANNOTATION)|| + annName.equals(FunctionSignature.SEQUENTIAL_ANNOTATION)) + checkExprTypeAnnotation(annotations); + + annotations.put(annName, annotationLiterals); + } + return annotations; + } + + private Function parseFunctionDef(Hashtable annotations, QName qname, boolean allowExternal) throws StaticException, MXQueryException { Iterator seqTypeIt; if (!parseString("(", true, false)) { @@ -1856,7 +1922,7 @@ if (!returnType.isUndefined() && !co.isScripting() - && funOpts.expCategory == XDMIterator.EXPR_CATEGORY_UPDATING) + && annotations.containsKey(FunctionSignature.UPDATING_ANNOTATION)) throw new StaticException( ErrorCodes.U0028_UPDATE_STATIC_FUNCTION_UPDATING_RETURNTYPE, "'updating' function must not specify a return type", @@ -1868,7 +1934,7 @@ external = true; // TODO: Insert runtime PUL checking for external functions } else { - if (funOpts.nondeterministic) + if (annotations.containsKey(FunctionSignature.NONDETERMINISTIC_ANNOTATION)) generateStaticError( ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION, "A UDF cannot be specified as nondeterminitic"); @@ -1886,13 +1952,16 @@ true, true, getCurrentContext(), getCurrentLoc(), true); // streaming } + Hashtable paramAnnotations = new Hashtable(); + if (annotations.containsKey(FunctionSignature.SEQUENTIAL_ANNOTATION)) + paramAnnotations.put(VariableHolder.ASSIGNABLE_ANNOTATION, new XDMIterator[]{}); getCurrentContext().registerVariable( (QName) paramNames.elementAt(i), false, - seqTypeIt, false); + seqTypeIt, annotations); } Iterator body; - if (funOpts.expCategory == XDMIterator.EXPR_CATEGORY_SEQUENTIAL) { + if (annotations.containsKey(FunctionSignature.SEQUENTIAL_ANNOTATION)) { body = Block(); } else { body = EnclosedExpr(false); @@ -1905,15 +1974,22 @@ seqTypeIt = null; } + int exprCategory = XDMIterator.EXPR_CATEGORY_SIMPLE; + if (annotations.containsKey(FunctionSignature.UPDATING_ANNOTATION)) + exprCategory = XDMIterator.EXPR_CATEGORY_UPDATING; + if (annotations.containsKey(FunctionSignature.SEQUENTIAL_ANNOTATION)) + exprCategory = XDMIterator.EXPR_CATEGORY_SEQUENTIAL; + funcCallIter = new UserdefFuncCall(getCurrentContext(), qname, paramArr, arrParamTypes, body, returnType, - seqTypeIt, funOpts.expCategory, getCurrentLoc()); + seqTypeIt, exprCategory, getCurrentLoc()); funcCallIter.staticInit(); funcCallIter = (UserdefFuncCall)funcCallIter.require(0); if (!allowExternal) { // if inline function // compute the closure // all variable references which are not resolved within the + // context Vector subs = funcCallIter.getAllSubItersRecursive(); Vector closure = new Vector(); for (int i=0;i<subs.size();i++) { @@ -1942,8 +2018,7 @@ fs = new FunctionSignature(qname, arrParamTypes, FunctionSignature.USER_DEFINED_FUNCTION, - funOpts.expCategory, !funOpts.nondeterministic, - funOpts.privateVisbility); + annotations); // Check if the category can be resolved now funcCallIter.getExpressionCategoryType(co.isScripting()); addedFunctions.addElement(funcCallIter); @@ -1951,80 +2026,67 @@ } else { fs = new FunctionSignature(qname, arrParamTypes, FunctionSignature.EXTERNAL_FUNCTION, - funOpts.expCategory, !funOpts.nondeterministic, - !funOpts.privateVisbility); + annotations); } - Function fn = new Function(null, fs, funcCallIter, null, null); + Function fn = new Function(null, fs, funcCallIter, null, returnType); return fn; } - private FunctionOptions functionOptions() throws MXQueryException { - - int expressionCategory = -1; - int visibilityMode = -1; - int deterministicMode = -1; - + private Hashtable functionOptions(Hashtable annotations) throws MXQueryException { while (true) { int oldPos = index; if (co.isUpdate() && parseKeyword("updating")) { - if (expressionCategory != -1) - generateStaticError( - ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT, - "Only a one of 'updating','sequential','simple' allowed"); - expressionCategory = XDMIterator.EXPR_CATEGORY_UPDATING; + checkExprTypeAnnotation(annotations); + annotations.put(FunctionSignature.UPDATING_ANNOTATION, new XDMIterator[]{}); } else if (co.isScripting() && parseKeyword("sequential")) { - if (expressionCategory != -1) - generateStaticError( - ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT, - "Only a one of 'updating','sequential','simple' allowed"); - expressionCategory = XDMIterator.EXPR_CATEGORY_SEQUENTIAL; + checkExprTypeAnnotation(annotations); } else if (parseKeyword("simple")) { - if (expressionCategory != -1) - generateStaticError( - ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT, - "Only a one of 'updating','sequential','simple' allowed"); + checkExprTypeAnnotation(annotations); + annotations.put(FunctionSignature.SEQUENTIAL_ANNOTATION, new XDMIterator[]{}); } else if (co.isXquery11() && parseKeyword("private")) { - if (visibilityMode != -1) - generateStaticError( - ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION, - "Only a one of 'private','public'allowed"); - visibilityMode = FunctionOptions.VISIBILITY_PRIVATE; + checkVisibilityAnnotation(annotations); + annotations.put(FunctionSignature.PRIVATE_ANNOTATION, new XDMIterator[]{}); } else if (co.isXquery11() && parseKeyword("public")) { - if (visibilityMode != -1) - generateStaticError( - ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION, - "Only a one of 'private','public'allowed"); - visibilityMode = FunctionOptions.VISIBILITY_PUBLIC; + checkVisibilityAnnotation(annotations); + annotations.put(FunctionSignature.PUBLIC_ANNOTATION, new XDMIterator[]{}); } else if (co.isXquery11() && parseKeyword("nondeterministic")) { - if (deterministicMode != -1) - generateStaticError( - ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION, - "Only a one of 'deterministic','nondeterministic'allowed"); - deterministicMode = FunctionOptions.EXECUTION_NONDET; + checkDeterministicAnnotation(annotations); + annotations.put(FunctionSignature.NONDETERMINISTIC_ANNOTATION, new XDMIterator[]{}); } else if (co.isXquery11() && parseKeyword("deterministic")) { - if (deterministicMode != -1) - generateStaticError( - ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION, - "Only a one of 'deterministic','nondeterministic'allowed"); - deterministicMode = FunctionOptions.EXECUTION_DET; + checkDeterministicAnnotation(annotations); + annotations.put(FunctionSignature.DETERMINISTIC_ANNOTATION, new XDMIterator[]{}); } else { index = oldPos; break; } } + return annotations; + } - if (expressionCategory == -1) - expressionCategory = XDMIterator.EXPR_CATEGORY_SIMPLE; - if (visibilityMode == -1) - visibilityMode = FunctionOptions.VISIBILITY_PUBLIC; // public - if (deterministicMode == -1) - deterministicMode = FunctionOptions.EXECUTION_DET; + void checkDeterministicAnnotation(Hashtable annotations) + throws StaticException { + if (annotations.containsKey(FunctionSignature.DETERMINISTIC_ANNOTATION) || annotations.containsKey(FunctionSignature.NONDETERMINISTIC_ANNOTATION)) + generateStaticError( + ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION, + "Only a one of 'deterministic','nondeterministic'allowed"); + } - FunctionOptions fo = new FunctionOptions(expressionCategory, - visibilityMode, deterministicMode); + void checkVisibilityAnnotation(Hashtable annotations) + throws StaticException { + if (annotations.containsKey(FunctionSignature.PUBLIC_ANNOTATION) || annotations.containsKey(FunctionSignature.PRIVATE_ANNOTATION)) + generateStaticError( + ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION, + "Only a one of 'private','public'allowed"); + } - return fo; + void checkExprTypeAnnotation(Hashtable annotations) throws StaticException { + if (annotations.containsKey(FunctionSignature.SEQUENTIAL_ANNOTATION) || + annotations.containsKey(FunctionSignature.SIMPLE_ANNOTATION) || + annotations.containsKey(FunctionSignature.UPDATING_ANNOTATION)) + generateStaticError( + ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT, + "Only a one of 'updating','sequential','simple' allowed"); } private void checkingPrologInitializer(Iterator expr, QName varname) @@ -2637,7 +2699,7 @@ extendCurrentContextScope(); getCurrentContext().registerVariable(varQName, true, seqTypeIt, - false); + new Hashtable()); Context current = getCurrentContext(); return generatePatternIterator(varQName, qType, seq, windowType, selectionType, current, outerContext, pat); @@ -2910,7 +2972,7 @@ } } getCurrentContext().registerVariable(varQName, true, seqTypeIt, - false); + new Hashtable()); return generateForseqIterator(varQName, qType, seq, windowType, outerContext, startVars, startExpr, forceEnd, endVars, @@ -2973,7 +3035,7 @@ } if (windowType == 0) { getCurrentContext().registerVariable(varQName, true, seqTypeIt, - false); + new Hashtable()); return new ForseqGeneralIterator(getCurrentContext(), windowType, varQName, qType, seq, ForseqIterator.ORDER_MODE_END, getCurrentLoc()); @@ -3045,7 +3107,7 @@ resolveVarsOnReset = false; getCurrentContext().registerVariable(varQName, true, seqTypeIt, - false); + new Hashtable()); return generateForseqIterator(varQName, qType, seq, windowType, outerContext, startVars, startExpr, forceEnd, endVars, @@ -3248,7 +3310,7 @@ if ((inIt = ExprSingle()) != null) { // wait with the new context until in is parsed extendCurrentContextScope().registerVariable(q, true, - seqTypeIt, false); + seqTypeIt, new Hashtable()); if (p != null) { getCurrentContext().registerVariable(p, true); @@ -3302,7 +3364,7 @@ // parsed extendCurrentContextScope() .registerVariable(qname, false, - seqTypeIt, false); + seqTypeIt, new Hashtable()); if (p1 != null) { getCurrentContext().registerVariable( p1, true); @@ -3452,7 +3514,7 @@ if (score) { useFTScoring = false; extendCurrentContextScope().registerVariable(q, - false, seqTypeIt, false); + false, seqTypeIt, new Hashtable()); Score s = new Score(inIt, getCurrentContext(), getCurrentLoc()); its.insertElementAt(new LetIterator( @@ -3461,7 +3523,7 @@ } else { extendCurrentContextScope().registerVariable(q, - false, seqTypeIt, false); + false, seqTypeIt, new Hashtable()); its.insertElementAt(new LetIterator( getCurrentContext(), new Iterator[] { inIt }, q, t, @@ -3506,7 +3568,7 @@ if ((inIt1 = ExprSingle()) != null) { extendCurrentContextScope() .registerVariable(qname, false, - seqTypeIt, false); + seqTypeIt, new Hashtable()); its.insertElementAt(new LetIterator( getCurrentContext(), new Iterator[] { inIt1 }, qname, @@ -3680,11 +3742,12 @@ } private TypeInfo FunctionTest() throws MXQueryException { + Hashtable annotations = Annotation(); if (parseKeyword("function")) if (parseString("(",true,false)) { if (parseString("*",true,false)) { parseKeywordYieldError(")"); - return new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE); + return new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE,null,null,annotations); } else { Vector params = new Vector(); TypeInfo param; @@ -3709,7 +3772,7 @@ TypeInfo returnType = TypeDeclaration(); TypeInfo [] paramTypes = new TypeInfo[params.size()]; params.copyInto(paramTypes); - return new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE,paramTypes,returnType); + return new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE,paramTypes,returnType,annotations); } } @@ -3986,7 +4049,7 @@ createNewContextScope(); inIt.setContext(getCurrentContext(), true); getCurrentContext().registerVariable(q, false, - seqTypeIt, false); + seqTypeIt, new Hashtable()); inIt = new ForIterator(getCurrentContext(), new Iterator[] { inIt }, q, t, null, getCurrentLoc(), false); @@ -4014,7 +4077,7 @@ if ((inIt1 = ExprSingle()) != null) { extendCurrentContextScope() .registerVariable(qname, false, - seqTypeIt, false); + seqTypeIt, new Hashtable()); inIt1 = new ForIterator( getCurrentContext(), new Iterator[] { inIt1 }, @@ -6517,7 +6580,7 @@ private Iterator InlineFunction() throws MXQueryException { int startIndex = index; if (parseKeyword("function")) { - Function fn = parseFunctionDef(new FunctionOptions(XDMIterator.EXPR_CATEGORY_SIMPLE, FunctionOptions.VISIBILITY_PUBLIC, FunctionOptions.EXECUTION_DET), null, false); + Function fn = parseFunctionDef(new Hashtable(), null, false); if (fn == null) { index = startIndex; return null; @@ -7135,7 +7198,7 @@ } TypeInfo [] wType = new TypeInfo[types.size()]; types.copyInto(wType); - FunctionSignature fs = new FunctionSignature(null,wType,FunctionSignature.USER_DEFINED_FUNCTION,sig.getExpressionCategory(),sig.isNonDeterministic(),sig.isPrivateFunction()); + FunctionSignature fs = new FunctionSignature(null,wType,FunctionSignature.USER_DEFINED_FUNCTION,sig.getAllAnnotations()); FunctionItemWrapperIterator fi = new FunctionItemWrapperIterator(getCurrentContext(),it, placeHolders, applied,getCurrentLoc()); Function fu = new Function(null,fs,fi,null,null); FunctionItemToken ft = new FunctionItemToken(fu); @@ -8648,8 +8711,10 @@ getCurrentContext(), getCurrentLoc(), false); } try { + Hashtable annotations = new Hashtable(); + annotations.put(VariableHolder.ASSIGNABLE_ANNOTATION, new XDMIterator[]{}); getCurrentContext().registerVariable(varName, false, - seqTypeIt, true); + seqTypeIt, annotations); } catch (StaticException se) { if (se.getErrorCode() .equals(ErrorCodes.E0049_STATIC_MODULE_DUPLICATE_VARIABLE_NAMES)) Modified: trunk/MXQuery/src/ch/ethz/mxquery/query/parser/SchemaParser.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/query/parser/SchemaParser.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/query/parser/SchemaParser.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -48,6 +48,7 @@ import ch.ethz.mxquery.functions.FunctionSignature; import ch.ethz.mxquery.functions.xs.XSConstructorIterator; import ch.ethz.mxquery.model.XDMIterator; +import ch.ethz.mxquery.util.Hashtable; import ch.ethz.mxquery.util.URIUtils; public class SchemaParser implements DOMErrorHandler { @@ -288,9 +289,10 @@ TypeInfo[] paramTypes = new TypeInfo[1]; paramTypes[0] = new TypeInfo(Type.ITEM, Type.OCCURRENCE_IND_ZERO_OR_MORE); + Hashtable annotations = new Hashtable(); + annotations.put(FunctionSignature.PRIVATE_ANNOTATION, new XDMIterator[]{}); FunctionSignature signature = new FunctionSignature(qn, paramTypes, - FunctionSignature.SYSTEM_FUNCTION, - XDMIterator.EXPR_CATEGORY_SIMPLE, false, true); + FunctionSignature.SYSTEM_FUNCTION,annotations); XDMIterator it = XSConstructorIterator.getBaseTypeConstructor(ctx, Type.getTypeFootprint( qn, dict), dict); if (it != null) { Modified: trunk/MXQuery/src/ch/ethz/mxquery/query/webservice/WSDLHandler.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/query/webservice/WSDLHandler.java 2011-05-23 09:59:07 UTC (rev 4365) +++ trunk/MXQuery/src/ch/ethz/mxquery/query/webservice/WSDLHandler.java 2011-05-24 13:32:19 UTC (rev 4366) @@ -314,7 +314,10 @@ // only function name and arity params[i] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE); } - FunctionSignature signature = new FunctionSignature(functionName,params,FunctionSignature.EXTERNAL_FUNCTION,XDMIterator.EXPR_CATEGORY_SEQUENTIAL,true, false); + Hashtable annotations = new Hashtable(); + annotations.put(FunctionSignature.SEQUENTIAL_ANNOTATION,new XDMIterator[]{}); + annotations.put(FunctionSignature.NONDETERMINISTIC_ANNOTATION,new XDMIterator[]{}); + FunctionSignature signature = new FunctionSignature(functionName,params,FunctionSignature.EXTERNAL_FUNCTION,annotations); Function function = new Function(null,signature,wf, null, null); context.addFunction(function, true, true); } Modified: trunk/MXQuery/src/examples/ExternalFunctionExample.java ======================================... [truncated message content] |