001package org.apache.commons.digester3;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import static org.apache.commons.digester3.binder.DigesterLoader.newLoader;
023import static org.junit.Assert.assertEquals;
024import static org.junit.Assert.assertFalse;
025import static org.junit.Assert.assertTrue;
026
027import org.apache.commons.digester3.annotations.FromAnnotationsRuleModule;
028import org.apache.commons.digester3.binder.AbstractRulesModule;
029import org.apache.commons.digester3.binder.RulesModule;
030import org.apache.commons.digester3.xmlrules.FromXmlRulesModule;
031import org.junit.Test;
032import org.xml.sax.SAXParseException;
033
034/**
035 * DIGESTER-153
036 */
037public final class Digester153TestCase
038{
039
040    @Test
041    public void basicConstructor()
042        throws Exception
043    {
044        ObjectCreateRule createRule = new ObjectCreateRule( TestBean.class );
045        createRule.setConstructorArgumentTypes( boolean.class, double.class );
046
047        Digester digester = new Digester();
048        digester.addRule( "toplevel/bean", createRule );
049        digester.addCallParam( "toplevel/bean", 0, "boolean" );
050        digester.addCallParam( "toplevel/bean", 1, "double" );
051
052        TestBean bean = digester.parse( getClass().getResourceAsStream( "BasicConstructor.xml" ) );
053
054        assertTrue( bean.getBooleanProperty() );
055        assertEquals( 9.99D, bean.getDoubleProperty(), 0 );
056
057        // do it again to exercise the cglib Factory:
058        bean = digester.parse( getClass().getResourceAsStream( "BasicConstructor.xml" ) );
059
060        assertTrue( bean.getBooleanProperty() );
061        assertEquals( 9.99D, bean.getDoubleProperty(), 0 );
062    }
063
064    @Test
065    public void constructorWithAttributeAndElement()
066        throws Exception
067    {
068        ObjectCreateRule createRule = new ObjectCreateRule( TestBean.class );
069        createRule.setConstructorArgumentTypes( boolean.class, double.class );
070
071        Digester digester = new Digester();
072        digester.addRule( "toplevel/bean", createRule );
073        digester.addCallParam( "toplevel/bean", 0, "boolean" );
074        digester.addCallParam( "toplevel/bean/double", 1 );
075        digester.addBeanPropertySetter("toplevel/bean/float", "floatProperty");
076
077        TestBean bean = digester.parse( getClass().getResourceAsStream( "ConstructorWithAttributeAndElement.xml" ) );
078
079        assertTrue( bean.getBooleanProperty() );
080        assertEquals( 9.99D, bean.getDoubleProperty(), 0 );
081        assertEquals( Float.valueOf( 5.5f ), Float.valueOf( bean.getFloatProperty() ) );
082
083        // do it again to exercise the cglib Factory:
084        bean = digester.parse( getClass().getResourceAsStream( "ConstructorWithAttributeAndElement.xml" ) );
085
086        assertTrue( bean.getBooleanProperty() );
087        assertEquals( 9.99D, bean.getDoubleProperty(), 0 );
088        assertEquals( Float.valueOf( 5.5f ), Float.valueOf( bean.getFloatProperty() ) );
089    }
090
091    @Test
092    public void basicConstructorViaBinder()
093        throws Exception
094    {
095        succesfullConstructor( new AbstractRulesModule()
096        {
097
098            @Override
099            protected void configure()
100            {
101                forPattern( "toplevel/bean" )
102                    .createObject().ofType( TestBean.class ).usingConstructor( boolean.class, double.class )
103                    .then()
104                    .callParam().fromAttribute( "boolean" ).ofIndex( 0 )
105                    .then()
106                    .callParam().fromAttribute( "double" ).ofIndex( 1 );
107            }
108
109        } );
110    }
111
112    @Test
113    public void basicConstructorViaAnnotations()
114        throws Exception
115    {
116        succesfullConstructor( new FromAnnotationsRuleModule()
117        {
118
119            @Override
120            protected void configureRules()
121            {
122                bindRulesFrom( TestBean.class );
123            }
124
125        } );
126    }
127
128    @Test
129    public void basicConstructorViaXML()
130        throws Exception
131    {
132        succesfullConstructor( new FromXmlRulesModule()
133        {
134
135            @Override
136            protected void loadRules()
137            {
138                loadXMLRules( getClass().getResourceAsStream( "xmlrules/constructor-testrules.xml" ) );
139            }
140
141        } );
142    }
143
144    private void succesfullConstructor( RulesModule rulesModule )
145        throws Exception
146    {
147        TestBean bean = newLoader( rulesModule )
148                            .newDigester()
149                            .parse( getClass().getResourceAsStream( "BasicConstructor.xml" ) );
150
151        assertTrue( bean.getBooleanProperty() );
152        assertEquals( 9.99D, bean.getDoubleProperty(), 0 );
153    }
154
155    @Test
156    public void basicConstructorWithValuesNotFound()
157        throws Exception
158    {
159        ObjectCreateRule createRule = new ObjectCreateRule( TestBean.class );
160        createRule.setConstructorArgumentTypes( boolean.class, double.class );
161
162        Digester digester = new Digester();
163        digester.addRule( "toplevel/bean", createRule );
164        digester.addCallParam( "toplevel/bean", 0, "notFound1" );
165        digester.addCallParam( "toplevel/bean", 1, "notFound2" );
166
167        TestBean bean = digester.parse( getClass().getResourceAsStream( "BasicConstructor.xml" ) );
168
169        assertFalse( bean.getBooleanProperty() );
170        assertEquals( 0D, bean.getDoubleProperty(), 0 );
171    }
172
173    @Test( expected = SAXParseException.class )
174    public void basicConstructorWithWrongParameters()
175        throws Exception
176    {
177        ObjectCreateRule createRule = new ObjectCreateRule( TestBean.class );
178        createRule.setConstructorArgumentTypes( boolean.class );
179
180        Digester digester = new Digester();
181        digester.addRule( "toplevel/bean", createRule );
182
183        digester.parse( getClass().getResourceAsStream( "BasicConstructor.xml" ) );
184    }
185
186    @Test
187    public void constructorWithClassDefinedInAttribute()
188        throws Exception
189    {
190        ObjectCreateRule createRule = new ObjectCreateRule( null, "type" );
191        createRule.setConstructorArgumentTypes( boolean.class, double.class );
192
193        Digester digester = new Digester();
194        digester.addRule( "toplevel/bean", createRule );
195        digester.addCallParam( "toplevel/bean", 0, "boolean" );
196        digester.addCallParam( "toplevel/bean", 1, "double" );
197
198        TestBean bean = digester.parse( getClass().getResourceAsStream( "AttributeDefinedConstructor.xml" ) );
199
200        assertTrue( bean.getBooleanProperty() );
201        assertEquals( 9.99D, bean.getDoubleProperty(), 0 );
202    }
203
204}