1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.vafer.dependency;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.Map;
24 import java.util.Set;
25 import java.util.jar.JarEntry;
26 import java.util.jar.JarInputStream;
27
28 import org.objectweb.asm.ClassReader;
29 import org.vafer.dependency.asm.DependenciesClassAdapter;
30
31 public final class Clazzpath {
32
33 public interface ClashHandler {
34
35 void handleClash( final Clazz pClazz );
36
37 }
38
39 private final Set units = new HashSet();
40
41 private final Map missing = new HashMap();
42
43 private final Map clazzes = new HashMap();
44
45 public Clazzpath() {
46 }
47
48 public boolean removeClazzpathUnit( final ClazzpathUnit pUnit ) {
49
50 return units.remove(pUnit);
51 }
52
53 public ClazzpathUnit addClazzpathUnit( final InputStream pInputStream, final String pId, final ClashHandler pClashHandler ) throws IOException {
54
55 final Map unitClazzes = new HashMap();
56 final Map unitDependencies = new HashMap();
57
58 final ClazzpathUnit unit = new ClazzpathUnit(pId, unitClazzes, unitDependencies);
59
60 final JarInputStream inputStream = new JarInputStream(pInputStream);
61
62 while (true) {
63 final JarEntry entry = inputStream.getNextJarEntry();
64
65 if (entry == null) {
66 break;
67 }
68
69 final String entryName = entry.getName();
70 if (entryName.endsWith(".class")) {
71
72 final String clazzName = entryName.substring(0, entryName.length() - 6).replace('/', '.');
73
74 Clazz clazz = getClazz(clazzName);
75
76 if (clazz == null) {
77 clazz = (Clazz) missing.get(clazzName);
78
79 if (clazz != null) {
80
81 clazz = (Clazz) missing.remove(clazzName);
82 } else {
83 clazz = new Clazz(unit, clazzName);
84 }
85 } else {
86
87 pClashHandler.handleClash(clazz);
88 }
89
90 clazzes.put(clazzName, clazz);
91 unitClazzes.put(clazzName, clazz);
92
93 final DependenciesClassAdapter v = new DependenciesClassAdapter();
94 new ClassReader(inputStream).accept(v, 0);
95 final Set depNames = v.getDependencies();
96
97 for (final Iterator it = depNames.iterator(); it.hasNext();) {
98 final String depName = (String) it.next();
99
100 Clazz dep = getClazz(depName);
101
102 if (dep == null) {
103
104 dep = (Clazz) missing.get(depName);
105 }
106
107 if (dep == null) {
108
109 dep = new Clazz(unit, depName);
110 missing.put(depName, dep);
111 }
112
113 if (dep != clazz) {
114 unitDependencies.put(depName, dep);
115 clazz.addDependency(dep);
116 }
117 }
118 }
119 }
120
121 units.add(unit);
122
123 return unit;
124 }
125
126 public Set getClazzes() {
127 final Set all = new HashSet();
128 for (final Iterator it = clazzes.values().iterator(); it.hasNext();) {
129 final Clazz clazz = (Clazz) it.next();
130 all.add(clazz);
131 }
132 return all;
133 }
134
135 public Set getMissingClazzes() {
136 final Set all = new HashSet();
137 for (final Iterator it = missing.values().iterator(); it.hasNext();) {
138 final Clazz clazz = (Clazz) it.next();
139 all.add(clazz);
140 }
141 return all;
142 }
143
144 public Clazz getClazz(final String pClazzName) {
145 return (Clazz) clazzes.get(pClazzName);
146 }
147
148 public ClazzpathUnit[] getUnits() {
149 return (ClazzpathUnit[]) units.toArray(new ClazzpathUnit[units.size()]);
150 }
151
152 }