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