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 }