ant-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gscok...@apache.org
Subject svn commit: r629194 [1/2] - in /ant/ivy/core/trunk: ./ doc/ doc/ivyfile/ src/java/org/apache/ivy/core/module/descriptor/ src/java/org/apache/ivy/core/resolve/ src/java/org/apache/ivy/plugins/parser/ src/java/org/apache/ivy/plugins/parser/m2/ src/java/o...
Date Tue, 19 Feb 2008 19:18:50 GMT
Author: gscokart
Date: Tue Feb 19 11:18:43 2008
New Revision: 629194

URL: http://svn.apache.org/viewvc?rev=629194&view=rev
Log:
IMPORVEMENT: Refactor the PomModuleDescriptorParser in order to allow easier integration of maven pom

Added:
    ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java   (with props)
    ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomReader.java   (with props)
    ant/ivy/core/trunk/test/java/org/apache/ivy/plugins/parser/m2/test-dependencieMgt.pom   (with props)
    ant/ivy/core/trunk/test/java/org/apache/ivy/plugins/parser/m2/test-parentDependencieMgt.pom   (with props)
Modified:
    ant/ivy/core/trunk/CHANGES.txt
    ant/ivy/core/trunk/doc/concept.html
    ant/ivy/core/trunk/doc/ivyfile/info.html
    ant/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultModuleDescriptor.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/ModuleDescriptor.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolveEngine.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/AbstractModuleDescriptorParser.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/ivy.xsd
    ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/ResourceHelper.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/util/XMLHelper.java
    ant/ivy/core/trunk/test/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParserTest.java
    ant/ivy/core/trunk/test/java/org/apache/ivy/plugins/parser/xml/test-write-full.xml
    ant/ivy/core/trunk/test/java/org/apache/ivy/plugins/parser/xml/test.xml

Modified: ant/ivy/core/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/CHANGES.txt?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/CHANGES.txt (original)
+++ ant/ivy/core/trunk/CHANGES.txt Tue Feb 19 11:18:43 2008
@@ -125,6 +125,7 @@
 - IMPROVEMENT: Improvements on hello ivy example (IVY-626) (with contribution from Jacob Grydholt Jensen)
 - IMPROVEMENT: Make the root attribute in the ivyrep resolver mandatory (IVY-625)
 - IMPROVEMENT: New text representation for main module metadata concepts (IVY-649)
+- IMPORVEMENT: Refactor the PomModuleDescriptorParser in order to allow easier integration of maven pom
 
 - FIX: m2 incompatibility - IVY does not recognize property section (IVY-637)
 - FIX: m2 incompatibility - IVY does not recognize parent pom (IVY-636)

Modified: ant/ivy/core/trunk/doc/concept.html
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/doc/concept.html?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/doc/concept.html (original)
+++ ant/ivy/core/trunk/doc/concept.html Tue Feb 19 11:18:43 2008
@@ -183,7 +183,8 @@
 	/>
 </ivy-module>
 </code>
-Then you can use the extra attribute when you declare a dependency on foo:
+Then you must use the extra attribute when you declare a dependency on foo.  Those extra attributes 
+will indeed be used as identifier for the module like the org the name and the revision:
 <code>
 <dependency org="apache" name="foo" e:color="blue" rev="1.5+" />
 </code>

Modified: ant/ivy/core/trunk/doc/ivyfile/info.html
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/doc/ivyfile/info.html?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/doc/ivyfile/info.html (original)
+++ ant/ivy/core/trunk/doc/ivyfile/info.html Tue Feb 19 11:18:43 2008
@@ -67,6 +67,7 @@
         <td>0..1</td></tr>
 </tbody>
 </table>
+After the description, you can also place your own tags in your onw namespace.  This allow to provide some custom information about the module.
 
 	</textarea>
 <script type="text/javascript">xooki.postProcess();</script>

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultModuleDescriptor.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultModuleDescriptor.java?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultModuleDescriptor.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultModuleDescriptor.java Tue Feb 19 11:18:43 2008
@@ -215,6 +215,8 @@
     
     private Map/*<String,String>*/ extraAttributesNamespaces = new LinkedHashMap();
 
+    private Map/*<String,String>*/ extraDescription = new HashMap();
+
     public DefaultModuleDescriptor(ModuleRevisionId id, String status, Date pubDate) {
         this(id, status, pubDate, false);
     }
@@ -617,5 +619,15 @@
 
     public void addExtraAttributeNamespace(String prefix, String namespace) {
         extraAttributesNamespaces.put(prefix, namespace);
+    }
+
+   
+    
+    public void addExtraInfo(String infoKey, String value) {
+        extraDescription.put(infoKey, value);
+    }
+    
+    public Map getExtraInfo() {
+        return extraDescription;
     }
 }

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/ModuleDescriptor.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/ModuleDescriptor.java?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/ModuleDescriptor.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/ModuleDescriptor.java Tue Feb 19 11:18:43 2008
@@ -230,4 +230,13 @@
      *         URIs.
      */
     Map/*<String,String>*/ getExtraAttributesNamespaces();
+    
+    
+    /**
+     * Returns the custom info provided in the info tag.
+     * All the tags except the description are given.
+     * The key is the name of the tag, the value is its content.
+     * @return
+     */
+    Map/*<String,String>*/ getExtraInfo();
 }

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolveEngine.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolveEngine.java?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolveEngine.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolveEngine.java Tue Feb 19 11:18:43 2008
@@ -171,8 +171,7 @@
     }
 
     /**
-     * Resolve dependencies of a module described by an ivy file. Note: the method signature is way
-     * too long, we should use a class to store the settings of the resolve.
+     * Resolve dependencies of a module described by an ivy file.
      */
     public ResolveReport resolve(URL ivySource, ResolveOptions options) throws ParseException,
             IOException {

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/AbstractModuleDescriptorParser.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/AbstractModuleDescriptorParser.java?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/AbstractModuleDescriptorParser.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/AbstractModuleDescriptorParser.java Tue Feb 19 11:18:43 2008
@@ -35,6 +35,7 @@
 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
 import org.apache.ivy.core.module.id.ModuleRevisionId;
 import org.apache.ivy.plugins.repository.Resource;
+import org.apache.ivy.plugins.repository.ResourceHelper;
 import org.apache.ivy.plugins.repository.url.URLResource;
 import org.apache.ivy.util.Message;
 import org.xml.sax.SAXException;
@@ -92,7 +93,7 @@
         protected void setResource(Resource res) {
             this.res = res; // used for log and date only
             md = new DefaultModuleDescriptor(parser, res);
-            md.setLastModified(getLastModified());
+            md.setLastModified(ResourceHelper.getLastModifiedOrDefault(res));
         }
 
         protected Resource getResource() {
@@ -346,22 +347,12 @@
             return new Date(md.getLastModified());
         }
 
-        protected long getLastModified() {
-            long last = getResource().getLastModified();
-            if (last > 0) {
-                return last;
-            } else {
-                Message.debug("impossible to get date for " + getResource() + ": using 'now'");
-                return System.currentTimeMillis();
-            }
-        }
-
         private void replaceConfigurationWildcards(ModuleDescriptor md) {
             Configuration[] configs = md.getConfigurations();
             for (int i = 0; i < configs.length; i++) {
                 configs[i].replaceWildcards(md);
             }
         }
-
     }
