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.ldap.aci;
022
023
024 import java.io.StringReader;
025 import java.text.ParseException;
026 import java.util.Map;
027
028 import org.apache.directory.shared.i18n.I18n;
029 import org.apache.directory.shared.ldap.name.NameComponentNormalizer;
030 import org.apache.directory.shared.ldap.schema.normalizers.OidNormalizer;
031
032 import antlr.RecognitionException;
033 import antlr.TokenStreamException;
034
035
036 /**
037 * A reusable wrapper around the antlr generated parser for an ACIItem as
038 * defined by X.501. This class enables the reuse of the antlr parser/lexer pair
039 * without having to recreate them every time.
040 *
041 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
042 * @version $Rev: 912399 $
043 */
044 public class ACIItemParser
045 {
046 /** the antlr generated parser being wrapped */
047 private ReusableAntlrACIItemParser parser;
048
049 /** the antlr generated lexer being wrapped */
050 private ReusableAntlrACIItemLexer lexer;
051
052 private final boolean isNormalizing;
053
054
055 /**
056 * Creates a ACIItem parser.
057 */
058 public ACIItemParser( Map<String, OidNormalizer> oidsMap )
059 {
060 this.lexer = new ReusableAntlrACIItemLexer( new StringReader( "" ) );
061 this.parser = new ReusableAntlrACIItemParser( lexer );
062
063 this.parser.init( oidsMap ); // this method MUST be called while we cannot do
064 // constructor overloading for antlr generated parser
065 this.isNormalizing = false;
066 }
067
068
069 /**
070 * Creates a normalizing ACIItem parser.
071 */
072 public ACIItemParser(NameComponentNormalizer normalizer, Map<String, OidNormalizer> oidsMap )
073 {
074 this.lexer = new ReusableAntlrACIItemLexer( new StringReader( "" ) );
075 this.parser = new ReusableAntlrACIItemParser( lexer );
076
077 this.parser.setNormalizer( normalizer );
078 this.parser.init( oidsMap ); // this method MUST be called while we cannot do
079 // constructor overloading for antlr generated parser
080 this.isNormalizing = true;
081 }
082
083
084 /**
085 * Initializes the plumbing by creating a pipe and coupling the parser/lexer
086 * pair with it. param spec the specification to be parsed
087 */
088 private synchronized void reset( String spec )
089 {
090 StringReader in = new StringReader( spec );
091 this.lexer.prepareNextInput( in );
092 this.parser.resetState();
093 }
094
095
096 /**
097 * Parses an ACIItem without exhausting the parser.
098 *
099 * @param spec
100 * the specification to be parsed
101 * @return the specification bean
102 * @throws ParseException
103 * if there are any recognition errors (bad syntax)
104 */
105 public synchronized ACIItem parse( String spec ) throws ParseException
106 {
107 ACIItem aCIItem = null;
108
109 if ( spec == null || spec.trim().equals( "" ) )
110 {
111 return null;
112 }
113
114 reset( spec ); // reset and initialize the parser / lexer pair
115
116 try
117 {
118 aCIItem = this.parser.wrapperEntryPoint();
119 }
120 catch ( TokenStreamException e )
121 {
122 throw new ParseException( I18n.err( I18n.ERR_00004, spec, e.getLocalizedMessage() ), 0 );
123 }
124 catch ( RecognitionException e )
125 {
126 throw new ParseException( I18n.err( I18n.ERR_00004, spec, e.getLocalizedMessage() ), e.getColumn() );
127 }
128
129 return aCIItem;
130 }
131
132
133 /**
134 * Tests to see if this parser is normalizing.
135 *
136 * @return true if it normalizes false otherwise
137 */
138 public boolean isNormizing()
139 {
140 return this.isNormalizing;
141 }
142 }