001    package org.apache.commons.digester3.binder;
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    
022    import java.util.HashMap;
023    import java.util.Map;
024    
025    import org.apache.commons.digester3.SetNestedPropertiesRule;
026    
027    /**
028     * Builder chained when invoking {@link LinkedRuleBuilder#setNestedProperties()}.
029     *
030     * @since 3.0
031     */
032    public final class NestedPropertiesBuilder
033        extends AbstractBackToLinkedRuleBuilder<SetNestedPropertiesRule>
034    {
035    
036        private final Map<String, String> elementNames = new HashMap<String, String>();
037    
038        private boolean trimData = true;
039    
040        private boolean allowUnknownChildElements = false;
041    
042        NestedPropertiesBuilder( String keyPattern, String namespaceURI, RulesBinder mainBinder,
043                                        LinkedRuleBuilder mainBuilder )
044        {
045            super( keyPattern, namespaceURI, mainBinder, mainBuilder );
046        }
047    
048        /**
049         * Allows ignore a matching element.
050         *
051         * @param elementName The child xml element to be ignored
052         * @return this builder instance
053         */
054        public NestedPropertiesBuilder ignoreElement( String elementName )
055        {
056            if ( elementName == null )
057            {
058                reportError( "setNestedProperties().ignoreElement( String )", "empty 'elementName' not allowed" );
059            }
060            return addAlias( elementName ).forProperty( null );
061        }
062    
063        /**
064         * Allows element2property mapping to be overridden.
065         *
066         * @param elementName The child xml element to match
067         * @param propertyName The java bean property to be assigned the value
068         * @return this builder instance
069         * @deprecated
070         */
071        @Deprecated
072        public NestedPropertiesBuilder addAlias( String elementName, String propertyName )
073        {
074            return addAlias( elementName ).forProperty( propertyName );
075        }
076    
077        /**
078         * Allows element2property mapping to be overridden.
079         *
080         * @param elementName The child xml element to match
081         * @return the property alias builder
082         * @since 3.2
083         */
084        public AddAliasBuilder<NestedPropertiesBuilder> addAlias( String elementName )
085        {
086            if ( elementName == null )
087            {
088                reportError( "setProperties().addAlias( String )", "empty 'elementName' not allowed" );
089            }
090            return new AddAliasBuilder<NestedPropertiesBuilder>( this, elementNames, elementName );
091        }
092    
093        /**
094         * When set to true, any text within child elements will have leading
095         * and trailing whitespace removed before assignment to the target
096         * object.
097         *
098         * @param trimData Flag to set any text within child elements will have leading
099         *                 and trailing whitespace removed
100         * @return this builder instance
101         */
102        public NestedPropertiesBuilder trimData( boolean trimData )
103        {
104            this.trimData = trimData;
105            return this;
106        }
107    
108        /**
109         * Determines whether an error is reported when a nested element is encountered for which there is no corresponding
110         * property-setter method.
111         *
112         * @param allowUnknownChildElements flag to ignore any child element for which there is no corresponding
113         *        object property
114         * @return this builder instance
115         */
116        public NestedPropertiesBuilder allowUnknownChildElements( boolean allowUnknownChildElements )
117        {
118            this.allowUnknownChildElements = allowUnknownChildElements;
119            return this;
120        }
121    
122        /**
123         * {@inheritDoc}
124         */
125        @Override
126        protected SetNestedPropertiesRule createRule()
127        {
128            SetNestedPropertiesRule rule = new SetNestedPropertiesRule( elementNames );
129            rule.setTrimData( trimData );
130            rule.setAllowUnknownChildElements( allowUnknownChildElements );
131            return rule;
132        }
133    
134    }