001package org.apache.maven.artifact.repository;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023import java.util.Collections;
024import java.util.List;
025
026import org.apache.maven.RepositoryUtils;
027import org.apache.maven.artifact.metadata.ArtifactMetadata;
028import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
029import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
030import org.apache.maven.artifact.repository.metadata.RepositoryMetadataStoreException;
031import org.apache.maven.repository.Proxy;
032import org.eclipse.aether.DefaultRepositorySystemSession;
033import org.eclipse.aether.RepositorySystem;
034import org.eclipse.aether.RepositorySystemSession;
035import org.eclipse.aether.artifact.Artifact;
036import org.eclipse.aether.metadata.Metadata;
037import org.eclipse.aether.repository.LocalArtifactRegistration;
038import org.eclipse.aether.repository.LocalArtifactRequest;
039import org.eclipse.aether.repository.LocalArtifactResult;
040import org.eclipse.aether.repository.LocalMetadataRegistration;
041import org.eclipse.aether.repository.LocalMetadataRequest;
042import org.eclipse.aether.repository.LocalMetadataResult;
043import org.eclipse.aether.repository.LocalRepository;
044import org.eclipse.aether.repository.LocalRepositoryManager;
045import org.eclipse.aether.repository.RemoteRepository;
046
047/**
048 * <strong>Warning:</strong> This is an internal utility class that is only public for technical reasons, it is not part
049 * of the public API. In particular, this class can be changed or deleted without prior notice.
050 * 
051 * @author Benjamin Bentmann
052 */
053public class LegacyLocalRepositoryManager
054    implements LocalRepositoryManager
055{
056
057    private final ArtifactRepository delegate;
058
059    private final LocalRepository repo;
060
061    private final boolean realLocalRepo;
062
063    public static RepositorySystemSession overlay( ArtifactRepository repository, RepositorySystemSession session,
064                                                   RepositorySystem system )
065    {
066        if ( repository == null || repository.getBasedir() == null )
067        {
068            return session;
069        }
070
071        if ( session != null )
072        {
073            LocalRepositoryManager lrm = session.getLocalRepositoryManager();
074            if ( lrm != null && lrm.getRepository().getBasedir().equals( new File( repository.getBasedir() ) ) )
075            {
076                return session;
077            }
078        }
079        else
080        {
081            session = new DefaultRepositorySystemSession();
082        }
083
084        final LocalRepositoryManager llrm = new LegacyLocalRepositoryManager( repository );
085
086        return new DefaultRepositorySystemSession( session ).setLocalRepositoryManager( llrm );
087    }
088
089    private LegacyLocalRepositoryManager( ArtifactRepository delegate )
090    {
091        if ( delegate == null )
092        {
093            throw new IllegalArgumentException( "local repository delegate missing" );
094        }
095        this.delegate = delegate;
096
097        ArtifactRepositoryLayout layout = delegate.getLayout();
098        repo =
099            new LocalRepository( new File( delegate.getBasedir() ),
100                                 ( layout != null ) ? layout.getClass().getSimpleName() : "legacy" );
101
102        /*
103         * NOTE: "invoker:install" vs "appassembler:assemble": Both mojos use the artifact installer to put an artifact
104         * into a repository. In the first case, the result needs to be a proper local repository that one can use for
105         * local artifact resolution. In the second case, the result needs to precisely obey the path information of the
106         * repository's layout to allow pointing at artifacts within the repository. Unfortunately,
107         * DefaultRepositoryLayout does not correctly describe the layout of a local repository which unlike a remote
108         * repository never uses timestamps in the filename of a snapshot artifact. The discrepancy gets notable when a
109         * remotely resolved snapshot artifact gets passed into pathOf(). So producing a proper local artifact path
110         * using DefaultRepositoryLayout requires us to enforce usage of the artifact's base version. This
111         * transformation however contradicts the other use case of precisely obeying the repository's layout. The below
112         * flag tries to detect which use case applies to make both plugins happy.
113         */
114        realLocalRepo = ( layout instanceof DefaultRepositoryLayout ) && "local".equals( delegate.getId() );
115    }
116
117    public LocalRepository getRepository()
118    {
119        return repo;
120    }
121
122    public String getPathForLocalArtifact( Artifact artifact )
123    {
124        if ( realLocalRepo )
125        {
126            return delegate.pathOf( RepositoryUtils.toArtifact( artifact.setVersion( artifact.getBaseVersion() ) ) );
127        }
128        return delegate.pathOf( RepositoryUtils.toArtifact( artifact ) );
129    }
130
131    public String getPathForRemoteArtifact( Artifact artifact, RemoteRepository repository, String context )
132    {
133        return delegate.pathOf( RepositoryUtils.toArtifact( artifact ) );
134    }
135
136    public String getPathForLocalMetadata( Metadata metadata )
137    {
138        return delegate.pathOfLocalRepositoryMetadata( new ArtifactMetadataAdapter( metadata ), delegate );
139    }
140
141    public String getPathForRemoteMetadata( Metadata metadata, RemoteRepository repository, String context )
142    {
143        return delegate.pathOfLocalRepositoryMetadata( new ArtifactMetadataAdapter( metadata ),
144                                                       new ArtifactRepositoryAdapter( repository ) );
145    }
146
147    public LocalArtifactResult find( RepositorySystemSession session, LocalArtifactRequest request )
148    {
149        String path = getPathForLocalArtifact( request.getArtifact() );
150        File file = new File( getRepository().getBasedir(), path );
151
152        LocalArtifactResult result = new LocalArtifactResult( request );
153        if ( file.isFile() )
154        {
155            result.setFile( file );
156            result.setAvailable( true );
157        }
158
159        return result;
160    }
161
162    public LocalMetadataResult find( RepositorySystemSession session, LocalMetadataRequest request )
163    {
164        Metadata metadata = request.getMetadata();
165
166        String path;
167        if ( request.getRepository() == null )
168        {
169            path = getPathForLocalMetadata( metadata );
170        }
171        else
172        {
173            path = getPathForRemoteMetadata( metadata, request.getRepository(), request.getContext() );
174        }
175
176        File file = new File( getRepository().getBasedir(), path );
177
178        LocalMetadataResult result = new LocalMetadataResult( request );
179        if ( file.isFile() )
180        {
181            result.setFile( file );
182        }
183
184        return result;
185    }
186
187    public void add( RepositorySystemSession session, LocalArtifactRegistration request )
188    {
189        // noop
190    }
191
192    public void add( RepositorySystemSession session, LocalMetadataRegistration request )
193    {
194        // noop
195    }
196
197    static class ArtifactMetadataAdapter
198        implements ArtifactMetadata
199    {
200
201        private final Metadata metadata;
202
203        public ArtifactMetadataAdapter( Metadata metadata )
204        {
205            this.metadata = metadata;
206        }
207
208        public boolean storedInArtifactVersionDirectory()
209        {
210            return metadata.getVersion().length() > 0;
211        }
212
213        public boolean storedInGroupDirectory()
214        {
215            return metadata.getArtifactId().length() <= 0;
216        }
217
218        public String getGroupId()
219        {
220            return nullify( metadata.getGroupId() );
221        }
222
223        public String getArtifactId()
224        {
225            return nullify( metadata.getArtifactId() );
226        }
227
228        public String getBaseVersion()
229        {
230            return nullify( metadata.getVersion() );
231        }
232
233        private String nullify( String str )
234        {
235            return ( str == null || str.length() <= 0 ) ? null : str;
236        }
237
238        public Object getKey()
239        {
240            return metadata.toString();
241        }
242
243        public String getRemoteFilename()
244        {
245            return metadata.getType();
246        }
247
248        public String getLocalFilename( ArtifactRepository repository )
249        {
250            return insertRepositoryKey( getRemoteFilename(), repository.getKey() );
251        }
252
253        private String insertRepositoryKey( String filename, String repositoryKey )
254        {
255            String result;
256            int idx = filename.indexOf( '.' );
257            if ( idx < 0 )
258            {
259                result = filename + '-' + repositoryKey;
260            }
261            else
262            {
263                result = filename.substring( 0, idx ) + '-' + repositoryKey + filename.substring( idx );
264            }
265            return result;
266        }
267
268        public void merge( org.apache.maven.repository.legacy.metadata.ArtifactMetadata metadata )
269        {
270            // not used
271        }
272
273        public void merge( ArtifactMetadata metadata )
274        {
275            // not used
276        }
277
278        public void storeInLocalRepository( ArtifactRepository localRepository, ArtifactRepository remoteRepository )
279            throws RepositoryMetadataStoreException
280        {
281            // not used
282        }
283
284        public String extendedToString()
285        {
286            return metadata.toString();
287        }
288
289    }
290
291    static class ArtifactRepositoryAdapter
292        implements ArtifactRepository
293    {
294
295        private final RemoteRepository repository;
296
297        public ArtifactRepositoryAdapter( RemoteRepository repository )
298        {
299            this.repository = repository;
300        }
301
302        public String pathOf( org.apache.maven.artifact.Artifact artifact )
303        {
304            return null;
305        }
306
307        public String pathOfRemoteRepositoryMetadata( ArtifactMetadata artifactMetadata )
308        {
309            return null;
310        }
311
312        public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
313        {
314            return null;
315        }
316
317        public String getUrl()
318        {
319            return repository.getUrl();
320        }
321
322        public void setUrl( String url )
323        {
324        }
325
326        public String getBasedir()
327        {
328            return null;
329        }
330
331        public String getProtocol()
332        {
333            return repository.getProtocol();
334        }
335
336        public String getId()
337        {
338            return repository.getId();
339        }
340
341        public void setId( String id )
342        {
343        }
344
345        public ArtifactRepositoryPolicy getSnapshots()
346        {
347            return null;
348        }
349
350        public void setSnapshotUpdatePolicy( ArtifactRepositoryPolicy policy )
351        {
352        }
353
354        public ArtifactRepositoryPolicy getReleases()
355        {
356            return null;
357        }
358
359        public void setReleaseUpdatePolicy( ArtifactRepositoryPolicy policy )
360        {
361        }
362
363        public ArtifactRepositoryLayout getLayout()
364        {
365            return null;
366        }
367
368        public void setLayout( ArtifactRepositoryLayout layout )
369        {
370        }
371
372        public String getKey()
373        {
374            return getId();
375        }
376
377        public boolean isUniqueVersion()
378        {
379            return true;
380        }
381
382        public boolean isBlacklisted()
383        {
384            return false;
385        }
386
387        public void setBlacklisted( boolean blackListed )
388        {
389        }
390
391        public org.apache.maven.artifact.Artifact find( org.apache.maven.artifact.Artifact artifact )
392        {
393            return null;
394        }
395
396        public List<String> findVersions( org.apache.maven.artifact.Artifact artifact )
397        {
398            return Collections.emptyList();
399        }
400
401        public boolean isProjectAware()
402        {
403            return false;
404        }
405
406        public void setAuthentication( Authentication authentication )
407        {
408        }
409
410        public Authentication getAuthentication()
411        {
412            return null;
413        }
414
415        public void setProxy( Proxy proxy )
416        {
417        }
418
419        public Proxy getProxy()
420        {
421            return null;
422        }
423
424        public List<ArtifactRepository> getMirroredRepositories()
425        {
426            return Collections.emptyList();
427        }
428
429        public void setMirroredRepositories( List<ArtifactRepository> mirroredRepositories )
430        {
431        }
432
433    }
434
435}