1
2
3
4 package net.sourceforge.pmd.dcd.graph;
5
6 import java.util.ArrayList;
7 import java.util.Collections;
8 import java.util.List;
9
10 import net.sourceforge.pmd.dcd.ClassLoaderUtil;
11 import net.sourceforge.pmd.util.filter.Filter;
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public class UsageGraph implements NodeVisitorAcceptor {
48
49 private final List<ClassNode> classNodes = new ArrayList<ClassNode>();
50
51 protected final Filter<String> classFilter;
52
53 public UsageGraph(Filter<String> classFilter) {
54 this.classFilter = classFilter;
55 }
56
57 public Object accept(NodeVisitor visitor, Object data) {
58 for (ClassNode classNode : classNodes) {
59 visitor.visit(classNode, data);
60 }
61 return data;
62 }
63
64 public boolean isClass(String className) {
65 checkClassName(className);
66 return Collections.binarySearch(classNodes, className, ClassNodeComparator.INSTANCE) >= 0;
67 }
68
69 public ClassNode defineClass(String className) {
70 checkClassName(className);
71 int index = Collections.binarySearch(classNodes, className, ClassNodeComparator.INSTANCE);
72 ClassNode classNode;
73 if (index >= 0) {
74 classNode = classNodes.get(index);
75 } else {
76 classNode = new ClassNode(className);
77 classNodes.add(-(index + 1), classNode);
78 }
79 return classNode;
80 }
81
82 public FieldNode defineField(String className, String name, String desc) {
83 ClassNode classNode = defineClass(className);
84 return classNode.defineField(name, desc);
85 }
86
87 public MemberNode defineConstructor(String className, String name, String desc) {
88 ClassNode classNode = defineClass(className);
89 return classNode.defineConstructor(name, desc);
90 }
91
92 public MemberNode defineMethod(String className, String name, String desc) {
93 ClassNode classNode = defineClass(className);
94 if (ClassLoaderUtil.CLINIT.equals(name) || ClassLoaderUtil.INIT.equals(name)) {
95 return classNode.defineConstructor(name, desc);
96 } else {
97 return classNode.defineMethod(name, desc);
98 }
99 }
100
101 public void usageField(String className, String name, String desc, MemberNode usingMemberNode) {
102 checkClassName(className);
103 if (classFilter.filter(className)) {
104 FieldNode fieldNode = defineField(className, name, desc);
105 usage(fieldNode, usingMemberNode);
106 }
107 }
108
109 public void usageMethod(String className, String name, String desc, MemberNode usingMemberNode) {
110 checkClassName(className);
111 if (classFilter.filter(className)) {
112 MemberNode memberNode;
113 if (ClassLoaderUtil.CLINIT.equals(name) || ClassLoaderUtil.INIT.equals(name)) {
114 memberNode = defineConstructor(className, name, desc);
115 } else {
116 memberNode = defineMethod(className, name, desc);
117 }
118 usage(memberNode, usingMemberNode);
119 }
120 }
121
122 private void usage(MemberNode use, MemberNode user) {
123 use.addUser(user);
124 user.addUse(use);
125 }
126
127 private final void checkClassName(String className) {
128
129 if (className.indexOf('/') >= 0 || className.indexOf('\\') >= 0) {
130 throw new IllegalArgumentException("Invalid class name: " + className);
131 }
132 }
133 }