View Javadoc

1   package org.apache.maven.plugin.invoker;
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 java.io.File;
23  import java.io.IOException;
24  import java.io.Reader;
25  import java.io.Writer;
26  import java.text.SimpleDateFormat;
27  import java.util.Collection;
28  import java.util.Date;
29  import java.util.LinkedHashSet;
30  import java.util.Set;
31  import java.util.TimeZone;
32  
33  import org.apache.maven.artifact.Artifact;
34  import org.codehaus.plexus.util.IOUtil;
35  import org.codehaus.plexus.util.ReaderFactory;
36  import org.codehaus.plexus.util.WriterFactory;
37  import org.codehaus.plexus.util.xml.Xpp3Dom;
38  import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
39  import org.codehaus.plexus.util.xml.Xpp3DomUtils;
40  import org.codehaus.plexus.util.xml.Xpp3DomWriter;
41  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
42  
43  /**
44   * Provides utility methods for artifact metadata processing.
45   * 
46   * @author Benjamin Bentmann
47   */
48  class MetadataUtils
49  {
50  
51      /**
52       * Creates local metadata files for the specified artifact. The goal is to simulate the installation of the artifact
53       * by a local build, thereby decoupling the forked builds from the inderministic collection of remote repositories
54       * that are available to the main build and from which the artifact was originally resolved.
55       * 
56       * @param file The artifact's file in the local test repository, must not be <code>null</code>.
57       * @param artifact The artifact to create metadata for, must not be <code>null</code>.
58       * @throws IOException If the metadata could not be created.
59       */
60      public static void createMetadata( File file, Artifact artifact )
61          throws IOException
62      {
63          TimeZone tz = java.util.TimeZone.getTimeZone( "UTC" );
64          SimpleDateFormat fmt = new SimpleDateFormat( "yyyyMMddHHmmss" );
65          fmt.setTimeZone( tz );
66          String timestamp = fmt.format( new Date() );
67  
68          if ( artifact.isSnapshot() )
69          {
70              File metadataFile = new File( file.getParentFile(), "maven-metadata-local.xml" );
71  
72              Xpp3Dom metadata = new Xpp3Dom( "metadata" );
73              addChild( metadata, "groupId", artifact.getGroupId() );
74              addChild( metadata, "artifactId", artifact.getArtifactId() );
75              addChild( metadata, "version", artifact.getBaseVersion() );
76              Xpp3Dom versioning = new Xpp3Dom( "versioning" );
77              versioning.addChild( addChild( new Xpp3Dom( "snapshot" ), "localCopy", "true" ) );
78              addChild( versioning, "lastUpdated", timestamp );
79              metadata.addChild( versioning );
80  
81              writeMetadata( metadataFile, metadata );
82          }
83  
84          {
85              File metadataFile = new File( file.getParentFile().getParentFile(), "maven-metadata-local.xml" );
86  
87              Set<String> allVersions = new LinkedHashSet<String>();
88  
89              Xpp3Dom metadata = readMetadata( metadataFile );
90  
91              if ( metadata != null )
92              {
93                  Xpp3Dom versioning = metadata.getChild( "versioning" );
94                  if ( versioning != null )
95                  {
96                      Xpp3Dom versions = versioning.getChild( "versions" );
97                      if ( versions != null )
98                      {
99  
100                         Xpp3Dom[] children = versions.getChildren( "version" );
101                         for ( int i = 0; i < children.length; i++ )
102                         {
103                             allVersions.add( children[i].getValue() );
104                         }
105                     }
106                 }
107             }
108 
109             allVersions.add( artifact.getBaseVersion() );
110 
111             metadata = new Xpp3Dom( "metadata" );
112             addChild( metadata, "groupId", artifact.getGroupId() );
113             addChild( metadata, "artifactId", artifact.getArtifactId() );
114             Xpp3Dom versioning = new Xpp3Dom( "versioning" );
115             versioning.addChild( addChildren( new Xpp3Dom( "versions" ), "version", allVersions ) );
116             addChild( versioning, "lastUpdated", timestamp );
117             metadata.addChild( versioning );
118 
119             metadata = Xpp3DomUtils.mergeXpp3Dom( metadata, readMetadata( metadataFile ) );
120 
121             writeMetadata( metadataFile, metadata );
122         }
123     }
124 
125     private static Xpp3Dom addChild( Xpp3Dom parent, String childName, String childValue )
126     {
127         Xpp3Dom child = new Xpp3Dom( childName );
128         child.setValue( childValue );
129         parent.addChild( child );
130         return parent;
131     }
132 
133     private static Xpp3Dom addChildren( Xpp3Dom parent, String childName, Collection<String> childValues )
134     {
135         for ( String childValue : childValues )
136         {
137             addChild( parent, childName, childValue );
138         }
139         return parent;
140     }
141 
142     private static Xpp3Dom readMetadata( File metadataFile )
143         throws IOException
144     {
145         if ( !metadataFile.isFile() )
146         {
147             return null;
148         }
149 
150         Reader reader = ReaderFactory.newXmlReader( metadataFile );
151         try
152         {
153             try
154             {
155                 return Xpp3DomBuilder.build( reader );
156             }
157             catch ( XmlPullParserException e )
158             {
159                 throw (IOException) new IOException( e.getMessage() ).initCause( e );
160             }
161         }
162         finally
163         {
164             IOUtil.close( reader );
165         }
166     }
167 
168     private static void writeMetadata( File metadataFile, Xpp3Dom metadata )
169         throws IOException
170     {
171         metadataFile.getParentFile().mkdirs();
172 
173         Writer writer = WriterFactory.newXmlWriter( metadataFile );
174         try
175         {
176             Xpp3DomWriter.write( writer, metadata );
177         }
178         finally
179         {
180             IOUtil.close( writer );
181         }
182     }
183 
184 }