⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setnestedpropertiesrule.java

📁 JAVA 文章管理系统源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* $Id: SetNestedPropertiesRule.java,v 1.8 2004/05/10 06:52:50 skitching Exp $
 *
 * Copyright 2003-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ 


package org.apache.commons.digester;


import java.util.List;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.HashMap;
import java.beans.PropertyDescriptor;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaProperty;
import org.apache.commons.beanutils.PropertyUtils;

import org.xml.sax.Attributes;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * <p>Rule implementation that sets properties on the object at the top of the
 * stack, based on child elements with names matching properties on that 
 * object.</p>
 *
 * <p>Example input that can be processed by this rule:</p>
 * <pre>
 *   [widget]
 *    [height]7[/height]
 *    [width]8[/width]
 *    [label]Hello, world[/label]
 *   [/widget]
 * </pre>
 *
 * <p>This rule supports custom mapping of attribute names to property names.
 * The default mapping for particular attributes can be overridden by using 
 * {@link #SetNestedPropertiesRule(String[] elementNames,
 *                                 String[] propertyNames)}.
 * This allows child elements to be mapped to properties with different names.
 * Certain elements can also be marked to be ignored.</p>
 *
 * <p>A very similar effect can be achieved using a combination of the 
 * <code>BeanPropertySetterRule</code> and the <code>ExtendedBaseRules</code> 
 * rules manager; this <code>Rule</code>, however, works fine with the default 
 * <code>RulesBase</code> rules manager.</p>
 *
 * <p><b>Implementation Notes</b></p>
 *
 * <p>This class works by creating its own simple Rules implementation. When
 * begin is invoked on this rule, the digester's current rules object is
 * replaced by a custom one. When end is invoked for this rule, the original
 * rules object is restored. The digester rules objects therefore behave in
 * a stack-like manner.</p>
 *
 * <p>For each child element encountered, the custom Rules implementation
 * ensures that a special AnyChildRule instance is included in the matches 
 * returned to the digester, and it is this rule instance that is responsible 
 * for setting the appropriate property on the target object (if such a property 
 * exists). The effect is therefore like a "trailing wildcard pattern". The 
 * custom Rules implementation also returns the matches provided by the 
 * underlying Rules implementation for the same pattern, so other rules
 * are not "disabled" during processing of a SetNestedPropertiesRule.</p> 
 *
 * @since 1.6
 */

public class SetNestedPropertiesRule extends Rule {

    /**
     * Dummy object that can be placed in collections to indicate an
     * ignored property when null cannot be used for that purpose.
     */
    private static final String PROP_IGNORE = "ignore-me";
    
    private Log log = null;
    
    private AnyChildRule anyChildRule = new AnyChildRule();
    private AnyChildRules newRules = new AnyChildRules(anyChildRule);
    private Rules oldRules = null;

    private boolean trimData = true;
    private boolean allowUnknownChildElements = false;
    
    private HashMap elementNames = new HashMap();

    // ----------------------------------------------------------- Constructors

    /**
     * Base constructor.
     */
    public SetNestedPropertiesRule() {
        // nothing to set up 
    }
    
    /** 
     * <p>Convenience constructor overrides the mapping for just one property.</p>
     *
     * <p>For details about how this works, see
     * {@link #SetNestedPropertiesRule(String[] elementNames, 
     * String[] propertyNames)}.</p>
     *
     * @param elementName map the child element to match 
     * @param propertyName to a property with this name
     */
    public SetNestedPropertiesRule(String elementName, String propertyName) {
        elementNames.put(elementName, propertyName);
    }
    
    /** 
     * <p>Constructor allows element->property mapping to be overriden.</p>
     *
     * <p>Two arrays are passed in. 
     * One contains the element names and the other the property names.
     * The element name / property name pairs are match by position
     * In order words, the first string in the element name list matches
     * to the first string in the property name list and so on.</p>
     *
     * <p>If a property name is null or the element name has no matching
     * property name, then this indicates that the element should be ignored.</p>
     * 
     * <h5>Example One</h5>
     * <p> The following constructs a rule that maps the <code>alt-city</code>
     * element to the <code>city</code> property and the <code>alt-state</code>
     * to the <code>state</code> property. 
     * All other child elements are mapped as usual using exact name matching.
     * <code><pre>
     *      SetNestedPropertiesRule(
     *                new String[] {"alt-city", "alt-state"}, 
     *                new String[] {"city", "state"});
     * </pre></code>
     *
     * <h5>Example Two</h5>
     * <p> The following constructs a rule that maps the <code>class</code>
     * element to the <code>className</code> property.
     * The element <code>ignore-me</code> is not mapped.
     * All other elements are mapped as usual using exact name matching.
     * <code><pre>
     *      SetPropertiesRule(
     *                new String[] {"class", "ignore-me"}, 
     *                new String[] {"className"});
     * </pre></code>
     *
     * @param elementNames names of elements to map
     * @param propertyNames names of properties mapped to
     */
    public SetNestedPropertiesRule(String[] elementNames, String[] propertyNames) {
        for (int i=0, size=elementNames.length; i<size; i++) {
            String propName = null;
            if (i < propertyNames.length) {
                propName = propertyNames[i];
            }
            
            if (propName == null) {
                this.elementNames.put(elementNames[i], PROP_IGNORE);
            }
            else {
                this.elementNames.put(elementNames[i], propName);
            }
        }
    }
        
    // --------------------------------------------------------- Public Methods

    /** Invoked when rule is added to digester. */
    public void setDigester(Digester digester) {
        super.setDigester(digester);
        log = digester.getLogger();
        anyChildRule.setDigester(digester);
    }
    
    /**
     * When set to true, any text within child elements will have leading
     * and trailing whitespace removed before assignment to the target
     * object. The default value for this attribute is true.
     */
    public void setTrimData(boolean trimData) {
        this.trimData = trimData;
    }
    
    /** See {@link #setTrimData}. */
     public boolean getTrimData() {
        return trimData;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -