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  
51      /**
52       * Returns the grammar's name
53       * 
54       * @return The grammar name
55       */
56      public String getName()
57      {
58          return name;
59      }
60  
61  
62      /**
63       * Sets the grammar's name
64       * 
65       * @param name the name to set
66       */
67      public void setName( String name )
68      {
69          this.name = name;
70      }
71  
72  
73      /**
74       * Gets the transition associated with the state and tag
75       * 
76       * @param state The current state
77       * @param tag The current tag
78       * @return A valid transition if any, or null.
79       */
80      public GrammarTransition getTransition( Enum<Dsmlv2StatesEnum> state, Tag tag )
81      {
82          return transitions[state.ordinal()].get( tag );
83      }
84  
85  
86      /**
87       * Gets the states of the current grammar
88       * 
89       * @return Returns the statesEnum.
90       */
91      public Enum<Dsmlv2StatesEnum>[] getStatesEnum()
92      {
93          return Dsmlv2StatesEnum.values();
94      }
95  
96  
97      /**
98       * {@inheritDoc}
99       */
100     public void executeAction( Dsmlv2Container container ) throws XmlPullParserException, IOException
101     {
102         XmlPullParser xpp = container.getParser();
103 
104         int eventType = xpp.getEventType();
105 
106         do
107         {
108             switch ( eventType )
109             {
110                 case XmlPullParser.START_DOCUMENT:
111                     container.setState( Dsmlv2StatesEnum.INIT_GRAMMAR_STATE );
112                     break;
113 
114                 case XmlPullParser.END_DOCUMENT:
115                     container.setState( Dsmlv2StatesEnum.GRAMMAR_END );
116                     break;
117 
118                 case XmlPullParser.START_TAG:
119                     processTag( container, Tag.START );
120                     break;
121 
122                 case XmlPullParser.END_TAG:
123                     processTag( container, Tag.END );
124                     break;
125 
126                 default:
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.toLowerCaseAscii( 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 }