|
From: <max...@us...> - 2011-06-13 18:57:22
|
Revision: 4400
http://mxquery.svn.sourceforge.net/mxquery/?rev=4400&view=rev
Author: maxspeicher
Date: 2011-06-13 18:57:15 +0000 (Mon, 13 Jun 2011)
Log Message:
-----------
- improved method discovery in NativeFuncCall.java
- added helper classes UiListener and BackgroundTask to Android branch
- extended MXQuery helper class in Android branch with certain methods for using prepared expressions + some minor changes
- added Android-specific version of fn:doc-available() (cf. fn:doc())
Modified Paths:
--------------
trunk/MXQuery/android/src/ch/ethz/mxquery/android/MXQuery.java
trunk/MXQuery/android/src/ch/ethz/mxquery/android/UiListener.java
trunk/MXQuery/src/ch/ethz/mxquery/iterators/NativeFuncCall.java
Added Paths:
-----------
trunk/MXQuery/android/src/ch/ethz/mxquery/android/BackgroundTask.java
trunk/MXQuery/android/src/ch/ethz/mxquery/functions/fn/DocAvailable.java
Added: trunk/MXQuery/android/src/ch/ethz/mxquery/android/BackgroundTask.java
===================================================================
--- trunk/MXQuery/android/src/ch/ethz/mxquery/android/BackgroundTask.java (rev 0)
+++ trunk/MXQuery/android/src/ch/ethz/mxquery/android/BackgroundTask.java 2011-06-13 18:57:15 UTC (rev 4400)
@@ -0,0 +1,72 @@
+package ch.ethz.mxquery.android;
+
+import android.app.Activity;
+import android.os.AsyncTask;
+
+public class BackgroundTask extends AsyncTask<Void, Void, Void> {
+
+ private Activity current;
+ private String dialogTitle, whileFunction, postFunction;
+
+ public BackgroundTask(String dialogTitle, String whileFunction, String postFunction) {
+ this.current = MXQuery.getActivity();
+ this.dialogTitle = dialogTitle;
+ this.whileFunction = whileFunction;
+ this.postFunction = postFunction;
+ }
+
+ public void execute() {
+ this.execute(null, null, null);
+ }
+
+ @Override
+ protected void onPreExecute() {
+ MXQuery.setDialogTitle(dialogTitle);
+ current.showDialog(1);
+ }
+
+ @Override
+ protected Void doInBackground(Void... arg0) {
+// try {
+// XQPreparedExpression xqjp;
+//
+// if ((xqjp = MXQuery.getPreparedExpression()) != null) {
+// xqjp.bindString(new QName("yyExt"), whileFunction, null);
+// Log.i("BackgroundTask", "Query result: " + MXQuery.doPreparedQuery(xqjp));
+// }
+// } catch (XQException xqe) {
+// xqe.printStackTrace();
+// Log.e("BackgroundTask", "Error: " + xqe.getMessage());
+// }
+
+ MXQuery.doQuery(
+ MXQuery.getXQueryFile() +
+ whileFunction + "()"
+ );
+
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void unused) {
+ current.removeDialog(1);
+
+// try {
+// XQPreparedExpression xqjp;
+//
+// if ((xqjp = MXQuery.getPreparedExpression()) != null) {
+// xqjp.bindString(new QName("yyExt"), postFunction, null);
+// Log.i("BackgroundTask", "Query result: " + MXQuery.doPreparedQuery(xqjp));
+// }
+// } catch (XQException xqe) {
+// xqe.printStackTrace();
+// Log.e("BackgroundTask", "Error: " + xqe.getMessage());
+// }
+
+ MXQuery.doQuery(
+ MXQuery.getXQueryFile() +
+ postFunction + "()"
+ );
+ }
+
+}
Modified: trunk/MXQuery/android/src/ch/ethz/mxquery/android/MXQuery.java
===================================================================
--- trunk/MXQuery/android/src/ch/ethz/mxquery/android/MXQuery.java 2011-06-12 23:50:51 UTC (rev 4399)
+++ trunk/MXQuery/android/src/ch/ethz/mxquery/android/MXQuery.java 2011-06-13 18:57:15 UTC (rev 4400)
@@ -1,18 +1,13 @@
package ch.ethz.mxquery.android;
import java.io.BufferedReader;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
-import ch.ethz.mxquery.xqj.MXQueryXQDataSource;
-import ch.ethz.repackaged.xquery.XQConnection;
-import ch.ethz.repackaged.xquery.XQDataSource;
-import ch.ethz.repackaged.xquery.XQException;
-import ch.ethz.repackaged.xquery.XQExpression;
-import ch.ethz.repackaged.xquery.XQSequence;
-
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@@ -21,14 +16,26 @@
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
+import android.widget.Toast;
+import ch.ethz.mxquery.xqj.MXQueryXQDataSource;
+import ch.ethz.repackaged.xquery.XQConnection;
+import ch.ethz.repackaged.xquery.XQDataSource;
+import ch.ethz.repackaged.xquery.XQException;
+import ch.ethz.repackaged.xquery.XQExpression;
+import ch.ethz.repackaged.xquery.XQPreparedExpression;
+import ch.ethz.repackaged.xquery.XQSequence;
public class MXQuery {
private static Activity act;
private static Context ctx;
+ private static Object[] arguments;
+ private static String dialogTitle;
private static String xQueryFile;
private static XQDataSource xqjd = new MXQueryXQDataSource(MXQueryXQDataSource.XQJ_SCRIPTING_MODE);
+ private static HashMap<Activity, XQPreparedExpression> preparedExpressions = new HashMap<Activity, XQPreparedExpression>();
+
public static void init(Activity act) {
MXQuery.ctx = act.getApplicationContext();
MXQuery.act = act;
@@ -42,10 +49,6 @@
return act;
}
- public static void startActivity(Class<?> next) {
- act.startActivity(new Intent(act, next));
- }
-
public static String getXQueryFile() {
return xQueryFile;
}
@@ -54,6 +57,30 @@
xQueryFile = readXQueryFile(rawResourceId);
}
+ public static XQPreparedExpression getPreparedExpression() {
+ if (preparedExpressions.containsKey(act)) {
+ return preparedExpressions.get(act);
+ } else {
+ return null;
+ }
+ }
+
+ public static XQPreparedExpression getPreparedExpression(Activity a) {
+ if (preparedExpressions.containsKey(a)) {
+ return preparedExpressions.get(a);
+ } else {
+ return null;
+ }
+ }
+
+ public static Object getArgument(int index) {
+ return arguments[index];
+ }
+
+ public static void setArguments(Object[] args) {
+ arguments = args;
+ }
+
public static Button getButton(int id) {
return (Button) act.findViewById(id);
}
@@ -66,6 +93,91 @@
return (TextView) act.findViewById(id);
}
+ public static String getDialogTitle() {
+ return dialogTitle;
+ }
+
+ public static void setDialogTitle(String title) {
+ dialogTitle = title;
+ }
+
+ public static void startActivity(String className) {
+ try {
+ act.startActivity(new Intent(act, Class.forName(className)));
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void makeToast(String msg) {
+ Toast.makeText(act, msg, 1).show();
+ }
+
+ public static void prepareExpression(Activity a, int rawResourceId) throws XQException {
+ String xQueryFile = readXQueryFile(rawResourceId);
+ String funcSignature = "declare( simple| sequential| updating)? function ([^\\s(]+) ?\\(([^)]*)\\)";
+
+ Pattern funcSignaturePattern = Pattern.compile(funcSignature);
+ Matcher funcSignatureMatcher = funcSignaturePattern.matcher(xQueryFile);
+
+ xQueryFile += "\ndeclare variable $yyExt external;\n";
+
+ boolean updating = false;
+ boolean sequential = false;
+ int i = 0;
+ String temp = "";
+ String funcModifier, funcName, argString;
+
+ while (funcSignatureMatcher.find()) {
+ funcModifier = funcSignatureMatcher.group(1);
+ funcName = funcSignatureMatcher.group(2);
+ argString = funcSignatureMatcher.group(3);
+
+ if (funcModifier != null && funcModifier.contains("updating")) {
+ updating = true;
+ } else if (funcModifier != null && funcModifier.contains("sequential")) {
+ sequential = true;
+ }
+
+ temp += (i == 0 ? " if " : " else if ");
+ temp += "($x eq '" + funcName + "') then\n " + funcName + "(";
+
+ int dollarSigns = 0;
+
+ for (int j=0; j<argString.length(); ++j) {
+ if (argString.charAt(j) == '$') {
+ temp += (dollarSigns > 0 ? ", " : "");
+ temp += ("m:getArgument(" + dollarSigns + ")");
+ ++dollarSigns;
+ }
+ }
+
+ temp += ")\n";
+
+ ++i;
+ }
+
+ xQueryFile += "declare ";
+
+ if (updating) {
+ xQueryFile += "updating ";
+ } else if (sequential) {
+ xQueryFile += "sequential ";
+ }
+
+ xQueryFile += (
+ "function local:yyChooseFunction($x) {\n" +
+ " $x,\n" + temp +
+ " else\n 'Error! No function chosen!'\n};\n" +
+ "local:yyChooseFunction($yyExt)"
+ );
+
+ XQConnection xqjc = xqjd.getConnection();
+ XQPreparedExpression xqjp = xqjc.prepareExpression(xQueryFile);
+
+ preparedExpressions.put(a, xqjp);
+ }
+
public static String doQuery(String query) {
StringWriter result = new StringWriter();
@@ -78,11 +190,29 @@
xqjc.close();
} catch (XQException xqe) {
xqe.printStackTrace();
+
return xqe.getMessage();
}
+
return result.toString();
}
+
+ public static String doPreparedQuery(XQPreparedExpression xqjp) {
+ StringWriter result = new StringWriter();
+ try {
+ XQSequence xqjs = xqjp.executeQuery();
+
+ xqjs.writeSequence(result, null);
+ } catch (XQException xqe) {
+ xqe.printStackTrace();
+
+ return xqe.getMessage();
+ }
+
+ return result.toString();
+ }
+
public static String readXQueryFile(int rawResourceId) {
BufferedReader in = new BufferedReader(new InputStreamReader(
act.getResources().openRawResource(rawResourceId)));
Modified: trunk/MXQuery/android/src/ch/ethz/mxquery/android/UiListener.java
===================================================================
--- trunk/MXQuery/android/src/ch/ethz/mxquery/android/UiListener.java 2011-06-12 23:50:51 UTC (rev 4399)
+++ trunk/MXQuery/android/src/ch/ethz/mxquery/android/UiListener.java 2011-06-13 18:57:15 UTC (rev 4400)
@@ -2,25 +2,40 @@
import android.view.View;
import android.view.View.OnClickListener;
-import ch.ethz.mxquery.android.MXQuery;
public class UiListener implements OnClickListener {
- public String methodName;
+ private String methodName;
public static View view;
public UiListener(String methodName) {
- this.methodName = methodName;
+ this.methodName = methodName;
}
public void onClick(View v) {
- view = v;
-
- MXQuery.doQuery(
- MXQuery.getXQueryFile() +
- methodName +
- "(uil:view())"
- );
+ view = v;
+
+// Object[] args = new Object[1];
+// args[0] = v;
+// MXQuery.setArguments(args);
+//
+// try {
+// XQPreparedExpression xqjp;
+//
+// if ((xqjp = MXQuery.getPreparedExpression()) != null) {
+// xqjp.bindString(new QName("yyExt"), methodName, null);
+// Log.i("UiListener", "Query result: " + MXQuery.doPreparedQuery(xqjp));
+// }
+// } catch (XQException xqe) {
+// xqe.printStackTrace();
+// Log.e("UiListener", "Error: " + xqe.getMessage());
+// }
+
+ MXQuery.doQuery(
+ MXQuery.getXQueryFile() +
+ methodName +
+ "(uil:view())"
+ );
}
}
Added: trunk/MXQuery/android/src/ch/ethz/mxquery/functions/fn/DocAvailable.java
===================================================================
--- trunk/MXQuery/android/src/ch/ethz/mxquery/functions/fn/DocAvailable.java (rev 0)
+++ trunk/MXQuery/android/src/ch/ethz/mxquery/functions/fn/DocAvailable.java 2011-06-13 18:57:15 UTC (rev 4400)
@@ -0,0 +1,133 @@
+/* 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.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Vector;
+
+import ch.ethz.mxquery.android.MXQuery;
+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.types.TypeLexicalConstraints;
+import ch.ethz.mxquery.datamodel.xdm.BooleanToken;
+import ch.ethz.mxquery.exceptions.DynamicException;
+import ch.ethz.mxquery.exceptions.ErrorCodes;
+import ch.ethz.mxquery.exceptions.MXQueryException;
+import ch.ethz.mxquery.model.TokenBasedIterator;
+import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.IOLib;
+
+public class DocAvailable extends TokenBasedIterator {
+
+ protected void init() throws MXQueryException {
+ String add = getStringValueOrEmpty(subIters[0]);
+
+ if (add == null) {
+ currentToken = BooleanToken.FALSE_TOKEN;
+ return;
+ }
+ URI uri;
+
+ if (!TypeLexicalConstraints.isValidURI(add))
+ throw new DynamicException(ErrorCodes.F0017_INVALID_ARGUMENT_TO_FN_DOC,"Invalid URI given to fn:doc-available", loc);
+ try {
+ if (TypeLexicalConstraints.isAbsoluteURI(add)) {
+ uri = new URI(add);
+ } else {
+// String base = context.getBaseURI();
+// String add1 = add;
+// if (add1.startsWith("/"))
+// add1 = add1.substring(1);
+ uri = new URI(IOLib.convertToAndroid(add));
+ }
+ } catch (URISyntaxException se) {
+ throw new DynamicException(ErrorCodes.F0017_INVALID_ARGUMENT_TO_FN_DOC,"Invalid URI given to fn:doc-available", loc);
+ }
+ if(add.startsWith("http://")){
+
+ URL url;
+ try {
+ url = uri.toURL();
+ } catch (MalformedURLException e) {
+ throw new DynamicException(ErrorCodes.F0017_INVALID_ARGUMENT_TO_FN_DOC,"Invalid URI given to fn:doc-available", loc);
+ }
+ try {
+ InputStream in = url.openStream();
+ in.close();
+ } catch (IOException e) {
+ currentToken = BooleanToken.FALSE_TOKEN;
+ return;
+ }
+ currentToken = BooleanToken.TRUE_TOKEN;
+ // }
+ // catch(Exception e){
+ // throw new DynamicException(ErrorCodes.A0006_EC_URI_NOT_FOUND, "Remote Data cannot be accessed: " + e);
+ // }
+ }
+ else {
+// File xml;
+// try {
+// xml = new File(uri);
+// }catch(IllegalArgumentException ia) {
+// try {
+// xml = new File(add);
+// } catch (IllegalArgumentException ia2) {
+// throw new DynamicException(ErrorCodes.F0017_INVALID_ARGUMENT_TO_FN_DOC,"Invalid URI given to fn:doc-available", loc);
+// }
+// }
+// if (xml.exists()) {
+// currentToken = BooleanToken.TRUE_TOKEN;
+// } else {
+// currentToken = BooleanToken.FALSE_TOKEN;
+// }
+
+ try {
+ BufferedReader in = new BufferedReader(
+ new InputStreamReader(
+ MXQuery.getContext().openFileInput(uri.toString())
+ )
+ );
+ currentToken = BooleanToken.TRUE_TOKEN;
+ } catch (FileNotFoundException e) {
+ currentToken = BooleanToken.FALSE_TOKEN;
+ } catch (IOException e) {
+ currentToken = BooleanToken.FALSE_TOKEN;
+ }
+ }
+ }
+
+ public TypeInfo getStaticType() {
+ return new TypeInfo(Type.BOOLEAN,Type.OCCURRENCE_IND_EXACTLY_ONE);
+ }
+
+ protected XDMIterator copy(Context context, XDMIterator[] subIters, Vector nestedPredCtxStack)
+ throws MXQueryException {
+ XDMIterator copy = new DocAvailable();
+ copy.setContext(context, true);
+ copy.setSubIters(subIters);
+ return copy;
+ }
+
+}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/iterators/NativeFuncCall.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/iterators/NativeFuncCall.java 2011-06-12 23:50:51 UTC (rev 4399)
+++ trunk/MXQuery/src/ch/ethz/mxquery/iterators/NativeFuncCall.java 2011-06-13 18:57:15 UTC (rev 4400)
@@ -149,40 +149,59 @@
*/
for (int i=0; i<methods.length; ++i) {
if (methodName.equals(methods[i].getName())) {
+// System.out.println("[CAND] " + methods[i].toGenericString());
Class[] params = methods[i].getParameterTypes();
- boolean add = true;
-
- if (params.length == invocationParams.length) {
+
+ if (invocationParams.length == params.length) {
+ boolean add = true;
+
for (int j=0; j<params.length; ++j) {
+ if (params[j].equals(byte.class)) {
+ params[j] = Byte.class;
+ } else if (params[j].equals(short.class)) {
+ params[j] = Short.class;
+ } else if (params[j].equals(int.class)) {
+ params[j] = Integer.class;
+ } else if (params[j].equals(long.class)) {
+ params[j] = Long.class;
+ } else if (params[j].equals(float.class)) {
+ params[j] = Float.class;
+ } else if (params[j].equals(double.class)) {
+ params[j] = Double.class;
+ } else if (params[j].equals(boolean.class)) {
+ params[j] = Boolean.class;
+ } else if (params[j].equals(char.class)) {
+ params[j] = Character.class;
+ }
+
if (!params[j].isInstance(invocationParams[j])) {
+// System.out.println("failure: "
+// + invocationParams[j].toString() + ", "
+// + invocationParamsTypes[j].getName() + " -> "
+// + params[j].getName());
add = false;
+ } else {
+// System.out.println("success: "
+// + invocationParams[j].toString() + ", "
+// + invocationParamsTypes[j].getName() + " -> "
+// + params[j].getName());
}
}
-
+
if (add) {
+// System.out.println("[ADD] " + methods[i].toGenericString());
candidates.add(methods[i]);
}
}
- }
+ }
}
- try {
- meth = native_function.getMethod(methodName, invocationParamsTypes);
+ if (candidates.size() > 0) {
+ meth = (Method) candidates.get(0);
res = meth.invoke(instanceToCall, invocationParams);
- } catch (NoSuchMethodException e) {
- /*
- * The method name provided by XQuery is either the
- * name of a field, or the method could not be
- * retrieved b/c the parameter types of the signature
- * are interfaces or abstract classes.
- */
- if (candidates.size() == 1) {
- meth = (Method) candidates.get(0);
- res = meth.invoke(instanceToCall, invocationParams);
- } else {
- field = native_function.getField(methodName);
- res = field.get(instanceToCall);
- }
+ } else {
+ field = native_function.getField(methodName);
+ res = field.get(instanceToCall);
}
}
@@ -197,19 +216,19 @@
this.current = new TokenIterator(context, wrap, loc, false);
}
} catch (SecurityException e) {
- throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "Native call failed: "+e.getMessage(), loc);
+ throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "SecurityException: Native call failed: "+e.getMessage(), loc);
} catch (NoSuchFieldException e) {
- throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "Native call failed: "+e.getMessage(), loc);
+ throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "NoSuchFieldException: Native call failed: "+e.getMessage(), loc);
} catch (NoSuchMethodException e) {
- throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "Native call failed: "+e.getMessage(), loc);
+ throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "NoSuchMethodException: Native call failed: "+e.getMessage(), loc);
} catch (IllegalArgumentException e) {
- throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "Native call failed: "+e.getMessage(), loc);
+ throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "IllegalArgumentException: Native call failed: "+e.getMessage(), loc);
} catch (IllegalAccessException e) {
- throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "Native call failed: "+e.getMessage(), loc);
+ throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "IllegalAccessException: Native call failed: "+e.getMessage(), loc);
} catch (InvocationTargetException e) {
- throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "Native call failed: "+e.getMessage(), loc);
+ throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "InvocationTargetException: Native call failed: "+e.getMessage(), loc);
} catch (InstantiationException e) {
- throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "Native call failed: "+e.getMessage(), loc);
+ throw new DynamicException(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE, "InstantiationException: Native call failed: "+e.getMessage(), loc);
}
//this.current = new TokenIterator(context, 42,Type.INT, loc);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|