+
 }

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java?rev=629194&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java Tue Feb 19 11:18:43 2008
@@ -0,0 +1,276 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ivy.plugins.parser.m2;
+
+import java.text.ParseException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.ivy.Ivy;
+import org.apache.ivy.core.module.descriptor.Configuration;
+import org.apache.ivy.core.module.descriptor.DefaultArtifact;
+import org.apache.ivy.core.module.descriptor.DefaultDependencyArtifactDescriptor;
+import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
+import org.apache.ivy.core.module.descriptor.DefaultExcludeRule;
+import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
+import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
+import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
+import org.apache.ivy.core.module.descriptor.Configuration.Visibility;
+import org.apache.ivy.core.module.id.ArtifactId;
+import org.apache.ivy.core.module.id.ModuleId;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.plugins.matcher.ExactPatternMatcher;
+import org.apache.ivy.plugins.matcher.PatternMatcher;
+import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
+import org.apache.ivy.plugins.parser.m2.PomReader.PomDependencyData;
+import org.apache.ivy.plugins.parser.m2.PomReader.PomDependencyMgt;
+import org.apache.ivy.plugins.repository.Resource;
+
+
+/**
+ * Build a module descriptor.  This class handle the complexity of the structure of an ivy 
+ * ModuleDescriptor and isolate the PomModuleDescriptorParser from it. 
+ */
+public class PomModuleDescriptorBuilder {
+
+    
+    public static final Configuration[] MAVEN2_CONFIGURATIONS = new Configuration[] {
+        new Configuration("default", Visibility.PUBLIC,
+                "runtime dependencies and master artifact can be used with this conf",
+                new String[] {"runtime", "master"}, true, null),
+        new Configuration("master", Visibility.PUBLIC,
+                "contains only the artifact published by this module itself, "
+                + "with no transitive dependencies",
+                new String[0], true, null),
+        new Configuration("compile", Visibility.PUBLIC,
+                "this is the default scope, used if none is specified. "
+                + "Compile dependencies are available in all classpaths.",
+                new String[0], true, null),
+        new Configuration("provided", Visibility.PUBLIC,
+                "this is much like compile, but indicates you expect the JDK or a container "
+                + "to provide it. "
+                + "It is only available on the compilation classpath, and is not transitive.",
+                new String[0], true, null),
+        new Configuration("runtime", Visibility.PUBLIC,
+                "this scope indicates that the dependency is not required for compilation, "
+                + "but is for execution. It is in the runtime and test classpaths, "
+                + "but not the compile classpath.",
+                new String[] {"compile"}, true, null),
+        new Configuration("test", Visibility.PRIVATE,
+                "this scope indicates that the dependency is not required for normal use of "
+                + "the application, and is only available for the test compilation and "
+                + "execution phases.",
+                new String[] {"runtime"}, true, null),
+        new Configuration("system", Visibility.PUBLIC,
+                "this scope is similar to provided except that you have to provide the JAR "
+                + "which contains it explicitly. The artifact is always available and is not "
+                + "looked up in a repository.",
+                new String[0], true, null),
+        new Configuration("optional", Visibility.PUBLIC, 
+                "contains all optional dependencies", new String[0], true, null)
+                };
+
+    static final Map MAVEN2_CONF_MAPPING = new HashMap();
+
+    private static final String DEPENDENCY_MANAGEMENT = "m:dependency.management";        
+    private static final String DEPENDENCY_MANAGEMENT_DELIMITER = "__";
+
+    
+    static interface ConfMapper {
+        public void addMappingConfs(DefaultDependencyDescriptor dd, boolean isOptional);
+    }
+    
+    static {
+        MAVEN2_CONF_MAPPING.put("compile", new ConfMapper() {
+            public void addMappingConfs(DefaultDependencyDescriptor dd, boolean isOptional) {
+                if (isOptional) {
+                    dd.addDependencyConfiguration("optional", "compile(*)");
+                    //dd.addDependencyConfiguration("optional", "provided(*)");
+                    dd.addDependencyConfiguration("optional", "master(*)");
+                    
+                } else {
+                    dd.addDependencyConfiguration("compile", "compile(*)");
+                    //dd.addDependencyConfiguration("compile", "provided(*)");
+                    dd.addDependencyConfiguration("compile", "master(*)");
+                    dd.addDependencyConfiguration("runtime", "runtime(*)");
+                }
+            }
+        });
+        MAVEN2_CONF_MAPPING.put("provided", new ConfMapper() {
+            public void addMappingConfs(DefaultDependencyDescriptor dd, boolean isOptional) {
+                if (isOptional) {
+                    dd.addDependencyConfiguration("optional", "compile(*)");
+                    dd.addDependencyConfiguration("optional", "provided(*)");
+                    dd.addDependencyConfiguration("optional", "runtime(*)");
+                    dd.addDependencyConfiguration("optional", "master(*)");                    
+                } else {
+                    dd.addDependencyConfiguration("provided", "compile(*)");
+                    dd.addDependencyConfiguration("provided", "provided(*)");
+                    dd.addDependencyConfiguration("provided", "runtime(*)");
+                    dd.addDependencyConfiguration("provided", "master(*)");
+                }
+            }
+        });
+        MAVEN2_CONF_MAPPING.put("runtime", new ConfMapper() {
+            public void addMappingConfs(DefaultDependencyDescriptor dd, boolean isOptional) {
+                if (isOptional) {
+                    dd.addDependencyConfiguration("optional", "compile(*)");
+                    dd.addDependencyConfiguration("optional", "provided(*)");
+                    dd.addDependencyConfiguration("optional", "master(*)");
+                    
+                } else {
+                    dd.addDependencyConfiguration("runtime", "compile(*)");
+                    dd.addDependencyConfiguration("runtime", "runtime(*)");
+                    dd.addDependencyConfiguration("runtime", "master(*)");
+                }
+            }
+        });
+        MAVEN2_CONF_MAPPING.put("test", new ConfMapper() {
+            public void addMappingConfs(DefaultDependencyDescriptor dd, boolean isOptional) {
+                //optional/test doesn't make sense
+                dd.addDependencyConfiguration("runtime", "compile(*)");
+                dd.addDependencyConfiguration("runtime", "runtime(*)");
+                dd.addDependencyConfiguration("runtime", "master(*)");
+            }
+        });
+        MAVEN2_CONF_MAPPING.put("system", new ConfMapper() {
+            public void addMappingConfs(DefaultDependencyDescriptor dd, boolean isOptional) {
+                //optional/system doesn't make sense
+                dd.addDependencyConfiguration("system", "master(*)");
+            }
+        });
+    }
+
+    
+    
+    private final DefaultModuleDescriptor ivyModuleDescriptor;
+
+
+    private ModuleRevisionId mrid;
+
+    
+    public PomModuleDescriptorBuilder(ModuleDescriptorParser parser, Resource res) {
+        ivyModuleDescriptor = new DefaultModuleDescriptor(parser, res);
+        ivyModuleDescriptor.setResolvedPublicationDate(new Date(res.getLastModified()));
+        for (int i = 0; i < MAVEN2_CONFIGURATIONS.length; i++) {
+            ivyModuleDescriptor.addConfiguration(MAVEN2_CONFIGURATIONS[i]);
+        }
+        ivyModuleDescriptor.setMappingOverride(true);
+        ivyModuleDescriptor.addExtraAttributeNamespace("m", Ivy.getIvyHomeURL() + "maven");
+    }
+
+
+    public ModuleDescriptor getModuleDescriptor() {
+        return ivyModuleDescriptor;
+    }
+
+
+    public void setModuleRevId(String groupId, String artifactId, String version) {
+        mrid = ModuleRevisionId.newInstance(groupId, artifactId, version);
+        ivyModuleDescriptor.setModuleRevisionId(mrid);
+     }
+
+
+    public void addArtifact(String artifactId, String packaging) {
+        ivyModuleDescriptor.addArtifact("master", 
+                new DefaultArtifact(mrid, new Date(), artifactId, packaging, packaging));
+    }
+
+
+    public void addDependency(Resource res, PomDependencyData dep) throws ParseException {
+        if (!MAVEN2_CONF_MAPPING.containsKey(dep.getScope())) {
+            String msg = "Unknown scope " + dep.getScope() + " for dependency "
+                    + ModuleId.newInstance(dep.getGroupId(), dep.getArtifaceId()) + " in "
+                    + res.getName();
+            throw new ParseException(msg, 0);
+        }
+        
+        String version = dep.getVersion();
+        version = (version == null || version.length() == 0) ? getDefaultVersion(dep) : version;
+        ModuleRevisionId moduleRevId = ModuleRevisionId.newInstance(dep.getGroupId(), dep
+                .getArtifaceId(), version);
+        DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(ivyModuleDescriptor,
+                moduleRevId, true, false, true);
+        ConfMapper mapping = (ConfMapper) MAVEN2_CONF_MAPPING.get(dep.getScope());
+        mapping.addMappingConfs(dd, dep.isOptional());
+        Map extraAtt = new HashMap();
+        if (dep.getClassifier() != null) {
+            // we deal with classifiers by setting an extra attribute and forcing the
+            // dependency to assume such an artifact is published
+            extraAtt.put("m:classifier", dep.getClassifier());
+            DefaultDependencyArtifactDescriptor depArtifact = 
+                    new DefaultDependencyArtifactDescriptor(dd.getDependencyId().getName(),
+                        "jar", "jar", null, extraAtt);
+            // here we have to assume a type and ext for the artifact, so this is a limitation
+            // compared to how m2 behave with classifiers
+            String optionalizedScope = dep.isOptional() ? "optional" : dep.getScope();
+            dd.addDependencyArtifact(optionalizedScope, depArtifact);
+        }
+        
+        for (Iterator itExcl = dep.getExcludedModules().iterator(); itExcl.hasNext();) {
+            ModuleId excludedModule = (ModuleId) itExcl.next();
+            String[] confs = dd.getModuleConfigurations();
+            for (int k = 0; k < confs.length; k++) {
+                dd.addExcludeRule(confs[k], new DefaultExcludeRule(new ArtifactId(
+                    excludedModule, PatternMatcher.ANY_EXPRESSION,
+                                PatternMatcher.ANY_EXPRESSION,
+                                PatternMatcher.ANY_EXPRESSION),
+                                ExactPatternMatcher.INSTANCE, null));
+            }
+        }
+    
+        ivyModuleDescriptor.addDependency(dd);
+    }
+
+
+    public void addDependency(DependencyDescriptor descriptor) {
+        ivyModuleDescriptor.addDependency(descriptor);
+    }
+
+
+    public void addDependencyMgt(PomDependencyMgt dep) {
+        String key = getDependencyMgtExtraDataKey(dep.getGroupId(), dep.getArtifaceId());
+        ivyModuleDescriptor.addExtraInfo(key, dep.getVersion());
+    }
+
+    private String getDefaultVersion(PomDependencyData dep) {
+        String key = getDependencyMgtExtraDataKey(dep.getGroupId(), dep.getArtifaceId());        
+        return (String) ivyModuleDescriptor.getExtraInfo().get(key);
+    }
+
+
+    public static String getDependencyMgtExtraDataKey(String groupId, String artifaceId) {
+        return DEPENDENCY_MANAGEMENT + DEPENDENCY_MANAGEMENT_DELIMITER + groupId
+                + DEPENDENCY_MANAGEMENT_DELIMITER + artifaceId;
+    }
+
+
+    public void addExtraDescription(Map extraAttributes) {
+        for (Iterator it = extraAttributes.entrySet().iterator(); it.hasNext();) {
+            Map.Entry entry =  (Entry) it.next();
+            if (!ivyModuleDescriptor.getExtraInfo().containsKey(entry.getKey())) {
+                ivyModuleDescriptor.addExtraInfo((String)entry.getKey(), (String)entry.getValue());
+            }
+        }
+    }
+
+    
+}

