1 6 package fr.jayasoft.ivy.resolver; 7 8 import java.io.File ; 9 import java.io.IOException ; 10 import java.net.MalformedURLException ; 11 import java.net.URL ; 12 import java.text.ParseException ; 13 import java.text.SimpleDateFormat ; 14 import java.util.ArrayList ; 15 import java.util.Collection ; 16 import java.util.Collections ; 17 import java.util.Date ; 18 import java.util.HashMap ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.ListIterator ; 22 import java.util.Map ; 23 24 import fr.jayasoft.ivy.Artifact; 25 import fr.jayasoft.ivy.ArtifactOrigin; 26 import fr.jayasoft.ivy.DefaultArtifact; 27 import fr.jayasoft.ivy.DefaultModuleDescriptor; 28 import fr.jayasoft.ivy.DefaultModuleRevision; 29 import fr.jayasoft.ivy.DependencyDescriptor; 30 import fr.jayasoft.ivy.DependencyResolver; 31 import fr.jayasoft.ivy.Ivy; 32 import fr.jayasoft.ivy.IvyNode; 33 import fr.jayasoft.ivy.ModuleDescriptor; 34 import fr.jayasoft.ivy.ModuleId; 35 import fr.jayasoft.ivy.ModuleRevisionId; 36 import fr.jayasoft.ivy.ResolveData; 37 import fr.jayasoft.ivy.ResolvedModuleRevision; 38 import fr.jayasoft.ivy.event.download.EndArtifactDownloadEvent; 39 import fr.jayasoft.ivy.event.download.NeedArtifactEvent; 40 import fr.jayasoft.ivy.event.download.StartArtifactDownloadEvent; 41 import fr.jayasoft.ivy.parser.ModuleDescriptorParser; 42 import fr.jayasoft.ivy.parser.ModuleDescriptorParserRegistry; 43 import fr.jayasoft.ivy.report.ArtifactDownloadReport; 44 import fr.jayasoft.ivy.report.DownloadReport; 45 import fr.jayasoft.ivy.report.DownloadStatus; 46 import fr.jayasoft.ivy.repository.Resource; 47 import fr.jayasoft.ivy.repository.ResourceHelper; 48 import fr.jayasoft.ivy.repository.url.URLRepository; 49 import fr.jayasoft.ivy.repository.url.URLResource; 50 import fr.jayasoft.ivy.util.ChecksumHelper; 51 import fr.jayasoft.ivy.util.IvyPatternHelper; 52 import fr.jayasoft.ivy.util.Message; 53 import fr.jayasoft.ivy.xml.XmlModuleDescriptorParser; 54 import fr.jayasoft.ivy.xml.XmlModuleDescriptorWriter; 55 56 60 public abstract class BasicResolver extends AbstractResolver { 61 public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat ("yyyyMMddHHmmss"); 62 63 protected String _workspaceName; 64 67 private boolean _envDependent = true; 68 69 private List _ivyattempts = new ArrayList (); 70 private Map _artattempts = new HashMap (); 71 72 private Boolean _checkmodified = null; 73 74 private boolean _checkconsistency = true; 75 76 private boolean _allownomd = true; 77 78 private String _checksums = null; 79 80 private URLRepository _extartifactrep = new URLRepository(); 82 public BasicResolver() { 83 _workspaceName = Ivy.getLocalHostName(); 84 } 85 86 public String getWorkspaceName() { 87 return _workspaceName; 88 } 89 90 public void setWorkspaceName(String workspaceName) { 91 _workspaceName = workspaceName; 92 } 93 94 public boolean isEnvDependent() { 95 return _envDependent; 96 } 97 98 public void setEnvDependent(boolean envDependent) { 99 _envDependent = envDependent; 100 } 101 102 106 public boolean isCheckmodified() { 107 if (_checkmodified == null) { 108 if (getIvy() != null) { 109 String check = getIvy().getVariable("ivy.resolver.default.check.modified"); 110 return check != null ? Boolean.valueOf(check).booleanValue() : false; 111 } else { 112 return false; 113 } 114 } else { 115 return _checkmodified.booleanValue(); 116 } 117 } 118 119 120 public void setCheckmodified(boolean check) { 121 _checkmodified = Boolean.valueOf(check); 122 } 123 124 public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data) throws ParseException { 125 DependencyDescriptor systemDd = dd; 126 dd = fromSystem(dd); 127 128 clearIvyAttempts(); 129 boolean downloaded = false; 130 boolean searched = false; 131 ModuleRevisionId mrid = dd.getDependencyRevisionId(); 132 int index = mrid.getRevision().indexOf("@"); 134 if (index != -1 && !mrid.getRevision().substring(index+1).equals(_workspaceName)) { 135 Message.verbose("\t"+getName()+": unhandled revision => "+mrid.getRevision()); 136 return null; 137 } 138 139 boolean isDynamic = getIvy().getVersionMatcher().isDynamic(mrid); 140 if (isDynamic && !acceptLatest()) { 141 Message.error("dynamic revisions not handled by "+getClass().getName()+". impossible to resolve "+mrid); 142 return null; 143 } 144 145 boolean isChangingRevision = getChangingMatcher().matches(mrid.getRevision()); 146 boolean isChangingDependency = isChangingRevision || dd.isChanging(); 147 148 ResolvedModuleRevision cachedRmr = null; 151 boolean checkedCache = false; 152 if (!isDynamic && !isCheckmodified() && !isChangingDependency) { 153 cachedRmr = findModuleInCache(data, mrid); 154 checkedCache = true; 155 if (cachedRmr != null) { 156 if (cachedRmr.getDescriptor().isDefault() && cachedRmr.getResolver() != this) { 157 Message.verbose("\t"+getName()+": found revision in cache: "+mrid+" (resolved by "+cachedRmr.getResolver().getName()+"): but it's a default one, maybe we can find a better one"); 158 } else { 159 Message.verbose("\t"+getName()+": revision in cache: "+mrid); 160 return toSystem(cachedRmr); 161 } 162 } 163 } 164 checkInterrupted(); 165 URL cachedIvyURL = null; 166 ResolvedResource ivyRef = findIvyFileRef(dd, data); 167 checkInterrupted(); 168 searched = true; 169 170 ModuleDescriptorParser parser; 172 ModuleDescriptor md; 173 ModuleDescriptor systemMd = null; 174 if (ivyRef == null) { 175 if (!isAllownomd()) { 176 Message.verbose("\t"+getName()+": no ivy file found for "+mrid); 177 logIvyNotFound(mrid); 178 return null; 179 } 180 parser = XmlModuleDescriptorParser.getInstance(); 181 md = DefaultModuleDescriptor.newDefaultInstance(mrid, dd.getAllDependencyArtifactsIncludes()); 182 ResolvedResource artifactRef = findFirstArtifactRef(md, dd, data); 183 if (getIvy() != null && getIvy().isInterrupted()) { 184 throw new RuntimeException ("interrupted"); 185 } 186 if (artifactRef == null) { 187 Message.verbose("\t"+getName()+": no ivy file nor artifact found for "+mrid); 188 logIvyNotFound(mrid); 189 String [] conf = md.getConfigurationsNames(); 190 for (int i = 0; i < conf.length; i++) { 191 Artifact[] artifacts = md.getArtifacts(conf[i]); 192 for (int j = 0; j < artifacts.length; j++) { 193 logArtifactNotFound(artifacts[j]); 194 } 195 } 196 if (!checkedCache) { 197 cachedRmr = findModuleInCache(data, mrid); 198 } 199 if (cachedRmr != null) { 200 Message.verbose("\t"+getName()+": revision in cache: "+mrid); 201 return toSystem(cachedRmr); 202 } 203 return null; 204 } else { 205 Message.verbose("\t"+getName()+": no ivy file found for "+mrid+": using default data"); 206 logIvyNotFound(mrid); 207 if (isDynamic) { 208 md.setResolvedModuleRevisionId(ModuleRevisionId.newInstance(mrid, artifactRef.getRevision())); 209 } 210 } 211 } else { 212 ResolvedModuleRevision rmr = null; 213 if (ivyRef instanceof MDResolvedResource) { 214 rmr = ((MDResolvedResource)ivyRef).getResolvedModuleRevision(); 215 } 216 if (rmr == null) { 217 rmr = parse(ivyRef, dd, data); 218 if (rmr == null) { 219 return null; 220 } 221 } 222 if (!rmr.isDownloaded()) { 223 return toSystem(rmr); 224 } else { 225 md = rmr.getDescriptor(); 226 parser = ModuleDescriptorParserRegistry.getInstance().getParser(ivyRef.getResource()); 227 cachedIvyURL = rmr.getLocalMDUrl(); 228 229 systemMd = toSystem(md); 231 if (_checkconsistency) { 232 checkDescriptorConsistency(mrid, md, ivyRef); 233 checkDescriptorConsistency(systemDd.getDependencyRevisionId(), systemMd, ivyRef); 234 } else { 235 if (md instanceof DefaultModuleDescriptor) { 236 String revision = getRevision(ivyRef, mrid, md); 237 ((DefaultModuleDescriptor)md).setModuleRevisionId(ModuleRevisionId.newInstance(mrid, revision)); 238 } else { 239 Message.warn("consistency disabled with instance of non DefaultModuleDescriptor... module info can't be updated, so consistency check will be done"); 240 checkDescriptorConsistency(mrid, md, ivyRef); 241 checkDescriptorConsistency(systemDd.getDependencyRevisionId(), systemMd, ivyRef); 242 } 243 } 244 } 245 } 246 247 if (systemMd == null) { 248 systemMd = toSystem(md); 249 } 250 251 ModuleRevisionId resolvedMrid = mrid; 253 if (isDynamic) { 254 resolvedMrid = md.getResolvedModuleRevisionId(); 255 if (resolvedMrid.getRevision() == null || resolvedMrid.getRevision().length() == 0) { 256 if (ivyRef.getRevision() == null || ivyRef.getRevision().length() == 0) { 257 resolvedMrid = ModuleRevisionId.newInstance(resolvedMrid, "working@"+getName()); 258 } else { 259 resolvedMrid = ModuleRevisionId.newInstance(resolvedMrid, ivyRef.getRevision()); 260 } 261 } 262 Message.verbose("\t\t["+resolvedMrid.getRevision()+"] "+mrid.getModuleId()); 263 } 264 md.setResolvedModuleRevisionId(resolvedMrid); 265 systemMd.setResolvedModuleRevisionId(toSystem(resolvedMrid)); 267 if (!getIvy().getVersionMatcher().accept(mrid, md)) { 269 Message.info("\t"+getName()+": unacceptable revision => was="+md.getModuleRevisionId().getRevision()+" required="+mrid.getRevision()); 270 return null; 271 } 272 273 274 if (data.getDate() != null) { 276 long pubDate = getPublicationDate(md, dd, data); 277 if (pubDate > data.getDate().getTime()) { 278 Message.info("\t"+getName()+": unacceptable publication date => was="+new Date (pubDate)+" required="+data.getDate()); 279 return null; 280 } else if (pubDate == -1) { 281 Message.info("\t"+getName()+": impossible to guess publication date: artifact missing for "+mrid); 282 return null; 283 } 284 md.setResolvedPublicationDate(new Date (pubDate)); 285 systemMd.setResolvedPublicationDate(new Date (pubDate)); } 287 288 try { 289 File ivyFile = data.getIvy().getIvyFileInCache(data.getCache(), systemMd.getResolvedModuleRevisionId()); 290 if (ivyRef == null) { 291 XmlModuleDescriptorWriter.write(systemMd, ivyFile); 293 } else { 294 if (md instanceof DefaultModuleDescriptor) { 295 DefaultModuleDescriptor dmd = (DefaultModuleDescriptor)md; 296 if (data.getIvy().logNotConvertedExclusionRule() && dmd.isNamespaceUseful()) { 297 Message.warn("the module descriptor "+ivyRef.getResource()+" has information which can't be converted into the system namespace. It will require the availability of the namespace '"+getNamespace().getName()+"' to be fully usable."); 298 } 299 } 300 parser.toIvyFile(cachedIvyURL.openStream(), ivyRef.getResource(), ivyFile, systemMd); 302 long repLastModified = ivyRef.getLastModified(); 303 if (repLastModified > 0) { 304 ivyFile.setLastModified(repLastModified); 305 } 306 } 307 } catch (Exception e) { 308 if (ivyRef == null) { 309 Message.warn("impossible to create ivy file in cache for module : " + resolvedMrid); 310 } else { 311 e.printStackTrace(); 312 Message.warn("impossible to copy ivy file to cache : "+ivyRef.getResource()); 313 } 314 } 315 316 data.getIvy().saveResolver(data.getCache(), systemMd, getName()); 317 data.getIvy().saveArtResolver(data.getCache(), systemMd, getName()); 318 return new DefaultModuleRevision(this, this, systemMd, searched, downloaded, cachedIvyURL); 319 } 320 321 private String getRevision(ResolvedResource ivyRef, ModuleRevisionId askedMrid, ModuleDescriptor md) throws ParseException { 322 String revision = ivyRef.getRevision(); 323 if (revision == null) { 324 Message.debug("no revision found in reference for "+askedMrid); 325 if (getIvy().getVersionMatcher().isDynamic(askedMrid)) { 326 if (md.getModuleRevisionId().getRevision() == null) { 327 return "working@"+getName(); 328 } else { 329 Message.debug("using "+askedMrid); 330 revision = md.getModuleRevisionId().getRevision(); 331 } 332 } else { 333 Message.debug("using "+askedMrid); 334 revision = askedMrid.getRevision(); 335 } 336 } 337 return revision; 338 } 339 340 public ResolvedModuleRevision parse( 341 ResolvedResource ivyRef, 342 DependencyDescriptor dd, 343 ResolveData data 344 ) throws ParseException { 345 346 ModuleRevisionId mrid = dd.getDependencyRevisionId(); 347 ModuleDescriptorParser parser = ModuleDescriptorParserRegistry.getInstance().getParser(ivyRef.getResource()); 348 if (parser == null) { 349 Message.warn("no module descriptor parser available for "+ivyRef.getResource()); 350 return null; 351 } 352 Message.verbose("\t"+getName()+": found md file for "+mrid); 353 Message.verbose("\t\t=> "+ivyRef); 354 Message.debug("\tparser = "+parser); 355 356 boolean isChangingRevision = getChangingMatcher().matches(mrid.getRevision()); 357 boolean isChangingDependency = isChangingRevision || dd.isChanging(); 358 Date cachedPublicationDate = null; 359 ModuleRevisionId resolvedMrid = mrid; 360 361 if (getIvy().getVersionMatcher().isDynamic(mrid)) { 363 resolvedMrid = ModuleRevisionId.newInstance(mrid, ivyRef.getRevision()); 364 IvyNode node = getSystemNode(data, resolvedMrid); 365 if (node != null && node.getModuleRevision() != null) { 366 if (node.getDescriptor() != null && node.getDescriptor().isDefault()) { 368 Message.verbose("\t"+getName()+": found already resolved revision: "+resolvedMrid+": but it's a default one, maybe we can find a better one"); 369 } else { 370 Message.verbose("\t"+getName()+": revision already resolved: "+resolvedMrid); 371 return searchedRmr(node.getModuleRevision()); 372 } 373 } 374 } 375 376 ResolvedModuleRevision rmr = findModuleInCache(data, resolvedMrid); 378 if (rmr != null) { 379 if (rmr.getDescriptor().isDefault() && rmr.getResolver() != this) { 380 Message.verbose("\t"+getName()+": found revision in cache: "+mrid+" (resolved by "+rmr.getResolver().getName()+"): but it's a default one, maybe we can find a better one"); 381 } else { 382 if (!isCheckmodified() && !isChangingDependency) { 383 Message.verbose("\t"+getName()+": revision in cache: "+mrid); 384 return searchedRmr(rmr); 385 } 386 long repLastModified = ivyRef.getLastModified(); 387 long cacheLastModified = rmr.getDescriptor().getLastModified(); 388 if (!rmr.getDescriptor().isDefault() && repLastModified <= cacheLastModified) { 389 Message.verbose("\t"+getName()+": revision in cache (not updated): "+resolvedMrid); 390 return searchedRmr(rmr); 391 } else { 392 Message.verbose("\t"+getName()+": revision in cache is not up to date: "+resolvedMrid); 393 if (isChangingDependency) { 394 cachedPublicationDate = rmr.getDescriptor().getResolvedPublicationDate(); 397 } 398 } 399 } 400 } 401 402 URL cachedIvyURL = null; 404 File ivyTempFile = null; 405 try { 406 if (ResourceHelper.equals(ivyRef.getResource(), 408 data.getIvy().getIvyFileInCache(data.getCache(), toSystem(resolvedMrid)))) { 409 Message.error("invalid configuration for resolver '"+getName()+"': pointing ivy files to ivy cache is forbidden !"); 410 return null; 411 } 412 413 ivyTempFile = File.createTempFile("ivy", "xml"); 415 ivyTempFile.deleteOnExit(); 416 Message.debug("\t"+getName()+": downloading "+ivyRef.getResource()+" to "+ivyTempFile); 417 getAndCheck(ivyRef.getResource(), ivyTempFile); 418 try { 419 cachedIvyURL = ivyTempFile.toURL(); 420 } catch (MalformedURLException ex) { 421 Message.warn("malformed url exception for temp file: "+ivyTempFile+": "+ex.getMessage()); 422 return null; 423 } 424 } catch (IOException ex) { 425 Message.warn("problem while downloading ivy file: "+ivyRef.getResource()+" to "+ivyTempFile+": "+ex.getMessage()); 426 return null; 427 } 428 try { 429 ModuleDescriptor md = parser.parseDescriptor(data.getIvy(), cachedIvyURL, ivyRef.getResource(), doValidate(data)); 430 Message.debug("\t"+getName()+": parsed downloaded md file for "+mrid+" parsed="+md.getModuleRevisionId()); 431 432 433 boolean deleteOldArtifacts = false; 435 if (cachedPublicationDate != null && !cachedPublicationDate.equals(md.getResolvedPublicationDate())) { 436 Message.verbose(dd+" has changed: deleting old artifacts"); 438 deleteOldArtifacts = true; 439 } 440 if (deleteOldArtifacts) { 441 String [] confs = rmr.getDescriptor().getConfigurationsNames(); 442 for (int i = 0; i < confs.length; i++) { 443 Artifact[] arts = rmr.getDescriptor().getArtifacts(confs[i]); 444 for (int j = 0; j < arts.length; j++) { 445 Artifact transformedArtifact = toSystem(arts[j]); 446 ArtifactOrigin origin = data.getIvy().getSavedArtifactOrigin(data.getCache(), transformedArtifact); 447 File artFile = data.getIvy().getArchiveFileInCache(data.getCache(), transformedArtifact, origin, false); 448 if (artFile.exists()) { 449 Message.debug("deleting "+artFile); 450 artFile.delete(); 451 } 452 data.getIvy().removeSavedArtifactOrigin(data.getCache(), transformedArtifact); 453 } 454 } 455 } else if (isChangingDependency){ 456 Message.verbose(dd+" is changing, but has not changed: will trust cached artifacts if any"); 457 } 458 return new DefaultModuleRevision(this, this, md, true, true, cachedIvyURL); 459 } catch (IOException ex) { 460 Message.warn("io problem while parsing ivy file: "+ivyRef.getResource()+": "+ex.getMessage()); 461 return null; 462 } 463 464 } 465 466 protected ResourceMDParser getRMDParser(final DependencyDescriptor dd, final ResolveData data) { 467 return new ResourceMDParser() { 468 public MDResolvedResource parse(Resource resource, String rev) { 469 try { 470 ResolvedModuleRevision rmr = BasicResolver.this.parse(new ResolvedResource(resource, rev), dd, data); 471 if (rmr == null) { 472 return null; 473 } else { 474 return new MDResolvedResource(resource, rev, rmr); 475 } 476 } catch (ParseException e) { 477 return null; 478 } 479 } 480 481 }; 482 } 483 484 protected ResourceMDParser getDefaultRMDParser(final ModuleId mid) { 485 return new ResourceMDParser() { 486 public MDResolvedResource parse(Resource resource, String rev) { 487 return new MDResolvedResource(resource, rev, new DefaultModuleRevision(BasicResolver.this, BasicResolver.this, DefaultModuleDescriptor.newDefaultInstance(new ModuleRevisionId(mid, rev)), false, false, null)); 488 } 489 }; 490 } 491 492 493 private void checkDescriptorConsistency(ModuleRevisionId mrid, ModuleDescriptor md, ResolvedResource ivyRef) throws ParseException { 499 boolean ok = true; 500 StringBuffer errors = new StringBuffer (); 501 if (!mrid.getOrganisation().equals(md.getModuleRevisionId().getOrganisation())) { 502 Message.error("\t"+getName()+": bad organisation found in "+ivyRef.getResource()+": expected='"+mrid.getOrganisation()+"' found='"+md.getModuleRevisionId().getOrganisation()+"'"); 503 errors.append("bad organisation: expected='"+mrid.getOrganisation()+"' found='"+md.getModuleRevisionId().getOrganisation()+"'; "); 504 ok = false; 505 } 506 if (!mrid.getName().equals(md.getModuleRevisionId().getName())) { 507 Message.error("\t"+getName()+": bad module name found in "+ivyRef.getResource()+": expected='"+mrid.getName()+" found='"+md.getModuleRevisionId().getName()+"'"); 508 errors.append("bad module name: expected='"+mrid.getName()+"' found='"+md.getModuleRevisionId().getName()+"'; "); 509 ok = false; 510 } 511 if (ivyRef.getRevision() != null && !ivyRef.getRevision().startsWith("working@")) { 512 ModuleRevisionId expectedMrid = ModuleRevisionId.newInstance(mrid, ivyRef.getRevision()); 513 if (!getIvy().getVersionMatcher().accept(expectedMrid, md)) { 514 Message.error("\t"+getName()+": bad revision found in "+ivyRef.getResource()+": expected='"+ivyRef.getRevision()+" found='"+md.getModuleRevisionId().getRevision()+"'"); 515 errors.append("bad revision: expected='"+ivyRef.getRevision()+"' found='"+md.getModuleRevisionId().getRevision()+"'; "); 516 ok = false; 517 } 518 } 519 if (!getIvy().getStatusManager().isStatus(md.getStatus())) { 520 Message.error("\t"+getName()+": bad status found in "+ivyRef.getResource()+": '"+md.getStatus()+"'"); 521 errors.append("bad status: '"+md.getStatus()+"'; "); 522 ok = false; 523 } 524 if (!ok) { 525 throw new ParseException ("inconsistent module descriptor file found in '"+ivyRef.getResource()+"': "+errors, 0); 526 } 527 } 528 529 protected void clearIvyAttempts() { 530 _ivyattempts.clear(); 531 clearArtifactAttempts(); 532 } 533 534 protected ResolvedModuleRevision searchedRmr(final ResolvedModuleRevision rmr) { 535 return new ResolvedModuleRevision() { 537 public boolean isSearched() { 538 return true; 539 } 540 541 public boolean isDownloaded() { 542 return rmr.isDownloaded(); 543 } 544 545 public ModuleDescriptor getDescriptor() { 546 return rmr.getDescriptor(); 547 } 548 549 public Date getPublicationDate() { 550 return rmr.getPublicationDate(); 551 } 552 553 public ModuleRevisionId getId() { 554 return rmr.getId(); 555 } 556 557 public DependencyResolver getResolver() { 558 return rmr.getResolver(); 559 } 560 561 public DependencyResolver getArtifactResolver() { 562 return rmr.getArtifactResolver(); 563 } 564 public URL getLocalMDUrl() { 565 return rmr.getLocalMDUrl(); 566 } 567 }; 568 } 569 570 protected void logIvyAttempt(String attempt) { 571 _ivyattempts.add(attempt); 572 Message.verbose("\t\ttried "+attempt); 573 } 574 575 protected void logArtifactAttempt(Artifact art, String attempt) { 576 List attempts = (List )_artattempts.get(art); 577 if (attempts == null) { 578 attempts = new ArrayList (); 579 _artattempts.put(art, attempts); 580 } 581 attempts.add(attempt); 582 Message.verbose("\t\ttried "+attempt); 583 } 584 585 public void reportFailure() { 586 for (ListIterator iter = _ivyattempts.listIterator(); iter.hasNext();) { 587 String m = (String )iter.next(); 588 Message.warn("\t\t"+getName()+": tried "+m); 589 } 590 for (Iterator iter = _artattempts.keySet().iterator(); iter.hasNext();) { 591 Artifact art = (Artifact)iter.next(); 592 List attempts = (List )_artattempts.get(art); 593 if (attempts != null) { 594 Message.warn("\t\t"+getName()+": tried artifact "+art+":"); 595 for (ListIterator iterator = attempts.listIterator(); iterator.hasNext();) { 596 String m = (String )iterator.next(); 597 Message.warn("\t\t\t"+m); 598 } 599 } 600 } 601 } 602 603 public void reportFailure(Artifact art) { 604 List attempts = (List )_artattempts.get(art); 605 if (attempts != null) { 606 for (ListIterator iter = attempts.listIterator(); iter.hasNext();) { 607 String m = (String )iter.next(); 608 Message.warn("\t\t"+getName()+": tried "+m); 609 } 610 } 611 } 612 613 protected boolean acceptLatest() { 614 return true; 615 } 616 617 public DownloadReport download(Artifact[] artifacts, Ivy ivy, File cache, boolean useOrigin) { 618 clearArtifactAttempts(); 619 DownloadReport dr = new DownloadReport(); 620 for (int i = 0; i < artifacts.length; i++) { 621 final ArtifactDownloadReport adr = new ArtifactDownloadReport(artifacts[i]); 622 dr.addArtifactReport(adr); 623 ivy.fireIvyEvent(new NeedArtifactEvent(ivy, this, artifacts[i])); 624 ArtifactOrigin origin = ivy.getSavedArtifactOrigin(cache, artifacts[i]); 625 File archiveFile = ivy.getArchiveFileInCache(cache, artifacts[i], origin, useOrigin); 629 630 if (archiveFile.exists()) { 631 Message.verbose("\t[NOT REQUIRED] "+artifacts[i]); 632 adr.setDownloadStatus(DownloadStatus.NO); 633 adr.setSize(archiveFile.length()); 634 adr.setArtifactOrigin(origin); 635 } else { 636 Artifact artifact = fromSystem(artifacts[i]); 637 if (!artifact.equals(artifacts[i])) { 638 Message.verbose("\t"+getName()+"looking for artifact "+artifact+ " (is "+artifacts[i]+" in system namespace)"); 639 } 640 long start = System.currentTimeMillis(); 641 try { 642 ResolvedResource artifactRef = getArtifactRef(artifact, null); 643 if (artifactRef != null) { 644 origin = new ArtifactOrigin(artifactRef.getResource().isLocal(), artifactRef.getResource().getName()); 645 if (useOrigin && artifactRef.getResource().isLocal()) { 646 Message.verbose("\t[NOT REQUIRED] "+artifacts[i]); 647 ivy.saveArtifactOrigin(cache, artifacts[i], origin); 648 archiveFile = ivy.getArchiveFileInCache(cache, artifacts[i], origin); 649 adr.setDownloadStatus(DownloadStatus.NO); 650 adr.setSize(archiveFile.length()); 651 adr.setArtifactOrigin(origin); 652 } else { 653 archiveFile = ivy.getArchiveFileInCache(cache, artifacts[i], origin, useOrigin); 655 if (ResourceHelper.equals(artifactRef.getResource(), 656 archiveFile)) { 657 Message.error("invalid configuration for resolver '"+getName()+"': pointing artifacts to ivy cache is forbidden !"); 658 return null; 659 } 660 Message.info("downloading "+artifactRef.getResource()+" ..."); 661 ivy.fireIvyEvent(new StartArtifactDownloadEvent(ivy, this, artifacts[i], origin)); 662 663 File tmp = ivy.getArchiveFileInCache(cache, 664 new DefaultArtifact( 665 artifacts[i].getModuleRevisionId(), 666 artifacts[i].getPublicationDate(), 667 artifacts[i].getName(), 668 artifacts[i].getType(), 669 artifacts[i].getExt()+".part", 670 artifacts[i].getExtraAttributes()), 671 origin, useOrigin); 672 673 if (artifactRef.getResource().getName().equals(String.valueOf(artifacts[i].getUrl()))) { 675 Message.verbose("\t"+getName()+": downloading "+artifactRef.getResource().getName()); 676 Message.debug("\t\tto "+tmp); 677 if (tmp.getParentFile() != null) { 678 tmp.getParentFile().mkdirs(); 679 } 680 _extartifactrep.get(artifactRef.getResource().getName(), tmp); 681 adr.setSize(tmp.length()); 682 } else { 683 adr.setSize(getAndCheck(artifactRef.getResource(), tmp)); 684 } 685 if (!tmp.renameTo(archiveFile)) { 686 Message.warn("\t[FAILED ] "+artifacts[i]+" impossible to move temp file to definitive one ("+(System.currentTimeMillis()-start)+"ms)"); 687 adr.setDownloadStatus(DownloadStatus.FAILED); 688 } else { 689 ivy.saveArtifactOrigin(cache, artifacts[i], origin); 690 Message.info("\t[SUCCESSFUL ] "+artifacts[i]+" ("+(System.currentTimeMillis()-start)+"ms)"); 691 adr.setDownloadStatus(DownloadStatus.SUCCESSFUL); 692 adr.setArtifactOrigin(origin); 693 } 694 } 695 } else { 696 logArtifactNotFound(artifacts[i]); 697 adr.setDownloadStatus(DownloadStatus.FAILED); 698 } 699 } catch (Exception ex) { 700 Message.warn("\t[FAILED ] "+artifacts[i]+" : "+ex.getMessage()+" ("+(System.currentTimeMillis()-start)+"ms)"); 701 adr.setDownloadStatus(DownloadStatus.FAILED); 702 } 703 checkInterrupted(); 704 } 705 ivy.fireIvyEvent(new EndArtifactDownloadEvent(ivy, this, artifacts[i], adr, archiveFile)); 706 } 707 return dr; 708 } 709 710 protected void clearArtifactAttempts() { 711 _artattempts.clear(); 712 } 713 714 public boolean exists(Artifact artifact) { 715 ResolvedResource artifactRef = getArtifactRef(artifact, null); 716 if (artifactRef != null) { 717 return artifactRef.getResource().exists(); 718 } 719 return false; 720 } 721 722 protected long getPublicationDate(ModuleDescriptor md, DependencyDescriptor dd, ResolveData data) { 723 if (md.getPublicationDate() != null) { 724 return md.getPublicationDate().getTime(); 725 } 726 ResolvedResource artifactRef = findFirstArtifactRef(md, dd, data); 727 if (artifactRef != null) { 728 return artifactRef.getLastModified(); 729 } 730 return -1; 731 } 732 733 public String toString() { 734 return getName(); 735 } 736 737 public String [] listTokenValues(String token, Map otherTokenValues) { 738 Collection ret = findNames(otherTokenValues, token); 739 return (String []) ret.toArray(new String [ret.size()]); 740 } 741 742 public OrganisationEntry[] listOrganisations() { 743 Collection names = findNames(Collections.EMPTY_MAP, IvyPatternHelper.ORGANISATION_KEY); 744 OrganisationEntry[] ret = new OrganisationEntry[names.size()]; 745 int i =0; 746 for (Iterator iter = names.iterator(); iter.hasNext(); i++) { 747 String org = (String )iter.next(); 748 ret[i] = new OrganisationEntry(this, org); 749 } 750 return ret; 751 } 752 753 public ModuleEntry[] listModules(OrganisationEntry org) { 754 Map tokenValues = new HashMap (); 755 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, org.getOrganisation()); 756 Collection names = findNames(tokenValues, IvyPatternHelper.MODULE_KEY); 757 ModuleEntry[] ret = new ModuleEntry[names.size()]; 758 int i =0; 759 for (Iterator iter = names.iterator(); iter.hasNext(); i++) { 760 String name = (String )iter.next(); 761 ret[i] = new ModuleEntry(org, name); 762 } 763 return ret; 764 } 765 766 public RevisionEntry[] listRevisions(ModuleEntry mod) { 767 Map tokenValues = new HashMap (); 768 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, mod.getOrganisation()); 769 tokenValues.put(IvyPatternHelper.MODULE_KEY, mod.getModule()); 770 Collection names = findNames(tokenValues, IvyPatternHelper.REVISION_KEY); 771 RevisionEntry[] ret = new RevisionEntry[names.size()]; 772 int i =0; 773 for (Iterator iter = names.iterator(); iter.hasNext(); i++) { 774 String name = (String )iter.next(); 775 ret[i] = new RevisionEntry(mod, name); 776 } 777 return ret; 778 } 779 780 protected abstract Collection findNames(Map tokenValues, String token); 781 782 protected abstract ResolvedResource findIvyFileRef(DependencyDescriptor dd, ResolveData data); 783 784 protected ResolvedResource findFirstArtifactRef(ModuleDescriptor md, DependencyDescriptor dd, ResolveData data) { 785 ResolvedResource ret = null; 786 String [] conf = md.getConfigurationsNames(); 787 for (int i = 0; i < conf.length; i++) { 788 Artifact[] artifacts = md.getArtifacts(conf[i]); 789 for (int j = 0; j < artifacts.length; j++) { 790 ret = getArtifactRef(artifacts[j], data.getDate()); 791 if (ret != null) { 792 return ret; 793 } 794 } 795 } 796 return null; 797 } 798 799 protected long getAndCheck(Resource resource, File dest) throws IOException { 800 long size = get(resource, dest); 801 String [] checksums = getChecksumAlgorithms(); 802 boolean checked = false; 803 for (int i = 0; i < checksums.length && !checked; i++) { 804 checked = check(resource, dest, checksums[i]); 805 } 806 return size; 807 } 808 809 private boolean check(Resource resource, File dest, String algorithm) throws IOException { 810 Resource csRes = resource.clone(resource.getName()+"."+algorithm); 811 if (csRes.exists()) { 812 Message.debug(algorithm + " file found for "+resource+": checking..."); 813 File csFile = File.createTempFile("ivytmp", algorithm); 814 try { 815 get(csRes, csFile); 816 if (!ChecksumHelper.check(dest, csFile, algorithm)) { 817 dest.delete(); 818 throw new IOException ("invalid "+algorithm); 819 } else { 820 Message.verbose(algorithm + " OK for "+resource); 821 return true; 822 } 823 } finally { 824 csFile.delete(); 825 } 826 } else { 827 return false; 828 } 829 } 830 831 832 protected ResolvedResource getArtifactRef(Artifact artifact, Date date) { 833 ResolvedResource ret = findArtifactRef(artifact, date); 834 if (ret == null && artifact.getUrl() != null) { 835 URL url = artifact.getUrl(); 836 Message.verbose("\tusing url for "+artifact+": "+url); 837 ret = new ResolvedResource(new URLResource(url), artifact.getModuleRevisionId().getRevision()); 838 } 839 return ret; 840 } 841 842 protected abstract ResolvedResource findArtifactRef(Artifact artifact, Date date); 843 844 protected abstract long get(Resource resource, File dest) throws IOException ; 845 846 protected abstract void logIvyNotFound(ModuleRevisionId mrid); 847 848 protected abstract void logArtifactNotFound(Artifact artifact); 849 850 public boolean isCheckconsistency() { 851 return _checkconsistency; 852 } 853 854 public void setCheckconsistency(boolean checkConsitency) { 855 _checkconsistency = checkConsitency; 856 } 857 858 public boolean isAllownomd() { 859 return _allownomd; 860 } 861 public void setAllownomd(boolean b) { 862 _allownomd = b; 863 } 864 865 public String [] getChecksumAlgorithms() { 866 String csDef = _checksums == null ? getIvy().getVariable("ivy.checksums") : _checksums; 867 if (csDef == null) { 868 return new String [0]; 869 } 870 String [] checksums = csDef.split(","); 873 List algos = new ArrayList (); 874 for (int i = 0; i < checksums.length; i++) { 875 String cs = checksums[i].trim(); 876 if (!"".equals(cs) && !"none".equals(cs)) { 877 algos.add(cs); 878 } 879 } 880 return (String []) algos.toArray(new String [algos.size()]); 881 } 882 883 public void setChecksums(String checksums) { 884 _checksums = checksums; 885 } 886 887 } 888 | Popular Tags |