View Javadoc

    1   /**
    2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    3    */
    4   package net.sourceforge.pmd.lang.java.xpath;
    5
    6   import java.util.Arrays;
    7   import java.util.List;
    8
    9   import net.sourceforge.pmd.lang.ast.Node;
    10  import net.sourceforge.pmd.lang.ast.xpath.Attribute;
    11  import net.sourceforge.pmd.lang.java.ast.TypeNode;
    12
    13  import org.jaxen.Context;
    14  import org.jaxen.Function;
    15  import org.jaxen.FunctionCallException;
    16  import org.jaxen.SimpleFunctionContext;
    17  import org.jaxen.XPathFunctionContext;
    18
    19  public class TypeOfFunction implements Function {
    20
    21      public static void registerSelfInSimpleContext() {
    22  	((SimpleFunctionContext) XPathFunctionContext.getInstance()).registerFunction(null, "typeof",
    23  		new TypeOfFunction());
    24      }
    25
    26  	public Object call(Context context, List args) throws FunctionCallException {
    27
    28  		String nodeTypeName = null;
    29  		String fullTypeName = null;
    30  		String shortTypeName = null;
    31  		Attribute attr = null;
    32  		for (int i = 0; i < args.size(); i++) {
    33  		    if (args.get(i) instanceof List) {
    34  			if (attr == null) {
    35  			    attr = (Attribute) ((List) args.get(i)).get(0);
    36  			    nodeTypeName = attr.getStringValue();
    37  			} else {
    38  			    throw new IllegalArgumentException(
    39  				    "typeof function can take only a single argument which is an Attribute.");
    40  			}
    41  		    } else {
    42  			if (fullTypeName == null) {
    43  			    fullTypeName = (String) args.get(i);
    44  			} else if (shortTypeName == null) {
    45  			    shortTypeName = (String) args.get(i);
    46  			} else {
    47  			    break;
    48  			}
    49  		    }
    50  		}
    51  		if (fullTypeName == null) {
    52  		    throw new IllegalArgumentException(
    53  			    "typeof function must be given at least one String argument for the fully qualified type name.");
    54  			}
    55  		Node n = (Node) context.getNodeSet().get(0);
    56  		return typeof(n, nodeTypeName, fullTypeName, shortTypeName);
    57      }
    58
    59      // TEST //ClassOrInterfaceType[typeof(@Image, 'java.lang.String')]
    60      public static boolean typeof(Node n, String nodeTypeName, String fullTypeName, String shortTypeName) {
    61  	if (n instanceof TypeNode) {
    62  	    Class type = ((TypeNode) n).getType();
    63  	    if (type == null) {
    64  		return nodeTypeName != null
    65  			&& (nodeTypeName.equals(fullTypeName) || nodeTypeName.equals(shortTypeName));
    66  	    }
    67  	    if (type.getName().equals(fullTypeName)) {
    68  		return true;
    69  	    }
    70  	    List<Class> implementors = Arrays.asList(type.getInterfaces());
    71  	    if (implementors.contains(type)) {
    72  		return true;
    73  	    }
    74  	    Class<?> superC = type.getSuperclass();
    75  	    while (superC != null && !superC.equals(Object.class)) {
    76  		if (superC.getName().equals(fullTypeName)) {
    77  		    return true;
    78  		}
    79  		superC = superC.getSuperclass();
    80  	    }
    81  	} else {
    82  	    throw new IllegalArgumentException("typeof function may only be called on a TypeNode.");
    83  	}
    84  	return false;
    85      }
    86  }