View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    * 
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   * 
19   */
20  package org.apache.directory.api.dsmlv2;
21  
22  
23  import java.io.IOException;
24  import java.util.HashMap;
25  
26  import org.apache.directory.api.i18n.I18n;
27  import org.apache.directory.api.util.Strings;
28  import org.xmlpull.v1.XmlPullParser;
29  import org.xmlpull.v1.XmlPullParserException;
30  
31  
32  /**
33   * The abstract Grammar which is the Mother of all the grammars. It contains
34   * the transitions table.
35   *
36   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
37   */
38  public abstract class AbstractGrammar implements Grammar
39  {
40      /**
41       * Table of transitions. It's a two dimension array, the first dimension
42       * indexes the states, the second dimension indexes the Tag value, so it is
43       * 256 wide.
44       */
45      protected HashMap<Tag, GrammarTransition>[] transitions;
46  
47      /** The grammar name */
48      protected String name;
49  
50      /** The grammar's states */
51      protected Enum<Dsmlv2StatesEnum>[] statesEnum;
52  
53  
54      /**
55       * Returns the grammar's name
56       * 
57       * @return The grammar name
58       */
59      public String getName()
60      {
61          return name;
62      }
63  
64  
65      /**
66       * Sets the grammar's name
67       * 
68       * @param name the name to set
69       */
70      public void setName( String name )
71      {
72          this.name = name;
73      }
74  
75  
76      /**
77       * Gets the transition associated with the state and tag
78       * 
79       * @param state The current state
80       * @param tag The current tag
81       * @return A valid transition if any, or null.
82       */
83      public GrammarTransition getTransition( Enum<Dsmlv2StatesEnum> state, Tag tag )
84      {
85          return transitions[state.ordinal()].get( tag );
86      }
87  
88  
89      /**
90       * Gets the states of the current grammar
91       * 
92       * @return Returns the statesEnum.
93       */
94      public Enum<Dsmlv2StatesEnum>[] getStatesEnum()
95      {
96          return Dsmlv2StatesEnum.values();
97      }
98  
99  
100     /**
101      * {@inheritDoc}
102      */
103     public void executeAction( Dsmlv2Container container ) throws XmlPullParserException, IOException
104     {
105         XmlPullParser xpp = container.getParser();
106 
107         int eventType = xpp.getEventType();
108 
109         do
110         {
111             switch ( eventType )
112             {
113                 case XmlPullParser.START_DOCUMENT:
114                     container.setState( Dsmlv2StatesEnum.INIT_GRAMMAR_STATE );
115                     break;
116 
117                 case XmlPullParser.END_DOCUMENT:
118                     container.setState( Dsmlv2StatesEnum.GRAMMAR_END );
119                     break;
120 
121                 case XmlPullParser.START_TAG:
122                     processTag( container, Tag.START );
123                     break;
124 
125                 case XmlPullParser.END_TAG:
126                     processTag( container, Tag.END );
127                     break;
128             }
129 
130             eventType = xpp.next();
131         }
132         while ( eventType != XmlPullParser.END_DOCUMENT );
133     }
134 
135 
136     /**
137      * Processes the task required in the grammar to the given tag type
138      *
139      * @param container the DSML container
140      * @param tagType the tag type
141      * @throws XmlPullParserException when an error occurs during the parsing
142      */
143     private void processTag( Dsmlv2Container container, int tagType ) throws XmlPullParserException
144     {
145         XmlPullParser xpp = container.getParser();
146 
147         String tagName = Strings.toLowerCase( xpp.getName() );
148 
149         GrammarTransition transition = getTransition( container.getState(), new Tag( tagName, tagType ) );
150 
151         if ( transition != null )
152         {
153             container.setState( transition.getNextState() );
154 
155             if ( transition.hasAction() )
156             {
157                 GrammarAction action = transition.getAction();
158                 action.action( container );
159             }
160         }
161         else
162         {
163             throw new XmlPullParserException( I18n.err( I18n.ERR_03036, new Tag( tagName, tagType ) ), xpp, null );
164         }
165     }
166 }