1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.ldap.model.schema.parsers;
21
22
23 import java.io.StringReader;
24 import java.text.ParseException;
25 import java.util.List;
26
27 import org.apache.directory.api.i18n.I18n;
28 import org.apache.directory.api.ldap.model.constants.MetaSchemaConstants;
29 import org.apache.directory.api.ldap.model.schema.SchemaObject;
30 import org.apache.directory.api.util.Strings;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import antlr.RecognitionException;
35 import antlr.TokenStreamException;
36 import antlr.TokenStreamRecognitionException;
37
38
39
40
41
42
43
44 public abstract class AbstractSchemaParser<T extends SchemaObject>
45 {
46
47 protected static final Logger LOG = LoggerFactory.getLogger( AbstractSchemaParser.class );
48
49
50 protected ParserMonitor monitor = new ParserMonitorAdapter();
51
52
53 protected ReusableAntlrSchemaParser parser;
54
55
56 protected ReusableAntlrSchemaLexer lexer;
57
58
59 private Class<T> schemaObjectType;
60
61
62 private I18n errorCodeOnNull;
63
64
65 private I18n errorCodeOnParseExceptionWithPosition;
66
67
68 private I18n errorCodeOnParseException;
69
70
71
72
73
74
75
76
77 protected AbstractSchemaParser( Class<T> schemaObjectType, I18n errorCodeOnNull, I18n errorCodeOnParseExceptionWithPosition,
78 I18n errorCodeOnParseException )
79 {
80 this.schemaObjectType = schemaObjectType;
81 this.errorCodeOnNull = errorCodeOnNull;
82 this.errorCodeOnParseExceptionWithPosition = errorCodeOnParseExceptionWithPosition;
83 this.errorCodeOnParseException = errorCodeOnParseException;
84 lexer = new ReusableAntlrSchemaLexer( new StringReader( "" ) );
85 parser = new ReusableAntlrSchemaParser( lexer );
86 }
87
88
89
90
91
92
93
94
95 protected void reset( String spec )
96 {
97 StringReader in = new StringReader( spec );
98 lexer.prepareNextInput( in );
99 parser.resetState();
100 }
101
102
103
104
105
106
107
108 public void setParserMonitor( ParserMonitor parserMonitor )
109 {
110 this.monitor = parserMonitor;
111 parser.setParserMonitor( parserMonitor );
112 }
113
114
115
116
117
118
119
120
121
122
123 public void setQuirksMode( boolean enabled )
124 {
125 parser.setQuirksMode( enabled );
126 }
127
128
129
130
131
132
133
134 public boolean isQuirksMode()
135 {
136 return parser.isQuirksMode();
137 }
138
139
140
141
142
143
144
145
146
147 public synchronized T parse( String schemaDescription ) throws ParseException
148 {
149 LOG.debug( "Parsing a {} : {}", schemaObjectType.getClass().getSimpleName(), schemaDescription );
150
151 if ( schemaDescription == null )
152 {
153 LOG.error( I18n.err( errorCodeOnNull ) );
154 throw new ParseException( "Null", 0 );
155 }
156
157 reset( schemaDescription );
158
159 try
160 {
161 T schemaObject = doParse();
162 schemaObject.setSpecification( schemaDescription );
163
164
165 updateSchemaName( schemaObject );
166
167 return schemaObject;
168 }
169 catch ( RecognitionException re )
170 {
171 ParseException parseException = wrapRecognitionException( schemaDescription, re );
172 throw parseException;
173 }
174 catch ( TokenStreamRecognitionException tsre )
175 {
176 if ( tsre.recog != null )
177 {
178 ParseException parseException = wrapRecognitionException( schemaDescription, tsre.recog );
179 throw parseException;
180 }
181 else
182 {
183 ParseException parseException = wrapTokenStreamException( schemaDescription, tsre );
184 throw parseException;
185 }
186 }
187 catch ( TokenStreamException tse )
188 {
189 ParseException parseException = wrapTokenStreamException( schemaDescription, tse );
190 throw parseException;
191 }
192 }
193
194
195 private ParseException wrapRecognitionException( String schemaDescription, RecognitionException re )
196 {
197 String msg = I18n.err( errorCodeOnParseExceptionWithPosition, schemaDescription, re.getMessage(),
198 re.getColumn() );
199 LOG.error( msg );
200 ParseException parseException = new ParseException( msg, re.getColumn() );
201 parseException.initCause( re );
202 return parseException;
203 }
204
205
206 private ParseException wrapTokenStreamException( String schemaDescription, TokenStreamException tse )
207 {
208 String msg = I18n.err( errorCodeOnParseException, schemaDescription, tse.getMessage() );
209 LOG.error( msg );
210 ParseException parseException = new ParseException( msg, 0 );
211 parseException.initCause( tse );
212 return parseException;
213 }
214
215
216
217
218
219
220
221
222
223 protected abstract T doParse() throws RecognitionException, TokenStreamException;
224
225
226
227
228
229
230
231
232 private void updateSchemaName( SchemaObject schemaObject )
233 {
234
235 List<String> schemaExtension = schemaObject.getExtension( MetaSchemaConstants.X_SCHEMA_AT );
236
237 if ( schemaExtension != null )
238 {
239 String schemaName = schemaExtension.get( 0 );
240
241 if ( Strings.isEmpty( schemaName ) )
242 {
243 schemaObject.setSchemaName( MetaSchemaConstants.SCHEMA_OTHER );
244 }
245 else
246 {
247 schemaObject.setSchemaName( schemaName );
248 }
249 }
250 else
251 {
252 schemaObject.setSchemaName( MetaSchemaConstants.SCHEMA_OTHER );
253 }
254 }
255 }