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