View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.artifact.repository.metadata;
20  
21  import javax.xml.stream.XMLStreamException;
22  
23  import java.io.File;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.OutputStream;
27  import java.nio.file.Files;
28  
29  import org.apache.maven.artifact.Artifact;
30  import org.apache.maven.artifact.metadata.ArtifactMetadata;
31  import org.apache.maven.artifact.repository.ArtifactRepository;
32  import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
33  import org.apache.maven.metadata.v4.MetadataStaxReader;
34  import org.apache.maven.metadata.v4.MetadataStaxWriter;
35  
36  /**
37   * Shared methods of the repository metadata handling.
38   *
39   */
40  @Deprecated
41  public abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
42      private static final String LS = System.lineSeparator();
43  
44      private Metadata metadata;
45  
46      protected AbstractRepositoryMetadata(Metadata metadata) {
47          this.metadata = metadata;
48      }
49  
50      public String getRemoteFilename() {
51          return "maven-metadata.xml";
52      }
53  
54      public String getLocalFilename(ArtifactRepository repository) {
55          return "maven-metadata-" + repository.getKey() + ".xml";
56      }
57  
58      public void storeInLocalRepository(ArtifactRepository localRepository, ArtifactRepository remoteRepository)
59              throws RepositoryMetadataStoreException {
60          try {
61              updateRepositoryMetadata(localRepository, remoteRepository);
62          } catch (IOException | XMLStreamException e) {
63              throw new RepositoryMetadataStoreException("Error updating group repository metadata", e);
64          }
65      }
66  
67      protected void updateRepositoryMetadata(ArtifactRepository localRepository, ArtifactRepository remoteRepository)
68              throws IOException, XMLStreamException {
69          Metadata metadata = null;
70  
71          File metadataFile = new File(
72                  localRepository.getBasedir(), localRepository.pathOfLocalRepositoryMetadata(this, remoteRepository));
73  
74          if (metadataFile.length() == 0) {
75              if (!metadataFile.delete()) {
76                  // sleep for 10ms just in case this is windows holding a file lock
77                  try {
78                      Thread.sleep(10);
79                  } catch (InterruptedException e) {
80                      // ignore
81                  }
82                  metadataFile.delete(); // if this fails, forget about it, we'll try to overwrite it anyway so no need
83                  // to delete on exit
84              }
85          } else if (metadataFile.exists()) {
86              try (InputStream input = Files.newInputStream(metadataFile.toPath())) {
87                  metadata = new Metadata(new MetadataStaxReader().read(input, false));
88              }
89          }
90  
91          boolean changed;
92  
93          // If file could not be found or was not valid, start from scratch
94          if (metadata == null) {
95              metadata = this.metadata;
96  
97              changed = true;
98          } else {
99              changed = metadata.merge(this.metadata);
100         }
101 
102         // beware meta-versions!
103         String version = metadata.getVersion();
104         if (Artifact.LATEST_VERSION.equals(version) || Artifact.RELEASE_VERSION.equals(version)) {
105             // meta-versions are not valid <version/> values...don't write them.
106             metadata.setVersion(null);
107         }
108 
109         if (changed || !metadataFile.exists()) {
110             metadataFile.getParentFile().mkdirs();
111             try (OutputStream output = Files.newOutputStream(metadataFile.toPath())) {
112                 MetadataStaxWriter mappingWriter = new MetadataStaxWriter();
113                 mappingWriter.write(output, metadata.getDelegate());
114             }
115         } else {
116             metadataFile.setLastModified(System.currentTimeMillis());
117         }
118     }
119 
120     public String toString() {
121         return "repository metadata for: '" + getKey() + "'";
122     }
123 
124     protected static Metadata createMetadata(Artifact artifact, Versioning versioning) {
125         Metadata metadata = new Metadata();
126         metadata.setGroupId(artifact.getGroupId());
127         metadata.setArtifactId(artifact.getArtifactId());
128         metadata.setVersion(artifact.getVersion());
129         metadata.setVersioning(versioning);
130         return metadata;
131     }
132 
133     protected static Versioning createVersioning(Snapshot snapshot) {
134         Versioning versioning = new Versioning();
135         versioning.setSnapshot(snapshot);
136         return versioning;
137     }
138 
139     public void setMetadata(Metadata metadata) {
140         this.metadata = metadata;
141     }
142 
143     public Metadata getMetadata() {
144         return metadata;
145     }
146 
147     public void merge(org.apache.maven.repository.legacy.metadata.ArtifactMetadata metadata) {
148         // TODO not sure that it should assume this, maybe the calls to addMetadata should pre-merge, then artifact
149         // replaces?
150         AbstractRepositoryMetadata repoMetadata = (AbstractRepositoryMetadata) metadata;
151         this.metadata.merge(repoMetadata.getMetadata());
152     }
153 
154     public void merge(ArtifactMetadata metadata) {
155         // TODO not sure that it should assume this, maybe the calls to addMetadata should pre-merge, then artifact
156         // replaces?
157         AbstractRepositoryMetadata repoMetadata = (AbstractRepositoryMetadata) metadata;
158         this.metadata.merge(repoMetadata.getMetadata());
159     }
160 
161     public String extendedToString() {
162         StringBuilder buffer = new StringBuilder(256);
163 
164         buffer.append(LS).append("Repository Metadata").append(LS).append("--------------------------");
165         buffer.append(LS).append("GroupId: ").append(getGroupId());
166         buffer.append(LS).append("ArtifactId: ").append(getArtifactId());
167         buffer.append(LS).append("Metadata Type: ").append(getClass().getName());
168 
169         return buffer.toString();
170     }
171 
172     public int getNature() {
173         return RELEASE;
174     }
175 
176     public ArtifactRepositoryPolicy getPolicy(ArtifactRepository repository) {
177         int nature = getNature();
178         if ((nature & RepositoryMetadata.RELEASE_OR_SNAPSHOT) == RepositoryMetadata.RELEASE_OR_SNAPSHOT) {
179             ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy(repository.getReleases());
180             policy.merge(repository.getSnapshots());
181             return policy;
182         } else if ((nature & RepositoryMetadata.SNAPSHOT) != 0) {
183             return repository.getSnapshots();
184         } else {
185             return repository.getReleases();
186         }
187     }
188 }