View Javadoc

1   package org.apache.maven.artifact.repository;
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.Collections;
24  import java.util.List;
25  
26  import org.apache.maven.artifact.Artifact;
27  import org.apache.maven.artifact.metadata.ArtifactMetadata;
28  import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
29  import org.apache.maven.repository.Proxy;
30  
31  //TODO: completely separate local and remote artifact repositories
32  public class MavenArtifactRepository
33      implements ArtifactRepository
34  {
35      private String id;
36  
37      private String url;
38  
39      private String basedir;
40  
41      private String protocol;
42  
43      private ArtifactRepositoryLayout layout;
44  
45      private ArtifactRepositoryPolicy snapshots;
46  
47      private ArtifactRepositoryPolicy releases;
48  
49      private Authentication authentication;
50  
51      private Proxy proxy;
52  
53      public MavenArtifactRepository()
54      {
55      }
56  
57      /**
58       * Create a remote download repository.
59       *
60       * @param id        the unique identifier of the repository
61       * @param url       the URL of the repository
62       * @param layout    the layout of the repository
63       * @param snapshots the policies to use for snapshots
64       * @param releases  the policies to use for releases
65       */
66      public MavenArtifactRepository( String id, String url, ArtifactRepositoryLayout layout,
67                                      ArtifactRepositoryPolicy snapshots, ArtifactRepositoryPolicy releases )
68      {
69          this.id = id;
70          this.url = url;
71          this.layout = layout;
72          this.snapshots = snapshots;
73          this.releases = releases;
74          //
75          // Derive these from the URL
76          //
77          this.protocol = protocol( url );
78          this.basedir = basedir( url );
79      }
80  
81      public String pathOf( Artifact artifact )
82      {
83          return layout.pathOf( artifact );
84      }
85  
86      public String pathOfRemoteRepositoryMetadata( ArtifactMetadata artifactMetadata )
87      {
88          return layout.pathOfRemoteRepositoryMetadata( artifactMetadata );
89      }
90  
91      public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
92      {
93          return layout.pathOfLocalRepositoryMetadata( metadata, repository );
94      }
95  
96      public void setLayout( ArtifactRepositoryLayout layout )
97      {
98          this.layout = layout;
99      }
100 
101     public ArtifactRepositoryLayout getLayout()
102     {
103         return layout;
104     }
105 
106     public void setSnapshotUpdatePolicy( ArtifactRepositoryPolicy snapshots )
107     {
108         this.snapshots = snapshots;
109     }
110 
111     public ArtifactRepositoryPolicy getSnapshots()
112     {
113         return snapshots;
114     }
115 
116     public void setReleaseUpdatePolicy( ArtifactRepositoryPolicy releases )
117     {
118         this.releases = releases;
119     }
120 
121     public ArtifactRepositoryPolicy getReleases()
122     {
123         return releases;
124     }
125 
126     public String getKey()
127     {
128         return getId();
129     }
130 
131     public String toString()
132     {
133         StringBuilder sb = new StringBuilder();
134 
135         sb.append( "       id: " ).append( getId() ).append( "\n" );
136         sb.append( "      url: " ).append( getUrl() ).append( "\n" );
137         sb.append( "   layout: " ).append( layout != null ? layout.getId() : "none" ).append( "\n" );
138 
139         if ( snapshots != null )
140         {
141             sb.append( "snapshots: [enabled => " ).append( snapshots.isEnabled() );
142             sb.append( ", update => " ).append( snapshots.getUpdatePolicy() ).append( "]\n" );
143         }
144 
145         if ( releases != null )
146         {
147             sb.append( " releases: [enabled => " ).append( releases.isEnabled() );
148             sb.append( ", update => " ).append( releases.getUpdatePolicy() ).append( "]\n" );
149         }
150 
151         return sb.toString();
152     }
153 
154     public Artifact find( Artifact artifact )
155     {
156         File artifactFile = new File( getBasedir(), pathOf( artifact ) );
157 
158         // We need to set the file here or the resolver will fail with an NPE, not fully equipped to deal
159         // with multiple local repository implementations yet.
160         artifact.setFile( artifactFile );
161 
162         return artifact;
163     }
164 
165     public List<String> findVersions( Artifact artifact )
166     {
167         return Collections.emptyList();
168     }
169 
170     public String getId()
171     {
172         return id;
173     }
174 
175     public String getUrl()
176     {
177         return url;
178     }
179 
180     public String getBasedir()
181     {
182         return basedir;
183     }
184 
185     public String getProtocol()
186     {
187         return protocol;
188     }
189 
190     public void setId( String id )
191     {
192         this.id = id;
193     }
194 
195     public void setUrl( String url )
196     {
197         this.url = url;
198 
199         this.protocol = protocol( url );
200         this.basedir = basedir( url );
201     }
202 
203     // Path Utils
204 
205     /**
206      * /**
207      * Return the protocol name.
208      * <br/>
209      * E.g: for input
210      * <code>http://www.codehause.org</code> this method will return <code>http</code>
211      *
212      * @param url the url
213      * @return the host name
214      */
215     private static String protocol( final String url )
216     {
217         final int pos = url.indexOf( ":" );
218 
219         if ( pos == -1 )
220         {
221             return "";
222         }
223         return url.substring( 0, pos ).trim();
224     }
225 
226     /**
227      * Derive the path portion of the given URL.
228      *
229      * @param url the repository URL
230      * @return the basedir of the repository
231      * @todo need to URL decode for spaces?
232      */
233     private String basedir( String url )
234     {
235         String retValue = null;
236 
237         if ( protocol.equalsIgnoreCase( "file" ) )
238         {
239             retValue = url.substring( protocol.length() + 1 );
240             retValue = decode( retValue );
241             // special case: if omitted // on protocol, keep path as is
242             if ( retValue.startsWith( "//" ) )
243             {
244                 retValue = retValue.substring( 2 );
245 
246                 if ( retValue.length() >= 2 && ( retValue.charAt( 1 ) == '|' || retValue.charAt( 1 ) == ':' ) )
247                 {
248                     // special case: if there is a windows drive letter, then keep the original return value
249                     retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
250                 }
251                 else
252                 {
253                     // Now we expect the host
254                     int index = retValue.indexOf( "/" );
255                     if ( index >= 0 )
256                     {
257                         retValue = retValue.substring( index + 1 );
258                     }
259 
260                     // special case: if there is a windows drive letter, then keep the original return value
261                     if ( retValue.length() >= 2 && ( retValue.charAt( 1 ) == '|' || retValue.charAt( 1 ) == ':' ) )
262                     {
263                         retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
264                     }
265                     else if ( index >= 0 )
266                     {
267                         // leading / was previously stripped
268                         retValue = "/" + retValue;
269                     }
270                 }
271             }
272 
273             // special case: if there is a windows drive letter using |, switch to :
274             if ( retValue.length() >= 2 && retValue.charAt( 1 ) == '|' )
275             {
276                 retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
277             }
278 
279             // normalize separators
280             retValue = new File( retValue ).getPath();
281         }
282 
283         if ( retValue == null )
284         {
285             retValue = "/";
286         }
287         return retValue.trim();
288     }
289 
290     /**
291      * Decodes the specified (portion of a) URL. <strong>Note:</strong> This decoder assumes that ISO-8859-1 is used to
292      * convert URL-encoded octets to characters.
293      *
294      * @param url The URL to decode, may be <code>null</code>.
295      * @return The decoded URL or <code>null</code> if the input was <code>null</code>.
296      */
297     private static String decode( String url )
298     {
299         String decoded = url;
300         if ( url != null )
301         {
302             int pos = -1;
303             while ( ( pos = decoded.indexOf( '%', pos + 1 ) ) >= 0 )
304             {
305                 if ( pos + 2 < decoded.length() )
306                 {
307                     String hexStr = decoded.substring( pos + 1, pos + 3 );
308                     char ch = (char) Integer.parseInt( hexStr, 16 );
309                     decoded = decoded.substring( 0, pos ) + ch + decoded.substring( pos + 3 );
310                 }
311             }
312         }
313         return decoded;
314     }
315 
316     public int hashCode()
317     {
318         final int prime = 31;
319         int result = 1;
320         result = prime * result + ( ( getId() == null ) ? 0 : getId().hashCode() );
321         return result;
322     }
323 
324     public boolean equals( Object obj )
325     {
326         if ( this == obj )
327         {
328             return true;
329         }
330         if ( obj == null )
331         {
332             return false;
333         }
334         if ( getClass() != obj.getClass() )
335         {
336             return false;
337         }
338 
339         ArtifactRepository other = (ArtifactRepository) obj;
340 
341         return eq( getId(), other.getId() );
342     }
343 
344     protected static <T> boolean eq( T s1, T s2 )
345     {
346         return s1 != null ? s1.equals( s2 ) : s2 == null;
347     }
348 
349     public Authentication getAuthentication()
350     {
351         return authentication;
352     }
353 
354     public void setAuthentication( Authentication authentication )
355     {
356         this.authentication = authentication;
357     }
358 
359     public Proxy getProxy()
360     {
361         return proxy;
362     }
363 
364     public void setProxy( Proxy proxy )
365     {
366         this.proxy = proxy;
367     }
368 
369     public boolean isBlacklisted()
370     {
371         return false;
372     }
373 
374     public void setBlacklisted( boolean blackListed )
375     {
376         // no op
377     }
378 
379     public boolean isUniqueVersion()
380     {
381         return true;
382     }
383 
384     public boolean isProjectAware()
385     {
386         return false;
387     }
388 
389 }