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