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.File;
24 import java.io.FileReader;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.InputStreamReader;
28 import java.text.ParseException;
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33
34 import org.apache.commons.lang.exception.ExceptionUtils;
35 import org.apache.directory.api.i18n.I18n;
36 import org.apache.directory.api.ldap.model.schema.AttributeType;
37 import org.apache.directory.api.ldap.model.schema.MutableAttributeType;
38 import org.apache.directory.api.ldap.model.schema.ObjectClass;
39 import org.apache.directory.api.ldap.model.schema.SchemaObject;
40 import org.apache.directory.api.ldap.model.schema.syntaxCheckers.OpenLdapObjectIdentifierMacro;
41
42 import antlr.RecognitionException;
43 import antlr.TokenStreamException;
44
45
46
47
48
49
50
51 public class OpenLdapSchemaParser extends AbstractSchemaParser<SchemaObject>
52 {
53
54
55 private List<Object> schemaDescriptions;
56
57
58 private List<MutableAttributeType> attributeTypes;
59
60
61 private List<ObjectClass> objectClasses;
62
63
64 private Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros;
65
66
67 private boolean isResolveObjectIdentifierMacros;
68
69
70
71
72
73
74
75 public OpenLdapSchemaParser() throws IOException
76 {
77 super( null, null, null, null );
78 isResolveObjectIdentifierMacros = true;
79 super.setQuirksMode( true );
80 }
81
82
83 @Override
84 protected SchemaObject doParse() throws RecognitionException, TokenStreamException
85 {
86 throw new UnsupportedOperationException( "OpenLdapSchemaParser is not a normal schema parser" );
87 }
88
89
90
91
92
93 public void clear()
94 {
95 }
96
97
98
99
100
101
102
103 public List<MutableAttributeType> getAttributeTypes()
104 {
105 return attributeTypes;
106 }
107
108
109
110
111
112
113
114 public List<ObjectClass> getObjectClassTypes()
115 {
116 return objectClasses;
117 }
118
119
120
121
122
123
124
125 public Map<String, OpenLdapObjectIdentifierMacro> getObjectIdentifierMacros()
126 {
127 return objectIdentifierMacros;
128 }
129
130
131
132
133
134
135
136
137 private void afterParse() throws ParseException
138 {
139 objectClasses = new ArrayList<ObjectClass>();
140 attributeTypes = new ArrayList<MutableAttributeType>();
141 objectIdentifierMacros = new HashMap<String, OpenLdapObjectIdentifierMacro>();
142
143
144 for ( Object obj : schemaDescriptions )
145 {
146 if ( obj instanceof OpenLdapObjectIdentifierMacro )
147 {
148 OpenLdapObjectIdentifierMacro oid = ( OpenLdapObjectIdentifierMacro ) obj;
149 objectIdentifierMacros.put( oid.getName(), oid );
150 }
151 else if ( obj instanceof AttributeType )
152 {
153 MutableAttributeType attributeType = ( MutableAttributeType ) obj;
154
155 attributeTypes.add( attributeType );
156 }
157 else if ( obj instanceof ObjectClass )
158 {
159 ObjectClass objectClass = ( ObjectClass ) obj;
160
161 objectClasses.add( objectClass );
162 }
163 }
164
165 if ( isResolveObjectIdentifierMacros() )
166 {
167
168 for ( OpenLdapObjectIdentifierMacro oid : objectIdentifierMacros.values() )
169 {
170 resolveObjectIdentifierMacro( oid );
171 }
172
173
174 for ( ObjectClass objectClass : objectClasses )
175 {
176 objectClass.setOid( getResolveOid( objectClass.getOid() ) );
177 }
178
179
180 for ( MutableAttributeType attributeType : attributeTypes )
181 {
182 attributeType.setOid( getResolveOid( attributeType.getOid() ) );
183 attributeType.setSyntaxOid( getResolveOid( attributeType.getSyntaxOid() ) );
184 }
185
186 }
187 }
188
189
190 private String getResolveOid( String oid )
191 {
192 if ( oid != null && oid.indexOf( ':' ) != -1 )
193 {
194
195 String[] nameAndSuffix = oid.split( ":" );
196 if ( objectIdentifierMacros.containsKey( nameAndSuffix[0] ) )
197 {
198 OpenLdapObjectIdentifierMacro macro = objectIdentifierMacros.get( nameAndSuffix[0] );
199 return macro.getResolvedOid() + "." + nameAndSuffix[1];
200 }
201 }
202 return oid;
203 }
204
205
206 private void resolveObjectIdentifierMacro( OpenLdapObjectIdentifierMacro macro ) throws ParseException
207 {
208 String rawOidOrNameSuffix = macro.getRawOidOrNameSuffix();
209
210 if ( macro.isResolved() )
211 {
212
213 return;
214 }
215 else if ( rawOidOrNameSuffix.indexOf( ':' ) != -1 )
216 {
217
218 String[] nameAndSuffix = rawOidOrNameSuffix.split( ":" );
219 if ( objectIdentifierMacros.containsKey( nameAndSuffix[0] ) )
220 {
221 OpenLdapObjectIdentifierMacro parentMacro = objectIdentifierMacros.get( nameAndSuffix[0] );
222 resolveObjectIdentifierMacro( parentMacro );
223 macro.setResolvedOid( parentMacro.getResolvedOid() + "." + nameAndSuffix[1] );
224 }
225 else
226 {
227 throw new ParseException( I18n.err( I18n.ERR_04257, nameAndSuffix[0] ), 0 );
228 }
229
230 }
231 else
232 {
233
234 if ( objectIdentifierMacros.containsKey( rawOidOrNameSuffix ) )
235 {
236 OpenLdapObjectIdentifierMacro parentMacro = objectIdentifierMacros.get( rawOidOrNameSuffix );
237 resolveObjectIdentifierMacro( parentMacro );
238 macro.setResolvedOid( parentMacro.getResolvedOid() );
239 }
240 else
241 {
242 macro.setResolvedOid( rawOidOrNameSuffix );
243 }
244 }
245 }
246
247
248
249
250
251
252
253
254
255 public SchemaObject parse( String schemaObject ) throws ParseException
256 {
257 if ( schemaObject == null || schemaObject.trim().equals( "" ) )
258 {
259 throw new ParseException( I18n.err( I18n.ERR_04258 ), 0 );
260 }
261
262 reset( schemaObject );
263 invokeParser( schemaObject );
264
265 if ( !schemaDescriptions.isEmpty() )
266 {
267 for ( Object obj : schemaDescriptions )
268 {
269 if ( obj instanceof SchemaObject )
270 {
271 return ( SchemaObject ) obj;
272 }
273 }
274 }
275 return null;
276 }
277
278
279 private void invokeParser( String subject ) throws ParseException
280 {
281 try
282 {
283 monitor.startedParse( "starting parse on:\n" + subject );
284 schemaDescriptions = parser.openLdapSchema();
285 afterParse();
286 monitor.finishedParse( "Done parsing!" );
287 }
288 catch ( RecognitionException e )
289 {
290 String msg = "Parser failure on:\n\t" + subject;
291 msg += "\nAntlr exception trace:\n" + ExceptionUtils.getFullStackTrace( e );
292 throw new ParseException( msg, e.getColumn() );
293 }
294 catch ( TokenStreamException e2 )
295 {
296 String msg = "Parser failure on:\n\t" + subject;
297 msg += "\nAntlr exception trace:\n" + ExceptionUtils.getFullStackTrace( e2 );
298 throw new ParseException( msg, 0 );
299 }
300 }
301
302
303
304
305
306
307
308
309
310 public void parse( InputStream schemaIn ) throws IOException, ParseException
311 {
312 InputStreamReader in = new InputStreamReader( schemaIn );
313 lexer.prepareNextInput( in );
314 parser.resetState();
315
316 invokeParser( "schema input stream ==> " + schemaIn.toString() );
317 }
318
319
320
321
322
323
324
325
326
327 public void parse( File schemaFile ) throws IOException, ParseException
328 {
329 FileReader in = new FileReader( schemaFile );
330 lexer.prepareNextInput( in );
331 parser.resetState();
332
333 invokeParser( "schema file ==> " + schemaFile.getAbsolutePath() );
334 }
335
336
337
338
339
340
341
342 public boolean isResolveObjectIdentifierMacros()
343 {
344 return isResolveObjectIdentifierMacros;
345 }
346
347
348
349
350
351
352
353 public void setResolveObjectIdentifierMacros( boolean resolveObjectIdentifierMacros )
354 {
355 this.isResolveObjectIdentifierMacros = resolveObjectIdentifierMacros;
356 }
357
358 }