001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    
021    package org.apache.directory.shared.dsmlv2;
022    
023    
024    import java.io.IOException;
025    import java.util.HashMap;
026    
027    import org.apache.directory.shared.i18n.I18n;
028    import org.xmlpull.v1.XmlPullParser;
029    import org.xmlpull.v1.XmlPullParserException;
030    
031    
032    /**
033     * The abstract IGrammar which is the Mother of all the grammars. It contains
034     * the transitions table.
035     *
036     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
037     * @version $Rev$, $Date$
038     */
039    public abstract class AbstractGrammar implements IGrammar
040    {
041    
042        /**
043         * Table of transitions. It's a two dimension array, the first dimension
044         * indice the states, the second dimension indices the Tag value, so it is
045         * 256 wide.
046         */
047        protected HashMap<Tag, GrammarTransition>[] transitions;
048    
049        /** The grammar name */
050        protected String name;
051    
052        /** The grammar's states */
053        protected IStates statesEnum;
054    
055    
056        /**
057         * Return the grammar's name
058         * 
059         * @return The grammar name
060         */
061        public String getName()
062        {
063            return name;
064        }
065    
066    
067        /**
068         * Set the grammar's name
069         * 
070         * @param name
071         *      the name to set
072         */
073        public void setName( String name )
074        {
075            this.name = name;
076        }
077    
078    
079        /**
080         * Get the transition associated with the state and tag
081         * 
082         * @param state
083         *            The current state
084         * @param tag
085         *            The current tag
086         * @return A valid transition if any, or null.
087         */
088        public GrammarTransition getTransition( int state, Tag tag )
089        {
090            return transitions[state].get( tag );
091        }
092    
093    
094        /**
095         * Get the states of the current grammar
096         * 
097         * @return 
098         *      Returns the statesEnum.
099         */
100        public IStates getStatesEnum()
101        {
102            return statesEnum;
103        }
104    
105    
106        /**
107         * Set the states for this grammar
108         * 
109         * @param statesEnum
110         *      The statesEnum to set.
111         */
112        public void setStatesEnum( IStates statesEnum )
113        {
114            this.statesEnum = statesEnum;
115        }
116    
117    
118        /* (non-Javadoc)
119         * @see org.apache.directory.shared.dsmlv2.IGrammar#executeAction(org.apache.directory.shared.dsmlv2.Dsmlv2Container)
120         */
121        public void executeAction( Dsmlv2Container container ) throws XmlPullParserException, IOException
122        {
123            XmlPullParser xpp = container.getParser();
124    
125            int eventType = xpp.getEventType();
126            do
127            {
128                if ( eventType == XmlPullParser.START_DOCUMENT )
129                {
130                    container.setState( Dsmlv2StatesEnum.INIT_GRAMMAR_STATE );
131                }
132                else if ( eventType == XmlPullParser.END_DOCUMENT )
133                {
134                    container.setState( Dsmlv2StatesEnum.END_STATE );
135                }
136                else if ( eventType == XmlPullParser.START_TAG )
137                {
138                    processTag( container, Tag.START );
139                }
140                else if ( eventType == XmlPullParser.END_TAG )
141                {
142                    processTag( container, Tag.END );
143                }
144                eventType = xpp.next();
145            }
146            while ( eventType != XmlPullParser.END_DOCUMENT );
147        }
148    
149    
150        /**
151         * Processes the task required in the grammar to the given tag type
152         *
153         * @param container
154         *      the DSML container
155         * @param tagType
156         *      the tag type
157         * @throws XmlPullParserException 
158         *      when an error occurs during the parsing
159         */
160        private void processTag( Dsmlv2Container container, int tagType ) throws XmlPullParserException
161        {
162            XmlPullParser xpp = container.getParser();
163    
164            String tagName = xpp.getName().toLowerCase();
165    
166            GrammarTransition transition = getTransition( container.getState(), new Tag( tagName, tagType ) );
167    
168            if ( transition != null )
169            {
170                container.setState( transition.getNextState() );
171    
172                if ( transition.hasAction() )
173                {
174                    transition.getAction().action( container );
175                }
176            }
177            else
178            {
179                throw new XmlPullParserException( I18n.err( I18n.ERR_03036, new Tag( tagName, tagType ) ), xpp, null );
180            }
181        }
182    }