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
.Property
;
24 import javax
.jcr
.RepositoryException
;
25 import javax
.jcr
.Session
;
26 import javax
.jcr
.nodetype
.NodeType
;
27 import javax
.xml
.parsers
.DocumentBuilder
;
28 import javax
.xml
.parsers
.DocumentBuilderFactory
;
30 import org
.apache
.commons
.io
.FilenameUtils
;
31 import org
.apache
.commons
.io
.IOUtils
;
32 import org
.apache
.commons
.logging
.Log
;
33 import org
.apache
.commons
.logging
.LogFactory
;
34 import org
.argeo
.jcr
.JcrUtils
;
35 import org
.argeo
.slc
.SlcException
;
36 import org
.argeo
.slc
.aether
.AetherTemplate
;
37 import org
.argeo
.slc
.jcr
.SlcNames
;
38 import org
.argeo
.slc
.jcr
.SlcTypes
;
39 import org
.argeo
.slc
.repo
.ArtifactIndexer
;
40 import org
.argeo
.slc
.repo
.RepoConstants
;
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
;
63 private ArtifactIndexer artifactIndexer
= new ArtifactIndexer();
66 log
.debug(jcrSession
.getUserID());
67 Set
<Artifact
> artifacts
= resolveDistribution();
68 syncDistribution(artifacts
);
71 public Set
<Artifact
> resolveDistribution() {
73 Artifact pomArtifact
= new DefaultArtifact(rootCoordinates
);
74 Comparator
<Artifact
> artifactComparator
= new Comparator
<Artifact
>() {
75 public int compare(Artifact o1
, Artifact o2
) {
76 return o1
.getArtifactId().compareTo(o2
.getArtifactId());
80 Set
<Artifact
> registeredArtifacts
= new TreeSet
<Artifact
>(
82 parsePom(aetherTemplate
, registeredArtifacts
, pomArtifact
);
83 if (log
.isDebugEnabled())
84 log
.debug("Gathered " + registeredArtifacts
.size()
87 // Resolve and add non-optional dependencies
88 Set
<Artifact
> artifacts
= new TreeSet
<Artifact
>(artifactComparator
);
89 for (Artifact artifact
: registeredArtifacts
) {
91 addArtifact(artifacts
, artifact
);
92 DependencyNode node
= aetherTemplate
93 .resolveDependencies(artifact
);
94 addDependencies(artifacts
, node
);
95 } catch (Exception e
) {
96 log
.error("Could not resolve dependencies of " + artifact
97 + ": " + e
.getCause().getMessage());
102 if (log
.isDebugEnabled())
103 log
.debug("Resolved " + artifacts
.size() + " artifacts");
104 Properties distributionDescriptor
= new Properties();
105 for (Artifact artifact
: artifacts
) {
106 log
.debug(artifact
.getArtifactId() + " ["
107 + artifact
.getVersion() + "]\t(" + artifact
+ ")");
108 distributionDescriptor
.setProperty(artifact
.getArtifactId()
109 + ":" + artifact
.getVersion(), artifact
.toString());
112 ByteArrayOutputStream out
= new ByteArrayOutputStream();
113 distributionDescriptor
.store(out
, "");
114 log
.debug(new String(out
.toByteArray()));
118 } catch (Exception e
) {
119 throw new SlcException("Cannot resolve distribution", e
);
123 protected void syncDistribution(Set
<Artifact
> artifacts
) {
124 Long begin
= System
.currentTimeMillis();
126 JcrUtils
.mkdirs(jcrSession
, artifactBasePath
);
127 JcrUtils
.mkdirs(jcrSession
, distributionsBasePath
+ '/'
129 artifacts
: for (Artifact artifact
: artifacts
) {
130 File file
= artifact
.getFile();
132 log
.warn("File not found for " + artifact
);
134 file
= artifactToFile(artifact
);
136 if (!file
.exists()) {
137 log
.warn("Generated file " + file
+ " for " + artifact
138 + " does not exist");
144 String parentPath
= artifactBasePath
+ '/'
145 + artifactParentPath(artifact
);
147 if (!jcrSession
.itemExists(parentPath
)) {
148 parentNode
= JcrUtils
.mkdirs(jcrSession
, parentPath
,
151 parentNode
= jcrSession
.getNode(parentPath
);
155 if (!parentNode
.hasNode(file
.getName())) {
156 fileNode
= createFileNode(parentNode
, file
);
158 fileNode
= parentNode
.getNode(file
.getName());
161 if (artifactIndexer
.support(fileNode
.getPath()))
162 artifactIndexer
.index(fileNode
);
163 if (fileNode
.isNodeType(SlcTypes
.SLC_JAR_FILE
)) {
164 processOsgiBundle(fileNode
);
169 .itemExists(bundleDistributionPath(fileNode
))
171 .isNodeType(SlcTypes
.SLC_BUNDLE_ARTIFACT
))
172 jcrSession
.getWorkspace().clone(
173 jcrSession
.getWorkspace().getName(),
175 bundleDistributionPath(fileNode
), false);
177 if (log
.isDebugEnabled())
178 log
.debug("Synchronized " + fileNode
);
179 } catch (Exception e
) {
180 log
.error("Could not synchronize " + artifact
, e
);
181 jcrSession
.refresh(false);
186 Long duration
= (System
.currentTimeMillis() - begin
) / 1000;
187 if (log
.isDebugEnabled())
188 log
.debug("Synchronized distribution in " + duration
+ "s");
189 } catch (Exception e
) {
190 throw new SlcException("Cannot synchronize distribution", e
);
194 protected String
artifactParentPath(Artifact artifact
) {
195 return artifact
.getGroupId().replace('.', '/') + '/'
196 + artifact
.getArtifactId() + '/' + artifact
.getVersion();
199 protected String
bundleDistributionPath(Node fileNode
) {
201 return distributionsBasePath
205 + fileNode
.getProperty(SlcNames
.SLC_SYMBOLIC_NAME
)
208 + fileNode
.getProperty(SlcNames
.SLC_BUNDLE_VERSION
)
210 } catch (RepositoryException e
) {
211 throw new SlcException("Cannot create distribution path for "
216 protected File
artifactToFile(Artifact artifact
) {
217 return new File(System
.getProperty("user.home")
223 + artifact
.getGroupId().replace('.', File
.separatorChar
)
225 + artifact
.getArtifactId()
227 + artifact
.getVersion()
229 + artifact
.getArtifactId()
231 + artifact
.getVersion()
232 + (artifact
.getClassifier().equals("") ?
""
233 : '-' + artifact
.getClassifier()) + '.'
234 + artifact
.getExtension());
237 protected void processOsgiBundle(Node fileNode
) {
238 Binary manifestBinary
= null;
239 InputStream manifestIn
= null;
241 manifestBinary
= fileNode
.getProperty(SlcNames
.SLC_MANIFEST
)
243 manifestIn
= manifestBinary
.getStream();
244 Manifest manifest
= new Manifest(manifestIn
);
245 Attributes attrs
= manifest
.getMainAttributes();
247 if (log
.isTraceEnabled())
248 for (Object key
: attrs
.keySet())
249 log
.trace(key
+ ": " + attrs
.getValue(key
.toString()));
251 if (!attrs
.containsKey(new Name(Constants
.BUNDLE_SYMBOLICNAME
))) {
252 log
.warn(fileNode
+ " is not an OSGi bundle");
253 return;// not an osgi bundle
256 fileNode
.addMixin(SlcTypes
.SLC_BUNDLE_ARTIFACT
);
259 String symbolicName
= attrs
.getValue(Constants
.BUNDLE_SYMBOLICNAME
);
260 // make sure there is no directive
261 symbolicName
= symbolicName
.split(";")[0];
262 fileNode
.setProperty(SlcNames
.SLC_SYMBOLIC_NAME
, symbolicName
);
265 addAttr(Constants
.BUNDLE_SYMBOLICNAME
, fileNode
, attrs
);
266 addAttr(Constants
.BUNDLE_NAME
, fileNode
, attrs
);
267 addAttr(Constants
.BUNDLE_DESCRIPTION
, fileNode
, attrs
);
268 addAttr(Constants
.BUNDLE_MANIFESTVERSION
, fileNode
, attrs
);
269 addAttr(Constants
.BUNDLE_CATEGORY
, fileNode
, attrs
);
270 addAttr(Constants
.BUNDLE_ACTIVATIONPOLICY
, fileNode
, attrs
);
271 addAttr(Constants
.BUNDLE_COPYRIGHT
, fileNode
, attrs
);
272 addAttr(Constants
.BUNDLE_VENDOR
, fileNode
, attrs
);
273 addAttr("Bundle-License", fileNode
, attrs
);
274 addAttr(Constants
.BUNDLE_DOCURL
, fileNode
, attrs
);
275 addAttr(Constants
.BUNDLE_CONTACTADDRESS
, fileNode
, attrs
);
276 addAttr(Constants
.BUNDLE_ACTIVATOR
, fileNode
, attrs
);
277 addAttr(Constants
.BUNDLE_UPDATELOCATION
, fileNode
, attrs
);
278 addAttr(Constants
.BUNDLE_LOCALIZATION
, fileNode
, attrs
);
280 // required execution environment
281 if (attrs
.containsKey(new Name(
282 Constants
.BUNDLE_REQUIREDEXECUTIONENVIRONMENT
)))
283 fileNode
.setProperty(
285 + Constants
.BUNDLE_REQUIREDEXECUTIONENVIRONMENT
,
287 Constants
.BUNDLE_REQUIREDEXECUTIONENVIRONMENT
)
291 if (attrs
.containsKey(new Name(Constants
.BUNDLE_CLASSPATH
)))
292 fileNode
.setProperty(
293 SlcNames
.SLC_
+ Constants
.BUNDLE_CLASSPATH
, attrs
294 .getValue(Constants
.BUNDLE_CLASSPATH
)
298 Version version
= new Version(
299 attrs
.getValue(Constants
.BUNDLE_VERSION
));
300 fileNode
.setProperty(SlcNames
.SLC_BUNDLE_VERSION
,
302 cleanSubNodes(fileNode
, SlcNames
.SLC_
+ Constants
.BUNDLE_VERSION
);
303 Node bundleVersionNode
= fileNode
.addNode(SlcNames
.SLC_
304 + Constants
.BUNDLE_VERSION
, SlcTypes
.SLC_OSGI_VERSION
);
305 mapOsgiVersion(version
, bundleVersionNode
);
308 cleanSubNodes(fileNode
, SlcNames
.SLC_
+ Constants
.FRAGMENT_HOST
);
309 if (attrs
.containsKey(new Name(Constants
.FRAGMENT_HOST
))) {
310 String fragmentHost
= attrs
.getValue(Constants
.FRAGMENT_HOST
);
311 String
[] tokens
= fragmentHost
.split(";");
312 Node node
= fileNode
.addNode(SlcNames
.SLC_
313 + Constants
.FRAGMENT_HOST
, SlcTypes
.SLC_FRAGMENT_HOST
);
314 node
.setProperty(SlcNames
.SLC_SYMBOLIC_NAME
, tokens
[0]);
315 for (int i
= 1; i
< tokens
.length
; i
++) {
317 .startsWith(Constants
.BUNDLE_VERSION_ATTRIBUTE
)) {
318 node
.setProperty(SlcNames
.SLC_BUNDLE_VERSION
,
319 attributeValue(tokens
[i
]));
325 cleanSubNodes(fileNode
, SlcNames
.SLC_
+ Constants
.IMPORT_PACKAGE
);
326 if (attrs
.containsKey(new Name(Constants
.IMPORT_PACKAGE
))) {
327 String importPackages
= attrs
328 .getValue(Constants
.IMPORT_PACKAGE
);
329 List
<String
> packages
= parsePackages(importPackages
);
330 for (String pkg
: packages
) {
331 String
[] tokens
= pkg
.split(";");
332 Node node
= fileNode
.addNode(SlcNames
.SLC_
333 + Constants
.IMPORT_PACKAGE
,
334 SlcTypes
.SLC_IMPORTED_PACKAGE
);
335 node
.setProperty(SlcNames
.SLC_NAME
, tokens
[0]);
336 for (int i
= 1; i
< tokens
.length
; i
++) {
337 if (tokens
[i
].startsWith(Constants
.VERSION_ATTRIBUTE
)) {
338 node
.setProperty(SlcNames
.SLC_VERSION
,
339 attributeValue(tokens
[i
]));
341 .startsWith(Constants
.RESOLUTION_DIRECTIVE
)) {
343 SlcNames
.SLC_OPTIONAL
,
344 directiveValue(tokens
[i
]).equals(
345 Constants
.RESOLUTION_OPTIONAL
));
351 // dynamic import package
352 cleanSubNodes(fileNode
, SlcNames
.SLC_
353 + Constants
.DYNAMICIMPORT_PACKAGE
);
354 if (attrs
.containsKey(new Name(Constants
.DYNAMICIMPORT_PACKAGE
))) {
355 String importPackages
= attrs
356 .getValue(Constants
.DYNAMICIMPORT_PACKAGE
);
357 List
<String
> packages
= parsePackages(importPackages
);
358 for (String pkg
: packages
) {
359 String
[] tokens
= pkg
.split(";");
360 Node node
= fileNode
.addNode(SlcNames
.SLC_
361 + Constants
.DYNAMICIMPORT_PACKAGE
,
362 SlcTypes
.SLC_DYNAMIC_IMPORTED_PACKAGE
);
363 node
.setProperty(SlcNames
.SLC_NAME
, tokens
[0]);
364 for (int i
= 1; i
< tokens
.length
; i
++) {
365 if (tokens
[i
].startsWith(Constants
.VERSION_ATTRIBUTE
)) {
366 node
.setProperty(SlcNames
.SLC_VERSION
,
367 attributeValue(tokens
[i
]));
374 cleanSubNodes(fileNode
, SlcNames
.SLC_
+ Constants
.EXPORT_PACKAGE
);
375 if (attrs
.containsKey(new Name(Constants
.EXPORT_PACKAGE
))) {
376 String exportPackages
= attrs
377 .getValue(Constants
.EXPORT_PACKAGE
);
378 List
<String
> packages
= parsePackages(exportPackages
);
379 for (String pkg
: packages
) {
380 String
[] tokens
= pkg
.split(";");
381 Node node
= fileNode
.addNode(SlcNames
.SLC_
382 + Constants
.EXPORT_PACKAGE
,
383 SlcTypes
.SLC_EXPORTED_PACKAGE
);
384 node
.setProperty(SlcNames
.SLC_NAME
, tokens
[0]);
385 // TODO: are these cleans really necessary?
386 cleanSubNodes(node
, SlcNames
.SLC_USES
);
387 cleanSubNodes(node
, SlcNames
.SLC_VERSION
);
388 for (int i
= 1; i
< tokens
.length
; i
++) {
389 if (tokens
[i
].startsWith(Constants
.VERSION_ATTRIBUTE
)) {
390 String versionStr
= attributeValue(tokens
[i
]);
391 Node versionNode
= node
.addNode(
392 SlcNames
.SLC_VERSION
,
393 SlcTypes
.SLC_OSGI_VERSION
);
394 mapOsgiVersion(new Version(versionStr
), versionNode
);
396 .startsWith(Constants
.USES_DIRECTIVE
)) {
397 String usedPackages
= directiveValue(tokens
[i
]);
398 // log.debug("uses='" + usedPackages + "'");
399 for (String usedPackage
: usedPackages
.split(",")) {
400 // log.debug("usedPackage='" + usedPackage +
402 Node usesNode
= node
.addNode(SlcNames
.SLC_USES
,
403 SlcTypes
.SLC_JAVA_PACKAGE
);
404 usesNode
.setProperty(SlcNames
.SLC_NAME
,
413 cleanSubNodes(fileNode
, SlcNames
.SLC_
+ Constants
.REQUIRE_BUNDLE
);
414 if (attrs
.containsKey(new Name(Constants
.REQUIRE_BUNDLE
))) {
415 String requireBundle
= attrs
.getValue(Constants
.REQUIRE_BUNDLE
);
416 String
[] bundles
= requireBundle
.split(",");
417 for (String bundle
: bundles
) {
418 String
[] tokens
= bundle
.split(";");
419 Node node
= fileNode
.addNode(SlcNames
.SLC_
420 + Constants
.REQUIRE_BUNDLE
,
421 SlcTypes
.SLC_REQUIRED_BUNDLE
);
422 node
.setProperty(SlcNames
.SLC_SYMBOLIC_NAME
, tokens
[0]);
423 for (int i
= 1; i
< tokens
.length
; i
++) {
425 .startsWith(Constants
.BUNDLE_VERSION_ATTRIBUTE
)) {
426 node
.setProperty(SlcNames
.SLC_BUNDLE_VERSION
,
427 attributeValue(tokens
[i
]));
429 .startsWith(Constants
.RESOLUTION_DIRECTIVE
)) {
431 SlcNames
.SLC_OPTIONAL
,
432 directiveValue(tokens
[i
]).equals(
433 Constants
.RESOLUTION_OPTIONAL
));
438 } catch (Exception e
) {
439 throw new SlcException("Cannot process OSGi bundle " + fileNode
, e
);
441 if (manifestBinary
!= null)
442 manifestBinary
.dispose();
443 IOUtils
.closeQuietly(manifestIn
);
447 /** Parse package list with nested directive with ',' */
448 private List
<String
> parsePackages(String str
) {
449 List
<String
> res
= new ArrayList
<String
>();
450 StringBuffer curr
= new StringBuffer("");
452 for (char c
: str
.toCharArray()) {
455 res
.add(curr
.toString());
456 curr
= new StringBuffer("");
458 } else if (c
== '\"') {
465 res
.add(curr
.toString());
470 private void addAttr(String key
, Node node
, Attributes attrs
)
471 throws RepositoryException
{
472 addAttr(new Name(key
), node
, attrs
);
475 private void addAttr(Name key
, Node node
, Attributes attrs
)
476 throws RepositoryException
{
477 if (attrs
.containsKey(key
)) {
478 String value
= attrs
.getValue(key
);
479 node
.setProperty(SlcNames
.SLC_
+ key
, value
);
483 private void cleanSubNodes(Node node
, String name
)
484 throws RepositoryException
{
485 if (node
.hasNode(name
)) {
486 NodeIterator nit
= node
.getNodes(name
);
487 while (nit
.hasNext())
488 nit
.nextNode().remove();
492 protected void mapOsgiVersion(Version version
, Node versionNode
)
493 throws RepositoryException
{
494 versionNode
.setProperty(SlcNames
.SLC_AS_STRING
, version
.toString());
495 versionNode
.setProperty(SlcNames
.SLC_MAJOR
, version
.getMajor());
496 versionNode
.setProperty(SlcNames
.SLC_MINOR
, version
.getMinor());
497 versionNode
.setProperty(SlcNames
.SLC_MICRO
, version
.getMicro());
498 if (!version
.getQualifier().equals(""))
499 versionNode
.setProperty(SlcNames
.SLC_QUALIFIER
,
500 version
.getQualifier());
503 private String
attributeValue(String str
) {
504 return extractValue(str
, "=");
507 private String
directiveValue(String str
) {
508 return extractValue(str
, ":=");
511 private String
extractValue(String str
, String eq
) {
512 String
[] tokens
= str
.split(eq
);
513 // String key = tokens[0];
514 String value
= tokens
[1].trim();
516 if (value
.startsWith("\""))
517 value
= value
.substring(1);
518 if (value
.endsWith("\""))
519 value
= value
.substring(0, value
.length() - 1);
523 protected Node
createFileNode(Node parentNode
, File file
) {
524 Binary binary
= null;
526 Node fileNode
= parentNode
527 .addNode(file
.getName(), NodeType
.NT_FILE
);
528 Node contentNode
= fileNode
.addNode(Node
.JCR_CONTENT
,
529 NodeType
.NT_RESOURCE
);
530 binary
= jcrSession
.getValueFactory().createBinary(
531 new FileInputStream(file
));
532 contentNode
.setProperty(Property
.JCR_DATA
, binary
);
534 if (FilenameUtils
.isExtension(file
.getName(), "jar")) {
535 JarInputStream jarIn
= null;
536 ByteArrayOutputStream bo
= null;
537 ByteArrayInputStream bi
= null;
538 Binary manifestBinary
= null;
540 jarIn
= new JarInputStream(binary
.getStream());
541 Manifest manifest
= jarIn
.getManifest();
542 bo
= new ByteArrayOutputStream();
544 bi
= new ByteArrayInputStream(bo
.toByteArray());
545 manifestBinary
= jcrSession
.getValueFactory().createBinary(
547 fileNode
.addMixin(SlcTypes
.SLC_JAR_FILE
);
548 fileNode
.setProperty(SlcNames
.SLC_MANIFEST
, manifestBinary
);
549 Attributes attrs
= manifest
.getMainAttributes();
550 addAttr(Attributes
.Name
.MANIFEST_VERSION
, fileNode
, attrs
);
551 addAttr(Attributes
.Name
.SIGNATURE_VERSION
, fileNode
, attrs
);
552 addAttr(Attributes
.Name
.CLASS_PATH
, fileNode
, attrs
);
553 addAttr(Attributes
.Name
.MAIN_CLASS
, fileNode
, attrs
);
554 addAttr(Attributes
.Name
.EXTENSION_NAME
, fileNode
, attrs
);
555 addAttr(Attributes
.Name
.IMPLEMENTATION_VERSION
, fileNode
,
557 addAttr(Attributes
.Name
.IMPLEMENTATION_VENDOR
, fileNode
,
559 addAttr(Attributes
.Name
.IMPLEMENTATION_VENDOR_ID
, fileNode
,
561 addAttr(Attributes
.Name
.SPECIFICATION_TITLE
, fileNode
,
563 addAttr(Attributes
.Name
.SPECIFICATION_VERSION
, fileNode
,
565 addAttr(Attributes
.Name
.SPECIFICATION_VENDOR
, fileNode
,
567 addAttr(Attributes
.Name
.SEALED
, fileNode
, attrs
);
569 if (manifestBinary
!= null)
570 manifestBinary
.dispose();
571 IOUtils
.closeQuietly(bi
);
572 IOUtils
.closeQuietly(bo
);
573 IOUtils
.closeQuietly(jarIn
);
577 } catch (Exception e
) {
578 throw new SlcException("Cannot create file node based on " + file
579 + " under " + parentNode
, e
);
586 /** Recursively adds non optional dependencies */
587 private void addDependencies(Set
<Artifact
> artifacts
, DependencyNode node
) {
588 for (DependencyNode child
: node
.getChildren()) {
589 if (!child
.getDependency().isOptional()) {
590 addArtifact(artifacts
, child
.getDependency().getArtifact());
591 addDependencies(artifacts
, child
);
596 private void addArtifact(Set
<Artifact
> artifacts
, Artifact artifact
) {
597 if (!excludedArtifacts
.contains(artifact
.getGroupId() + ":"
598 + artifact
.getArtifactId()))
599 artifacts
.add(artifact
);
603 * Directly parses Maven POM XML format in order to find all artifacts
604 * references under the dependency and dependencyManagement tags. This is
605 * meant to migrate existing pom registering a lot of artifacts, not to
606 * replace Maven resolving.
608 protected void parsePom(AetherTemplate aetherTemplate
,
609 Set
<Artifact
> artifacts
, Artifact pomArtifact
) {
610 if (log
.isDebugEnabled())
611 log
.debug("Gather dependencies for " + pomArtifact
);
614 File file
= aetherTemplate
.getResolvedFile(pomArtifact
);
615 DocumentBuilder documentBuilder
= DocumentBuilderFactory
616 .newInstance().newDocumentBuilder();
617 Document doc
= documentBuilder
.parse(file
);
620 Properties props
= new Properties();
621 props
.setProperty("project.version", pomArtifact
.getBaseVersion());
622 NodeList properties
= doc
.getElementsByTagName("properties");
623 if (properties
.getLength() > 0) {
624 NodeList propertiesElems
= properties
.item(0).getChildNodes();
625 for (int i
= 0; i
< propertiesElems
.getLength(); i
++) {
626 if (propertiesElems
.item(i
) instanceof Element
) {
627 Element property
= (Element
) propertiesElems
.item(i
);
628 props
.put(property
.getNodeName(),
629 property
.getTextContent());
634 // dependencies (direct and dependencyManagement)
635 NodeList dependencies
= doc
.getElementsByTagName("dependency");
636 for (int i
= 0; i
< dependencies
.getLength(); i
++) {
637 Element dependency
= (Element
) dependencies
.item(i
);
638 String groupId
= dependency
.getElementsByTagName("groupId")
639 .item(0).getTextContent().trim();
640 String artifactId
= dependency
641 .getElementsByTagName("artifactId").item(0)
642 .getTextContent().trim();
643 String version
= dependency
.getElementsByTagName("version")
644 .item(0).getTextContent().trim();
645 if (version
.startsWith("${")) {
646 String versionKey
= version
.substring(0,
647 version
.length() - 1).substring(2);
648 if (!props
.containsKey(versionKey
))
649 throw new SlcException("Cannot interpret version "
651 version
= props
.getProperty(versionKey
);
653 NodeList scopes
= dependency
.getElementsByTagName("scope");
654 if (scopes
.getLength() > 0
655 && scopes
.item(0).getTextContent().equals("import")) {
657 parsePom(aetherTemplate
, artifacts
, new DefaultArtifact(
658 groupId
, artifactId
, "pom", version
));
660 // TODO: deal with scope?
661 // TODO: deal with type
663 Artifact artifact
= new DefaultArtifact(groupId
,
664 artifactId
, type
, version
);
665 artifacts
.add(artifact
);
668 } catch (Exception e
) {
669 throw new SlcException("Cannot process " + pomArtifact
, e
);
673 public void setAetherTemplate(AetherTemplate aetherTemplate
) {
674 this.aetherTemplate
= aetherTemplate
;
677 public void setExcludedArtifacts(Set
<String
> excludedArtifactIds
) {
678 this.excludedArtifacts
= excludedArtifactIds
;
681 public void setRootCoordinates(String rootCoordinates
) {
682 this.rootCoordinates
= rootCoordinates
;
685 public void setJcrSession(Session jcrSession
) {
686 this.jcrSession
= jcrSession
;
689 public void setDistributionName(String distributionName
) {
690 this.distributionName
= distributionName
;