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.api.dsmlv2; 021 022 023import java.io.IOException; 024import java.util.HashMap; 025 026import org.apache.directory.api.i18n.I18n; 027import org.apache.directory.api.util.Strings; 028import org.xmlpull.v1.XmlPullParser; 029import org.xmlpull.v1.XmlPullParserException; 030 031 032/** 033 * The abstract Grammar 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 */ 038public abstract class AbstractGrammar implements Grammar 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 051 /** 052 * Returns the grammar's name 053 * 054 * @return The grammar name 055 */ 056 public String getName() 057 { 058 return name; 059 } 060 061 062 /** 063 * Sets the grammar's name 064 * 065 * @param name the name to set 066 */ 067 public void setName( String name ) 068 { 069 this.name = name; 070 } 071 072 073 /** 074 * Gets the transition associated with the state and tag 075 * 076 * @param state The current state 077 * @param tag The current tag 078 * @return A valid transition if any, or null. 079 */ 080 public GrammarTransition getTransition( Enum<Dsmlv2StatesEnum> state, Tag tag ) 081 { 082 return transitions[state.ordinal()].get( tag ); 083 } 084 085 086 /** 087 * Gets the states of the current grammar 088 * 089 * @return Returns the statesEnum. 090 */ 091 public Enum<Dsmlv2StatesEnum>[] getStatesEnum() 092 { 093 return Dsmlv2StatesEnum.values(); 094 } 095 096 097 /** 098 * {@inheritDoc} 099 */ 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}