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