View Javadoc
1   package org.apache.maven.archetype.source;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.archetype.catalog.Archetype;
23  import org.apache.maven.archetype.catalog.ArchetypeCatalog;
24  import org.apache.maven.artifact.manager.WagonManager;
25  import org.apache.maven.wagon.Wagon;
26  import org.apache.maven.wagon.WagonException;
27  import org.apache.maven.wagon.authentication.AuthenticationInfo;
28  import org.apache.maven.wagon.proxy.ProxyInfo;
29  import org.apache.maven.wagon.repository.Repository;
30  import org.codehaus.plexus.component.annotations.Component;
31  import org.codehaus.plexus.component.annotations.Requirement;
32  import org.codehaus.plexus.util.ReaderFactory;
33  
34  import java.io.File;
35  import java.io.IOException;
36  import java.util.Properties;
37  
38  /**
39   * @author Jason van Zyl
40   */
41  @Component( role = ArchetypeDataSource.class, hint = "remote-catalog" )
42  public class RemoteCatalogArchetypeDataSource
43      extends CatalogArchetypeDataSource
44  {
45      @Requirement
46      private WagonManager wagonManager;
47  
48      public static final String REPOSITORY_PROPERTY = "repository";
49  
50      /**
51       * Id of the repository used to download catalog file. Proxy or authentication info can
52       * be setup in settings.xml.
53       */
54      public static final String REPOSITORY_ID = "archetype";
55  
56      public ArchetypeCatalog getArchetypeCatalog( Properties properties )
57          throws ArchetypeDataSourceException
58      {
59          String repository = properties.getProperty( REPOSITORY_PROPERTY );
60  
61          if ( repository == null )
62          {
63              throw new ArchetypeDataSourceException( "To use the remote catalog you must specify the 'repository'"
64                  + " property with an URL." );
65          }
66  
67          if ( repository.endsWith( "/" ) )
68          {
69              repository = repository.substring( 0, repository.length() - 1 );
70          }
71  
72          try
73          {
74              return downloadCatalog( repository, ARCHETYPE_CATALOG_FILENAME );
75          }
76          catch ( ArchetypeDataSourceException e )
77          {
78              throw e;
79          }
80          catch ( Exception e )
81          { // When the default archetype catalog name doesn't work, we assume the repository is the URL to a file
82              String repositoryPath = repository.substring( 0, repository.lastIndexOf( "/" ) );
83              String filename = repository.substring( repository.lastIndexOf( "/" ) + 1 );
84  
85              try
86              {
87                  return downloadCatalog( repositoryPath, filename );
88              }
89              catch ( Exception ex )
90              {
91                  getLogger().warn( "Error reading archetype catalog " + repository, ex );
92                  return new ArchetypeCatalog();
93              }
94          }
95      }
96  
97      public void updateCatalog( Properties properties, Archetype archetype )
98          throws ArchetypeDataSourceException
99      {
100         throw new ArchetypeDataSourceException( "Not supported yet." );
101     }
102 
103     private ArchetypeCatalog downloadCatalog( String repositoryPath, String filename )
104         throws WagonException, IOException, ArchetypeDataSourceException
105     {
106         getLogger().debug( "Searching for remote catalog: " + repositoryPath + "/" + filename );
107 
108         // We use wagon to take advantage of a Proxy that has already been setup in a Maven environment.
109         Repository wagonRepository = new Repository( REPOSITORY_ID, repositoryPath );
110         AuthenticationInfo authInfo = wagonManager.getAuthenticationInfo( wagonRepository.getId() );
111         ProxyInfo proxyInfo = wagonManager.getProxy( wagonRepository.getProtocol() );
112 
113         Wagon wagon = wagonManager.getWagon( wagonRepository );
114 
115         File catalog = File.createTempFile( "archetype-catalog", ".xml" );
116         try
117         {
118             wagon.connect( wagonRepository, authInfo, proxyInfo );
119             wagon.get( filename, catalog );
120 
121             return readCatalog( ReaderFactory.newXmlReader( catalog ) );
122         }
123         finally
124         {
125             disconnectWagon( wagon );
126             catalog.delete();
127         }
128     }
129 
130     private void disconnectWagon( Wagon wagon )
131     {
132         try
133         {
134             wagon.disconnect();
135         }
136         catch ( Exception e )
137         {
138             getLogger().warn( "Problem disconnecting from wagon - ignoring: " + e.getMessage() );
139         }
140     }
141 
142 }