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 }