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 @Override 057 public String getName() 058 { 059 return name; 060 } 061 062 063 /** 064 * Sets the grammar's name 065 * 066 * @param name the name to set 067 */ 068 @Override 069 public void setName( String name ) 070 { 071 this.name = name; 072 } 073 074 075 /** 076 * Gets the transition associated with the state and tag 077 * 078 * @param state The current state 079 * @param tag The current tag 080 * @return A valid transition if any, or null. 081 */ 082 public GrammarTransition getTransition( Enum<Dsmlv2StatesEnum> state, Tag tag ) 083 { 084 return transitions[state.ordinal()].get( tag ); 085 } 086 087 088 /** 089 * Gets the states of the current grammar 090 * 091 * @return Returns the statesEnum. 092 */ 093 @Override 094 public Enum<Dsmlv2StatesEnum>[] getStatesEnum() 095 { 096 return Dsmlv2StatesEnum.values(); 097 } 098 099 100 /** 101 * {@inheritDoc} 102 */ 103 @Override 104 public void executeAction( Dsmlv2Container container ) throws XmlPullParserException, IOException 105 { 106 XmlPullParser xpp = container.getParser(); 107 108 int eventType = xpp.getEventType(); 109 110 do 111 { 112 switch ( eventType ) 113 { 114 case XmlPullParser.START_DOCUMENT: 115 container.setState( Dsmlv2StatesEnum.INIT_GRAMMAR_STATE ); 116 break; 117 118 case XmlPullParser.END_DOCUMENT: 119 container.setState( Dsmlv2StatesEnum.GRAMMAR_END ); 120 break; 121 122 case XmlPullParser.START_TAG: 123 processTag( container, Tag.START ); 124 break; 125 126 case XmlPullParser.END_TAG: 127 processTag( container, Tag.END ); 128 break; 129 130 default: 131 break; 132 } 133 134 eventType = xpp.next(); 135 } 136 while ( eventType != XmlPullParser.END_DOCUMENT ); 137 } 138 139 140 /** 141 * Processes the task required in the grammar to the given tag type 142 * 143 * @param container the DSML container 144 * @param tagType the tag type 145 * @throws XmlPullParserException when an error occurs during the parsing 146 */ 147 private void processTag( Dsmlv2Container container, int tagType ) throws XmlPullParserException 148 { 149 XmlPullParser xpp = container.getParser(); 150 151 String tagName = Strings.toLowerCaseAscii( xpp.getName() ); 152 153 GrammarTransition transition = getTransition( container.getState(), new Tag( tagName, tagType ) ); 154 155 if ( transition != null ) 156 { 157 container.setState( transition.getNextState() ); 158 159 if ( transition.hasAction() ) 160 { 161 GrammarAction action = transition.getAction(); 162 action.action( container ); 163 } 164 } 165 else 166 { 167 throw new XmlPullParserException( I18n.err( I18n.ERR_03036_MISSING_TAG, new Tag( tagName, tagType ) ), xpp, null ); 168 } 169 } 170}