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: 928938 $ 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 }