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 */ 020package org.apache.directory.shared.dsmlv2; 021 022 023import java.io.IOException; 024import java.util.HashMap; 025 026import org.apache.directory.shared.i18n.I18n; 027import org.xmlpull.v1.XmlPullParser; 028import org.xmlpull.v1.XmlPullParserException; 029 030 031/** 032 * The abstract IGrammar which is the Mother of all the grammars. It contains 033 * the transitions table. 034 * 035 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 036 */ 037public abstract class AbstractGrammar implements Grammar 038{ 039 040 /** 041 * Table of transitions. It's a two dimension array, the first dimension 042 * indexes the states, the second dimension indexes the Tag value, so it is 043 * 256 wide. 044 */ 045 protected HashMap<Tag, GrammarTransition>[] transitions; 046 047 /** The grammar name */ 048 protected String name; 049 050 /** The grammar's states */ 051 protected Enum<Dsmlv2StatesEnum>[] statesEnum; 052 053 054 /** 055 * Return the grammar's name 056 * 057 * @return The grammar name 058 */ 059 public String getName() 060 { 061 return name; 062 } 063 064 065 /** 066 * Set the grammar's name 067 * 068 * @param name 069 * the name to set 070 */ 071 public void setName( String name ) 072 { 073 this.name = name; 074 } 075 076 077 /** 078 * Get the transition associated with the state and tag 079 * 080 * @param state 081 * The current state 082 * @param tag 083 * The current tag 084 * @return A valid transition if any, or null. 085 */ 086 public GrammarTransition getTransition( Enum<Dsmlv2StatesEnum> state, Tag tag ) 087 { 088 return transitions[state.ordinal()].get( tag ); 089 } 090 091 092 /** 093 * Get the states of the current grammar 094 * 095 * @return 096 * Returns the statesEnum. 097 */ 098 public Enum<Dsmlv2StatesEnum>[] getStatesEnum() 099 { 100 return Dsmlv2StatesEnum.values(); 101 } 102 103 104 /** 105 * Set the states for this grammar 106 * 107 * @param statesEnum 108 * The statesEnum to set. 109 */ 110 public void setStatesEnum( Enum<Dsmlv2StatesEnum>[] statesEnum ) 111 { 112 this.statesEnum = statesEnum; 113 } 114 115 116 /** 117 * {@inheritDoc} 118 */ 119 public void executeAction( Dsmlv2Container container ) throws XmlPullParserException, IOException 120 { 121 XmlPullParser xpp = container.getParser(); 122 123 int eventType = xpp.getEventType(); 124 125 do 126 { 127 if ( eventType == XmlPullParser.START_DOCUMENT ) 128 { 129 container.setState( Dsmlv2StatesEnum.INIT_GRAMMAR_STATE ); 130 } 131 else if ( eventType == XmlPullParser.END_DOCUMENT ) 132 { 133 container.setState( Dsmlv2StatesEnum.GRAMMAR_END ); 134 } 135 else if ( eventType == XmlPullParser.START_TAG ) 136 { 137 processTag( container, Tag.START ); 138 } 139 else if ( eventType == XmlPullParser.END_TAG ) 140 { 141 processTag( container, Tag.END ); 142 } 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 GrammarAction action = transition.getAction(); 175 action.action( container ); 176 } 177 } 178 else 179 { 180 throw new XmlPullParserException( I18n.err( I18n.ERR_03036, new Tag( tagName, tagType ) ), xpp, null ); 181 } 182 } 183}