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