001 /*****************************************************************************
002 * Copyright (C) PicoContainer Organization. All rights reserved. *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file. *
007 *****************************************************************************/
008 package org.picocontainer.defaults;
009
010 import java.io.FileNotFoundException;
011
012 import org.jmock.MockObjectTestCase;
013 import org.picocontainer.MutablePicoContainer;
014 import org.picocontainer.Parameter;
015 import org.picocontainer.PicoIntrospectionException;
016
017
018 /**
019 * @author Aslak Hellesøy
020 * @author Jörg Schaible
021 * @version $Revision: 2291 $
022 */
023 public class LifecycleVisitorTestCase extends MockObjectTestCase {
024
025 public abstract static class RecordingLifecycle {
026 private final StringBuffer recording;
027
028 protected RecordingLifecycle(StringBuffer recording) {
029 this.recording = recording;
030 }
031
032 public void demarrer() {
033 recording.append("<" + code());
034 }
035
036 public void arreter() {
037 recording.append(code() + ">");
038 }
039
040 public void ecraser() {
041 recording.append("!" + code());
042 }
043
044 private String code() {
045 String name = getClass().getName();
046 return name.substring(name.indexOf('$') + 1);
047 }
048
049 public void uncallableByVisitor(final String s) {
050 }
051
052 public void throwsAtVisit() throws FileNotFoundException {
053 throw new FileNotFoundException();
054 }
055
056 private void callMe() {
057 }
058 }
059
060 public static class One extends RecordingLifecycle {
061 public One(StringBuffer sb) {
062 super(sb);
063 }
064 }
065
066 public static class Two extends RecordingLifecycle {
067 public Two(StringBuffer sb, One one) {
068 super(sb);
069 assertNotNull(one);
070 }
071 }
072
073 public static class Three extends RecordingLifecycle {
074 public Three(StringBuffer sb, One one, Two two) {
075 super(sb);
076 assertNotNull(one);
077 assertNotNull(two);
078 }
079 }
080
081 public static class Four extends RecordingLifecycle {
082 public Four(StringBuffer sb, Two two, Three three, One one) {
083 super(sb);
084 assertNotNull(one);
085 assertNotNull(two);
086 assertNotNull(three);
087 }
088 }
089
090 public void testShouldAllowCustomLifecycle() throws NoSuchMethodException {
091 LifecycleVisitor starter = new LifecycleVisitor(
092 RecordingLifecycle.class.getMethod("demarrer", null), RecordingLifecycle.class, true);
093 LifecycleVisitor stopper = new LifecycleVisitor(
094 RecordingLifecycle.class.getMethod("arreter", null), RecordingLifecycle.class, false);
095 LifecycleVisitor disposer = new LifecycleVisitor(
096 RecordingLifecycle.class.getMethod("ecraser", null), RecordingLifecycle.class, false);
097
098 MutablePicoContainer parent = new DefaultPicoContainer();
099 MutablePicoContainer child = parent.makeChildContainer();
100 parent.registerComponentImplementation("recording", StringBuffer.class);
101 child.registerComponentImplementation(Four.class);
102 parent.registerComponentImplementation(Two.class);
103 parent.registerComponentImplementation(One.class, One.class, new Parameter[]{ComponentParameter.DEFAULT});
104 child.registerComponentImplementation(Three.class);
105
106 starter.traverse(parent);
107 stopper.traverse(parent);
108 disposer.traverse(parent);
109
110 assertEquals("<One<Two<Three<FourFour>Three>Two>One>!Four!Three!Two!One", parent.getComponentInstance(
111 "recording").toString());
112 }
113
114 public void testPicoIntrospectionExceptionForInvalidMethod() throws NoSuchMethodException {
115 LifecycleVisitor visitor = new LifecycleVisitor(RecordingLifecycle.class.getMethod(
116 "uncallableByVisitor", new Class[]{String.class}), RecordingLifecycle.class, true);
117 MutablePicoContainer pico = new DefaultPicoContainer();
118 pico.registerComponentImplementation(StringBuffer.class);
119 pico.registerComponentImplementation(One.class);
120 try {
121 visitor.traverse(pico);
122 fail("PicoIntrospectionException expected");
123 } catch (PicoIntrospectionException e) {
124 assertTrue(e.getCause() instanceof IllegalArgumentException);
125 }
126 }
127
128 public void testPicoIntrospectionExceptionForThrownException() throws NoSuchMethodException {
129 LifecycleVisitor visitor = new LifecycleVisitor(
130 RecordingLifecycle.class.getMethod("throwsAtVisit", null), RecordingLifecycle.class, true);
131 MutablePicoContainer pico = new DefaultPicoContainer();
132 pico.registerComponentImplementation(StringBuffer.class);
133 pico.registerComponentImplementation(One.class);
134 try {
135 visitor.traverse(pico);
136 fail("PicoIntrospectionException expected");
137 } catch (PicoIntrospectionException e) {
138 assertTrue(e.getCause() instanceof FileNotFoundException);
139 }
140 }
141
142 public void testPicoIntrospectionExceptionForInaccessibleMethod() throws NoSuchMethodException {
143 LifecycleVisitor visitor = new LifecycleVisitor(
144 RecordingLifecycle.class.getDeclaredMethod("callMe", null), RecordingLifecycle.class, true);
145 MutablePicoContainer pico = new DefaultPicoContainer();
146 pico.registerComponentImplementation(StringBuffer.class);
147 pico.registerComponentImplementation(One.class);
148 try {
149 visitor.traverse(pico);
150 fail("PicoIntrospectionException expected");
151 } catch (PicoIntrospectionException e) {
152 assertTrue(e.getCause() instanceof IllegalAccessException);
153 }
154 }
155 }