From: <et...@us...> - 2011-05-22 11:10:28
|
Revision: 4361 http://mxquery.svn.sourceforge.net/mxquery/?rev=4361&view=rev Author: etterth Date: 2011-05-22 11:10:21 +0000 (Sun, 22 May 2011) Log Message: ----------- - Refactored NativeFunctionImporter to allow support for different languages Modified Paths: -------------- trunk/MXQuery/midp_src/ch/ethz/mxquery/functions/NativeFunctionImporter.java trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java Added Paths: ----------- trunk/MXQuery/xqib_src/ch/ethz/mxquery/functions/NativeFunctionImporter.java Modified: trunk/MXQuery/midp_src/ch/ethz/mxquery/functions/NativeFunctionImporter.java =================================================================== --- trunk/MXQuery/midp_src/ch/ethz/mxquery/functions/NativeFunctionImporter.java 2011-05-19 21:50:35 UTC (rev 4360) +++ trunk/MXQuery/midp_src/ch/ethz/mxquery/functions/NativeFunctionImporter.java 2011-05-22 11:10:21 UTC (rev 4361) @@ -9,8 +9,13 @@ public class NativeFunctionImporter { - public static Context getNativeMethods(String className) throws MXQueryException{ + public static Context getNativeMethods(String uri) throws MXQueryException{ + String className = uri.substring(5); Context ctx = new Context(); throw new MXQueryException(ErrorCodes.A0002_EC_NOT_SUPPORTED, "Import of native methods not supported", QueryLocation.OUTSIDE_QUERY_LOC); } + + public static boolean isNativeUri(String uri) { + return uri.startsWith("java:"); + } } Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java 2011-05-19 21:50:35 UTC (rev 4360) +++ trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java 2011-05-22 11:10:21 UTC (rev 4361) @@ -1,219 +1,21 @@ package ch.ethz.mxquery.functions; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.Map; import ch.ethz.mxquery.contextConfig.Context; -import ch.ethz.mxquery.datamodel.QName; -import ch.ethz.mxquery.datamodel.types.Type; -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; -import ch.ethz.mxquery.exceptions.StaticException; -import ch.ethz.mxquery.iterators.NativeFuncCall; -import ch.ethz.mxquery.model.XDMIterator; public class NativeFunctionImporter { - static class MethodData { - Class baseClass; - String methodName; - TypeInfo [] paramTypes; - TypeInfo returnType; - - public MethodData(Class baseClass, String methodName, - TypeInfo[] paramTypes, TypeInfo returnType) { - super(); - this.baseClass = baseClass; - this.methodName = methodName; - this.paramTypes = paramTypes; - this.returnType = returnType; - } - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((baseClass == null) ? 0 : baseClass.hashCode()); - result = prime * result - + ((methodName == null) ? 0 : methodName.hashCode()); - result = prime * result + paramTypes.length; - return result; - } - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - MethodData other = (MethodData) obj; - if (baseClass == null) { - if (other.baseClass != null) - return false; - } else if (!baseClass.equals(other.baseClass)) - return false; - if (methodName == null) { - if (other.methodName != null) - return false; - } else if (!methodName.equals(other.methodName)) - return false; - if (paramTypes == null) { - if (other.paramTypes != null) - return false; - }else if (paramTypes.length != other.paramTypes.length) - return false; - return true; - } - - } - public static Context getNativeMethods(String className) throws MXQueryException{ + public static Context getNativeMethods(String uri) throws MXQueryException{ + String className = uri.substring(5); Context ctx = new Context(); - - try { - Class toImport = Class.forName(className); - - Map functions = new HashMap(); - - Constructor [] constructors = toImport.getConstructors(); - for (int i=0;i<constructors.length;i++) { - Constructor cur = constructors[i]; - int mod = cur.getModifiers(); - if (Modifier.isPublic(mod)) { - TypeInfo [] params; - Class [] paramTypes = cur.getParameterTypes(); - params = new TypeInfo[paramTypes.length]; - for (int j=0;j<params.length;j++) { - params[j] = getXQueryType(paramTypes[j]); - } - MethodData md = new MethodData(toImport, "new", params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_EXACTLY_ONE)); - if (!functions.containsKey(md)) - functions.put(md,md); - else { - MethodData existingMd = (MethodData)functions.get(md); - for (int j=0;j<existingMd.paramTypes.length;j++) { - if (!params[j].equals(existingMd.paramTypes [j])) { - if (Type.isNumericPrimitiveType(params[j].getType()) && Type.isNumericPrimitiveType(existingMd.paramTypes[j].getType())) - existingMd.paramTypes[j] = new TypeInfo(Type.NUMBER,Type.OCCURRENCE_IND_EXACTLY_ONE); - else - if (Type.isAtomicType(params[j].getType(), Context.getDictionary()) && Type.isAtomicType(existingMd.paramTypes[j].getType(),Context.getDictionary())) - existingMd.paramTypes[j] = new TypeInfo(Type.ANY_ATOMIC_TYPE,Type.OCCURRENCE_IND_EXACTLY_ONE); - else - existingMd.paramTypes[j] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_EXACTLY_ONE); - } - } - } - - } - } - - Method [] methods = toImport.getMethods(); - - for (int i=0;i<methods.length;i++) { - Method cur = methods[i]; - int mod = cur.getModifiers(); - if (Modifier.isPublic(mod)) { - String name = cur.getName(); - Class [] paramTypes = cur.getParameterTypes(); - TypeInfo [] params = new TypeInfo[paramTypes.length]; - if (Modifier.isStatic(mod)) { - params = new TypeInfo[paramTypes.length]; - for (int j=0;j<params.length;j++) { - params[j] = getXQueryType(paramTypes[j]); - } - } - else { - params = new TypeInfo[paramTypes.length+1]; - params[0] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_EXACTLY_ONE); - for (int j=1;j<params.length;j++) { - params[j] = getXQueryType(paramTypes[j-1]); - } - } - TypeInfo resultType = getXQueryType(cur.getReturnType()); - MethodData md = new MethodData(toImport, name, params, resultType); - if (!functions.containsKey(md)) - functions.put(md,md); - else { - MethodData existingMd = (MethodData)functions.get(md); - for (int j=0;j<existingMd.paramTypes.length;j++) { - if (!params[j].equals(existingMd.paramTypes [j])) { - if (Type.isNumericPrimitiveType(params[j].getType()) && Type.isNumericPrimitiveType(existingMd.paramTypes[j].getType())) - existingMd.paramTypes[j] = new TypeInfo(Type.NUMBER,Type.OCCURRENCE_IND_EXACTLY_ONE); - else - existingMd.paramTypes[j] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_EXACTLY_ONE); - //throw new StaticException(ErrorCodes.A0020_Incompatible_Overload, "Overloaded Java Function "+className+"."+name+" could not be mapped", QueryLocation.OUTSIDE_QUERY_LOC); - } - } - } - - } - } - - Field [] fields = toImport.getFields(); - - for (int i=0;i<fields.length;i++) { - Field cur = fields[i]; - int mod = cur.getModifiers(); - if (Modifier.isPublic(mod)) { - String name = cur.getName(); - TypeInfo[] params; - if (Modifier.isStatic(mod)) { - params = new TypeInfo[0]; - } - else { - params = new TypeInfo[1]; - params[0] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_EXACTLY_ONE); - } - TypeInfo resultType = getXQueryType(cur.getType()); - MethodData md = new MethodData(toImport, name, params, resultType); - if (!functions.containsKey(md)) - functions.put(md,md); - } - } - - java.util.Iterator allFuncts = functions.values().iterator(); - 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); - 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) { - throw new StaticException(ErrorCodes.A0019_Unknown_Class, "Class "+className+" could not be found", QueryLocation.OUTSIDE_QUERY_LOC); - } - return ctx; + throw new MXQueryException(ErrorCodes.A0002_EC_NOT_SUPPORTED, "Import of native methods not supported", QueryLocation.OUTSIDE_QUERY_LOC); } - private static TypeInfo getXQueryType(Class class1) { - - if (class1.isPrimitive()) { - if (class1.getName().equals("long")) - return new TypeInfo(Type.LONG,Type.OCCURRENCE_IND_EXACTLY_ONE); - if (class1.getName().equals("double")) - return new TypeInfo(Type.DOUBLE,Type.OCCURRENCE_IND_EXACTLY_ONE); - if (class1.getName().equals("float")) - return new TypeInfo(Type.FLOAT,Type.OCCURRENCE_IND_EXACTLY_ONE); - if (class1.getName().equals("int")) - return new TypeInfo(Type.INT,Type.OCCURRENCE_IND_EXACTLY_ONE); - if (class1.getName().equals("boolean")) - return new TypeInfo(Type.BOOLEAN,Type.OCCURRENCE_IND_EXACTLY_ONE); - System.out.println(class1.getPackage()+" "+class1.getName()); - return new TypeInfo(Type.UNTYPED_ATOMIC,Type.OCCURRENCE_IND_EXACTLY_ONE); - } - if (class1.getName().equals("java.lang.String")) - return new TypeInfo(Type.STRING,Type.OCCURRENCE_IND_EXACTLY_ONE); - if (class1.getName().equals("java.lang.CharSequence")) - return new TypeInfo(Type.STRING,Type.OCCURRENCE_IND_EXACTLY_ONE); - if (class1.getName().equals("java.lang.Double")) - return new TypeInfo(Type.DOUBLE,Type.OCCURRENCE_IND_EXACTLY_ONE); - if (class1.getName().equals("java.lang.Float")) - return new TypeInfo(Type.FLOAT,Type.OCCURRENCE_IND_EXACTLY_ONE); - return new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE); - } + public static boolean isNativeUri(String uri) { + return uri.startsWith("java:"); + } } Modified: trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java =================================================================== --- trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java 2011-05-19 21:50:35 UTC (rev 4360) +++ trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java 2011-05-22 11:10:21 UTC (rev 4361) @@ -940,8 +940,8 @@ ErrorCodes.E0033_STATIC_MODULE_MULTIPLE_BINDINGS_FOR_SAME_PREFIX, "Multiple declarations of Namespace " + name); ctx.addNamespace(new Namespace(name, uri)); - if (uri.startsWith("java:")) { - Context javamod = NativeFunctionImporter.getNativeMethods(uri.substring(5)); + if (NativeFunctionImporter.isNativeUri(uri)) { + Context javamod = NativeFunctionImporter.getNativeMethods(uri); importModuleFunctionsVariables(uri, name, javamod); } declaredNamespaces.add(name); Added: trunk/MXQuery/xqib_src/ch/ethz/mxquery/functions/NativeFunctionImporter.java =================================================================== --- trunk/MXQuery/xqib_src/ch/ethz/mxquery/functions/NativeFunctionImporter.java (rev 0) +++ trunk/MXQuery/xqib_src/ch/ethz/mxquery/functions/NativeFunctionImporter.java 2011-05-22 11:10:21 UTC (rev 4361) @@ -0,0 +1,21 @@ +package ch.ethz.mxquery.functions; + + +import ch.ethz.mxquery.contextConfig.Context; +import ch.ethz.mxquery.exceptions.ErrorCodes; +import ch.ethz.mxquery.exceptions.MXQueryException; +import ch.ethz.mxquery.exceptions.QueryLocation; + +public class NativeFunctionImporter { + + + public static Context getNativeMethods(String uri) throws MXQueryException{ + String className = uri.substring(5); + Context ctx = new Context(); + throw new MXQueryException(ErrorCodes.A0002_EC_NOT_SUPPORTED, "Import of native methods not supported", QueryLocation.OUTSIDE_QUERY_LOC); + } + + public static boolean isNativeUri(String uri) { + return uri.startsWith("java:"); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |