1 /* |
|
2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 package com.nokia.ivy; |
|
19 |
|
20 import java.io.*; |
|
21 import java.util.ArrayList; |
|
22 import java.util.Collection; |
|
23 import java.util.Collections; |
|
24 import java.util.Date; |
|
25 import java.util.HashMap; |
|
26 import java.util.HashSet; |
|
27 import java.util.Iterator; |
|
28 import java.util.List; |
|
29 import java.util.ListIterator; |
|
30 import java.util.Map; |
|
31 |
|
32 import org.apache.ivy.core.IvyPatternHelper; |
|
33 import org.apache.ivy.core.module.descriptor.Artifact; |
|
34 import org.apache.ivy.core.module.descriptor.DefaultArtifact; |
|
35 import org.apache.ivy.core.module.descriptor.DependencyDescriptor; |
|
36 import org.apache.ivy.core.module.descriptor.ModuleDescriptor; |
|
37 import org.apache.ivy.core.module.id.ModuleRevisionId; |
|
38 import org.apache.ivy.core.resolve.ResolveData; |
|
39 import org.apache.ivy.core.settings.IvyPattern; |
|
40 import org.apache.ivy.plugins.latest.LatestStrategy; |
|
41 import org.apache.ivy.plugins.repository.BasicResource; |
|
42 import org.apache.ivy.plugins.repository.Resource; |
|
43 import org.apache.ivy.plugins.resolver.BasicResolver; |
|
44 import org.apache.ivy.plugins.resolver.util.MDResolvedResource; |
|
45 import org.apache.ivy.plugins.resolver.util.ResolvedResource; |
|
46 import org.apache.ivy.plugins.resolver.util.ResourceMDParser; |
|
47 import org.apache.ivy.plugins.version.VersionMatcher; |
|
48 import org.apache.ivy.util.Message; |
|
49 |
|
50 |
|
51 /** |
|
52 * Ivy plugin to read tool versions |
|
53 */ |
|
54 public class ToolResolver extends BasicResolver |
|
55 { |
|
56 |
|
57 private static final Map<String, String> IVY_ARTIFACT_ATTRIBUTES = new HashMap<String, String>(); |
|
58 static { |
|
59 IVY_ARTIFACT_ATTRIBUTES.put(IvyPatternHelper.ARTIFACT_KEY, "ivy"); |
|
60 IVY_ARTIFACT_ATTRIBUTES.put(IvyPatternHelper.TYPE_KEY, "ivy"); |
|
61 IVY_ARTIFACT_ATTRIBUTES.put(IvyPatternHelper.EXT_KEY, "xml"); |
|
62 } |
|
63 |
|
64 private List<String> ivyPatterns = new ArrayList<String>(); // List (String pattern) |
|
65 private List<String> artifactPatterns = new ArrayList<String>(); // List (String pattern) |
|
66 private boolean m2compatible; |
|
67 |
|
68 |
|
69 public ResolvedResource findIvyFileRef(DependencyDescriptor dd, ResolveData data) { |
|
70 ModuleRevisionId mrid = dd.getDependencyRevisionId(); |
|
71 if (isM2compatible()) { |
|
72 mrid = convertM2IdForResourceSearch(mrid); |
|
73 } |
|
74 return findResourceUsingPatterns(mrid, ivyPatterns, DefaultArtifact.newIvyArtifact(mrid, data.getDate()), getRMDParser(dd, data), data.getDate()); |
|
75 } |
|
76 |
|
77 protected ResolvedResource findArtifactRef(Artifact artifact, Date date) { |
|
78 ModuleRevisionId mrid = artifact.getModuleRevisionId(); |
|
79 if (isM2compatible()) { |
|
80 mrid = convertM2IdForResourceSearch(mrid); |
|
81 } |
|
82 return findResourceUsingPatterns(mrid, artifactPatterns, artifact, getDefaultRMDParser(artifact.getModuleRevisionId().getModuleId()), date); |
|
83 } |
|
84 |
|
85 @SuppressWarnings("unchecked") |
|
86 protected ResolvedResource findResourceUsingPatterns(ModuleRevisionId moduleRevision, List patternList, Artifact artifact, ResourceMDParser rmdparser, Date date) { |
|
87 ResolvedResource rres = null; |
|
88 |
|
89 List<ResolvedResource> resolvedResources = new ArrayList<ResolvedResource>(); |
|
90 boolean dynamic = getSettings().getVersionMatcher().isDynamic(moduleRevision); |
|
91 boolean stop = false; |
|
92 for (Iterator iter = patternList.iterator(); iter.hasNext() && !stop;) { |
|
93 String pattern = (String)iter.next(); |
|
94 rres = findResourceUsingPattern(moduleRevision, pattern, artifact, rmdparser, date); |
|
95 if (rres != null) { |
|
96 resolvedResources.add(rres); |
|
97 stop = !dynamic; // stop iterating if we are not searching a dynamic revision |
|
98 } |
|
99 } |
|
100 |
|
101 if (resolvedResources.size() > 1) { |
|
102 ResolvedResource[] rress = (ResolvedResource[]) resolvedResources.toArray(new ResolvedResource[resolvedResources.size()]); |
|
103 rres = findResource(rress, getName(), getLatestStrategy(), getSettings().getVersionMatcher(), rmdparser, moduleRevision, date); |
|
104 } |
|
105 |
|
106 return rres; |
|
107 } |
|
108 |
|
109 @SuppressWarnings("unchecked") |
|
110 public ResolvedResource findResource( |
|
111 ResolvedResource[] rress, |
|
112 String name, |
|
113 LatestStrategy strategy, |
|
114 VersionMatcher versionMatcher, |
|
115 ResourceMDParser rmdparser, |
|
116 ModuleRevisionId mrid, |
|
117 Date date) { |
|
118 ResolvedResource found = null; |
|
119 List sorted = strategy.sort(rress); |
|
120 List rejected = new ArrayList(); |
|
121 for (ListIterator iter = sorted.listIterator(sorted.size()); iter.hasPrevious();) { |
|
122 ResolvedResource rres = (ResolvedResource) iter.previous(); |
|
123 if (date != null && rres.getLastModified() > date.getTime()) { |
|
124 Message.verbose("\t" + name + ": too young: " + rres); |
|
125 rejected.add(rres.getRevision() + " (" + rres.getLastModified() + ")"); |
|
126 continue; |
|
127 } |
|
128 ModuleRevisionId foundMrid = ModuleRevisionId.newInstance(mrid, rres.getRevision()); |
|
129 if (!versionMatcher.accept(mrid, foundMrid)) { |
|
130 Message.debug("\t" + name + ": rejected by version matcher: " + rres); |
|
131 rejected.add(rres.getRevision()); |
|
132 continue; |
|
133 } |
|
134 if (versionMatcher.needModuleDescriptor(mrid, foundMrid)) { |
|
135 ResolvedResource resolvedResource = rmdparser.parse(rres.getResource(), rres.getRevision()); |
|
136 ModuleDescriptor md = ((MDResolvedResource)resolvedResource).getResolvedModuleRevision().getDescriptor(); |
|
137 if (md.isDefault()) { |
|
138 Message.debug("\t" + name + ": default md rejected by version matcher requiring module descriptor: " + rres); |
|
139 rejected.add(rres.getRevision() + " (MD)"); |
|
140 continue; |
|
141 } else if (!versionMatcher.accept(mrid, md)) { |
|
142 Message.debug("\t" + name + ": md rejected by version matcher: " + rres); |
|
143 rejected.add(rres.getRevision() + " (MD)"); |
|
144 continue; |
|
145 } else { |
|
146 found = resolvedResource; |
|
147 } |
|
148 } else { |
|
149 found = rres; |
|
150 } |
|
151 |
|
152 if (found != null) { |
|
153 if (!found.getResource().exists()) { |
|
154 Message.debug("\t" + name + ": resource not reachable for " + mrid + ": res=" + found.getResource()); |
|
155 logAttempt(found.getResource().toString()); |
|
156 continue; |
|
157 } |
|
158 break; |
|
159 } |
|
160 } |
|
161 if (found == null && !rejected.isEmpty()) { |
|
162 logAttempt(rejected.toString()); |
|
163 } |
|
164 |
|
165 return found; |
|
166 } |
|
167 |
|
168 @SuppressWarnings("unchecked") |
|
169 protected Collection findNames(Map tokenValues, String token) { |
|
170 Collection names = new HashSet(); |
|
171 names.addAll(findIvyNames(tokenValues, token)); |
|
172 if (isAllownomd()) { |
|
173 names.addAll(findArtifactNames(tokenValues, token)); |
|
174 } |
|
175 return names; |
|
176 } |
|
177 |
|
178 protected Collection<String> findIvyNames(Map<String, String> tokenValues, String token) { |
|
179 Collection<String> names = new HashSet<String>(); |
|
180 tokenValues = new HashMap<String, String>(tokenValues); |
|
181 tokenValues.put(IvyPatternHelper.ARTIFACT_KEY, "ivy"); |
|
182 tokenValues.put(IvyPatternHelper.TYPE_KEY, "ivy"); |
|
183 tokenValues.put(IvyPatternHelper.EXT_KEY, "xml"); |
|
184 findTokenValues(names, getIvyPatterns(), tokenValues, token); |
|
185 getSettings().filterIgnore(names); |
|
186 return names; |
|
187 } |
|
188 |
|
189 protected Collection<String> findArtifactNames(Map<String, String> tokenValues, String token) { |
|
190 Collection<String> names = new HashSet<String>(); |
|
191 tokenValues = new HashMap<String, String>(tokenValues); |
|
192 tokenValues.put(IvyPatternHelper.ARTIFACT_KEY, tokenValues.get(IvyPatternHelper.MODULE_KEY)); |
|
193 tokenValues.put(IvyPatternHelper.TYPE_KEY, "jar"); |
|
194 tokenValues.put(IvyPatternHelper.EXT_KEY, "jar"); |
|
195 findTokenValues(names, getArtifactPatterns(), tokenValues, token); |
|
196 getSettings().filterIgnore(names); |
|
197 return names; |
|
198 } |
|
199 |
|
200 // should be overridden by subclasses wanting to have listing features |
|
201 protected void findTokenValues(Collection<String> names, List<String> patterns, Map<String, String> tokenValues, String token) { |
|
202 } |
|
203 /** |
|
204 * example of pattern : ~/Workspace/[module]/[module].ivy.xml |
|
205 * @param pattern |
|
206 */ |
|
207 public void addIvyPattern(String pattern) { |
|
208 ivyPatterns.add(pattern); |
|
209 } |
|
210 |
|
211 public void addArtifactPattern(String pattern) { |
|
212 artifactPatterns.add(pattern); |
|
213 } |
|
214 |
|
215 public List<String> getIvyPatterns() { |
|
216 return Collections.unmodifiableList(ivyPatterns); |
|
217 } |
|
218 |
|
219 public List<String> getArtifactPatterns() { |
|
220 return Collections.unmodifiableList(artifactPatterns); |
|
221 } |
|
222 protected void setIvyPatterns(List<String> ivyPatterns) { |
|
223 this.ivyPatterns = ivyPatterns; |
|
224 } |
|
225 protected void setArtifactPatterns(List<String> artifactPatterns) { |
|
226 this.artifactPatterns = artifactPatterns; |
|
227 } |
|
228 |
|
229 /* |
|
230 * Methods respecting ivy conf method specifications |
|
231 */ |
|
232 public void addConfiguredIvy(IvyPattern p) { |
|
233 ivyPatterns.add(p.getPattern()); |
|
234 } |
|
235 |
|
236 public void addConfiguredArtifact(IvyPattern p) { |
|
237 artifactPatterns.add(p.getPattern()); |
|
238 } |
|
239 |
|
240 public void dumpSettings() { |
|
241 super.dumpSettings(); |
|
242 Message.debug("\t\tm2compatible: " + isM2compatible()); |
|
243 Message.debug("\t\tivy patterns:"); |
|
244 for (ListIterator iter = getIvyPatterns().listIterator(); iter.hasNext();) { |
|
245 String pattern = (String)iter.next(); |
|
246 Message.debug("\t\t\t" + pattern); |
|
247 } |
|
248 Message.debug("\t\tartifact patterns:"); |
|
249 for (ListIterator iter = getArtifactPatterns().listIterator(); iter.hasNext();) { |
|
250 String pattern = (String)iter.next(); |
|
251 Message.debug("\t\t\t" + pattern); |
|
252 } |
|
253 } |
|
254 |
|
255 public boolean isM2compatible() { |
|
256 return m2compatible; |
|
257 } |
|
258 |
|
259 public void setM2compatible(boolean m2compatible) { |
|
260 this.m2compatible = m2compatible; |
|
261 } |
|
262 |
|
263 protected ModuleRevisionId convertM2IdForResourceSearch(ModuleRevisionId mrid) { |
|
264 if (mrid.getOrganisation().indexOf('.') == -1) { |
|
265 return mrid; |
|
266 } |
|
267 return ModuleRevisionId.newInstance(mrid.getOrganisation().replace('.', '/'), mrid.getName(), mrid.getBranch(), mrid.getRevision(), mrid.getExtraAttributes()); |
|
268 } |
|
269 |
|
270 |
|
271 |
|
272 public void publish(Artifact artifact, File src, boolean overwrite) throws IOException |
|
273 { |
|
274 Message.verbose("ToolResolver.publish() start"); |
|
275 } |
|
276 |
|
277 private static File findExecutableOnPath(String executableName) { |
|
278 String systemPath = System.getenv("PATH"); |
|
279 String[] pathDirs = systemPath.split(File.pathSeparator); |
|
280 String[] extensions = {""}; |
|
281 |
|
282 // Using PATHEXT to get the supported extenstions on windows platform |
|
283 if (System.getProperty("os.name").toLowerCase().startsWith("win")) { |
|
284 extensions = System.getenv("PATHEXT").split(File.pathSeparator); |
|
285 } |
|
286 |
|
287 for (String extension : extensions) { |
|
288 String checkName = executableName; |
|
289 if (System.getProperty("os.name").toLowerCase().startsWith("win") && !executableName.toLowerCase().endsWith(extension.toLowerCase())) { |
|
290 checkName = executableName + extension; |
|
291 } |
|
292 |
|
293 File file = new File(checkName); |
|
294 if (file.isAbsolute()) { |
|
295 Message.verbose("Testing: " + file.getAbsolutePath()); |
|
296 if (file.isFile()) { |
|
297 return file; |
|
298 } |
|
299 } |
|
300 for (String pathDir : pathDirs) { |
|
301 file = new File(pathDir, checkName); |
|
302 Message.verbose("Testing: " + file.getAbsolutePath()); |
|
303 if (file.isFile()) { |
|
304 return file; |
|
305 } |
|
306 } |
|
307 } |
|
308 return null; |
|
309 } |
|
310 |
|
311 protected ResolvedResource findResourceUsingPattern(ModuleRevisionId mrid, String pattern, |
|
312 Artifact artifact, ResourceMDParser rmdparser, Date date) |
|
313 { |
|
314 Message.verbose("ToolResolver.findResourceUsingPattern() start"); |
|
315 |
|
316 Message.verbose(artifact.getName()); |
|
317 Message.verbose(mrid.getRevision()); |
|
318 Message.verbose(artifact.getAttribute("versionArgs")); |
|
319 |
|
320 String toolVersion = mrid.getRevision(); |
|
321 ResolvedResource resolvedResource = null; |
|
322 try |
|
323 { |
|
324 File executable = findExecutableOnPath(artifact.getName()); |
|
325 if (executable == null) { |
|
326 return null; |
|
327 } |
|
328 Message.verbose("executable: " + executable.getAbsolutePath()); |
|
329 String versionText = getToolVersion(executable, artifact.getAttribute("versionArgs")); |
|
330 Message.verbose(versionText); |
|
331 |
|
332 if (versionText.contains(toolVersion) || versionText.matches(artifact.getAttribute("versionExp"))) |
|
333 { |
|
334 BasicResource resource = new BasicResource(executable.getAbsolutePath(), true, 0, 0, true); |
|
335 resolvedResource = new ResolvedResource(resource, toolVersion); |
|
336 } |
|
337 } |
|
338 catch (IOException e) |
|
339 { |
|
340 // TODO Auto-generated catch block |
|
341 e.printStackTrace(); |
|
342 } |
|
343 return resolvedResource; |
|
344 } |
|
345 |
|
346 @Override |
|
347 protected long get(Resource resource, File dest) throws IOException |
|
348 { |
|
349 Message.verbose("ToolResolver.get() start"); |
|
350 return 0; |
|
351 } |
|
352 |
|
353 private String getToolVersion(File executable, String versionArgs) throws IOException |
|
354 { |
|
355 Runtime runtime = Runtime.getRuntime(); |
|
356 Message.verbose("'" + executable.getAbsolutePath() + " " + versionArgs + "'"); |
|
357 //Process toolProcess = runtime.exec(toolName+ "." + toolType + " " + versionArgs); |
|
358 Process toolProcess = runtime.exec(executable.getAbsolutePath() + " " + versionArgs); |
|
359 InputStream in = toolProcess.getInputStream(); |
|
360 InputStream err = toolProcess.getErrorStream(); |
|
361 String outText = toString(in).trim(); |
|
362 String errText = toString(err).trim(); |
|
363 Message.verbose("err: " + errText); |
|
364 return outText + errText; |
|
365 } |
|
366 |
|
367 private String toString(InputStream inputStream) throws IOException |
|
368 { |
|
369 byte[] buffer = new byte[4096]; |
|
370 OutputStream outputStream = new ByteArrayOutputStream(); |
|
371 |
|
372 while (true) { |
|
373 int read = inputStream.read(buffer); |
|
374 |
|
375 if (read == -1) { |
|
376 break; |
|
377 } |
|
378 |
|
379 outputStream.write(buffer, 0, read); |
|
380 } |
|
381 |
|
382 outputStream.close(); |
|
383 inputStream.close(); |
|
384 |
|
385 return outputStream.toString(); |
|
386 } |
|
387 |
|
388 @Override |
|
389 protected Resource getResource(String arg0) throws IOException { |
|
390 // TODO Auto-generated method stub |
|
391 return null; |
|
392 } |
|
393 |
|
394 } |
|
395 |
|
396 |
|