1 package org
.argeo
.slc
.repo
.maven
;
3 import java
.io
.ByteArrayOutputStream
;
5 import java
.util
.Comparator
;
6 import java
.util
.HashSet
;
7 import java
.util
.Properties
;
9 import java
.util
.TreeSet
;
11 import javax
.jcr
.Session
;
12 import javax
.xml
.parsers
.DocumentBuilder
;
13 import javax
.xml
.parsers
.DocumentBuilderFactory
;
15 import org
.apache
.commons
.logging
.Log
;
16 import org
.apache
.commons
.logging
.LogFactory
;
17 import org
.argeo
.slc
.SlcException
;
18 import org
.argeo
.slc
.aether
.AetherTemplate
;
19 import org
.sonatype
.aether
.artifact
.Artifact
;
20 import org
.sonatype
.aether
.graph
.DependencyNode
;
21 import org
.sonatype
.aether
.util
.artifact
.DefaultArtifact
;
22 import org
.w3c
.dom
.Document
;
23 import org
.w3c
.dom
.Element
;
24 import org
.w3c
.dom
.NodeList
;
26 public class ImportMavenDependencies
implements Runnable
{
27 private final static Log log
= LogFactory
28 .getLog(ImportMavenDependencies
.class);
30 private AetherTemplate aetherTemplate
;
31 private String rootCoordinates
;
32 private Set
<String
> excludedArtifacts
= new HashSet
<String
>();
34 private Session jcrSession
;
37 Set
<Artifact
> artifacts
= resolveDistribution();
40 public Set
<Artifact
> resolveDistribution() {
42 Artifact pomArtifact
= new DefaultArtifact(rootCoordinates
);
43 Comparator
<Artifact
> artifactComparator
= new Comparator
<Artifact
>() {
44 public int compare(Artifact o1
, Artifact o2
) {
45 return o1
.getArtifactId().compareTo(o2
.getArtifactId());
49 Set
<Artifact
> registeredArtifacts
= new TreeSet
<Artifact
>(
51 parsePom(aetherTemplate
, registeredArtifacts
, pomArtifact
);
52 if (log
.isDebugEnabled())
53 log
.debug("Gathered " + registeredArtifacts
.size()
56 // Resolve and add non-optional dependencies
57 Set
<Artifact
> artifacts
= new TreeSet
<Artifact
>(artifactComparator
);
58 for (Artifact artifact
: registeredArtifacts
) {
60 addArtifact(artifacts
, artifact
);
61 DependencyNode node
= aetherTemplate
62 .resolveDependencies(artifact
);
63 addDependencies(artifacts
, node
);
64 } catch (Exception e
) {
65 log
.error("Could not resolve dependencies of " + artifact
66 + ": " + e
.getCause().getMessage());
71 if (log
.isDebugEnabled())
72 log
.debug("Resolved " + artifacts
.size() + " artifacts");
73 Properties distributionDescriptor
= new Properties();
74 for (Artifact artifact
: artifacts
) {
75 log
.debug(artifact
.getArtifactId() + " ["
76 + artifact
.getVersion() + "]\t(" + artifact
+ ")");
77 distributionDescriptor
.setProperty(artifact
.getArtifactId()
78 + ":" + artifact
.getVersion(), artifact
.toString());
81 ByteArrayOutputStream out
= new ByteArrayOutputStream();
82 distributionDescriptor
.store(out
, "");
83 log
.debug(new String(out
.toByteArray()));
87 } catch (Exception e
) {
88 throw new SlcException("Cannot resolve distribution", e
);
92 protected void syncDistribution(Set
<Artifact
> artifacts
) {
96 /** Recursively adds non optional dependencies */
97 private void addDependencies(Set
<Artifact
> artifacts
, DependencyNode node
) {
98 for (DependencyNode child
: node
.getChildren()) {
99 if (!child
.getDependency().isOptional()) {
100 addArtifact(artifacts
, child
.getDependency().getArtifact());
101 addDependencies(artifacts
, child
);
106 private void addArtifact(Set
<Artifact
> artifacts
, Artifact artifact
) {
107 if (!excludedArtifacts
.contains(artifact
.getGroupId() + ":"
108 + artifact
.getArtifactId()))
109 artifacts
.add(artifact
);
113 * Directly parses Maven POM XML format in order to find all artifacts
114 * references under the dependency and dependencyManagement tags. This is
115 * meant to migrate existing pom registering a lot of artifacts, not to
116 * replace Maven resolving.
118 protected void parsePom(AetherTemplate aetherTemplate
,
119 Set
<Artifact
> artifacts
, Artifact pomArtifact
) {
120 if (log
.isDebugEnabled())
121 log
.debug("Gather dependencies for " + pomArtifact
);
124 File file
= aetherTemplate
.getResolvedFile(pomArtifact
);
125 DocumentBuilder documentBuilder
= DocumentBuilderFactory
126 .newInstance().newDocumentBuilder();
127 Document doc
= documentBuilder
.parse(file
);
130 Properties props
= new Properties();
131 props
.setProperty("project.version", pomArtifact
.getBaseVersion());
132 NodeList properties
= doc
.getElementsByTagName("properties");
133 if (properties
.getLength() > 0) {
134 NodeList propertiesElems
= properties
.item(0).getChildNodes();
135 for (int i
= 0; i
< propertiesElems
.getLength(); i
++) {
136 if (propertiesElems
.item(i
) instanceof Element
) {
137 Element property
= (Element
) propertiesElems
.item(i
);
138 props
.put(property
.getNodeName(),
139 property
.getTextContent());
144 // dependencies (direct and dependencyManagement)
145 NodeList dependencies
= doc
.getElementsByTagName("dependency");
146 for (int i
= 0; i
< dependencies
.getLength(); i
++) {
147 Element dependency
= (Element
) dependencies
.item(i
);
148 String groupId
= dependency
.getElementsByTagName("groupId")
149 .item(0).getTextContent().trim();
150 String artifactId
= dependency
151 .getElementsByTagName("artifactId").item(0)
152 .getTextContent().trim();
153 String version
= dependency
.getElementsByTagName("version")
154 .item(0).getTextContent().trim();
155 if (version
.startsWith("${")) {
156 String versionKey
= version
.substring(0,
157 version
.length() - 1).substring(2);
158 if (!props
.containsKey(versionKey
))
159 throw new SlcException("Cannot interpret version "
161 version
= props
.getProperty(versionKey
);
163 NodeList scopes
= dependency
.getElementsByTagName("scope");
164 if (scopes
.getLength() > 0
165 && scopes
.item(0).getTextContent().equals("import")) {
167 parsePom(aetherTemplate
, artifacts
, new DefaultArtifact(
168 groupId
, artifactId
, "pom", version
));
170 // TODO: deal with scope?
171 // TODO: deal with type
173 Artifact artifact
= new DefaultArtifact(groupId
,
174 artifactId
, type
, version
);
175 artifacts
.add(artifact
);
178 } catch (Exception e
) {
179 throw new SlcException("Cannot process " + pomArtifact
, e
);
183 public void setAetherTemplate(AetherTemplate aetherTemplate
) {
184 this.aetherTemplate
= aetherTemplate
;
187 public void setExcludedArtifacts(Set
<String
> excludedArtifactIds
) {
188 this.excludedArtifacts
= excludedArtifactIds
;
191 public void setRootCoordinates(String rootCoordinates
) {
192 this.rootCoordinates
= rootCoordinates
;
195 public void setJcrSession(Session jcrSession
) {
196 this.jcrSession
= jcrSession
;