001: package org.apache.maven.lifecycle;
002:
003: import org.apache.maven.lifecycle.model.BuildBinding;
004: import org.apache.maven.lifecycle.model.CleanBinding;
005: import org.apache.maven.lifecycle.model.LifecycleBinding;
006: import org.apache.maven.lifecycle.model.LifecycleBindings;
007: import org.apache.maven.lifecycle.model.MojoBinding;
008: import org.apache.maven.lifecycle.model.Phase;
009: import org.apache.maven.lifecycle.model.SiteBinding;
010: import org.codehaus.plexus.util.xml.Xpp3Dom;
011:
012: import java.util.ArrayList;
013: import java.util.HashMap;
014: import java.util.Iterator;
015: import java.util.List;
016: import java.util.Map;
017:
018: public class LifecycleUtils {
019:
020: private LifecycleUtils() {
021: }
022:
023: public static void setOrigin(final LifecycleBindings bindings,
024: final String origin) {
025: for (Iterator bindingIt = bindings.getBindingList().iterator(); bindingIt
026: .hasNext();) {
027: LifecycleBinding binding = (LifecycleBinding) bindingIt
028: .next();
029:
030: if (binding == null) {
031: continue;
032: }
033:
034: for (Iterator phaseIt = binding.getPhasesInOrder()
035: .iterator(); phaseIt.hasNext();) {
036: Phase phase = (Phase) phaseIt.next();
037:
038: if (phase == null) {
039: continue;
040: }
041:
042: for (Iterator mojoIt = phase.getBindings().iterator(); mojoIt
043: .hasNext();) {
044: MojoBinding mojoBinding = (MojoBinding) mojoIt
045: .next();
046:
047: mojoBinding.setOrigin(origin);
048: }
049: }
050: }
051: }
052:
053: public static List getMojoBindingListForLifecycle(
054: final String stopPhase, final LifecycleBindings bindings)
055: throws NoSuchPhaseException {
056: LifecycleBinding binding = findLifecycleBindingForPhase(
057: stopPhase, bindings);
058:
059: if (binding == null) {
060: throw new NoSuchPhaseException(stopPhase,
061: "Phase not found in any lifecycle.");
062: }
063:
064: return getMojoBindingListForLifecycle(stopPhase, binding);
065: }
066:
067: public static List getMojoBindingListForLifecycle(
068: final String stopPhase, final LifecycleBinding lifecycle)
069: throws NoSuchPhaseException {
070: List phaseNames = lifecycle.getPhaseNamesInOrder();
071:
072: int idx = phaseNames.indexOf(stopPhase);
073:
074: if (idx < 0) {
075: throw new NoSuchPhaseException(stopPhase,
076: "Phase not found in lifecycle: "
077: + lifecycle.getId());
078: }
079:
080: List phases = lifecycle.getPhasesInOrder();
081:
082: List bindings = new ArrayList();
083: for (int i = 0; i <= idx; i++) {
084: Phase phase = (Phase) phases.get(i);
085: List phaseBindings = phase.getBindings();
086:
087: if ((phaseBindings != null) && !phaseBindings.isEmpty()) {
088: bindings.addAll(phaseBindings);
089: }
090: }
091:
092: return bindings;
093: }
094:
095: /**
096: * @return null if the phase is not contained in any of the lifecycles.
097: */
098: public static LifecycleBinding findLifecycleBindingForPhase(
099: final String phaseName, final LifecycleBindings lifecycles) {
100: List lifecyclesAvailable = lifecycles.getBindingList();
101:
102: for (Iterator it = lifecyclesAvailable.iterator(); it.hasNext();) {
103: LifecycleBinding lifecycle = (LifecycleBinding) it.next();
104:
105: if (lifecycle.getPhaseNamesInOrder().indexOf(phaseName) > -1) {
106: return lifecycle;
107: }
108: }
109:
110: return null;
111: }
112:
113: public static void removeMojoBinding(final String phaseName,
114: final MojoBinding mojoBinding,
115: final LifecycleBinding lifecycleBinding,
116: final boolean considerExecutionId)
117: throws NoSuchPhaseException {
118: List phaseNames = lifecycleBinding.getPhaseNamesInOrder();
119:
120: int idx = phaseNames.indexOf(phaseName);
121:
122: if (idx < 0) {
123: throw new NoSuchPhaseException(phaseName, "Phase: "
124: + phaseName + " not found in lifecycle: "
125: + lifecycleBinding.getId());
126: }
127:
128: List phases = lifecycleBinding.getPhasesInOrder();
129:
130: Phase phase = (Phase) phases.get(idx);
131:
132: if (phase != null) {
133: List mojoBindings = phase.getBindings();
134:
135: String targetKey = MojoBindingUtils.createMojoBindingKey(
136: mojoBinding, considerExecutionId);
137:
138: for (Iterator it = mojoBindings.iterator(); it.hasNext();) {
139: MojoBinding candidate = (MojoBinding) it.next();
140:
141: String candidateKey = MojoBindingUtils
142: .createMojoBindingKey(candidate,
143: considerExecutionId);
144: if (candidateKey.equals(targetKey)) {
145: it.remove();
146: }
147: }
148:
149: phase.setBindings(mojoBindings);
150: }
151: }
152:
153: public static void addMojoBinding(final String phaseName,
154: final MojoBinding mojoBinding,
155: final LifecycleBinding lifecycleBinding)
156: throws NoSuchPhaseException {
157: List phaseNames = lifecycleBinding.getPhaseNamesInOrder();
158:
159: int idx = phaseNames.indexOf(phaseName);
160:
161: if (idx < 0) {
162: throw new NoSuchPhaseException(phaseName, "Phase: "
163: + phaseName + " not found in lifecycle: "
164: + lifecycleBinding.getId());
165: }
166:
167: List phases = lifecycleBinding.getPhasesInOrder();
168:
169: Phase phase = (Phase) phases.get(idx);
170: phase.addBinding(mojoBinding);
171: }
172:
173: public static void addMojoBinding(final String phaseName,
174: final MojoBinding mojo, final LifecycleBindings bindings)
175: throws LifecycleSpecificationException {
176: LifecycleBinding binding = findLifecycleBindingForPhase(
177: phaseName, bindings);
178:
179: if (binding == null) {
180: throw new NoSuchPhaseException(phaseName,
181: "Phase not found in any lifecycle: " + phaseName);
182: }
183:
184: addMojoBinding(phaseName, mojo, binding);
185: }
186:
187: public static LifecycleBindings mergeBindings(
188: final LifecycleBindings existingBindings,
189: final LifecycleBindings newBindings,
190: final LifecycleBindings defaultBindings,
191: final boolean mergeConfigIfExecutionIdMatches) {
192: return mergeBindings(existingBindings, newBindings,
193: defaultBindings, mergeConfigIfExecutionIdMatches, false);
194: }
195:
196: public static LifecycleBindings mergeBindings(
197: final LifecycleBindings existingBindings,
198: final LifecycleBindings newBindings,
199: final LifecycleBindings defaultBindings,
200: final boolean mergeConfigIfExecutionIdMatches,
201: final boolean reverseConfigMergeDirection) {
202: LifecycleBindings result = new LifecycleBindings();
203: result.setPackaging(newBindings.getPackaging());
204:
205: CleanBinding cb = (CleanBinding) cloneBinding(existingBindings
206: .getCleanBinding());
207: if ((defaultBindings != null) && isNullOrEmpty(cb)) {
208: cb = (CleanBinding) cloneBinding(defaultBindings
209: .getCleanBinding());
210: }
211:
212: if (cb == null) {
213: cb = new CleanBinding();
214: }
215:
216: result.setCleanBinding(cb);
217:
218: BuildBinding bb = (BuildBinding) cloneBinding(existingBindings
219: .getBuildBinding());
220: if ((defaultBindings != null) && isNullOrEmpty(bb)) {
221: bb = (BuildBinding) cloneBinding(defaultBindings
222: .getBuildBinding());
223: }
224:
225: if (bb == null) {
226: bb = new BuildBinding();
227: }
228:
229: result.setBuildBinding(bb);
230:
231: SiteBinding sb = (SiteBinding) cloneBinding(existingBindings
232: .getSiteBinding());
233: if ((defaultBindings != null) && isNullOrEmpty(sb)) {
234: sb = (SiteBinding) cloneBinding(defaultBindings
235: .getSiteBinding());
236: }
237:
238: if (sb == null) {
239: sb = new SiteBinding();
240: }
241:
242: result.setSiteBinding(sb);
243:
244: for (Iterator bindingIt = newBindings.getBindingList()
245: .iterator(); bindingIt.hasNext();) {
246: LifecycleBinding lifecycleBinding = (LifecycleBinding) bindingIt
247: .next();
248:
249: if (lifecycleBinding != null) {
250: List phaseNames = lifecycleBinding
251: .getPhaseNamesInOrder();
252: List phases = lifecycleBinding.getPhasesInOrder();
253:
254: for (int i = 0; i < phases.size(); i++) {
255: Phase phase = (Phase) phases.get(i);
256: String name = (String) phaseNames.get(i);
257:
258: if ((phase != null)
259: && (phase.getBindings() != null)
260: && !phase.getBindings().isEmpty()) {
261: for (Iterator phaseIt = phase.getBindings()
262: .iterator(); phaseIt.hasNext();) {
263: MojoBinding mojoBinding = (MojoBinding) phaseIt
264: .next();
265:
266: mojoBinding = cloneMojoBinding(mojoBinding);
267:
268: if (mergeConfigIfExecutionIdMatches) {
269: MojoBinding matchingBinding = findMatchingMojoBinding(
270: mojoBinding, existingBindings,
271: true);
272:
273: if (matchingBinding != null) {
274: Xpp3Dom existingConfig = new Xpp3Dom(
275: (Xpp3Dom) matchingBinding
276: .getConfiguration());
277:
278: Xpp3Dom configuration;
279: if (reverseConfigMergeDirection) {
280: configuration = Xpp3Dom
281: .mergeXpp3Dom(
282: existingConfig,
283: (Xpp3Dom) mojoBinding
284: .getConfiguration());
285: } else {
286: configuration = Xpp3Dom
287: .mergeXpp3Dom(
288: (Xpp3Dom) mojoBinding
289: .getConfiguration(),
290: existingConfig);
291: }
292:
293: mojoBinding
294: .setConfiguration(configuration);
295:
296: if ((mojoBinding.getOrigin() == null)
297: && (matchingBinding
298: .getOrigin() != null)) {
299: mojoBinding
300: .setOrigin(matchingBinding
301: .getOrigin());
302: }
303:
304: LifecycleBinding resultBinding = findLifecycleBindingForPhase(
305: name, result);
306:
307: try {
308: removeMojoBinding(name,
309: matchingBinding,
310: resultBinding, true);
311: } catch (NoSuchPhaseException e) {
312: IllegalStateException error = new IllegalStateException(
313: e.getMessage()
314: + "\nSomething strange is going on. Merging should not encounter such inconsistencies.");
315:
316: error.initCause(e);
317:
318: throw error;
319: }
320: }
321: }
322:
323: try {
324: addMojoBinding(name, mojoBinding,
325: result);
326: } catch (LifecycleSpecificationException e) {
327: // NOTE: this shouldn't happen as long as normal components are used
328: // to create/read these LifecycleBindings instances.
329: IllegalArgumentException error = new IllegalArgumentException(
330: "Project bindings are invalid. Reason: "
331: + e.getMessage());
332:
333: error.initCause(e);
334:
335: throw error;
336: }
337: }
338: }
339: }
340: }
341: }
342:
343: return result;
344: }
345:
346: private static boolean isNullOrEmpty(final LifecycleBinding binding) {
347: if (binding == null) {
348: return true;
349: }
350:
351: for (Iterator it = binding.getPhasesInOrder().iterator(); it
352: .hasNext();) {
353: Phase phase = (Phase) it.next();
354:
355: if (!phase.getBindings().isEmpty()) {
356: return false;
357: }
358: }
359:
360: return true;
361: }
362:
363: public static MojoBinding findMatchingMojoBinding(
364: final MojoBinding mojoBinding,
365: final LifecycleBindings inBindings,
366: final boolean considerExecutionId) {
367: String key = MojoBindingUtils.createMojoBindingKey(mojoBinding,
368: considerExecutionId);
369:
370: return (MojoBinding) mapMojoBindingsByKey(inBindings,
371: considerExecutionId).get(key);
372: }
373:
374: private static Map mapMojoBindingsByKey(
375: final LifecycleBindings bindings,
376: final boolean considerExecutionId) {
377: Map byKey = new HashMap();
378:
379: for (Iterator bindingIt = bindings.getBindingList().iterator(); bindingIt
380: .hasNext();) {
381: LifecycleBinding binding = (LifecycleBinding) bindingIt
382: .next();
383:
384: if (binding != null) {
385: for (Iterator phaseIt = binding.getPhasesInOrder()
386: .iterator(); phaseIt.hasNext();) {
387: Phase phase = (Phase) phaseIt.next();
388:
389: if (phase != null) {
390: for (Iterator mojoIt = phase.getBindings()
391: .iterator(); mojoIt.hasNext();) {
392: MojoBinding mojoBinding = (MojoBinding) mojoIt
393: .next();
394:
395: byKey.put(MojoBindingUtils
396: .createMojoBindingKey(mojoBinding,
397: considerExecutionId),
398: mojoBinding);
399: }
400: }
401: }
402: }
403: }
404:
405: return byKey;
406: }
407:
408: public static void removeMojoBindings(final List toRemove,
409: final LifecycleBindings bindings,
410: final boolean considerExecutionId)
411: throws NoSuchPhaseException {
412: if (bindings.getCleanBinding() != null) {
413: removeMojoBindings(toRemove, bindings.getCleanBinding(),
414: considerExecutionId);
415: }
416:
417: if (bindings.getBuildBinding() != null) {
418: removeMojoBindings(toRemove, bindings.getBuildBinding(),
419: considerExecutionId);
420: }
421:
422: if (bindings.getSiteBinding() != null) {
423: removeMojoBindings(toRemove, bindings.getSiteBinding(),
424: considerExecutionId);
425: }
426: }
427:
428: public static void removeMojoBindings(final List toRemove,
429: final LifecycleBinding removeFrom,
430: final boolean considerExecutionId)
431: throws NoSuchPhaseException {
432: // remove where gid:aid:goal matches.
433: List targets = new ArrayList();
434: for (Iterator it = toRemove.iterator(); it.hasNext();) {
435: MojoBinding binding = (MojoBinding) it.next();
436:
437: targets.add(MojoBindingUtils.createMojoBindingKey(binding,
438: considerExecutionId));
439: }
440:
441: List phases = removeFrom.getPhasesInOrder();
442:
443: for (int i = 0; i < phases.size(); i++) {
444: Phase phase = (Phase) phases.get(i);
445: List phaseBindings = phase.getBindings();
446:
447: for (Iterator mojoIt = phaseBindings.iterator(); mojoIt
448: .hasNext();) {
449: MojoBinding binding = (MojoBinding) mojoIt.next();
450: String key = MojoBindingUtils.createMojoBindingKey(
451: binding, considerExecutionId);
452: if (targets.contains(key)) {
453: mojoIt.remove();
454: }
455: }
456:
457: phase.setBindings(phaseBindings);
458: }
459: }
460:
461: public static LifecycleBindings cloneBindings(
462: final LifecycleBindings bindings) {
463: LifecycleBindings result = new LifecycleBindings();
464:
465: if (bindings.getCleanBinding() != null) {
466: result.setCleanBinding((CleanBinding) cloneBinding(bindings
467: .getCleanBinding()));
468: }
469:
470: if (bindings.getBuildBinding() != null) {
471: result.setBuildBinding((BuildBinding) cloneBinding(bindings
472: .getBuildBinding()));
473: }
474:
475: if (bindings.getSiteBinding() != null) {
476: result.setSiteBinding((SiteBinding) cloneBinding(bindings
477: .getSiteBinding()));
478: }
479:
480: return result;
481: }
482:
483: public static LifecycleBinding cloneBinding(
484: final LifecycleBinding binding) {
485: if (binding == null) {
486: return null;
487: }
488:
489: LifecycleBinding result;
490: if (binding instanceof CleanBinding) {
491: result = new CleanBinding();
492: } else if (binding instanceof SiteBinding) {
493: result = new SiteBinding();
494: } else if (binding instanceof BuildBinding) {
495: result = new BuildBinding();
496: } else {
497: throw new IllegalArgumentException(
498: "Unrecognized LifecycleBinding type: "
499: + binding.getClass().getName()
500: + "; cannot clone.");
501: }
502:
503: List phases = binding.getPhasesInOrder();
504: List names = binding.getPhaseNamesInOrder();
505:
506: for (int i = 0; i < phases.size(); i++) {
507: Phase phase = (Phase) phases.get(i);
508: String phaseName = (String) names.get(i);
509:
510: for (Iterator mojoIt = phase.getBindings().iterator(); mojoIt
511: .hasNext();) {
512: MojoBinding originalBinding = (MojoBinding) mojoIt
513: .next();
514:
515: MojoBinding newBinding = cloneMojoBinding(originalBinding);
516:
517: try {
518: addMojoBinding(phaseName, newBinding, result);
519: } catch (NoSuchPhaseException e) {
520: IllegalStateException error = new IllegalStateException(
521: e.getMessage()
522: + "\nSomething strange is going on. Cloning should not encounter such inconsistencies.");
523:
524: error.initCause(e);
525:
526: throw error;
527: }
528: }
529: }
530:
531: return result;
532: }
533:
534: public static MojoBinding cloneMojoBinding(final MojoBinding binding) {
535: MojoBinding result = new MojoBinding();
536:
537: result.setGroupId(binding.getGroupId());
538: result.setArtifactId(binding.getArtifactId());
539: result.setVersion(binding.getVersion());
540: result.setConfiguration(binding.getConfiguration());
541: result.setExecutionId(binding.getExecutionId());
542: result.setGoal(binding.getGoal());
543: result.setOrigin(binding.getOrigin());
544:
545: return result;
546: }
547:
548: public static Phase findPhaseForMojoBinding(
549: final MojoBinding mojoBinding,
550: final LifecycleBindings lifecycleBindings,
551: final boolean considerExecutionId) {
552: String targetKey = MojoBindingUtils.createMojoBindingKey(
553: mojoBinding, considerExecutionId);
554:
555: for (Iterator lifecycleIt = lifecycleBindings.getBindingList()
556: .iterator(); lifecycleIt.hasNext();) {
557: LifecycleBinding binding = (LifecycleBinding) lifecycleIt
558: .next();
559:
560: for (Iterator phaseIt = binding.getPhasesInOrder()
561: .iterator(); phaseIt.hasNext();) {
562: Phase phase = (Phase) phaseIt.next();
563:
564: for (Iterator mojoIt = phase.getBindings().iterator(); mojoIt
565: .hasNext();) {
566: MojoBinding candidate = (MojoBinding) mojoIt.next();
567: String key = MojoBindingUtils.createMojoBindingKey(
568: candidate, considerExecutionId);
569: if (key.equals(targetKey)) {
570: return phase;
571: }
572: }
573: }
574: }
575:
576: return null;
577: }
578:
579: public static boolean isMojoBindingPresent(
580: final MojoBinding binding, final List candidates,
581: final boolean considerExecutionId) {
582: String key = MojoBindingUtils.createMojoBindingKey(binding,
583: considerExecutionId);
584:
585: for (Iterator it = candidates.iterator(); it.hasNext();) {
586: MojoBinding candidate = (MojoBinding) it.next();
587:
588: String candidateKey = MojoBindingUtils
589: .createMojoBindingKey(candidate,
590: considerExecutionId);
591:
592: if (candidateKey.equals(key)) {
593: return true;
594: }
595: }
596:
597: return false;
598: }
599:
600: public static boolean isValidPhaseName(final String phaseName) {
601: LifecycleBindings test = new LifecycleBindings();
602: for (Iterator it = test.getBindingList().iterator(); it
603: .hasNext();) {
604: LifecycleBinding binding = (LifecycleBinding) it.next();
605:
606: if (binding.getPhaseNamesInOrder().contains(phaseName)) {
607: return true;
608: }
609: }
610:
611: return false;
612: }
613:
614: public static List getValidPhaseNames() {
615: List phaseNames = new ArrayList();
616:
617: LifecycleBindings bindings = new LifecycleBindings();
618: for (Iterator bindingIt = bindings.getBindingList().iterator(); bindingIt
619: .hasNext();) {
620: LifecycleBinding binding = (LifecycleBinding) bindingIt
621: .next();
622:
623: for (Iterator phaseNameIt = binding.getPhaseNamesInOrder()
624: .iterator(); phaseNameIt.hasNext();) {
625: phaseNames.add(phaseNameIt.next());
626: }
627: }
628:
629: return phaseNames;
630: }
631:
632: public static List getValidBuildPhaseNames() {
633: List phaseNames = new ArrayList();
634:
635: LifecycleBinding binding = new BuildBinding();
636:
637: for (Iterator phaseNameIt = binding.getPhaseNamesInOrder()
638: .iterator(); phaseNameIt.hasNext();) {
639: phaseNames.add(phaseNameIt.next());
640: }
641:
642: return phaseNames;
643: }
644:
645: public static List getValidCleanPhaseNames() {
646: List phaseNames = new ArrayList();
647:
648: LifecycleBinding binding = new CleanBinding();
649:
650: for (Iterator phaseNameIt = binding.getPhaseNamesInOrder()
651: .iterator(); phaseNameIt.hasNext();) {
652: phaseNames.add(phaseNameIt.next());
653: }
654:
655: return phaseNames;
656: }
657:
658: public static List getValidSitePhaseNames() {
659: List phaseNames = new ArrayList();
660:
661: LifecycleBinding binding = new SiteBinding();
662:
663: for (Iterator phaseNameIt = binding.getPhaseNamesInOrder()
664: .iterator(); phaseNameIt.hasNext();) {
665: phaseNames.add(phaseNameIt.next());
666: }
667:
668: return phaseNames;
669: }
670:
671: /**
672: * @deprecated Use {@link MojoBindingUtils#createMojoBindingKey(MojoBinding, boolean)} instead.
673: */
674: public static String createMojoBindingKey(
675: final MojoBinding mojoBinding,
676: final boolean considerExecutionId) {
677: return MojoBindingUtils.createMojoBindingKey(mojoBinding,
678: considerExecutionId);
679: }
680: }
|