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.repository.legacy.resolver.transform;
20  
21  import javax.inject.Named;
22  import javax.inject.Singleton;
23  
24  import java.text.DateFormat;
25  import java.text.SimpleDateFormat;
26  import java.util.Date;
27  import java.util.GregorianCalendar;
28  import java.util.TimeZone;
29  
30  import org.apache.maven.artifact.Artifact;
31  import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
32  import org.apache.maven.artifact.repository.ArtifactRepository;
33  import org.apache.maven.artifact.repository.RepositoryRequest;
34  import org.apache.maven.artifact.repository.metadata.Metadata;
35  import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
36  import org.apache.maven.artifact.repository.metadata.RepositoryMetadataResolutionException;
37  import org.apache.maven.artifact.repository.metadata.Snapshot;
38  import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;
39  import org.apache.maven.artifact.repository.metadata.Versioning;
40  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
41  
42  /**
43   */
44  @Named("snapshot")
45  @Singleton
46  @Deprecated
47  public class SnapshotTransformation extends AbstractVersionTransformation {
48      private static final String DEFAULT_SNAPSHOT_TIMESTAMP_FORMAT = "yyyyMMdd.HHmmss";
49  
50      private static final TimeZone DEFAULT_SNAPSHOT_TIME_ZONE = TimeZone.getTimeZone("Etc/UTC");
51  
52      private String deploymentTimestamp;
53  
54      @Override
55      public void transformForResolve(Artifact artifact, RepositoryRequest request) throws ArtifactResolutionException {
56          // Only select snapshots that are unresolved (eg 1.0-SNAPSHOT, not 1.0-20050607.123456)
57          if (artifact.isSnapshot() && artifact.getBaseVersion().equals(artifact.getVersion())) {
58              try {
59                  String version = resolveVersion(artifact, request);
60                  artifact.updateVersion(version, request.getLocalRepository());
61              } catch (RepositoryMetadataResolutionException e) {
62                  throw new ArtifactResolutionException(e.getMessage(), artifact, e);
63              }
64          }
65      }
66  
67      @Override
68      public void transformForInstall(Artifact artifact, ArtifactRepository localRepository) {
69          if (artifact.isSnapshot()) {
70              Snapshot snapshot = new Snapshot();
71              snapshot.setLocalCopy(true);
72              RepositoryMetadata metadata = new SnapshotArtifactRepositoryMetadata(artifact, snapshot);
73  
74              artifact.addMetadata(metadata);
75          }
76      }
77  
78      @Override
79      public void transformForDeployment(
80              Artifact artifact, ArtifactRepository remoteRepository, ArtifactRepository localRepository)
81              throws ArtifactDeploymentException {
82          if (artifact.isSnapshot()) {
83              Snapshot snapshot = new Snapshot();
84  
85              // TODO Should this be changed for MNG-6754 too?
86              snapshot.setTimestamp(getDeploymentTimestamp());
87  
88              // we update the build number anyway so that it doesn't get lost. It requires the timestamp to take effect
89              try {
90                  int buildNumber = resolveLatestSnapshotBuildNumber(artifact, localRepository, remoteRepository);
91  
92                  snapshot.setBuildNumber(buildNumber + 1);
93              } catch (RepositoryMetadataResolutionException e) {
94                  throw new ArtifactDeploymentException(
95                          "Error retrieving previous build number for artifact '" + artifact.getDependencyConflictId()
96                                  + "': " + e.getMessage(),
97                          e);
98              }
99  
100             RepositoryMetadata metadata = new SnapshotArtifactRepositoryMetadata(artifact, snapshot);
101 
102             artifact.setResolvedVersion(
103                     constructVersion(metadata.getMetadata().getVersioning(), artifact.getBaseVersion()));
104 
105             artifact.addMetadata(metadata);
106         }
107     }
108 
109     public String getDeploymentTimestamp() {
110         if (deploymentTimestamp == null) {
111             deploymentTimestamp = getUtcDateFormatter().format(new Date());
112         }
113         return deploymentTimestamp;
114     }
115 
116     @Override
117     protected String constructVersion(Versioning versioning, String baseVersion) {
118         String version = null;
119         Snapshot snapshot = versioning.getSnapshot();
120         if (snapshot != null) {
121             if (snapshot.getTimestamp() != null && snapshot.getBuildNumber() > 0) {
122                 String newVersion = snapshot.getTimestamp() + "-" + snapshot.getBuildNumber();
123                 version = baseVersion.replace(Artifact.SNAPSHOT_VERSION, newVersion);
124             } else {
125                 version = baseVersion;
126             }
127         }
128         return version;
129     }
130 
131     private int resolveLatestSnapshotBuildNumber(
132             Artifact artifact, ArtifactRepository localRepository, ArtifactRepository remoteRepository)
133             throws RepositoryMetadataResolutionException {
134         RepositoryMetadata metadata = new SnapshotArtifactRepositoryMetadata(artifact);
135 
136         getLogger().info("Retrieving previous build number from " + remoteRepository.getId());
137         repositoryMetadataManager.resolveAlways(metadata, localRepository, remoteRepository);
138 
139         int buildNumber = 0;
140         Metadata repoMetadata = metadata.getMetadata();
141         if ((repoMetadata != null)
142                 && (repoMetadata.getVersioning() != null
143                         && repoMetadata.getVersioning().getSnapshot() != null)) {
144             buildNumber = repoMetadata.getVersioning().getSnapshot().getBuildNumber();
145         }
146         return buildNumber;
147     }
148 
149     public static DateFormat getUtcDateFormatter() {
150         DateFormat utcDateFormatter = new SimpleDateFormat(DEFAULT_SNAPSHOT_TIMESTAMP_FORMAT);
151         utcDateFormatter.setCalendar(new GregorianCalendar());
152         utcDateFormatter.setTimeZone(DEFAULT_SNAPSHOT_TIME_ZONE);
153         return utcDateFormatter;
154     }
155 }