1 package org
.argeo
.slc
.repo
.maven
;
3 import java
.util
.regex
.Pattern
;
5 import org
.apache
.commons
.io
.FilenameUtils
;
6 import org
.argeo
.api
.cms
.CmsLog
;
7 import org
.argeo
.slc
.SlcException
;
8 import org
.eclipse
.aether
.artifact
.Artifact
;
9 import org
.eclipse
.aether
.artifact
.DefaultArtifact
;
10 import org
.eclipse
.aether
.graph
.DependencyNode
;
12 /** Utilities related to Aether */
13 public class AetherUtils
{
14 public final static String SNAPSHOT
= "SNAPSHOT";
16 public static final Pattern SNAPSHOT_TIMESTAMP
= Pattern
17 .compile("^(.*-)?([0-9]{8}.[0-9]{6}-[0-9]+)$");
19 private final static CmsLog log
= CmsLog
.getLog(AetherUtils
.class);
21 /** Logs a dependency node and its transitive dependencies as a tree. */
22 public static void logDependencyNode(int depth
,
23 DependencyNode dependencyNode
) {
24 if (!log
.isDebugEnabled())
27 StringBuffer prefix
= new StringBuffer(depth
* 2 + 2);
28 // prefix.append("|-");
29 for (int i
= 0; i
< depth
* 2; i
++) {
32 Artifact artifact
= dependencyNode
.getDependency().getArtifact();
33 log
.debug(prefix
+ "|-> " + artifact
.getArtifactId() + " ["
34 + artifact
.getVersion() + "]"
35 + (dependencyNode
.getDependency().isOptional() ?
" ?" : ""));
36 for (DependencyNode child
: dependencyNode
.getChildren()) {
37 logDependencyNode(depth
+ 1, child
);
42 * Converts a path (relative to a repository root) to an {@link Artifact}.
47 * the layout type, currently ignored because only the 'default'
48 * Maven 2 layout is currently supported:
49 * /my/group/id/artifactId/
50 * version/artifactId-version[-classifier].extension
51 * @return the related artifact or null if the file is not an artifact
52 * (Maven medata data XML files, check sums, etc.)
54 public static Artifact
convertPathToArtifact(String path
, String type
) {
55 // TODO rewrite it with regexp (unit tests first!)
58 if (path
.startsWith("/"))
59 path
= path
.substring(1);
62 String
[] tokensSlash
= path
.split("/");
63 if (tokensSlash
.length
< 4)
65 StringBuffer groupId
= new StringBuffer(path
.length());
66 for (int i
= 0; i
< tokensSlash
.length
- 3; i
++) {
69 groupId
.append(tokensSlash
[i
]);
71 String artifactId
= tokensSlash
[tokensSlash
.length
- 3];
72 String baseVersion
= tokensSlash
[tokensSlash
.length
- 2];
73 String fileName
= tokensSlash
[tokensSlash
.length
- 1];
75 if (!fileName
.startsWith(artifactId
))
77 // FIXME make it configurable? (via an argument?)
78 if (FilenameUtils
.isExtension(fileName
, new String
[] { "sha1", "md5" }))
81 String extension
= FilenameUtils
.getExtension(fileName
);
82 String baseName
= FilenameUtils
.getBaseName(fileName
);
84 // check since we assume hereafter
85 if (!baseName
.startsWith(artifactId
))
86 throw new SlcException("Base name '" + baseName
87 + " does not start with artifact id '" + artifactId
90 boolean isSnapshot
= baseVersion
.endsWith("-" + SNAPSHOT
);
91 String baseBaseVersion
= isSnapshot ? baseVersion
.substring(0,
92 baseVersion
.length() - SNAPSHOT
.length() - 1) : baseVersion
;
93 int artifactAndBaseBaseVersionLength
= artifactId
.length() + 1
94 + baseBaseVersion
.length() + 1;
95 String classifier
= null;
96 if (baseName
.length() > artifactAndBaseBaseVersionLength
) {
97 String dashRest
= baseName
98 .substring(artifactAndBaseBaseVersionLength
);
99 String
[] dashes
= dashRest
.split("-");
102 if (dashes
[0].equals(SNAPSHOT
)) {
103 if (dashRest
.length() > SNAPSHOT
.length() + 1)
104 classifier
= dashRest
.substring(SNAPSHOT
.length() + 1);
107 if (dashes
.length
> 2)// assume no '-' in classifier
108 classifier
= dashes
[2];
111 if (dashes
.length
> 0)
112 classifier
= dashes
[0];
117 // String classifier = null;
118 // int firstDash = baseName.indexOf('-');
119 // int classifierDash = baseName.lastIndexOf('-');
120 // if (classifierDash > 0 && classifierDash != firstDash) {
121 // classifier = baseName.substring(classifierDash + 1);
123 // if (isSnapshot && classifier != null) {
124 // if (classifier.equals(SNAPSHOT))
125 // classifier = null;
128 // Long.parseLong(classifier); // build number
129 // // if not failed this is a timestamped version
130 // classifier = null;
131 // } catch (NumberFormatException e) {
137 String version
= baseName
.substring(artifactId
.length() + 1);
138 if (classifier
!= null)
139 version
= version
.substring(0,
140 version
.length() - classifier
.length() - 1);
142 // consistency checks
143 if (!isSnapshot
&& !version
.equals(baseVersion
))
144 throw new SlcException("Base version '" + baseVersion
145 + "' and version '" + version
+ "' not in line in " + path
);
146 if (!isSnapshot
&& isSnapshotVersion(version
))
147 throw new SlcException("SNAPSHOT base version '" + baseVersion
148 + "' and version '" + version
+ "' not in line in " + path
);
150 DefaultArtifact artifact
= new DefaultArtifact(groupId
.toString(),
151 artifactId
, classifier
, extension
, version
);
155 /** Hacked from aether */
156 public static boolean isSnapshotVersion(String version
) {
157 return version
.endsWith(SNAPSHOT
)
158 || SNAPSHOT_TIMESTAMP
.matcher(version
).matches();