1 6 package fr.jayasoft.ivy; 7 8 import java.io.File ; 9 import java.io.FileInputStream ; 10 import java.io.FileNotFoundException ; 11 import java.io.FileOutputStream ; 12 import java.io.IOException ; 13 import java.io.InputStream ; 14 import java.net.InetAddress ; 15 import java.net.MalformedURLException ; 16 import java.net.URL ; 17 import java.net.URLClassLoader ; 18 import java.net.UnknownHostException ; 19 import java.text.ParseException ; 20 import java.text.SimpleDateFormat ; 21 import java.util.ArrayList ; 22 import java.util.Arrays ; 23 import java.util.Collection ; 24 import java.util.Collections ; 25 import java.util.Comparator ; 26 import java.util.Date ; 27 import java.util.HashMap ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.LinkedHashMap ; 31 import java.util.LinkedHashSet ; 32 import java.util.List ; 33 import java.util.ListIterator ; 34 import java.util.Map ; 35 import java.util.Properties ; 36 import java.util.Set ; 37 import java.util.StringTokenizer ; 38 39 import javax.swing.event.EventListenerList ; 40 41 import org.xml.sax.SAXException ; 42 43 import fr.jayasoft.ivy.IvyNode.EvictionData; 44 import fr.jayasoft.ivy.circular.CircularDependencyStrategy; 45 import fr.jayasoft.ivy.circular.ErrorCircularDependencyStrategy; 46 import fr.jayasoft.ivy.circular.IgnoreCircularDependencyStrategy; 47 import fr.jayasoft.ivy.circular.WarnCircularDependencyStrategy; 48 import fr.jayasoft.ivy.conflict.LatestConflictManager; 49 import fr.jayasoft.ivy.conflict.NoConflictManager; 50 import fr.jayasoft.ivy.conflict.StrictConflictManager; 51 import fr.jayasoft.ivy.event.FilteredIvyListener; 52 import fr.jayasoft.ivy.event.IvyEvent; 53 import fr.jayasoft.ivy.event.IvyEventFilter; 54 import fr.jayasoft.ivy.event.IvyListener; 55 import fr.jayasoft.ivy.event.Trigger; 56 import fr.jayasoft.ivy.event.download.PrepareDownloadEvent; 57 import fr.jayasoft.ivy.event.resolve.EndResolveEvent; 58 import fr.jayasoft.ivy.event.resolve.StartResolveEvent; 59 import fr.jayasoft.ivy.filter.Filter; 60 import fr.jayasoft.ivy.filter.FilterHelper; 61 import fr.jayasoft.ivy.latest.LatestLexicographicStrategy; 62 import fr.jayasoft.ivy.latest.LatestRevisionStrategy; 63 import fr.jayasoft.ivy.latest.LatestTimeStrategy; 64 import fr.jayasoft.ivy.matcher.ExactOrRegexpPatternMatcher; 65 import fr.jayasoft.ivy.matcher.ExactPatternMatcher; 66 import fr.jayasoft.ivy.matcher.GlobPatternMatcher; 67 import fr.jayasoft.ivy.matcher.Matcher; 68 import fr.jayasoft.ivy.matcher.MatcherHelper; 69 import fr.jayasoft.ivy.matcher.ModuleIdMatcher; 70 import fr.jayasoft.ivy.matcher.PatternMatcher; 71 import fr.jayasoft.ivy.matcher.RegexpPatternMatcher; 72 import fr.jayasoft.ivy.namespace.NameSpaceHelper; 73 import fr.jayasoft.ivy.namespace.Namespace; 74 import fr.jayasoft.ivy.parser.ModuleDescriptorParser; 75 import fr.jayasoft.ivy.parser.ModuleDescriptorParserRegistry; 76 import fr.jayasoft.ivy.report.ArtifactDownloadReport; 77 import fr.jayasoft.ivy.report.ConfigurationResolveReport; 78 import fr.jayasoft.ivy.report.DownloadReport; 79 import fr.jayasoft.ivy.report.DownloadStatus; 80 import fr.jayasoft.ivy.report.LogReportOutputter; 81 import fr.jayasoft.ivy.report.ReportOutputter; 82 import fr.jayasoft.ivy.report.ResolveReport; 83 import fr.jayasoft.ivy.report.XmlReportOutputter; 84 import fr.jayasoft.ivy.repository.TransferEvent; 85 import fr.jayasoft.ivy.repository.TransferListener; 86 import fr.jayasoft.ivy.repository.url.URLResource; 87 import fr.jayasoft.ivy.resolver.AbstractResolver; 88 import fr.jayasoft.ivy.resolver.CacheResolver; 89 import fr.jayasoft.ivy.resolver.ChainResolver; 90 import fr.jayasoft.ivy.resolver.DualResolver; 91 import fr.jayasoft.ivy.resolver.ModuleEntry; 92 import fr.jayasoft.ivy.resolver.OrganisationEntry; 93 import fr.jayasoft.ivy.resolver.RevisionEntry; 94 import fr.jayasoft.ivy.status.StatusManager; 95 import fr.jayasoft.ivy.url.URLHandlerRegistry; 96 import fr.jayasoft.ivy.util.FileUtil; 97 import fr.jayasoft.ivy.util.IvyPatternHelper; 98 import fr.jayasoft.ivy.util.Message; 99 import fr.jayasoft.ivy.util.PropertiesFile; 100 import fr.jayasoft.ivy.version.ChainVersionMatcher; 101 import fr.jayasoft.ivy.version.ExactVersionMatcher; 102 import fr.jayasoft.ivy.version.LatestVersionMatcher; 103 import fr.jayasoft.ivy.version.SubVersionMatcher; 104 import fr.jayasoft.ivy.version.VersionMatcher; 105 import fr.jayasoft.ivy.version.VersionRangeMatcher; 106 import fr.jayasoft.ivy.xml.XmlIvyConfigurationParser; 107 import fr.jayasoft.ivy.xml.XmlModuleDescriptorParser; 108 import fr.jayasoft.ivy.xml.XmlModuleDescriptorUpdater; 109 import fr.jayasoft.ivy.xml.XmlReportParser; 110 111 124 public class Ivy implements TransferListener { 125 126 public static Ivy getCurrent() { 127 Ivy cur = IvyContext.getContext().getIvy(); 128 if (cur == null) { 129 cur = new Ivy(); 130 IvyContext.getContext().setIvy(cur); 131 } 132 return cur; 133 } 134 135 136 public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat ("yyyyMMddHHmmss"); 137 138 private static final String DEFAULT_CACHE_ARTIFACT_PATTERN = "[organisation]/[module]/[type]s/[artifact]-[revision](.[ext])"; 139 private static final String DEFAULT_CACHE_DATA_FILE_PATTERN = "[organisation]/[module]/ivydata-[revision].properties"; 140 private static final String DEFAULT_CACHE_IVY_PATTERN = "[organisation]/[module]/ivy-[revision].xml"; 141 private static final String DEFAULT_CACHE_RESOLVED_IVY_PATTERN = "resolved-[organisation]-[module]-[revision].xml"; 142 private static final String DEFAULT_CACHE_RESOLVED_IVY_PROPERTIES_PATTERN = "resolved-[organisation]-[module]-[revision].properties"; 143 144 private Map _typeDefs = new HashMap (); 145 private Map _resolversMap = new HashMap (); 146 private DependencyResolver _defaultResolver; 147 private DependencyResolver _dictatorResolver = null; 148 149 private String _defaultResolverName; 150 private File _defaultCache; 151 152 private String _defaultBranch = null; 153 154 private boolean _checkUpToDate = true; 155 private Map _moduleConfigurations = new LinkedHashMap (); 157 private Map _conflictsManager = new HashMap (); private Map _latestStrategies = new HashMap (); private Map _namespaces = new HashMap (); private Map _matchers = new HashMap (); private Map _reportOutputters = new HashMap (); private Map _versionMatchers = new HashMap (); private Map _circularDependencyStrategies = new HashMap (); 165 private Map _variables = new HashMap (); 166 167 private String _cacheIvyPattern = DEFAULT_CACHE_IVY_PATTERN; 168 private String _cacheResolvedIvyPattern = DEFAULT_CACHE_RESOLVED_IVY_PATTERN; 169 private String _cacheResolvedIvyPropertiesPattern = DEFAULT_CACHE_RESOLVED_IVY_PROPERTIES_PATTERN; 170 private String _cacheArtifactPattern = DEFAULT_CACHE_ARTIFACT_PATTERN; 171 private String _cacheDataFilePattern = DEFAULT_CACHE_DATA_FILE_PATTERN; 172 173 private boolean _validate = true; 174 175 private LatestStrategy _defaultLatestStrategy = null; 176 private ConflictManager _defaultConflictManager = null; 177 private CircularDependencyStrategy _circularDependencyStrategy = null; 178 179 private List _listingIgnore = new ArrayList (); 180 181 private boolean _repositoriesConfigured; 182 183 private boolean _useRemoteConfig = false; 184 185 private File _defaultUserDir; 186 187 private Set _fetchedSet = new HashSet (); 188 189 private List _classpathURLs = new ArrayList (); 190 191 private ClassLoader _classloader; 192 193 private StatusManager _statusManager; 194 195 private long _interruptTimeout = 2000; 196 197 private boolean _interrupted; 198 199 public Ivy() { 200 setVariable("ivy.default.conf.dir", Ivy.class.getResource("conf").toExternalForm(), true); 201 202 String ivyTypeDefs = System.getProperty("ivy.typedef.files"); 203 if (ivyTypeDefs != null) { 204 String [] files = ivyTypeDefs.split("\\,"); 205 for (int i = 0; i < files.length; i++) { 206 try { 207 typeDefs(new FileInputStream (new File (files[i].trim())), true); 208 } catch (FileNotFoundException e) { 209 Message.warn("typedefs file not found: "+files[i].trim()); 210 } catch (IOException e) { 211 Message.warn("problem with typedef file: "+files[i].trim()+": "+e.getMessage()); 212 } 213 } 214 } else { 215 try { 216 typeDefs(Ivy.class.getResourceAsStream("typedef.properties"), true); 217 } catch (IOException e) { 218 Message.warn("impossible to load default type defs"); 219 } 220 } 221 LatestLexicographicStrategy latestLexicographicStrategy = new LatestLexicographicStrategy(); 222 LatestRevisionStrategy latestRevisionStrategy = new LatestRevisionStrategy(); 223 LatestTimeStrategy latestTimeStrategy = new LatestTimeStrategy(); 224 225 addLatestStrategy("latest-revision", latestRevisionStrategy); 226 addLatestStrategy("latest-lexico", latestLexicographicStrategy); 227 addLatestStrategy("latest-time", latestTimeStrategy); 228 229 addConflictManager("latest-revision", new LatestConflictManager("latest-revision", latestRevisionStrategy)); 230 addConflictManager("latest-time", new LatestConflictManager("latest-time", latestTimeStrategy)); 231 addConflictManager("all", new NoConflictManager()); 232 addConflictManager("strict", new StrictConflictManager()); 233 234 addMatcher(ExactPatternMatcher.getInstance()); 235 addMatcher(RegexpPatternMatcher.getInstance()); 236 addMatcher(ExactOrRegexpPatternMatcher.getInstance()); 237 addMatcher(GlobPatternMatcher.getInstance()); 238 239 addReportOutputter(new XmlReportOutputter()); 240 addReportOutputter(new LogReportOutputter()); 241 242 configureDefaultCircularDependencyStrategies(); 243 244 _listingIgnore.add(".cvsignore"); 245 _listingIgnore.add("CVS"); 246 _listingIgnore.add(".svn"); 247 248 addSystemProperties(); 249 250 addTransferListener(new TransferListener() { 251 public void transferProgress(TransferEvent evt) { 252 switch (evt.getEventType()) { 253 case TransferEvent.TRANSFER_PROGRESS: 254 Message.progress(); 255 break; 256 case TransferEvent.TRANSFER_COMPLETED: 257 Message.endProgress(" ("+(evt.getTotalLength() / 1024)+"kB)"); 258 break; 259 default: 260 break; 261 } 262 } 263 }); 264 IvyContext.getContext().setIvy(this); 265 } 266 267 private void addSystemProperties() { 268 addAllVariables(System.getProperties()); 269 } 270 271 274 public void configureRepositories(boolean remote) { 275 IvyContext.getContext().setIvy(this); 276 if (!_repositoriesConfigured) { 277 Properties props = new Properties (); 278 boolean configured = false; 279 if (_useRemoteConfig && remote) { 280 try { 281 URL url = new URL ("http://www.jayasoft.org/ivy/repository.properties"); 282 Message.verbose("configuring repositories with "+url); 283 props.load(URLHandlerRegistry.getDefault().openStream(url)); 284 configured = true; 285 } catch (Exception ex) { 286 Message.verbose("unable to use remote repository configuration: "+ex.getMessage()); 287 props = new Properties (); 288 } 289 } 290 if (!configured) { 291 try { 292 props.load(Ivy.class.getResourceAsStream("repository.properties")); 293 } catch (IOException e) { 294 Message.error("unable to use internal repository configuration: "+e.getMessage()); 295 } 296 } 297 addAllVariables(props, false); 298 _repositoriesConfigured = true; 299 } 300 } 301 302 303 public void typeDefs(InputStream stream) throws IOException { 304 typeDefs(stream, false); 305 } 306 public void typeDefs(InputStream stream, boolean silentFail) throws IOException { 307 IvyContext.getContext().setIvy(this); 308 try { 309 Properties p = new Properties (); 310 p.load(stream); 311 typeDefs(p, silentFail); 312 } finally { 313 stream.close(); 314 } 315 } 316 317 public void typeDefs(Properties p) { 318 typeDefs(p, false); 319 } 320 public void typeDefs(Properties p, boolean silentFail) { 321 IvyContext.getContext().setIvy(this); 322 for (Iterator iter = p.keySet().iterator(); iter.hasNext();) { 323 String name = (String ) iter.next(); 324 typeDef(name, p.getProperty(name), silentFail); 325 } 326 } 327 328 329 public void configure(File configurationFile) throws ParseException , IOException { 333 IvyContext.getContext().setIvy(this); 334 Message.info(":: configuring :: file = "+configurationFile); 335 long start = System.currentTimeMillis(); 336 setConfigurationVariables(configurationFile); 337 if (getVariable("ivy.default.ivy.user.dir") != null) { 338 setDefaultIvyUserDir(new File (getVariable("ivy.default.ivy.user.dir"))); 339 } else { 340 getDefaultIvyUserDir(); 341 } 342 getDefaultCache(); 343 344 loadDefaultProperties(); 345 try { 346 new XmlIvyConfigurationParser(this).parse(configurationFile.toURL()); 347 } catch (MalformedURLException e) { 348 IllegalArgumentException iae = new IllegalArgumentException ("given file cannot be transformed to url: "+configurationFile); 349 iae.initCause(e); 350 throw iae; 351 } 352 setVariable("ivy.default.ivy.user.dir", getDefaultIvyUserDir().getAbsolutePath(), false); 353 Message.verbose("configuration done ("+(System.currentTimeMillis()-start)+"ms)"); 354 dumpConfig(); 355 } 356 357 public void configure(URL configurationURL) throws ParseException , IOException { 358 IvyContext.getContext().setIvy(this); 359 Message.info(":: configuring :: url = "+configurationURL); 360 long start = System.currentTimeMillis(); 361 setConfigurationVariables(configurationURL); 362 if (getVariable("ivy.default.ivy.user.dir") != null) { 363 setDefaultIvyUserDir(new File (getVariable("ivy.default.ivy.user.dir"))); 364 } else { 365 getDefaultIvyUserDir(); 366 } 367 getDefaultCache(); 368 369 loadDefaultProperties(); 370 new XmlIvyConfigurationParser(this).parse(configurationURL); 371 setVariable("ivy.default.ivy.user.dir", getDefaultIvyUserDir().getAbsolutePath(), false); 372 Message.verbose("configuration done ("+(System.currentTimeMillis()-start)+"ms)"); 373 dumpConfig(); 374 } 375 376 private void loadDefaultProperties() throws IOException { 377 loadProperties(Ivy.class.getResource("ivy.properties"), false); 378 } 379 380 public void configureDefault() throws ParseException , IOException { 381 configure(getDefaultConfigurationURL()); 382 } 383 384 public void setConfigurationVariables(File configurationFile) { 385 IvyContext.getContext().setIvy(this); 386 try { 387 setVariable("ivy.conf.dir", new File (configurationFile.getAbsolutePath()).getParent()); 388 setVariable("ivy.conf.file", configurationFile.getAbsolutePath()); 389 setVariable("ivy.conf.url", configurationFile.toURL().toExternalForm()); 390 } catch (MalformedURLException e) { 391 IllegalArgumentException iae = new IllegalArgumentException ("given file cannot be transformed to url: "+configurationFile); 392 iae.initCause(e); 393 throw iae; 394 } 395 } 396 397 public void setConfigurationVariables(URL configurationURL) { 398 IvyContext.getContext().setIvy(this); 399 String confURL = configurationURL.toExternalForm(); 400 setVariable("ivy.conf.url", confURL); 401 int slashIndex = confURL.lastIndexOf('/'); 402 if (slashIndex != -1) { 403 setVariable("ivy.conf.dir", confURL.substring(0, slashIndex)); 404 } else { 405 Message.warn("configuration url does not contain any slash (/): ivy.conf.dir variable not set"); 406 } 407 } 408 409 private void dumpConfig() { 410 Message.verbose("\tdefault cache: "+getDefaultCache()); 411 Message.verbose("\tdefault resolver: "+getDefaultResolver()); 412 Message.debug("\tdefault latest strategy: "+getDefaultLatestStrategy()); 413 Message.debug("\tdefault conflict manager: "+getDefaultConflictManager()); 414 Message.debug("\tcircular dependency strategy: "+getCircularDependencyStrategy()); 415 Message.debug("\tvalidate: "+doValidate()); 416 Message.debug("\tcheck up2date: "+isCheckUpToDate()); 417 Message.debug("\tcache ivy pattern: "+getCacheIvyPattern()); 418 Message.debug("\tcache artifact pattern: "+getCacheArtifactPattern()); 419 420 if (!_classpathURLs.isEmpty()) { 421 Message.verbose("\t-- "+_classpathURLs.size()+" custom classpath urls:"); 422 for (Iterator iter = _classpathURLs.iterator(); iter.hasNext();) { 423 Message.debug("\t\t"+iter.next()); 424 } 425 } 426 Message.verbose("\t-- "+_resolversMap.size()+" resolvers:"); 427 for (Iterator iter = _resolversMap.values().iterator(); iter.hasNext();) { 428 DependencyResolver resolver = (DependencyResolver)iter.next(); 429 resolver.dumpConfig(); 430 } 431 if (!_moduleConfigurations.isEmpty()) { 432 Message.debug("\tmodule configurations:"); 433 for (Iterator iter = _moduleConfigurations.keySet().iterator(); iter.hasNext();) { 434 ModuleIdMatcher midm = (ModuleIdMatcher)iter.next(); 435 ModuleSettings s = (ModuleSettings)_moduleConfigurations.get(midm); 436 Message.debug("\t\t"+midm+" -> "+s); 437 } 438 } 439 } 440 441 public void loadProperties(URL url) throws IOException { 442 loadProperties(url, true); 443 } 444 public void loadProperties(URL url, boolean overwrite) throws IOException { 445 loadProperties(url.openStream(), overwrite); 446 } 447 public void loadProperties(File file) throws IOException { 448 loadProperties(file, true); 449 } 450 451 public void loadProperties(File file, boolean overwrite) throws IOException { 452 loadProperties(new FileInputStream (file), overwrite); 453 } 454 455 private void loadProperties(InputStream stream, boolean overwrite) throws IOException { 456 try { 457 Properties properties = new Properties (); 458 properties.load(stream); 459 addAllVariables(properties, overwrite); 460 } finally { 461 if (stream != null) { 462 try { 463 stream.close(); 464 } catch (IOException e) {} 465 } 466 } 467 } 468 469 public void setVariable(String varName, String value) { 470 setVariable(varName, value, true); 471 } 472 473 public void setVariable(String varName, String value, boolean overwrite) { 474 if (overwrite || !_variables.containsKey(varName)) { 475 Message.debug("setting '"+varName+"' to '"+value+"'"); 476 _variables.put(varName, substitute(value)); 477 } else { 478 Message.debug("'"+varName+"' already set: discarding '"+value+"'"); 479 } 480 } 481 482 public void addAllVariables(Map variables) { 483 addAllVariables(variables, true); 484 } 485 486 public void addAllVariables(Map variables, boolean overwrite) { 487 for (Iterator iter = variables.keySet().iterator(); iter.hasNext();) { 488 String key = (String )iter.next(); 489 String val = (String )variables.get(key); 490 setVariable(key, val, overwrite); 491 } 492 } 493 494 501 public String substitute(String str) { 502 return IvyPatternHelper.substituteVariables(str, getVariables()); 503 } 504 505 511 public Map getVariables() { 512 return _variables; 513 } 514 515 public Class typeDef(String name, String className) { 516 return typeDef(name, className, false); 517 } 518 519 public Class typeDef(String name, String className, boolean silentFail) { 520 Class clazz = classForName(className, silentFail); 521 if (clazz != null) { 522 _typeDefs.put(name, clazz); 523 } 524 return clazz; 525 } 526 527 private Class classForName(String className, boolean silentFail) { 528 try { 529 return getClassLoader().loadClass(className); 530 } catch (ClassNotFoundException e) { 531 if (silentFail) { 532 Message.info("impossible to define new type: class not found: "+className+" in "+_classpathURLs+" nor Ivy classloader"); 533 return null; 534 } else { 535 throw new RuntimeException ("impossible to define new type: class not found: "+className+" in "+_classpathURLs+" nor Ivy classloader"); 536 } 537 } 538 } 539 540 private ClassLoader getClassLoader() { 541 if (_classloader == null) { 542 if (_classpathURLs.isEmpty()) { 543 _classloader = Ivy.class.getClassLoader(); 544 } else { 545 _classloader = new URLClassLoader ( 546 (URL [])_classpathURLs.toArray(new URL [_classpathURLs.size()]), 547 Ivy.class.getClassLoader()); 548 } 549 } 550 return _classloader; 551 } 552 553 554 public void addClasspathURL(URL url) { 555 _classpathURLs.add(url); 556 _classloader = null; 557 } 558 559 public Map getTypeDefs() { 560 return _typeDefs; 561 } 562 563 public Class getTypeDef(String name) { 564 return (Class )_typeDefs.get(name); 565 } 566 567 public void addConfigured(DependencyResolver resolver) { 569 addResolver(resolver); 570 } 571 572 public void addConfigured(ModuleDescriptorParser parser) { 573 ModuleDescriptorParserRegistry.getInstance().addParser(parser); 574 } 575 576 public void addResolver(DependencyResolver resolver) { 577 if (resolver == null) { 578 throw new NullPointerException ("null resolver"); 579 } 580 if (resolver instanceof IvyAware) { 581 ((IvyAware)resolver).setIvy(this); 582 } 583 _resolversMap.put(resolver.getName(), resolver); 584 if (resolver instanceof ChainResolver) { 585 List subresolvers = ((ChainResolver)resolver).getResolvers(); 586 for (Iterator iter = subresolvers.iterator(); iter.hasNext();) { 587 DependencyResolver dr = (DependencyResolver)iter.next(); 588 addResolver(dr); 589 } 590 } else if (resolver instanceof DualResolver) { 591 DependencyResolver ivyResolver = ((DualResolver)resolver).getIvyResolver(); 592 if (ivyResolver != null) { 593 addResolver(ivyResolver); 594 } 595 DependencyResolver artifactResolver = ((DualResolver)resolver).getArtifactResolver(); 596 if (artifactResolver != null) { 597 addResolver(artifactResolver); 598 } 599 } 600 } 601 602 public void setDefaultCache(File cacheDirectory) { 603 _defaultCache = cacheDirectory; 604 } 605 606 public void setDefaultResolver(String resolverName) { 607 checkResolverName(resolverName); 608 _defaultResolverName = resolverName; 609 } 610 611 private void checkResolverName(String resolverName) { 612 if (resolverName != null && !_resolversMap.containsKey(resolverName)) { 613 throw new IllegalArgumentException ("no resolver found called "+resolverName+": check your configuration"); 614 } 615 } 616 617 625 public void addModuleConfiguration(ModuleId mid, PatternMatcher matcher, String resolverName, String branch, String conflictManager) { 626 checkResolverName(resolverName); 627 _moduleConfigurations.put(new ModuleIdMatcher(mid, matcher), new ModuleSettings(resolverName, branch, conflictManager)); 628 } 629 630 public File getDefaultIvyUserDir() { 631 if (_defaultUserDir==null) { 632 if (getVariable("ivy.home") != null) { 633 setDefaultIvyUserDir(new File (getVariable("ivy.home"))); 634 Message.verbose("using ivy.default.ivy.user.dir variable for default ivy user dir: "+_defaultUserDir); 635 } else { 636 setDefaultIvyUserDir(new File (System.getProperty("user.home"), ".ivy")); 637 Message.verbose("no default ivy user dir defined: set to "+_defaultUserDir); 638 } 639 } 640 return _defaultUserDir; 641 } 642 643 public void setDefaultIvyUserDir(File defaultUserDir) { 644 _defaultUserDir = defaultUserDir; 645 setVariable("ivy.default.ivy.user.dir", _defaultUserDir.getAbsolutePath()); 646 setVariable("ivy.home", _defaultUserDir.getAbsolutePath()); 647 } 648 649 public File getDefaultCache() { 650 if (_defaultCache==null) { 651 _defaultCache = new File (getDefaultIvyUserDir(), "cache"); 652 Message.verbose("no default cache defined: set to "+_defaultCache); 653 } 654 return _defaultCache; 655 } 656 657 public DependencyResolver getResolver(ModuleId moduleId) { 658 if (_dictatorResolver != null) { 659 return _dictatorResolver; 660 } 661 String resolverName = getResolverName(moduleId); 662 return getResolver(resolverName); 663 } 664 665 public DependencyResolver getResolver(String resolverName) { 666 if (_dictatorResolver != null) { 667 return _dictatorResolver; 668 } 669 DependencyResolver resolver = (DependencyResolver)_resolversMap.get(resolverName); 670 if (resolver == null) { 671 Message.error("unknown resolver "+resolverName); 672 } 673 return resolver; 674 } 675 676 public DependencyResolver getDefaultResolver() { 677 if (_dictatorResolver != null) { 678 return _dictatorResolver; 679 } 680 if (_defaultResolver == null) { 681 _defaultResolver = (DependencyResolver)_resolversMap.get(_defaultResolverName); 682 } 683 return _defaultResolver; 684 } 685 686 public String getResolverName(ModuleId moduleId) { 687 for (Iterator iter = _moduleConfigurations.keySet().iterator(); iter.hasNext();) { 688 ModuleIdMatcher midm = (ModuleIdMatcher)iter.next(); 689 if (midm.matches(moduleId)) { 690 ModuleSettings ms = (ModuleSettings)_moduleConfigurations.get(midm); 691 if (ms.getResolverName() != null) { 692 return ms.getResolverName(); 693 } 694 } 695 } 696 return _defaultResolverName; 697 } 698 699 public String getDefaultBranch(ModuleId moduleId) { 700 for (Iterator iter = _moduleConfigurations.keySet().iterator(); iter.hasNext();) { 701 ModuleIdMatcher midm = (ModuleIdMatcher)iter.next(); 702 if (midm.matches(moduleId)) { 703 ModuleSettings ms = (ModuleSettings)_moduleConfigurations.get(midm); 704 if (ms.getBranch() != null) { 705 return ms.getBranch(); 706 } 707 } 708 } 709 return getDefaultBranch(); 710 } 711 712 public String getDefaultBranch() { 713 return _defaultBranch; 714 } 715 public void setDefaultBranch(String defaultBranch) { 716 _defaultBranch = defaultBranch; 717 } 718 719 public ConflictManager getConflictManager(ModuleId moduleId) { 720 for (Iterator iter = _moduleConfigurations.keySet().iterator(); iter.hasNext();) { 721 ModuleIdMatcher midm = (ModuleIdMatcher)iter.next(); 722 if (midm.matches(moduleId)) { 723 ModuleSettings ms = (ModuleSettings)_moduleConfigurations.get(midm); 724 if (ms.getConflictManager() != null) { 725 ConflictManager cm = getConflictManager(ms.getConflictManager()); 726 if (cm == null) { 727 throw new IllegalStateException ("ivy badly configured: unknown conflict manager "+ms.getConflictManager()); 728 } 729 return cm; 730 } 731 } 732 } 733 return getDefaultConflictManager(); 734 } 735 736 public void addConfigured(ConflictManager cm) { 737 addConflictManager(cm.getName(), cm); 738 } 739 740 public ConflictManager getConflictManager(String name) { 741 if ("default".equals(name)) { 742 return getDefaultConflictManager(); 743 } 744 return (ConflictManager)_conflictsManager.get(name); 745 } 746 public void addConflictManager(String name, ConflictManager cm) { 747 if (cm instanceof IvyAware) { 748 ((IvyAware)cm).setIvy(this); 749 } 750 _conflictsManager.put(name, cm); 751 } 752 753 public void addConfigured(LatestStrategy latest) { 754 addLatestStrategy(latest.getName(), latest); 755 } 756 757 public LatestStrategy getLatestStrategy(String name) { 758 if ("default".equals(name)) { 759 return getDefaultLatestStrategy(); 760 } 761 return (LatestStrategy)_latestStrategies.get(name); 762 } 763 public void addLatestStrategy(String name, LatestStrategy latest) { 764 if (latest instanceof IvyAware) { 765 ((IvyAware)latest).setIvy(this); 766 } 767 _latestStrategies.put(name, latest); 768 } 769 770 public void addConfigured(Namespace ns) { 771 addNamespace(ns); 772 } 773 774 public Namespace getNamespace(String name) { 775 if ("system".equals(name)) { 776 return getSystemNamespace(); 777 } 778 return (Namespace)_namespaces.get(name); 779 } 780 781 public Namespace getSystemNamespace() { 782 return Namespace.SYSTEM_NAMESPACE; 783 } 784 785 public void addNamespace(Namespace ns) { 786 if (ns instanceof IvyAware) { 787 ((IvyAware)ns).setIvy(this); 788 } 789 _namespaces.put(ns.getName(), ns); 790 } 791 792 public void addConfigured(PatternMatcher m) { 793 addMatcher(m); 794 } 795 796 public PatternMatcher getMatcher(String name) { 797 return (PatternMatcher)_matchers.get(name); 798 } 799 800 public void addMatcher(PatternMatcher m) { 801 if (m instanceof IvyAware) { 802 ((IvyAware)m).setIvy(this); 803 } 804 _matchers.put(m.getName(), m); 805 } 806 807 public void addConfigured(ReportOutputter outputter) { 808 addReportOutputter(outputter); 809 } 810 811 public ReportOutputter getReportOutputter(String name) { 812 return (ReportOutputter) _reportOutputters.get(name); 813 } 814 815 public void addReportOutputter(ReportOutputter outputter) { 816 if (outputter instanceof IvyAware) { 817 ((IvyAware) outputter).setIvy(this); 818 } 819 _reportOutputters.put(outputter.getName(), outputter); 820 } 821 822 public ReportOutputter[] getReportOutputters() { 823 return (ReportOutputter[]) _reportOutputters.values().toArray(new ReportOutputter[_reportOutputters.size()]); 824 } 825 826 public void addConfigured(VersionMatcher vmatcher) { 827 addVersionMatcher(vmatcher); 828 } 829 830 public VersionMatcher getVersionMatcher(String name) { 831 return (VersionMatcher) _versionMatchers.get(name); 832 } 833 834 public void addVersionMatcher(VersionMatcher vmatcher) { 835 if (vmatcher instanceof IvyAware) { 836 ((IvyAware) vmatcher).setIvy(this); 837 } 838 _versionMatchers.put(vmatcher.getName(), vmatcher); 839 840 if (_versionMatcher == null) { 841 _versionMatcher = new ChainVersionMatcher(); 842 addVersionMatcher(new ExactVersionMatcher()); 843 } 844 if (_versionMatcher instanceof ChainVersionMatcher) { 845 ChainVersionMatcher chain = (ChainVersionMatcher) _versionMatcher; 846 chain.add(vmatcher); 847 } 848 } 849 850 public VersionMatcher[] getVersionMatchers() { 851 return (VersionMatcher[]) _versionMatchers.values().toArray(new VersionMatcher[_versionMatchers.size()]); 852 } 853 854 public VersionMatcher getVersionMatcher() { 855 if (_versionMatcher == null) { 856 configureDefaultVersionMatcher(); 857 } 858 return _versionMatcher; 859 } 860 861 public void configureDefaultVersionMatcher() { 862 addVersionMatcher(new LatestVersionMatcher()); 863 addVersionMatcher(new SubVersionMatcher()); 864 addVersionMatcher(new VersionRangeMatcher()); 865 } 866 867 868 public CircularDependencyStrategy getCircularDependencyStrategy() { 869 if (_circularDependencyStrategy == null) { 870 _circularDependencyStrategy = getCircularDependencyStrategy("default"); 871 } 872 return _circularDependencyStrategy; 873 } 874 875 public CircularDependencyStrategy getCircularDependencyStrategy(String name) { 876 if ("default".equals(name)) { 877 name = "warn"; 878 } 879 return (CircularDependencyStrategy)_circularDependencyStrategies.get(name); 880 } 881 882 public void setCircularDependencyStrategy(CircularDependencyStrategy strategy) { 883 _circularDependencyStrategy = strategy; 884 } 885 886 public void addConfigured(CircularDependencyStrategy strategy) { 887 addCircularDependencyStrategy(strategy); 888 } 889 890 private void addCircularDependencyStrategy(CircularDependencyStrategy strategy) { 891 _circularDependencyStrategies.put(strategy.getName(), strategy); 892 } 893 894 private void configureDefaultCircularDependencyStrategies() { 895 addCircularDependencyStrategy(WarnCircularDependencyStrategy.getInstance()); 896 addCircularDependencyStrategy(ErrorCircularDependencyStrategy.getInstance()); 897 addCircularDependencyStrategy(IgnoreCircularDependencyStrategy.getInstance()); 898 } 899 900 910 public boolean check(URL ivyFile, String resolvername) { 911 try { 912 IvyContext.getContext().setIvy(this); 913 boolean result = true; 914 ModuleDescriptor md = ModuleDescriptorParserRegistry.getInstance().parseDescriptor(this, ivyFile, doValidate()); 916 917 if (resolvername != null) { 919 DependencyResolver resolver = getResolver(resolvername); 920 String [] confs = md.getConfigurationsNames(); 921 Set artifacts = new HashSet (); 922 for (int i = 0; i < confs.length; i++) { 923 artifacts.addAll(Arrays.asList(md.getArtifacts(confs[i]))); 924 } 925 for (Iterator iter = artifacts.iterator(); iter.hasNext();) { 926 Artifact art = (Artifact)iter.next(); 927 if (!resolver.exists(art)) { 928 Message.info("declared publication not found: "+art); 929 result = false; 930 } 931 } 932 } 933 934 DependencyDescriptor[] dds = md.getDependencies(); 936 ResolveData data = new ResolveData(this, getDefaultCache(), new Date (), null, true); 937 for (int i = 0; i < dds.length; i++) { 938 String [] masterConfs = dds[i].getModuleConfigurations(); 940 for (int j = 0; j < masterConfs.length; j++) { 941 if (!"*".equals(masterConfs[j].trim()) && md.getConfiguration(masterConfs[j]) == null) { 942 Message.info("dependency required in non existing conf for "+ivyFile+" \n\tin "+dds[i].getDependencyRevisionId()+": "+masterConfs[j]); 943 result = false; 944 } 945 } 946 DependencyResolver resolver = getResolver(dds[i].getDependencyId()); 948 ResolvedModuleRevision rmr = resolver.getDependency(dds[i], data); 949 if (rmr == null) { 950 Message.info("dependency not found in "+ivyFile+":\n\t"+dds[i]); 951 result = false; 952 } else { 953 String [] depConfs = dds[i].getDependencyConfigurations(md.getConfigurationsNames()); 954 for (int j = 0; j < depConfs.length; j++) { 955 if (!Arrays.asList(rmr.getDescriptor().getConfigurationsNames()).contains(depConfs[j])) { 956 Message.info("dependency configuration is missing for "+ivyFile+"\n\tin "+dds[i].getDependencyRevisionId()+": "+depConfs[j]); 957 result = false; 958 } 959 Artifact[] arts = rmr.getDescriptor().getArtifacts(depConfs[j]); 960 for (int k = 0; k < arts.length; k++) { 961 if (!resolver.exists(arts[k])) { 962 Message.info("dependency artifact is missing for "+ivyFile+"\n\t in "+dds[i].getDependencyRevisionId()+": "+arts[k]); 963 result = false; 964 } 965 } 966 } 967 } 968 } 969 return result; 970 } catch (ParseException e) { 971 Message.info("parse problem on "+ivyFile+": "+e); 972 return false; 973 } catch (IOException e) { 974 Message.info("io problem on "+ivyFile+": "+e); 975 return false; 976 } catch (Exception e) { 977 Message.info("problem on "+ivyFile+": "+e); 978 return false; 979 } 980 } 981 982 983 public ResolvedModuleRevision findModule(ModuleRevisionId id) { 984 DependencyResolver r = getResolver(id.getModuleId()); 985 if (r == null) { 986 throw new IllegalStateException ("no resolver found for "+id.getModuleId()); 987 } 988 DefaultModuleDescriptor md = DefaultModuleDescriptor.newCallerInstance(id, new String [] {"*"}, false, false); 989 try { 990 return r.getDependency(new DefaultDependencyDescriptor(id, true), new ResolveData(this, getDefaultCache(), null, new ConfigurationResolveReport(this, md, "default", null, getDefaultCache()), false)); 991 } catch (ParseException e) { 992 throw new RuntimeException ("problem whle parsing repository module descriptor for "+id+": "+e, e); 993 } 994 } 995 996 1000 1001 public ResolveReport resolve(File ivySource) throws ParseException , IOException { 1002 return resolve(ivySource.toURL()); 1003 } 1004 public ResolveReport resolve(URL ivySource) throws ParseException , IOException { 1005 return resolve(ivySource, null, new String [] {"*"}, null, null, true); 1006 } 1007 1021 public ResolveReport resolve(URL ivySource, String revision, String [] confs, File cache, Date date, boolean validate) throws ParseException , IOException { 1022 return resolve(ivySource, revision, confs, cache, date, validate, false); 1023 } 1024 public ResolveReport resolve(URL ivySource, String revision, String [] confs, File cache, Date date, boolean validate, boolean useCacheOnly) throws ParseException , IOException { 1025 return resolve(ivySource, revision, confs, cache, date, validate, useCacheOnly, FilterHelper.NO_FILTER); 1026 } 1027 1028 1031 public ResolveReport resolve(ModuleRevisionId mrid, String [] confs) throws ParseException , IOException { 1032 return resolve(mrid, confs, true, false, null, null, true, false, FilterHelper.NO_FILTER); 1033 } 1034 1035 public ResolveReport resolve(final ModuleRevisionId mrid, String [] confs, boolean transitive, boolean changing, File cache, Date date, boolean validate, boolean useCacheOnly, Filter artifactFilter) throws ParseException , IOException { 1036 return resolve(mrid, confs, transitive, changing, cache, date, validate, useCacheOnly, false, artifactFilter); 1037 } 1038 1039 1042 public ResolveReport resolve(final ModuleRevisionId mrid, String [] confs, boolean transitive, boolean changing, File cache, Date date, boolean validate, boolean useCacheOnly, boolean useOrigin, Filter artifactFilter) throws ParseException , IOException { 1043 DefaultModuleDescriptor md; 1044 if (confs.length == 1 && confs[0].equals("*")) { 1045 ResolvedModuleRevision rmr = findModule(mrid); 1046 if (rmr == null) { 1047 md = DefaultModuleDescriptor.newCallerInstance(mrid, confs, transitive, changing); 1048 return new ResolveReport(md){ 1049 public boolean hasError() { 1050 return true; 1051 } 1052 public List getProblemMessages() { 1053 return Arrays.asList(new String [] {"module not found: "+mrid}); 1054 } 1055 }; 1056 } else { 1057 confs = rmr.getDescriptor().getConfigurationsNames(); 1058 md = DefaultModuleDescriptor.newCallerInstance(ModuleRevisionId.newInstance(mrid, rmr.getId().getRevision()), confs, transitive, changing); 1059 } 1060 } else { 1061 md = DefaultModuleDescriptor.newCallerInstance(mrid, confs, transitive, changing); 1062 } 1063 1064 return resolve(md, new String [] {"*"}, cache, date, validate, useCacheOnly, true, useOrigin, true, true, artifactFilter); 1065 } 1066 1067 public ResolveReport resolve(URL ivySource, String revision, String [] confs, File cache, Date date, boolean validate, boolean useCacheOnly, Filter artifactFilter) throws ParseException , IOException { 1068 return resolve(ivySource, revision, confs, cache, date, validate, useCacheOnly, true, artifactFilter); 1069 } 1070 public ResolveReport resolve(URL ivySource, String revision, String [] confs, File cache, Date date, boolean validate, boolean useCacheOnly, boolean transitive, Filter artifactFilter) throws ParseException , IOException { 1071 return resolve(ivySource, revision, confs, cache, date, validate, useCacheOnly, transitive, false, artifactFilter); 1072 } 1073 1078 public ResolveReport resolve(URL ivySource, String revision, String [] confs, File cache, Date date, boolean validate, boolean useCacheOnly, boolean transitive, boolean useOrigin, Filter artifactFilter) throws ParseException , IOException { 1079 IvyContext.getContext().setIvy(this); 1080 IvyContext.getContext().setCache(cache); 1081 1082 URLResource res = new URLResource(ivySource); 1083 ModuleDescriptorParser parser = ModuleDescriptorParserRegistry.getInstance().getParser(res); 1084 Message.verbose("using "+parser+" to parse "+ivySource); 1085 ModuleDescriptor md = parser.parseDescriptor(this, ivySource, validate); 1086 if (revision == null && md.getResolvedModuleRevisionId().getRevision() == null) { 1087 revision = "working@"+getLocalHostName(); 1088 } 1089 if (revision != null) { 1090 md.setResolvedModuleRevisionId(ModuleRevisionId.newInstance(md.getModuleRevisionId(), revision)); 1091 } 1092 1093 return resolve(md, confs, cache, date, validate, useCacheOnly, transitive, useOrigin, true, true, artifactFilter); 1094 } 1095 1096 public ResolveReport resolve(ModuleDescriptor md, String [] confs, File cache, Date date, boolean validate, boolean useCacheOnly, Filter artifactFilter) throws ParseException , IOException , FileNotFoundException { 1097 return resolve(md, confs, cache, date, validate, useCacheOnly, true, artifactFilter); 1098 } 1099 public ResolveReport resolve(ModuleDescriptor md, String [] confs, File cache, Date date, boolean validate, boolean useCacheOnly, boolean transitive, Filter artifactFilter) throws ParseException , IOException , FileNotFoundException { 1100 return resolve(md, confs, cache, date, validate, useCacheOnly, transitive, true, true, artifactFilter); 1101 } 1102 public ResolveReport resolve(ModuleDescriptor md, String [] confs, File cache, Date date, boolean validate, boolean useCacheOnly, boolean transitive, boolean download, boolean outputReport, Filter artifactFilter) throws ParseException , IOException , FileNotFoundException { 1103 return resolve(md, confs, cache, date, validate, useCacheOnly, transitive, false, download, outputReport, artifactFilter); 1104 } 1105 1110 public ResolveReport resolve(ModuleDescriptor md, String [] confs, File cache, Date date, boolean validate, boolean useCacheOnly, boolean transitive, boolean useOrigin, boolean download, boolean outputReport, Filter artifactFilter) throws ParseException , IOException , FileNotFoundException { 1111 IvyContext.getContext().setIvy(this); 1112 DependencyResolver oldDictator = getDictatorResolver(); 1113 if (useCacheOnly) { 1114 setDictatorResolver(new CacheResolver(this)); 1115 } 1116 try { 1117 if (cache==null) { cache = getDefaultCache(); 1119 IvyContext.getContext().setCache(cache); 1120 } 1121 if (artifactFilter == null) { 1122 artifactFilter = FilterHelper.NO_FILTER; 1123 } 1124 if (confs.length == 1 && confs[0].equals("*")) { 1125 confs = md.getConfigurationsNames(); 1126 } 1127 fireIvyEvent(new StartResolveEvent(this, md, confs)); 1128 1129 long start = System.currentTimeMillis(); 1130 Message.info(":: resolving dependencies :: "+md.getResolvedModuleRevisionId()+(transitive?"":" [not transitive]")); 1131 Message.info("\tconfs: "+Arrays.asList(confs)); 1132 Message.verbose("\tvalidate = "+validate); 1133 ResolveReport report = new ResolveReport(md); 1134 1135 IvyNode[] dependencies = getDependencies(md, confs, cache, date, report, validate, transitive); 1137 report.setDependencies(Arrays.asList(dependencies), artifactFilter); 1138 1139 1140 File ivyFileInCache = getResolvedIvyFileInCache(cache, md.getResolvedModuleRevisionId()); 1142 md.toIvyFile(ivyFileInCache); 1143 1144 File ivyPropertiesInCache = getResolvedIvyPropertiesInCache(cache, md.getResolvedModuleRevisionId()); 1148 Properties props = new Properties (); 1149 if (dependencies.length > 0) { 1150 IvyNode root = dependencies[0].getRoot(); 1151 for (int i = 0; i < dependencies.length; i++) { 1152 if (!dependencies[i].isCompletelyEvicted() && !dependencies[i].hasProblem()) { 1153 DependencyDescriptor dd = dependencies[i].getDependencyDescriptor(root); 1154 if (dd != null) { 1155 String rev = dependencies[i].getResolvedId().getRevision(); 1156 String status = dependencies[i].getDescriptor().getStatus(); 1157 props.put(dd.getDependencyRevisionId().encodeToString(), rev+" "+status); 1158 } 1159 } 1160 } 1161 } 1162 props.store(new FileOutputStream (ivyPropertiesInCache), md.getResolvedModuleRevisionId()+ " resolved revisions"); 1163 Message.verbose("\tresolved ivy file produced in "+ivyFileInCache); 1164 1165 report.setResolveTime(System.currentTimeMillis()-start); 1166 1167 if (download) { 1168 Message.verbose(":: downloading artifacts ::"); 1169 1170 downloadArtifacts(report, cache, useOrigin, artifactFilter); 1171 } 1172 1173 1174 if (outputReport) { 1175 outputReport(report, cache); 1176 } 1177 1178 fireIvyEvent(new EndResolveEvent(this, md, confs, report)); 1179 return report; 1180 } finally { 1181 setDictatorResolver(oldDictator); 1182 } 1183 } 1184 1185 public void outputReport(ResolveReport report, File cache) { 1186 Message.info(":: resolution report ::"); 1187 report.setProblemMessages(Message.getProblems()); 1188 report.output(getReportOutputters(), cache); 1190 1191 Message.verbose("\tresolve done ("+report.getResolveTime()+"ms resolve - "+report.getDownloadTime()+"ms download)"); 1192 Message.sumupProblems(); 1193 } 1194 1195 public void downloadArtifacts(ResolveReport report, File cache, boolean useOrigin, Filter artifactFilter) { 1196 long start = System.currentTimeMillis(); 1197 IvyNode[] dependencies = (IvyNode[]) report.getDependencies().toArray(new IvyNode[report.getDependencies().size()]); 1198 1199 fireIvyEvent(new PrepareDownloadEvent(this, (Artifact[])report.getArtifacts().toArray(new Artifact[report.getArtifacts().size()]))); 1200 1201 for (int i = 0; i < dependencies.length; i++) { 1202 checkInterrupted(); 1203 if (!dependencies[i].isCompletelyEvicted() && !dependencies[i].hasProblem()) { 1205 DependencyResolver resolver = dependencies[i].getModuleRevision().getArtifactResolver(); 1206 Artifact[] selectedArtifacts = dependencies[i].getSelectedArtifacts(artifactFilter); 1207 DownloadReport dReport = resolver.download(selectedArtifacts, this, cache, useOrigin); 1208 ArtifactDownloadReport[] adrs = dReport.getArtifactsReports(); 1209 for (int j = 0; j < adrs.length; j++) { 1210 if (adrs[j].getDownloadStatus() == DownloadStatus.FAILED) { 1211 Message.warn("\t[NOT FOUND ] "+adrs[j].getArtifact()); 1212 resolver.reportFailure(adrs[j].getArtifact()); 1213 } 1214 } 1215 String [] dconfs = dependencies[i].getRootModuleConfigurations(); 1217 for (int j = 0; j < dconfs.length; j++) { 1218 if (dependencies[i].isEvicted(dconfs[j])) { 1222 report.getConfigurationReport(dconfs[j]).addDependency(dependencies[i]); 1223 } else { 1224 report.getConfigurationReport(dconfs[j]).addDependency(dependencies[i], dReport); 1225 } 1226 } 1227 } 1228 } 1229 report.setDownloadTime(System.currentTimeMillis() - start); 1230 } 1231 1232 1235 public void checkInterrupted() { 1236 if (isInterrupted()) { 1237 Message.info("operation interrupted"); 1238 throw new RuntimeException ("operation interrupted"); 1239 } 1240 } 1241 1242 1257 public ArtifactDownloadReport download(Artifact artifact, File cache) { 1258 IvyContext.getContext().setIvy(this); 1259 IvyContext.getContext().setCache(cache); 1260 if (cache == null) { 1261 cache = getDefaultCache(); 1262 } 1263 DependencyResolver resolver = getResolver(artifact.getModuleRevisionId().getModuleId()); 1264 DownloadReport r = resolver.download(new Artifact[] {artifact}, this, cache, false); 1265 return r.getArtifactReport(artifact); 1266 } 1267 1268 1281 public IvyNode[] getDependencies(URL ivySource, String [] confs, File cache, Date date, boolean validate) throws ParseException , IOException { 1282 return getDependencies(ModuleDescriptorParserRegistry.getInstance().parseDescriptor(this, ivySource, validate), confs, cache, date, null, validate); 1283 } 1284 1285 1297 public IvyNode[] getDependencies(ModuleDescriptor md, String [] confs, File cache, Date date, ResolveReport report, boolean validate) { 1298 return getDependencies(md, confs, cache, date, report, validate, true); 1299 } 1300 public IvyNode[] getDependencies(ModuleDescriptor md, String [] confs, File cache, Date date, ResolveReport report, boolean validate, boolean transitive) { 1301 IvyContext.getContext().setIvy(this); 1302 IvyContext.getContext().setCache(cache); 1303 if (md == null) { 1304 throw new NullPointerException ("module descriptor must not be null"); 1305 } 1306 if (cache==null) { cache = getDefaultCache(); 1308 } 1309 if (confs.length == 1 && confs[0].equals("*")) { 1310 confs = md.getConfigurationsNames(); 1311 } 1312 1313 Map dependenciesMap = new LinkedHashMap (); 1314 Date reportDate = new Date (); 1315 ResolveData data = new ResolveData(this, cache, date, null, validate, transitive, dependenciesMap); 1316 IvyNode rootNode = new IvyNode(data, md); 1317 1318 for (int i = 0; i < confs.length; i++) { 1319 _fetchedSet.clear(); 1321 1322 Configuration configuration = md.getConfiguration(confs[i]); 1323 if (configuration == null) { 1324 Message.error("asked configuration not found in "+md.getModuleRevisionId()+": "+confs[i]); 1325 } else { 1326 ConfigurationResolveReport confReport = null; 1327 if (report != null) { 1328 confReport = report.getConfigurationReport(confs[i]); 1329 if (confReport == null) { 1330 confReport = new ConfigurationResolveReport(this, md, confs[i], reportDate, cache); 1331 report.addReport(confs[i], confReport); 1332 } 1333 } 1334 data.setReport(confReport); 1336 1337 rootNode.setRootModuleConf(confs[i]); 1339 rootNode.setRequestedConf(confs[i]); 1340 rootNode.updateConfsToFetch(Collections.singleton(confs[i])); 1341 1342 fetchDependencies(rootNode, confs[i], false); 1344 } 1345 } 1346 1347 Collection dependencies = new LinkedHashSet (dependenciesMap.size()); for (Iterator iter = dependenciesMap.values().iterator(); iter.hasNext();) { 1350 IvyNode dep = (IvyNode) iter.next(); 1351 if (dep != null) { 1352 dependencies.add(dep); 1353 } 1354 } 1355 List sortedDependencies = sortNodes(dependencies); 1356 Collections.reverse(sortedDependencies); 1357 1358 for (ListIterator iter = sortedDependencies.listIterator(); iter.hasNext();) { 1364 IvyNode node = (IvyNode)iter.next(); 1365 if (!node.isCompletelyEvicted()) { 1366 for (int i = 0; i < confs.length; i++) { 1367 IvyNode.Caller[] callers = node.getCallers(confs[i]); 1368 if (debugConflictResolution()) { 1369 Message.debug("checking if "+node.getId()+" is transitively evicted in "+confs[i]); 1370 } 1371 boolean allEvicted = callers.length > 0; 1372 for (int j = 0; j < callers.length; j++) { 1373 if (callers[j].getModuleRevisionId().equals(md.getModuleRevisionId())) { 1374 allEvicted = false; 1376 break; 1377 } else { 1378 IvyNode callerNode = (IvyNode)dependenciesMap.get(callers[j].getModuleRevisionId()); 1379 if (callerNode == null) { 1380 Message.warn("ivy internal error: no node found for "+callers[j].getModuleRevisionId()+": looked in "+dependenciesMap.keySet()+" and root module id was "+md.getModuleRevisionId()); 1381 } else if (!callerNode.isEvicted(confs[i])) { 1382 allEvicted = false; 1383 break; 1384 } else { 1385 if (debugConflictResolution()) { 1386 Message.debug("caller "+callerNode.getId()+" of "+node.getId()+" is evicted"); 1387 } 1388 } 1389 } 1390 } 1391 if (allEvicted) { 1392 Message.verbose("all callers are evicted for "+node+": evicting too"); 1393 node.markEvicted(confs[i], null, null, null); 1394 } else { 1395 if (debugConflictResolution()) { 1396 Message.debug(node.getId()+" isn't transitively evicted, at least one caller was not evicted"); 1397 } 1398 } 1399 } 1400 } 1401 } 1402 1403 return (IvyNode[]) dependencies.toArray(new IvyNode[dependencies.size()]); 1404 } 1405 1406 1407 1408 1409 private void fetchDependencies(IvyNode node, String conf, boolean shouldBePublic) { 1410 checkInterrupted(); 1411 long start = System.currentTimeMillis(); 1412 if (debugConflictResolution()) { 1413 Message.debug(node.getId()+" => resolving dependencies in "+conf); 1414 } 1415 resolveConflict(node, node.getParent()); 1416 1417 if (node.loadData(conf, shouldBePublic)) { 1418 node = node.getRealNode(true); 1420 resolveConflict(node, node.getParent()); 1421 if (!node.isEvicted(node.getRootModuleConf())) { 1422 String [] confs = node.getRealConfs(conf); 1423 for (int i = 0; i < confs.length; i++) { 1424 doFetchDependencies(node, confs[i]); 1425 } 1426 } 1427 } else if (!node.hasProblem()) { 1428 if (!node.isEvicted(node.getRootModuleConf())) { 1431 String [] confs = node.getRealConfs(conf); 1432 for (int i = 0; i < confs.length; i++) { 1433 doFetchDependencies(node, confs[i]); 1434 } 1435 } 1436 } 1437 if (node.isEvicted(node.getRootModuleConf())) { 1438 IvyNode.EvictionData ed = node.getEvictedData(node.getRootModuleConf()); 1440 if (ed.getSelected() != null) { 1441 for (Iterator iter = ed.getSelected().iterator(); iter.hasNext();) { 1442 IvyNode selected = (IvyNode)iter.next(); 1443 fetchDependencies(selected, conf, true); 1444 } 1445 } 1446 } 1447 if (debugConflictResolution()) { 1448 Message.debug(node.getId()+" => dependencies resolved in "+conf+" ("+(System.currentTimeMillis()-start)+"ms)"); 1449 } 1450 } 1451 1452 private void doFetchDependencies(IvyNode node, String conf) { 1453 Configuration c = node.getConfiguration(conf); 1454 if (c == null) { 1455 Message.warn("configuration not found '"+conf+"' in "+node.getResolvedId()+": ignoring"); 1456 if (node.getParent() != null) { 1457 Message.warn("it was required from "+node.getParent().getResolvedId()); 1458 } 1459 return; 1460 } 1461 1464 boolean requestedConfSet = false; 1466 if (node.getRequestedConf()==null) { 1467 node.setRequestedConf(conf); 1468 requestedConfSet = true; 1469 } 1470 String [] extendedConfs = c.getExtends(); 1472 if (extendedConfs.length > 0) { 1473 node.updateConfsToFetch(Arrays.asList(extendedConfs)); 1474 } 1475 for (int i = 0; i < extendedConfs.length; i++) { 1476 fetchDependencies(node, extendedConfs[i], false); 1477 } 1478 1479 DependencyDescriptor dd = node.getDependencyDescriptor(node.getParent()); 1481 if (!isDependenciesFetched(node, conf) && (dd == null || node.isTransitive())) { 1482 Collection dependencies = node.getDependencies(conf, true); 1483 for (Iterator iter = dependencies.iterator(); iter.hasNext();) { 1484 IvyNode dep = (IvyNode)iter.next(); 1485 dep = dep.getRealNode(); node.traverse(conf, dep); if (dep.isCircular()) { 1488 continue; 1489 } 1490 String [] confs = dep.getRequiredConfigurations(node, conf); 1491 for (int i = 0; i < confs.length; i++) { 1492 fetchDependencies(dep, confs[i], true); 1493 } 1494 confs = dep.getConfsToFetch(); 1497 for (int i = 0; i < confs.length; i++) { 1498 fetchDependencies(dep, confs[i], true); 1499 } 1500 } 1501 } 1502 if (requestedConfSet) { 1505 node.setRequestedConf(null); 1506 } 1507 1508 } 1509 1510 1511 1517 private boolean isDependenciesFetched(IvyNode node, String conf) { 1518 ModuleId moduleId = node.getModuleId(); 1519 ModuleRevisionId moduleRevisionId = node.getResolvedId(); 1520 String key = moduleId.getOrganisation()+"|"+moduleId.getName()+"|"+moduleRevisionId.getRevision() + 1521 "|" + conf; 1522 if (_fetchedSet.contains(key)) { 1523 return true; 1524 } 1525 _fetchedSet.add(key); 1526 return false; 1527 } 1528 1529 private void resolveConflict(IvyNode node, IvyNode parent) { 1530 resolveConflict(node, parent, Collections.EMPTY_SET); 1531 } 1532 private void resolveConflict(IvyNode node, IvyNode parent, Collection toevict) { 1533 if (parent == null || node == parent) { 1534 return; 1535 } 1536 if (checkConflictSolved(node, parent)) { 1538 return; 1539 } 1540 1541 Collection resolvedNodes = new HashSet (parent.getResolvedNodes(node.getModuleId(), node.getRootModuleConf())); 1543 Collection conflicts = computeConflicts(node, parent, toevict, resolvedNodes); 1544 if (debugConflictResolution()) { 1545 Message.debug("found conflicting revisions for "+node+" in "+parent+": "+conflicts); 1546 } 1547 1548 Collection resolved = parent.getConflictManager(node.getModuleId()).resolveConflicts(parent, conflicts); 1549 if (debugConflictResolution()) { 1550 Message.debug("selected revisions for "+node+" in "+parent+": "+resolved); 1551 } 1552 if (resolved.contains(node)) { 1553 1555 toevict = resolvedNodes; 1557 toevict.removeAll(resolved); 1558 1559 for (Iterator iter = toevict.iterator(); iter.hasNext();) { 1560 IvyNode te = (IvyNode)iter.next(); 1561 te.markEvicted(node.getRootModuleConf(), parent, parent.getConflictManager(node.getModuleId()), resolved); 1562 1563 if (debugConflictResolution()) { 1564 Message.debug("evicting "+te+" by "+te.getEvictedData(node.getRootModuleConf())); 1565 } 1566 } 1567 1568 parent.setResolvedNodes(node.getModuleId(), node.getRootModuleConf(), resolved); 1572 1573 Collection evicted = new HashSet (parent.getEvictedNodes(node.getModuleId(), node.getRootModuleConf())); 1574 evicted.removeAll(resolved); 1575 evicted.addAll(toevict); 1576 parent.setEvictedNodes(node.getModuleId(), node.getRootModuleConf(), evicted); 1577 1578 resolveConflict(node, parent.getParent(), toevict); 1579 } else { 1580 if (resolved.isEmpty()) { 1582 if (debugConflictResolution()) { 1583 Message.verbose("conflict manager '"+parent.getConflictManager(node.getModuleId())+"' evicted all revisions among "+conflicts); 1584 } 1585 } 1586 1587 1588 1590 Collection evicted = new HashSet (parent.getEvictedNodes(node.getModuleId(), node.getRootModuleConf())); 1591 toevict.removeAll(resolved); 1592 evicted.removeAll(resolved); 1593 evicted.addAll(toevict); 1594 evicted.add(node); 1595 parent.setEvictedNodes(node.getModuleId(), node.getRootModuleConf(), evicted); 1596 1597 1598 node.markEvicted(node.getRootModuleConf(), parent, parent.getConflictManager(node.getModuleId()), resolved); 1599 if (debugConflictResolution()) { 1600 Message.debug("evicting "+node+" by "+node.getEvictedData(node.getRootModuleConf())); 1601 } 1602 1603 Collection prevResolved = parent.getResolvedNodes(node.getModuleId(), node.getRootModuleConf()); 1605 if (!prevResolved.equals(resolved)) { 1606 parent.setResolvedNodes(node.getModuleId(), node.getRootModuleConf(), resolved); 1607 for (Iterator iter = resolved.iterator(); iter.hasNext();) { 1608 IvyNode sel = (IvyNode)iter.next(); 1609 if (!prevResolved.contains(sel)) { 1610 resolveConflict(sel, parent.getParent(), toevict); 1611 } 1612 } 1613 } 1614 1615 } 1616 } 1617 1618 private Collection computeConflicts(IvyNode node, IvyNode parent, Collection toevict, Collection resolvedNodes) { 1619 Collection conflicts = new HashSet (); 1620 if (resolvedNodes.removeAll(toevict)) { 1621 conflicts.add(node); 1624 Collection deps = parent.getDependencies(parent.getRequiredConfigurations()); 1625 for (Iterator iter = deps.iterator(); iter.hasNext();) { 1626 IvyNode dep = (IvyNode)iter.next(); 1627 conflicts.addAll(dep.getResolvedNodes(node.getModuleId(), node.getRootModuleConf())); 1628 } 1629 } else if (resolvedNodes.isEmpty() && node.getParent() != parent) { 1630 conflicts.add(node); 1631 DependencyDescriptor[] dds = parent.getDescriptor().getDependencies(); 1632 for (int i = 0; i < dds.length; i++) { 1633 if (dds[i].getDependencyId().equals(node.getModuleId())) { 1634 IvyNode n = node.findNode(dds[i].getDependencyRevisionId()); 1635 if (n != null) { 1636 conflicts.add(n); 1637 break; 1638 } 1639 } 1640 } 1641 } else { 1642 conflicts.add(node); 1643 conflicts.addAll(resolvedNodes); 1644 } 1645 return conflicts; 1646 } 1647 1648 private boolean checkConflictSolved(IvyNode node, IvyNode parent) { 1649 if (parent.getResolvedRevisions(node.getModuleId(), node.getRootModuleConf()).contains(node.getResolvedId())) { 1650 if (debugConflictResolution()) { 1653 Message.debug("conflict resolution already done for "+node+" in "+parent); 1654 } 1655 EvictionData evictionData = node.getEvictionDataInRoot(node.getRootModuleConf(), parent); 1656 if (evictionData != null) { 1657 if (debugConflictResolution()) { 1659 Message.debug(node+" was previously evicted in root module conf "+node.getRootModuleConf()); 1660 } 1661 1662 node.markEvicted(evictionData); 1663 if (debugConflictResolution()) { 1664 Message.debug("evicting "+node+" by "+evictionData); 1665 } 1666 } 1667 return true; 1668 } else if (parent.getEvictedRevisions(node.getModuleId(), node.getRootModuleConf()).contains(node.getResolvedId())) { 1669 if (debugConflictResolution()) { 1672 Message.debug("conflict resolution already done for "+node+" in "+parent); 1673 } 1674 return true; 1675 } 1676 return false; 1677 } 1678 1679 public ResolvedModuleRevision findModuleInCache(ModuleRevisionId mrid, File cache, boolean validate) { 1680 IvyContext.getContext().setIvy(this); 1681 IvyContext.getContext().setCache(cache); 1682 if (!getVersionMatcher().isDynamic(mrid)) { 1684 File ivyFile = getIvyFileInCache(cache, mrid); 1685 if (ivyFile.exists()) { 1686 try { 1688 ModuleDescriptor depMD = XmlModuleDescriptorParser.getInstance().parseDescriptor(this, ivyFile.toURL(), validate); 1689 String resolverName = getSavedResolverName(cache, depMD); 1690 String artResolverName = getSavedArtResolverName(cache, depMD); 1691 DependencyResolver resolver = (DependencyResolver)_resolversMap.get(resolverName); 1692 if (resolver == null) { 1693 Message.debug("\tresolver not found: "+resolverName+" => trying to use the one configured for "+mrid); 1694 resolver = getResolver(depMD.getResolvedModuleRevisionId().getModuleId()); 1695 if (resolver != null) { 1696 Message.debug("\tconfigured resolver found for "+depMD.getResolvedModuleRevisionId()+": "+resolver.getName()+": saving this data"); 1697 saveResolver(cache, depMD, resolver.getName()); 1698 } 1699 } 1700 DependencyResolver artResolver = (DependencyResolver)_resolversMap.get(artResolverName); 1701 if (artResolver == null) { 1702 artResolver = resolver; 1703 } 1704 if (resolver != null) { 1705 Message.debug("\tfound ivy file in cache for "+mrid+" (resolved by "+resolver.getName()+"): "+ivyFile); 1706 return new DefaultModuleRevision(resolver, artResolver, depMD, false, false, ivyFile.toURL()); 1707 } else { 1708 Message.debug("\tresolver not found: "+resolverName+" => cannot use cached ivy file for "+mrid); 1709 } 1710 } catch (Exception e) { 1711 Message.debug("\tproblem while parsing cached ivy file for: "+mrid+": "+e.getMessage()); 1713 } 1714 } else { 1715 Message.debug("\tno ivy file in cache for "+mrid+": tried "+ivyFile); 1716 } 1717 } 1718 return null; 1719 } 1720 1721 1722 1726 public ResolveReport install(ModuleRevisionId mrid, String from, String to, boolean transitive, boolean validate, boolean overwrite, Filter artifactFilter, File cache, String matcherName) throws IOException { 1727 IvyContext.getContext().setIvy(this); 1728 IvyContext.getContext().setCache(cache); 1729 if (cache == null) { 1730 cache = getDefaultCache(); 1731 } 1732 if (artifactFilter == null) { 1733 artifactFilter = FilterHelper.NO_FILTER; 1734 } 1735 DependencyResolver fromResolver = getResolver(from); 1736 DependencyResolver toResolver = getResolver(to); 1737 if (fromResolver == null) { 1738 throw new IllegalArgumentException ("unknown resolver "+from+". Available resolvers are: "+_resolversMap.keySet()); 1739 } 1740 if (toResolver == null) { 1741 throw new IllegalArgumentException ("unknown resolver "+to+". Available resolvers are: "+_resolversMap.keySet()); 1742 } 1743 PatternMatcher matcher = getMatcher(matcherName); 1744 if (matcher == null) { 1745 throw new IllegalArgumentException ("unknown matcher "+matcherName+". Available matchers are: "+_matchers.keySet()); 1746 } 1747 1748 Message.info(":: installing "+mrid+" ::"); 1750 DependencyResolver oldDicator = getDictatorResolver(); 1751 boolean log = logNotConvertedExclusionRule(); 1752 try { 1753 setLogNotConvertedExclusionRule(true); 1754 setDictatorResolver(fromResolver); 1755 1756 DefaultModuleDescriptor md = new DefaultModuleDescriptor(ModuleRevisionId.newInstance("jayasoft", "ivy-install", "1.0"), getStatusManager().getDefaultStatus(), new Date ()); 1757 md.addConfiguration(new Configuration("default")); 1758 md.addConflictManager(new ModuleId(ExactPatternMatcher.ANY_EXPRESSION, ExactPatternMatcher.ANY_EXPRESSION), ExactPatternMatcher.getInstance(), new NoConflictManager()); 1759 1760 if (MatcherHelper.isExact(matcher, mrid)) { 1761 DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md, mrid, false, false, transitive); 1762 dd.addDependencyConfiguration("default", "*"); 1763 md.addDependency(dd); 1764 } else { 1765 Collection mrids = findModuleRevisionIds(fromResolver, mrid, matcher); 1766 1767 for (Iterator iter = mrids.iterator(); iter.hasNext();) { 1768 ModuleRevisionId foundMrid = (ModuleRevisionId)iter.next(); 1769 Message.info("\tfound "+foundMrid+" to install: adding to the list"); 1770 DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md, foundMrid, false, false, transitive); 1771 dd.addDependencyConfiguration("default", "*"); 1772 md.addDependency(dd); 1773 } 1774 } 1775 1776 ResolveReport report = new ResolveReport(md); 1778 1779 Message.info(":: resolving dependencies ::"); 1780 IvyNode[] dependencies = getDependencies(md, new String [] {"default"}, cache, null, report, validate); 1781 report.setDependencies(Arrays.asList(dependencies), artifactFilter); 1782 1783 Message.info(":: downloading artifacts to cache ::"); 1784 downloadArtifacts(report, cache, false, artifactFilter); 1785 1786 Message.info(":: installing in "+to+" ::"); 1788 for (int i = 0; i < dependencies.length; i++) { 1789 ModuleDescriptor depmd = dependencies[i].getDescriptor(); 1790 if (depmd != null) { 1791 Message.verbose("installing "+depmd.getModuleRevisionId()); 1792 publish(depmd, 1793 toResolver, 1794 Collections.singleton(cache.getAbsolutePath()+"/"+getCacheArtifactPattern()), 1795 cache.getAbsolutePath()+"/"+getCacheIvyPattern(), 1796 null, 1797 overwrite, 1798 null); 1799 } 1800 } 1801 1802 Message.info(":: install resolution report ::"); 1803 1804 report.output(getReportOutputters(), cache); 1806 1807 return report; 1808 } finally { 1809 setDictatorResolver(oldDicator); 1810 setLogNotConvertedExclusionRule(log); 1811 } 1812 } 1813 1814 public Collection findModuleRevisionIds(DependencyResolver resolver, ModuleRevisionId pattern, PatternMatcher matcher) { 1815 IvyContext.getContext().setIvy(this); 1816 Collection mrids = new ArrayList (); 1817 String resolverName = resolver.getName(); 1818 1819 Message.verbose("looking for modules matching "+pattern+" using "+matcher.getName()); 1820 Namespace fromNamespace = resolver instanceof AbstractResolver ? ((AbstractResolver)resolver).getNamespace() : null; 1821 1822 Collection modules = new ArrayList (); 1823 1824 OrganisationEntry[] orgs = resolver.listOrganisations(); 1825 if (orgs == null || orgs.length == 0) { 1826 String org = pattern.getOrganisation(); 1828 if (fromNamespace != null) { 1829 org = NameSpaceHelper.transform(pattern.getModuleId(), fromNamespace.getFromSystemTransformer()).getOrganisation(); 1830 } 1831 modules.addAll(Arrays.asList(resolver.listModules(new OrganisationEntry(resolver, org)))); 1832 } else { 1833 Matcher orgMatcher = matcher.getMatcher(pattern.getOrganisation()); 1834 for (int i = 0; i < orgs.length; i++) { 1835 String org = orgs[i].getOrganisation(); 1836 String systemOrg = org; 1837 if (fromNamespace != null) { 1838 systemOrg = NameSpaceHelper.transformOrganisation(org, fromNamespace.getToSystemTransformer()); 1839 } 1840 if (orgMatcher.matches(systemOrg)) { 1841 modules.addAll(Arrays.asList(resolver.listModules(new OrganisationEntry(resolver, org)))); 1842 } 1843 } 1844 } 1845 Message.debug("found " + modules.size() + " modules for "+pattern.getOrganisation()+" on " + resolverName); 1846 boolean foundModule = false; 1847 for (Iterator iter = modules.iterator(); iter.hasNext();) { 1848 ModuleEntry mEntry = (ModuleEntry)iter.next(); 1849 1850 ModuleId foundMid = new ModuleId(mEntry.getOrganisation(), mEntry.getModule()); 1851 ModuleId systemMid = foundMid; 1852 if (fromNamespace != null) { 1853 systemMid = NameSpaceHelper.transform(foundMid, fromNamespace.getToSystemTransformer()); 1854 } 1855 1856 if (MatcherHelper.matches(matcher, pattern.getModuleId(), systemMid)) { 1857 foundModule = true; 1859 RevisionEntry[] rEntries = resolver.listRevisions(mEntry); 1860 Message.debug("found " + rEntries.length + " revisions for [" + mEntry.getOrganisation() + ", "+ mEntry.getModule() + "] on " + resolverName); 1861 1862 boolean foundRevision = false; 1863 for (int j = 0; j < rEntries.length; j++) { 1864 RevisionEntry rEntry = rEntries[j]; 1865 1866 ModuleRevisionId foundMrid = ModuleRevisionId.newInstance(mEntry.getOrganisation(), mEntry.getModule(), rEntry.getRevision()); 1867 ModuleRevisionId systemMrid = foundMrid; 1868 if (fromNamespace != null) { 1869 systemMrid = fromNamespace.getToSystemTransformer().transform(foundMrid); 1870 } 1871 1872 if (MatcherHelper.matches(matcher, pattern, systemMrid)) { 1873 foundRevision = true; 1875 mrids.add(systemMrid); 1876 } 1877 } 1878 if (!foundRevision) { 1879 Message.debug("no revision found matching "+pattern+" in [" + mEntry.getOrganisation() + "," + mEntry.getModule()+ "] using " + resolverName); 1880 } 1881 } 1882 } 1883 if (!foundModule) { 1884 Message.debug("no module found matching "+pattern+" using " + resolverName); 1885 } 1886 return mrids; 1887 } 1888 1889 1893 1894 1903 public int retrieve(ModuleId moduleId, String [] confs, final File cache, String destFilePattern) { 1904 return retrieve(moduleId, confs, cache, destFilePattern, null); 1905 } 1906 1909 public int retrieve(ModuleId moduleId, String [] confs, final File cache, String destFilePattern, String destIvyPattern) { 1910 return retrieve(moduleId, confs, cache, destFilePattern, destIvyPattern, FilterHelper.NO_FILTER); 1911 } 1912 1913 public int retrieve(ModuleId moduleId, String [] confs, final File cache, String destFilePattern, String destIvyPattern, Filter artifactFilter) { 1914 return retrieve(moduleId, confs, cache, destFilePattern, destIvyPattern, artifactFilter, false, false); 1915 } 1916 public int retrieve(ModuleId moduleId, String [] confs, final File cache, String destFilePattern, String destIvyPattern, Filter artifactFilter, boolean sync, boolean useOrigin) { 1917 if (artifactFilter == null) { 1918 artifactFilter = FilterHelper.NO_FILTER; 1919 } 1920 1921 IvyContext.getContext().setIvy(this); 1922 IvyContext.getContext().setCache(cache); 1923 Message.info(":: retrieving :: "+moduleId+(sync?" [sync]":"")); 1924 Message.info("\tconfs: "+Arrays.asList(confs)); 1925 long start = System.currentTimeMillis(); 1926 1927 destFilePattern = IvyPatternHelper.substituteVariables(destFilePattern, getVariables()); 1928 destIvyPattern = IvyPatternHelper.substituteVariables(destIvyPattern, getVariables()); 1929 try { 1930 Map artifactsToCopy = determineArtifactsToCopy(moduleId, confs, cache, destFilePattern, destIvyPattern, artifactFilter); 1931 File fileRetrieveRoot = new File (IvyPatternHelper.getTokenRoot(destFilePattern)); 1932 File ivyRetrieveRoot = destIvyPattern == null ? null : new File (IvyPatternHelper.getTokenRoot(destIvyPattern)); 1933 Collection targetArtifactsStructure = new HashSet (); Collection targetIvysStructure = new HashSet (); 1936 int targetsCopied = 0; 1938 int targetsUpToDate = 0; 1939 for (Iterator iter = artifactsToCopy.keySet().iterator(); iter.hasNext();) { 1940 Artifact artifact = (Artifact)iter.next(); 1941 File archive; 1942 if ("ivy".equals(artifact.getType())) { 1943 archive = getIvyFileInCache(cache, artifact.getModuleRevisionId()); 1944 } else { 1945 archive = getArchiveFileInCache(cache, artifact, getSavedArtifactOrigin(cache, artifact), useOrigin); 1946 if (!useOrigin && !archive.exists()) { 1947 archive = getArchiveFileInCache(cache, artifact, getSavedArtifactOrigin(cache, artifact)); 1950 } 1951 } 1952 Set dest = (Set )artifactsToCopy.get(artifact); 1953 Message.verbose("\tretrieving "+archive); 1954 for (Iterator it2 = dest.iterator(); it2.hasNext();) { 1955 checkInterrupted(); 1956 File destFile = new File ((String )it2.next()); 1957 if (!_checkUpToDate || !upToDate(archive, destFile)) { 1958 Message.verbose("\t\tto "+destFile); 1959 FileUtil.copy(archive, destFile, null); 1960 targetsCopied++; 1961 } else { 1962 Message.verbose("\t\tto "+destFile+" [NOT REQUIRED]"); 1963 targetsUpToDate++; 1964 } 1965 if ("ivy".equals(artifact.getType())) { 1966 targetIvysStructure.addAll(FileUtil.getPathFiles(ivyRetrieveRoot, destFile)); 1967 } else { 1968 targetArtifactsStructure.addAll(FileUtil.getPathFiles(fileRetrieveRoot, destFile)); 1969 } 1970 } 1971 } 1972 1973 if (sync) { 1974 Message.verbose("\tsyncing..."); 1975 Collection existingArtifacts = FileUtil.listAll(fileRetrieveRoot); 1976 Collection existingIvys = ivyRetrieveRoot == null ? null : FileUtil.listAll(ivyRetrieveRoot); 1977 1978 if (fileRetrieveRoot.equals(ivyRetrieveRoot)) { 1979 Collection target = targetArtifactsStructure; 1980 target.addAll(targetIvysStructure); 1981 Collection existing = existingArtifacts; 1982 existing.addAll(existingIvys); 1983 sync(target, existing); 1984 } else { 1985 sync(targetArtifactsStructure, existingArtifacts); 1986 if (existingIvys != null) { 1987 sync(targetIvysStructure, existingIvys); 1988 } 1989 } 1990 } 1991 Message.info("\t"+targetsCopied+" artifacts copied, "+targetsUpToDate+" already retrieved"); 1992 Message.verbose("\tretrieve done ("+(System.currentTimeMillis()-start)+"ms)"); 1993 1994 return targetsCopied; 1995 } catch (Exception ex) { 1996 throw new RuntimeException ("problem during retrieve of "+moduleId+": "+ex, ex); 1997 } 1998 } 1999 2000 private void sync(Collection target, Collection existing) { 2001 Collection toRemove = new HashSet (); 2002 for (Iterator iter = existing.iterator(); iter.hasNext();) { 2003 File file = (File ) iter.next(); 2004 toRemove.add(file.getAbsoluteFile()); 2005 } 2006 for (Iterator iter = target.iterator(); iter.hasNext();) { 2007 File file = (File ) iter.next(); 2008 toRemove.remove(file.getAbsoluteFile()); 2009 } 2010 for (Iterator iter = toRemove.iterator(); iter.hasNext();) { 2011 File file = (File ) iter.next(); 2012 if (file.exists()) { 2013 Message.verbose("\t\tdeleting "+file); 2014 FileUtil.forceDelete(file); 2015 } 2016 } 2017 } 2018 2019 public Map determineArtifactsToCopy(ModuleId moduleId, String [] confs, final File cache, String destFilePattern, String destIvyPattern) throws ParseException , IOException { 2020 return determineArtifactsToCopy(moduleId, confs, cache, destFilePattern, destIvyPattern, FilterHelper.NO_FILTER); 2021 } 2022 2023 public Map determineArtifactsToCopy(ModuleId moduleId, String [] confs, final File cache, String destFilePattern, String destIvyPattern, Filter artifactFilter) throws ParseException , IOException { 2024 IvyContext.getContext().setIvy(this); 2025 IvyContext.getContext().setCache(cache); 2026 2027 if (artifactFilter == null) { 2028 artifactFilter = FilterHelper.NO_FILTER; 2029 } 2030 2031 final Map artifactsToCopy = new HashMap (); final Map conflictsMap = new HashMap (); final Map conflictsConfMap = new HashMap (); XmlReportParser parser = new XmlReportParser(); 2036 for (int i = 0; i < confs.length; i++) { 2037 final String conf = confs[i]; 2038 Collection artifacts = new ArrayList (Arrays.asList(parser.getArtifacts(moduleId, conf, cache))); 2039 if (destIvyPattern != null) { 2040 ModuleRevisionId[] mrids = parser.getRealDependencyRevisionIds(moduleId, conf, cache); 2041 for (int j = 0; j < mrids.length; j++) { 2042 artifacts.add(DefaultArtifact.newIvyArtifact(mrids[j], null)); 2043 } 2044 } 2045 for (Iterator iter = artifacts.iterator(); iter.hasNext();) { 2046 Artifact artifact = (Artifact)iter.next(); 2047 String destPattern = "ivy".equals(artifact.getType()) ? destIvyPattern: destFilePattern; 2048 2049 if (!"ivy".equals(artifact.getType()) && !artifactFilter.accept(artifact)) { 2050 continue; } 2052 2053 String destFileName = IvyPatternHelper.substitute(destPattern, artifact, conf); 2054 2055 Set dest = (Set )artifactsToCopy.get(artifact); 2056 if (dest == null) { 2057 dest = new HashSet (); 2058 artifactsToCopy.put(artifact, dest); 2059 } 2060 String copyDest = new File (destFileName).getAbsolutePath(); 2061 dest.add(copyDest); 2062 2063 Set conflicts = (Set )conflictsMap.get(copyDest); 2064 Set conflictsConf = (Set )conflictsConfMap.get(copyDest); 2065 if (conflicts == null) { 2066 conflicts = new HashSet (); 2067 conflictsMap.put(copyDest, conflicts); 2068 } 2069 if (conflictsConf == null) { 2070 conflictsConf = new HashSet (); 2071 conflictsConfMap.put(copyDest, conflictsConf); 2072 } 2073 conflicts.add(artifact); 2074 conflictsConf.add(conf); 2075 } 2076 } 2077 2078 for (Iterator iter = conflictsMap.keySet().iterator(); iter.hasNext();) { 2080 String copyDest = (String )iter.next(); 2081 Set artifacts = (Set )conflictsMap.get(copyDest); 2082 Set conflictsConfs = (Set )conflictsConfMap.get(copyDest); 2083 if (artifacts.size() > 1) { 2084 List artifactsList = new ArrayList (artifacts); 2085 Collections.sort(artifactsList, getConflictResolvingPolicy()); 2088 Message.info("\tconflict on "+copyDest+" in "+conflictsConfs+": "+((Artifact)artifactsList.get(artifactsList.size() -1)).getModuleRevisionId().getRevision()+" won"); 2090 2091 for (int i=artifactsList.size() - 2; i >=0; i--) { 2094 Artifact looser = (Artifact)artifactsList.get(i); 2095 Message.verbose("\t\tremoving conflict looser artifact: "+looser); 2096 Set dest = (Set )artifactsToCopy.get(looser); 2098 dest.remove(copyDest); 2099 if (dest.isEmpty()) { 2100 artifactsToCopy.remove(looser); 2101 } 2102 } 2103 } 2104 } 2105 return artifactsToCopy; 2106 } 2107 2108 private boolean upToDate(File source, File target) { 2109 if (!target.exists()) { 2110 return false; 2111 } 2112 return source.lastModified() <= target.lastModified(); 2113 } 2114 2115 2122 private Comparator getConflictResolvingPolicy() { 2123 return new Comparator () { 2124 public int compare(Object o1, Object o2) { 2126 Artifact a1 = (Artifact)o1; 2127 Artifact a2 = (Artifact)o2; 2128 if (a1.getPublicationDate().after(a2.getPublicationDate())) { 2129 return +1; 2131 } else if (a1.getPublicationDate().before(a2.getPublicationDate())) { 2132 return -1; 2134 } else { 2135 return 0; 2136 } 2137 } 2138 }; 2139 } 2140 2141 public void deliver(ModuleRevisionId mrid, 2145 String revision, 2146 File cache, 2147 String destIvyPattern, 2148 String status, 2149 Date pubdate, 2150 PublishingDependencyRevisionResolver pdrResolver, 2151 boolean validate 2152 ) throws IOException , ParseException { 2153 deliver(mrid, revision, cache, destIvyPattern, status, pubdate, pdrResolver, validate, true); 2154 } 2155 2156 2172 public void deliver(ModuleRevisionId mrid, 2173 String revision, 2174 File cache, 2175 String destIvyPattern, 2176 String status, 2177 Date pubdate, 2178 PublishingDependencyRevisionResolver pdrResolver, 2179 boolean validate, 2180 boolean resolveDynamicRevisions) throws IOException , ParseException { 2181 IvyContext.getContext().setIvy(this); 2182 IvyContext.getContext().setCache(cache); 2183 Message.info(":: delivering :: "+mrid+" :: "+revision+" :: "+status+" :: "+pubdate); 2184 Message.verbose("\tvalidate = "+validate); 2185 long start = System.currentTimeMillis(); 2186 destIvyPattern = substitute(destIvyPattern); 2187 2188 File ivyFile = getResolvedIvyFileInCache(cache, mrid); 2190 if (!ivyFile.exists()) { 2191 throw new IllegalStateException ("ivy file not found in cache for "+mrid+": please resolve dependencies before publishing ("+ivyFile+")"); 2192 } 2193 ModuleDescriptor md = null; 2194 URL ivyFileURL = null; 2195 try { 2196 ivyFileURL = ivyFile.toURL(); 2197 md = XmlModuleDescriptorParser.getInstance().parseDescriptor(this, ivyFileURL, validate); 2198 md.setResolvedModuleRevisionId(ModuleRevisionId.newInstance(mrid, revision)); 2199 md.setResolvedPublicationDate(pubdate); 2200 } catch (MalformedURLException e) { 2201 throw new RuntimeException ("malformed url obtained for file "+ivyFile); 2202 } catch (ParseException e) { 2203 throw new IllegalStateException ("bad ivy file in cache for "+mrid+": please clean and resolve again"); 2204 } 2205 2206 Map resolvedRevisions = new HashMap (); Map dependenciesStatus = new HashMap (); File ivyProperties = getResolvedIvyPropertiesInCache(cache, mrid); 2210 if (!ivyProperties.exists()) { 2211 throw new IllegalStateException ("ivy properties not found in cache for "+mrid+": please resolve dependencies before publishing ("+ivyFile+")"); 2212 } 2213 Properties props = new Properties (); 2214 props.load(new FileInputStream (ivyProperties)); 2215 2216 for (Iterator iter = props.keySet().iterator(); iter.hasNext();) { 2217 String depMridStr = (String )iter.next(); 2218 String [] parts = props.getProperty(depMridStr).split(" "); 2219 ModuleRevisionId decodedMrid = ModuleRevisionId.decode(depMridStr); 2220 if (resolveDynamicRevisions) { 2221 resolvedRevisions.put(decodedMrid, parts[0]); 2222 } 2223 dependenciesStatus.put(decodedMrid, parts[1]); 2224 } 2225 2226 Map resolvedDependencies = new HashMap (); DependencyDescriptor[] dependencies = md.getDependencies(); 2229 for (int i = 0; i < dependencies.length; i++) { 2230 String rev = (String )resolvedRevisions.get(dependencies[i].getDependencyRevisionId()); 2231 if (rev == null) { 2232 rev = dependencies[i].getDependencyRevisionId().getRevision(); 2233 } 2234 String depStatus = (String )dependenciesStatus.get(dependencies[i].getDependencyRevisionId()); 2235 resolvedDependencies.put(dependencies[i].getDependencyRevisionId(), 2236 pdrResolver.resolve(md, status, 2237 ModuleRevisionId.newInstance(dependencies[i].getDependencyRevisionId(), rev), 2238 depStatus)); 2239 } 2240 2241 String publishedIvy = IvyPatternHelper.substitute(destIvyPattern, md.getResolvedModuleRevisionId()); 2245 Message.info("\tdelivering ivy file to "+publishedIvy); 2246 try { 2247 XmlModuleDescriptorUpdater.update(this, ivyFileURL, 2248 new File (publishedIvy), 2249 resolvedDependencies, status, revision, pubdate, null, true); 2250 } catch (SAXException ex) { 2251 throw new IllegalStateException ("bad ivy file in cache for "+mrid+": please clean and resolve again"); 2252 } 2253 2254 Message.verbose("\tdeliver done ("+(System.currentTimeMillis()-start)+"ms)"); 2255 } 2256 2257 2266 public Collection publish(ModuleRevisionId mrid, String pubrevision, File cache, String srcArtifactPattern, String resolverName, String srcIvyPattern, boolean validate) throws IOException { 2267 return publish(mrid, pubrevision, cache, srcArtifactPattern, resolverName, srcIvyPattern, validate, false); 2268 } 2269 2278 public Collection publish(ModuleRevisionId mrid, String pubrevision, File cache, String srcArtifactPattern, String resolverName, String srcIvyPattern, boolean validate, boolean overwrite) throws IOException { 2279 return publish(mrid, pubrevision, cache, srcArtifactPattern, resolverName, srcIvyPattern, null, null, null, validate, overwrite, false, null); 2280 } 2281 public Collection publish(ModuleRevisionId mrid, String pubrevision, File cache, String srcArtifactPattern, String resolverName, String srcIvyPattern, String status, Date pubdate, Artifact[] extraArtifacts, boolean validate, boolean overwrite, boolean update, String conf) throws IOException { 2282 return publish(mrid, pubrevision, cache, Collections.singleton(srcArtifactPattern), resolverName, srcIvyPattern, status, pubdate, extraArtifacts, validate, overwrite, update, conf); 2283 } 2284 2312 public Collection publish(ModuleRevisionId mrid, String pubrevision, File cache, Collection srcArtifactPattern, String resolverName, String srcIvyPattern, String status, Date pubdate, Artifact[] extraArtifacts, boolean validate, boolean overwrite, boolean update, String conf) throws IOException { 2313 IvyContext.getContext().setIvy(this); 2314 IvyContext.getContext().setCache(cache); 2315 Message.info(":: publishing :: "+mrid.getModuleId()); 2316 Message.verbose("\tvalidate = "+validate); 2317 long start = System.currentTimeMillis(); 2318 srcIvyPattern = substitute(srcIvyPattern); 2319 ModuleRevisionId pubmrid = ModuleRevisionId.newInstance(mrid, pubrevision); 2321 File ivyFile; 2322 if (srcIvyPattern != null) { 2323 ivyFile = new File (IvyPatternHelper.substitute(srcIvyPattern, DefaultArtifact.newIvyArtifact(pubmrid, new Date ()))); 2324 if (!ivyFile.exists()) { 2325 throw new IllegalArgumentException ("ivy file to publish not found for "+mrid+": call deliver before ("+ivyFile+")"); 2326 } 2327 } else { 2328 ivyFile = getResolvedIvyFileInCache(cache, mrid); 2329 if (!ivyFile.exists()) { 2330 throw new IllegalStateException ("ivy file not found in cache for "+mrid+": please resolve dependencies before publishing ("+ivyFile+")"); 2331 } 2332 } 2333 2334 ModuleDescriptor md = null; 2335 URL ivyFileURL = null; 2336 try { 2337 ivyFileURL = ivyFile.toURL(); 2338 md = XmlModuleDescriptorParser.getInstance().parseDescriptor(this, ivyFileURL, false); 2339 if (srcIvyPattern != null) { 2340 if (!pubrevision.equals(md.getModuleRevisionId().getRevision())) { 2341 if (update) { 2342 File tmp = File.createTempFile("ivy", ".xml"); 2343 tmp.deleteOnExit(); 2344 try { 2345 XmlModuleDescriptorUpdater.update(this, ivyFileURL, tmp, new HashMap (), status==null?md.getStatus():status, pubrevision, pubdate==null?new Date ():pubdate, null, true); 2346 ivyFile = tmp; 2347 md = XmlModuleDescriptorParser.getInstance().parseDescriptor(this, ivyFile.toURL(), false); 2349 srcIvyPattern = ivyFile.getAbsolutePath(); 2350 } catch (SAXException e) { 2351 throw new IllegalStateException ("bad ivy file for "+mrid+": "+ivyFile+": "+e); 2352 } 2353 } else { 2354 throw new IllegalArgumentException ("cannot publish "+ivyFile+" as "+pubrevision+": bad revision found in ivy file. Use deliver before."); 2355 } 2356 } 2357 } else { 2358 md.setResolvedModuleRevisionId(pubmrid); 2359 } 2360 } catch (MalformedURLException e) { 2361 throw new RuntimeException ("malformed url obtained for file "+ivyFile); 2362 } catch (ParseException e) { 2363 throw new IllegalStateException ("bad ivy file for "+mrid+": "+ivyFile+": "+e); 2364 } 2365 2366 DependencyResolver resolver = getResolver(resolverName); 2367 if (resolver == null) { 2368 throw new IllegalArgumentException ("unknown resolver "+resolverName); 2369 } 2370 2371 Collection missing = publish(md, resolver, srcArtifactPattern, srcIvyPattern, extraArtifacts, overwrite, conf); 2373 Message.verbose("\tpublish done ("+(System.currentTimeMillis()-start)+"ms)"); 2374 return missing; 2375 } 2376 2377 private Collection publish(ModuleDescriptor md, DependencyResolver resolver, Collection srcArtifactPattern, String srcIvyPattern, Artifact[] extraArtifacts, boolean overwrite, String conf) throws IOException { 2378 Collection missing = new ArrayList (); 2379 Set artifactsSet = new HashSet (); 2380 String [] confs; 2381 if (null == conf || "".equals(conf)) { 2382 confs = md.getConfigurationsNames(); 2383 } else { 2384 StringTokenizer st = new StringTokenizer (conf, ","); 2385 confs = new String [st.countTokens()]; 2386 int counter = 0; 2387 while (st.hasMoreTokens()) { 2388 confs[counter] = st.nextToken().trim(); 2389 counter++; 2390 } 2391 } 2392 2393 for (int i = 0; i < confs.length; i++) { 2394 Artifact[] artifacts = md.getArtifacts(confs[i]); 2395 for (int j = 0; j < artifacts.length; j++) { 2396 artifactsSet.add(artifacts[j]); 2397 } 2398 } 2399 if (extraArtifacts != null) { 2400 for (int i = 0; i < extraArtifacts.length; i++) { 2401 artifactsSet.add(new MDArtifact(md, extraArtifacts[i].getName(), extraArtifacts[i].getType(), extraArtifacts[i].getExt(), extraArtifacts[i].getUrl(), extraArtifacts[i].getExtraAttributes())); 2402 } 2403 } 2404 for (Iterator iter = artifactsSet.iterator(); iter.hasNext();) { 2406 Artifact artifact = (Artifact) iter.next(); 2407 boolean published = false; 2409 for (Iterator iterator = srcArtifactPattern.iterator(); iterator.hasNext() && !published;) { 2410 String pattern = (String ) iterator.next(); 2411 published = publish(artifact, substitute(pattern), resolver, overwrite); 2412 } 2413 if (!published) { 2414 Message.info("missing artifact "+artifact+":"); 2415 for (Iterator iterator = srcArtifactPattern.iterator(); iterator.hasNext();) { 2416 String pattern = (String ) iterator.next(); 2417 Message.info("\t"+new File (IvyPatternHelper.substitute(pattern, artifact))+" file does not exist"); 2418 } 2419 missing.add(artifact); 2420 } 2421 } 2422 if (srcIvyPattern != null) { 2423 Artifact artifact = MDArtifact.newIvyArtifact(md); 2424 if (!publish(artifact, srcIvyPattern, resolver, overwrite)) { 2425 Message.info("missing ivy file for "+md.getModuleRevisionId()+": "+new File (IvyPatternHelper.substitute(srcIvyPattern, artifact))+" file does not exist"); 2426 missing.add(artifact); 2427 } 2428 } 2429 return missing; 2430 } 2431 2432 private boolean publish(Artifact artifact, String srcArtifactPattern, DependencyResolver resolver, boolean overwrite) throws IOException { 2433 checkInterrupted(); 2434 File src = new File (IvyPatternHelper.substitute(srcArtifactPattern, artifact)); 2435 if (src.exists()) { 2436 resolver.publish(artifact, src, overwrite); 2437 return true; 2438 } else { 2439 return false; 2440 } 2441 } 2442 2443 2447 2450 public List sortNodes(Collection nodes) { 2451 IvyContext.getContext().setIvy(this); 2452 return ModuleDescriptorSorter.sortNodes(getVersionMatcher(), nodes); 2453 } 2454 2455 2456 2463 public List sortModuleDescriptors(Collection moduleDescriptors) { 2464 IvyContext.getContext().setIvy(this); 2465 return ModuleDescriptorSorter.sortModuleDescriptors(getVersionMatcher(), moduleDescriptors); 2466 } 2467 2468 2472 public File getResolvedIvyFileInCache(File cache, ModuleRevisionId mrid) { 2473 IvyContext.getContext().setIvy(this); 2474 IvyContext.getContext().setCache(cache); 2475 return new File (cache, IvyPatternHelper.substitute(_cacheResolvedIvyPattern, mrid.getOrganisation(), mrid.getName(), mrid.getRevision(), "ivy", "ivy", "xml")); 2476 } 2477 2478 public File getResolvedIvyPropertiesInCache(File cache, ModuleRevisionId mrid) { 2479 IvyContext.getContext().setIvy(this); 2480 IvyContext.getContext().setCache(cache); 2481 return new File (cache, IvyPatternHelper.substitute(_cacheResolvedIvyPropertiesPattern, mrid.getOrganisation(), mrid.getName(), mrid.getRevision(), "ivy", "ivy", "xml")); 2482 } 2483 2484 public File getIvyFileInCache(File cache, ModuleRevisionId mrid) { 2485 IvyContext.getContext().setIvy(this); 2486 IvyContext.getContext().setCache(cache); 2487 return new File (cache, IvyPatternHelper.substitute(_cacheIvyPattern, DefaultArtifact.newIvyArtifact(mrid, null))); 2488 } 2489 2490 2496 public File getArchiveFileInCache(File cache, Artifact artifact) { 2497 IvyContext.getContext().setIvy(this); 2498 IvyContext.getContext().setCache(cache); 2499 ArtifactOrigin origin = getSavedArtifactOrigin(cache, artifact); 2500 return getArchiveFileInCache(cache, artifact, origin); 2501 } 2502 2503 2509 public File getArchiveFileInCache(File cache, Artifact artifact, ArtifactOrigin origin) { 2510 IvyContext.getContext().setIvy(this); 2511 IvyContext.getContext().setCache(cache); 2512 File archive = new File (cache, getArchivePathInCache(artifact, origin)); 2513 if (!archive.exists() && origin != null && origin.isLocal()) { 2514 File original = new File (origin.getLocation()); 2515 if (original.exists()) { 2516 return original; 2517 } 2518 } 2519 return archive; 2520 } 2521 2529 public File getArchiveFileInCache(File cache, Artifact artifact, ArtifactOrigin origin, boolean useOrigin) { 2530 IvyContext.getContext().setIvy(this); 2531 IvyContext.getContext().setCache(cache); 2532 if (useOrigin && origin != null && origin.isLocal()) { 2533 return new File (origin.getLocation()); 2534 } else { 2535 return new File (cache, getArchivePathInCache(artifact, origin)); 2536 } 2537 } 2538 2539 2542 public File getArchiveFileInCache(File cache, String organisation, String module, String revision, String artifact, String type, String ext) { 2543 IvyContext.getContext().setIvy(this); 2544 IvyContext.getContext().setCache(cache); 2545 return new File (cache, getArchivePathInCache(organisation, module, revision, artifact, type, ext)); 2546 } 2547 2548 2553 public String getArchivePathInCache(Artifact artifact) { 2554 IvyContext.getContext().setIvy(this); 2555 return IvyPatternHelper.substitute(_cacheArtifactPattern, artifact); 2556 } 2557 2558 public String getArchivePathInCache(Artifact artifact, ArtifactOrigin origin) { 2559 IvyContext.getContext().setIvy(this); 2560 return IvyPatternHelper.substitute(_cacheArtifactPattern, artifact, origin); 2561 } 2562 2563 2566 public String getArchivePathInCache(String organisation, String module, String revision, String artifact, String type, String ext) { 2567 IvyContext.getContext().setIvy(this); 2568 return getArchivePathInCache(new DefaultArtifact(ModuleRevisionId.newInstance(organisation, module, revision), new Date (), artifact, type, ext)); 2569 } 2570 2571 2579 2583 public void interrupt() { 2584 Thread operatingThread = IvyContext.getContext().getOperatingThread(); 2585 interrupt(operatingThread); 2586 } 2587 2588 2592 public void interrupt(Thread operatingThread) { 2593 if (operatingThread != null && operatingThread.isAlive()) { 2594 if (operatingThread == Thread.currentThread()) { 2595 throw new IllegalStateException ("cannot call interrupt from ivy operating thread"); 2596 } 2597 Message.verbose("interrupting operating thread..."); 2598 operatingThread.interrupt(); 2599 synchronized (this) { 2600 _interrupted = true; 2601 } 2602 try { 2603 Message.verbose("waiting clean interruption of operating thread"); 2604 operatingThread.join(_interruptTimeout); 2605 } catch (InterruptedException e) { 2606 } 2607 if (operatingThread.isAlive()) { 2608 Message.warn("waited clean interruption for too long: stopping operating thread"); 2609 operatingThread.stop(); 2610 } 2611 synchronized (this) { 2612 _interrupted = false; 2613 } 2614 } 2615 } 2616 2617 public static String getLocalHostName() { 2618 try { 2619 return InetAddress.getLocalHost().getHostName(); 2620 } catch (UnknownHostException e) { 2621 return "localhost"; 2622 } 2623 } 2624 2625 2626 2633 public String [] listTokenValues(String token, Map otherTokenValues) { 2634 List r = new ArrayList (); 2635 for (Iterator iter = _resolversMap.values().iterator(); iter.hasNext();) { 2636 DependencyResolver resolver = (DependencyResolver)iter.next(); 2637 r.addAll(Arrays.asList(resolver.listTokenValues(token, otherTokenValues))); 2638 } 2639 return (String [])r.toArray(new String [r.size()]); 2640 } 2641 2642 public OrganisationEntry[] listOrganisationEntries() { 2643 List entries = new ArrayList (); 2644 for (Iterator iter = _resolversMap.values().iterator(); iter.hasNext();) { 2645 DependencyResolver resolver = (DependencyResolver)iter.next(); 2646 entries.addAll(Arrays.asList(resolver.listOrganisations())); 2647 } 2648 return (OrganisationEntry[])entries.toArray(new OrganisationEntry[entries.size()]); 2649 } 2650 public String [] listOrganisations() { 2651 Collection orgs = new HashSet (); 2652 for (Iterator iter = _resolversMap.values().iterator(); iter.hasNext();) { 2653 DependencyResolver resolver = (DependencyResolver)iter.next(); 2654 OrganisationEntry[] entries = resolver.listOrganisations(); 2655 if (entries != null) { 2656 for (int i = 0; i < entries.length; i++) { 2657 if (entries[i] != null) { 2658 orgs.add(entries[i].getOrganisation()); 2659 } 2660 } 2661 } 2662 } 2663 return (String [])orgs.toArray(new String [orgs.size()]); 2664 } 2665 public ModuleEntry[] listModuleEntries(OrganisationEntry org) { 2666 List entries = new ArrayList (); 2667 for (Iterator iter = _resolversMap.values().iterator(); iter.hasNext();) { 2668 DependencyResolver resolver = (DependencyResolver)iter.next(); 2669 entries.addAll(Arrays.asList(resolver.listModules(org))); 2670 } 2671 return (ModuleEntry[])entries.toArray(new ModuleEntry[entries.size()]); 2672 } 2673 public String [] listModules(String org) { 2674 List mods = new ArrayList (); 2675 for (Iterator iter = _resolversMap.values().iterator(); iter.hasNext();) { 2676 DependencyResolver resolver = (DependencyResolver)iter.next(); 2677 ModuleEntry[] entries = resolver.listModules(new OrganisationEntry(resolver, org)); 2678 if (entries != null) { 2679 for (int i = 0; i < entries.length; i++) { 2680 if (entries[i] != null) { 2681 mods.add(entries[i].getModule()); 2682 } 2683 } 2684 } 2685 } 2686 return (String [])mods.toArray(new String [mods.size()]); 2687 } 2688 public RevisionEntry[] listRevisionEntries(ModuleEntry module) { 2689 List entries = new ArrayList (); 2690 for (Iterator iter = _resolversMap.values().iterator(); iter.hasNext();) { 2691 DependencyResolver resolver = (DependencyResolver)iter.next(); 2692 entries.addAll(Arrays.asList(resolver.listRevisions(module))); 2693 } 2694 return (RevisionEntry[])entries.toArray(new RevisionEntry[entries.size()]); 2695 } 2696 public String [] listRevisions(String org, String module) { 2697 List revs = new ArrayList (); 2698 for (Iterator iter = _resolversMap.values().iterator(); iter.hasNext();) { 2699 DependencyResolver resolver = (DependencyResolver)iter.next(); 2700 RevisionEntry[] entries = resolver.listRevisions(new ModuleEntry(new OrganisationEntry(resolver, org), module)); 2701 if (entries != null) { 2702 for (int i = 0; i < entries.length; i++) { 2703 if (entries[i] != null) { 2704 revs.add(entries[i].getRevision()); 2705 } 2706 } 2707 } 2708 } 2709 return (String [])revs.toArray(new String [revs.size()]); 2710 } 2711 2712 2717 public boolean listingIgnore(String name) { 2718 return _listingIgnore.contains(name); 2719 } 2720 2721 2726 public void filterIgnore(Collection names) { 2727 names.removeAll(_listingIgnore); 2728 } 2729 2730 public boolean isCheckUpToDate() { 2731 return _checkUpToDate; 2732 } 2733 public void setCheckUpToDate(boolean checkUpToDate) { 2734 _checkUpToDate = checkUpToDate; 2735 } 2736 2737 public String getCacheArtifactPattern() { 2738 return _cacheArtifactPattern; 2739 } 2740 2741 2742 public void setCacheArtifactPattern(String cacheArtifactPattern) { 2743 _cacheArtifactPattern = cacheArtifactPattern; 2744 } 2745 2746 2747 public String getCacheIvyPattern() { 2748 return _cacheIvyPattern; 2749 } 2750 2751 2752 public void setCacheIvyPattern(String cacheIvyPattern) { 2753 _cacheIvyPattern = cacheIvyPattern; 2754 } 2755 2756 public boolean doValidate() { 2757 return _validate; 2758 } 2759 2760 public void setValidate(boolean validate) { 2761 _validate = validate; 2762 } 2763 2764 public String getVariable(String name) { 2765 String val = (String )_variables.get(name); 2766 return val==null?val:substitute(val); 2767 } 2768 2769 public ConflictManager getDefaultConflictManager() { 2770 if (_defaultConflictManager == null) { 2771 _defaultConflictManager = new LatestConflictManager(getDefaultLatestStrategy()); 2772 } 2773 return _defaultConflictManager; 2774 } 2775 2776 2777 public void setDefaultConflictManager(ConflictManager defaultConflictManager) { 2778 _defaultConflictManager = defaultConflictManager; 2779 } 2780 2781 2782 public LatestStrategy getDefaultLatestStrategy() { 2783 if (_defaultLatestStrategy == null) { 2784 _defaultLatestStrategy = new LatestRevisionStrategy(); 2785 } 2786 return _defaultLatestStrategy; 2787 } 2788 2789 2790 public void setDefaultLatestStrategy(LatestStrategy defaultLatestStrategy) { 2791 _defaultLatestStrategy = defaultLatestStrategy; 2792 } 2793 2794 private EventListenerList _listeners = new EventListenerList (); 2795 2796 private boolean _logNotConvertedExclusionRule; 2797 2798 private Boolean _debugConflictResolution; 2799 2800 private VersionMatcher _versionMatcher; 2801 2802 public void addTransferListener(TransferListener listener) { 2803 _listeners.add(TransferListener.class, listener); 2804 } 2805 2806 public void removeTransferListener(TransferListener listener) { 2807 _listeners.remove(TransferListener.class, listener); 2808 } 2809 2810 public boolean hasTransferListener(TransferListener listener) { 2811 return Arrays.asList(_listeners.getListeners(TransferListener.class)).contains(listener); 2812 } 2813 protected void fireTransferEvent(TransferEvent evt) { 2814 Object [] listeners = _listeners.getListenerList(); 2815 for (int i = listeners.length-2; i>=0; i-=2) { 2816 if (listeners[i]==TransferListener.class) { 2817 ((TransferListener)listeners[i+1]).transferProgress(evt); 2818 } 2819 } 2820 } 2821 2822 public void addTrigger(Trigger trigger) { 2823 addIvyListener(trigger, trigger.getEventFilter()); 2824 } 2825 2826 public void addConfigured(Trigger trigger) { 2827 addTrigger(trigger); 2828 } 2829 2830 public void addIvyListener(IvyListener listener) { 2831 _listeners.add(IvyListener.class, listener); 2832 } 2833 2834 public void addIvyListener(IvyListener listener, String eventName) { 2835 addIvyListener(listener, new IvyEventFilter(eventName, null, null)); 2836 } 2837 2838 public void addIvyListener(IvyListener listener, Filter filter) { 2839 _listeners.add(IvyListener.class, new FilteredIvyListener(listener, filter)); 2840 } 2841 2842 public void removeIvyListener(IvyListener listener) { 2843 _listeners.remove(IvyListener.class, listener); 2844 IvyListener[] listeners = (IvyListener[])_listeners.getListeners(IvyListener.class); 2845 for (int i = 0; i < listeners.length; i++) { 2846 if (listeners[i] instanceof FilteredIvyListener) { 2847 if (listener.equals(((FilteredIvyListener)listeners[i]).getIvyListener())) { 2848 _listeners.remove(IvyListener.class, listeners[i]); 2849 } 2850 } 2851 } 2852 } 2853 2854 public boolean hasIvyListener(IvyListener listener) { 2855 return Arrays.asList(_listeners.getListeners(IvyListener.class)).contains(listener); 2856 } 2857 public void fireIvyEvent(IvyEvent evt) { 2858 Object [] listeners = _listeners.getListenerList(); 2859 for (int i = listeners.length-2; i>=0; i-=2) { 2860 if (listeners[i]==IvyListener.class) { 2861 ((IvyListener)listeners[i+1]).progress(evt); 2862 } 2863 } 2864 } 2865 2866 public void transferProgress(TransferEvent evt) { 2867 fireTransferEvent(evt); 2868 fireIvyEvent(evt); 2869 } 2870 2871 public boolean isUseRemoteConfig() { 2872 return _useRemoteConfig; 2873 } 2874 2875 public void setUseRemoteConfig(boolean useRemoteConfig) { 2876 _useRemoteConfig = useRemoteConfig; 2877 } 2878 2879 public DependencyResolver getDictatorResolver() { 2880 return _dictatorResolver; 2881 } 2882 2883 public void setDictatorResolver(DependencyResolver dictatorResolver) { 2884 _dictatorResolver = dictatorResolver; 2885 } 2886 2887 2894 public void setVariables(Map variables) { 2895 if (variables == null) { 2896 throw new NullPointerException ("variables shouldn't be null"); 2897 } 2898 _variables = variables; 2899 } 2900 2901 public static URL getDefaultConfigurationURL() { 2902 return Ivy.class.getResource("conf/ivyconf.xml"); 2903 } 2904 2905 2912 public void saveResolver(File cache, ModuleDescriptor md, String name) { 2913 PropertiesFile cdf = getCachedDataFile(cache, md); 2914 cdf.setProperty("resolver", name); 2915 cdf.save(); 2916 } 2917 2918 2925 public void saveArtResolver(File cache, ModuleDescriptor md, String name) { 2926 PropertiesFile cdf = getCachedDataFile(cache, md); 2927 cdf.setProperty("artifact.resolver", name); 2928 cdf.save(); 2929 } 2930 2931 public void saveArtifactOrigin(File cache, Artifact artifact, ArtifactOrigin origin) { 2932 PropertiesFile cdf = getCachedDataFile(cache, artifact.getModuleRevisionId()); 2933 cdf.setProperty("artifact." + artifact.getName() + "#" + artifact.getExt() + ".is-local", String.valueOf(origin.isLocal())); 2934 cdf.setProperty("artifact." + artifact.getName() + "#" + artifact.getExt() + ".location", origin.getLocation()); 2935 cdf.save(); 2936 } 2937 2938 public ArtifactOrigin getSavedArtifactOrigin(File cache, Artifact artifact) { 2939 PropertiesFile cdf = getCachedDataFile(cache, artifact.getModuleRevisionId()); 2940 String location = cdf.getProperty("artifact." + artifact.getName() + "#" + artifact.getExt() + ".location"); 2941 boolean isLocal = Boolean.valueOf(cdf.getProperty("artifact." + artifact.getName() + "#" + artifact.getExt() + ".is-local")).booleanValue(); 2942 2943 if (location == null) { 2944 return null; 2946 } 2947 2948 return new ArtifactOrigin(isLocal, location); 2949 } 2950 2951 public void removeSavedArtifactOrigin(File cache, Artifact artifact) { 2952 PropertiesFile cdf = getCachedDataFile(cache, artifact.getModuleRevisionId()); 2953 cdf.remove("artifact." + artifact.getName() + "#" + artifact.getExt() + ".location"); 2954 cdf.remove("artifact." + artifact.getName() + "#" + artifact.getExt() + ".is-local"); 2955 cdf.save(); 2956 } 2957 2958 private String getSavedResolverName(File cache, ModuleDescriptor md) { 2959 PropertiesFile cdf = getCachedDataFile(cache, md); 2960 return cdf.getProperty("resolver"); 2961 } 2962 2963 private String getSavedArtResolverName(File cache, ModuleDescriptor md) { 2964 PropertiesFile cdf = getCachedDataFile(cache, md); 2965 return cdf.getProperty("artifact.resolver"); 2966 } 2967 2968 private PropertiesFile getCachedDataFile(File cache, ModuleDescriptor md) { 2969 return getCachedDataFile(cache, md.getResolvedModuleRevisionId()); 2970 } 2971 2972 private PropertiesFile getCachedDataFile(File cache, ModuleRevisionId mRevId) { 2973 return new PropertiesFile(new File (cache, IvyPatternHelper.substitute(getCacheDataFilePattern(),mRevId)), "ivy cached data file for "+mRevId); 2974 } 2975 2976 public String getCacheDataFilePattern() { 2977 return _cacheDataFilePattern; 2978 } 2979 2980 public boolean logModuleWhenFound() { 2981 String var = getVariable("ivy.log.module.when.found"); 2982 return var == null || Boolean.valueOf(var).booleanValue(); 2983 } 2984 2985 public boolean logResolvedRevision() { 2986 String var = getVariable("ivy.log.resolved.revision"); 2987 return var == null || Boolean.valueOf(var).booleanValue(); 2988 } 2989 2990 public boolean debugConflictResolution() { 2991 if (_debugConflictResolution == null) { 2992 String var = getVariable("ivy.log.conflict.resolution"); 2993 _debugConflictResolution = Boolean.valueOf(var != null && Boolean.valueOf(var).booleanValue()); 2994 } 2995 return _debugConflictResolution.booleanValue(); 2996 } 2997 2998 public boolean logNotConvertedExclusionRule() { 2999 return _logNotConvertedExclusionRule; 3000 } 3001 public void setLogNotConvertedExclusionRule(boolean logNotConvertedExclusionRule) { 3002 _logNotConvertedExclusionRule = logNotConvertedExclusionRule; 3003 } 3004 public StatusManager getStatusManager() { 3005 if (_statusManager == null) { 3006 _statusManager = StatusManager.newDefaultInstance(); 3007 } 3008 return _statusManager; 3009 } 3010 public void setStatusManager(StatusManager statusManager) { 3011 _statusManager = statusManager; 3012 } 3013 3014 3015 private static class ModuleSettings { 3016 private String _resolverName; 3017 private String _branch; 3018 private String _conflictManager; 3019 public ModuleSettings(String resolverName, String branch, String conflictManager) { 3020 _resolverName = resolverName; 3021 _branch = branch; 3022 _conflictManager = conflictManager; 3023 } 3024 public String toString() { 3025 return _resolverName != null ? "resolver: "+_resolverName:"" 3026 +_branch != null ? "branch: "+_branch:""; 3027 } 3028 public String getBranch() { 3029 return _branch; 3030 } 3031 public String getResolverName() { 3032 return _resolverName; 3033 } 3034 protected String getConflictManager() { 3035 return _conflictManager; 3036 } 3037 } 3038 3039 3040 public synchronized boolean isInterrupted() { 3041 return _interrupted; 3042 } 3043 3044 3045 3053 public ModuleId[] listModules(ModuleId criteria, PatternMatcher matcher) { 3054 List ret = new ArrayList (); 3055 Matcher orgMatcher = matcher.getMatcher(criteria.getOrganisation()); 3056 Matcher modMatcher = matcher.getMatcher(criteria.getName()); 3057 Map tokenValues = new HashMap (); 3058 String [] orgs = listTokenValues(IvyPatternHelper.ORGANISATION_KEY, tokenValues); 3059 for (int i = 0; i < orgs.length; i++) { 3060 if (orgMatcher.matches(orgs[i])) { 3061 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, orgs[i]); 3062 String [] mods = listTokenValues(IvyPatternHelper.MODULE_KEY, tokenValues); 3063 for (int j = 0; j < mods.length; j++) { 3064 if (modMatcher.matches(mods[j])) { 3065 ret.add(new ModuleId(orgs[i], mods[j])); 3066 } 3067 } 3068 } 3069 } 3070 return (ModuleId[]) ret.toArray(new ModuleId[ret.size()]); 3071 } 3072 3073 3074 3082 public ModuleRevisionId[] listModules(ModuleRevisionId criteria, PatternMatcher matcher) { 3083 List ret = new ArrayList (); 3084 Matcher orgMatcher = matcher.getMatcher(criteria.getOrganisation()); 3085 Matcher modMatcher = matcher.getMatcher(criteria.getName()); 3086 Matcher branchMatcher = matcher.getMatcher(criteria.getBranch()); 3087 Matcher revMatcher = matcher.getMatcher(criteria.getRevision()); 3088 Map tokenValues = new HashMap (); 3089 String [] orgs = listTokenValues(IvyPatternHelper.ORGANISATION_KEY, tokenValues); 3090 for (int i = 0; i < orgs.length; i++) { 3091 if (orgMatcher.matches(orgs[i])) { 3092 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, orgs[i]); 3093 String [] mods = listTokenValues(IvyPatternHelper.MODULE_KEY, tokenValues); 3094 for (int j = 0; j < mods.length; j++) { 3095 if (modMatcher.matches(mods[j])) { 3096 tokenValues.put(IvyPatternHelper.MODULE_KEY, mods[j]); 3097 String [] branches = listTokenValues(IvyPatternHelper.BRANCH_KEY, tokenValues); 3098 if (branches == null || branches.length == 0) { 3099 branches = new String [] {getDefaultBranch(new ModuleId(orgs[i], mods[j]))}; 3100 } 3101 for (int k = 0; k < branches.length; k++) { 3102 if (branchMatcher.matches(branches[k])) { 3103 tokenValues.put(IvyPatternHelper.BRANCH_KEY, tokenValues); 3104 String [] revs = listTokenValues(IvyPatternHelper.REVISION_KEY, tokenValues); 3105 for (int l = 0; l < revs.length; l++) { 3106 if (revMatcher.matches(revs[l])) { 3107 ret.add(ModuleRevisionId.newInstance(orgs[i], mods[j], branches[k], revs[l])); 3108 } 3109 } 3110 } 3111 } 3112 } 3113 } 3114 } 3115 } 3116 return (ModuleRevisionId[]) ret.toArray(new ModuleRevisionId[ret.size()]); 3117 } 3118 3119} 3120 | Popular Tags |