You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2006/09/11 03:40:11 UTC

svn commit: r442063 - in /incubator/abdera/java/trunk: core/src/main/java/org/apache/abdera/util/ parser/src/main/java/org/apache/abdera/parser/stax/ parser/src/main/java/org/apache/abdera/parser/stax/util/

Author: jmsnell
Date: Sun Sep 10 18:40:10 2006
New Revision: 442063

URL: http://svn.apache.org/viewvc?view=rev&rev=442063
Log:
Provide a mechanism for providing custom XPath functions and variables (jaxen specific)
Provide a custom abdera xpath function for resolving relative URI references

  XPath xpath = abdera.getXPath();
  System.out.println(xpath.evaluate("abdera:resolve(/a:entry/a:author/a:uri)", entry);

We can plug in other helpful Abdera specific functions as needed.

Added:
    incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/ResolveFunction.java
Modified:
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/AbstractXPath.java
    incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMXPath.java

Modified: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/AbstractXPath.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/AbstractXPath.java?view=diff&rev=442063&r1=442062&r2=442063
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/AbstractXPath.java (original)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/AbstractXPath.java Sun Sep 10 18:40:10 2006
@@ -40,9 +40,8 @@
       initDefaultNamespaces();
   }
   
-  private Map<String, String> initDefaultNamespaces() {
+  protected Map<String, String> initDefaultNamespaces() {
     Map<String,String> namespaces = new HashMap<String,String>();
-    namespaces = new HashMap<String,String>();
     namespaces.put("a", Constants.ATOM_NS);
     namespaces.put("app", Constants.APP_NS);
     return namespaces;

Modified: incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMXPath.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMXPath.java?view=diff&rev=442063&r1=442062&r2=442063
==============================================================================
--- incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMXPath.java (original)
+++ incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMXPath.java Sun Sep 10 18:40:10 2006
@@ -17,26 +17,102 @@
 */
 package org.apache.abdera.parser.stax;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.xml.namespace.QName;
+
 import org.apache.abdera.model.Base;
+import org.apache.abdera.parser.stax.util.ResolveFunction;
 import org.apache.abdera.util.AbstractXPath;
 import org.apache.abdera.xpath.XPathException;
 import org.apache.axiom.om.xpath.DocumentNavigator;
 import org.jaxen.BaseXPath;
+import org.jaxen.Function;
+import org.jaxen.FunctionContext;
 import org.jaxen.JaxenException;
+import org.jaxen.SimpleFunctionContext;
+import org.jaxen.SimpleVariableContext;
+import org.jaxen.VariableContext;
 import org.jaxen.XPath;
 
 public class FOMXPath extends AbstractXPath {
   
+  private final Map<QName,Function> functions;
+  private final Map<QName,Object> variables;
+  
+  public FOMXPath() {
+    this(null,null,null);
+  }
+  
+  protected FOMXPath(Map<String,String> defaultNamespaces) {
+    this(defaultNamespaces,null,null);
+  }
+  
+  protected FOMXPath(
+    Map<String,String> defaultNamespaces, 
+    Map<QName,Function> defaultFunctions,
+    Map<QName,Object> defaultVariables) {
+    super(defaultNamespaces);
+    functions = (defaultFunctions != null) ? 
+        defaultFunctions : 
+        initDefaultFunctions();
+    variables = (defaultVariables != null) ?
+        defaultVariables :
+        initDefaultVariables();
+  }
+  
+  protected Map<String, String> initDefaultNamespaces() {
+    Map<String,String> namespaces = super.initDefaultNamespaces();
+    namespaces.put("abdera", "http://incubator.apache.org/abdera");
+    return namespaces;
+  }
+  
+  private Map<QName, Function> initDefaultFunctions() {
+    Map<QName,Function> functions = new HashMap<QName,Function>();
+    functions.put(ResolveFunction.QNAME, new ResolveFunction());
+    return functions;
+  }
+  
+  private Map<QName, Object> initDefaultVariables() {
+    Map<QName,Object> variables = new HashMap<QName,Object>();
+    return variables;
+  }
+  
   public static XPath getXPath(String path) throws JaxenException {
     return getXPath(path, null);
   }
   
+  private static FunctionContext getFunctionContext(Map<QName,Function> functions) {
+    SimpleFunctionContext context = new SimpleFunctionContext();
+    for (QName qname : functions.keySet()) {
+      Function function = functions.get(qname);
+      context.registerFunction(
+        qname.getNamespaceURI(), 
+        qname.getLocalPart(), 
+        function);
+    }
+    return context;
+  }
+  
+  private static VariableContext getVariableContext(Map<QName,Object> variables) {
+    SimpleVariableContext context = new SimpleVariableContext();
+    for (QName qname : variables.keySet()) {
+      Object value = variables.get(qname);
+      context.setVariableValue(
+        qname.getNamespaceURI(), 
+        qname.getLocalPart(), 
+        value);
+    }
+    return context;
+  }
+  
   public static XPath getXPath(
-    String path, 
-    Map<String,String> namespaces) 
+    String path,
+    Map<String,String> namespaces,
+    Map<QName,Function> functions,
+    Map<QName,Object> variables)
       throws JaxenException {
     DocumentNavigator nav = new DocumentNavigator();
     XPath contextpath = new BaseXPath(path, nav);
@@ -45,86 +121,158 @@
         contextpath.addNamespace(entry.getKey(), entry.getValue());
       }
     }
-    
-    return contextpath;
+    if (functions != null)
+      contextpath.setFunctionContext(getFunctionContext(functions));
+    if (variables != null)
+      contextpath.setVariableContext(getVariableContext(variables));
+    return contextpath;    
+  }
+  
+  public static XPath getXPath(
+    String path, 
+    Map<String,String> namespaces) 
+      throws JaxenException {
+    return getXPath(path, namespaces, null, null);
   }
 
   public List selectNodes(
     String path, 
     Base base, 
-    Map<String,String> namespaces) throws XPathException {
+    Map<String,String> namespaces,
+    Map<QName,Function> functions,
+    Map<QName,Object> variables) 
+      throws XPathException {
     try {
-      XPath xpath = getXPath(path, namespaces);
+      XPath xpath = getXPath(path, namespaces, functions, variables);
       return xpath.selectNodes(base);
     } catch (JaxenException e) {
       throw new XPathException(e);
     }
   }
   
