blob: 0109ad4321a4d6f0f6048793385d75548228b83c [file] [log] [blame]
Stuart McCullochf3173222012-06-07 21:57:32 +00001package aQute.lib.spring;
2
3import java.io.*;
4import java.util.*;
5import java.util.Map.Entry;
6import java.util.regex.*;
7
8import javax.xml.transform.*;
9import javax.xml.transform.stream.*;
10
11import aQute.bnd.service.*;
12import aQute.lib.osgi.*;
13import aQute.lib.osgi.Descriptors.PackageRef;
14import aQute.libg.header.*;
15
16/**
17 * This component is called when we find a resource in the META-INF/*.xml
18 * pattern. We parse the resource and and the imports to the builder.
19 *
20 * Parsing is done with XSLT (first time I see the use of having XML for the
21 * Spring configuration files!).
22 *
23 * @author aqute
24 *
25 */
26public class SpringComponent implements AnalyzerPlugin {
27 static Transformer transformer;
28 static Pattern SPRING_SOURCE = Pattern.compile("META-INF/spring/.*\\.xml");
29 static Pattern QN = Pattern.compile("[_A-Za-z$][_A-Za-z0-9$]*(\\.[_A-Za-z$][_A-Za-z0-9$]*)*");
30
31 public static Set<CharSequence> analyze(InputStream in) throws Exception {
32 if (transformer == null) {
33 TransformerFactory tf = TransformerFactory.newInstance();
34 Source source = new StreamSource(SpringComponent.class
35 .getResourceAsStream("extract.xsl"));
36 transformer = tf.newTransformer(source);
37 }
38
39 Set<CharSequence> refers = new HashSet<CharSequence>();
40
41 ByteArrayOutputStream bout = new ByteArrayOutputStream();
42 Result r = new StreamResult(bout);
43 Source s = new StreamSource(in);
44 transformer.transform(s, r);
45
46 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
47 bout.close();
48
49 BufferedReader br = new BufferedReader(new InputStreamReader(bin, "UTF8"));
50
51 String line = br.readLine();
52 while (line != null) {
53 line = line.trim();
54 if (line.length() > 0) {
55 String parts[] = line.split("\\s*,\\s*");
56 for (int i = 0; i < parts.length; i++) {
57 int n = parts[i].lastIndexOf('.');
58 if (n > 0) {
59 refers.add(parts[i].subSequence(0, n));
60 }
61 }
62 }
63 line = br.readLine();
64 }
65 br.close();
66 return refers;
67 }
68
69 public boolean analyzeJar(Analyzer analyzer) throws Exception {
70 Jar jar = analyzer.getJar();
71 Map<String, Resource> dir = jar.getDirectories().get("META-INF/spring");
72 if ( dir == null || dir.isEmpty())
73 return false;
74
75 for (Iterator<Entry<String, Resource>> i = dir.entrySet().iterator(); i.hasNext();) {
76 Entry<String, Resource> entry = i.next();
77 String path = entry.getKey();
78 Resource resource = entry.getValue();
79 if (SPRING_SOURCE.matcher(path).matches()) {
80 try {
81 InputStream in = resource.openInputStream();
82 Set<CharSequence> set = analyze(in);
83 in.close();
84 for (Iterator<CharSequence> r = set.iterator(); r.hasNext();) {
85 PackageRef pack = analyzer.getPackageRef((String) r.next());
86 if ( !QN.matcher(pack.getFQN()).matches())
87 analyzer.warning("Package does not seem a package in spring resource ("+path+"): " + pack );
88 if (!analyzer.getReferred().containsKey(pack))
89 analyzer.getReferred().put(pack, new Attrs());
90 }
91 } catch( Exception e ) {
92 analyzer.error("Unexpected exception in processing spring resources("+path+"): " + e );
93 }
94 }
95 }
96 return false;
97 }
98
99}