Propchange: ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java Tue Feb 19 11:18:43 2008
@@ -22,48 +22,27 @@
 import java.io.InputStream;
 import java.net.URL;
 import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
 
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.ivy.Ivy;
 import org.apache.ivy.core.IvyContext;
-import org.apache.ivy.core.IvyPatternHelper;
 import org.apache.ivy.core.module.descriptor.Artifact;
-import org.apache.ivy.core.module.descriptor.Configuration;
 import org.apache.ivy.core.module.descriptor.DefaultArtifact;
-import org.apache.ivy.core.module.descriptor.DefaultDependencyArtifactDescriptor;
 import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
-import org.apache.ivy.core.module.descriptor.DefaultExcludeRule;
 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
-import org.apache.ivy.core.module.descriptor.Configuration.Visibility;
-import org.apache.ivy.core.module.id.ArtifactId;
-import org.apache.ivy.core.module.id.ModuleId;
 import org.apache.ivy.core.module.id.ModuleRevisionId;
 import org.apache.ivy.core.resolve.ResolveData;
 import org.apache.ivy.core.resolve.ResolveEngine;
 import org.apache.ivy.core.resolve.ResolveOptions;
-import org.apache.ivy.plugins.matcher.ExactPatternMatcher;
-import org.apache.ivy.plugins.matcher.PatternMatcher;
-import org.apache.ivy.plugins.parser.AbstractModuleDescriptorParser;
+import org.apache.ivy.core.resolve.ResolvedModuleRevision;
 import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
 import org.apache.ivy.plugins.parser.ParserSettings;
 import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
 import org.apache.ivy.plugins.repository.Resource;
+import org.apache.ivy.plugins.repository.url.URLResource;
 import org.apache.ivy.plugins.resolver.DependencyResolver;
-import org.apache.ivy.plugins.resolver.util.ResolvedResource;
 import org.apache.ivy.util.Message;
-import org.apache.ivy.util.XMLHelper;
-import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 
 /**
@@ -72,526 +51,12 @@
  * The configurations used in the generated module descriptor mimics the behavior defined by maven 2
  * scopes, as documented here:<br/>
  * http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
- * 
+ * The PomModuleDescriptorParser use a PomDomReader to read the pom, and the 
+ * PomModuleDescriptorBuilder to write the ivy module descriptor using the info read by the 
+ * PomDomReader.  
  */