-  @SuppressWarnings("unchecked")
-  public Object selectSingleNode(
+  public List selectNodes(
     String path, 
     Base base, 
     Map<String,String> namespaces) throws XPathException {
+    return selectNodes(path, base, namespaces, functions, variables);
+  }
+
+  public Object selectSingleNode(
+    String path, 
+    Base base, 
+    Map<String,String> namespaces,
+    Map<QName,Function> functions,
+    Map<QName,Object> variables) throws XPathException {
     try {
-      XPath xpath = getXPath(path, namespaces);
+      XPath xpath = getXPath(path, namespaces, functions, variables);
       return xpath.selectSingleNode(base);
     } catch (JaxenException e) {
       throw new XPathException(e);
     }
   }
   
-  @SuppressWarnings("unchecked")
-  public Object evaluate(
+  public Object selectSingleNode(
     String path, 
     Base base, 
     Map<String,String> namespaces) throws XPathException {
+    return selectSingleNode(path, base, namespaces, functions, variables);
+  }
+  
+  public Object evaluate(
+    String path, 
+    Base base, 
+    Map<String,String> namespaces,
+    Map<QName,Function> functions,
+    Map<QName,Object> variables) throws XPathException {
     try {
-      XPath xpath = getXPath(path, namespaces);
+      XPath xpath = getXPath(path, namespaces, functions, variables);
       return xpath.evaluate(base);
     } catch (JaxenException e) {
       throw new XPathException(e);
     }
   }
-  
+
+  public Object evaluate(
+    String path, 
+    Base base, 
+    Map<String,String> namespaces) throws XPathException {
+    return evaluate(path,base,namespaces,functions, variables);
+  }
+
   public String valueOf(
     String path, 
     Base base, 
-    Map<String,String> namespaces) 
+    Map<String,String> namespaces,
+    Map<QName,Function> functions,
+    Map<QName,Object> variables) 
       throws XPathException {
     try {
-      XPath xpath = getXPath(path, namespaces);
+      XPath xpath = getXPath(path, namespaces, functions, variables);
       return xpath.stringValueOf(base);
     } catch (JaxenException e) {
       throw new XPathException(e);
     }
   }
+
+  public String valueOf(
+    String path, 
+    Base base, 
+    Map<String,String> namespaces) 
+      throws XPathException {
+    return valueOf(path,base,namespaces,functions, variables);
+  }
   
   public boolean booleanValueOf(
     String path, 
     Base base, 
-    Map<String,String> namespaces) 
+    Map<String,String> namespaces,
+    Map<QName,Function> functions,
+    Map<QName,Object> variables) 
       throws XPathException {
     try {
-      XPath xpath = getXPath(path, namespaces);
+      XPath xpath = getXPath(path, namespaces, functions, variables);
       return xpath.booleanValueOf(base);
     } catch (JaxenException e) {
       throw new XPathException(e);
     }
   }
