001    package 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    
022    import static java.lang.String.format;
023    
024    import org.xml.sax.Attributes;
025    
026    /**
027     * Rule implementation that creates a new object and pushes it onto the object stack. When the element is complete, the
028     * object will be popped
029     */
030    public class ObjectCreateRule
031        extends Rule
032    {
033    
034        // ----------------------------------------------------------- Constructors
035    
036        /**
037         * Construct an object create rule with the specified class name.
038         * 
039         * @param className Java class name of the object to be created
040         */
041        public ObjectCreateRule( String className )
042        {
043            this( className, (String) null );
044        }
045    
046        /**
047         * Construct an object create rule with the specified class.
048         * 
049         * @param clazz Java class name of the object to be created
050         */
051        public ObjectCreateRule( Class<?> clazz )
052        {
053            this( clazz.getName(), (String) null );
054            this.clazz = clazz;
055        }
056    
057        /**
058         * Construct an object create rule with the specified class name and an optional attribute name containing an
059         * override.
060         * 
061         * @param className Java class name of the object to be created
062         * @param attributeName Attribute name which, if present, contains an override of the class name to create
063         */
064        public ObjectCreateRule( String className, String attributeName )
065        {
066            this.className = className;
067            this.attributeName = attributeName;
068        }
069    
070        /**
071         * Construct an object create rule with the specified class and an optional attribute name containing an override.
072         * 
073         * @param attributeName Attribute name which, if present, contains an
074         * @param clazz Java class name of the object to be created override of the class name to create
075         */
076        public ObjectCreateRule( String attributeName, Class<?> clazz )
077        {
078            this( clazz.getName(), attributeName );
079            this.clazz = clazz;
080        }
081    
082        // ----------------------------------------------------- Instance Variables
083    
084        /**
085         * The attribute containing an override class name if it is present.
086         */
087        protected String attributeName = null;
088    
089        /**
090         * The Java class of the object to be created.
091         */
092        protected Class<?> clazz = null;
093    
094        /**
095         * The Java class name of the object to be created.
096         */
097        protected String className = null;
098    
099        // --------------------------------------------------------- Public Methods
100    
101        /**
102         * {@inheritDoc}
103         */
104        @Override
105        public void begin( String namespace, String name, Attributes attributes )
106            throws Exception
107        {
108            Class<?> clazz = this.clazz;
109    
110            if ( clazz == null )
111            {
112                // Identify the name of the class to instantiate
113                String realClassName = className;
114                if ( attributeName != null )
115                {
116                    String value = attributes.getValue( attributeName );
117                    if ( value != null )
118                    {
119                        realClassName = value;
120                    }
121                }
122                if ( getDigester().getLogger().isDebugEnabled() )
123                {
124                    getDigester().getLogger().debug( format( "[ObjectCreateRule]{%s} New '%s'",
125                                                             getDigester().getMatch(),
126                                                             realClassName ) );
127                }
128    
129                // Instantiate the new object and push it on the context stack
130                clazz = getDigester().getClassLoader().loadClass( realClassName );
131            }
132            Object instance = clazz.newInstance();
133            getDigester().push( instance );
134        }
135    
136        /**
137         * {@inheritDoc}
138         */
139        @Override
140        public void end( String namespace, String name )
141            throws Exception
142        {
143            Object top = getDigester().pop();
144            if ( getDigester().getLogger().isDebugEnabled() )
145            {
146                getDigester().getLogger().debug( format( "[ObjectCreateRule]{%s} Pop '%s'",
147                                                         getDigester().getMatch(),
148                                                         top.getClass().getName() ) );
149            }
150        }
151    
152        /**
153         * {@inheritDoc}
154         */
155        @Override
156        public String toString()
157        {
158            return format( "ObjectCreateRule[className=%s, attributeName=%s]", className, attributeName );
159        }
160    
161    }