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