1 package org
.argeo
.slc
.repo
.maven
;
3 import java
.io
.ByteArrayInputStream
;
4 import java
.io
.ByteArrayOutputStream
;
6 import java
.io
.FileInputStream
;
7 import java
.io
.InputStream
;
8 import java
.util
.ArrayList
;
9 import java
.util
.Comparator
;
10 import java
.util
.HashSet
;
11 import java
.util
.List
;
12 import java
.util
.Properties
;
14 import java
.util
.TreeSet
;
15 import java
.util
.jar
.Attributes
;
16 import java
.util
.jar
.Attributes
.Name
;
17 import java
.util
.jar
.JarInputStream
;
18 import java
.util
.jar
.Manifest
;
20 import javax
.jcr
.Binary
;
21 import javax
.jcr
.Node
;
22 import javax
.jcr
.NodeIterator
;
23 import javax
.jcr
.PathNotFoundException
;
24 import javax
.jcr
.Property
;
25 import javax
.jcr
.RepositoryException
;
26 import javax
.jcr
.Session
;
27 import javax
.jcr
.nodetype
.NodeType
;
28 import javax
.xml
.parsers
.DocumentBuilder
;
29 import javax
.xml
.parsers
.DocumentBuilderFactory
;
31 import org
.apache
.commons
.io
.FilenameUtils
;
32 import org
.apache
.commons
.io
.IOUtils
;
33 import org
.apache
.commons
.logging
.Log
;
34 import org
.apache
.commons
.logging
.LogFactory
;
35 import org
.argeo
.jcr
.JcrUtils
;
36 import org
.argeo
.slc
.SlcException
;
37 import org
.argeo
.slc
.aether
.AetherTemplate
;
38 import org
.argeo
.slc
.repo
.RepoConstants
;
39 import org
.argeo
.slc
.repo
.RepoNames
;
40 import org
.argeo
.slc
.repo
.RepoTypes
;
41 import org
.osgi
.framework
.Constants
;
42 import org
.osgi
.framework
.Version
;
43 import org
.sonatype
.aether
.artifact
.Artifact
;
44 import org
.sonatype
.aether
.graph
.DependencyNode
;
45 import org
.sonatype
.aether
.util
.artifact
.DefaultArtifact
;
46 import org
.w3c
.dom
.Document
;
47 import org
.w3c
.dom
.Element
;
48 import org
.w3c
.dom
.NodeList
;
50 public class ImportMavenDependencies
implements Runnable
{
51 private final static Log log
= LogFactory
52 .getLog(ImportMavenDependencies
.class);
54 private AetherTemplate aetherTemplate
;
55 private String rootCoordinates
;
56 private Set
<String
> excludedArtifacts
= new HashSet
<String
>();
58 private Session jcrSession
;
59 private String artifactBasePath
= RepoConstants
.ARTIFACTS_BASE_PATH
;
60 private String distributionsBasePath
= "/slc/repo/distributions";
61 private String distributionName
;
64 log
.debug(jcrSession
.getUserID());
65 Set
<Artifact
> artifacts
= resolveDistribution();
66 syncDistribution(artifacts
);
69 public Set
<Artifact
> resolveDistribution() {
71 Artifact pomArtifact
= new DefaultArtifact(rootCoordinates
);
72 Comparator
<Artifact
> artifactComparator
= new Comparator
<Artifact
>() {
73 public int compare(Artifact o1
, Artifact o2
) {
74 return o1
.getArtifactId().compareTo(o2
.getArtifactId());
78 Set
<Artifact
> registeredArtifacts
= new TreeSet
<Artifact
>(
80 parsePom(aetherTemplate
, registeredArtifacts
, pomArtifact
);
81 if (log
.isDebugEnabled())
82 log
.debug("Gathered " + registeredArtifacts
.size()
85 // Resolve and add non-optional dependencies
86 Set
<Artifact
> artifacts
= new TreeSet
<Artifact
>(artifactComparator
);
87 for (Artifact artifact
: registeredArtifacts
) {
89 addArtifact(artifacts
, artifact
);
90 DependencyNode node
= aetherTemplate
91 .resolveDependencies(artifact
);
92 addDependencies(artifacts
, node
);
93 } catch (Exception e
) {
94 log
.error("Could not resolve dependencies of " + artifact
95 + ": " + e
.getCause().getMessage());
100 if (log
.isDebugEnabled())
101 log
.debug("Resolved " + artifacts
.size() + " artifacts");
102 Properties distributionDescriptor
= new Properties();
103 for (Artifact artifact
: artifacts
) {
104 log
.debug(artifact
.getArtifactId() + " ["
105 + artifact
.getVersion() + "]\t(" + artifact
+ ")");
106 distributionDescriptor
.setProperty(artifact
.getArtifactId()
107 + ":" + artifact
.getVersion(), artifact
.toString());
110 ByteArrayOutputStream out
= new ByteArrayOutputStream();
111 distributionDescriptor
.store(out
, "");
112 log
.debug(new String(out
.toByteArray()));
116 } catch (Exception e
) {
117 throw new SlcException("Cannot resolve distribution", e
);
121 protected void syncDistribution(Set
<Artifact
> artifacts
) {
122 Long begin
= System
.currentTimeMillis();
124 JcrUtils
.mkdirs(jcrSession
, artifactBasePath
);
125 JcrUtils
.mkdirs(jcrSession
, distributionsBasePath
+ '/'
127 artifacts
: for (Artifact artifact
: artifacts
) {
128 File file
= artifact
.getFile();
130 log
.warn("File not found for " + artifact
);
132 file
= artifactToFile(artifact
);
134 if (!file
.exists()) {
135 log
.warn("Generated file " + file
+ " for " + artifact
136 + " does not exist");
142 String parentPath
= artifactBasePath
+ '/'
143 + artifactParentPath(artifact
);
145 if (!jcrSession
.itemExists(parentPath
)) {
146 parentNode
= JcrUtils
.mkdirs(jcrSession
, parentPath
,
147 NodeType
.NT_FOLDER
, false);
149 parentNode
= jcrSession
.getNode(parentPath
);
153 if (!parentNode
.hasNode(file
.getName())) {
154 fileNode
= createFileNode(parentNode
, file
);
156 fileNode
= parentNode
.getNode(file
.getName());
158 processArtifact(fileNode
, artifact
);
159 if (fileNode
.isNodeType(RepoTypes
.SLC_JAR_FILE
)) {
160 processOsgiBundle(fileNode
);
165 .itemExists(bundleDistributionPath(fileNode
))
167 .isNodeType(RepoTypes
.SLC_BUNDLE_ARTIFACT
))
168 jcrSession
.getWorkspace().clone(
169 jcrSession
.getWorkspace().getName(),
171 bundleDistributionPath(fileNode
), false);
173 if (log
.isDebugEnabled())
174 log
.debug("Synchronized " + fileNode
);
175 } catch (Exception e
) {
176 log
.error("Could not synchronize " + artifact
, e
);
177 jcrSession
.refresh(false);
182 Long duration
= (System
.currentTimeMillis() - begin
) / 1000;
183 if (log
.isDebugEnabled())
184 log
.debug("Synchronized distribution in " + duration
+ "s");
185 } catch (Exception e
) {
186 throw new SlcException("Cannot synchronize distribution", e
);
190 protected String
artifactParentPath(Artifact artifact
) {
191 return artifact
.getGroupId().replace('.', '/') + '/'
192 + artifact
.getArtifactId() + '/' + artifact
.getVersion();
195 protected String
bundleDistributionPath(Node fileNode
) {
197 return distributionsBasePath
201 + fileNode
.getProperty(RepoNames
.SLC_SYMBOLIC_NAME
)
204 + fileNode
.getProperty(RepoNames
.SLC_BUNDLE_VERSION
)
206 } catch (RepositoryException e
) {
207 throw new SlcException("Cannot create distribution path for "
212 protected void processArtifact(Node fileNode
, Artifact artifact
) {
214 fileNode
.addMixin(RepoTypes
.SLC_ARTIFACT
);
215 fileNode
.setProperty(RepoNames
.SLC_ARTIFACT_ID
,
216 artifact
.getArtifactId());
217 fileNode
.setProperty(RepoNames
.SLC_GROUP_ID
, artifact
.getGroupId());
218 fileNode
.setProperty(RepoNames
.SLC_ARTIFACT_VERSION
,
219 artifact
.getVersion());
220 fileNode
.setProperty(RepoNames
.SLC_ARTIFACT_EXTENSION
,
221 artifact
.getExtension());
222 fileNode
.setProperty(RepoNames
.SLC_ARTIFACT_CLASSIFIER
,
223 artifact
.getClassifier());
224 } catch (RepositoryException e
) {
225 throw new SlcException("Cannot process artifact " + artifact
226 + " on node " + fileNode
, e
);
231 protected File
artifactToFile(Artifact artifact
) {
232 return new File(System
.getProperty("user.home")
238 + artifact
.getGroupId().replace('.', File
.separatorChar
)
240 + artifact
.getArtifactId()
242 + artifact
.getVersion()
244 + artifact
.getArtifactId()
246 + artifact
.getVersion()
247 + (artifact
.getClassifier().equals("") ?
""
248 : '-' + artifact
.getClassifier()) + '.'
249 + artifact
.getExtension());
252 protected void processOsgiBundle(Node fileNode
) {
253 Binary manifestBinary
= null;
254 InputStream manifestIn
= null;
256 manifestBinary
= fileNode
.getProperty(RepoNames
.SLC_MANIFEST
)
258 manifestIn
= manifestBinary
.getStream();
259 Manifest manifest
= new Manifest(manifestIn
);
260 Attributes attrs
= manifest
.getMainAttributes();
262 if (log
.isTraceEnabled())
263 for (Object key
: attrs
.keySet())
264 log
.trace(key
+ ": " + attrs
.getValue(key
.toString()));
266 if (!attrs
.containsKey(new Name(Constants
.BUNDLE_SYMBOLICNAME
))) {
267 log
.warn(fileNode
+ " is not an OSGi bundle");
268 return;// not an osgi bundle
271 fileNode
.addMixin(RepoTypes
.SLC_BUNDLE_ARTIFACT
);
274 String symbolicName
= attrs
.getValue(Constants
.BUNDLE_SYMBOLICNAME
);
275 // make sure there is no directive
276 symbolicName
= symbolicName
.split(";")[0];
277 fileNode
.setProperty(RepoNames
.SLC_SYMBOLIC_NAME
, symbolicName
);
280 addAttr(Constants
.BUNDLE_SYMBOLICNAME
, fileNode
, attrs
);
281 addAttr(Constants
.BUNDLE_NAME
, fileNode
, attrs
);
282 addAttr(Constants
.BUNDLE_DESCRIPTION
, fileNode
, attrs
);
283 addAttr(Constants
.BUNDLE_MANIFESTVERSION
, fileNode
, attrs
);
284 addAttr(Constants
.BUNDLE_CATEGORY
, fileNode
, attrs
);
285 addAttr(Constants
.BUNDLE_ACTIVATIONPOLICY
, fileNode
, attrs
);
286 addAttr(Constants
.BUNDLE_COPYRIGHT
, fileNode
, attrs
);
287 addAttr(Constants
.BUNDLE_VENDOR
, fileNode
, attrs
);
288 addAttr("Bundle-License", fileNode
, attrs
);
289 addAttr(Constants
.BUNDLE_DOCURL
, fileNode
, attrs
);
290 addAttr(Constants
.BUNDLE_CONTACTADDRESS
, fileNode
, attrs
);
291 addAttr(Constants
.BUNDLE_ACTIVATOR
, fileNode
, attrs
);
292 addAttr(Constants
.BUNDLE_UPDATELOCATION
, fileNode
, attrs
);
293 addAttr(Constants
.BUNDLE_LOCALIZATION
, fileNode
, attrs
);
295 // required execution environment
296 if (attrs
.containsKey(new Name(
297 Constants
.BUNDLE_REQUIREDEXECUTIONENVIRONMENT
)))
298 fileNode
.setProperty(
300 + Constants
.BUNDLE_REQUIREDEXECUTIONENVIRONMENT
,
302 Constants
.BUNDLE_REQUIREDEXECUTIONENVIRONMENT
)
306 if (attrs
.containsKey(new Name(Constants
.BUNDLE_CLASSPATH
)))
307 fileNode
.setProperty(RepoNames
.SLC_
308 + Constants
.BUNDLE_CLASSPATH
,
309 attrs
.getValue(Constants
.BUNDLE_CLASSPATH
).split(","));
312 Version version
= new Version(
313 attrs
.getValue(Constants
.BUNDLE_VERSION
));
314 fileNode
.setProperty(RepoNames
.SLC_BUNDLE_VERSION
,
316 cleanSubNodes(fileNode
, RepoNames
.SLC_
+ Constants
.BUNDLE_VERSION
);
317 Node bundleVersionNode
= fileNode
.addNode(RepoNames
.SLC_
318 + Constants
.BUNDLE_VERSION
, RepoTypes
.SLC_OSGI_VERSION
);
319 mapOsgiVersion(version
, bundleVersionNode
);
322 cleanSubNodes(fileNode
, RepoNames
.SLC_
+ Constants
.FRAGMENT_HOST
);
323 if (attrs
.containsKey(new Name(Constants
.FRAGMENT_HOST
))) {
324 String fragmentHost
= attrs
.getValue(Constants
.FRAGMENT_HOST
);
325 String
[] tokens
= fragmentHost
.split(";");
326 Node node
= fileNode
.addNode(RepoNames
.SLC_
327 + Constants
.FRAGMENT_HOST
, RepoTypes
.SLC_FRAGMENT_HOST
);
328 node
.setProperty(RepoNames
.SLC_SYMBOLIC_NAME
, tokens
[0]);
329 for (int i
= 1; i
< tokens
.length
; i
++) {
331 .startsWith(Constants
.BUNDLE_VERSION_ATTRIBUTE
)) {
332 node
.setProperty(RepoNames
.SLC_BUNDLE_VERSION
,
333 attributeValue(tokens
[i
]));
339 cleanSubNodes(fileNode
, RepoNames
.SLC_
+ Constants
.IMPORT_PACKAGE
);
340 if (attrs
.containsKey(new Name(Constants
.IMPORT_PACKAGE
))) {
341 String importPackages
= attrs
342 .getValue(Constants
.IMPORT_PACKAGE
);
343 List
<String
> packages
= parsePackages(importPackages
);
344 for (String pkg
: packages
) {
345 String
[] tokens
= pkg
.split(";");
346 Node node
= fileNode
.addNode(RepoNames
.SLC_
347 + Constants
.IMPORT_PACKAGE
,
348 RepoTypes
.SLC_IMPORTED_PACKAGE
);
349 node
.setProperty(RepoNames
.SLC_NAME
, tokens
[0]);
350 for (int i
= 1; i
< tokens
.length
; i
++) {
351 if (tokens
[i
].startsWith(Constants
.VERSION_ATTRIBUTE
)) {
352 node
.setProperty(RepoNames
.SLC_VERSION
,
353 attributeValue(tokens
[i
]));
355 .startsWith(Constants
.RESOLUTION_DIRECTIVE
)) {
357 RepoNames
.SLC_OPTIONAL
,
358 directiveValue(tokens
[i
]).equals(
359 Constants
.RESOLUTION_OPTIONAL
));
365 // dynamic import package
366 cleanSubNodes(fileNode
, RepoNames
.SLC_
367 + Constants
.DYNAMICIMPORT_PACKAGE
);
368 if (attrs
.containsKey(new Name(Constants
.DYNAMICIMPORT_PACKAGE
))) {
369 String importPackages
= attrs
370 .getValue(Constants
.DYNAMICIMPORT_PACKAGE
);
371 List
<String
> packages
= parsePackages(importPackages
);
372 for (String pkg
: packages
) {
373 String
[] tokens
= pkg
.split(";");
374 Node node
= fileNode
.addNode(RepoNames
.SLC_
375 + Constants
.DYNAMICIMPORT_PACKAGE
,
376 RepoTypes
.SLC_DYNAMIC_IMPORTED_PACKAGE
);
377 node
.setProperty(RepoNames
.SLC_NAME
, tokens
[0]);
378 for (int i
= 1; i
< tokens
.length
; i
++) {
379 if (tokens
[i
].startsWith(Constants
.VERSION_ATTRIBUTE
)) {
380 node
.setProperty(RepoNames
.SLC_VERSION
,
381 attributeValue(tokens
[i
]));
388 cleanSubNodes(fileNode
, RepoNames
.SLC_
+ Constants
.EXPORT_PACKAGE
);
389 if (attrs
.containsKey(new Name(Constants
.EXPORT_PACKAGE
))) {
390 String exportPackages
= attrs
391 .getValue(Constants
.EXPORT_PACKAGE
);
392 List
<String
> packages
= parsePackages(exportPackages
);
393 for (String pkg
: packages
) {
394 String
[] tokens
= pkg
.split(";");
395 Node node
= fileNode
.addNode(RepoNames
.SLC_
396 + Constants
.EXPORT_PACKAGE
,
397 RepoTypes
.SLC_EXPORTED_PACKAGE
);
398 node
.setProperty(RepoNames
.SLC_NAME
, tokens
[0]);
399 // TODO: are these cleans really necessary?
400 cleanSubNodes(node
, RepoNames
.SLC_USES
);
401 cleanSubNodes(node
, RepoNames
.SLC_VERSION
);
402 for (int i
= 1; i
< tokens
.length
; i
++) {
403 if (tokens
[i
].startsWith(Constants
.VERSION_ATTRIBUTE
)) {
404 String versionStr
= attributeValue(tokens
[i
]);
405 Node versionNode
= node
.addNode(
406 RepoNames
.SLC_VERSION
,
407 RepoTypes
.SLC_OSGI_VERSION
);
408 mapOsgiVersion(new Version(versionStr
), versionNode
);
410 .startsWith(Constants
.USES_DIRECTIVE
)) {
411 String usedPackages
= directiveValue(tokens
[i
]);
412 // log.debug("uses='" + usedPackages + "'");
413 for (String usedPackage
: usedPackages
.split(",")) {
414 // log.debug("usedPackage='" + usedPackage +
416 Node usesNode
= node
.addNode(
418 RepoTypes
.SLC_JAVA_PACKAGE
);
419 usesNode
.setProperty(RepoNames
.SLC_NAME
,
428 cleanSubNodes(fileNode
, RepoNames
.SLC_
+ Constants
.REQUIRE_BUNDLE
);
429 if (attrs
.containsKey(new Name(Constants
.REQUIRE_BUNDLE
))) {
430 String requireBundle
= attrs
.getValue(Constants
.REQUIRE_BUNDLE
);
431 String
[] bundles
= requireBundle
.split(",");
432 for (String bundle
: bundles
) {
433 String
[] tokens
= bundle
.split(";");
434 Node node
= fileNode
.addNode(RepoNames
.SLC_
435 + Constants
.REQUIRE_BUNDLE
,
436 RepoTypes
.SLC_REQUIRED_BUNDLE
);
437 node
.setProperty(RepoNames
.SLC_SYMBOLIC_NAME
, tokens
[0]);
438 for (int i
= 1; i
< tokens
.length
; i
++) {
440 .startsWith(Constants
.BUNDLE_VERSION_ATTRIBUTE
)) {
441 node
.setProperty(RepoNames
.SLC_BUNDLE_VERSION
,
442 attributeValue(tokens
[i
]));
444 .startsWith(Constants
.RESOLUTION_DIRECTIVE
)) {
446 RepoNames
.SLC_OPTIONAL
,
447 directiveValue(tokens
[i
]).equals(
448 Constants
.RESOLUTION_OPTIONAL
));
453 } catch (Exception e
) {
454 throw new SlcException("Cannot process OSGi bundle " + fileNode
, e
);
456 if (manifestBinary
!= null)
457 manifestBinary
.dispose();
458 IOUtils
.closeQuietly(manifestIn
);
462 /** Parse package list with nested directive with ',' */
463 private List
<String
> parsePackages(String str
) {
464 List
<String
> res
= new ArrayList
<String
>();
465 StringBuffer curr
= new StringBuffer("");
467 for (char c
: str
.toCharArray()) {
470 res
.add(curr
.toString());
471 curr
= new StringBuffer("");
473 } else if (c
== '\"') {
480 res
.add(curr
.toString());
485 private void addAttr(String key
, Node node
, Attributes attrs
)
486 throws RepositoryException
{
487 addAttr(new Name(key
), node
, attrs
);
490 private void addAttr(Name key
, Node node
, Attributes attrs
)
491 throws RepositoryException
{
492 if (attrs
.containsKey(key
)) {
493 String value
= attrs
.getValue(key
);
494 node
.setProperty(RepoNames
.SLC_
+ key
, value
);
498 private void cleanSubNodes(Node node
, String name
)
499 throws RepositoryException
{
500 if (node
.hasNode(name
)) {
501 NodeIterator nit
= node
.getNodes(name
);
502 while (nit
.hasNext())
503 nit
.nextNode().remove();
507 protected void mapOsgiVersion(Version version
, Node versionNode
)
508 throws RepositoryException
{
509 versionNode
.setProperty(RepoNames
.SLC_AS_STRING
, version
.toString());
510 versionNode
.setProperty(RepoNames
.SLC_MAJOR
, version
.getMajor());
511 versionNode
.setProperty(RepoNames
.SLC_MINOR
, version
.getMinor());
512 versionNode
.setProperty(RepoNames
.SLC_MICRO
, version
.getMicro());
513 if (!version
.getQualifier().equals(""))
514 versionNode
.setProperty(RepoNames
.SLC_QUALIFIER
,
515 version
.getQualifier());
518 private String
attributeValue(String str
) {
519 return extractValue(str
, "=");
522 private String
directiveValue(String str
) {
523 return extractValue(str
, ":=");
526 private String
extractValue(String str
, String eq
) {
527 String
[] tokens
= str
.split(eq
);
528 // String key = tokens[0];
529 String value
= tokens
[1].trim();
531 if (value
.startsWith("\""))
532 value
= value
.substring(1);
533 if (value
.endsWith("\""))
534 value
= value
.substring(0, value
.length() - 1);
538 protected Node
createFileNode(Node parentNode
, File file
) {
539 Binary binary
= null;
541 Node fileNode
= parentNode
542 .addNode(file
.getName(), NodeType
.NT_FILE
);
543 Node contentNode
= fileNode
.addNode(Node
.JCR_CONTENT
,
544 NodeType
.NT_RESOURCE
);
545 binary
= jcrSession
.getValueFactory().createBinary(
546 new FileInputStream(file
));
547 contentNode
.setProperty(Property
.JCR_DATA
, binary
);
549 if (FilenameUtils
.isExtension(file
.getName(), "jar")) {
550 JarInputStream jarIn
= null;
551 ByteArrayOutputStream bo
= null;
552 ByteArrayInputStream bi
= null;
553 Binary manifestBinary
= null;
555 jarIn
= new JarInputStream(binary
.getStream());
556 Manifest manifest
= jarIn
.getManifest();
557 bo
= new ByteArrayOutputStream();
559 bi
= new ByteArrayInputStream(bo
.toByteArray());
560 manifestBinary
= jcrSession
.getValueFactory().createBinary(
562 fileNode
.addMixin(RepoTypes
.SLC_JAR_FILE
);
563 fileNode
.setProperty(RepoNames
.SLC_MANIFEST
, manifestBinary
);
564 Attributes attrs
= manifest
.getMainAttributes();
565 addAttr(Attributes
.Name
.MANIFEST_VERSION
, fileNode
, attrs
);
566 addAttr(Attributes
.Name
.SIGNATURE_VERSION
, fileNode
, attrs
);
567 addAttr(Attributes
.Name
.CLASS_PATH
, fileNode
, attrs
);
568 addAttr(Attributes
.Name
.MAIN_CLASS
, fileNode
, attrs
);
569 addAttr(Attributes
.Name
.EXTENSION_NAME
, fileNode
, attrs
);
570 addAttr(Attributes
.Name
.IMPLEMENTATION_VERSION
, fileNode
,
572 addAttr(Attributes
.Name
.IMPLEMENTATION_VENDOR
, fileNode
,
574 addAttr(Attributes
.Name
.IMPLEMENTATION_VENDOR_ID
, fileNode
,
576 addAttr(Attributes
.Name
.SPECIFICATION_TITLE
, fileNode
,
578 addAttr(Attributes
.Name
.SPECIFICATION_VERSION
, fileNode
,
580 addAttr(Attributes
.Name
.SPECIFICATION_VENDOR
, fileNode
,
582 addAttr(Attributes
.Name
.SEALED
, fileNode
, attrs
);
584 if (manifestBinary
!= null)
585 manifestBinary
.dispose();
586 IOUtils
.closeQuietly(bi
);
587 IOUtils
.closeQuietly(bo
);
588 IOUtils
.closeQuietly(jarIn
);
592 } catch (Exception e
) {
593 throw new SlcException("Cannot create file node based on " + file
594 + " under " + parentNode
, e
);
601 /** Recursively adds non optional dependencies */
602 private void addDependencies(Set
<Artifact
> artifacts
, DependencyNode node
) {
603 for (DependencyNode child
: node
.getChildren()) {
604 if (!child
.getDependency().isOptional()) {
605 addArtifact(artifacts
, child
.getDependency().getArtifact());
606 addDependencies(artifacts
, child
);
611 private void addArtifact(Set
<Artifact
> artifacts
, Artifact artifact
) {
612 if (!excludedArtifacts
.contains(artifact
.getGroupId() + ":"
613 + artifact
.getArtifactId()))
614 artifacts
.add(artifact
);
618 * Directly parses Maven POM XML format in order to find all artifacts
619 * references under the dependency and dependencyManagement tags. This is
620 * meant to migrate existing pom registering a lot of artifacts, not to
621 * replace Maven resolving.
623 protected void parsePom(AetherTemplate aetherTemplate
,
624 Set
<Artifact
> artifacts
, Artifact pomArtifact
) {
625 if (log
.isDebugEnabled())
626 log
.debug("Gather dependencies for " + pomArtifact
);
629 File file
= aetherTemplate
.getResolvedFile(pomArtifact
);
630 DocumentBuilder documentBuilder
= DocumentBuilderFactory
631 .newInstance().newDocumentBuilder();
632 Document doc
= documentBuilder
.parse(file
);
635 Properties props
= new Properties();
636 props
.setProperty("project.version", pomArtifact
.getBaseVersion());
637 NodeList properties
= doc
.getElementsByTagName("properties");
638 if (properties
.getLength() > 0) {
639 NodeList propertiesElems
= properties
.item(0).getChildNodes();
640 for (int i
= 0; i
< propertiesElems
.getLength(); i
++) {
641 if (propertiesElems
.item(i
) instanceof Element
) {
642 Element property
= (Element
) propertiesElems
.item(i
);
643 props
.put(property
.getNodeName(),
644 property
.getTextContent());
649 // dependencies (direct and dependencyManagement)
650 NodeList dependencies
= doc
.getElementsByTagName("dependency");
651 for (int i
= 0; i
< dependencies
.getLength(); i
++) {
652 Element dependency
= (Element
) dependencies
.item(i
);
653 String groupId
= dependency
.getElementsByTagName("groupId")
654 .item(0).getTextContent().trim();
655 String artifactId
= dependency
656 .getElementsByTagName("artifactId").item(0)
657 .getTextContent().trim();
658 String version
= dependency
.getElementsByTagName("version")
659 .item(0).getTextContent().trim();
660 if (version
.startsWith("${")) {
661 String versionKey
= version
.substring(0,
662 version
.length() - 1).substring(2);
663 if (!props
.containsKey(versionKey
))
664 throw new SlcException("Cannot interpret version "
666 version
= props
.getProperty(versionKey
);
668 NodeList scopes
= dependency
.getElementsByTagName("scope");
669 if (scopes
.getLength() > 0
670 && scopes
.item(0).getTextContent().equals("import")) {
672 parsePom(aetherTemplate
, artifacts
, new DefaultArtifact(
673 groupId
, artifactId
, "pom", version
));
675 // TODO: deal with scope?
676 // TODO: deal with type
678 Artifact artifact
= new DefaultArtifact(groupId
,
679 artifactId
, type
, version
);
680 artifacts
.add(artifact
);
683 } catch (Exception e
) {
684 throw new SlcException("Cannot process " + pomArtifact
, e
);
688 public void setAetherTemplate(AetherTemplate aetherTemplate
) {
689 this.aetherTemplate
= aetherTemplate
;
692 public void setExcludedArtifacts(Set
<String
> excludedArtifactIds
) {
693 this.excludedArtifacts
= excludedArtifactIds
;
696 public void setRootCoordinates(String rootCoordinates
) {
697 this.rootCoordinates
= rootCoordinates
;
700 public void setJcrSession(Session jcrSession
) {
701 this.jcrSession
= jcrSession
;
704 public void setDistributionName(String distributionName
) {
705 this.distributionName
= distributionName
;