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