View Javadoc
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 }