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      * Return the protocol name.
209      * <br/>
210      * E.g: for input
211      * <code>http://www.codehause.org</code> this method will return <code>http</code>
212      *
213      * @param url the url
214      * @return the host name
215      */
216     private static String protocol( final String url )
217     {
218         final int pos = url.indexOf( ":" );
219 
220         if ( pos == -1 )
221         {
222             return "";
223         }
224         return url.substring( 0, pos ).trim();
225     }
226 
227     /**
228      * Derive the path portion of the given URL.
229      *
230      * @param url the repository URL
231      * @return the basedir of the repository
232      * @todo need to URL decode for spaces?
233      */
234     private String basedir( String url )
235     {
236         String retValue = null;
237 
238         if ( protocol.equalsIgnoreCase( "file" ) )
239         {
240             retValue = url.substring( protocol.length() + 1 );
241             retValue = decode( retValue );
242             // special case: if omitted // on protocol, keep path as is
243             if ( retValue.startsWith( "//" ) )
244             {
245                 retValue = retValue.substring( 2 );
246 
247                 if ( retValue.length() >= 2 && ( retValue.charAt( 1 ) == '|' || retValue.charAt( 1 ) == ':' ) )
248                 {
249                     // special case: if there is a windows drive letter, then keep the original return value
250                     retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
251                 }
252                 else
253                 {
254                     // Now we expect the host
255                     int index = retValue.indexOf( "/" );
256                     if ( index >= 0 )
257                     {
258                         retValue = retValue.substring( index + 1 );
259                     }
260 
261                     // special case: if there is a windows drive letter, then keep the original return value
262                     if ( retValue.length() >= 2 && ( retValue.charAt( 1 ) == '|' || retValue.charAt( 1 ) == ':' ) )
263                     {
264                         retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
265                     }
266                     else if ( index >= 0 )
267                     {
268                         // leading / was previously stripped
269                         retValue = "/" + retValue;
270                     }
271                 }
272             }
273 
274             // special case: if there is a windows drive letter using |, switch to :
275             if ( retValue.length() >= 2 && retValue.charAt( 1 ) == '|' )
276             {
277                 retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
278             }
279 
280             // normalize separators
281             retValue = new File( retValue ).getPath();
282         }
283 
284         if ( retValue == null )
285         {
286             retValue = "/";
287         }
288         return retValue.trim();
289     }
290 
291     /**
292      * Decodes the specified (portion of a) URL. <strong>Note:</strong> This decoder assumes that ISO-8859-1 is used to
293      * convert URL-encoded bytes to characters.
294      *
295      * @param url The URL to decode, may be <code>null</code>.
296      * @return The decoded URL or <code>null</code> if the input was <code>null</code>.
297      */
298     private static String decode( String url )
299     {
300         String decoded = url;
301         if ( url != null )
302         {
303             int pos = -1;
304             while ( ( pos = decoded.indexOf( '%', pos + 1 ) ) >= 0 )
305             {
306                 if ( pos + 2 < decoded.length() )
307                 {
308                     String hexStr = decoded.substring( pos + 1, pos + 3 );
309                     char ch = (char) Integer.parseInt( hexStr, 16 );
310                     decoded = decoded.substring( 0, pos ) + ch + decoded.substring( pos + 3 );
311                 }
312             }
313         }
314         return decoded;
315     }
316 
317     public int hashCode()
318     {
319         final int prime = 31;
320         int result = 1;
321         result = prime * result + ( ( getId() == null ) ? 0 : getId().hashCode() );
322         return result;
323     }
324 
325     public boolean equals( Object obj )
326     {
327         if ( this == obj )
328         {
329             return true;
330         }
331         if ( obj == null )
332         {
333             return false;
334         }
335         if ( getClass() != obj.getClass() )
336         {
337             return false;
338         }
339 
340         ArtifactRepository other = (ArtifactRepository) obj;
341 
342         return eq( getId(), other.getId() );
343     }
344 
345     protected static <T> boolean eq( T s1, T s2 )
346     {
347         return s1 != null ? s1.equals( s2 ) : s2 == null;
348     }
349 
350     public Authentication getAuthentication()
351     {
352         return authentication;
353     }
354 
355     public void setAuthentication( Authentication authentication )
356     {
357         this.authentication = authentication;
358     }
359 
360     public Proxy getProxy()
361     {
362         return proxy;
363     }
364 
365     public void setProxy( Proxy proxy )
366     {
367         this.proxy = proxy;
368     }
369 
370     public boolean isBlacklisted()
371     {
372         return false;
373     }
374 
375     public void setBlacklisted( boolean blackListed )
376     {
377         // no op
378     }
379 
380     public boolean isUniqueVersion()
381     {
382         return true;
383     }
384 
385     public boolean isProjectAware()
386     {
387         return false;
388     }
389 
390     public List<ArtifactRepository> getMirroredRepositories()
391     {
392         return mirroredRepositories;
393     }
394 
395     public void setMirroredRepositories( List<ArtifactRepository> mirroredRepositories )
396     {
397         if ( mirroredRepositories != null )
398         {
399             this.mirroredRepositories = mirroredRepositories;
400         }
401         else
402         {
403             this.mirroredRepositories = Collections.emptyList();
404         }
405     }
406 
407 }