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