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 /** The grammar's states */ 051 protected Enum<Dsmlv2StatesEnum>[] statesEnum; 052 053 054 /** 055 * Returns the grammar's name 056 * 057 * @return The grammar name 058 */ 059 public String getName() 060 { 061 return name; 062 } 063 064 065 /** 066 * Sets the grammar's name 067 * 068 * @param name the name to set 069 */ 070 public void setName( String name ) 071 { 072 this.name = name; 073 } 074 075 076 /** 077 * Gets the transition associated with the state and tag 078 * 079 * @param state The current state 080 * @param tag The current tag 081 * @return A valid transition if any, or null. 082 */ 083 public GrammarTransition getTransition( Enum<Dsmlv2StatesEnum> state, Tag tag ) 084 { 085 return transitions[state.ordinal()].get( tag ); 086 } 087 088 089 /** 090 * Gets the states of the current grammar 091 * 092 * @return Returns the statesEnum. 093 */ 094 public Enum<Dsmlv2StatesEnum>[] getStatesEnum() 095 { 096 return Dsmlv2StatesEnum.values(); 097 } 098 099 100 /** 101 * {@inheritDoc} 102 */ 103 public void executeAction( Dsmlv2Container container ) throws XmlPullParserException, IOException 104 { 105 XmlPullParser xpp = container.getParser(); 106 107 int eventType = xpp.getEventType(); 108 109 do 110 { 111 switch ( eventType ) 112 { 113 case XmlPullParser.START_DOCUMENT: 114 container.setState( Dsmlv2StatesEnum.INIT_GRAMMAR_STATE ); 115 break; 116 117 case XmlPullParser.END_DOCUMENT: 118 container.setState( Dsmlv2StatesEnum.GRAMMAR_END ); 119 break; 120 121 case XmlPullParser.START_TAG: 122 processTag( container, Tag.START ); 123 break; 124 125 case XmlPullParser.END_TAG: 126 processTag( container, Tag.END ); 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.toLowerCase( 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}