001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.ivy.plugins.resolver;
019:
020: import java.io.ByteArrayInputStream;
021: import java.io.File;
022: import java.io.IOException;
023: import java.util.ArrayList;
024: import java.util.Arrays;
025: import java.util.Collection;
026: import java.util.Date;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030:
031: import org.apache.ivy.core.IvyPatternHelper;
032: import org.apache.ivy.core.event.EventManager;
033: import org.apache.ivy.core.module.descriptor.Artifact;
034: import org.apache.ivy.core.module.descriptor.DefaultArtifact;
035: import org.apache.ivy.core.module.id.ModuleRevisionId;
036: import org.apache.ivy.core.report.DownloadReport;
037: import org.apache.ivy.core.resolve.DownloadOptions;
038: import org.apache.ivy.plugins.latest.LatestStrategy;
039: import org.apache.ivy.plugins.repository.AbstractRepository;
040: import org.apache.ivy.plugins.repository.Repository;
041: import org.apache.ivy.plugins.repository.Resource;
042: import org.apache.ivy.plugins.resolver.util.ResolvedResource;
043: import org.apache.ivy.plugins.resolver.util.ResolverHelper;
044: import org.apache.ivy.plugins.resolver.util.ResourceMDParser;
045: import org.apache.ivy.plugins.version.VersionMatcher;
046: import org.apache.ivy.util.ChecksumHelper;
047: import org.apache.ivy.util.FileUtil;
048: import org.apache.ivy.util.Message;
049:
050: /**
051: *
052: */
053: public class RepositoryResolver extends AbstractResourceResolver {
054:
055: private Repository repository;
056:
057: private Boolean alwaysCheckExactRevision = null;
058:
059: public RepositoryResolver() {
060: }
061:
062: public Repository getRepository() {
063: return repository;
064: }
065:
066: public void setRepository(Repository repository) {
067: this .repository = repository;
068: }
069:
070: public void setName(String name) {
071: super .setName(name);
072: if (repository instanceof AbstractRepository) {
073: ((AbstractRepository) repository).setName(name);
074: }
075: }
076:
077: protected ResolvedResource findResourceUsingPattern(
078: ModuleRevisionId mrid, String pattern, Artifact artifact,
079: ResourceMDParser rmdparser, Date date) {
080: return findResourceUsingPattern(getName(), getRepository(),
081: getLatestStrategy(), getSettings().getVersionMatcher(),
082: rmdparser, mrid, pattern, artifact, date,
083: isAlwaysCheckExactRevision());
084: }
085:
086: public ResolvedResource findResourceUsingPattern(String name,
087: Repository repository, LatestStrategy strategy,
088: VersionMatcher versionMatcher, ResourceMDParser rmdparser,
089: ModuleRevisionId mrid, String pattern, Artifact artifact,
090: Date date, boolean alwaysCheckExactRevision) {
091: try {
092: if (!versionMatcher.isDynamic(mrid)
093: || alwaysCheckExactRevision) {
094: String resourceName = IvyPatternHelper.substitute(
095: pattern, mrid, artifact);
096: Message.debug("\t trying " + resourceName);
097: logAttempt(resourceName);
098: Resource res = repository.getResource(resourceName);
099: boolean reachable = res.exists();
100: if (reachable) {
101: String revision = pattern
102: .indexOf(IvyPatternHelper.REVISION_KEY) == -1 ? "working@"
103: + name
104: : mrid.getRevision();
105: return new ResolvedResource(res, revision);
106: } else if (versionMatcher.isDynamic(mrid)) {
107: return findDynamicResourceUsingPattern(name,
108: repository, strategy, versionMatcher,
109: rmdparser, mrid, pattern, artifact, date);
110: } else {
111: Message.debug("\t" + name
112: + ": resource not reachable for " + mrid
113: + ": res=" + res);
114: return null;
115: }
116: } else {
117: return findDynamicResourceUsingPattern(name,
118: repository, strategy, versionMatcher,
119: rmdparser, mrid, pattern, artifact, date);
120: }
121: } catch (IOException ex) {
122: throw new RuntimeException(name
123: + ": unable to get resource for "
124: + mrid
125: + ": res="
126: + IvyPatternHelper.substitute(pattern, mrid,
127: artifact) + ": " + ex, ex);
128: }
129: }
130:
131: private ResolvedResource findDynamicResourceUsingPattern(
132: String name, Repository repository,
133: LatestStrategy strategy, VersionMatcher versionMatcher,
134: ResourceMDParser rmdparser, ModuleRevisionId mrid,
135: String pattern, Artifact artifact, Date date) {
136: logAttempt(IvyPatternHelper
137: .substitute(
138: pattern,
139: ModuleRevisionId
140: .newInstance(
141: mrid,
142: IvyPatternHelper
143: .getTokenString(IvyPatternHelper.REVISION_KEY)),
144: artifact));
145: ResolvedResource[] rress = listResources(repository, mrid,
146: pattern, artifact);
147: if (rress == null) {
148: Message.debug("\t" + name
149: + ": unable to list resources for " + mrid
150: + ": pattern=" + pattern);
151: return null;
152: } else {
153: ResolvedResource found = findResource(rress, name,
154: strategy, versionMatcher, rmdparser, mrid, date);
155: if (found == null) {
156: Message.debug("\t" + name + ": no resource found for "
157: + mrid + ": pattern=" + pattern);
158: }
159: return found;
160: }
161: }
162:
163: /**
164: * List all revisions as resolved resources for the given artifact in the given repository using
165: * the given pattern, and using the given mrid except its revision.
166: *
167: * @param repository
168: * the repository in which revisions should be located
169: * @param mrid
170: * the module revision id to look for (except revision)
171: * @param pattern
172: * the pattern to use to locate the revisions
173: * @param artifact
174: * the artifact to find
175: * @return an array of ResolvedResource, all pointing to a different revision of the given
176: * Artifact.
177: */
178: protected ResolvedResource[] listResources(Repository repository,
179: ModuleRevisionId mrid, String pattern, Artifact artifact) {
180: return ResolverHelper.findAll(repository, mrid, pattern,
181: artifact);
182: }
183:
184: protected long get(Resource resource, File dest) throws IOException {
185: Message.verbose("\t" + getName() + ": downloading "
186: + resource.getName());
187: Message.debug("\t\tto " + dest);
188: if (dest.getParentFile() != null) {
189: dest.getParentFile().mkdirs();
190: }
191: repository.get(resource.getName(), dest);
192: return dest.length();
193: }
194:
195: public void publish(Artifact artifact, File src, boolean overwrite)
196: throws IOException {
197: String destPattern;
198: if ("ivy".equals(artifact.getType())
199: && !getIvyPatterns().isEmpty()) {
200: destPattern = (String) getIvyPatterns().get(0);
201: } else if (!getArtifactPatterns().isEmpty()) {
202: destPattern = (String) getArtifactPatterns().get(0);
203: } else {
204: throw new IllegalStateException("impossible to publish "
205: + artifact + " using " + this
206: + ": no artifact pattern defined");
207: }
208: // Check for m2 compatibility
209: ModuleRevisionId mrid = artifact.getModuleRevisionId();
210: if (isM2compatible()) {
211: mrid = convertM2IdForResourceSearch(mrid);
212: }
213:
214: String dest = getDestination(destPattern, artifact, mrid);
215:
216: put(artifact, src, dest, overwrite);
217: Message.info("\tpublished " + artifact.getName() + " to "
218: + hidePassword(dest));
219: }
220:
221: protected String getDestination(String pattern, Artifact artifact,
222: ModuleRevisionId mrid) {
223: return IvyPatternHelper.substitute(pattern, mrid, artifact);
224: }
225:
226: private void put(Artifact artifact, File src, String dest,
227: boolean overwrite) throws IOException {
228: repository.put(artifact, src, dest, overwrite);
229: String[] checksums = getChecksumAlgorithms();
230: for (int i = 0; i < checksums.length; i++) {
231: putChecksum(artifact, src, dest, overwrite, checksums[i]);
232: }
233: }
234:
235: private void putChecksum(Artifact artifact, File src, String dest,
236: boolean overwrite, String algorithm) throws IOException {
237: File csFile = File.createTempFile("ivytemp", algorithm);
238: try {
239: FileUtil.copy(new ByteArrayInputStream(ChecksumHelper
240: .computeAsString(src, algorithm).getBytes()),
241: csFile, null);
242: repository.put(DefaultArtifact.cloneWithAnotherTypeAndExt(
243: artifact, algorithm, artifact.getExt() + "."
244: + algorithm), csFile, dest + "."
245: + algorithm, overwrite);
246: } finally {
247: csFile.delete();
248: }
249: }
250:
251: public DownloadReport download(Artifact[] artifacts,
252: DownloadOptions options) {
253: EventManager eventManager = getEventManager();
254: try {
255: if (eventManager != null) {
256: repository.addTransferListener(eventManager);
257: }
258: return super .download(artifacts, options);
259: } finally {
260: if (eventManager != null) {
261: repository.removeTransferListener(eventManager);
262: }
263: }
264: }
265:
266: protected void findTokenValues(Collection names, List patterns,
267: Map tokenValues, String token) {
268: for (Iterator iter = patterns.iterator(); iter.hasNext();) {
269: String pattern = (String) iter.next();
270: String partiallyResolvedPattern = IvyPatternHelper
271: .substituteTokens(pattern, tokenValues);
272: String[] values = ResolverHelper.listTokenValues(
273: repository, partiallyResolvedPattern, token);
274: if (values != null) {
275: names.addAll(filterNames(new ArrayList(Arrays
276: .asList(values))));
277: }
278: }
279: }
280:
281: public String getTypeName() {
282: return "repository";
283: }
284:
285: public void dumpSettings() {
286: super .dumpSettings();
287: Message.debug("\t\trepository: " + getRepository());
288: }
289:
290: public void setSettings(ResolverSettings settings) {
291: super .setSettings(settings);
292: if (settings != null) {
293: if (alwaysCheckExactRevision == null) {
294: alwaysCheckExactRevision = Boolean
295: .valueOf(settings
296: .getVariable("ivy.default.always.check.exact.revision"));
297: }
298: }
299: }
300:
301: public boolean isAlwaysCheckExactRevision() {
302: return alwaysCheckExactRevision == null ? true
303: : alwaysCheckExactRevision.booleanValue();
304: }
305:
306: public void setAlwaysCheckExactRevision(
307: boolean alwaysCheckExactRevision) {
308: this.alwaysCheckExactRevision = Boolean
309: .valueOf(alwaysCheckExactRevision);
310: }
311:
312: }
|