Package org.apache.commons.digester

Source Code of org.apache.commons.digester.FactoryCreateRule

/* $Id: FactoryCreateRule.java,v 1.21.2.1 2004/07/30 20:11:01 rdonkin Exp $
*
* Copyright 2001-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 org.xml.sax.Attributes;

import org.apache.commons.collections.ArrayStack;


/**
* <p>Rule implementation that uses an {@link ObjectCreationFactory} to create
* a new object which it pushes onto the object stack.  When the element is
* complete, the object will be popped.</p>
*
* <p>This rule is intended in situations where the element's attributes are
* needed before the object can be created.  A common senario is for the
* ObjectCreationFactory implementation to use the attributes  as parameters
* in a call to either a factory method or to a non-empty constructor.
*/

public class FactoryCreateRule extends Rule {

    // ----------------------------------------------------------- Fields
   
    /** Should exceptions thrown by the factory be ignored? */
    private boolean ignoreCreateExceptions;
    /** Stock to manage */
    private ArrayStack exceptionIgnoredStack;

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


    /**
     * Construct a factory create rule that will use the specified
     * class name to create an {@link ObjectCreationFactory} which will
     * then be used to create an object and push it on the stack.
     *
     * @param digester The associated Digester
     * @param className Java class name of the object creation factory class
     *
     * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
     * Use {@link #FactoryCreateRule(String className)} instead.
     */
    public FactoryCreateRule(Digester digester, String className) {

        this(className);

    }


    /**
     * Construct a factory create rule that will use the specified
     * class to create an {@link ObjectCreationFactory} which will
     * then be used to create an object and push it on the stack.
     *
     * @param digester The associated Digester
     * @param clazz Java class name of the object creation factory class
     *
     * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
     * Use {@link #FactoryCreateRule(Class clazz)} instead.
     */
    public FactoryCreateRule(Digester digester, Class clazz) {

        this(clazz);

    }


    /**
     * Construct a factory create rule that will use the specified
     * class name (possibly overridden by the specified attribute if present)
     * to create an {@link ObjectCreationFactory}, which will then be used
     * to instantiate an object instance and push it onto the stack.
     *
     * @param digester The associated Digester
     * @param className Default Java class name of the factory class
     * @param attributeName Attribute name which, if present, contains an
     *  override of the class name of the object creation factory to create.
     *
     * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
     * Use {@link #FactoryCreateRule(String className, String attributeName)} instead.
     */
    public FactoryCreateRule(Digester digester,
                             String className, String attributeName) {

        this(className, attributeName);

    }


    /**
     * Construct a factory create rule that will use the specified
     * class (possibly overridden by the specified attribute if present)
     * to create an {@link ObjectCreationFactory}, which will then be used
     * to instantiate an object instance and push it onto the stack.
     *
     * @param digester The associated Digester
     * @param clazz Default Java class name of the factory class
     * @param attributeName Attribute name which, if present, contains an
     *  override of the class name of the object creation factory to create.
     *
     * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
     * Use {@link #FactoryCreateRule(Class clazz, String attributeName)} instead.
     */
    public FactoryCreateRule(Digester digester,
                             Class clazz, String attributeName) {

        this(clazz, attributeName);

    }


    /**
     * Construct a factory create rule using the given, already instantiated,
     * {@link ObjectCreationFactory}.
     *
     * @param digester The associated Digester
     * @param creationFactory called on to create the object.
     *
     * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
     * Use {@link #FactoryCreateRule(ObjectCreationFactory creationFactory)} instead.
     */
    public FactoryCreateRule(Digester digester,
                             ObjectCreationFactory creationFactory) {

        this(creationFactory);

    }   

    /**
     * <p>Construct a factory create rule that will use the specified
     * class name to create an {@link ObjectCreationFactory} which will
     * then be used to create an object and push it on the stack.</p>
     *
     * <p>Exceptions thrown during the object creation process will be propagated.</p>
     *
     * @param className Java class name of the object creation factory class
     */
    public FactoryCreateRule(String className) {

        this(className, false);

    }


    /**
     * <p>Construct a factory create rule that will use the specified
     * class to create an {@link ObjectCreationFactory} which will
     * then be used to create an object and push it on the stack.</p>
     *
     * <p>Exceptions thrown during the object creation process will be propagated.</p>
     *
     * @param clazz Java class name of the object creation factory class
     */
    public FactoryCreateRule(Class clazz) {

        this(clazz, false);

    }