-public final class PomModuleDescriptorParser extends AbstractModuleDescriptorParser {
-    public static final Configuration[] MAVEN2_CONFIGURATIONS = new Configuration[] {
-            new Configuration("default", Visibility.PUBLIC,
-                    "runtime dependencies and master artifact can be used with this conf",
-                    new String[] {"runtime", "master"}, true, null),
-            new Configuration(
-                    "master",
-                    Visibility.PUBLIC,
-                    "contains only the artifact published by this module itself, "
-                    + "with no transitive dependencies",
-                    new String[0], true, null),
-            new Configuration(
-                    "compile",
-                    Visibility.PUBLIC,
-                    "this is the default scope, used if none is specified. "
-                    + "Compile dependencies are available in all classpaths.",
-                    new String[0], true, null),
-            new Configuration(
-                    "provided",
-                    Visibility.PUBLIC,
-                    "this is much like compile, but indicates you expect the JDK or a container "
-                    + "to provide it. "
-                    + "It is only available on the compilation classpath, and is not transitive.",
-                    new String[0], true, null),
-            new Configuration(
-                    "runtime",
-                    Visibility.PUBLIC,
-                    "this scope indicates that the dependency is not required for compilation, "
-                    + "but is for execution. It is in the runtime and test classpaths, "
-                    + "but not the compile classpath.",
-                    new String[] {"compile"}, true, null),
-            new Configuration(
-                    "test",
-                    Visibility.PRIVATE,
-                    "this scope indicates that the dependency is not required for normal use of "
-                    + "the application, and is only available for the test compilation and "
-                    + "execution phases.",
-                    new String[] {"runtime"}, true, null),
-            new Configuration(
-                    "system",
-                    Visibility.PUBLIC,
-                    "this scope is similar to provided except that you have to provide the JAR "
-                    + "which contains it explicitly. The artifact is always available and is not "
-                    + "looked up in a repository.",
-                    new String[0], true, null),
-                    };
-
-    private static final Configuration OPTIONAL_CONFIGURATION = new Configuration("optional",
-            Visibility.PUBLIC, "contains all optional dependencies", new String[0], true, null);
-
-    private static final Map MAVEN2_CONF_MAPPING = new HashMap();
-
-    static {
-        MAVEN2_CONF_MAPPING.put("compile", "compile->@(*),master(*);runtime->@(*)");
-        MAVEN2_CONF_MAPPING
-                .put("provided", "provided->compile(*),provided(*),runtime(*),master(*)");
-        MAVEN2_CONF_MAPPING.put("runtime", "runtime->compile(*),runtime(*),master(*)");
-        MAVEN2_CONF_MAPPING.put("test", "test->compile(*),runtime(*),master(*)");
-        MAVEN2_CONF_MAPPING.put("system", "system->master(*)");
-    }
-
-    private static final class Parser extends AbstractParser {
-        private static final String JAR_EXTENSION = "jar";
-        
-        private static final String DEPENDENCY_MANAGEMENT = "dependency.management";
-        
-        private static final String DEPENDENCY_MANAGEMENT_DELIMITER = "__";
-        
-        private ParserSettings settings;
-
-        private Stack contextStack = new Stack();
-
-        private String organisation;
-        
-        private String module;
-
-        private String revision;
-
-        private String scope;
-
-        private String classifier;
-
-        private String type;
-
-        private String ext;
-
-        private boolean optional = false;
-
-        private List exclusions = new ArrayList();
-
-        private DefaultDependencyDescriptor dd;
-
-        private Map properties = new HashMap();
-        
-        private StringBuffer buffer = new StringBuffer();
-
-        private String relocationOrganisation = null;
-        
-        private String relocationModule;
-
-        private String relocationRevision;
-        
-        private String dmGroupId;
-        
-        private String dmArtifactId;
-        
-        private String dmVersion;
-
-
-        public Parser(ModuleDescriptorParser parser, Resource res, ParserSettings settings) {
-            super(parser);
-            setResource(res);
-            this.settings = settings;
-            md.setResolvedPublicationDate(new Date(res.getLastModified()));
-            for (int i = 0; i < MAVEN2_CONFIGURATIONS.length; i++) {
-                md.addConfiguration(MAVEN2_CONFIGURATIONS[i]);
-            }
-        }
-
-        public void startElement(String uri, String localName, String qName, Attributes attributes)
-                throws SAXException {
-            contextStack.push(qName);
-            String context = getContext();
-            if ("optional".equals(qName)) {
-                optional = true;
-            } else if ("project/dependencies/dependency/exclusions".equals(context)) {
-                if (dd == null) {
-                    // stores dd now cause exclusions will override org and module
-                    dd = new DefaultDependencyDescriptor(md, ModuleRevisionId.newInstance(
-                        organisation, module, revision), true, false, true);
-                    organisation = null;
-                    module = null;
-                    revision = null;
-                }
-            } else if (md.getModuleRevisionId() == null) {
-                if ("project/dependencies".equals(context) || "project/profiles".equals(context)
-                        || "project/build".equals(context)) {
-                    fillMrid();
-                }
-            }
-        }
-
-        private void fillMrid() throws SAXException {
-            if (organisation == null) {
-                throw new SAXException("no groupId found in pom");
-            }
-            if (module == null) {
-                throw new SAXException("no artifactId found in pom");
-            }
-            if (revision == null) {
-                revision = "SNAPSHOT";
-            }
-            ModuleRevisionId mrid = ModuleRevisionId.newInstance(organisation, module, revision);
-            properties.put("project.groupId", organisation);
-            properties.put("pom.groupId", organisation);
-            properties.put("project.artifactId", module);
-            properties.put("pom.artifactId", module);
-            properties.put("project.version", revision);
-            properties.put("pom.version", revision);
-            properties.put("version", revision);
-            md.setModuleRevisionId(mrid);
-            if (type == null) {
-                type = JAR_EXTENSION;
-                ext = JAR_EXTENSION;
-            }
-            md.setModuleArtifact(
-                DefaultArtifact.newPomArtifact(mrid, getDefaultPubDate()));
-            md.addArtifact("master", 
-                new DefaultArtifact(mrid, getDefaultPubDate(), module, type, ext));
-            organisation = null;
-            module = null;
-            revision = null;
-        }
+public final class PomModuleDescriptorParser implements ModuleDescriptorParser {
 
-        public void endElement(String uri, String localName, String qName) throws SAXException {
-            processTextContent();
-            
-            String context = getContext();
-            if (md.getModuleRevisionId() == null && ("project".equals(context))) {
-                fillMrid();
-            } else if ("project/parent/version".equals(context)) {
-                properties.put("parent.version", revision);
-            } else if ("project/parent/groupId".equals(context)) {
-                properties.put("parent.groupId", organisation);
-            } else if (context.equals("project/parent")) {
-                parseParentPom();
-            } else if (((organisation != null && module != null) || dd != null)
-                    && "project/dependencies/dependency".equals(context)) {
-                if (revision == null) {
-                    // if the revision is null, see if we can get it from the dependency management
-                    String key = DEPENDENCY_MANAGEMENT + DEPENDENCY_MANAGEMENT_DELIMITER 
-                        + organisation + DEPENDENCY_MANAGEMENT_DELIMITER + module;
-                    revision = (String) properties.get(key);
-                }
-                if (dd == null) {
-                    // if we still don't have revision, then we are done.
-                    if (revision == null) {
-                        return;
-                    }
-                    dd = new DefaultDependencyDescriptor(md, ModuleRevisionId.newInstance(
-                        organisation, module, revision), true, false, true);
-                }
-                scope = scope == null ? "compile" : scope;
-                if (optional && "compile".equals(scope)) {
-                    scope = "runtime";
-                }
-                String mapping = (String) MAVEN2_CONF_MAPPING.get(scope);
-                if (mapping == null) {
-                    Message.verbose("unknown scope " + scope + " in " + getResource());
-                    mapping = (String) MAVEN2_CONF_MAPPING.get("compile");
-                }
-                if (optional) {
-                    mapping = mapping.replaceAll(scope + "\\-\\>", "optional->");
-                    if (md.getConfiguration("optional") == null) {
-                        md.addConfiguration(OPTIONAL_CONFIGURATION);
-                    }
-                }
-                parseDepsConfs(mapping, dd);
-
-                if (classifier != null) {
-                    // we deal with classifiers by setting an extra attribute and forcing the
-                    // dependency to assume such an artifact is published
-                    
-                    // declare the extra attribute namespace if not declared yet
-                    if (!md.getExtraAttributesNamespaces().containsKey("m")) {
-                        md.addExtraAttributeNamespace("m", Ivy.getIvyHomeURL() + "maven");
-                    }
-                    Map extraAtt = Collections.singletonMap("m:classifier", classifier);
-                    
-                    String[] confs = dd.getModuleConfigurations();
-                    for (int i = 0; i < confs.length; i++) {
-                        dd.addDependencyArtifact(confs[i],
-                            new DefaultDependencyArtifactDescriptor(
-                                    dd.getDependencyId().getName(), JAR_EXTENSION, JAR_EXTENSION, 
-                                    /*
-                                     * here we have to assume a type and ext for the artifact, so
-                                     * this is a limitation compared to how m2 behave with
-                                     * classifiers
-                                     */
-                                    null, extraAtt));
-                    }
-                }
-                for (Iterator iter = exclusions.iterator(); iter.hasNext();) {
-                    ModuleId mid = (ModuleId) iter.next();
-                    String[] confs = dd.getModuleConfigurations();
-                    for (int i = 0; i < confs.length; i++) {
-                        dd
-                                .addExcludeRule(confs[i], new DefaultExcludeRule(new ArtifactId(
-                                        mid, PatternMatcher.ANY_EXPRESSION,
-                                        PatternMatcher.ANY_EXPRESSION,
-                                        PatternMatcher.ANY_EXPRESSION),
-                                        ExactPatternMatcher.INSTANCE, null));
-                    }
-                }
-                md.addDependency(dd);
-                dd = null;
-            } else if ((organisation != null && module != null)
-                   && "project/dependencies/dependency/exclusions/exclusion".equals(context)) {
-                exclusions.add(new ModuleId(organisation, module));
-                organisation = null;
-                module = null;
-            } else if ("project/distributionManagement/relocation".equals(context)) {
-                if (relocationOrganisation == null) {
-                    relocationOrganisation = organisation;
-                }
-                if (relocationModule == null) {
-                    relocationModule = module;
-                }
-                if (relocationRevision == null) {
-                    relocationRevision = revision;
-                }
-                ModuleRevisionId myModuleRev = ModuleRevisionId.newInstance(
-                    organisation, module, revision);
-                ModuleRevisionId relocationeModuleRev = ModuleRevisionId.newInstance(
-                    relocationOrganisation, relocationModule, relocationRevision);
-                md.setModuleRevisionId(myModuleRev);
-                if (relocationOrganisation.equals(organisation) 
-                        && relocationModule.equals(module)) {                    
-                    Message.error("Relocation to an other version number not supported in ivy : "
-                        + myModuleRev + " relocated to " + relocationModule 
-                        + ". Please update your dependency to directly use the right version.");
-                    Message.warn("Resolution will only pick dependencies of the relocated element." 
-                        + "  Artefact and other metadata will be ignored.");
-                    Parser relocationParser = parserOtherPom(relocationeModuleRev);
-                    if (relocationParser == null) {
-                        throw new SAXException("Relocation can not be found : " + relocationModule);
-                    }
-                    DependencyDescriptor[] dependencies = relocationParser.md.getDependencies();
-                    for (int i = 0; i < dependencies.length; i++) {
-                        md.addDependency(dependencies[i]);
-                    }                    
-                } else {
-                    Message.info(myModuleRev.toString() + " is relocated to " 
-                        + relocationeModuleRev + ". Please update your dependencies.");
-                    Message.verbose("Relocated module will be considered as a dependency");
-                    dd = new DefaultDependencyDescriptor(md, relocationeModuleRev,
-                        true, false, true);
-                    /*Map all public dependencies */
-                    dd.addDependencyConfiguration("compile","compile");
-                    dd.addDependencyConfiguration("runtime","runtime");
-                    dd.addDependencyConfiguration("default","default");
-                    dd.addDependencyConfiguration("master","master");
-                    dd.addDependencyConfiguration("provided","provided");
-                    dd.addDependencyConfiguration("system","system");
-                    md.addDependency(dd);
-                    dd = null;
-                }
-            } else if ("project/dependencyManagement/dependencies/dependency".equals(context)) {
-                if (dmGroupId != null && dmArtifactId != null && dmVersion != null) {
-                   // Note: we can't use substitute pattern, fillMrid has not been called yet.
-                   String key = DEPENDENCY_MANAGEMENT + DEPENDENCY_MANAGEMENT_DELIMITER 
-                       + dmGroupId + DEPENDENCY_MANAGEMENT_DELIMITER + dmArtifactId;
-                   properties.put(key, dmVersion);
-                }
-            }
-            if ("project/dependencies/dependency".equals(context)) {
-                organisation = null;
-                module = null;
-                revision = null;
-                scope = null;
-                classifier = null;
-                optional = false;
-                exclusions.clear();
-            }
-            contextStack.pop();
-        }
-
-        private void processTextContent() {
-            if (buffer != null) {
-                String txt = IvyPatternHelper.substituteVariables(buffer.toString(), 
-                        properties).trim();
-                buffer = null;
-                
-                if (txt.length() == 0) {
-                    return;
-                }
-                
-                String context = getContext();
-                if (context.equals("project/parent/groupId") && organisation == null) {
-                    organisation = txt;
-                    return;
-                }
-                if (context.equals("project/parent/version") && revision == null) {
-                    revision = txt;
-                    return;
-                } 
-                if (context.equals("project/parent/artifactId")) {
-                    properties.put("parent.artifactId", txt);
-                }
-                if (context.equals("project/parent/packaging") && type == null) {
-                    type = txt;
-                    ext = txt;
-                    return;
-                }
-                if (context.equals("project/distributionManagement/relocation/groupId")) {
-                    relocationOrganisation = txt;
-                    return;
-                }
-                if (context.equals("project/distributionManagement/relocation/artifactId")) {
-                    relocationModule = txt;
-                    return;
-                }
-                if (context.equals("project/distributionManagement/relocation/version")) {
-                    relocationRevision = txt;
-                    return;
-                }
-                if (context.startsWith("project/parent")) {
-                    return;
-                } 
-                if (context.equals(
-                    "project/dependencyManagement/dependencies/dependency/groupId")) {
-                    dmGroupId = txt;
-                    return;
-                }
-                if (context.equals(
-                    "project/dependencyManagement/dependencies/dependency/artifactId")) {
-                    dmArtifactId = txt;
-                    return;
-                }
-                if (context.equals(
-                    "project/dependencyManagement/dependencies/dependency/version")) {
-                    dmVersion = txt;
-                   return;
-                }
-                if (context.startsWith("project/properties")) {
-                    String key = context.substring("project/properties/".length());
-                    properties.put(key, txt);
-                }
-                if (md.getModuleRevisionId() == null
-                        || context.startsWith("project/dependencies/dependency")) {
-                    if (context.equals("project/groupId")) {
-                        organisation = txt;
-                    } else if (organisation == null && context.endsWith("groupId")) {
-                        organisation = txt;
-                    } else if (module == null && context.endsWith("artifactId")) {
-                        module = txt;
-                    } else if (context.equals("project/version")
-                            || (revision == null && context.endsWith("version"))) {
-                        revision = txt;
-                    } else if (revision == null && context.endsWith("version")) {
-                        revision = txt;
-                    } else if (type == null && context.endsWith("packaging")) {
-                        type = txt;
-                        ext = txt;
-                    } else if (scope == null && context.endsWith("scope")) {
-                        scope = txt;
-                    } else if (classifier == null && context.endsWith("dependency/classifier")) {
-                        classifier = txt;
-                    }
-                }
-            }
-        }
-
-        public void characters(char[] ch, int start, int length) throws SAXException {
-            if (buffer == null) {
-                buffer = new StringBuffer();
-            }
-            buffer.append(ch, start, length);
-        }
-
-        private String getContext() {
-            StringBuffer buf = new StringBuffer();
-            for (Iterator iter = contextStack.iterator(); iter.hasNext();) {
-                String ctx = (String) iter.next();
-                buf.append(ctx).append("/");
-            }
-            if (buf.length() > 0) {
-                buf.setLength(buf.length() - 1);
-            }
-            return buf.toString();
-        }
-
-        public ModuleDescriptor getDescriptor() {
-            return md;
-        }
-        
-        public void parseParentPom() throws SAXException {
-            String parentOrg = (String) properties.get("parent.groupId");
-            String parentName = (String) properties.get("parent.artifactId");
-            String parentVersion = (String) properties.get("parent.version");
-            
-            if (parentOrg != null && parentName != null && parentVersion != null) {
-                ModuleRevisionId parent = ModuleRevisionId.newInstance(parentOrg, parentName, 
-                                           parentVersion);
-                Parser parser = parserOtherPom(parent);
-                if (parser == null) {
-                    //see comments in parserOtherPom for case where parser==nul 
-                    return;
-                }
-                
-                // move the parent properties into ours
-                Map parentProps = parser.properties;
-                Set keys = parentProps.keySet();
-                for (Iterator iter = keys.iterator(); iter.hasNext();) {
-                    String key = iter.next().toString();
-                    if (key.startsWith("pom")) {
-                        // don't see a need to copy pom values from parent...
-                        // ignore
-                    } else if (key.startsWith("parent")) {
-                        // don't see a need to copy parent values from parent...
-                        // ignore
-                    } else {
-                        // the key may need the groupId substituted
-                        String fullKey = IvyPatternHelper.substituteVariables(key, 
-                                parentProps).trim();
-                        String fullValue = IvyPatternHelper.substituteVariables(
-                                parentProps.get(key).toString(), parentProps).trim();
-                        properties.put(fullKey, fullValue);
-                    }
-                }
-
-            }
-        }
-
-        private Parser parserOtherPom(ModuleRevisionId other) throws SAXException {
-            DependencyResolver resolver = settings.getResolver(other);
-            if (resolver == null) {
-                // TODO: Maybe log warning or throw exception here?
-                return null;
-            }
-            
-            DependencyDescriptor dd = new DefaultDependencyDescriptor(other, true);
-            ResolveData data = IvyContext.getContext().getResolveData();
-            if (data == null) {
-                ResolveEngine engine = IvyContext.getContext().getIvy().getResolveEngine();
-                ResolveOptions options = new ResolveOptions();
-                options.setDownload(false);
-                data = new ResolveData(engine, options);
-            }
-            
-            ResolvedResource rr = resolver.findIvyFileRef(dd, data);
-            
-            if (rr == null) {
-                // parent not found. Maybe we should throw an exception here?
-                return null;
-            }
-            
-            Parser parser = new Parser(getModuleDescriptorParser(), rr.getResource(), settings);
-            InputStream pomStream = null;
-            try {
-                pomStream = rr.getResource().openStream();
-                XMLHelper.parse(pomStream, null, parser, null);
-            } catch (IOException e) {
-                throw new SAXException("Error occurred while parsing parent", e);
-            } catch (ParserConfigurationException e) {
-                throw new SAXException("Error occurred while parsing parent", e);
-            } finally {
-                if (pomStream != null) {
-                    try {
-                        pomStream.close();
-                    } catch (IOException e) {
-                        // ignore
-                    }
-                }
-            }
-            return parser;
-        }
-    }
 
     private static final PomModuleDescriptorParser INSTANCE = new PomModuleDescriptorParser();
 
@@ -602,29 +67,6 @@
     private PomModuleDescriptorParser() {
     }
 
-    public ModuleDescriptor parseDescriptor(ParserSettings settings, URL descriptorURL, 
-            Resource res, boolean validate) throws ParseException, IOException {
-        Parser parser = new Parser(this, res, settings);
-        try {
-            XMLHelper.parse(descriptorURL, null, parser);
-        } catch (SAXException ex) {
-            ParseException pe = new ParseException(ex.getMessage() + " in " + descriptorURL, 0);
-            pe.initCause(ex);
-            throw pe;
-        } catch (ParserConfigurationException ex) {
-            IllegalStateException ise = new IllegalStateException(ex.getMessage() + " in "
-                    + descriptorURL);
-            ise.initCause(ex);
-            throw ise;
-        }
-        ModuleDescriptor md = parser.getDescriptor();
-        if (md.getModuleRevisionId() == null) {
-            throw new ParseException("invalid pom " + res 
-                + ": no module revision id found. "
-                + "Check that this pom has a groupId, artifactId and version.", 0);
-        }
-        return md;
-    }
 
     public void toIvyFile(InputStream is, Resource res, File destFile, ModuleDescriptor md)
             throws ParseException, IOException {
@@ -652,6 +94,134 @@
     
     public String getType() {
         return "pom";
+    }
+
+    public ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL descriptorURL, 
+            boolean validate) throws ParseException, IOException {        
+        URLResource resource = new URLResource(descriptorURL);
+        return parseDescriptor(ivySettings, descriptorURL, resource, validate);
+    }
+
+    public ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL descriptorURL, 
+            Resource res, boolean validate) throws ParseException, IOException {
+        
+        PomModuleDescriptorBuilder mdBuilder = new PomModuleDescriptorBuilder(this, res);
+        
+        try {           
+            PomReader domReader = new PomReader(descriptorURL, res);
+            
+            domReader.setProperty("parent.version", domReader.getParentVersion());
+            
+            String groupId = domReader.getGroupId();
+            String artifactId = domReader.getArtifactId();
+            String version = domReader.getVersion();
+            mdBuilder.setModuleRevId(groupId , artifactId , version);
+
+            ModuleRevisionId relocation = domReader.getRelocation();
+            
+            if (relocation != null) {
+                if (groupId != null && artifactId != null
+                        && artifactId.equals(relocation.getName())
+                        && groupId.equals(relocation.getOrganisation())) {
+                    Message.error("Relocation to an other version number not supported in ivy : "
+                            + mdBuilder.getModuleDescriptor().getModuleRevisionId()
+                            + " relocated to " + relocation
+                            + ". Please update your dependency to directly use the right version.");
+                    Message.warn("Resolution will only pick dependencies of the relocated element."
+                            + "  Artefact and other metadata will be ignored.");
+                    ResolvedModuleRevision relocatedModule = parseOtherPom(ivySettings, relocation);
+                    DependencyDescriptor[] dds = relocatedModule.getDescriptor().getDependencies();
+                    for (int i = 0; i < dds.length; i++) {
+                        mdBuilder.addDependency(dds[i]);
+                    }
+                } else {
+                    Message.info(mdBuilder.getModuleDescriptor().getModuleRevisionId()
+                            + " is relocated to " + relocation
+                            + ". Please update your dependencies.");
+                    Message.verbose("Relocated module will be considered as a dependency");
+                    DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(mdBuilder
+                            .getModuleDescriptor(), relocation, true, false, true);
+                    /* Map all public dependencies */
+                    dd.addDependencyConfiguration("compile", "compile");
+                    dd.addDependencyConfiguration("runtime", "runtime");
+                    dd.addDependencyConfiguration("default", "default");
+                    dd.addDependencyConfiguration("master", "master");
+                    dd.addDependencyConfiguration("provided", "provided");
+                    dd.addDependencyConfiguration("system", "system");
+                    mdBuilder.addDependency(dd);
+                }
+            } else {                            
+                domReader.setProperty("project.groupId", groupId);
+                domReader.setProperty("pom.groupId", groupId);
+                domReader.setProperty("project.artifactId", artifactId);
+                domReader.setProperty("pom.artifactId", artifactId);
+                domReader.setProperty("project.version", version);
+                domReader.setProperty("pom.version", version);
+                domReader.setProperty("version", version);
+
+                if (domReader.hasParent()) {
+                    domReader.setProperty("parent.version", domReader.getParentVersion());
+                    //Is there any other parent properties?
+                }
+                
+                for (Iterator it = domReader.getDependencyMgt().iterator(); it.hasNext();) {
+                    PomReader.PomDependencyMgt dep = (PomReader.PomDependencyMgt) it.next();
+                    mdBuilder.addDependencyMgt(dep);
+                }
+                
+                if (domReader.hasParent()) {
+                    ModuleRevisionId parentModRevID = ModuleRevisionId.newInstance(
+                        domReader.getParentGroupId(), 
+                        domReader.getParentArtifactId(), 
+                        domReader.getParentVersion());
+                    ResolvedModuleRevision parentModule = parseOtherPom(ivySettings, 
+                        parentModRevID);
+                    ModuleDescriptor parentDescr = parentModule.getDescriptor();
+                    mdBuilder.addExtraDescription(parentDescr.getExtraInfo());
+                    for (int i = 0; i < parentDescr.getDependencies().length; i++) {
+                        mdBuilder.addDependency(parentDescr.getDependencies()[i]);
+                    }
+                }                
+                
+                for (Iterator it = domReader.getDependencies().iterator(); it.hasNext();) {
+                    PomReader.PomDependencyData dep = (PomReader.PomDependencyData) it.next();
+                    mdBuilder.addDependency(res, dep);
+                }
+                mdBuilder.addArtifact(artifactId , domReader.getPackaging());
+            }            
+        } catch (SAXException e) {
+            throw newParserException(e);
+        }
+        
+        return mdBuilder.getModuleDescriptor();
+    }
+
+    private ResolvedModuleRevision parseOtherPom(ParserSettings ivySettings,
+            ModuleRevisionId parentModRevID) throws ParseException {
+        DependencyDescriptor dd = new DefaultDependencyDescriptor(parentModRevID, true);
+        ResolveData data = IvyContext.getContext().getResolveData();
+        if (data == null) {
+            ResolveEngine engine = IvyContext.getContext().getIvy().getResolveEngine();
+            ResolveOptions options = new ResolveOptions();
+            options.setDownload(false);
+            data = new ResolveData(engine, options);
+        }
+        
+        DependencyResolver resolver = ivySettings.getResolver(parentModRevID);
+        if (resolver == null) {
+            // TODO: Throw exception here?
+            return null;
+        } else {
+            ResolvedModuleRevision otherModule = resolver.getDependency(dd, data);
+            return otherModule;
+        }
+    }
+
+    private ParseException newParserException(Exception e) {
+        Message.error(e.getMessage());
+        ParseException pe = new ParseException(e.getMessage() , 0);
+        pe.initCause(e);
+        return pe;
     }
 
 }

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomReader.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomReader.java?rev=629194&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomReader.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomReader.java Tue Feb 19 11:18:43 2008
@@ -0,0 +1,322 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ivy.plugins.parser.m2;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.LinkedList;
+
+import org.apache.ivy.core.IvyPatternHelper;
+import org.apache.ivy.core.module.id.ModuleId;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.plugins.repository.Resource;
+import org.apache.ivy.util.XMLHelper;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+
+
+/**
+ * Provides the method to read some data out of the DOM tree of a pom 
+ * file.
+ */
+public class PomReader {
+    
+    private static final String PACKAGING = "packaging";
+    private static final String DEPENDENCY = "dependency";
+    private static final String DEPENDENCIES = "dependencies";
+    private static final String DEPENDENCY_MGT = "dependencyManagement";
+    private static final String PROJECT = "project";
+    private static final String GROUP_ID = "groupId";
+    private static final String ARTIFACT_ID = "artifactId";
+    private static final String VERSION = "version";
+    private static final String PARENT = "parent";
+    private static final String SCOPE = "scope";
+    private static final String CLASSIFIER = "classifier";
+    private static final String OPTIONAL = "optional";
+    private static final String EXCLUSIONS = "exclusions";
+    private static final String EXCLUSION = "exclusion";
+    private static final String DISTRIBUTION_MGT = "distributionManagement";
+    private static final String RELOCATION = "relocation";
+    
+    
+    
+
+    private HashMap properties = new HashMap();
+    
+    private final Element projectElement;
+    private final Element parentElement;
+    
+    public PomReader(URL descriptorURL, Resource res) throws IOException, SAXException {
+        Document pomDomDoc = XMLHelper.parseToDom(descriptorURL, res);
+        projectElement = pomDomDoc.getDocumentElement();
+        if (!PROJECT.equals(projectElement.getNodeName())) {
+            throw new SAXParseException("project must be the root tag" , res.getName() , 
+                                        res.getName(), 0, 0);
+        }
+        parentElement = getFirstChildElement(projectElement , PARENT);
+        //TODO read the properties because it must be used to interpret every other field
+    }
+
+
+    public boolean hasParent() {
+        return parentElement != null;
+    }
+    
+    /**
+     * Add a property if not yet set and value is not null.
+     * This garantee that property keep the first value that is put on it and that the properties
+     * are never null.
+     */
+    public void setProperty(String prop, String val) {
+        if (!properties.containsKey(prop) && val != null) {
+            properties.put(prop, val);
+        }
+    }
+
+    
+    public String getGroupId() {
+        String groupId = getFirstChildText(projectElement , GROUP_ID);
+        if (groupId == null) {
+            groupId = getFirstChildText(parentElement, GROUP_ID);
+        } 
+        return replaceProps(groupId);
+
+    }
+
+    public String getParentGroupId() {
+        String groupId = getFirstChildText(parentElement , GROUP_ID);
+        if (groupId == null) {
+            groupId = getFirstChildText(projectElement, GROUP_ID);
+        }
+        return replaceProps(groupId);
+    }
+
+
+    
+    public String getArtifactId() {
+        String val = getFirstChildText(projectElement , ARTIFACT_ID);
+        if (val == null) {
+            val = getFirstChildText(parentElement, ARTIFACT_ID);
+        }
+        return replaceProps(val);
+    }
+
+    public String getParentArtifactId() {
+        String val = getFirstChildText(parentElement , ARTIFACT_ID);
+        if (val == null) {
+            val = getFirstChildText(projectElement, ARTIFACT_ID);
+        } 
+        return replaceProps(val);
+    }
+
+
+    public String getVersion() {
+        String val = getFirstChildText(projectElement , VERSION);
+        if (val == null) {
+            val = getFirstChildText(parentElement, VERSION);
+        } 
+        return replaceProps(val);
+    }
+
+    public String getParentVersion() {
+        String val = getFirstChildText(parentElement , VERSION);
+        if (val == null) {
+            val = getFirstChildText(projectElement, VERSION);
+        } 
+        return replaceProps(val);
+    }
+
+    
+    public String getPackaging() {
+        String val = getFirstChildText(projectElement , PACKAGING);
+        if (val == null) {
+            val = "jar";
+        }
+        return val;
+    }
+
+    
+    public ModuleRevisionId getRelocation() {
+        Element distrMgt = getFirstChildElement(projectElement, DISTRIBUTION_MGT);
+        Element relocation = getFirstChildElement(distrMgt , RELOCATION);
+        if (relocation == null) {
+            return null;
+        } else {
+            String relocGroupId = getFirstChildText(relocation, GROUP_ID);
+            String relocArtId = getFirstChildText(relocation, ARTIFACT_ID);
+            String relocVersion = getFirstChildText(relocation, VERSION);
+            relocGroupId = relocGroupId == null ? getGroupId() : relocGroupId;
+            relocArtId = relocArtId == null ? getArtifactId() : relocArtId;
+            relocVersion = relocVersion == null ? getVersion() : relocVersion;
+            return ModuleRevisionId.newInstance(relocGroupId, relocArtId, relocVersion);
+        }
+    }
+    
+    public Iterable/* <PomDependencyData> */ getDependencies() {
+        Element dependenciesElement = getFirstChildElement(projectElement, DEPENDENCIES);
+        LinkedList dependencies = new LinkedList();
+        if (dependenciesElement != null) {
+            NodeList childs = dependenciesElement.getChildNodes();
+            for (int i = 0; i < childs.getLength(); i++) {
+                Node node = childs.item(i);
+                if (node instanceof Element && DEPENDENCY.equals(node.getNodeName())) {
+                    dependencies.add(new PomDependencyData((Element) node));
+                }
+            }
+        }
+        return dependencies;
+    }
+    
+
+    public Iterable/* <PomDependencyMgt> */ getDependencyMgt() {
+        Element dependenciesElement = getFirstChildElement(projectElement, DEPENDENCY_MGT);
+        dependenciesElement = getFirstChildElement(dependenciesElement, DEPENDENCIES);
+        LinkedList dependencies = new LinkedList();
+        if (dependenciesElement != null) {
+            NodeList childs = dependenciesElement.getChildNodes();
+            for (int i = 0; i < childs.getLength(); i++) {
+                Node node = childs.item(i);
+                if (node instanceof Element && DEPENDENCY.equals(node.getNodeName())) {
+                    dependencies.add(new PomDependencyMgt((Element) node));
+                }
+            }
+        }
+        return dependencies;
+    }
+
+    
+    public class PomDependencyMgt {
+        private final Element depElement;
+        
+        PomDependencyMgt(Element depElement) {
+            this.depElement = depElement; 
+        }
+        
+        public String getGroupId() {
+            String val = getFirstChildText(depElement , GROUP_ID);
+            return replaceProps(val);
+        }
+
+        public String getArtifaceId() {
+            String val = getFirstChildText(depElement , ARTIFACT_ID);
+            return replaceProps(val);
+        }
+
+        public String getVersion() {
+            String val = getFirstChildText(depElement , VERSION);
+            return replaceProps(val);
+        }
+        
+    }
+    
+    
+    public class PomDependencyData extends PomDependencyMgt {
+        private final Element depElement;
+        PomDependencyData(Element depElement) {
+            super(depElement);
+            this.depElement = depElement;
+        }
+        
+        public String getScope() {
+            String val = getFirstChildText(depElement , SCOPE);
+            if (val == null) {
+                return "compile";
+            } else {
+                return replaceProps(val);
+            }
+        }
+        
+        public String getClassifier() {
+            String val = getFirstChildText(depElement , CLASSIFIER);
+            return replaceProps(val);
+        }
+
+        public boolean isOptional() {
+            return getFirstChildElement(depElement, OPTIONAL) != null;
+        }
+        
+        public Iterable/*<ModuleId>*/ getExcludedModules() {
+            Element exclusionsElement = getFirstChildElement(depElement, EXCLUSIONS);
+            LinkedList exclusions = new LinkedList();
+            if (exclusionsElement != null) {
+                NodeList childs = exclusionsElement.getChildNodes();
+                for (int i = 0; i < childs.getLength(); i++) {
+                    Node node = childs.item(i);
+                    if (node instanceof Element && EXCLUSION.equals(node.getNodeName())) {
+                        String groupId = getFirstChildText((Element) node, GROUP_ID);
+                        String arteficatId = getFirstChildText((Element) node, ARTIFACT_ID);
+                        exclusions.add(ModuleId.newInstance(groupId, arteficatId));
+                    }
+                }
+            }
+            return exclusions;            
+        }
+
+    }
+    
+    
+    
+   
+    
+    
+    
+    private String replaceProps(String val) {
+        if (val == null) {
+            return null;
+        } else {
+            return IvyPatternHelper.substituteVariables(val, properties).trim();
+        }
+    }
+
+    
+    
+    private static String getFirstChildText(Element parentElem, String name) {
+        Element node = getFirstChildElement(parentElem, name);
+        if (node != null) {
+            node.normalize();
+            return node.getTextContent();
+        } else {
+            return null;
+        }
+    }
+
+
+    private static Element getFirstChildElement(Element parentElem, String name) {
+        if (parentElem == null) {
+            return null;
+        }
+        NodeList childs = parentElem.getChildNodes();
+        for (int i = 0; i < childs.getLength(); i++) {
+            Node node = childs.item(i);
+            if (node instanceof Element && name.equals(node.getNodeName())) {
+                return (Element) node;
+            }
+        }
+        return null;
+    }
+
+
+
+
+}

