package org.apache.maven.plugins.invoker; /* * 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. */ import java.io.File; import java.io.IOException; import java.io.Reader; import java.io.Writer; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; import java.util.LinkedHashSet; import java.util.Set; import java.util.TimeZone; import org.apache.maven.artifact.Artifact; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.WriterFactory; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.Xpp3DomBuilder; import org.codehaus.plexus.util.xml.Xpp3DomUtils; import org.codehaus.plexus.util.xml.Xpp3DomWriter; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; /** * Provides utility methods for artifact metadata processing. * * @author Benjamin Bentmann */ class MetadataUtils { /** * Creates local metadata files for the specified artifact. The goal is to simulate the installation of the artifact * by a local build, thereby decoupling the forked builds from the inderministic collection of remote repositories * that are available to the main build and from which the artifact was originally resolved. * * @param file The artifact's file in the local test repository, must not be <code>null</code>. * @param artifact The artifact to create metadata for, must not be <code>null</code>. * @throws IOException If the metadata could not be created. */ public static void createMetadata( File file, Artifact artifact ) throws IOException { TimeZone tz = java.util.TimeZone.getTimeZone( "UTC" ); SimpleDateFormat fmt = new SimpleDateFormat( "yyyyMMddHHmmss" ); fmt.setTimeZone( tz ); String timestamp = fmt.format( new Date() ); if ( artifact.isSnapshot() ) { File metadataFile = new File( file.getParentFile(), "maven-metadata-local.xml" ); Xpp3Dom metadata = new Xpp3Dom( "metadata" ); addChild( metadata, "groupId", artifact.getGroupId() ); addChild( metadata, "artifactId", artifact.getArtifactId() ); addChild( metadata, "version", artifact.getBaseVersion() ); Xpp3Dom versioning = new Xpp3Dom( "versioning" ); versioning.addChild( addChild( new Xpp3Dom( "snapshot" ), "localCopy", "true" ) ); addChild( versioning, "lastUpdated", timestamp ); metadata.addChild( versioning ); writeMetadata( metadataFile, metadata ); } File metadataFile = new File( file.getParentFile().getParentFile(), "maven-metadata-local.xml" ); Set<String> allVersions = new LinkedHashSet<String>(); Xpp3Dom metadata = readMetadata( metadataFile ); if ( metadata != null ) { Xpp3Dom versioning = metadata.getChild( "versioning" ); if ( versioning != null ) { Xpp3Dom versions = versioning.getChild( "versions" ); if ( versions != null ) { Xpp3Dom[] children = versions.getChildren( "version" ); for ( Xpp3Dom aChildren : children ) { allVersions.add( aChildren.getValue() ); } } } } allVersions.add( artifact.getBaseVersion() ); metadata = new Xpp3Dom( "metadata" ); addChild( metadata, "groupId", artifact.getGroupId() ); addChild( metadata, "artifactId", artifact.getArtifactId() ); Xpp3Dom versioning = new Xpp3Dom( "versioning" ); versioning.addChild( addChildren( new Xpp3Dom( "versions" ), "version", allVersions ) ); addChild( versioning, "lastUpdated", timestamp ); metadata.addChild( versioning ); metadata = Xpp3DomUtils.mergeXpp3Dom( metadata, readMetadata( metadataFile ) ); writeMetadata( metadataFile, metadata ); } private static Xpp3Dom addChild( Xpp3Dom parent, String childName, String childValue ) { Xpp3Dom child = new Xpp3Dom( childName ); child.setValue( childValue ); parent.addChild( child ); return parent; } private static Xpp3Dom addChildren( Xpp3Dom parent, String childName, Collection<String> childValues ) { for ( String childValue : childValues ) { addChild( parent, childName, childValue ); } return parent; } private static Xpp3Dom readMetadata( File metadataFile ) throws IOException { if ( !metadataFile.isFile() ) { return null; } Reader reader = null; try { reader = ReaderFactory.newXmlReader( metadataFile ); final Xpp3Dom xpp3Dom = Xpp3DomBuilder.build( reader ); reader.close(); reader = null; return xpp3Dom; } catch ( XmlPullParserException e ) { throw (IOException) new IOException( e.getMessage() ).initCause( e ); } finally { IOUtil.close( reader ); } } private static void writeMetadata( File metadataFile, Xpp3Dom metadata ) throws IOException { metadataFile.getParentFile().mkdirs(); Writer writer = null; try { writer = WriterFactory.newXmlWriter( metadataFile ); Xpp3DomWriter.write( writer, metadata ); writer.close(); writer = null; } finally { IOUtil.close( writer ); } } }