001package org.apache.maven;
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.util.ArrayList;
023import java.util.Collection;
024import java.util.Collections;
025import java.util.List;
026import java.util.Map;
027
028import org.apache.maven.artifact.handler.ArtifactHandler;
029import org.apache.maven.artifact.handler.DefaultArtifactHandler;
030import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
031import org.apache.maven.artifact.repository.ArtifactRepository;
032import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
033import org.eclipse.aether.artifact.Artifact;
034import org.eclipse.aether.artifact.ArtifactProperties;
035import org.eclipse.aether.artifact.ArtifactType;
036import org.eclipse.aether.artifact.ArtifactTypeRegistry;
037import org.eclipse.aether.artifact.DefaultArtifact;
038import org.eclipse.aether.artifact.DefaultArtifactType;
039import org.eclipse.aether.graph.Dependency;
040import org.eclipse.aether.graph.DependencyFilter;
041import org.eclipse.aether.graph.DependencyNode;
042import org.eclipse.aether.graph.Exclusion;
043import org.eclipse.aether.repository.Authentication;
044import org.eclipse.aether.repository.Proxy;
045import org.eclipse.aether.repository.RemoteRepository;
046import org.eclipse.aether.repository.RepositoryPolicy;
047import org.eclipse.aether.util.repository.AuthenticationBuilder;
048
049/**
050 * <strong>Warning:</strong> This is an internal utility class that is only public for technical reasons, it is not part
051 * of the public API. In particular, this class can be changed or deleted without prior notice.
052 *
053 * @author Benjamin Bentmann
054 */
055public class RepositoryUtils
056{
057
058    private static String nullify( String string )
059    {
060        return ( string == null || string.length() <= 0 ) ? null : string;
061    }
062
063    private static org.apache.maven.artifact.Artifact toArtifact( Dependency dependency )
064    {
065        if ( dependency == null )
066        {
067            return null;
068        }
069
070        org.apache.maven.artifact.Artifact result = toArtifact( dependency.getArtifact() );
071        result.setScope( dependency.getScope() );
072        result.setOptional( dependency.isOptional() );
073
074        return result;
075    }
076
077    public static org.apache.maven.artifact.Artifact toArtifact( Artifact artifact )
078    {
079        if ( artifact == null )
080        {
081            return null;
082        }
083
084        ArtifactHandler handler = newHandler( artifact );
085
086        /*
087         * NOTE: From Artifact.hasClassifier(), an empty string and a null both denote "no classifier". However, some
088         * plugins only check for null, so be sure to nullify an empty classifier.
089         */
090        org.apache.maven.artifact.Artifact result =
091            new org.apache.maven.artifact.DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(),
092                                                           artifact.getVersion(), null,
093                                                           artifact.getProperty( ArtifactProperties.TYPE,
094                                                                                 artifact.getExtension() ),
095                                                           nullify( artifact.getClassifier() ), handler );
096
097        result.setFile( artifact.getFile() );
098        result.setResolved( artifact.getFile() != null );
099
100        List<String> trail = new ArrayList<>( 1 );
101        trail.add( result.getId() );
102        result.setDependencyTrail( trail );
103
104        return result;
105    }
106
107    public static void toArtifacts( Collection<org.apache.maven.artifact.Artifact> artifacts,
108                                    Collection<? extends DependencyNode> nodes, List<String> trail,
109                                    DependencyFilter filter )
110    {
111        for ( DependencyNode node : nodes )
112        {
113            org.apache.maven.artifact.Artifact artifact = toArtifact( node.getDependency() );
114
115            List<String> nodeTrail = new ArrayList<>( trail.size() + 1 );
116            nodeTrail.addAll( trail );
117            nodeTrail.add( artifact.getId() );
118
119            if ( filter == null || filter.accept( node, Collections.<DependencyNode>emptyList() ) )
120            {
121                artifact.setDependencyTrail( nodeTrail );
122                artifacts.add( artifact );
123            }
124
125            toArtifacts( artifacts, node.getChildren(), nodeTrail, filter );
126        }
127    }
128
129    public static Artifact toArtifact( org.apache.maven.artifact.Artifact artifact )
130    {
131        if ( artifact == null )
132        {
133            return null;
134        }
135
136        String version = artifact.getVersion();
137        if ( version == null && artifact.getVersionRange() != null )
138        {
139            version = artifact.getVersionRange().toString();
140        }
141
142        Map<String, String> props = null;
143        if ( org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
144        {
145            String localPath = ( artifact.getFile() != null ) ? artifact.getFile().getPath() : "";
146            props = Collections.singletonMap( ArtifactProperties.LOCAL_PATH, localPath );
147        }
148
149        Artifact result =
150            new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier(),
151                                 artifact.getArtifactHandler().getExtension(), version, props,
152                                 newArtifactType( artifact.getType(), artifact.getArtifactHandler() ) );
153        result = result.setFile( artifact.getFile() );
154
155        return result;
156    }
157
158    public static Dependency toDependency( org.apache.maven.artifact.Artifact artifact,
159                                           Collection<org.apache.maven.model.Exclusion> exclusions )
160    {
161        if ( artifact == null )
162        {
163            return null;
164        }
165
166        Artifact result = toArtifact( artifact );
167
168        List<Exclusion> excl = null;
169        if ( exclusions != null )
170        {
171            excl = new ArrayList<>( exclusions.size() );
172            for ( org.apache.maven.model.Exclusion exclusion : exclusions )
173            {
174                excl.add( toExclusion( exclusion ) );
175            }
176        }
177
178        return new Dependency( result, artifact.getScope(), artifact.isOptional(), excl );
179    }
180
181    public static List<RemoteRepository> toRepos( List<ArtifactRepository> repos )
182    {
183        if ( repos == null )
184        {
185            return null;
186        }
187
188        List<RemoteRepository> results = new ArrayList<>( repos.size() );
189        for ( ArtifactRepository repo : repos )
190        {
191            results.add( toRepo( repo ) );
192        }
193        return results;
194    }
195
196    public static RemoteRepository toRepo( ArtifactRepository repo )
197    {
198        RemoteRepository result = null;
199        if ( repo != null )
200        {
201            RemoteRepository.Builder builder =
202                new RemoteRepository.Builder( repo.getId(), getLayout( repo ), repo.getUrl() );
203            builder.setSnapshotPolicy( toPolicy( repo.getSnapshots() ) );
204            builder.setReleasePolicy( toPolicy( repo.getReleases() ) );
205            builder.setAuthentication( toAuthentication( repo.getAuthentication() ) );
206            builder.setProxy( toProxy( repo.getProxy() ) );
207            builder.setMirroredRepositories( toRepos( repo.getMirroredRepositories() ) );
208            result = builder.build();
209        }
210        return result;
211    }
212
213    public static String getLayout( ArtifactRepository repo )
214    {
215        try
216        {
217            return repo.getLayout().getId();
218        }
219        catch ( LinkageError e )
220        {
221            /*
222             * NOTE: getId() was added in 3.x and is as such not implemented by plugins compiled against 2.x APIs.
223             */
224            String className = repo.getLayout().getClass().getSimpleName();
225            if ( className.endsWith( "RepositoryLayout" ) )
226            {
227                String layout = className.substring( 0, className.length() - "RepositoryLayout".length() );
228                if ( layout.length() > 0 )
229                {
230                    layout = Character.toLowerCase( layout.charAt( 0 ) ) + layout.substring( 1 );
231                    return layout;
232                }
233            }
234            return "";
235        }
236    }
237
238    private static RepositoryPolicy toPolicy( ArtifactRepositoryPolicy policy )
239    {
240        RepositoryPolicy result = null;
241        if ( policy != null )
242        {
243            result = new RepositoryPolicy( policy.isEnabled(), policy.getUpdatePolicy(), policy.getChecksumPolicy() );
244        }
245        return result;
246    }
247
248    private static Authentication toAuthentication( org.apache.maven.artifact.repository.Authentication auth )
249    {
250        Authentication result = null;
251        if ( auth != null )
252        {
253            AuthenticationBuilder authBuilder = new AuthenticationBuilder();
254            authBuilder.addUsername( auth.getUsername() ).addPassword( auth.getPassword() );
255            authBuilder.addPrivateKey( auth.getPrivateKey(), auth.getPassphrase() );
256            result = authBuilder.build();
257        }
258        return result;
259    }
260
261    private static Proxy toProxy( org.apache.maven.repository.Proxy proxy )
262    {
263        Proxy result = null;
264        if ( proxy != null )
265        {
266            AuthenticationBuilder authBuilder = new AuthenticationBuilder();
267            authBuilder.addUsername( proxy.getUserName() ).addPassword( proxy.getPassword() );
268            result = new Proxy( proxy.getProtocol(), proxy.getHost(), proxy.getPort(), authBuilder.build() );
269        }
270        return result;
271    }
272
273    public static ArtifactHandler newHandler( Artifact artifact )
274    {
275        String type = artifact.getProperty( ArtifactProperties.TYPE, artifact.getExtension() );
276        DefaultArtifactHandler handler = new DefaultArtifactHandler( type );
277        handler.setExtension( artifact.getExtension() );
278        handler.setLanguage( artifact.getProperty( ArtifactProperties.LANGUAGE, null ) );
279        String addedToClasspath = artifact.getProperty( ArtifactProperties.CONSTITUTES_BUILD_PATH, "" );
280        handler.setAddedToClasspath( Boolean.parseBoolean( addedToClasspath ) );
281        String includesDependencies = artifact.getProperty( ArtifactProperties.INCLUDES_DEPENDENCIES, "" );
282        handler.setIncludesDependencies( Boolean.parseBoolean( includesDependencies ) );
283        return handler;
284    }
285
286    public static ArtifactType newArtifactType( String id, ArtifactHandler handler )
287    {
288        return new DefaultArtifactType( id, handler.getExtension(), handler.getClassifier(), handler.getLanguage(),
289                                        handler.isAddedToClasspath(), handler.isIncludesDependencies() );
290    }
291
292    public static Dependency toDependency( org.apache.maven.model.Dependency dependency,
293                                           ArtifactTypeRegistry stereotypes )
294    {
295        ArtifactType stereotype = stereotypes.get( dependency.getType() );
296        if ( stereotype == null )
297        {
298            stereotype = new DefaultArtifactType( dependency.getType() );
299        }
300
301        boolean system = dependency.getSystemPath() != null && dependency.getSystemPath().length() > 0;
302
303        Map<String, String> props = null;
304        if ( system )
305        {
306            props = Collections.singletonMap( ArtifactProperties.LOCAL_PATH, dependency.getSystemPath() );
307        }
308
309        Artifact artifact =
310            new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), dependency.getClassifier(), null,
311                                 dependency.getVersion(), props, stereotype );
312
313        List<Exclusion> exclusions = new ArrayList<>( dependency.getExclusions().size() );
314        for ( org.apache.maven.model.Exclusion exclusion : dependency.getExclusions() )
315        {
316            exclusions.add( toExclusion( exclusion ) );
317        }
318
319        Dependency result = new Dependency( artifact, dependency.getScope(), dependency.isOptional(), exclusions );
320
321        return result;
322    }
323
324    private static Exclusion toExclusion( org.apache.maven.model.Exclusion exclusion )
325    {
326        return new Exclusion( exclusion.getGroupId(), exclusion.getArtifactId(), "*", "*" );
327    }
328
329    public static ArtifactTypeRegistry newArtifactTypeRegistry( ArtifactHandlerManager handlerManager )
330    {
331        return new MavenArtifactTypeRegistry( handlerManager );
332    }
333
334    static class MavenArtifactTypeRegistry
335        implements ArtifactTypeRegistry
336    {
337
338        private final ArtifactHandlerManager handlerManager;
339
340        public MavenArtifactTypeRegistry( ArtifactHandlerManager handlerManager )
341        {
342            this.handlerManager = handlerManager;
343        }
344
345        public ArtifactType get( String stereotypeId )
346        {
347            ArtifactHandler handler = handlerManager.getArtifactHandler( stereotypeId );
348            return newArtifactType( stereotypeId, handler );
349        }
350
351    }
352
353    public static Collection<Artifact> toArtifacts( Collection<org.apache.maven.artifact.Artifact> artifactsToConvert )
354    {
355        List<Artifact> artifacts = new ArrayList<>();
356        for ( org.apache.maven.artifact.Artifact a : artifactsToConvert )
357        {
358            artifacts.add( toArtifact( a ) );
359        }
360        return artifacts;
361    }
362}