summaryrefslogtreecommitdiff
path: root/libjava/classpath/native/jni/xmlj/xmlj_xpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/native/jni/xmlj/xmlj_xpath.c')
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_xpath.c624
1 files changed, 624 insertions, 0 deletions
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_xpath.c b/libjava/classpath/native/jni/xmlj/xmlj_xpath.c
new file mode 100644
index 000000000..6aabaad23
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_xpath.c
@@ -0,0 +1,624 @@
+/* xmlj_xpath.c -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "gnu_xml_libxmlj_dom_GnomeDocument.h"
+#include "gnu_xml_libxmlj_dom_GnomeElement.h"
+#include "gnu_xml_libxmlj_dom_GnomeXPathExpression.h"
+#include "gnu_xml_libxmlj_dom_GnomeXPathNodeList.h"
+#include "gnu_xml_libxmlj_dom_GnomeXPathResult.h"
+#include "xmlj_node.h"
+#include "xmlj_util.h"
+#include <libxml/xpath.h>
+
+/* Local function prototypes */
+
+xmlXPathContextPtr
+xmljCreateXPathContextPtr (xmlNodePtr node);
+
+jobject
+xmljGetXPathResult (JNIEnv *env, xmlXPathObjectPtr obj);
+
+jobject
+xmljGetXPathNodeList (JNIEnv *env, xmlXPathObjectPtr obj);
+
+xmlXPathObjectPtr
+xmljGetXPathObjectID (JNIEnv *env, jobject obj);
+
+/**
+ * Creates an XPath context for the given node.
+ */
+xmlXPathContextPtr
+xmljCreateXPathContextPtr (xmlNodePtr node)
+{
+ xmlXPathContextPtr ctx;
+
+ ctx = xmlXPathNewContext (node->doc);
+ ctx->node = node;
+ return ctx;
+}
+
+/**
+ * Converts an xmlXPathObjectPtr to a Java XPathResult.
+ */
+jobject
+xmljGetXPathResult (JNIEnv *env, xmlXPathObjectPtr obj)
+{
+ jclass cls;
+ jmethodID method;
+ jobject ret;
+ jobject val;
+
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeXPathResult");
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ method = (*env)->GetMethodID (env, cls, "<init>", "(Ljava/lang/Object;)V");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ val = xmljAsField (env, obj);
+ ret = (*env)->NewObject (env, cls, method, val);
+
+ return ret;
+}
+
+/**
+ * Converts an xmlXPathObjectPtr to a Java XPathNodeList.
+ */
+jobject
+xmljGetXPathNodeList (JNIEnv *env, xmlXPathObjectPtr obj)
+{
+ jclass cls;
+ jmethodID method;
+ jobject ret;
+ jobject val;
+
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeXPathNodeList");
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ method = (*env)->GetMethodID (env, cls, "<init>", "(Ljava/lang/Object;)V");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ val = xmljAsField (env, obj);
+ ret = (*env)->NewObject (env, cls, method, val);
+
+ return ret;
+}
+
+xmlXPathObjectPtr
+xmljGetXPathObjectID (JNIEnv *env, jobject obj)
+{
+ jclass cls;
+ jfieldID field;
+ jobject val;
+ xmlXPathObjectPtr ret;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ field = (*env)->GetFieldID (env, cls, "obj", "Ljava/lang/Object;");
+ if (field == NULL)
+ {
+ return NULL;
+ }
+ val = (*env)->GetObjectField (env, obj, field);
+ ret = (xmlXPathObjectPtr) xmljAsPointer (env, val);
+
+ return ret;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_evaluate (JNIEnv *env,
+ jobject self
+ __attribute__((__unused__)),
+ jstring expression,
+ jobject contextNode,
+ jobject resolver,
+ jshort type,
+ jobject result)
+{
+ const xmlChar *str;
+ xmlNodePtr node;
+ xmlXPathContextPtr ctx;
+ xmlXPathObjectPtr eval = NULL;
+
+ str = xmljGetStringChars (env, expression);
+ node = xmljGetNodeID (env, contextNode);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ ctx = xmljCreateXPathContextPtr (node);
+ if (ctx != NULL)
+ {
+ eval = xmlXPathEval (str, ctx);
+ xmlXPathFreeContext (ctx);
+ }
+ xmlFree ((xmlChar *) str);
+ return xmljGetXPathResult (env, eval);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathExpression_init (JNIEnv *env,
+ jobject self
+ __attribute__((__unused__)),
+ jstring expression)
+{
+ const xmlChar *str;
+ xmlXPathCompExprPtr ptr;
+
+ str = xmljGetStringChars (env, expression);
+ ptr = xmlXPathCompile (str);
+ xmlFree ((xmlChar *) str);
+ return xmljAsField (env, ptr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathExpression_free (JNIEnv *env,
+ jobject self
+ __attribute__((__unused__)),
+ jobject ptr)
+{
+ xmlXPathCompExprPtr expr;
+
+ expr = (xmlXPathCompExprPtr) xmljAsPointer (env, ptr);
+ xmlXPathFreeCompExpr (expr);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathExpression_doEvaluate (JNIEnv *env,
+ jobject self
+ __attribute__((__unused__)),
+ jobject ptr,
+ jobject contextNode,
+ jshort type,
+ jobject result)
+{
+ xmlXPathCompExprPtr expr;
+ xmlNodePtr node;
+ xmlXPathContextPtr ctx;
+ xmlXPathObjectPtr eval = NULL;
+
+ expr = (xmlXPathCompExprPtr) xmljAsPointer (env, ptr);
+ node = xmljGetNodeID (env, contextNode);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ ctx = xmljCreateXPathContextPtr (node);
+ if (ctx != NULL)
+ {
+ eval = xmlXPathCompiledEval (expr, ctx);
+ xmlXPathFreeContext (ctx);
+ }
+ return xmljGetXPathResult (env, eval);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_free (JNIEnv *env,
+ jobject self
+ __attribute__((__unused__)),
+ jobject obj)
+{
+ xmlXPathFreeObject ((xmlXPathObjectPtr) xmljAsPointer (env, obj));
+}
+
+JNIEXPORT jshort JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getResultType (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ switch (obj->type)
+ {
+ case XPATH_UNDEFINED:
+ return 0; /* ANY_TYPE */
+ case XPATH_NUMBER:
+ return 1; /* NUMBER_TYPE */
+ case XPATH_STRING:
+ return 2; /* STRING_TYPE */
+ case XPATH_BOOLEAN:
+ return 3; /* BOOLEAN_TYPE */
+ case XPATH_NODESET:
+ return 6; /* UNORDERED_NODE_SNAPSHOT_TYPE */
+ case XPATH_POINT:
+ case XPATH_RANGE:
+ case XPATH_LOCATIONSET:
+ case XPATH_USERS:
+ case XPATH_XSLT_TREE:
+ /* TODO */
+ default:
+ return -1; /* TODO */
+ }
+}
+
+JNIEXPORT jdouble JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getNumberValue (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return 0.0;
+ }
+ return obj->floatval;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getStringValue (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, obj->stringval);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getBooleanValue (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ return obj->boolval;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getSingleNodeValue (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval->nodeNr > 0)
+ {
+ return xmljGetNodeInstance (env, obj->nodesetval->nodeTab[0]);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getInvalidIteratorState (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ return 0; /* TODO */
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getSnapshotLength (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return -1;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return -1;
+ }
+ return obj->nodesetval->nodeNr;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_iterateNext (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ return NULL; /* TODO */
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_snapshotItem (JNIEnv *env,
+ jobject self,
+ jint index)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval->nodeNr > 0)
+ {
+ return xmljGetNodeInstance (env, obj->nodesetval->nodeTab[index]);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+/* -- GnomeXPathNodeList -- */
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getElementsByTagName (JNIEnv *env,
+ jobject self,
+ jstring name)
+{
+ return Java_gnu_xml_libxmlj_dom_GnomeElement_getElementsByTagName (env,
+ self,
+ name);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getElementsByTagName (JNIEnv *env,
+ jobject self,
+ jstring name)
+{
+ const xmlChar *s_name;
+ const xmlChar *format;
+ xmlChar expr[256];
+ xmlNodePtr node;
+ xmlXPathContextPtr ctx;
+ xmlXPathObjectPtr eval = NULL;
+
+ node = xmljGetNodeID (env, self);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ s_name = xmljGetStringChars (env, name);
+ if (xmlStrEqual (s_name, BAD_CAST "*"))
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[node-type()=1]");
+ if (xmlStrPrintf (expr, 256, format) == -1)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[name()='%s']");
+ if (xmlStrPrintf (expr, 256, format, s_name) == -1)
+ {
+ return NULL;
+ }
+ }
+ xmlFree ((xmlChar *) s_name);
+ ctx = xmljCreateXPathContextPtr (node);
+ if (ctx != NULL)
+ {
+ eval = xmlXPathEval (expr, ctx);
+ xmlXPathFreeContext (ctx);
+ }
+ return xmljGetXPathNodeList (env, eval);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getElementsByTagNameNS (JNIEnv *env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ return Java_gnu_xml_libxmlj_dom_GnomeElement_getElementsByTagNameNS (env,
+ self,
+ uri,
+ localName);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getElementsByTagNameNS (JNIEnv *env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ const xmlChar *s_uri;
+ const xmlChar *s_localName;
+ const xmlChar *format;
+ xmlChar expr[256];
+ xmlNodePtr node;
+ xmlXPathContextPtr ctx;
+ xmlXPathObjectPtr eval = NULL;
+
+ node = xmljGetNodeID (env, self);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ s_uri = xmljGetStringChars (env, uri);
+ s_localName = xmljGetStringChars (env, localName);
+ if (uri == NULL)
+ {
+ /* namespace URI is empty */
+ if (xmlStrEqual (s_localName, BAD_CAST "*"))
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[namespace-uri()='' and node-type()=1]");
+ if (xmlStrPrintf (expr, 256, format) == -1)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[namespace-uri()='' and local-name()='%s']");
+ if (xmlStrPrintf (expr, 256, format, s_localName) == -1)
+ {
+ return NULL;
+ }
+ }
+ }
+ else if (xmlStrEqual (s_uri, BAD_CAST "*"))
+ {
+ /* matches all namespaces */
+ if (xmlStrEqual (s_localName, BAD_CAST "*"))
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[node-type()=1]");
+ if (xmlStrPrintf (expr, 256, format) == -1)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[local-name()='%s']");
+ if (xmlStrPrintf (expr, 256, format, s_localName) == -1)
+ {
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ if (xmlStrEqual (s_localName, BAD_CAST "*"))
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[namespace-uri()='%s' and node-type()=1]");
+ if (xmlStrPrintf (expr, 256, format, s_uri) == -1)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[namespace-uri()='%s' and local-name()='%s']");
+ if (xmlStrPrintf (expr, 256, format, s_uri, s_localName) == -1)
+ {
+ return NULL;
+ }
+ }
+ }
+ xmlFree ((xmlChar *) s_uri);
+ xmlFree ((xmlChar *) s_localName);
+ ctx = xmljCreateXPathContextPtr (node);
+ if (ctx != NULL)
+ {
+ eval = xmlXPathEval (expr, ctx);
+ xmlXPathFreeContext (ctx);
+ }
+ return xmljGetXPathNodeList (env, eval);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathNodeList_free (JNIEnv *env,
+ jobject self
+ __attribute__((__unused__)),
+ jobject obj)
+{
+ xmlXPathFreeObject ((xmlXPathObjectPtr) xmljAsPointer (env, obj));
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathNodeList_getLength (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return 0;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return 0;
+ }
+ return obj->nodesetval->nodeNr;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathNodeList_item (JNIEnv *env,
+ jobject self,
+ jint index)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval->nodeNr > 0)
+ {
+ return xmljGetNodeInstance (env, obj->nodesetval->nodeTab[index]);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+