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