|
From: <pm_...@us...> - 2011-05-12 11:10:50
|
Revision: 4331
http://mxquery.svn.sourceforge.net/mxquery/?rev=4331&view=rev
Author: pm_fischer
Date: 2011-05-12 11:10:38 +0000 (Thu, 12 May 2011)
Log Message:
-----------
Merge HOF implementation
Modified Paths:
--------------
trunk/MXQuery/midp_src/ch/ethz/mxquery/query/webservice/WSDLHandler.java
trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/Type.java
trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/TypeInfo.java
trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/NamedToken.java
trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/QNameToken.java
trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/Token.java
trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/TokenInterface.java
trunk/MXQuery/src/ch/ethz/mxquery/exceptions/ErrorCodes.java
trunk/MXQuery/src/ch/ethz/mxquery/extensionsModules/expathhttp/HttpIO.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/FG.xml
trunk/MXQuery/src/ch/ethz/mxquery/functions/Function.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionGallery.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/Abs.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/DataValuesIterator.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Deep_equal.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/FNString.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Node_Name.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Put.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/SubString.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/SubstringAfter.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/SubstringBefore.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Translate.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/UpperCase.java
trunk/MXQuery/src/ch/ethz/mxquery/iterators/NativeFuncCall.java
trunk/MXQuery/src/ch/ethz/mxquery/iterators/SequenceTypeIterator.java
trunk/MXQuery/src/ch/ethz/mxquery/iterators/UserdefFuncCall.java
trunk/MXQuery/src/ch/ethz/mxquery/iterators/UserdefFuncCallLateBinding.java
trunk/MXQuery/src/ch/ethz/mxquery/iterators/VariableIterator.java
trunk/MXQuery/src/ch/ethz/mxquery/iterators/XMLContent.java
trunk/MXQuery/src/ch/ethz/mxquery/model/Iterator.java
trunk/MXQuery/src/ch/ethz/mxquery/model/XDMIterator.java
trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java
trunk/MXQuery/src/ch/ethz/mxquery/query/parser/SEParser.java
trunk/MXQuery/src/ch/ethz/mxquery/query/parser/SchemaParser.java
trunk/MXQuery/src/ch/ethz/mxquery/query/webservice/WSDLGenerator.java
trunk/MXQuery/src/ch/ethz/mxquery/query/webservice/WSDLHandler.java
trunk/MXQuery/src/ch/ethz/mxquery/query/webservice/WSServer.java
trunk/MXQuery/src/ch/ethz/mxquery/sms/MMimpl/StreamStoreInput.java
trunk/MXQuery/src/ch/ethz/mxquery/sms/MMimpl/TokenBufferStore.java
trunk/MXQuery/src/examples/ExternalFunctionExample.java
trunk/MXQuery/xqib_src/ch/ethz/mxquery/extensionsModules/expathhttp/HttpIO.java
trunk/MXQuery/xqib_src/ch/ethz/mxquery/functions/Function.java
trunk/MXQuery/xqib_src/ch/ethz/mxquery/functions/FunctionGallery.java
trunk/MXQuery_Testing/src/ch/ethz/mxquery/test/TypeTest.java
Added Paths:
-----------
trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/FunctionItemToken.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Function_arity.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Function_name.java
trunk/MXQuery/src/ch/ethz/mxquery/iterators/ClosureIterator.java
trunk/MXQuery/src/ch/ethz/mxquery/iterators/FunctionItemWrapperIterator.java
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-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/midp_src/ch/ethz/mxquery/query/webservice/WSDLHandler.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -201,7 +201,7 @@
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);
- Function function = new Function(null,signature,wf,null,-1);
+ Function function = new Function(null,signature,wf,null,null);
context.addFunction(function, true, true);
}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/Type.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/Type.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/Type.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -44,6 +44,8 @@
public final static int ITEM = 0;
+ public final static int FUNCTION_ITEM = 1;
+
public final static int NODE = 2; // 0000000000000000000000000000010
/** Token types */
@@ -197,6 +199,9 @@
public static final int TYPE_NK_EMPTY_SEQ_TEST = 64;
/** occurrence indicators consts */
+
+ public final static int OCCURRENCE_IND_EMPTY = 0;
+
public final static int OCCURRENCE_IND_EXACTLY_ONE = 1;
public final static int OCCURRENCE_IND_ZERO_OR_ONE = 2;
@@ -625,7 +630,9 @@
case END_SEQUENCE:
q = new QName(null, "END_SEQUENCE");
break;
-
+ case FUNCTION_ITEM:
+ q = new QName(null, "function(*)");
+ break;
default:
throw new RuntimeException("Incorrect type passed. Type " + type + " is not supported in method getTypeQName");
}
@@ -1093,4 +1100,33 @@
public static boolean isNilled(int type) {
return ((type & MASK_CHECK_NILLABLE) == MASK_CHECK_NILLABLE);
}
+ /**
+ * Check if aocc is covered by bocc, as in XQ 3.0: 2.5.5.1 The SequenceType Subtype Judgement
+ * @param aocc Occurence indicator that needs to be checked
+ * @param bocc Occurence indicator that is provided
+ * @return true if aocc is contained by bocc, false otherwise
+ */
+ public static boolean isOccCompatible(int aocc, int bocc) {
+ if (aocc == bocc)
+ return true;
+ switch (bocc) {
+ case Type.OCCURRENCE_IND_EMPTY:
+ return false;
+ case Type.OCCURRENCE_IND_EXACTLY_ONE:
+ return false;
+ case Type.OCCURRENCE_IND_ZERO_OR_ONE:
+ if (aocc == Type.OCCURRENCE_IND_ZERO_OR_MORE || aocc==Type.OCCURRENCE_IND_ONE_OR_MORE)
+ return false;
+ else return true;
+ case Type.OCCURRENCE_IND_ZERO_OR_MORE:
+ return true;
+ case Type.OCCURRENCE_IND_ONE_OR_MORE:
+ if (aocc == Type.OCCURRENCE_IND_EXACTLY_ONE)
+ return true;
+ else return false;
+ }
+ // TODO: Infinite types
+ return true;
+ }
+
}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/TypeInfo.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/TypeInfo.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/TypeInfo.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -31,6 +31,8 @@
private int occurID = UNDEFINED;
private XQName qn = null;
private int typeAnnotation =UNDEFINED;
+ private TypeInfo [] paramTypes = null;
+ private TypeInfo returnType=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);
@@ -56,6 +58,14 @@
this.qn = name;
this.typeAnnotation = typeAn;
}
+
+ public TypeInfo(int type, int occurIndID, TypeInfo[] params,TypeInfo retType) {
+ this.type = type;
+ this.occurID = occurIndID;
+ this.paramTypes = params;
+ this.returnType = retType;
+ }
+
public int getTypeAnnotation() {
int t;
@@ -67,8 +77,9 @@
t = this.type & MASK_CLEAN_START_TAG;
}
- if (t == 0) return -1;
- else return t;
+ if (t == 0) return Type.ANY_TYPE;
+ else
+ return t;
//return typeAnnotation;
}
@@ -145,11 +156,21 @@
return (type == UNDEFINED);
}
+ public TypeInfo [] getParameterTypes() {
+ return paramTypes;
+ }
+
+ public TypeInfo getReturnType() {
+ return returnType;
+ }
+
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);
else
- return new TypeInfo(type, occurID,qn);
+ return new TypeInfo(type, occurID,qn);
}
public String toString() {
Added: trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/FunctionItemToken.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/FunctionItemToken.java (rev 0)
+++ trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/FunctionItemToken.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -0,0 +1,54 @@
+package ch.ethz.mxquery.datamodel.xdm;
+
+import java.util.Enumeration;
+
+import ch.ethz.mxquery.datamodel.QName;
+import ch.ethz.mxquery.datamodel.types.Type;
+import ch.ethz.mxquery.functions.Function;
+import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.Hashtable;
+
+public class FunctionItemToken extends Token{
+ Function func;
+ Hashtable closure;
+ public FunctionItemToken(Function fun) {
+ super(Type.FUNCTION_ITEM,null,null);
+ func = fun;
+ }
+ public FunctionItemToken(Function fun, Hashtable closure) {
+ super(Type.FUNCTION_ITEM,null,null);
+ func = fun;
+ this.closure = closure;
+ }
+
+ public long getLong() {
+ return func.getFunctionSignature().getArity();
+ }
+ public QName getQNameTokenValue() {
+ return (QName)func.getFunctionSignature().getName();
+ }
+ public Function getFunction() {
+ return func;
+ }
+ public TokenInterface copy() {
+ return new FunctionItemToken(func,closure);
+ }
+ public QName [] getClosureVarNames() {
+ if (closure != null) {
+ QName [] res = new QName[closure.size()];
+ Enumeration varNames = closure.keys();
+ int i=0;
+ while (varNames.hasMoreElements())
+ res[i++] = (QName) varNames.nextElement();
+ return res;
+ } else return new QName[]{};
+ }
+
+ public XDMIterator getClosureValue(QName qn) {
+ return (XDMIterator) closure.get(qn);
+ }
+
+ public FunctionItemToken coerce(Function fun) {
+ return new FunctionItemToken(fun, closure);
+ }
+}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/NamedToken.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/NamedToken.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/NamedToken.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -32,8 +32,6 @@
public String [] getIDREFS();
- public String getPrefix();
-
public NamedToken copy(XQName newName) throws MXQueryException;
public NamedToken copyStrip();
Modified: trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/QNameToken.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/QNameToken.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/QNameToken.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -19,7 +19,7 @@
import ch.ethz.mxquery.datamodel.QName;
import ch.ethz.mxquery.datamodel.types.Type;
-public final class QNameToken extends Token {
+public class QNameToken extends Token {
private final QName value;
public QNameToken(Identifier id, QName value) {
@@ -29,25 +29,15 @@
public QNameToken(QNameToken token) {
super(token);
- this.value = token.getQName();
+ this.value = token.getQNameTokenValue();
}
-
- public QName getQName() {
- return this.value;
- }
-
-
+
/* (non-Javadoc)
* @see ch.ethz.mxquery.util.tokens.Token#getNS()
*/
public String getNS() {
return value.getNamespaceURI();
}
-
- public void setNS(String uri) {
- value.setNamespaceURI(uri);
- }
-
public QName getQNameTokenValue() {
return this.value;
Modified: trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/Token.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/Token.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/Token.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -153,6 +153,14 @@
}
/* (non-Javadoc)
+ * @see ch.ethz.mxquery.datamodel.xdm.TokenInterface#getLocal()
+ */
+ public String getPrefix() {
+ return null;
+ }
+
+
+ /* (non-Javadoc)
* @see ch.ethz.mxquery.datamodel.xdm.TokenInterface#setId(ch.ethz.mxquery.datamodel.Identifier)
*/
public void setNodeId(Identifier id) throws MXQueryException{
Modified: trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/TokenInterface.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/TokenInterface.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/datamodel/xdm/TokenInterface.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -30,6 +30,8 @@
public abstract String getNS();
public abstract String getLocal();
+
+ public abstract String getPrefix();
/**
* Assigns a node ID to this node
* While tokens are meant to be immutable, we make an exception
Modified: trunk/MXQuery/src/ch/ethz/mxquery/exceptions/ErrorCodes.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/exceptions/ErrorCodes.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/exceptions/ErrorCodes.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -230,6 +230,9 @@
public final static QName F0033_REGULAR_EXPRESSION_MATCHES_EMPTY = new QName(XQStaticContext.URI_ERR,"err","FORX0003");
public final static QName F0034_INVALID_REPLACEMENT_STRING = new QName(XQStaticContext.URI_ERR,"err","FORX0004");
public final static QName F0035_AGUMENT_NOD_NO_TYPED_VALUE = new QName(XQStaticContext.URI_ERR,"err","FOTY0012");
+ public final static QName F0036_FUNCTION_ITEM_AT_FN_DATA = new QName(XQStaticContext.URI_ERR,"err","FOTY0013");
+ public final static QName F0037_FUNCTION_ITEM_AT_FN_STRING = new QName(XQStaticContext.URI_ERR,"err","FOTY0014");
+ public final static QName F0038_FUNCTION_ITEM_AT_DEEP_EQUAL = new QName(XQStaticContext.URI_ERR,"err","FOTY0015");
// Serializer error codes
public final static QName S0001_ATTRIBUTE_OR_NAMESPACE_NOT_ALLOWED_HERE = new QName(XQStaticContext.URI_ERR,"err","SENR0001");
Modified: trunk/MXQuery/src/ch/ethz/mxquery/extensionsModules/expathhttp/HttpIO.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/extensionsModules/expathhttp/HttpIO.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/extensionsModules/expathhttp/HttpIO.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -175,7 +175,7 @@
TypeInfo requestElement = new TypeInfo(Type.START_TAG, Type.OCCURRENCE_IND_EXACTLY_ONE,requestName);
- SequenceTypeIterator sq = new SequenceTypeIterator(requestElement, true, false, childContext, loc);
+ SequenceTypeIterator sq = new SequenceTypeIterator(requestElement, true, false, childContext, loc, false);
sq.setSubIters(subIters[0]);
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/FG.xml
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/FG.xml 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/FG.xml 2011-05-12 11:10:38 UTC (rev 4331)
@@ -388,6 +388,20 @@
<className>Floor</className>
</functionDescription>
<functionDescription>
+ <functionName>function-name</functionName>
+ <parameters>
+ <paramType>function(*)</paramType>
+ </parameters>
+ <className>Function_name</className>
+ </functionDescription>
+ <functionDescription>
+ <functionName>function-arity</functionName>
+ <parameters>
+ <paramType>function(*)</paramType>
+ </parameters>
+ <className>Function_arity</className>
+ </functionDescription>
+ <functionDescription>
<functionName>generate-id</functionName>
<parameters>
<paramType>node()</paramType>
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/Function.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/Function.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/Function.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -19,6 +19,7 @@
import ch.ethz.mxquery.contextConfig.Context;
import ch.ethz.mxquery.datamodel.QName;
+import ch.ethz.mxquery.datamodel.types.TypeInfo;
import ch.ethz.mxquery.exceptions.ErrorCodes;
import ch.ethz.mxquery.exceptions.MXQueryException;
import ch.ethz.mxquery.exceptions.QueryLocation;
@@ -38,20 +39,20 @@
protected String className;
- protected FunctionSignature signature;
+ FunctionSignature signature;
protected XDMIterator iter;
- int returnType = -1;
+ TypeInfo returnType = null;
String operation = null;
public Function(String className, FunctionSignature signature,
- XDMIterator iter, String op, int dataType) {
+ XDMIterator iter, String op, TypeInfo retDataType) {
this.className = className;
this.iter = iter;
this.signature = signature;
this.operation = op;
- this.returnType = dataType;
+ this.returnType = retDataType;
if (iter != null)
return;
@@ -78,8 +79,8 @@
public Function getAsExternalFunction(String prefix) {
QName fName = new QName(signature.getName().getNamespaceURI(), prefix,
signature.getName().getLocalPart());
- FunctionSignature newSig = new FunctionSignature(fName, signature
- .getParameterTypes(), FunctionSignature.EXTERNAL_FUNCTION,
+ FunctionSignature newSig = new FunctionSignature(fName, signature.paramTypes
+ , FunctionSignature.EXTERNAL_FUNCTION,
signature.getExpressionCategory(), false, true);
Function func = new Function(className, newSig, iter, operation, returnType);
return func;
@@ -116,9 +117,8 @@
* Get the signature of this function
*
* @return a copy of the signature
- * @throws MXQueryException
*/
- public FunctionSignature getFunctionSignature() throws MXQueryException {
+ public FunctionSignature getFunctionSignature() {
if (signature != null) {
return signature.copy();
} else {
@@ -151,12 +151,12 @@
try {
XDMIterator function = (XDMIterator) (Class.forName(className)
.newInstance());
- if (operation != null || returnType != -1) {
+ if (operation != null || returnType != null) {
RequestTypeMulti mult = (RequestTypeMulti)function;
if (operation != null)
mult.setOperation(operation);
- if (returnType != -1)
- mult.setReturnType(returnType);
+ if (returnType != null)
+ mult.setReturnType(returnType.getType());
}
return function;
} catch (ClassNotFoundException e) {
@@ -182,4 +182,25 @@
null, false, nestedPredCtxStack), operation, returnType);
return func;
}
+
+
+ public TypeInfo getReturnType() throws MXQueryException {
+ if (returnType != null)
+ return returnType;
+ if (iter!=null)
+ return iter.getStaticType();
+ else {
+ XDMIterator it = loadClass();
+ return it.getStaticType();
+ }
+
+ }
+
+ public QName[] getClosure() {
+ if (iter!=null && iter instanceof UserdefFuncCall) {
+ UserdefFuncCall ud = (UserdefFuncCall)iter;
+ return ud.getClosure();
+ } else
+ return null;
+ }
}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionGallery.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionGallery.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionGallery.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -122,16 +122,21 @@
public Function get(QName name, int arity) throws MXQueryException{
// fix for fn:contains - any arity > 2 possible
// TODO: refine to also include in the prefix/namespace
- if (name.getLocalPart().equals("concat") && arity > 2)
- arity = 2;
+ int localArity = arity;
+ if (name.getLocalPart().equals("concat") && name.getNamespaceURI().equals(Context.URI_FN)&& arity > 2)
+ localArity = 2;
// TODO: More elegant way. For now, create dummy signature with empty types
- TypeInfo [] typePlaceholder = new TypeInfo[arity];
+ TypeInfo [] typePlaceholder = new TypeInfo[localArity];
for (int i=0;i<typePlaceholder.length;i++) {
typePlaceholder[i] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE);
}
FunctionSignature signature = new FunctionSignature(name,typePlaceholder);
Function function = (Function)functions.get(signature);
if(function != null){
+ if (name.getLocalPart().equals("concat") &&
+ name.getNamespaceURI().equals(Context.URI_FN)&& arity > 2) {
+ function.signature.arity = arity;
+ }
return function;
}else{
return null;
@@ -233,7 +238,7 @@
xpp.require(XmlPullParser.START_TAG, null, "functionDescription");
xpp.nextTag();
String operation = null;
- int type = -1;
+ TypeInfo type = null;
while (!xpp.getName().equals("functionDescription") && xpp.getEventType() != XmlPullParser.END_TAG) {
String elementName = xpp.getName();
if (elementName.equals("functionName")) {
@@ -254,8 +259,9 @@
operation = xpp.getAttributeValue("", "op");
String rawType = xpp.getAttributeValue("", "type");
funcDesc[2] = xpp.nextText();
- if (rawType != null)
- type = getType(rawType,ctx);
+ if (rawType != null) {
+ type = new TypeInfo(getType(rawType,ctx),getOccur(rawType));
+ }
} else {
// element ignored
System.out.println("element ignored!");
@@ -303,9 +309,12 @@
}else if (rawType.equals("node()")){
return Type.NODE;
}else if (rawType.equals("element()")){
- return Type.ITEM;//TODO: fix it!
+ return Type.START_TAG;
+ }else if (rawType.startsWith("function(")){
+ return Type.FUNCTION_ITEM;
}else{
XQName qname = new QName(rawType);
+
if (qname.getNamespacePrefix()==null){
if (qname.getLocalPart().equals("numeric")){
qname = new QName(Context.URI_MXQ,Context.NS_MXQ,"number");
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionSignature.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionSignature.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionSignature.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -15,8 +15,10 @@
package ch.ethz.mxquery.functions;
+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;
@@ -32,6 +34,8 @@
TypeInfo [] paramTypes;
+ int arity = 0;
+
protected int type;
protected int expressionType;
@@ -59,6 +63,8 @@
expressionType = exprType;
nondet = nondeterministic;
privateScope = isPrivate;
+ if (this.paramTypes != null)
+ arity = paramTypes.length;
}
/**
* Checks the equality of Function Signatures.
@@ -80,7 +86,7 @@
* since the type of parameters is irrelevant
*/
public int hashCode() {
- return (qname.hashCode() << 3) | paramTypes.length;
+ return (qname.hashCode() << 3) | arity;
}
/**
* Returns the name of this function as qualified QName
@@ -94,20 +100,20 @@
* @return The number of parameters
*/
public int getArity() {
- if (paramTypes != null)
- return this.paramTypes.length;
- else
- return 0;
+ return arity;
}
/**
* Returns the type information for each of the parameters
* @return A type information for each parameter, an empty TypeInfo[] if no parameters in the function
*/
- public TypeInfo [] getParameterTypes() {
- if (paramTypes != null)
- return paramTypes;
+ public TypeInfo getParameterTypes(int pos) {
+ if (paramTypes != null && pos < paramTypes.length)
+ return paramTypes[pos];
else
- return new TypeInfo[]{};
+ if (qname.getLocalPart().equals("concat") && qname.getNamespaceURI().equals(XQStaticContext.URI_FN))
+ return new TypeInfo(Type.ANY_ATOMIC_TYPE,Type.OCCURRENCE_IND_ZERO_OR_ONE);
+ else
+ throw new RuntimeException("Trying to access an invalid parameter specification");
}
/**
* Get the type of function: built-in/system, user-defined, external
@@ -140,7 +146,12 @@
}
public FunctionSignature copy() {
- return new FunctionSignature(qname.copy(), paramTypes, type, expressionType, nondet, privateScope);
+ QName qn = null;
+ if (qname != null)
+ qn = qname.copy();
+ FunctionSignature fs = new FunctionSignature(qn, paramTypes, type, expressionType, nondet, privateScope);
+ 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-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -156,7 +156,7 @@
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);
- 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, 0);
+ 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);
}
} catch (ClassNotFoundException e) {
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Abs.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Abs.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Abs.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -96,7 +96,7 @@
}
double valU = Math.abs(db.getValue());
currentToken = new DoubleToken(null,new MXQueryDouble(valU));
-
+ break;
default:
throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE,"Invalid argument type", loc);
}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/DataValuesIterator.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/DataValuesIterator.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/DataValuesIterator.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -31,6 +31,7 @@
import ch.ethz.mxquery.datamodel.xdm.TokenInterface;
import ch.ethz.mxquery.datamodel.xdm.UntypedAtomicToken;
import ch.ethz.mxquery.datamodel.xdm.XDMScope;
+import ch.ethz.mxquery.exceptions.DynamicException;
import ch.ethz.mxquery.exceptions.ErrorCodes;
import ch.ethz.mxquery.exceptions.MXQueryException;
import ch.ethz.mxquery.exceptions.QueryLocation;
@@ -460,6 +461,8 @@
case Type.END_DOCUMENT:
level--;
break;
+ case Type.FUNCTION_ITEM:
+ throw new DynamicException(ErrorCodes.F0036_FUNCTION_ITEM_AT_FN_DATA, "Function Items do not have a typed value, thus cannot be atomized", loc);
case Type.END_SEQUENCE:
return new EmptySequenceIterator(context, loc);
}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Deep_equal.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Deep_equal.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Deep_equal.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -100,6 +100,9 @@
if (Type.isTextNode(t2Ev))
t2Ev = Type.getTextNodeValueType(t2Ev);
+ if (t1Ev == Type.FUNCTION_ITEM || t2Ev == Type.FUNCTION_ITEM)
+ throw new TypeException(ErrorCodes.F0038_FUNCTION_ITEM_AT_DEEP_EQUAL, "Function items not allow in fn:deep-equal()",loc);
+
if ((Type.isAtomicType(t1Ev, null)||t1Ev == Type.UNTYPED) && (Type.isAtomicType(t2Ev, null)||t2Ev == Type.UNTYPED)) {
try {
// TODO: support NaN
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/FNString.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/FNString.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/FNString.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -21,6 +21,7 @@
import ch.ethz.mxquery.datamodel.types.TypeInfo;
import ch.ethz.mxquery.datamodel.xdm.TextToken;
import ch.ethz.mxquery.datamodel.xdm.TokenInterface;
+import ch.ethz.mxquery.exceptions.DynamicException;
import ch.ethz.mxquery.exceptions.ErrorCodes;
import ch.ethz.mxquery.exceptions.MXQueryException;
import ch.ethz.mxquery.exceptions.TypeException;
@@ -35,7 +36,15 @@
// fn:string always atomizes!
input = DataValuesIterator.getDataIterator(it,context);
StringBuffer res = new StringBuffer();
- TokenInterface tok = input.next();
+ TokenInterface tok;
+ try {
+ tok = input.next();
+ } catch (DynamicException de) {
+ if (de.getErrorCode().equals(ErrorCodes.F0036_FUNCTION_ITEM_AT_FN_DATA))
+ throw new DynamicException(ErrorCodes.F0037_FUNCTION_ITEM_AT_FN_STRING, "Function items do not have a string value", loc);
+ else
+ throw de;
+ }
if (tok.getEventType()!=Type.END_SEQUENCE) {
res.append(tok.getValueAsString());
tok = input.next();
Copied: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Function_arity.java (from rev 4330, trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/FNString.java)
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Function_arity.java (rev 0)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Function_arity.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -0,0 +1,53 @@
+/* Copyright 2006 - 2009 ETH Zurich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.mxquery.functions.fn;
+
+import java.util.Vector;
+
+
+import ch.ethz.mxquery.contextConfig.Context;
+import ch.ethz.mxquery.datamodel.types.Type;
+import ch.ethz.mxquery.datamodel.types.TypeInfo;
+import ch.ethz.mxquery.datamodel.xdm.LongToken;
+import ch.ethz.mxquery.datamodel.xdm.TokenInterface;
+import ch.ethz.mxquery.exceptions.ErrorCodes;
+import ch.ethz.mxquery.exceptions.MXQueryException;
+import ch.ethz.mxquery.exceptions.TypeException;
+import ch.ethz.mxquery.model.TokenBasedIterator;
+import ch.ethz.mxquery.model.XDMIterator;
+
+public class Function_arity extends TokenBasedIterator {
+ protected void init() throws MXQueryException {
+ TokenInterface tok = subIters[0].next();
+
+ if (tok.getEventType() != Type.FUNCTION_ITEM && subIters[0].next().getEventType() != Type.END_SEQUENCE) {
+ throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE, "Expected a single function item", loc);
+ }
+
+ currentToken = new LongToken(Type.INTEGER, null, tok.getLong());
+ }
+
+ public TypeInfo getStaticType() {
+ return new TypeInfo(Type.INTEGER,Type.OCCURRENCE_IND_EXACTLY_ONE);
+ }
+
+ protected XDMIterator copy(Context context, XDMIterator[] subIters, Vector nestedPredCtxStack) throws MXQueryException {
+ XDMIterator copy = new Function_arity();
+ copy.setContext(context, true);
+ copy.setSubIters(subIters);
+ return copy;
+ }
+}
Copied: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Function_name.java (from rev 4330, trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/FNString.java)
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Function_name.java (rev 0)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Function_name.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -0,0 +1,58 @@
+/* Copyright 2006 - 2009 ETH Zurich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.mxquery.functions.fn;
+
+import java.util.Vector;
+
+
+import ch.ethz.mxquery.contextConfig.Context;
+import ch.ethz.mxquery.datamodel.types.Type;
+import ch.ethz.mxquery.datamodel.types.TypeInfo;
+import ch.ethz.mxquery.datamodel.xdm.QNameToken;
+import ch.ethz.mxquery.datamodel.xdm.Token;
+import ch.ethz.mxquery.datamodel.xdm.TokenInterface;
+import ch.ethz.mxquery.exceptions.ErrorCodes;
+import ch.ethz.mxquery.exceptions.MXQueryException;
+import ch.ethz.mxquery.exceptions.TypeException;
+import ch.ethz.mxquery.model.TokenBasedIterator;
+import ch.ethz.mxquery.model.XDMIterator;
+
+public class Function_name extends TokenBasedIterator {
+ protected void init() throws MXQueryException {
+ TokenInterface tok = subIters[0].next();
+
+ if (tok.getEventType() != Type.FUNCTION_ITEM && subIters[0].next().getEventType() != Type.END_SEQUENCE) {
+ throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE, "Expected a single function item", loc);
+ }
+
+ if (tok.getQNameTokenValue() != null) {
+ currentToken = new QNameToken(null,tok.getQNameTokenValue());
+ } else {
+ currentToken = Token.END_SEQUENCE_TOKEN;
+ }
+ }
+
+ public TypeInfo getStaticType() {
+ return new TypeInfo(Type.QNAME,Type.OCCURRENCE_IND_EXACTLY_ONE);
+ }
+
+ protected XDMIterator copy(Context context, XDMIterator[] subIters, Vector nestedPredCtxStack) throws MXQueryException {
+ XDMIterator copy = new Function_name();
+ copy.setContext(context, true);
+ copy.setSubIters(subIters);
+ return copy;
+ }
+}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Node_Name.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Node_Name.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Node_Name.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -59,10 +59,8 @@
switch (i) {
case Type.START_TAG:
case Type.PROCESSING_INSTRUCTION:
- String qname = inputToken.getName();
- QNameToken qn = new QNameToken(null,new QName(qname));
- if (inputToken.getNS() != null)
- qn.setNS(inputToken.getNS());
+ QName q = new QName(inputToken.getNS(),inputToken.getPrefix(),inputToken.getLocal());
+ QNameToken qn = new QNameToken(null,q);
currentToken = qn;
break;
case Type.START_DOCUMENT:
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Put.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Put.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Put.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -52,7 +52,7 @@
protected void createUpdateList() throws MXQueryException {
TypeInfo ti = new TypeInfo(Type.NODE,Type.OCCURRENCE_IND_EXACTLY_ONE);
- XDMIterator nodeParam = new SequenceTypeIterator(ti,true, false, context,loc);
+ XDMIterator nodeParam = new SequenceTypeIterator(ti,true, false, context,loc, false);
TokenInterface tok;
nodeParam.setSubIters(subIters[0]);
nodeParam.setResettable(true);
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/SubString.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/SubString.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/SubString.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -29,16 +29,14 @@
public class SubString extends TokenBasedIterator {
protected void init() throws MXQueryException {
- XDMIterator input = subIters[0];
- TokenInterface inputToken = input.next();
- int type = inputToken.getEventType();
+ String in = getStringValueOrEmpty(subIters[0]);
- if (type == Type.END_SEQUENCE) {
+ if (in == null) {
currentToken = new TextToken(null, "");
return;
}
// use string constructor to work around bug in JDK 1.5 for offset
- String res = new String(inputToken.getText());
+ String res = new String(in);
TokenInterface inputToken1 = subIters[1].next();
int type1 = Type.getEventTypeSubstituted(inputToken1.getEventType(), Context.getDictionary());
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/SubstringAfter.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/SubstringAfter.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/SubstringAfter.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -20,12 +20,9 @@
import ch.ethz.mxquery.datamodel.types.Type;
import ch.ethz.mxquery.datamodel.types.TypeInfo;
import ch.ethz.mxquery.datamodel.xdm.TextToken;
-import ch.ethz.mxquery.datamodel.xdm.Token;
-import ch.ethz.mxquery.datamodel.xdm.TokenInterface;
import ch.ethz.mxquery.exceptions.DynamicException;
import ch.ethz.mxquery.exceptions.ErrorCodes;
import ch.ethz.mxquery.exceptions.MXQueryException;
-import ch.ethz.mxquery.exceptions.TypeException;
import ch.ethz.mxquery.model.TokenBasedIterator;
import ch.ethz.mxquery.model.XDMIterator;
import ch.ethz.mxquery.util.Set;
@@ -33,21 +30,13 @@
public class SubstringAfter extends TokenBasedIterator {
protected void init() throws MXQueryException {
- XDMIterator iter0 = subIters[0];
- XDMIterator iter1 = subIters[1];
- TokenInterface inputToken1 = iter0.next();
- int type = inputToken1.getEventType();
- TokenInterface inputToken2 = iter1.next();
- int type2 = inputToken2.getEventType();
+ String res2 = getStringValueOrEmpty(subIters[1]);
+
+ String res = getStringValueOrEmpty(subIters[0]);
if (subIters.length > 2) {
// Minimum collation test - raise error on all collations that are not codepoint
- XDMIterator collIter = subIters[2];
- TokenInterface collToken = collIter.next();
- if (collToken == Token.END_SEQUENCE_TOKEN ||
- !Type.isTypeOrSubTypeOf(collToken.getEventType(),Type.STRING, Context.getDictionary()))
- throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE, "Wrong type for collation", loc);
- String collUri = collToken.getText();
+ String collUri = getStringValue(subIters[2]);
Set collations = context.getCollations();
if (!collations.contains(collUri))
throw new DynamicException(ErrorCodes.F0010_UNSUPPORTED_COLLATION, "Unsupported Collation", loc);
@@ -55,17 +44,11 @@
}
String result = null;
-
- String res2 = "";
- if (type2 != Type.END_SEQUENCE)
- res2 = inputToken2.getText();
+ if (res2 == null)
+ res2 = "";
- String res = "";
- if (type != Type.END_SEQUENCE)
- res = inputToken1.getText();
-
- if (res2.equals(""))
- result = res;
+ if (res == null)
+ result = "";
else {
int sPos = res.indexOf(res2);
if (sPos >= 0 ) {
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/SubstringBefore.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/SubstringBefore.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/SubstringBefore.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -20,12 +20,9 @@
import ch.ethz.mxquery.datamodel.types.Type;
import ch.ethz.mxquery.datamodel.types.TypeInfo;
import ch.ethz.mxquery.datamodel.xdm.TextToken;
-import ch.ethz.mxquery.datamodel.xdm.Token;
-import ch.ethz.mxquery.datamodel.xdm.TokenInterface;
import ch.ethz.mxquery.exceptions.DynamicException;
import ch.ethz.mxquery.exceptions.ErrorCodes;
import ch.ethz.mxquery.exceptions.MXQueryException;
-import ch.ethz.mxquery.exceptions.TypeException;
import ch.ethz.mxquery.model.TokenBasedIterator;
import ch.ethz.mxquery.model.XDMIterator;
import ch.ethz.mxquery.util.Set;
@@ -33,39 +30,23 @@
public class SubstringBefore extends TokenBasedIterator {
protected void init() throws MXQueryException {
- XDMIterator iter0 = subIters[0];
- XDMIterator iter1 = subIters[1];
- TokenInterface inputToken1 = iter0.next();
- int type = inputToken1.getEventType();
- TokenInterface inputToken2 = iter1.next();
- int type2 = inputToken2.getEventType();
+ String res2 = getStringValueOrEmpty(subIters[1]);
+
+ String res = getStringValueOrEmpty(subIters[0]);
+
if (subIters.length > 2) {
// Minimum collation test - raise error on all collations that are not codepoint
- XDMIterator collIter = subIters[2];
- TokenInterface collToken = collIter.next();
- if (collToken == Token.END_SEQUENCE_TOKEN ||
- !Type.isTypeOrSubTypeOf(collToken.getEventType(),Type.STRING, Context.getDictionary()))
- throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE, "Wrong type for collation", loc);
- String collUri = collToken.getText();
+ String collUri = getStringValue(subIters[2]);
Set collations = context.getCollations();
if (!collations.contains(collUri))
throw new DynamicException(ErrorCodes.F0010_UNSUPPORTED_COLLATION, "Unsupported Collation", loc);
}
-
-
+
String result = null;
-
- String res2 = "";
- if (type2 != Type.END_SEQUENCE)
- res2 = inputToken2.getText();
- String res = "";
- if (type != Type.END_SEQUENCE)
- res = inputToken1.getText();
-
- if (res2.equals(""))
+ if (res2 == null || res == null)
result = "";
else {
int sPos = res.indexOf(res2);
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Translate.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Translate.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Translate.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -22,10 +22,7 @@
import ch.ethz.mxquery.datamodel.types.Type;
import ch.ethz.mxquery.datamodel.types.TypeInfo;
import ch.ethz.mxquery.datamodel.xdm.TextToken;
-import ch.ethz.mxquery.datamodel.xdm.TokenInterface;
-import ch.ethz.mxquery.exceptions.ErrorCodes;
import ch.ethz.mxquery.exceptions.MXQueryException;
-import ch.ethz.mxquery.exceptions.TypeException;
import ch.ethz.mxquery.model.TokenBasedIterator;
import ch.ethz.mxquery.model.XDMIterator;
@@ -34,25 +31,17 @@
private Vector remove = new Vector();
protected void init() throws MXQueryException {
- TokenInterface arg = subIters[0].next();
- TokenInterface mapString = subIters[1].next();
- TokenInterface transString = subIters[2].next();
-
- if (arg.getEventType() == Type.END_SEQUENCE) {
+
+ String sArg = getStringValueOrEmpty(subIters[0]);
+
+ if (sArg == null || sArg.equals("")) {
currentToken = new TextToken(null, "");
return;
}
+
+ String sMap = getStringValue(subIters[1]);
+ String sTrans = getStringValue(subIters[2]);
- if (arg.getEventType() != Type.STRING ||
- mapString.getEventType() != Type.STRING ||
- transString.getEventType() != Type.STRING) {
- throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE, "Invalid argument type for fn:translate!", loc);
- }
-
- String sArg = arg.getText();
- String sMap = mapString.getText();
- String sTrans = transString.getText();
-
int transPos = 0;
for (int i=0; i<sMap.length(); i++) {
int sMapChar = sMap.codePointAt(i);
@@ -71,7 +60,7 @@
currentToken = new TextToken(null, translate(sArg));
}
-
+
private String translate(String input) {
StringBuffer result = new StringBuffer();
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/UpperCase.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/UpperCase.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/UpperCase.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -46,7 +46,7 @@
currentToken = new TextToken(null, res.toUpperCase());
break;
default:
- throw new TypeException(ErrorCodes.F0028_INVALID_ARGUMENT_TYPE, "Invalid argument type"+Type.getTypeQName(inputToken.getEventType(), Context.getDictionary()), loc);
+ throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE, "Invalid argument type"+Type.getTypeQName(inputToken.getEventType(), Context.getDictionary()), loc);
}
}
public TypeInfo getStaticType() {
Added: trunk/MXQuery/src/ch/ethz/mxquery/iterators/ClosureIterator.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/iterators/ClosureIterator.java (rev 0)
+++ trunk/MXQuery/src/ch/ethz/mxquery/iterators/ClosureIterator.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -0,0 +1,64 @@
+/* Copyright 2006 - 2009 ETH Zurich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.mxquery.iterators;
+
+
+import java.util.Vector;
+
+import ch.ethz.mxquery.contextConfig.Context;
+import ch.ethz.mxquery.datamodel.QName;
+import ch.ethz.mxquery.datamodel.xdm.FunctionItemToken;
+import ch.ethz.mxquery.exceptions.MXQueryException;
+import ch.ethz.mxquery.exceptions.QueryLocation;
+import ch.ethz.mxquery.functions.Function;
+import ch.ethz.mxquery.model.TokenBasedIterator;
+import ch.ethz.mxquery.model.VariableHolder;
+import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.Hashtable;
+
+public class ClosureIterator extends TokenBasedIterator {
+
+ Function func;
+ QName [] closure;
+
+
+
+ public ClosureIterator(Context context, Function func,
+ QName[] closure, QueryLocation loc) {
+ super(context,loc);
+ this.func = func;
+ this.closure = closure;
+ }
+
+
+ protected void init() throws MXQueryException {
+ // initialize all closure values from context
+ Hashtable closureVals = new Hashtable();
+ for (int i=0;i<closure.length;i++) {
+ VariableHolder vh = context.getVariable(closure[i]);
+ closureVals.put(closure[i], vh.getIter());
+ }
+ currentToken = new FunctionItemToken(func, closureVals);
+ }
+
+
+ protected XDMIterator copy(Context context, XDMIterator[] subIters, Vector nestedPredCtxStack) throws MXQueryException {
+ XDMIterator copy = new ClosureIterator(context, func,closure,loc);
+ copy.setSubIters(subIters);
+ return copy;
+
+ }
+}
Added: trunk/MXQuery/src/ch/ethz/mxquery/iterators/FunctionItemWrapperIterator.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/iterators/FunctionItemWrapperIterator.java (rev 0)
+++ trunk/MXQuery/src/ch/ethz/mxquery/iterators/FunctionItemWrapperIterator.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -0,0 +1,142 @@
+/* Copyright 2006 - 2009 ETH Zurich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.mxquery.iterators;
+
+/**
+ * Wrapper for function item, providing the facilities for partial application, function coercion, closure, etc
+ *
+ * */
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import ch.ethz.mxquery.contextConfig.Context;
+import ch.ethz.mxquery.datamodel.xdm.TokenInterface;
+import ch.ethz.mxquery.exceptions.ErrorCodes;
+import ch.ethz.mxquery.exceptions.MXQueryException;
+import ch.ethz.mxquery.exceptions.QueryLocation;
+import ch.ethz.mxquery.exceptions.StaticException;
+import ch.ethz.mxquery.exceptions.TypeException;
+import ch.ethz.mxquery.model.CurrentBasedIterator;
+import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.Hashtable;
+
+public class FunctionItemWrapperIterator extends CurrentBasedIterator {
+
+ XDMIterator wrappedFunction;
+ Hashtable paramMap; // free parameters with their position, mapping wrapped pos->caller pos
+ Hashtable appliedParams; // bound parameters, mapping wrapped pos->iterator
+
+
+
+ public FunctionItemWrapperIterator(Context ctx, XDMIterator wrappedFunction,
+ Hashtable paramMap, Hashtable appliedParams,QueryLocation loc) {
+ super(ctx,loc);
+ this.wrappedFunction = wrappedFunction;
+ this.paramMap = paramMap;
+ this.appliedParams = appliedParams;
+
+ }
+
+
+ protected void init() throws MXQueryException {
+ // first step: partial functions:
+ // set the subIterators for the parameters
+ current = wrappedFunction;
+
+ if (subIters.length != paramMap.size())
+ throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE, "Wrong number of parameters for dynamic function invocation", loc);
+ XDMIterator [] actualSubs = new XDMIterator[paramMap.size()+appliedParams.size()];
+ Enumeration applKeys = appliedParams.keys();
+ while (applKeys.hasMoreElements()) {
+ Integer wrappedPos = (Integer) applKeys.nextElement();
+ XDMIterator applIter = (XDMIterator) appliedParams.get(wrappedPos);
+ actualSubs[wrappedPos.intValue()] = applIter;
+ }
+
+ Enumeration paramKeys = paramMap.keys();
+ while (paramKeys.hasMoreElements()) {
+ Integer wrappedPos = (Integer) paramKeys.nextElement();
+ Integer paramPos = (Integer) paramMap.get(wrappedPos);
+ actualSubs[wrappedPos.intValue()] = subIters[paramPos.intValue()];
+ }
+
+ current.setSubIters(actualSubs);
+
+ }
+
+
+ protected XDMIterator copy(Context context, XDMIterator[] subIters, Vector nestedPredCtxStack) throws MXQueryException {
+ XDMIterator copy = new FunctionItemWrapperIterator(context, wrappedFunction,paramMap, appliedParams,loc);
+ copy.setSubIters(subIters);
+ return copy;
+
+ }
+
+ public TokenInterface next() throws MXQueryException {
+ if (called == 0) {
+ init();
+ called++;
+ }
+ return current.next();
+ }
+
+ public void setResettable(boolean r) throws MXQueryException {
+ wrappedFunction.setResettable(r);
+ super.setResettable(r);
+ }
+
+
+ public XDMIterator[] getAllSubIters() {
+ XDMIterator [] res;
+ if (subIters != null) {
+ res = new XDMIterator [subIters.length+1];
+ for (int i=0;i<subIters.length;i++)
+ res[i] = subIters[i];
+ }
+ else {
+ res = new XDMIterator[1];
+ }
+ res[res.length-1] = wrappedFunction;
+ return res;
+ }
+
+
+ protected void freeResources(boolean restartable)
+ throws MXQueryException {
+ super.freeResources(restartable);
+// if (!restartable)
+ current = null;
+ }
+
+ protected void resetImpl() throws MXQueryException {
+ // Do not reset current to keep function
+ // TODO: do we need to reset it with dynamic invocation?
+ called = 0;
+ if (current != null)
+ current.reset();
+ this.endOfSeq = false;
+ if (exprCategory == EXPR_CATEGORY_UPDATING && pendingUpdateList != null) {
+ pendingUpdateList.clear();
+ }
+ if (subIters != null) {
+ for (int i = 0; i < subIters.length; i++) {
+ subIters[i].reset();
+ }
+ }
+ depth = 0;
+ }
+}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/iterators/NativeFuncCall.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/iterators/NativeFuncCall.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/iterators/NativeFuncCall.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -207,19 +207,6 @@
}
subIters = subIt;
}
-
- private XDMIterator insertAtomizationCast(TypeInfo parType, XDMIterator toAdapt) {
- if (parType != null && parType.getType() != TypeInfo.UNDEFINED
- && Type.isAtomicType(parType.getType(), Context.getDictionary()))
- toAdapt = DataValuesIterator.getDataIterator(toAdapt, toAdapt.getContext());
-
- if (parType != null && parType.getType() != TypeInfo.UNDEFINED &&
- (parType.getType() != Type.END_SEQUENCE) &&
- parType.getType() != Type.ANY_ATOMIC_TYPE && !Type.isNode(parType.getType())
- && !Type.isTypeOrSubTypeOf(toAdapt.getStaticType().getType(),parType.getType(), Context.getDictionary()) && parType.getType() != Type.ITEM)
- toAdapt = new CastAsIterator(toAdapt.getContext(), toAdapt, parType, false, true,loc);
- return toAdapt;
- }
protected XDMIterator copy(Context context, XDMIterator[] subIters, Vector nestedPredCtxStack) throws MXQueryException {
NativeFuncCall copy = new NativeFuncCall(
Modified: trunk/MXQuery/src/ch/ethz/mxquery/iterators/SequenceTypeIterator.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/iterators/SequenceTypeIterator.java 2011-05-09 22:45:21 UTC (rev 4330)
+++ trunk/MXQuery/src/ch/ethz/mxquery/iterators/SequenceTypeIterator.java 2011-05-12 11:10:38 UTC (rev 4331)
@@ -26,12 +26,15 @@
import ch.ethz.mxquery.datamodel.types.Type;
import ch.ethz.mxquery.datamodel.types.TypeInfo;
import ch.ethz.mxquery.datamodel.xdm.BooleanToken;
+import ch.ethz.mxquery.datamodel.xdm.FunctionItemToken;
import ch.ethz.mxquery.datamodel.xdm.Token;
import ch.ethz.mxquery.datamodel.xdm.TokenInterface;
import ch.ethz.mxquery.exceptions.ErrorCodes;
import ch.ethz.mxquery.exceptions.MXQueryException;
import ch.ethz.mxquery.exceptions.QueryLocation;
import ch.ethz.mxquery.exceptions.TypeException;
+import ch.ethz.mxquery.functions.Function;
+import ch.ethz.mxquery.functions.FunctionSignature;
import ch.ethz.mxquery.model.CheckNodeType;
import ch.ethz.mxquery.model.CurrentBasedIterator;
import ch.ethz.mxquery.model.XDMIterator;
@@ -41,10 +44,11 @@
private boolean streaming = false;
private boolean atomicTypeTest = true;
+ private boolean functionTypeTest = false;
private boolean checkTokensType = true;
private TypeInfo tInfo = null;
private boolean promote = false;
-
+ private boolean coerce = false;
private String node_name = null;
private String node_name_uri = null;
private int itemCount = 0;
@@ -52,17 +56,21 @@
/**
* @param ctx TODO
+ * @param coerce TODO
*
*/
- public SequenceTypeIterator(TypeInfo tInfo, boolean streaming, boolean promote, Context ctx, QueryLocation location){
+ public SequenceTypeIterator(TypeInfo tInfo, boolean streaming, boolean promote, Context ctx, QueryLocation location, boolean coerce){
super(ctx, location);
this.tInfo = tInfo;
this.streaming = streaming;
this.promote = promote;
+ this.coerce = coerce;
int type = tInfo.getType();
if ( ! Type.isAtomicType(type, Context.getDictionary()) ) {
atomicTypeTest = false;
}
+ if (type == Type.FUNCTION_ITEM)
+ functionTypeTest = true;
}
public TokenInterface next() throws MXQueryException {
@@ -126,14 +134,19 @@
int typeAnn = tInfo.getTypeAnnotation();
String name = node_name;
String[] tokens = QName.parseQName(node_name);
- if (tokens.length > 1) name = tokens[1];
- if (typeAnn == 39 || typeAnn == 35 )
+ if (coerce && tInfo.getType() == Type.FUNCTION_ITEM) {
+ tok = coerceFunctionItem((FunctionItemToken)tok, tInfo);
+ return tok;
+ } else {
+ if (tokens.length > 1) name = tokens[1];
+ if (typeAnn == 39 || typeAnn == 35 )
throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE, "Sequence Type Matching Failed",loc);
- else if (typeAnn != -1&& name!=null&& !name.equals("*"))
+ else if (typeAnn != -1&& name!=null&& !name.equals("*"))
throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE, "Sequence Type Matching Failed: Expected {"+node_name_uri+"}:"+name+" with type: "+Type.getTypeQName(tInfo.getTypeAnnotation(), Context.getDictionary())+", encountered {"+tok.getNS()+"}:"+tok.getName()+" with type "+Type.getTypeQName(tok.getTypeAnnotation(), Context.getDictionary()), loc);
- else if ( name ==null || typeAnn != -1 && name.equals("*"))
+ else if ( name ==null || typeAnn != -1 && name.equals("*"))
throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE, "Sequence Type Matching Failed: Incorrect type: Expected "+Type.getTypeQName(typeAnn, Context.getDictionary())+", encountered type :"+Type.getTypeQName(tok.getTypeAnnotation(), Context.getDictionary()), loc);
- else throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE, "Sequence Type Matching Failed : Incorrect type: Expected "+Type.getTypeQName(tInfo.getType(), Context.getDictionary())+" encountered: "+Type.getTypeQName(tok.getEventType(), Context.getDictionary()), loc);
+ else throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE, "Sequence Type Matching Failed : Incorrect type: Expected "+Type.getTypeQName(tInfo.getType(), Context.getDictionary())+" encountered: "+Type.getTypeQName(tok.getEventType(), Context.getDictionary()), loc);
+ }
}
else return tok;
}
@@ -248,8 +261,11 @@
itemCount++;
if (this.atomicTypeTest)
- return isAtomicTypeItemFine(tok);
+ return isAtomicTypeItemFine(tok);
else
+ if (functionTypeTest)
+ return isFunctionItemFine(tok);
+ else
return isNodeKindTypeItemFine(tok);
}
@@ -321,7 +337,30 @@
}
}
-
+ private boolean isFunctionItemFine(TokenInterface tok) throws MXQueryException {
+ if (tok.getEventType()!=Type.FUNCTION_ITEM)
+ return false;
+ TypeInfo [] params = tInfo.getParameterTypes();
+ if (params != null) {
+ FunctionSignature fs = ((FunctionItemToken)tok).getFunction().getFunctionSignature();
+ if (fs.getArity() != params.length)
+ return false;
+ for (int i=0;i<params.length;i++) {
+ if (!Type.isTypeOrSubTypeOf(params[i].getType(),fs.getParameterTypes(i).getType(), Context.getDictionary()) ||
+ !Type.isTypeOrSubTypeOf(params[i].getTypeAnnotation(), fs.getParameterTypes(i).getTypeAnnotation(), Context.getDictionary()) ||
+ !Type.isOccCompatible(params[i].getOccurID(),fs.getParameterTypes(i).getOccurID(...
[truncated message content] |