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 ((SimpleFunctionContext) XPathFunctionContext.getInstance()).registerFunction(null, "typeof",
23 new TypeOfFunction());
24 }
25
26 public Object call(Context context, List args) throws FunctionCallException {
27 Node n = (Node) context.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(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 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 (n instanceof TypeNode) {
61 Class type = ((TypeNode) n).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 }
|