001/* $Id: BeanPropertySetterRuleTestCase.java 1140140 2011-06-27 12:34:56Z simonetripodi $ 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one or more 004 * contributor license agreements. See the NOTICE file distributed with 005 * this work for additional information regarding copyright ownership. 006 * The ASF licenses this file to You under the Apache License, Version 2.0 007 * (the "License"); you may not use this file except in compliance with 008 * the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.commons.digester3; 020 021import static org.apache.commons.digester3.binder.DigesterLoader.newLoader; 022import static org.junit.Assert.assertEquals; 023import static org.junit.Assert.assertNotNull; 024import static org.junit.Assert.assertTrue; 025import static org.junit.Assert.fail; 026 027import java.io.IOException; 028import java.io.Reader; 029import java.io.StringReader; 030import java.lang.reflect.InvocationTargetException; 031import java.util.ArrayList; 032import java.util.List; 033 034import org.apache.commons.digester3.binder.AbstractRulesModule; 035import org.junit.Test; 036import org.xml.sax.SAXException; 037 038/** 039 * <p> 040 * Test case for <code>BeanPropertySetterRule</code>. This contains tests for the main applications of the rule and two 041 * more general tests of digester functionality used by this rule. 042 */ 043public class BeanPropertySetterRuleTestCase 044{ 045 046 // ----------------------------------------------------- Instance Variables 047 048 /** 049 * Simple test xml document used in the tests. 050 */ 051 protected final static String TEST_XML = "<?xml version='1.0'?>" + "<root>ROOT BODY" + "<alpha>ALPHA BODY</alpha>" 052 + "<beta>BETA BODY</beta>" + "<gamma>GAMMA BODY</gamma>" + "<delta>DELTA BODY</delta>" + "</root>"; 053 054 // ------------------------------------------------ Individual Test Methods 055 056 /** 057 * This is a general digester test but it fits into here pretty well. This tests that the rule calling order is 058 * properly enforced. 059 */ 060 @Test 061 public void testDigesterRuleCallOrder() 062 throws SAXException, IOException 063 { 064 065 final List<Rule> callOrder = new ArrayList<Rule>(); 066 067 Digester digester = newLoader( new AbstractRulesModule() 068 { 069 070 @Override 071 protected void configure() 072 { 073 // add first test rule 074 forPattern( "root/alpha" ).addRuleCreatedBy( new TestRule.TestRuleProvider( "first", callOrder ) ); 075 // add second test rule 076 forPattern( "root/alpha" ).addRuleCreatedBy( new TestRule.TestRuleProvider( "second", callOrder ) ); 077 // add third test rule 078 forPattern( "root/alpha" ).addRuleCreatedBy( new TestRule.TestRuleProvider( "third", callOrder ) ); 079 } 080 081 }).newDigester(); 082 083 digester.parse( xmlTestReader() ); 084 085 // we should have nine entries in our list of calls 086 087 assertEquals( "Nine calls should have been made.", 9, callOrder.size() ); 088 089 // begin should be called in the order added 090 assertEquals( "First rule begin not called first.", "first", ( (TestRule) callOrder.get( 0 ) ).getIdentifier() ); 091 092 assertEquals( "Second rule begin not called second.", "second", 093 ( (TestRule) callOrder.get( 1 ) ).getIdentifier() ); 094 095 assertEquals( "Third rule begin not called third.", "third", ( (TestRule) callOrder.get( 2 ) ).getIdentifier() ); 096 097 // body text should be called in the order added 098 assertEquals( "First rule body text not called first.", "first", 099 ( (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}