You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by gs...@apache.org on 2008/02/19 20:18:50 UTC
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...
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() {
}
+
}