+  
+  public boolean booleanValueOf(
+    String path, 
+    Base base, 
+    Map<String,String> namespaces) 
+      throws XPathException {
+    return booleanValueOf(path,base,namespaces,functions, variables);
+  }
 
-  @SuppressWarnings("unchecked")
   public Number numericValueOf(
     String path, 
     Base base, 
-    Map<String,String>namespaces) 
+    Map<String,String> namespaces,
+    Map<QName,Function> functions,
+    Map<QName,Object> variables) 
       throws XPathException {
     try {
-      XPath xpath = getXPath(path, namespaces);
+      XPath xpath = getXPath(path, namespaces, functions, variables);
       return xpath.numberValueOf(base);
     } catch (JaxenException e) {
       throw new XPathException(e);
     }
   }
   
+  public Number numericValueOf(
+    String path, 
+    Base base, 
+    Map<String,String> namespaces) 
+      throws XPathException {
+    return numericValueOf(path, base, namespaces, functions, variables);
+  }
+  
+  public Map<QName,Function> getDefaultFunctions() {
+    return new HashMap<QName,Function>(functions);
+  }
+  
+  public Map<QName,Object> getDefaultVariables() {
+    return new HashMap<QName,Object>(variables);
+  }
 }

Added: incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/ResolveFunction.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/ResolveFunction.java?view=auto&rev=442063
==============================================================================
--- incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/ResolveFunction.java (added)
+++ incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/ResolveFunction.java Sun Sep 10 18:40:10 2006
@@ -0,0 +1,83 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* 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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.parser.stax.util;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.model.Document;
+import org.apache.abdera.model.Element;
+import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMContainer;
+import org.apache.axiom.om.OMNode;
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+import org.jaxen.function.StringFunction;
+
+public class ResolveFunction implements Function {
+  
+  public static final QName QNAME = new QName("http://incubator.apache.org/abdera", "resolve");
+  
+  public Object call(Context context, List args) throws FunctionCallException {
+    List<URI> results = new ArrayList<URI>();
+    if (args.isEmpty()) return null;
+    Navigator navigator = context.getNavigator();
+    for(Object obj : args) {
+      if (obj instanceof List) {
+        for (Object o : (List)obj) {
+          try {
+            String value = StringFunction.evaluate(o, navigator);
+            URI resolved = null;
+            URI baseUri = null;
+            if (o instanceof OMNode) {
+              OMNode node = (OMNode) o;
+              OMContainer el = node.getParent();
+              if (el instanceof Document) {
+                Document doc = (Document) el;
+                baseUri = doc.getBaseUri();
+              } else if (el instanceof Element) {
+                Element element = (Element) el;
+                baseUri = element.getBaseUri();
+              }
+            } else if (o instanceof OMAttribute) {
+              OMAttribute attr = (OMAttribute) o;
+              Element element = (Element) context.getNavigator().getParentNode(attr);
+              baseUri = element.getBaseUri();
+            }
+            if (baseUri != null) {
+              resolved = baseUri.resolve(value);
+              results.add(resolved);
+            }
+          } catch (Exception e) {}
+        }
+      } else {
+        // nothing to do
+      }
+    }
+    if (results.size() == 1) {
+      return results.get(0);
+    } else if (results.size() > 1) {
+      return results;
+    } else return null;
+  }
+}