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.eclipse.aether.DefaultRepositorySystemSession;
033    import org.eclipse.aether.RepositorySystem;
034    import org.eclipse.aether.RepositorySystemSession;
035    import org.eclipse.aether.artifact.Artifact;
036    import org.eclipse.aether.metadata.Metadata;
037    import org.eclipse.aether.repository.LocalArtifactRegistration;
038    import org.eclipse.aether.repository.LocalArtifactRequest;
039    import org.eclipse.aether.repository.LocalArtifactResult;
040    import org.eclipse.aether.repository.LocalMetadataRegistration;
041    import org.eclipse.aether.repository.LocalMetadataRequest;
042    import org.eclipse.aether.repository.LocalMetadataResult;
043    import org.eclipse.aether.repository.LocalRepository;
044    import org.eclipse.aether.repository.LocalRepositoryManager;
045    import 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     */
053    public 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    }