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