All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.jxpath.PackageFunctions Maven / Gradle / Ivy

There is a newer version: 0.40.13
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * 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.
 */
package org.apache.commons.jxpath;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.jxpath.functions.ConstructorFunction;
import org.apache.commons.jxpath.functions.MethodFunction;
import org.apache.commons.jxpath.util.MethodLookupUtils;
import org.apache.commons.jxpath.util.TypeUtils;

/**
 * Extension functions provided by Java classes.  The class prefix specified
 * in the constructor is used when a constructor or a static method is called.
 * Usually, a class prefix is a package name (hence the name of this class).
 *
 * Let's say, we declared a PackageFunction like this:
 * 
 *     new PackageFunctions("java.util.", "util")
 * 
* * We can now use XPaths like: *
*
"util:Date.new()"
*
Equivalent to new java.util.Date()
*
"util:Collections.singleton('foo')"
*
Equivalent to java.util.Collections.singleton("foo")
*
"util:substring('foo', 1, 2)"
*
Equivalent to "foo".substring(1, 2). Note that in * this case, the class prefix is not used. JXPath does not check that * the first parameter of the function (the method target) is in fact * a member of the package described by this PackageFunctions object.
*
* *

* If the first argument of a method or constructor is {@link ExpressionContext}, * the expression context in which the function is evaluated is passed to * the method. *

*

* There is one PackageFunctions object registered by default with each * JXPathContext. It does not have a namespace and uses no class prefix. * The existence of this object allows us to use XPaths like: * "java.util.Date.new()" and "length('foo')" * without the explicit registration of any extension functions. *

* * @author Dmitri Plotnikov * @version $Revision: 670727 $ $Date: 2008-06-23 15:10:38 -0500 (Mon, 23 Jun 2008) $ */ public class PackageFunctions implements Functions { private String classPrefix; private String namespace; private static final Object[] EMPTY_ARRAY = new Object[0]; /** * Create a new PackageFunctions. * @param classPrefix class prefix * @param namespace namespace String */ public PackageFunctions(String classPrefix, String namespace) { this.classPrefix = classPrefix; this.namespace = namespace; } /** * Returns the namespace specified in the constructor * @return (singleton) namespace Set */ public Set getUsedNamespaces() { return Collections.singleton(namespace); } /** * Returns a {@link Function}, if found, for the specified namespace, * name and parameter types. *

* @param namespace - if it is not the same as specified in the * construction, this method returns null * @param name - name of the method, which can one these forms: *

    *
  • methodname, if invoking a method on an object passed as the * first parameter
  • *
  • Classname.new, if looking for a constructor
  • *
  • subpackage.subpackage.Classname.new, if looking for a * constructor in a subpackage
  • *
  • Classname.methodname, if looking for a static method
  • *
  • subpackage.subpackage.Classname.methodname, if looking for a * static method of a class in a subpackage
  • *
* @param parameters Object[] of parameters * @return a MethodFunction, a ConstructorFunction or null if no function * is found */ public Function getFunction( String namespace, String name, Object[] parameters) { if ((namespace == null && this.namespace != null) //NOPMD || (namespace != null && !namespace.equals(this.namespace))) { return null; } if (parameters == null) { parameters = EMPTY_ARRAY; } if (parameters.length >= 1) { Object target = TypeUtils.convert(parameters[0], Object.class); if (target != null) { Method method = MethodLookupUtils.lookupMethod( target.getClass(), name, parameters); if (method != null) { return new MethodFunction(method); } if (target instanceof NodeSet) { target = ((NodeSet) target).getPointers(); } method = MethodLookupUtils.lookupMethod( target.getClass(), name, parameters); if (method != null) { return new MethodFunction(method); } if (target instanceof Collection) { Iterator iter = ((Collection) target).iterator(); if (iter.hasNext()) { target = iter.next(); if (target instanceof Pointer) { target = ((Pointer) target).getValue(); } } else { target = null; } } } if (target != null) { Method method = MethodLookupUtils.lookupMethod( target.getClass(), name, parameters); if (method != null) { return new MethodFunction(method); } } } String fullName = classPrefix + name; int inx = fullName.lastIndexOf('.'); if (inx == -1) { return null; } String className = fullName.substring(0, inx); String methodName = fullName.substring(inx + 1); Class functionClass; try { functionClass = Class.forName(className); } catch (ClassNotFoundException ex) { throw new JXPathException( "Cannot invoke extension function " + (namespace != null ? namespace + ":" + name : name), ex); } if (methodName.equals("new")) { Constructor constructor = MethodLookupUtils.lookupConstructor(functionClass, parameters); if (constructor != null) { return new ConstructorFunction(constructor); } } else { Method method = MethodLookupUtils.lookupStaticMethod( functionClass, methodName, parameters); if (method != null) { return new MethodFunction(method); } } return null; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy