TypeOfFunction.java
01 /**
02  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
03  */
04 package net.sourceforge.pmd.lang.java.xpath;
05 
06 import java.util.Arrays;
07 import java.util.List;
08 
09 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   ((SimpleFunctionContextXPathFunctionContext.getInstance()).registerFunction(null, "typeof",
23     new TypeOfFunction());
24     }
25 
26     public Object call(Context context, List argsthrows FunctionCallException {
27   Node n = (Nodecontext.getNodeSet().get(0);
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(iinstanceof List) {
34     if (attr == null) {
35         attr = (Attribute) ((Listargs.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 = (Stringargs.get(i);
44     else if (shortTypeName == null) {
45         shortTypeName = (Stringargs.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   return typeof(n, nodeTypeName, fullTypeName, shortTypeName);
56     }
57 
58     // TEST //ClassOrInterfaceType[typeof(@Image, 'java.lang.String')]
59     public static boolean typeof(Node n, String nodeTypeName, String fullTypeName, String shortTypeName) {
60   if (instanceof TypeNode) {
61       Class type = ((TypeNoden).getType();
62       if (type == null) {
63     return nodeTypeName != null
64       && (nodeTypeName.equals(fullTypeName|| nodeTypeName.equals(shortTypeName));
65       }
66       if (type.getName().equals(fullTypeName)) {
67     return true;
68       }
69       List<Class> implementors = Arrays.asList(type.getInterfaces());
70       if (implementors.contains(type)) {
71     return true;
72       }
73       Class<?> superC = type.getSuperclass();
74       while (superC != null && !superC.equals(Object.class)) {
75     if (superC.getName().equals(fullTypeName)) {
76         return true;
77     }
78     superC = superC.getSuperclass();
79       }
80   else {
81       throw new IllegalArgumentException("typeof function may only be called on a TypeNode.");
82   }
83   return false;
84     }
85 }