    /**
     * <p>Construct a factory create rule that will use the specified
     * class name (possibly overridden by the specified attribute if present)
     * to create an {@link ObjectCreationFactory}, which will then be used
     * to instantiate an object instance and push it onto the stack.</p>
     *
     * <p>Exceptions thrown during the object creation process will be propagated.</p>
     *
     * @param className Default Java class name of the factory class
     * @param attributeName Attribute name which, if present, contains an
     *  override of the class name of the object creation factory to create.
     */
    public FactoryCreateRule(String className, String attributeName) {

        this(className, attributeName, false);

    }


    /**
     * <p>Construct a factory create rule that will use the specified
     * class (possibly overridden by the specified attribute if present)
     * to create an {@link ObjectCreationFactory}, which will then be used
     * to instantiate an object instance and push it onto the stack.</p>
     *
     * <p>Exceptions thrown during the object creation process will be propagated.</p>
     *
     * @param clazz Default Java class name of the factory class
     * @param attributeName Attribute name which, if present, contains an
     *  override of the class name of the object creation factory to create.
     */
    public FactoryCreateRule(Class clazz, String attributeName) {

        this(clazz, attributeName, false);

    }


    /**
     * <p>Construct a factory create rule using the given, already instantiated,
     * {@link ObjectCreationFactory}.</p>
     *
     * <p>Exceptions thrown during the object creation process will be propagated.</p>
     *
     * @param creationFactory called on to create the object.
     */
    public FactoryCreateRule(ObjectCreationFactory creationFactory) {

        this(creationFactory, false);

    }
   
    /**
     * Construct a factory create rule that will use the specified
     * class name to create an {@link ObjectCreationFactory} which will
     * then be used to create an object and push it on the stack.
     *
     * @param className Java class name of the object creation factory class
     * @param ignoreCreateExceptions if true, exceptions thrown by the object
     *  creation factory
     * will be ignored.
     */
    public FactoryCreateRule(String className, boolean ignoreCreateExceptions) {

        this(className, null, ignoreCreateExceptions);

    }


    /**
     * Construct a factory create rule that will use the specified
     * class to create an {@link ObjectCreationFactory} which will
     * then be used to create an object and push it on the stack.
     *
     * @param clazz Java class name of the object creation factory class
     * @param ignoreCreateExceptions if true, exceptions thrown by the
     *  object creation factory
     * will be ignored.
     */
    public FactoryCreateRule(Class clazz, boolean ignoreCreateExceptions) {

        this(clazz, null, ignoreCreateExceptions);

    }


    /**
     * Construct a factory create rule that will use the specified
     * class name (possibly overridden by the specified attribute if present)
     * to create an {@link ObjectCreationFactory}, which will then be used
     * to instantiate an object instance and push it onto the stack.
     *
     * @param className Default Java class name of the factory class
     * @param attributeName Attribute name which, if present, contains an
     *  override of the class name of the object creation factory to create.
     * @param ignoreCreateExceptions if true, exceptions thrown by the object
     *  creation factory will be ignored.
     */
    public FactoryCreateRule(
                                String className,
                                String attributeName,
                                boolean ignoreCreateExceptions) {

        this.className = className;
        this.attributeName = attributeName;
        this.ignoreCreateExceptions = ignoreCreateExceptions;

    }


    /**
     * Construct a factory create rule that will use the specified
     * class (possibly overridden by the specified attribute if present)
     * to create an {@link ObjectCreationFactory}, which will then be used
     * to instantiate an object instance and push it onto the stack.
     *
     * @param clazz Default Java class name of the factory class
     * @param attributeName Attribute name which, if present, contains an
     *  override of the class name of the object creation factory to create.
     * @param ignoreCreateExceptions if true, exceptions thrown by the object
     *  creation factory will be ignored.
     */
    public FactoryCreateRule(
                                Class clazz,
                                String attributeName,
                                boolean ignoreCreateExceptions) {

        this(clazz.getName(), attributeName, ignoreCreateExceptions);

    }


    /**
     * Construct a factory create rule using the given, already instantiated,
     * {@link ObjectCreationFactory}.
     *
     * @param creationFactory called on to create the object.
     * @param ignoreCreateExceptions if true, exceptions thrown by the object
     *  creation factory will be ignored.
     */
    public FactoryCreateRule(
                            ObjectCreationFactory creationFactory,
                            boolean ignoreCreateExceptions) {

        this.creationFactory = creationFactory;
        this.ignoreCreateExceptions = ignoreCreateExceptions;
    }

