View Javadoc

1   /* $Id: BeanPropertySetterRuleTestCase.java 1140140 2011-06-27 12:34:56Z simonetripodi $
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one or more
4    * contributor license agreements.  See the NOTICE file distributed with
5    * this work for additional information regarding copyright ownership.
6    * The ASF licenses this file to You under the Apache License, Version 2.0
7    * (the "License"); you may not use this file except in compliance with
8    * the License.  You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.commons.digester3;
20  
21  import static org.apache.commons.digester3.binder.DigesterLoader.newLoader;
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertNotNull;
24  import static org.junit.Assert.assertTrue;
25  import static org.junit.Assert.fail;
26  
27  import java.io.IOException;
28  import java.io.Reader;
29  import java.io.StringReader;
30  import java.lang.reflect.InvocationTargetException;
31  import java.util.ArrayList;
32  import java.util.List;
33  
34  import org.apache.commons.digester3.binder.AbstractRulesModule;
35  import org.junit.Test;
36  import org.xml.sax.SAXException;
37  
38  /**
39   * <p>
40   * Test case for <code>BeanPropertySetterRule</code>. This contains tests for the main applications of the rule and two
41   * more general tests of digester functionality used by this rule.
42   */
43  public class BeanPropertySetterRuleTestCase
44  {
45  
46      // ----------------------------------------------------- Instance Variables
47  
48      /**
49       * Simple test xml document used in the tests.
50       */
51      protected final static String TEST_XML = "<?xml version='1.0'?>" + "<root>ROOT BODY" + "<alpha>ALPHA BODY</alpha>"
52          + "<beta>BETA BODY</beta>" + "<gamma>GAMMA BODY</gamma>" + "<delta>DELTA BODY</delta>" + "</root>";
53  
54      // ------------------------------------------------ Individual Test Methods
55  
56      /**
57       * This is a general digester test but it fits into here pretty well. This tests that the rule calling order is
58       * properly enforced.
59       */
60      @Test
61      public void testDigesterRuleCallOrder()
62          throws SAXException, IOException
63      {
64  
65          final List<Rule> callOrder = new ArrayList<Rule>();
66  
67          Digester digester = newLoader( new AbstractRulesModule()
68          {
69  
70              @Override
71              protected void configure()
72              {
73                  // add first test rule
74                  forPattern( "root/alpha" ).addRuleCreatedBy( new TestRule.TestRuleProvider( "first", callOrder ) );
75                  // add second test rule
76                  forPattern( "root/alpha" ).addRuleCreatedBy( new TestRule.TestRuleProvider( "second", callOrder ) );
77                  // add third test rule
78                  forPattern( "root/alpha" ).addRuleCreatedBy( new TestRule.TestRuleProvider( "third", callOrder ) );
79              }
80  
81          }).newDigester();
82  
83          digester.parse( xmlTestReader() );
84  
85          // we should have nine entries in our list of calls
86  
87          assertEquals( "Nine calls should have been made.", 9, callOrder.size() );
88  
89          // begin should be called in the order added
90          assertEquals( "First rule begin not called first.", "first", ( (TestRule) callOrder.get( 0 ) ).getIdentifier() );
91  
92          assertEquals( "Second rule begin not called second.", "second",
93                        ( (TestRule) callOrder.get( 1 ) ).getIdentifier() );
94  
95          assertEquals( "Third rule begin not called third.", "third", ( (TestRule) callOrder.get( 2 ) ).getIdentifier() );
96  
97          // body text should be called in the order added
98          assertEquals( "First rule body text not called first.", "first",
99                        ( (TestRule) callOrder.get( 3 ) ).getIdentifier() );
100 
101         assertEquals( "Second rule body text not called second.", "second",
102                       ( (TestRule) callOrder.get( 4 ) ).getIdentifier() );
103 
104         assertEquals( "Third rule body text not called third.", "third",
105                       ( (TestRule) callOrder.get( 5 ) ).getIdentifier() );
106 
107         // end should be called in reverse order
108         assertEquals( "Third rule end not called first.", "third", ( (TestRule) callOrder.get( 6 ) ).getIdentifier() );
109 
110         assertEquals( "Second rule end not called second.", "second", ( (TestRule) callOrder.get( 7 ) ).getIdentifier() );
111 
112         assertEquals( "First rule end not called third.", "first", ( (TestRule) callOrder.get( 8 ) ).getIdentifier() );
113 
114     }
115 
116     /**
117      * This is a general digester test but it fits into here pretty well. This tests that the body text stack is
118      * functioning correctly.
119      */
120     @Test
121     public void testDigesterBodyTextStack()
122         throws SAXException, IOException
123     {
124         final List<Rule> callOrder = new ArrayList<Rule>();
125 
126         Digester digester = newLoader(new AbstractRulesModule()
127         {
128 
129             @Override
130             protected void configure()
131             {
132                 forPattern( "root" ).addRuleCreatedBy( new TestRule.TestRuleProvider( "root", callOrder ) );
133                 forPattern( "root/alpha" ).addRuleCreatedBy( new TestRule.TestRuleProvider( "root/alpha", callOrder ) );
134                 forPattern( "root/beta" ).addRuleCreatedBy( new TestRule.TestRuleProvider( "root/beta", callOrder ) );
135                 forPattern( "root/gamma" ).addRuleCreatedBy( new TestRule.TestRuleProvider( "root/gamma", callOrder ) );
136             }
137 
138         }).newDigester();
139 
140         digester.parse( xmlTestReader() );
141 
142         assertEquals( "Root body text not set correct.", "ROOT BODY", ( (TestRule) callOrder.get( 0 ) ).getBodyText() );
143 
144         assertEquals( "Alpha body text not set correct.", "ALPHA BODY", ( (TestRule) callOrder.get( 1 ) ).getBodyText() );
145 
146         assertEquals( "Beta body text not set correct.", "BETA BODY", ( (TestRule) callOrder.get( 4 ) ).getBodyText() );
147 
148         assertEquals( "Gamma body text not set correct.", "GAMMA BODY", ( (TestRule) callOrder.get( 7 ) ).getBodyText() );
149 
150     }
151 
152     /**
153      * Test that you can successfully set a given property
154      */
155     @Test
156     public void testSetGivenProperty()
157         throws SAXException, IOException
158     {
159         Digester digester = newLoader(new AbstractRulesModule()
160         {
161 
162             @Override
163             protected void configure()
164             {
165                 forPattern( "root" ).createObject().ofType( SimpleTestBean.class );
166                 forPattern( "root" ).setBeanProperty().withName( "alpha" );
167 
168                 // we'll set property beta with the body text of child element alpha
169                 forPattern( "root/alpha" ).setBeanProperty().withName( "beta" );
170                 // we'll leave property gamma alone
171 
172                 // we'll set property delta (a write-only property) also
173                 forPattern( "root/delta" ).setBeanProperty().withName( "delta" );
174             }
175 
176         }).newDigester();
177 
178         SimpleTestBean bean = digester.parse( xmlTestReader() );
179 
180         // check properties are set correctly
181         assertEquals( "Property alpha not set correctly", "ROOT BODY", bean.getAlpha() );
182 
183         assertEquals( "Property beta not set correctly", "ALPHA BODY", bean.getBeta() );
184 
185         assertTrue( "Property gamma not set correctly", bean.getGamma() == null );
186 
187         assertEquals( "Property delta not set correctly", "DELTA BODY", bean.getDeltaValue() );
188 
189     }
190 
191     /**
192      * Test that trying to set an unknown property throws an exception.
193      */
194     @Test
195     public void testSetUnknownProperty()
196     {
197         Digester digester = newLoader(new AbstractRulesModule()
198         {
199 
200             @Override
201             protected void configure()
202             {
203                 forPattern( "root" ).createObject().ofType( "org.apache.commons.digester3.SimpleTestBean" );
204                 forPattern( "root" ).setBeanProperty().withName( "alpha" );
205 
206                 // attempt to set an unknown property name
207                 forPattern( "root/alpha" ).setBeanProperty().withName( "unknown" );
208             }
209 
210         }).newDigester();
211 
212         // Attempt to parse the input
213         try
214         {
215             SimpleTestBean bean = digester.parse( xmlTestReader() );
216             fail( "Should have thrown NoSuchMethodException" );
217             assertNotNull( bean ); // just to avoid compiler warning on unused variable
218         }
219         catch ( Exception e )
220         {
221             if ( e instanceof InvocationTargetException )
222             {
223                 Throwable t = ( (InvocationTargetException) e ).getTargetException();
224                 if ( t instanceof NoSuchMethodException )
225                 {
226                     // Expected result
227                 }
228                 else
229                 {
230                     fail( "Should have thrown NoSuchMethodException, threw " + t );
231                 }
232             }
233         }
234 
235     }
236 
237     /**
238      * Test that you can successfully automatically set properties.
239      */
240     @Test
241     public void testAutomaticallySetProperties()
242         throws SAXException, IOException
243     {
244         Digester digester = newLoader(new AbstractRulesModule()
245         {
246 
247             @Override
248             protected void configure()
249             {
250                 forPattern( "root" ).createObject().ofType( "org.apache.commons.digester3.SimpleTestBean" );
251                 forPattern( "root/?" ).setBeanProperty();
252             }
253 
254         }).newDigester( new ExtendedBaseRules() );
255 
256         SimpleTestBean bean = digester.parse( xmlTestReader() );
257 
258         // check properties are set correctly
259         assertEquals( "Property alpha not set correctly", "ALPHA BODY", bean.getAlpha() );
260 
261         assertEquals( "Property beta not set correctly", "BETA BODY", bean.getBeta() );
262 
263         assertEquals( "Property gamma not set correctly", "GAMMA BODY", bean.getGamma() );
264 
265     }
266 
267     @Test
268     public void extractPropertyNameFromAttribute() throws Exception
269     {
270         Employee expected = new Employee( "John", "Doe" );
271 
272         Employee actual = newLoader( new AbstractRulesModule()
273         {
274 
275             @Override
276             protected void configure()
277             {
278                 forPattern( "employee" ).createObject().ofType( Employee.class );
279                 forPattern( "employee/property" ).setBeanProperty().extractPropertyNameFromAttribute( "name" );
280             }
281 
282         } )
283         .newDigester()
284         .parse( getClass().getResource( "extractPropertyNameFromAttribute.xml" ) );
285 
286         assertEquals( expected.getFirstName(), actual.getFirstName() );
287         assertEquals( expected.getLastName(), actual.getLastName() );
288     }
289 
290     /**
291      * Get input stream from {@link #TEST_XML}.
292      */
293     private Reader xmlTestReader()
294     {
295         return new StringReader( TEST_XML );
296     }
297 
298 }