1 package org.eclipse.aether.util.artifact;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.io.File;
23 import java.util.Map;
24
25 import org.eclipse.aether.artifact.AbstractArtifact;
26 import org.eclipse.aether.artifact.Artifact;
27
28 /**
29 * An artifact whose identity is derived from another artifact. <em>Note:</em> Instances of this class are immutable and
30 * the exposed mutators return new objects rather than changing the current instance.
31 */
32 public final class SubArtifact
33 extends AbstractArtifact
34 {
35
36 private final Artifact mainArtifact;
37
38 private final String classifier;
39
40 private final String extension;
41
42 private final File file;
43
44 private final Map<String, String> properties;
45
46 /**
47 * Creates a new sub artifact. The classifier and extension specified for this artifact may use the asterisk
48 * character "*" to refer to the corresponding property of the main artifact. For instance, the classifier
49 * "*-sources" can be used to refer to the source attachment of an artifact. Likewise, the extension "*.asc" can be
50 * used to refer to the GPG signature of an artifact.
51 *
52 * @param mainArtifact The artifact from which to derive the identity, must not be {@code null}.
53 * @param classifier The classifier for this artifact, may be {@code null} if none.
54 * @param extension The extension for this artifact, may be {@code null} if none.
55 */
56 public SubArtifact( Artifact mainArtifact, String classifier, String extension )
57 {
58 this( mainArtifact, classifier, extension, (File) null );
59 }
60
61 /**
62 * Creates a new sub artifact. The classifier and extension specified for this artifact may use the asterisk
63 * character "*" to refer to the corresponding property of the main artifact. For instance, the classifier
64 * "*-sources" can be used to refer to the source attachment of an artifact. Likewise, the extension "*.asc" can be
65 * used to refer to the GPG signature of an artifact.
66 *
67 * @param mainArtifact The artifact from which to derive the identity, must not be {@code null}.
68 * @param classifier The classifier for this artifact, may be {@code null} if none.
69 * @param extension The extension for this artifact, may be {@code null} if none.
70 * @param file The file for this artifact, may be {@code null} if unresolved.
71 */
72 public SubArtifact( Artifact mainArtifact, String classifier, String extension, File file )
73 {
74 this( mainArtifact, classifier, extension, null, file );
75 }
76
77 /**
78 * Creates a new sub artifact. The classifier and extension specified for this artifact may use the asterisk
79 * character "*" to refer to the corresponding property of the main artifact. For instance, the classifier
80 * "*-sources" can be used to refer to the source attachment of an artifact. Likewise, the extension "*.asc" can be
81 * used to refer to the GPG signature of an artifact.
82 *
83 * @param mainArtifact The artifact from which to derive the identity, must not be {@code null}.
84 * @param classifier The classifier for this artifact, may be {@code null} if none.
85 * @param extension The extension for this artifact, may be {@code null} if none.
86 * @param properties The properties of the artifact, may be {@code null}.
87 */
88 public SubArtifact( Artifact mainArtifact, String classifier, String extension, Map<String, String> properties )
89 {
90 this( mainArtifact, classifier, extension, properties, null );
91 }
92
93 /**
94 * Creates a new sub artifact. The classifier and extension specified for this artifact may use the asterisk
95 * character "*" to refer to the corresponding property of the main artifact. For instance, the classifier
96 * "*-sources" can be used to refer to the source attachment of an artifact. Likewise, the extension "*.asc" can be
97 * used to refer to the GPG signature of an artifact.
98 *
99 * @param mainArtifact The artifact from which to derive the identity, must not be {@code null}.
100 * @param classifier The classifier for this artifact, may be {@code null} if none.
101 * @param extension The extension for this artifact, may be {@code null} if none.
102 * @param properties The properties of the artifact, may be {@code null}.
103 * @param file The file for this artifact, may be {@code null} if unresolved.
104 */
105 public SubArtifact( Artifact mainArtifact, String classifier, String extension, Map<String, String> properties,
106 File file )
107 {
108 if ( mainArtifact == null )
109 {
110 throw new IllegalArgumentException( "no artifact specified" );
111 }
112 this.mainArtifact = mainArtifact;
113 this.classifier = classifier;
114 this.extension = extension;
115 this.file = file;
116 this.properties = copyProperties( properties );
117 }
118
119 private SubArtifact( Artifact mainArtifact, String classifier, String extension, File file,
120 Map<String, String> properties )
121 {
122 // NOTE: This constructor assumes immutability of the provided properties, for internal use only
123 this.mainArtifact = mainArtifact;
124 this.classifier = classifier;
125 this.extension = extension;
126 this.file = file;
127 this.properties = properties;
128 }
129
130 public String getGroupId()
131 {
132 return mainArtifact.getGroupId();
133 }
134
135 public String getArtifactId()
136 {
137 return mainArtifact.getArtifactId();
138 }
139
140 public String getVersion()
141 {
142 return mainArtifact.getVersion();
143 }
144
145 public String getBaseVersion()
146 {
147 return mainArtifact.getBaseVersion();
148 }
149
150 public boolean isSnapshot()
151 {
152 return mainArtifact.isSnapshot();
153 }
154
155 public String getClassifier()
156 {
157 return expand( classifier, mainArtifact.getClassifier() );
158 }
159
160 public String getExtension()
161 {
162 return expand( extension, mainArtifact.getExtension() );
163 }
164
165 public File getFile()
166 {
167 return file;
168 }
169
170 public Artifact setFile( File file )
171 {
172 if ( ( this.file == null ) ? file == null : this.file.equals( file ) )
173 {
174 return this;
175 }
176 return new SubArtifact( mainArtifact, classifier, extension, file, properties );
177 }
178
179 public Map<String, String> getProperties()
180 {
181 return properties;
182 }
183
184 public Artifact setProperties( Map<String, String> properties )
185 {
186 if ( this.properties.equals( properties ) || ( properties == null && this.properties.isEmpty() ) )
187 {
188 return this;
189 }
190 return new SubArtifact( mainArtifact, classifier, extension, properties, file );
191 }
192
193 private static String expand( String pattern, String replacement )
194 {
195 String result = "";
196 if ( pattern != null )
197 {
198 result = pattern.replace( "*", replacement );
199
200 if ( replacement.length() <= 0 )
201 {
202 if ( pattern.startsWith( "*" ) )
203 {
204 int i = 0;
205 for ( ; i < result.length(); i++ )
206 {
207 char c = result.charAt( i );
208 if ( c != '-' && c != '.' )
209 {
210 break;
211 }
212 }
213 result = result.substring( i );
214 }
215 if ( pattern.endsWith( "*" ) )
216 {
217 int i = result.length() - 1;
218 for ( ; i >= 0; i-- )
219 {
220 char c = result.charAt( i );
221 if ( c != '-' && c != '.' )
222 {
223 break;
224 }
225 }
226 result = result.substring( 0, i + 1 );
227 }
228 }
229 }
230 return result;
231 }
232
233 }