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.io.InputStream;
023: import java.net.URL;
024: import java.text.ParseException;
025: import java.text.SimpleDateFormat;
026: import java.util.Collection;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030: import java.util.Properties;
031:
032: import org.apache.ivy.core.IvyContext;
033: import org.apache.ivy.core.LogOptions;
034: import org.apache.ivy.core.cache.DefaultResolutionCacheManager;
035: import org.apache.ivy.core.cache.RepositoryCacheManager;
036: import org.apache.ivy.core.cache.ResolutionCacheManager;
037: import org.apache.ivy.core.check.CheckEngine;
038: import org.apache.ivy.core.deliver.DeliverEngine;
039: import org.apache.ivy.core.deliver.DeliverOptions;
040: import org.apache.ivy.core.event.EventManager;
041: import org.apache.ivy.core.install.InstallEngine;
042: import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
043: import org.apache.ivy.core.module.id.ModuleId;
044: import org.apache.ivy.core.module.id.ModuleRevisionId;
045: import org.apache.ivy.core.publish.PublishEngine;
046: import org.apache.ivy.core.publish.PublishOptions;
047: import org.apache.ivy.core.report.ResolveReport;
048: import org.apache.ivy.core.repository.RepositoryManagementEngine;
049: import org.apache.ivy.core.resolve.ResolveData;
050: import org.apache.ivy.core.resolve.ResolveEngine;
051: import org.apache.ivy.core.resolve.ResolveOptions;
052: import org.apache.ivy.core.resolve.ResolvedModuleRevision;
053: import org.apache.ivy.core.retrieve.RetrieveEngine;
054: import org.apache.ivy.core.retrieve.RetrieveOptions;
055: import org.apache.ivy.core.search.ModuleEntry;
056: import org.apache.ivy.core.search.OrganisationEntry;
057: import org.apache.ivy.core.search.RevisionEntry;
058: import org.apache.ivy.core.search.SearchEngine;
059: import org.apache.ivy.core.settings.IvySettings;
060: import org.apache.ivy.core.sort.NonMatchingVersionReporter;
061: import org.apache.ivy.core.sort.SortEngine;
062: import org.apache.ivy.plugins.matcher.PatternMatcher;
063: import org.apache.ivy.plugins.repository.TransferEvent;
064: import org.apache.ivy.plugins.repository.TransferListener;
065: import org.apache.ivy.plugins.resolver.BasicResolver;
066: import org.apache.ivy.plugins.resolver.DependencyResolver;
067: import org.apache.ivy.plugins.trigger.Trigger;
068: import org.apache.ivy.util.HostUtil;
069: import org.apache.ivy.util.Message;
070: import org.apache.ivy.util.MessageLoggerEngine;
071: import org.apache.ivy.util.filter.Filter;
072:
073: /**
074: * <a href="http://incubator.apache.org/ivy/">Ivy</a> is a free java based dependency manager.
075: * <p>
076: * This class is the main class of Ivy, which acts as a Facade to all services offered by Ivy:
077: * <ul>
078: * <li>resolve dependencies</li>
079: * <li>retrieve artifacts to a local location</li>
080: * <li>deliver and publish modules</li>
081: * <li>repository search and listing</li>
082: * </ul>
083: * Here is one typical usage:
084: *
085: * <pre>
086: * Ivy ivy = Ivy.newInstance();
087: * ivy.configure(new URL("ivysettings.xml"));
088: * ivy.resolve(new URL("ivy.xml"));
089: * </pre>
090: *
091: * </p>
092: * <h2>Using Ivy engines directly</h2>
093: * <p>
094: * If the methods offered by the {@link Ivy} class are not flexible enough and you want to use Ivy
095: * engines directly, you need to call the methods within a single {@link IvyContext} associated to
096: * the {@link Ivy} instance you use.<br/> To do so, it is recommended to use the
097: * {@link #execute(org.apache.ivy.Ivy.IvyCallback)} method like this:
098: * <pre>
099: * Ivy ivy = Ivy.newInstance();
100: * ivy.execute(new IvyCallback() {
101: * public Object doInIvyContext(Ivy ivy, IvyContext context) {
102: * // obviously we can use regular Ivy methods in the callback
103: * ivy.configure(new URL("ivysettings.xml"));
104: * // and we can safely use Ivy engines too
105: * ivy.getResolveEngine().resolve(new URL("ivy.xml"));
106: * return null;
107: * }
108: * });
109: * </pre>
110: *
111: * </p>
112: */
113: public class Ivy {
114: /**
115: * Callback used to execute a set of Ivy related methods within an {@link IvyContext}.
116: *
117: * @see Ivy#execute(org.apache.ivy.Ivy.IvyCallback)
118: */
119: public static interface IvyCallback {
120: /**
121: * Executes Ivy related job within an {@link IvyContext}
122: *
123: * @param ivy
124: * the {@link Ivy} instance to which this callback is related
125: * @param context
126: * the {@link IvyContext} in which this callback is executed
127: * @return the result of this job, <code>null</code> if there is no result
128: */
129: public Object doInIvyContext(Ivy ivy, IvyContext context);
130: }
131:
132: private static final int KILO = 1024;
133:
134: public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
135: "yyyyMMddHHmmss");
136:
137: /**
138: * the current version of Ivy, as displayed on the console when
139: * Ivy is initialized
140: */
141: private static final String IVY_VERSION;
142: /**
143: * the date at which this version of Ivy has been built.
144: * May be empty if unknown.
145: */
146: private static final String IVY_DATE;
147:
148: static {
149: // initialize IVY_VERSION and IVY_DATE
150: Properties props = new Properties();
151: URL moduleURL = Message.class.getResource("/module.properties");
152: if (moduleURL != null) {
153: try {
154: InputStream module = moduleURL.openStream();
155: props.load(module);
156: module.close();
157: } catch (IOException e) {
158: // ignore this exception, we will initialize with default values
159: }
160: }
161: IVY_VERSION = props.getProperty("version",
162: "non official version");
163: IVY_DATE = props.getProperty("date", "");
164: }
165:
166: /**
167: * Returns the current version of Ivy, as displayed on the console when
168: * Ivy is initialized.
169: *
170: * @return the current version of Ivy
171: * @see #getIvyVersion()
172: */
173: public static String getIvyVersion() {
174: return IVY_VERSION;
175: }
176:
177: /**
178: * Returns the date at which this version of Ivy has been built.
179: * <p>
180: * May be empty if unknown.
181: *
182: * @return the date at which this version of Ivy has been built
183: * @see #getIvyVersion()
184: */
185: public static String getIvyDate() {
186: return IVY_DATE;
187: }
188:
189: /**
190: * Returns the URL at which Ivy web site can be found.
191: * @return the URL at which Ivy web site can be found
192: */
193: public static String getIvyHomeURL() {
194: return "http://ant.apache.org/ivy/";
195: }
196:
197: public static Ivy newInstance() {
198: Ivy ivy = new Ivy();
199: ivy.bind();
200: return ivy;
201: }
202:
203: public static Ivy newInstance(IvySettings settings) {
204: Ivy ivy = new Ivy();
205: ivy.setSettings(settings);
206: ivy.bind();
207: return ivy;
208: }
209:
210: /**
211: * True if the current processing has been requested to be interrupted, false otherwise
212: */
213: private boolean interrupted;
214:
215: /**
216: * True if this instance of Ivy has already been bound to its dependencies, false otherwise.
217: *
218: * @see bind()
219: */
220: private boolean bound;
221:
222: /*
223: * Following are dependencies of the Ivy instance on instances of engines and manager which
224: * actually do the work The attributes can be set either manually using the corresponding
225: * setters, or all at once with the default implementations using the bind method
226: */
227: private IvySettings settings;
228:
229: private EventManager eventManager;
230:
231: private SortEngine sortEngine;
232:
233: private SearchEngine searchEngine;
234:
235: private CheckEngine checkEngine;
236:
237: private ResolveEngine resolveEngine;
238:
239: private RetrieveEngine retrieveEngine;
240:
241: private DeliverEngine deliverEngine;
242:
243: private PublishEngine publishEngine;
244:
245: private InstallEngine installEngine;
246:
247: private RepositoryManagementEngine repositoryEngine;
248:
249: /**
250: * The logger engine to use to log messages when using this Ivy instance.
251: */
252: private MessageLoggerEngine loggerEngine = new MessageLoggerEngine();
253:
254: /**
255: * The default constructor of Ivy allows to create an instance of Ivy with none of its
256: * dependencies (engines, settings, ...) created. If you use this constructor, it's your
257: * responsibility to set the dependencies of Ivy using the appropriate setters
258: * (setResolveEngine, ...). You can also call the bind method to set all the dependencies except
259: * those that you have provided using the setters. If you want to get an instance ready to use,
260: * prefer the use of Ivy.newInstance().
261: */
262: public Ivy() {
263: }
264:
265: /**
266: * This method is used to bind this Ivy instance to required dependencies, i.e. instance of
267: * settings, engines, and so on.
268: * <p>
269: * After this call Ivy is still not configured, which means that
270: * the settings object is still empty.
271: * </p>
272: */
273: public void bind() {
274: pushContext();
275: try {
276: if (settings == null) {
277: settings = new IvySettings();
278: }
279: if (eventManager == null) {
280: eventManager = new EventManager();
281: }
282: if (sortEngine == null) {
283: sortEngine = new SortEngine(settings);
284: }
285: if (searchEngine == null) {
286: searchEngine = new SearchEngine(settings);
287: }
288: if (resolveEngine == null) {
289: resolveEngine = new ResolveEngine(settings,
290: eventManager, sortEngine);
291: }
292: if (retrieveEngine == null) {
293: retrieveEngine = new RetrieveEngine(settings,
294: eventManager);
295: }
296: if (deliverEngine == null) {
297: deliverEngine = new DeliverEngine(settings);
298: }
299: if (publishEngine == null) {
300: publishEngine = new PublishEngine(settings,
301: eventManager);
302: }
303: if (installEngine == null) {
304: installEngine = new InstallEngine(settings,
305: searchEngine, resolveEngine, publishEngine);
306: }
307: if (repositoryEngine == null) {
308: repositoryEngine = new RepositoryManagementEngine(
309: settings, searchEngine, resolveEngine);
310: }
311:
312: eventManager.addTransferListener(new TransferListener() {
313: public void transferProgress(TransferEvent evt) {
314: ResolveData resolve;
315: switch (evt.getEventType()) {
316: case TransferEvent.TRANSFER_PROGRESS:
317: resolve = IvyContext.getContext()
318: .getResolveData();
319: if (resolve == null
320: || !LogOptions.LOG_QUIET.equals(resolve
321: .getOptions().getLog())) {
322: Message.progress();
323: }
324: break;
325: case TransferEvent.TRANSFER_COMPLETED:
326: resolve = IvyContext.getContext()
327: .getResolveData();
328: if (resolve == null
329: || !LogOptions.LOG_QUIET.equals(resolve
330: .getOptions().getLog())) {
331: Message.endProgress(" ("
332: + (evt.getTotalLength() / KILO)
333: + "kB)");
334: }
335: break;
336: default:
337: break;
338: }
339: }
340: });
341:
342: bound = true;
343: } finally {
344: popContext();
345: }
346: }
347:
348: /**
349: * Executes the given callback in the context of this Ivy instance.
350: * <p>
351: * Alternatively you can use the {@link #pushContext()} and {@link #popContext()} methods, but
352: * this is not recommended:
353: *
354: * <pre>
355: * Object result = null;
356: * pushContext();
357: * try {
358: * result = callback.doInIvyContext(this, IvyContext.getContext());
359: * } finally {
360: * popContext();
361: * }
362: * doSomethingWithResult(result);
363: * </pre>
364: *
365: * </p>
366: *
367: * @param callback
368: * @return
369: */
370: public Object execute(IvyCallback callback) {
371: pushContext();
372: try {
373: return callback.doInIvyContext(this , IvyContext
374: .getContext());
375: } finally {
376: popContext();
377: }
378: }
379:
380: /**
381: * Pushes a new IvyContext bound to this Ivy instance if the current context is not already
382: * bound to this Ivy instance. If the current context is already bound to this Ivy instance, it
383: * pushes the current context on the context stack, so that you can (and must) always call
384: * {@link #popContext()} when you're done.
385: * <p>
386: * Alternatively, you can use the {@link #execute(org.apache.ivy.Ivy.IvyCallback)} method which
387: * takes care of everything for you.
388: * </p>
389: */
390: public void pushContext() {
391: if (IvyContext.getContext().peekIvy() != this ) {
392: // the current Ivy context is associated with another Ivy instance, we push a new
393: // instance
394: IvyContext.pushNewContext();
395: IvyContext.getContext().setIvy(this );
396: } else {
397: // the current Ivy context is already associated with this Ivy instance, we only push it
398: // for popping consistency
399: IvyContext.pushContext(IvyContext.getContext());
400: }
401: }
402:
403: /**
404: * Pops the current Ivy context.
405: * <p>
406: * You must call this method once and only once for each call to {@link #pushContext()}, when
407: * you're done with the your Ivy related work.
408: * </p>
409: * <p>
410: * Alternatively, you can use the {@link #execute(org.apache.ivy.Ivy.IvyCallback)} method which
411: * takes care of everything for you.
412: * </p>
413: */
414: public void popContext() {
415: IvyContext.popContext();
416: }
417:
418: // ///////////////////////////////////////////////////////////////////////
419: // LOAD SETTINGS
420: // ///////////////////////////////////////////////////////////////////////
421: public void configure(File settingsFile) throws ParseException,
422: IOException {
423: pushContext();
424: try {
425: assertBound();
426: settings.load(settingsFile);
427: postConfigure();
428: } finally {
429: popContext();
430: }
431: }
432:
433: public void configure(URL settingsURL) throws ParseException,
434: IOException {
435: pushContext();
436: try {
437: assertBound();
438: settings.load(settingsURL);
439: postConfigure();
440: } finally {
441: popContext();
442: }
443: }
444:
445: public void configureDefault() throws ParseException, IOException {
446: pushContext();
447: try {
448: assertBound();
449: settings.loadDefault();
450: postConfigure();
451: } finally {
452: popContext();
453: }
454: }
455:
456: /**
457: * Configures Ivy with 1.4 compatible default settings
458: */
459: public void configureDefault14() throws ParseException, IOException {
460: pushContext();
461: try {
462: assertBound();
463: settings.loadDefault14();
464: postConfigure();
465: } finally {
466: popContext();
467: }
468: }
469:
470: // ///////////////////////////////////////////////////////////////////////
471: // CHECK
472: // ///////////////////////////////////////////////////////////////////////
473: public boolean check(URL ivyFile, String resolvername) {
474: pushContext();
475: try {
476: return checkEngine.check(ivyFile, resolvername);
477: } finally {
478: popContext();
479: }
480: }
481:
482: // ///////////////////////////////////////////////////////////////////////
483: // RESOLVE
484: // ///////////////////////////////////////////////////////////////////////
485:
486: public ResolveReport resolve(File ivySource) throws ParseException,
487: IOException {
488: pushContext();
489: try {
490: return resolveEngine.resolve(ivySource);
491: } finally {
492: popContext();
493: }
494: }
495:
496: public ResolveReport resolve(URL ivySource) throws ParseException,
497: IOException {
498: pushContext();
499: try {
500: return resolveEngine.resolve(ivySource);
501: } finally {
502: popContext();
503: }
504: }
505:
506: public ResolveReport resolve(ModuleRevisionId mrid,
507: ResolveOptions options, boolean changing)
508: throws ParseException, IOException {
509: pushContext();
510: try {
511: return resolveEngine.resolve(mrid, options, changing);
512: } finally {
513: popContext();
514: }
515: }
516:
517: public ResolveReport resolve(URL ivySource, ResolveOptions options)
518: throws ParseException, IOException {
519: pushContext();
520: try {
521: return resolveEngine.resolve(ivySource, options);
522: } finally {
523: popContext();
524: }
525: }
526:
527: public ResolveReport resolve(ModuleDescriptor md,
528: ResolveOptions options) throws ParseException, IOException {
529: pushContext();
530: try {
531: return resolveEngine.resolve(md, options);
532: } finally {
533: popContext();
534: }
535: }
536:
537: // ///////////////////////////////////////////////////////////////////////
538: // INSTALL
539: // ///////////////////////////////////////////////////////////////////////
540:
541: public ResolveReport install(ModuleRevisionId mrid, String from,
542: String to, boolean transitive, boolean validate,
543: boolean overwrite, Filter artifactFilter, String matcherName)
544: throws IOException {
545: pushContext();
546: try {
547: return installEngine.install(mrid, from, to, transitive,
548: validate, overwrite, artifactFilter, matcherName);
549: } finally {
550: popContext();
551: }
552: }
553:
554: // ///////////////////////////////////////////////////////////////////////
555: // RETRIEVE
556: // ///////////////////////////////////////////////////////////////////////
557:
558: public int retrieve(ModuleRevisionId mrid, String destFilePattern,
559: RetrieveOptions options) throws IOException {
560: pushContext();
561: try {
562: return retrieveEngine.retrieve(mrid, destFilePattern,
563: options);
564: } finally {
565: popContext();
566: }
567: }
568:
569: // ///////////////////////////////////////////////////////////////////////
570: // DELIVER
571: // ///////////////////////////////////////////////////////////////////////
572:
573: public void deliver(ModuleRevisionId mrid, String revision,
574: String destIvyPattern) throws IOException, ParseException {
575: pushContext();
576: try {
577: deliverEngine.deliver(mrid, revision, destIvyPattern,
578: DeliverOptions.newInstance(settings));
579: } finally {
580: popContext();
581: }
582: }
583:
584: public void deliver(String revision, String destIvyPattern,
585: DeliverOptions options) throws IOException, ParseException {
586: pushContext();
587: try {
588: deliverEngine.deliver(revision, destIvyPattern, options);
589: } finally {
590: popContext();
591: }
592: }
593:
594: /**
595: * Example of use: deliver(mrid, "1.5", "target/ivy/ivy-[revision].xml",
596: * DeliverOptions.newInstance(settings).setStatus("release").setValidate(false));
597: *
598: * @param mrid
599: * @param revision
600: * @param destIvyPattern
601: * @param options
602: * @throws IOException
603: * @throws ParseException
604: */
605: public void deliver(ModuleRevisionId mrid, String revision,
606: String destIvyPattern, DeliverOptions options)
607: throws IOException, ParseException {
608: pushContext();
609: try {
610: deliverEngine.deliver(mrid, revision, destIvyPattern,
611: options);
612: } finally {
613: popContext();
614: }
615: }
616:
617: // ///////////////////////////////////////////////////////////////////////
618: // PUBLISH
619: // ///////////////////////////////////////////////////////////////////////
620:
621: public Collection publish(ModuleRevisionId mrid,
622: Collection srcArtifactPattern, String resolverName,
623: PublishOptions options) throws IOException {
624: pushContext();
625: try {
626: return publishEngine.publish(mrid, srcArtifactPattern,
627: resolverName, options);
628: } finally {
629: popContext();
630: }
631: }
632:
633: // ///////////////////////////////////////////////////////////////////////
634: // SORT
635: // ///////////////////////////////////////////////////////////////////////
636:
637: /**
638: * Sorts the collection of IvyNode from the less dependent to the more dependent
639: */
640: public List sortNodes(Collection nodes) {
641: pushContext();
642: try {
643: return getSortEngine().sortNodes(nodes);
644: } finally {
645: popContext();
646: }
647: }
648:
649: /**
650: * Sorts the given ModuleDescriptors from the less dependent to the more dependent. This sort
651: * ensures that a ModuleDescriptor is always found in the list before all ModuleDescriptors
652: * depending directly on it.
653: *
654: * @param moduleDescriptors
655: * a Collection of ModuleDescriptor to sort
656: * @param nonMatchingVersionReporter
657: * Used to report some non matching version (when a modules depends on a specific
658: * revision of an other modules present in the of modules to sort with a different
659: * revision.
660: * @return a List of sorted ModuleDescriptors
661: */
662: public List sortModuleDescriptors(Collection moduleDescriptors,
663: NonMatchingVersionReporter nonMatchingVersionReporter) {
664: pushContext();
665: try {
666: return getSortEngine().sortModuleDescriptors(
667: moduleDescriptors, nonMatchingVersionReporter);
668: } finally {
669: popContext();
670: }
671: }
672:
673: // ///////////////////////////////////////////////////////////////////////
674: // SEARCH
675: // ///////////////////////////////////////////////////////////////////////
676:
677: public ResolvedModuleRevision findModule(ModuleRevisionId mrid) {
678: pushContext();
679: try {
680: ResolveOptions options = new ResolveOptions();
681: options.setValidate(false);
682: return resolveEngine.findModule(mrid, options);
683: } finally {
684: popContext();
685: }
686: }
687:
688: public ModuleEntry[] listModuleEntries(OrganisationEntry org) {
689: pushContext();
690: try {
691: return searchEngine.listModuleEntries(org);
692: } finally {
693: popContext();
694: }
695: }
696:
697: public ModuleId[] listModules(ModuleId criteria,
698: PatternMatcher matcher) {
699: pushContext();
700: try {
701: return searchEngine.listModules(criteria, matcher);
702: } finally {
703: popContext();
704: }
705: }
706:
707: public ModuleRevisionId[] listModules(ModuleRevisionId criteria,
708: PatternMatcher matcher) {
709: pushContext();
710: try {
711: return searchEngine.listModules(criteria, matcher);
712: } finally {
713: popContext();
714: }
715: }
716:
717: public String[] listModules(String org) {
718: pushContext();
719: try {
720: return searchEngine.listModules(org);
721: } finally {
722: popContext();
723: }
724: }
725:
726: public OrganisationEntry[] listOrganisationEntries() {
727: pushContext();
728: try {
729: return searchEngine.listOrganisationEntries();
730: } finally {
731: popContext();
732: }
733: }
734:
735: public String[] listOrganisations() {
736: pushContext();
737: try {
738: return searchEngine.listOrganisations();
739: } finally {
740: popContext();
741: }
742: }
743:
744: public RevisionEntry[] listRevisionEntries(ModuleEntry module) {
745: pushContext();
746: try {
747: return searchEngine.listRevisionEntries(module);
748: } finally {
749: popContext();
750: }
751: }
752:
753: public String[] listRevisions(String org, String module) {
754: pushContext();
755: try {
756: return searchEngine.listRevisions(org, module);
757: } finally {
758: popContext();
759: }
760: }
761:
762: public String[] listTokenValues(String token, Map otherTokenValues) {
763: pushContext();
764: try {
765: return searchEngine
766: .listTokenValues(token, otherTokenValues);
767: } finally {
768: popContext();
769: }
770: }
771:
772: // ///////////////////////////////////////////////////////////////////////
773: // INTERRUPTIONS
774: // ///////////////////////////////////////////////////////////////////////
775:
776: /**
777: * Interrupts the current running operation, no later than interruptTimeout milliseconds after
778: * the call
779: */
780: public void interrupt() {
781: Thread operatingThread = IvyContext.getContext()
782: .getOperatingThread();
783: interrupt(operatingThread);
784: }
785:
786: /**
787: * Interrupts the current running operation in the given operating thread, no later than
788: * interruptTimeout milliseconds after the call
789: */
790: public void interrupt(Thread operatingThread) {
791: if (operatingThread != null && operatingThread.isAlive()) {
792: if (operatingThread == Thread.currentThread()) {
793: throw new IllegalStateException(
794: "cannot call interrupt from ivy operating thread");
795: }
796: Message.verbose("interrupting operating thread...");
797: operatingThread.interrupt();
798: synchronized (this ) {
799: interrupted = true;
800: }
801: try {
802: Message
803: .verbose("waiting clean interruption of operating thread");
804: operatingThread.join(settings.getInterruptTimeout());
805: } catch (InterruptedException e) {
806: // reset thread interrupt status
807: Thread.currentThread().interrupt();
808: }
809: if (operatingThread.isAlive()) {
810: Message
811: .warn("waited clean interruption for too long: stopping operating thread");
812: operatingThread.stop();
813: }
814: synchronized (this ) {
815: interrupted = false;
816: }
817: }
818: }
819:
820: public synchronized boolean isInterrupted() {
821: return interrupted;
822: }
823:
824: /**
825: * Check if the current operation has been interrupted, and if it is the case, throw a runtime
826: * exception
827: */
828: public void checkInterrupted() {
829: if (isInterrupted()) {
830: Message.info("operation interrupted");
831: throw new RuntimeException("operation interrupted");
832: }
833: }
834:
835: public static String getWorkingRevision() {
836: return "working@" + HostUtil.getLocalHostName();
837: }
838:
839: public ResolutionCacheManager getResolutionCacheManager() {
840: return settings.getResolutionCacheManager();
841: }
842:
843: private void assertBound() {
844: if (!bound) {
845: bind();
846: }
847: }
848:
849: private void postConfigure() {
850: Collection triggers = settings.getTriggers();
851: for (Iterator iter = triggers.iterator(); iter.hasNext();) {
852: Trigger trigger = (Trigger) iter.next();
853: eventManager.addIvyListener(trigger, trigger
854: .getEventFilter());
855: }
856:
857: for (Iterator iter = settings.getResolvers().iterator(); iter
858: .hasNext();) {
859: DependencyResolver resolver = (DependencyResolver) iter
860: .next();
861: if (resolver instanceof BasicResolver) {
862: ((BasicResolver) resolver)
863: .setEventManager(eventManager);
864: }
865: }
866: }
867:
868: public String getVariable(String name) {
869: pushContext();
870: try {
871: assertBound();
872: return settings.getVariable(name);
873: } finally {
874: popContext();
875: }
876: }
877:
878: public String substitute(String str) {
879: pushContext();
880: try {
881: assertBound();
882: return settings.substitute(str);
883: } finally {
884: popContext();
885: }
886: }
887:
888: public void setVariable(String varName, String value) {
889: pushContext();
890: try {
891: assertBound();
892: settings.setVariable(varName, value);
893: } finally {
894: popContext();
895: }
896: }
897:
898: // ///////////////////////////////////////////////////////////////////
899: // GETTERS / SETTERS
900: // ///////////////////////////////////////////////////////////////////
901:
902: public IvySettings getSettings() {
903: return settings;
904: }
905:
906: public EventManager getEventManager() {
907: return eventManager;
908: }
909:
910: public CheckEngine getCheckEngine() {
911: return checkEngine;
912: }
913:
914: public void setCheckEngine(CheckEngine checkEngine) {
915: this .checkEngine = checkEngine;
916: }
917:
918: public DeliverEngine getDeliverEngine() {
919: return deliverEngine;
920: }
921:
922: public void setDeliverEngine(DeliverEngine deliverEngine) {
923: this .deliverEngine = deliverEngine;
924: }
925:
926: public InstallEngine getInstallEngine() {
927: return installEngine;
928: }
929:
930: public void setInstallEngine(InstallEngine installEngine) {
931: this .installEngine = installEngine;
932: }
933:
934: public PublishEngine getPublishEngine() {
935: return publishEngine;
936: }
937:
938: public void setPublishEngine(PublishEngine publishEngine) {
939: this .publishEngine = publishEngine;
940: }
941:
942: public ResolveEngine getResolveEngine() {
943: return resolveEngine;
944: }
945:
946: public void setResolveEngine(ResolveEngine resolveEngine) {
947: this .resolveEngine = resolveEngine;
948: }
949:
950: public RetrieveEngine getRetrieveEngine() {
951: return retrieveEngine;
952: }
953:
954: public void setRetrieveEngine(RetrieveEngine retrieveEngine) {
955: this .retrieveEngine = retrieveEngine;
956: }
957:
958: public SearchEngine getSearchEngine() {
959: return searchEngine;
960: }
961:
962: public void setSearchEngine(SearchEngine searchEngine) {
963: this .searchEngine = searchEngine;
964: }
965:
966: public SortEngine getSortEngine() {
967: return sortEngine;
968: }
969:
970: public void setSortEngine(SortEngine sortEngine) {
971: this .sortEngine = sortEngine;
972: }
973:
974: public RepositoryManagementEngine getRepositoryEngine() {
975: return repositoryEngine;
976: }
977:
978: public void setRepositoryEngine(
979: RepositoryManagementEngine repositoryEngine) {
980: this .repositoryEngine = repositoryEngine;
981: }
982:
983: public void setEventManager(EventManager eventManager) {
984: this .eventManager = eventManager;
985: }
986:
987: public void setSettings(IvySettings settings) {
988: this .settings = settings;
989: }
990:
991: public MessageLoggerEngine getLoggerEngine() {
992: return loggerEngine;
993: }
994: }
|