| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.codehaus.mojo.archetypeng; |
| |
| import org.apache.maven.archetype.descriptor.ArchetypeDescriptorBuilder; |
| import org.apache.maven.artifact.repository.ArtifactRepository; |
| import org.apache.maven.artifact.repository.metadata.GroupRepositoryMetadata; |
| import org.apache.maven.artifact.repository.metadata.Plugin; |
| import org.apache.maven.artifact.repository.metadata.RepositoryMetadata; |
| import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager; |
| import org.apache.maven.artifact.repository.metadata.RepositoryMetadataResolutionException; |
| import org.apache.maven.shared.downloader.DownloadException; |
| import org.apache.maven.shared.downloader.DownloadNotFoundException; |
| import org.apache.maven.shared.downloader.Downloader; |
| |
| import org.codehaus.mojo.archetypeng.archetype.filesets.ArchetypeDescriptor; |
| import org.codehaus.mojo.archetypeng.archetype.filesets.io.xpp3.ArchetypeDescriptorXpp3Reader; |
| import org.codehaus.mojo.archetypeng.exception.UnknownArchetype; |
| import org.codehaus.mojo.archetypeng.exception.UnknownGroup; |
| |
| import org.codehaus.plexus.logging.AbstractLogEnabled; |
| import org.codehaus.plexus.util.StringUtils; |
| import org.codehaus.plexus.util.xml.pull.XmlPullParserException; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.Reader; |
| |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.net.URLClassLoader; |
| |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipException; |
| import java.util.zip.ZipFile; |
| |
| /** |
| * @plexus.component |
| */ |
| public class DefaultArchetypeArtifactManager |
| extends AbstractLogEnabled |
| implements ArchetypeArtifactManager |
| { |
| /** |
| * @plexus.requirement |
| */ |
| private Downloader downloader; |
| |
| /** |
| * @plexus.requirement |
| */ |
| private RepositoryMetadataManager repositoryMetadataManager; |
| |
| public File getArchetypeFile ( |
| final String groupId, |
| final String artifactId, |
| final String version, |
| final ArtifactRepository localRepository, |
| final List repositories |
| ) |
| throws UnknownArchetype |
| { |
| try |
| { |
| return |
| downloader.download ( groupId, artifactId, version, localRepository, repositories ); |
| } |
| catch ( DownloadNotFoundException ex ) |
| { |
| throw new UnknownArchetype ( ex ); |
| } |
| catch ( DownloadException ex ) |
| { |
| throw new UnknownArchetype ( ex ); |
| } |
| } |
| |
| public ClassLoader getArchetypeJarLoader ( File archetypeFile ) |
| throws UnknownArchetype |
| { |
| try |
| { |
| URL[] urls = new URL[1]; |
| |
| urls[0] = archetypeFile.toURI ().toURL (); |
| |
| return new URLClassLoader ( urls ); |
| } |
| catch ( MalformedURLException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| } |
| |
| public ClassLoader getArchetypeJarLoader ( |
| String groupId, |
| String artifactId, |
| String version, |
| ArtifactRepository localRepository, |
| List repositories |
| ) |
| throws UnknownArchetype |
| { |
| try |
| { |
| File archetypeFile = |
| getArchetypeFile ( groupId, artifactId, version, localRepository, repositories ); |
| URL[] urls = new URL[1]; |
| |
| urls[0] = archetypeFile.toURI ().toURL (); |
| |
| return new URLClassLoader ( urls ); |
| } |
| catch ( MalformedURLException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| } |
| |
| public List getArchetypes ( |
| String groupId, |
| ArtifactRepository localRepository, |
| List repositories |
| ) |
| throws UnknownGroup |
| { |
| try |
| { |
| List archetypes = new ArrayList (); |
| |
| RepositoryMetadata metadata = new GroupRepositoryMetadata ( groupId ); |
| |
| repositoryMetadataManager.resolve ( metadata, repositories, localRepository ); |
| |
| for ( |
| Iterator iter = metadata.getMetadata ().getPlugins ().iterator (); |
| iter.hasNext (); |
| ) |
| { |
| Plugin plugin = (Plugin) iter.next (); |
| |
| Archetype archetype = new Archetype (); |
| |
| archetype.setGroupId ( groupId ); |
| archetype.setArtifactId ( plugin.getArtifactId () ); |
| archetype.setName ( plugin.getName () ); |
| archetype.setPrefix ( plugin.getPrefix () ); |
| |
| if ( getLogger ().isDebugEnabled () ) |
| { |
| getLogger ().debug ( "plugin=" + groupId + ":" + plugin.getArtifactId () ); |
| } |
| |
| if ( !archetypes.contains ( archetype ) ) |
| { |
| archetypes.add ( archetype ); |
| } |
| } // end for |
| |
| return archetypes; |
| } |
| catch ( RepositoryMetadataResolutionException e ) |
| { |
| throw new UnknownGroup ( e ); |
| } |
| } |
| |
| public ZipFile getArchetypeZipFile ( File archetypeFile ) |
| throws UnknownArchetype |
| { |
| try |
| { |
| return new ZipFile ( archetypeFile ); |
| } |
| catch ( ZipException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| catch ( IOException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| } |
| |
| public ZipFile getArchetypeZipFile ( |
| String groupId, |
| String artifactId, |
| String version, |
| ArtifactRepository localRepository, |
| List repositories |
| ) |
| throws UnknownArchetype |
| { |
| try |
| { |
| File archetypeFile = |
| getArchetypeFile ( groupId, artifactId, version, localRepository, repositories ); |
| |
| return new ZipFile ( archetypeFile ); |
| } |
| catch ( ZipException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| catch ( IOException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| } |
| |
| public boolean exists ( |
| String groupId, |
| String artifactId, |
| String version, |
| ArtifactRepository localRepository, |
| List repositories |
| ) |
| { |
| try |
| { |
| File archetypeFile = |
| downloader.download ( groupId, artifactId, version, localRepository, repositories ); |
| |
| return archetypeFile.exists (); |
| } |
| catch ( DownloadException e ) |
| { |
| return false; |
| } |
| catch ( DownloadNotFoundException e ) |
| { |
| return false; |
| } |
| } |
| |
| public boolean isFileSetArchetype ( |
| String groupId, |
| String artifactId, |
| String version, |
| ArtifactRepository localRepository, |
| List repositories |
| ) |
| { |
| try |
| { |
| ClassLoader archetypeJarLoader = |
| getArchetypeJarLoader ( |
| groupId, |
| artifactId, |
| version, |
| localRepository, |
| repositories |
| ); |
| |
| org.codehaus.mojo.archetypeng.archetype.filesets.ArchetypeDescriptor descriptor = |
| loadFileSetArchetypeDescriptor ( archetypeJarLoader ); |
| |
| return descriptor.getId () != null; |
| } |
| catch ( XmlPullParserException e ) |
| { |
| return false; |
| } |
| catch ( IOException e ) |
| { |
| return false; |
| } |
| catch ( UnknownArchetype e ) |
| { |
| return false; |
| } |
| } |
| |
| public ArchetypeDescriptor getFileSetArchetypeDescriptor ( File archetypeFile ) |
| throws UnknownArchetype |
| { |
| try |
| { |
| ClassLoader archetypeJarLoader = getArchetypeJarLoader ( archetypeFile ); |
| |
| return loadFileSetArchetypeDescriptor ( archetypeJarLoader ); |
| } |
| catch ( XmlPullParserException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| catch ( IOException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| } |
| |
| public org.codehaus.mojo.archetypeng.archetype.filesets.ArchetypeDescriptor |
| getFileSetArchetypeDescriptor ( |
| String groupId, |
| String artifactId, |
| String version, |
| ArtifactRepository localRepository, |
| List repositories |
| ) |
| throws UnknownArchetype |
| { |
| try |
| { |
| ClassLoader archetypeJarLoader = |
| getArchetypeJarLoader ( |
| groupId, |
| artifactId, |
| version, |
| localRepository, |
| repositories |
| ); |
| |
| return loadFileSetArchetypeDescriptor ( archetypeJarLoader ); |
| } |
| catch ( XmlPullParserException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| catch ( IOException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| } |
| |
| public List getFilesetArchetypeResources ( File archetypeFile ) |
| throws UnknownArchetype |
| { |
| List archetypeResources = new ArrayList (); |
| |
| ZipFile zipFile = getArchetypeZipFile ( archetypeFile ); |
| |
| Enumeration enumeration = zipFile.entries (); |
| while ( enumeration.hasMoreElements () ) |
| { |
| ZipEntry entry = (ZipEntry) enumeration.nextElement (); |
| |
| if ( !entry.isDirectory () |
| && entry.getName ().startsWith ( Constants.ARCHETYPE_RESOURCES ) |
| ) |
| { |
| String resource = |
| StringUtils.replace ( |
| entry.getName (), |
| Constants.ARCHETYPE_RESOURCES + "/", |
| "" |
| ); |
| getLogger ().debug ( "Find resource " + entry.getName () ); |
| archetypeResources.add ( resource ); |
| } |
| else |
| { |
| getLogger ().debug ( "Not resource " + entry.getName () ); |
| } |
| } |
| return archetypeResources; |
| } |
| |
| public List getFilesetArchetypeResources ( |
| String groupId, |
| String artifactId, |
| String version, |
| ArtifactRepository localRepository, |
| List repositories |
| ) |
| throws UnknownArchetype |
| { |
| List archetypeResources = new ArrayList (); |
| |
| ZipFile zipFile = |
| getArchetypeZipFile ( groupId, artifactId, version, localRepository, repositories ); |
| |
| Enumeration enumeration = zipFile.entries (); |
| while ( enumeration.hasMoreElements () ) |
| { |
| ZipEntry entry = (ZipEntry) enumeration.nextElement (); |
| |
| if ( !entry.isDirectory () |
| && entry.getName ().startsWith ( Constants.ARCHETYPE_RESOURCES ) |
| ) |
| { |
| archetypeResources.add ( |
| StringUtils.replace ( |
| entry.getName (), |
| Constants.ARCHETYPE_RESOURCES + "/", |
| "" |
| ) |
| ); |
| } |
| } |
| return archetypeResources; |
| } |
| |
| public boolean isOldArchetype ( |
| String groupId, |
| String artifactId, |
| String version, |
| ArtifactRepository localRepository, |
| List repositories |
| ) |
| { |
| try |
| { |
| ClassLoader archetypeJarLoader = |
| getArchetypeJarLoader ( |
| groupId, |
| artifactId, |
| version, |
| localRepository, |
| repositories |
| ); |
| |
| org.apache.maven.archetype.descriptor.ArchetypeDescriptor descriptor = |
| loadOldArchetypeDescriptor ( archetypeJarLoader ); |
| |
| return descriptor.getId () != null; |
| } |
| catch ( XmlPullParserException e ) |
| { |
| return false; |
| } |
| catch ( IOException e ) |
| { |
| return false; |
| } |
| catch ( UnknownArchetype ex ) |
| { |
| return false; |
| } |
| } |
| |
| public org.apache.maven.archetype.descriptor.ArchetypeDescriptor getOldArchetypeDescriptor ( |
| String groupId, |
| String artifactId, |
| String version, |
| ArtifactRepository localRepository, |
| List repositories |
| ) |
| throws UnknownArchetype |
| { |
| try |
| { |
| ClassLoader archetypeJarLoader = |
| getArchetypeJarLoader ( |
| groupId, |
| artifactId, |
| version, |
| localRepository, |
| repositories |
| ); |
| |
| return loadOldArchetypeDescriptor ( archetypeJarLoader ); |
| } |
| catch ( XmlPullParserException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| catch ( IOException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| } |
| |
| public String getReleaseVersion ( |
| String groupId, |
| String artifactId, |
| ArtifactRepository localRepository, |
| List repositories |
| ) |
| throws UnknownArchetype |
| { |
| try |
| { |
| RepositoryMetadata metadata = |
| new GroupRepositoryMetadata ( groupId + "." + artifactId ); |
| |
| repositoryMetadataManager.resolve ( metadata, repositories, localRepository ); |
| |
| return metadata.getMetadata ().getVersioning ().getRelease (); |
| } |
| catch ( RepositoryMetadataResolutionException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| } |
| |
| public List getVersions ( |
| String groupId, |
| String artifactId, |
| ArtifactRepository localRepository, |
| List repositories |
| ) |
| throws UnknownArchetype |
| { |
| try |
| { |
| RepositoryMetadata metadata = |
| new GroupRepositoryMetadata ( groupId + "." + artifactId ); |
| |
| repositoryMetadataManager.resolve ( metadata, repositories, localRepository ); |
| |
| return metadata.getMetadata ().getVersioning ().getVersions (); |
| } |
| catch ( RepositoryMetadataResolutionException e ) |
| { |
| throw new UnknownArchetype ( e ); |
| } |
| } |
| |
| private Reader getArchetypeDescriptorReader ( ClassLoader archetypeJarLoader ) |
| throws IOException |
| { |
| InputStream is = getStream ( Constants.ARCHETYPE_DESCRIPTOR, archetypeJarLoader ); |
| |
| if ( is == null ) |
| { |
| throw new IOException ( |
| "The " + Constants.ARCHETYPE_DESCRIPTOR + " descriptor cannot be found." |
| ); |
| } |
| |
| return new InputStreamReader ( is ); |
| } |
| |
| private org.codehaus.mojo.archetypeng.archetype.filesets.ArchetypeDescriptor |
| loadFileSetArchetypeDescriptor ( ClassLoader archetypeJarLoader ) |
| throws XmlPullParserException, IOException |
| { |
| Reader reader = getArchetypeDescriptorReader ( archetypeJarLoader ); |
| |
| ArchetypeDescriptorXpp3Reader archetypeReader = new ArchetypeDescriptorXpp3Reader (); |
| |
| try |
| { |
| return archetypeReader.read ( reader, true ); |
| } |
| finally |
| { |
| reader.close (); |
| } |
| } |
| |
| private org.apache.maven.archetype.descriptor.ArchetypeDescriptor loadOldArchetypeDescriptor ( |
| ClassLoader archetypeJarLoader |
| ) |
| throws IOException, XmlPullParserException |
| { |
| ArchetypeDescriptorBuilder builder = new ArchetypeDescriptorBuilder (); |
| |
| org.apache.maven.archetype.descriptor.ArchetypeDescriptor descriptor = null; |
| |
| Reader reader = null; |
| try |
| { |
| reader = getOldArchetypeDescriptorReader ( archetypeJarLoader ); |
| |
| descriptor = builder.build ( reader ); |
| } |
| catch ( IOException ex ) |
| { |
| getLogger ().debug ( "Can not load old archetype", ex ); |
| } |
| catch ( XmlPullParserException ex ) |
| { |
| getLogger ().debug ( "Can not load old archetype", ex ); |
| } |
| finally |
| { |
| if ( reader != null ) |
| { |
| reader.close (); |
| } |
| } |
| |
| if ( descriptor == null ) |
| { |
| try |
| { |
| reader = getOlderArchetypeDescriptorReader ( archetypeJarLoader ); |
| |
| descriptor = builder.build ( reader ); |
| } |
| finally |
| { |
| if ( reader != null ) |
| { |
| reader.close (); |
| } |
| } |
| } |
| |
| return descriptor; |
| } |
| |
| private Reader getOldArchetypeDescriptorReader ( ClassLoader archetypeJarLoader ) |
| throws IOException |
| { |
| InputStream is = getStream ( Constants.OLD_ARCHETYPE_DESCRIPTOR, archetypeJarLoader ); |
| |
| if ( is == null ) |
| { |
| throw new IOException ( |
| "The " + Constants.OLD_ARCHETYPE_DESCRIPTOR + " descriptor cannot be found." |
| ); |
| } |
| |
| return new InputStreamReader ( is ); |
| } |
| |
| private Reader getOlderArchetypeDescriptorReader ( ClassLoader archetypeJarLoader ) |
| throws IOException |
| { |
| InputStream is = getStream ( Constants.OLDER_ARCHETYPE_DESCRIPTOR, archetypeJarLoader ); |
| |
| if ( is == null ) |
| { |
| throw new IOException ( |
| "The " + Constants.OLDER_ARCHETYPE_DESCRIPTOR + " descriptor cannot be found." |
| ); |
| } |
| |
| return new InputStreamReader ( is ); |
| } |
| |
| private InputStream getStream ( String name, ClassLoader loader ) |
| { |
| return |
| ( loader == null ) |
| ? Thread.currentThread ().getContextClassLoader ().getResourceAsStream ( name ) |
| : loader.getResourceAsStream ( name ); |
| } |
| } |