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