1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.osgi.annotations;
20
21 import java.io.File;
22 import java.net.URI;
23 import java.net.URL;
24 import java.util.Comparator;
25 import java.util.Enumeration;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.StringTokenizer;
31 import java.util.TreeSet;
32
33 import org.eclipse.jetty.annotations.ClassNameResolver;
34 import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
35 import org.eclipse.jetty.util.resource.Resource;
36 import org.osgi.framework.Bundle;
37 import org.osgi.framework.Constants;
38
39
40
41
42 public class AnnotationParser extends org.eclipse.jetty.annotations.AnnotationParser
43 {
44 private Set<URI> _alreadyParsed = new HashSet<URI>();
45
46 private Map<URI,Bundle> _uriToBundle = new HashMap<URI, Bundle>();
47 private Map<Bundle,Resource> _resourceToBundle = new HashMap<Bundle,Resource>();
48 private Map<Bundle,URI> _bundleToUri = new HashMap<Bundle, URI>();
49
50
51
52
53
54
55
56 protected Resource indexBundle(Bundle bundle) throws Exception
57 {
58 File bundleFile = BundleFileLocatorHelper.DEFAULT.getBundleInstallLocation(bundle);
59 Resource resource = Resource.newResource(bundleFile.toURI());
60 URI uri = resource.getURI();
61 _uriToBundle.put(uri,bundle);
62 _bundleToUri.put(bundle,uri);
63 _resourceToBundle.put(bundle,resource);
64 return resource;
65 }
66 protected URI getURI(Bundle bundle)
67 {
68 return _bundleToUri.get(bundle);
69 }
70 protected Resource getResource(Bundle bundle)
71 {
72 return _resourceToBundle.get(bundle);
73 }
74
75
76
77 @Override
78 public void parse (URI[] uris, ClassNameResolver resolver)
79 throws Exception
80 {
81 for (URI uri : uris)
82 {
83 Bundle associatedBundle = _uriToBundle.get(uri);
84 if (associatedBundle == null)
85 {
86 if (!_alreadyParsed.add(uri))
87 {
88 continue;
89 }
90
91
92 super.parse(new URI[] {uri},resolver);
93 }
94 else
95 {
96 parse(associatedBundle,resolver);
97 }
98 }
99 }
100
101 protected void parse(Bundle bundle, ClassNameResolver resolver)
102 throws Exception
103 {
104 URI uri = _bundleToUri.get(bundle);
105 if (!_alreadyParsed.add(uri))
106 {
107 return;
108 }
109
110 String bundleClasspath = (String)bundle.getHeaders().get(Constants.BUNDLE_CLASSPATH);
111 if (bundleClasspath == null)
112 {
113 bundleClasspath = ".";
114 }
115
116 TreeSet<String> paths = new TreeSet<String>(
117 new Comparator<String>()
118 {
119 public int compare(String o1, String o2)
120 {
121 int paths1 = new StringTokenizer(o1,"/",false).countTokens();
122 int paths2 = new StringTokenizer(o2,"/",false).countTokens();
123 if (paths1 == paths2)
124 {
125 return o1.compareTo(o2);
126 }
127 return paths2 - paths1;
128 }
129 });
130 boolean hasDotPath = false;
131 StringTokenizer tokenizer = new StringTokenizer(bundleClasspath, ",;", false);
132 while (tokenizer.hasMoreTokens())
133 {
134 String token = tokenizer.nextToken().trim();
135 if (!token.startsWith("/"))
136 {
137 token = "/" + token;
138 }
139 if (token.equals("/."))
140 {
141 hasDotPath = true;
142 }
143 else if (!token.endsWith(".jar") && !token.endsWith("/"))
144 {
145 paths.add(token+"/");
146 }
147 else
148 {
149 paths.add(token);
150 }
151 }
152
153
154
155 if (bundle.getEntry("/.classpath") != null)
156 {
157 if (bundle.getEntry("/bin/") != null)
158 {
159 paths.add("/bin/");
160 }
161 else if (bundle.getEntry("/target/classes/") != null)
162 {
163 paths.add("/target/classes/");
164 }
165 }
166 Enumeration classes = bundle.findEntries("/","*.class",true);
167 if (classes == null)
168 {
169 return;
170 }
171 while (classes.hasMoreElements())
172 {
173 URL classUrl = (URL) classes.nextElement();
174 String path = classUrl.getPath();
175
176 String name = null;
177 for (String prefixPath : paths)
178 {
179 if (path.startsWith(prefixPath))
180 {
181 name = path.substring(prefixPath.length());
182 break;
183 }
184 }
185 if (name == null && hasDotPath)
186 {
187
188 name = path.substring(1);
189 }
190
191 String shortName = name.replace('/', '.').substring(0,name.length()-6);
192 if ((resolver == null)|| (!resolver.isExcluded(shortName) && (!isParsed(shortName) || resolver.shouldOverride(shortName))))
193 scanClass(classUrl.openStream());
194 }
195 }
196
197 }