View Javadoc
1   package org.apache.maven.artifact.repository.metadata;
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  
27  import org.apache.maven.artifact.Artifact;
28  import org.apache.maven.artifact.metadata.ArtifactMetadata;
29  import org.apache.maven.artifact.repository.ArtifactRepository;
30  import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
31  import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
32  import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer;
33  import org.codehaus.plexus.util.IOUtil;
34  import org.codehaus.plexus.util.ReaderFactory;
35  import org.codehaus.plexus.util.WriterFactory;
36  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
37  
38  /**
39   * Shared methods of the repository metadata handling.
40   *
41   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
42   */
43  public abstract class AbstractRepositoryMetadata
44      implements RepositoryMetadata
45  {
46      private Metadata metadata;
47  
48      protected AbstractRepositoryMetadata( Metadata metadata )
49      {
50          this.metadata = metadata;
51      }
52  
53      public String getRemoteFilename()
54      {
55          return "maven-metadata.xml";
56      }
57  
58      public String getLocalFilename( ArtifactRepository repository )
59      {
60          return "maven-metadata-" + repository.getKey() + ".xml";
61      }
62  
63      public void storeInLocalRepository( ArtifactRepository localRepository,
64                                          ArtifactRepository remoteRepository )
65          throws RepositoryMetadataStoreException
66      {
67          try
68          {
69              updateRepositoryMetadata( localRepository, remoteRepository );
70          }
71          catch ( IOException e )
72          {
73              throw new RepositoryMetadataStoreException( "Error updating group repository metadata", e );
74          }
75          catch ( XmlPullParserException e )
76          {
77              throw new RepositoryMetadataStoreException( "Error updating group repository metadata", e );
78          }
79      }
80  
81      protected void updateRepositoryMetadata( ArtifactRepository localRepository,
82                                               ArtifactRepository remoteRepository )
83          throws IOException, XmlPullParserException
84      {
85          MetadataXpp3Reader mappingReader = new MetadataXpp3Reader();
86  
87          Metadata metadata = null;
88  
89          File metadataFile = new File( localRepository.getBasedir(),
90              localRepository.pathOfLocalRepositoryMetadata( this, remoteRepository ) );
91  
92          if ( metadataFile.length() == 0 )
93          {
94              if ( !metadataFile.delete() )
95              {
96                  // sleep for 10ms just in case this is windows holding a file lock
97                  try
98                  {
99                      Thread.sleep( 10 );
100                 }
101                 catch ( InterruptedException e )
102                 {
103                     // ignore
104                 }
105                 metadataFile.delete(); // if this fails, forget about it, we'll try to overwrite it anyway so no need
106                                        // to delete on exit
107             }
108         }
109         else if ( metadataFile.exists() )
110         {
111             Reader reader = null;
112 
113             try
114             {
115                 reader = ReaderFactory.newXmlReader( metadataFile );
116 
117                 metadata = mappingReader.read( reader, false );
118             }
119             finally
120             {
121                 IOUtil.close( reader );
122             }
123         }
124 
125         boolean changed;
126 
127         // If file could not be found or was not valid, start from scratch
128         if ( metadata == null )
129         {
130             metadata = this.metadata;
131 
132             changed = true;
133         }
134         else
135         {
136             changed = metadata.merge( this.metadata );
137         }
138 
139         // beware meta-versions!
140         String version = metadata.getVersion();
141         if ( version != null && ( Artifact.LATEST_VERSION.equals( version ) || Artifact.RELEASE_VERSION.equals(
142             version ) ) )
143         {
144             // meta-versions are not valid <version/> values...don't write them.
145             metadata.setVersion( null );
146         }
147 
148         if ( changed || !metadataFile.exists() )
149         {
150             Writer writer = null;
151             try
152             {
153                 metadataFile.getParentFile().mkdirs();
154                 writer = WriterFactory.newXmlWriter( metadataFile );
155 
156                 MetadataXpp3Writer mappingWriter = new MetadataXpp3Writer();
157 
158                 mappingWriter.write( writer, metadata );
159             }
160             finally
161             {
162                 IOUtil.close( writer );
163             }
164         }
165         else
166         {
167             metadataFile.setLastModified( System.currentTimeMillis() );
168         }
169     }
170 
171     public String toString()
172     {
173         return "repository metadata for: \'" + getKey() + "\'";
174     }
175 
176     protected static Metadata createMetadata( Artifact artifact,
177                                               Versioning versioning )
178     {
179         Metadata metadata = new Metadata();
180         metadata.setGroupId( artifact.getGroupId() );
181         metadata.setArtifactId( artifact.getArtifactId() );
182         metadata.setVersion( artifact.getVersion() );
183         metadata.setVersioning( versioning );
184         return metadata;
185     }
186 
187     protected static Versioning createVersioning( Snapshot snapshot )
188     {
189         Versioning versioning = new Versioning();
190         versioning.setSnapshot( snapshot );
191         versioning.updateTimestamp();
192         return versioning;
193     }
194 
195     public void setMetadata( Metadata metadata )
196     {
197         this.metadata = metadata;
198     }
199 
200     public Metadata getMetadata()
201     {
202         return metadata;
203     }
204 
205     public void merge( org.apache.maven.repository.legacy.metadata.ArtifactMetadata metadata )
206     {
207         // TODO: not sure that it should assume this, maybe the calls to addMetadata should pre-merge, then artifact replaces?
208         AbstractRepositoryMetadata repoMetadata = (AbstractRepositoryMetadata) metadata;
209         this.metadata.merge( repoMetadata.getMetadata() );
210     }
211 
212     public void merge( ArtifactMetadata metadata )
213     {
214         // TODO: not sure that it should assume this, maybe the calls to addMetadata should pre-merge, then artifact replaces?
215         AbstractRepositoryMetadata repoMetadata = (AbstractRepositoryMetadata) metadata;
216         this.metadata.merge( repoMetadata.getMetadata() );
217     }
218 
219     public String extendedToString()
220     {
221         StringBuilder buffer = new StringBuilder();
222 
223         buffer.append( "\nRepository Metadata\n--------------------------" );
224         buffer.append( "\nGroupId: " ).append( getGroupId() );
225         buffer.append( "\nArtifactId: " ).append( getArtifactId() );
226         buffer.append( "\nMetadata Type: " ).append( getClass().getName() );
227 
228         return buffer.toString();
229     }
230 
231     public int getNature()
232     {
233         return RELEASE;
234     }
235 
236     public ArtifactRepositoryPolicy getPolicy( ArtifactRepository repository )
237     {
238         int nature = getNature();
239         if ( ( nature & RepositoryMetadata.RELEASE_OR_SNAPSHOT ) == RepositoryMetadata.RELEASE_OR_SNAPSHOT )
240         {
241             ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy( repository.getReleases() );
242             policy.merge( repository.getSnapshots() );
243             return policy;
244         }
245         else if ( ( nature & RepositoryMetadata.SNAPSHOT ) != 0 )
246         {
247             return repository.getSnapshots();
248         }
249         else
250         {
251             return repository.getReleases();
252         }
253     }
254 
255 }