    // ----------------------------------------------------- Instance Variables


    /**
     * The attribute containing an override class name if it is present.
     */
    protected String attributeName = null;


    /**
     * The Java class name of the ObjectCreationFactory to be created.
     * This class must have a no-arguments constructor.
     */
    protected String className = null;


    /**
     * The object creation factory we will use to instantiate objects
     * as required based on the attributes specified in the matched XML
     * element.
     */
    protected ObjectCreationFactory creationFactory = null;


    // --------------------------------------------------------- Public Methods


    /**
     * Process the beginning of this element.
     *
     * @param attributes The attribute list of this element
     */
    public void begin(String namespace, String name, Attributes attributes) throws Exception {
       
        if (ignoreCreateExceptions) {
       
            if (exceptionIgnoredStack == null) {
                exceptionIgnoredStack = new ArrayStack();
            }
           
            try {
                Object instance = getFactory(attributes).createObject(attributes);
               
                if (digester.log.isDebugEnabled()) {
                    digester.log.debug("[FactoryCreateRule]{" + digester.match +
                            "} New " + instance.getClass().getName());
                }
                digester.push(instance);
                exceptionIgnoredStack.push(Boolean.FALSE);
               
            } catch (Exception e) {
                // log message and error
                if (digester.log.isInfoEnabled()) {
                    digester.log.info("[FactoryCreateRule] Create exception ignored: " +
                        ((e.getMessage() == null) ? e.getClass().getName() : e.getMessage()));
                    if (digester.log.isDebugEnabled()) {
                        digester.log.debug("[FactoryCreateRule] Ignored exception:", e);
                    }
                }
                exceptionIgnoredStack.push(Boolean.TRUE);
            }
           
        } else {
            Object instance = getFactory(attributes).createObject(attributes);
           
            if (digester.log.isDebugEnabled()) {
                digester.log.debug("[FactoryCreateRule]{" + digester.match +
                        "} New " + instance.getClass().getName());
            }
            digester.push(instance);
        }
    }


    /**
     * Process the end of this element.
     */
    public void end(String namespace, String name) throws Exception {
       
        // check if object was created
        // this only happens if an exception was thrown and we're ignoring them
        if
                ignoreCreateExceptions &&
                exceptionIgnoredStack != null &&
                !(exceptionIgnoredStack.empty())) {
               
            if (((Boolean) exceptionIgnoredStack.pop()).booleanValue()) {
                // creation exception was ignored
                // nothing was put onto the stack
                if (digester.log.isTraceEnabled()) {
                    digester.log.trace("[FactoryCreateRule] No creation so no push so no pop");
                }
                return;
            }
        }

        Object top = digester.pop();
        if (digester.log.isDebugEnabled()) {
            digester.log.debug("[FactoryCreateRule]{" + digester.match +
                    "} Pop " + top.getClass().getName());
        }

    }


    /**
     * Clean up after parsing is complete.
     */
    public void finish() throws Exception {

        if (attributeName != null) {
            creationFactory = null;
        }

    }


    /**
     * Render a printable version of this Rule.
     */
    public String toString() {

        StringBuffer sb = new StringBuffer("FactoryCreateRule[");
        sb.append("className=");
        sb.append(className);
        sb.append(", attributeName=");
        sb.append(attributeName);
        if (creationFactory != null) {
            sb.append(", creationFactory=");
            sb.append(creationFactory);
        }
        sb.append("]");
        return (sb.toString());

    }


    // ------------------------------------------------------ Protected Methods


    /**
     * Return an instance of our associated object creation factory,
     * creating one if necessary.
     *
     * @param attributes Attributes passed to our factory creation element
     *
     * @exception Exception if any error occurs
     */
    protected ObjectCreationFactory getFactory(Attributes attributes)
            throws Exception {

        if (creationFactory == null) {
            String realClassName = className;
            if (attributeName != null) {
                String value = attributes.getValue(attributeName);
                if (value != null) {
                    realClassName = value;
                }
            }
            if (digester.log.isDebugEnabled()) {
                digester.log.debug("[FactoryCreateRule]{" + digester.match +
                        "} New factory " + realClassName);
            }
            Class clazz = digester.getClassLoader().loadClass(realClassName);
            creationFactory = (ObjectCreationFactory)
                    clazz.newInstance();
            creationFactory.setDigester(digester);
        }
        return (creationFactory);

    }   
}
TOP

Related Classes of org.apache.commons.digester.FactoryCreateRule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.