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