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;
019:
020: import java.io.File;
021: import java.io.IOException;
022: import java.util.ArrayList;
023: import java.util.Collection;
024: import java.util.Date;
025: import java.util.Iterator;
026: import java.util.LinkedHashSet;
027: import java.util.regex.Matcher;
028: import java.util.regex.Pattern;
029:
030: import junit.framework.Assert;
031:
032: import org.apache.ivy.core.cache.DefaultRepositoryCacheManager;
033: import org.apache.ivy.core.event.EventManager;
034: import org.apache.ivy.core.module.descriptor.Artifact;
035: import org.apache.ivy.core.module.descriptor.DefaultArtifact;
036: import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
037: import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
038: import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
039: import org.apache.ivy.core.module.id.ModuleRevisionId;
040: import org.apache.ivy.core.resolve.ResolveData;
041: import org.apache.ivy.core.resolve.ResolveEngine;
042: import org.apache.ivy.core.resolve.ResolveOptions;
043: import org.apache.ivy.core.settings.IvySettings;
044: import org.apache.ivy.core.sort.SortEngine;
045: import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
046: import org.apache.ivy.plugins.resolver.DependencyResolver;
047: import org.apache.ivy.plugins.resolver.FileSystemResolver;
048: import org.apache.ivy.util.FileUtil;
049:
050: public class TestHelper {
051:
052: public static DefaultArtifact newArtifact(String organisation,
053: String module, String revision, String artifact,
054: String type, String ext) {
055: return new DefaultArtifact(ModuleRevisionId.newInstance(
056: organisation, module, revision), new Date(), artifact,
057: type, ext);
058: }
059:
060: public static File getArchiveFileInCache(Ivy ivy,
061: String organisation, String module, String revision,
062: String artifactName, String type, String ext) {
063: DefaultArtifact artifact = newArtifact(organisation, module,
064: revision, artifactName, type, ext);
065: return getRepositoryCacheManager(ivy,
066: artifact.getModuleRevisionId()).getArchiveFileInCache(
067: artifact);
068: }
069:
070: public static DefaultRepositoryCacheManager getRepositoryCacheManager(
071: Ivy ivy, ModuleRevisionId id) {
072: // WARN: this doesn't work if the resolver registered is a compound resolver (chain or dual)
073: // and a sub resolver doesn't use the same cache manager as the parent
074: return (DefaultRepositoryCacheManager) ivy.getSettings()
075: .getResolver(id).getRepositoryCacheManager();
076: }
077:
078: /**
079: * Assertion utility methods to test if a collection of {@link ModuleRevisionId} matches a given
080: * expected set of mrids.
081: * <p>
082: * Expected mrids is given as a String of comma separated string representations of
083: * {@link ModuleRevisionId}.
084: *
085: * @param expectedMrids
086: * the expected set of mrids
087: * @param mrids
088: * the3 mrids to test
089: */
090: public static void assertModuleRevisionIds(String expectedMrids,
091: Collection/* <ModuleRevisionId> */mrids) {
092: Collection expected = parseMrids(expectedMrids);
093: Assert.assertEquals(expected, mrids);
094: }
095:
096: /**
097: * Returns a Set of {@link ModuleRevisionId} corresponding to the given comma separated list of
098: * their text representation.
099: *
100: * @param mrids
101: * the text representation of the {@link ModuleRevisionId}
102: * @return a collection of {@link ModuleRevisionId}
103: */
104: public static Collection parseMrids(String mrids) {
105: String[] m = mrids.split(",?\\s+");
106: Collection c = new LinkedHashSet();
107: for (int i = 0; i < m.length; i++) {
108: c.add(ModuleRevisionId.parse(m[i]));
109: }
110: return c;
111: }
112:
113: /**
114: * Returns an array of {@link ModuleRevisionId} corresponding to the given comma separated list of
115: * their text representation.
116: *
117: * @param mrids
118: * the text representation of the {@link ModuleRevisionId}
119: * @return an array of {@link ModuleRevisionId}
120: */
121: public static ModuleRevisionId[] parseMridsToArray(String mrids) {
122: Collection parsedMrids = parseMrids(mrids);
123: return (ModuleRevisionId[]) parsedMrids
124: .toArray(new ModuleRevisionId[parsedMrids.size()]);
125: }
126:
127: /**
128: * Parses a string represenation of a module descriptor in micro ivy format.
129: * <p>
130: * Examples:
131: * <pre>
132: * #A;1
133: * </pre>
134: * <hr/>
135: * <pre>
136: * #A;2-> #B;[1.0,1.5]
137: * </pre>
138: * <hr/>
139: * <pre>
140: * #A;3-> { #B;[1.0,1.5] #C;[2.0,2.5] }
141: * </pre>
142: * </p>
143: *
144: * @param microIvy the micro ivy description of the module descriptor
145: * @return the parsed module descriptor
146: */
147: public static ModuleDescriptor parseMicroIvyDescriptor(
148: String microIvy) {
149: Pattern mridPattern = ModuleRevisionId.NON_CAPTURING_PATTERN;
150: Matcher m = mridPattern.matcher(microIvy);
151: if (m.matches()) {
152: return DefaultModuleDescriptor.newBasicInstance(
153: ModuleRevisionId.parse(microIvy), new Date());
154: }
155:
156: Pattern oneDependencyPattern = Pattern.compile("("
157: + mridPattern.pattern() + ")\\s*->\\s*("
158: + mridPattern.pattern() + ")");
159: m = oneDependencyPattern.matcher(microIvy);
160: if (m.matches()) {
161: DefaultModuleDescriptor md = DefaultModuleDescriptor
162: .newBasicInstance(ModuleRevisionId
163: .parse(m.group(1)), new Date());
164: md.addDependency(new DefaultDependencyDescriptor(
165: ModuleRevisionId.parse(m.group(2)), false));
166: return md;
167: }
168:
169: String p = "(" + mridPattern.pattern()
170: + ")\\s*->\\s*\\{\\s*((?:" + mridPattern.pattern()
171: + ",?\\s+)*" + mridPattern.pattern() + ")?\\s*\\}";
172: Pattern multipleDependenciesPattern = Pattern.compile(p);
173: m = multipleDependenciesPattern.matcher(microIvy);
174: if (m.matches()) {
175: DefaultModuleDescriptor md = DefaultModuleDescriptor
176: .newBasicInstance(ModuleRevisionId
177: .parse(m.group(1)), new Date());
178: String mrids = m.group(2);
179: if (mrids != null) {
180: Collection depMrids = parseMrids(mrids);
181: for (Iterator iter = depMrids.iterator(); iter
182: .hasNext();) {
183: ModuleRevisionId dep = (ModuleRevisionId) iter
184: .next();
185: md.addDependency(new DefaultDependencyDescriptor(
186: dep, false));
187: }
188: }
189: return md;
190: }
191: throw new IllegalArgumentException("invalid micro ivy format: "
192: + microIvy);
193: }
194:
195: /**
196: * Parses a collection of module descriptors in the micro ivy format, separated by double semi
197: * columns.
198: *
199: * @param microIvy
200: * the text representation of the collection of module descriptors
201: * @return the collection of module descriptors parsed
202: */
203: public static Collection/*<ModuleDescriptor>*/parseMicroIvyDescriptors(
204: String microIvy) {
205: String[] mds = microIvy.split("\\s*;;\\s*");
206: Collection r = new ArrayList();
207: for (int i = 0; i < mds.length; i++) {
208: r.add(parseMicroIvyDescriptor(mds[i]));
209: }
210: return r;
211: }
212:
213: /**
214: * Fills a repository with a set of module, using empty files for published artifacts.
215: *
216: * @param resolver the resolver to use to publish the modules
217: * @param mds the descriptors of the modules to put in the repository
218: * @throws IOException if an IO problem occurs while filling the repository
219: */
220: public static void fillRepository(DependencyResolver resolver,
221: Collection/*<ModuleDescriptor>*/mds) throws IOException {
222: File tmp = File.createTempFile("ivy", "tmp");
223: try {
224: for (Iterator iter = mds.iterator(); iter.hasNext();) {
225: boolean overwrite = false;
226: ModuleDescriptor md = (ModuleDescriptor) iter.next();
227: resolver.beginPublishTransaction(md
228: .getModuleRevisionId(), overwrite);
229: boolean published = false;
230: try {
231: XmlModuleDescriptorWriter.write(md, tmp);
232: resolver.publish(md.getMetadataArtifact(), tmp,
233: overwrite);
234: tmp.delete();
235: tmp.createNewFile();
236: Artifact[] artifacts = md.getAllArtifacts();
237: for (int i = 0; i < artifacts.length; i++) {
238: resolver.publish(artifacts[i], tmp, overwrite);
239: }
240: resolver.commitPublishTransaction();
241: published = true;
242: } finally {
243: if (!published) {
244: resolver.abortPublishTransaction();
245: }
246: }
247: }
248: } finally {
249: tmp.delete();
250: }
251: }
252:
253: /**
254: * A file system resolver which can be used with the
255: * {@link #fillRepository(DependencyResolver, Collection)} method to create a test case of
256: * module descriptor.
257: * <p>
258: * When finished you should call {@link #cleanTestRepository()}
259: * </p>
260: */
261: public static FileSystemResolver newTestRepository() {
262: FileSystemResolver testRepository = new FileSystemResolver();
263: testRepository.setName("test");
264: testRepository
265: .addIvyPattern("build/test/test-repo/[organisation]/[module]/[revision]/[artifact].[ext]");
266: testRepository
267: .addArtifactPattern("build/test/test-repo/[organisation]/[module]/[revision]/[artifact].[ext]");
268: return testRepository;
269: }
270:
271: /**
272: * Cleans up the test repository.
273: * @see #newTestRepository()
274: */
275: public static void cleanTestRepository() {
276: FileUtil.forceDelete(new File("build/test/test-repo"));
277: }
278:
279: /**
280: * Cleans up the test repository and cache.
281: * @see #newTestSettings()
282: */
283: public static void cleanTest() {
284: cleanTestRepository();
285: FileUtil.forceDelete(new File("build/test/cache"));
286: }
287:
288: /**
289: * Init a test resolver as default, useful combined with
290: * {@link #fillRepository(DependencyResolver, Collection)}.
291: *
292: * @param settings
293: * the settings to initialize
294: * @return test settings
295: */
296: public static IvySettings loadTestSettings(IvySettings settings) {
297: settings.setDefaultCache(new File("build/test/cache"));
298: settings.addResolver(newTestRepository());
299: settings.setDefaultResolver("test");
300: return settings;
301: }
302:
303: /**
304: * Create basic resolve data using the given settings
305: *
306: * @param settings
307: * the settings to use to create the resolve data
308: * @return basic resolve data useful for testing
309: */
310: public static ResolveData newResolveData(IvySettings settings) {
311: return new ResolveData(new ResolveEngine(settings,
312: new EventManager(), new SortEngine(settings)),
313: newResolveOptions(settings));
314: }
315:
316: /**
317: * Create basic resolve options using the given settings
318: *
319: * @param settings
320: * the settings to use to create the resolve options
321: * @return the basic resolve options, useful for testing
322: */
323: public static ResolveOptions newResolveOptions(IvySettings settings) {
324: return new ResolveOptions();
325: }
326: }
|