Improve capability to search source code on maven.org
emmanue1
5 years ago
+102
-65
9 | 9 | import org.jd.gui.api.API; |
10 | 10 | import org.jd.gui.api.model.Container; |
11 | 11 | import org.jd.gui.service.preferencespanel.MavenOrgSourceLoaderPreferencesProvider; |
12 | import org.jd.gui.spi.PreferencesPanel; | |
13 | 12 | import org.jd.gui.spi.SourceLoader; |
14 | 13 | import org.jd.gui.util.exception.ExceptionUtil; |
15 | 14 | |
16 | import javax.swing.*; | |
17 | import javax.swing.event.DocumentEvent; | |
18 | import javax.swing.event.DocumentListener; | |
19 | 15 | import javax.xml.stream.XMLInputFactory; |
20 | 16 | import javax.xml.stream.XMLStreamConstants; |
21 | 17 | import javax.xml.stream.XMLStreamReader; |
22 | import javax.xml.transform.Source; | |
23 | import java.awt.*; | |
24 | import java.awt.event.ActionEvent; | |
25 | import java.awt.event.ActionListener; | |
26 | 18 | import java.io.*; |
27 | 19 | import java.net.URL; |
28 | import java.nio.file.Path; | |
29 | 20 | import java.security.DigestInputStream; |
30 | 21 | import java.security.MessageDigest; |
31 | 22 | import java.util.*; |
32 | import java.util.List; | |
33 | import java.util.regex.Pattern; | |
34 | 23 | import java.util.zip.ZipEntry; |
35 | 24 | import java.util.zip.ZipInputStream; |
36 | 25 | |
54 | 43 | } |
55 | 44 | |
56 | 45 | if (accepted(filters, entry.getPath())) { |
57 | return search(entry, cache.get(entry.getContainer().getRoot().getParent())); | |
46 | return searchSource(entry, cache.get(entry.getContainer().getRoot().getParent())); | |
58 | 47 | } |
59 | 48 | } |
60 | 49 | |
63 | 52 | |
64 | 53 | @Override |
65 | 54 | public String loadSource(API api, Container.Entry entry) { |
66 | boolean activated = !"false".equals(api.getPreferences().get(MavenOrgSourceLoaderPreferencesProvider.ACTIVATED)); | |
67 | ||
68 | 55 | if (isActivated(api)) { |
69 | 56 | String filters = api.getPreferences().get(MavenOrgSourceLoaderPreferencesProvider.FILTERS); |
70 | 57 | |
73 | 60 | } |
74 | 61 | |
75 | 62 | if (accepted(filters, entry.getPath())) { |
76 | return search(entry, load(entry.getContainer().getRoot().getParent())); | |
63 | return searchSource(entry, downloadSourceJarFile(entry.getContainer().getRoot().getParent())); | |
77 | 64 | } |
78 | 65 | } |
79 | 66 | |
82 | 69 | |
83 | 70 | @Override |
84 | 71 | public File loadSourceFile(API api, Container.Entry entry) { |
85 | return isActivated(api) ? load(entry) : null; | |
72 | return isActivated(api) ? downloadSourceJarFile(entry) : null; | |
86 | 73 | } |
87 | 74 | |
88 | 75 | private static boolean isActivated(API api) { |
89 | 76 | return !"false".equals(api.getPreferences().get(MavenOrgSourceLoaderPreferencesProvider.ACTIVATED)); |
90 | 77 | } |
91 | 78 | |
92 | protected String search(Container.Entry entry, File file) { | |
93 | if (file != null) { | |
94 | String fileName = file.toString().toLowerCase(); | |
95 | ||
96 | if (fileName.endsWith(".zip") || fileName.endsWith(".jar")) { | |
97 | byte[] buffer = new byte[1024 * 2]; | |
98 | ||
99 | try (ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(file)))) { | |
100 | ZipEntry ze = zis.getNextEntry(); | |
101 | String name = entry.getPath(); | |
102 | ||
103 | name = name.substring(0, name.length()-6) + ".java"; // 6 = ".class".length() | |
104 | ||
105 | while (ze != null) { | |
106 | if (ze.getName().equals(name)) { | |
107 | ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
108 | int read = zis.read(buffer); | |
109 | ||
110 | while (read > 0) { | |
111 | out.write(buffer, 0, read); | |
112 | read = zis.read(buffer); | |
113 | } | |
114 | ||
115 | return new String(out.toByteArray(), "UTF-8"); | |
116 | } | |
117 | ||
118 | ze = zis.getNextEntry(); | |
119 | } | |
120 | ||
121 | zis.closeEntry(); | |
122 | } catch (IOException e) { | |
123 | assert ExceptionUtil.printStackTrace(e); | |
124 | } | |
125 | } | |
126 | } | |
127 | ||
128 | return null; | |
129 | } | |
130 | ||
131 | protected File load(Container.Entry entry) { | |
79 | protected String searchSource(Container.Entry entry, File sourceJarFile) { | |
80 | if (sourceJarFile != null) { | |
81 | byte[] buffer = new byte[1024 * 2]; | |
82 | ||
83 | try (ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(sourceJarFile)))) { | |
84 | ZipEntry ze = zis.getNextEntry(); | |
85 | String name = entry.getPath(); | |
86 | ||
87 | name = name.substring(0, name.length()-6) + ".java"; // 6 = ".class".length() | |
88 | ||
89 | while (ze != null) { | |
90 | if (ze.getName().equals(name)) { | |
91 | ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
92 | int read = zis.read(buffer); | |
93 | ||
94 | while (read > 0) { | |
95 | out.write(buffer, 0, read); | |
96 | read = zis.read(buffer); | |
97 | } | |
98 | ||
99 | return new String(out.toByteArray(), "UTF-8"); | |
100 | } | |
101 | ||
102 | ze = zis.getNextEntry(); | |
103 | } | |
104 | ||
105 | zis.closeEntry(); | |
106 | } catch (IOException e) { | |
107 | assert ExceptionUtil.printStackTrace(e); | |
108 | } | |
109 | } | |
110 | ||
111 | return null; | |
112 | } | |
113 | ||
114 | protected File downloadSourceJarFile(Container.Entry entry) { | |
132 | 115 | if (cache.containsKey(entry)) { |
133 | 116 | return cache.get(entry); |
134 | 117 | } |
157 | 140 | URL searchUrl = new URL(MAVENORG_SEARCH_URL_PREFIX + sha1 + MAVENORG_SEARCH_URL_SUFFIX); |
158 | 141 | boolean sourceAvailable = false; |
159 | 142 | String id = null; |
143 | String numFound = null; | |
160 | 144 | |
161 | 145 | try (InputStream is = searchUrl.openStream()) { |
162 | 146 | XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(is); |
171 | 155 | } else { |
172 | 156 | name = "str"; |
173 | 157 | } |
158 | } else if ("result".equals(reader.getLocalName())) { | |
159 | numFound = reader.getAttributeValue(null, "numFound"); | |
174 | 160 | } else { |
175 | 161 | name = ""; |
176 | 162 | } |
191 | 177 | reader.close(); |
192 | 178 | } |
193 | 179 | |
194 | if (sourceAvailable == false) { | |
195 | failed.add(entry); | |
196 | } else { | |
197 | // Load source | |
180 | String groupId=null, artifactId=null, version=null; | |
181 | ||
182 | if ("0".equals(numFound)) { | |
183 | // File not indexed by Apache Solr of maven.org -> Try to found groupId, artifactId, version in 'pom.properties' | |
184 | Properties pomProperties = getPomProperties(entry); | |
185 | ||
186 | if (pomProperties != null) { | |
187 | groupId = pomProperties.getProperty("groupId"); | |
188 | artifactId = pomProperties.getProperty("artifactId"); | |
189 | version = pomProperties.getProperty("version"); | |
190 | } | |
191 | } else if ("1".equals(numFound) && sourceAvailable) { | |
198 | 192 | int index1 = id.indexOf(':'); |
199 | 193 | int index2 = id.lastIndexOf(':'); |
200 | String groupId = id.substring(0, index1); | |
201 | String artifactId = id.substring(index1+1, index2); | |
202 | String version = id.substring(index2+1); | |
194 | ||
195 | groupId = id.substring(0, index1); | |
196 | artifactId = id.substring(index1+1, index2); | |
197 | version = id.substring(index2+1); | |
198 | } | |
199 | ||
200 | if (artifactId != null) { | |
201 | // Load source | |
203 | 202 | String filePath = groupId.replace('.', '/') + '/' + artifactId + '/' + version + '/' + artifactId + '-' + version; |
204 | 203 | URL loadUrl = new URL(MAVENORG_LOAD_URL_PREFIX + filePath + MAVENORG_LOAD_URL_SUFFIX); |
205 | File tmpFile = File.createTempFile("jd-gui.tmp.", '.' + artifactId + '-' + version + "-sources.jar"); | |
204 | File tmpFile = File.createTempFile("jd-gui.tmp.", '.' + groupId + '_' + artifactId + '_' + version + "-sources.jar"); | |
206 | 205 | |
207 | 206 | tmpFile.delete(); |
208 | 207 | tmpFile.deleteOnExit(); |
220 | 219 | } |
221 | 220 | } catch (Exception e) { |
222 | 221 | assert ExceptionUtil.printStackTrace(e); |
223 | failed.add(entry); | |
222 | } | |
223 | } | |
224 | ||
225 | failed.add(entry); | |
226 | return null; | |
227 | } | |
228 | ||
229 | private static Properties getPomProperties(Container.Entry parent) { | |
230 | // Search 'META-INF/maven/*/*/pom.properties' | |
231 | for (Container.Entry child1 : parent.getChildren()) { | |
232 | if (child1.isDirectory() && child1.getPath().equals("META-INF")) { | |
233 | for (Container.Entry child2 : child1.getChildren()) { | |
234 | if (child2.isDirectory() && child2.getPath().equals("META-INF/maven")) { | |
235 | if (child2.isDirectory()) { | |
236 | Collection<Container.Entry> children = child2.getChildren(); | |
237 | if (children.size() == 1) { | |
238 | Container.Entry entry = children.iterator().next(); | |
239 | if (entry.isDirectory()) { | |
240 | children = entry.getChildren(); | |
241 | if (children.size() == 1) { | |
242 | entry = children.iterator().next(); | |
243 | for (Container.Entry child3 : entry.getChildren()) { | |
244 | if (!child3.isDirectory() && child3.getPath().endsWith("/pom.properties")) { | |
245 | // Load properties | |
246 | try (InputStream is = child3.getInputStream()) { | |
247 | Properties properties = new Properties(); | |
248 | properties.load(is); | |
249 | return properties; | |
250 | } catch (Exception e) { | |
251 | assert ExceptionUtil.printStackTrace(e); | |
252 | } | |
253 | } | |
254 | } | |
255 | } | |
256 | } | |
257 | } | |
258 | } | |
259 | } | |
260 | } | |
224 | 261 | } |
225 | 262 | } |
226 | 263 |