Propchange: ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java Tue Feb 19 11:18:43 2008
@@ -177,11 +177,17 @@
         private static final int EXCLUDE = 9;
 
         private static final int DEPS = 10;
-
+        
+        private static final int DESCRIPTION = 11;
+        
         private int state = NONE;
 
         private final URL xmlURL;
 
+        private StringBuffer buffer;
+        
+        
+
         public Parser(ModuleDescriptorParser parser, ParserSettings ivySettings, boolean validate,
                 URL xmlURL) {
             super(parser);
@@ -257,11 +263,14 @@
                     ivyModuleStarted(attributes);
                 } else if ("info".equals(qName)) {
                     infoStarted(attributes);
-                } else if ("license".equals(qName)) {
+                } else if (state == INFO && "license".equals(qName)) {
                     md.addLicense(new License(ivy.substitute(attributes.getValue("name")), ivy
                             .substitute(attributes.getValue("url"))));
-                } else if ("description".equals(qName)) {
+                } else if (state == INFO && "description".equals(qName)) {
                     md.setHomePage(ivy.substitute(attributes.getValue("homepage")));
+                    state = DESCRIPTION;
+                } else if (state == INFO) {
+                    buffer = new StringBuffer();
                 } else if ("configurations".equals(qName)) {
                     configurationStarted(attributes);
                 } else if ("publications".equals(qName)) {
@@ -292,7 +301,7 @@
                             .getValue("name")));
                 } else if ("manager".equals(qName) && state == CONFLICT) {
                     managerStarted(attributes);
-                 } else if ("include".equals(qName) && state == CONF) {
+                } else if ("include".equals(qName) && state == CONF) {
                     includeConfStarted(attributes);
                 } else if (validate && state != INFO) {
                     addError("unknwon tag " + qName);
@@ -698,6 +707,14 @@
             return matcher;
         }
 
