Index: ivy-trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java =================================================================== --- ivy-trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java (revision 1362174) +++ ivy-trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java (working copy) @@ -24,7 +24,7 @@ import java.net.URL; import java.text.ParseException; import java.util.Arrays; -import java.util.Iterator; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; @@ -58,7 +58,6 @@ import org.apache.ivy.core.resolve.ResolveEngine; import org.apache.ivy.core.resolve.ResolveOptions; import org.apache.ivy.core.resolve.ResolvedModuleRevision; -import org.apache.ivy.core.settings.IvySettings; import org.apache.ivy.plugins.conflict.ConflictManager; import org.apache.ivy.plugins.conflict.FixedConflictManager; import org.apache.ivy.plugins.matcher.PatternMatcher; @@ -230,30 +229,23 @@ public Parser(ModuleDescriptorParser parser, ParserSettings ivySettings) { super(parser); settings = ivySettings; - configureModuleInheritanceRepository(); + configureModuleInheritanceRepositoryMap(); } + /** - * Configure module inheritance repository (repository containning all path references - * to parent modules). Basicaly it checks if module inheritance repository exist - * in current ivy context, otherwise it will create one as a {@link URLResolver} + * Configure module inheritance repository (repository containing all path references + * to parent modules). Basically it checks if module inheritance repository exists + * in current ivy context, otherwise it will create one as a {@link URLResolver}. + * @return */ - protected void configureModuleInheritanceRepository() { - IvySettings ivysettings = IvyContext.getContext().getSettings(); - DependencyResolver parentModuleResolver=null; - //Does module-inheritance-repository exists ? - for (Iterator iterator = ivysettings.getResolvers().iterator(); iterator.hasNext();) { - DependencyResolver resolver = (DependencyResolver) iterator.next(); - if (resolver.getName().equals(MODULE_INHERITANCE_REPOSITORY)) { - parentModuleResolver=resolver; - break; - } - } - //if does not exist create one - if (parentModuleResolver == null) { - parentModuleResolver= new URLResolver(); - parentModuleResolver.setName(MODULE_INHERITANCE_REPOSITORY); - ivysettings.addResolver(parentModuleResolver); + protected Map configureModuleInheritanceRepositoryMap() { + IvyContext ivyContext = IvyContext.getContext(); + Map moduleInheritanceRepositoryMap = (Map)ivyContext.get(MODULE_INHERITANCE_REPOSITORY); + if (moduleInheritanceRepositoryMap == null) { + moduleInheritanceRepositoryMap = new HashMap(1); + ivyContext.set(MODULE_INHERITANCE_REPOSITORY, moduleInheritanceRepositoryMap); } + return moduleInheritanceRepositoryMap; } public void setInput(InputStream descriptorInput) { @@ -428,13 +420,13 @@ //check on filesystem based on location attribute (for dev ONLY) try { - checkParentModuleOnFilesystem(location); + checkParentModuleOnFilesystem(location, parentMrid); } catch (IOException e) { Message.warn("Unable to parse included ivy file " + location + ": " + e.getMessage()); } - // resolve parent from module inheritance repository + // Resolve parent module descriptor from module inheritance repository parent = resolveParentFromModuleInheritanceRepository(parentMrid); // if not found, tries to resolve using repositories @@ -616,22 +608,35 @@ * Check if parent module is reachable using location attribute (for dev purpose). * If parent module is reachable it will be registered in module inheritance repository * @param location a given location + * @param parentMrid * @throws IOException * @throws ParseException */ - protected void checkParentModuleOnFilesystem(String location) throws IOException, ParseException { - URL url =getSettings().getRelativeUrlResolver().getURL(descriptorURL, location); - //is parent module reachable using location attribute ? - if (url.openConnection().getContentLength() >0 ) { - IvySettings ivysettings = IvyContext.getContext().getSettings(); - URLResolver urlResolver= (URLResolver) ivysettings.getResolver(MODULE_INHERITANCE_REPOSITORY); - if (urlResolver == null) { - throw new ParseException("Unable to find module inheritance repository", 0); - } - - if (!urlResolver.getIvyPatterns().contains(url.toExternalForm())) { - Message.debug("Registering parent module into module inheritance repository, parent module location is "+url.toExternalForm()); - urlResolver.addIvyPattern(url.toExternalForm()); + protected void checkParentModuleOnFilesystem(String location, ModuleRevisionId parentMrid) throws IOException, ParseException { + IvyContext ivyContext = IvyContext.getContext(); + Map moduleInheritanceRepositoryMap = (Map)ivyContext.get(MODULE_INHERITANCE_REPOSITORY); + if (moduleInheritanceRepositoryMap == null) { + moduleInheritanceRepositoryMap = configureModuleInheritanceRepositoryMap(); + } + File file = new File(location); + URL url = null; + if (file.isAbsolute()) { + url = getSettings().getRelativeUrlResolver().getURL(descriptorURL, + file.getAbsolutePath(), location); + } else { + url = getSettings().getRelativeUrlResolver().getURL(descriptorURL, location); + } + // Is parent module reachable using location attribute? + if (url.openConnection().getContentLength() > 0) { + String urlString = url.toExternalForm(); + if (!moduleInheritanceRepositoryMap.containsKey(urlString)) { + Message.debug("Registering parent module into module inheritance repository map. Parent module location: " + urlString); + URLResolver parentModuleResolver = new URLResolver(); + parentModuleResolver.setName(getModuleInheritanceRepositoryParentResolverName(parentMrid)); + parentModuleResolver.addIvyPattern(url.toExternalForm()); + // Do we even need to be adding this resolver to the Ivy settings considering that it's being placed in the map and not being used elsewhere? + ivyContext.getSettings().addResolver(parentModuleResolver); + moduleInheritanceRepositoryMap.put(urlString, parentModuleResolver); } } } @@ -665,13 +670,13 @@ } /** - * Resolve parent module from module inhertance repository + * Resolve parent module from module inheritance repository * @param parentMrid a given {@link ModuleRevisionId} to find * @return a {@link ModuleDescriptor} if found. Return null if no {@link ModuleDescriptor} was found * @throws ParseException */ protected ModuleDescriptor resolveParentFromModuleInheritanceRepository(ModuleRevisionId parentMrid) throws ParseException { - Message.debug("Trying to load included ivy file from module inheritance repository " ); + Message.debug("Trying to resolve included ivy file from module inheritance repository " ); DependencyDescriptor dd = new DefaultDependencyDescriptor(parentMrid, true); ResolveEngine engine = IvyContext.getContext().getIvy().getResolveEngine(); ResolveOptions options = new ResolveOptions(); @@ -679,7 +684,11 @@ options.setDownload(false); ResolveData data = new ResolveData(engine, options); - DependencyResolver resolver = IvyContext.getContext().getSettings().getResolver(MODULE_INHERITANCE_REPOSITORY); + DependencyResolver resolver = IvyContext.getContext().getSettings().getResolver(getModuleInheritanceRepositoryParentResolverName(parentMrid)); + // The parent resolver will be null if its dev-only filesystem path hasn't been specified via the location attribute of the extends element. + if (resolver == null) { + return null; + } dd = NameSpaceHelper.toSystem(dd, getSettings().getContextNamespace()); ResolvedModuleRevision otherModule = resolver.getDependency(dd, data); if (otherModule != null) { @@ -688,6 +697,10 @@ return null; } } + + private static String getModuleInheritanceRepositoryParentResolverName(ModuleRevisionId parentMrid) { + return MODULE_INHERITANCE_REPOSITORY + "-" + parentMrid.toString(); + } protected void publicationsStarted(Attributes attributes) { state = State.PUB;