+        
+        public void characters(char[] ch, int start, int length) throws SAXException {
+            if (buffer != null) {
+                buffer.append(ch, start, length);
+            }            
+        }
+
+        
         public void endElement(String uri, String localName, String qName) throws SAXException {
             if (state == PUB && "artifact".equals(qName)
                     && artifact.getConfigurations().length == 0) {
@@ -735,6 +752,13 @@
                 state = DEPS;
             } else if ("dependencies".equals(qName)) {
                 state = NONE;
+            } else if (state == INFO && "info".equals(qName)) {
+                state = NONE;
+            } else if (state == INFO && "description".equals(qName)) {
+                state = INFO;
+            } else if (state == INFO) {
+                md.addExtraInfo(qName, buffer==null?"":buffer.toString());
+                buffer = null;
             }
         }
 

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java Tue Feb 19 11:18:43 2008
@@ -382,7 +382,26 @@
             printExtraAttributes(md, out, "\t\t");
             out.println();
         }
-        out.println("\t/>");
+        if (md.getExtraInfo().size()>0) {
+            out.println("\t>");
+            for (Iterator it = md.getExtraInfo().entrySet().iterator(); it.hasNext();) {
+                Map.Entry extraDescr = (Map.Entry) it.next();
+                if (extraDescr.getValue()==null || ((String)extraDescr.getValue()).length()==0) {
+                    continue;
+                }
+                out.print("\t\t<");
+                out.print(extraDescr.getKey());
+                out.print(">");
+                out.print(XMLHelper.escape((String) extraDescr.getValue()));
+                out.print("</");
+                out.print(extraDescr.getKey());
+                out.println(">");
+            }
+            out.println("\t</info>");
+        } else {
+            out.println("\t/>");            
+        }
+
     }
 
     private static String getConfs(ModuleDescriptor md, Artifact artifact) {

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/ivy.xsd
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/ivy.xsd?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/ivy.xsd (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/ivy.xsd Tue Feb 19 11:18:43 2008
@@ -71,6 +71,7 @@
 					            <xs:attribute name="homepage" type="xs:string"/>
 			            	</xs:complexType>
 			      		</xs:element>
+			      		<xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
 			        </xs:sequence>
 		            <xs:attribute name="organisation" type="xs:string" use="required"/>
 		            <xs:attribute name="module" type="xs:string" use="required"/>

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/ResourceHelper.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/ResourceHelper.java?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/ResourceHelper.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/ResourceHelper.java Tue Feb 19 11:18:43 2008
@@ -22,8 +22,14 @@
 
 import org.apache.ivy.plugins.repository.file.FileResource;
 import org.apache.ivy.plugins.repository.url.URLResource;
+import org.apache.ivy.util.Message;
 
-public class ResourceHelper {
+public final class ResourceHelper {
+    
+    private ResourceHelper() {
+        
+    }
+    
     public static boolean equals(Resource res, File f) {
         if (res == null && f == null) {
             return true;
@@ -41,5 +47,15 @@
             }
         }
         return false;
+    }
+
+    public static long getLastModifiedOrDefault(Resource res) {
+        long last = res.getLastModified();
+        if (last > 0) {
+            return last;
+        } else {
+            Message.debug("impossible to get date for " + res + ": using 'now'");
+            return System.currentTimeMillis();
+        }
     }
 }

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/util/XMLHelper.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/util/XMLHelper.java?rev=629194&r1=629193&r2=629194&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/util/XMLHelper.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/util/XMLHelper.java Tue Feb 19 11:18:43 2008
@@ -21,11 +21,15 @@
 import java.io.InputStream;
 import java.net.URL;
 
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 
+import org.apache.ivy.plugins.repository.Resource;
 import org.apache.ivy.util.url.URLHandlerRegistry;
+import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXNotRecognizedException;
 import org.xml.sax.ext.LexicalHandler;
@@ -49,6 +53,8 @@
 
     private static boolean canUseSchemaValidation = true;
 
+    private static DocumentBuilder docBuilder;
+    
     static {
         VALIDATING_FACTORY.setNamespaceAware(true);
         VALIDATING_FACTORY.setValidating(true);
@@ -177,6 +183,33 @@
         return result.toString();
     }
 
+    
+    public static Document parseToDom(URL descriptorURL, Resource res) throws IOException,
+            SAXException {
+        DocumentBuilder docBuilder = getDocBuilder();
+        InputStream pomStream = res.openStream();
+        Document pomDomDoc;
+        try {
+            pomDomDoc = docBuilder.parse(pomStream, res.getName());
+        } finally {
+            pomStream.close();
+        } 
+        return pomDomDoc;
+    }
+
+    public static DocumentBuilder getDocBuilder() {
+        if (docBuilder == null) {
+            try {
+                docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+            } catch (ParserConfigurationException e) {
+                throw new RuntimeException(e);
+            }        
+        }
+        return docBuilder;
+    }
+
+
     private XMLHelper() {
     }
+
 }



Mime
View raw message