1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.ldap.server.tools.schema;
18
19
20 import java.io.*;
21 import java.util.List;
22 import java.util.ArrayList;
23
24 import org.apache.velocity.app.Velocity;
25 import org.apache.velocity.VelocityContext;
26
27 import org.apache.ldap.server.schema.bootstrap.BootstrapSchema;
28 import org.apache.ldap.server.schema.bootstrap.ProducerTypeEnum;
29
30
31 /***
32 * Generates Eve schema classses from OpenLDAP schema files.
33 *
34 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
35 * @version $Rev: 264732 $
36 */
37 public class DirectorySchemaTool
38 {
39 private static String basedir = System.getProperty( "basedir", "." );
40
41 /*** property for dir where OpenLDAP schema files and deps file are stored */
42 public static final String SCHEMA_SRC_DIR_PROP = "maven.ldap.server.schema.src.dir";
43
44 /*** property for dir where the generated class files are created */
45 public static final String SCHEMA_TARGET_DIR_PROP = "maven.ldap.server.schema.target.dir";
46
47 /*** default dir where OpenLDAP schema files and deps file are kept */
48 public static final String SCHEMA_SRC_DIR_DEFAULT =
49 basedir + File.separator + "src" + File.separator + "main"
50 + File.separator + "schema";
51
52 /*** default dir where java src files are kept */
53 public static final String JAVA_SRC_DIR_DEFAULT =
54 basedir + File.separator + "src" + File.separator + "main"
55 + File.separator + "java";
56
57 /*** property for the name of the schema dependency file */
58 public static final String SCHEMA_DEP_FILE_DEFAULT = "schema.deps";
59
60 /*** default dir where the generated class files are created */
61 public static final String SCHEMA_TARGET_DIR_DEFAULT =
62 basedir + File.separator + "target" + File.separator + "schema";
63
64
65 /*** the source directory where the schema OpenLDAP source files are kept */
66 private String schemaSrcDir = SCHEMA_SRC_DIR_DEFAULT;
67
68 /*** the directory where we generate schema class files */
69 private String schemaTargetDir = SCHEMA_TARGET_DIR_DEFAULT;
70
71 private String javaSrcDir = JAVA_SRC_DIR_DEFAULT;
72
73 private BootstrapSchema schema;
74
75 private OpenLdapSchemaParser parser;
76
77
78
79 public DirectorySchemaTool() throws Exception
80 {
81 parser = new OpenLdapSchemaParser();
82
83 Velocity.init();
84 }
85
86
87 public String getSchemaSrcDir()
88 {
89 return schemaSrcDir;
90 }
91
92
93 public void setSchemaSrcDir( String schemaSrcDir )
94 {
95 this.schemaSrcDir = schemaSrcDir;
96 }
97
98
99 public String getSchemaTargetDir()
100 {
101 return schemaTargetDir;
102 }
103
104
105 public void setSchemaTargetDir( String schemaTargetDir )
106 {
107 this.schemaTargetDir = schemaTargetDir;
108 }
109
110
111 public String getJavaSrcDir()
112 {
113 return javaSrcDir;
114 }
115
116
117 public void setJavaSrcDir( String javaSrcDir )
118 {
119 this.javaSrcDir = javaSrcDir;
120 }
121
122
123 public BootstrapSchema getSchema()
124 {
125 return schema;
126 }
127
128
129 public void setSchema( BootstrapSchema schema )
130 {
131 this.schema = schema;
132 }
133
134
135 public void generate() throws Exception
136 {
137 if ( schema == null )
138 {
139 throw new NullPointerException( "the schema property must be set" );
140 }
141
142 String filePath = schemaSrcDir + File.separator + schema.getSchemaName() + ".schema";
143
144 InputStream in = new FileInputStream( filePath );
145
146 parser.parse( in );
147
148 generateSchema();
149
150 generateAttributeTypes();
151
152 generateObjectClasses();
153
154 generateRest();
155 }
156
157
158 protected void generateSchema() throws Exception
159 {
160 StringBuffer schemaCapped = new StringBuffer();
161
162 schemaCapped.append( Character.toUpperCase( schema.getSchemaName().charAt( 0 ) ) );
163
164 schemaCapped.append( schema.getSchemaName().substring( 1, schema.getSchemaName().length() ) );
165
166 VelocityContext context = new VelocityContext();
167
168 context.put( "package", schema.getPackageName() );
169
170 context.put( "classname", schemaCapped.toString() + "Schema" );
171
172 context.put( "schema", schema.getSchemaName() );
173
174 context.put( "owner", schema.getOwner() ) ;
175
176 context.put( "deps", schema.getDependencies() ) ;
177
178 Reader fileIn = getResourceReader( "Schema.template" );
179
180 Writer writer = getResourceWriter( schema.getUnqualifiedClassName() );
181
182 Velocity.evaluate( context, writer, "LOG", fileIn );
183
184 writer.flush();
185
186 writer.close();
187 }
188
189
190 protected void generateRest() throws Exception
191 {
192 List types = new ArrayList();
193
194 types.addAll( ProducerTypeEnum.list() );
195
196 types.remove( ProducerTypeEnum.ATTRIBUTE_TYPE_PRODUCER );
197
198 types.remove( ProducerTypeEnum.OBJECT_CLASS_PRODUCER );
199
200 ProducerTypeEnum type = null;
201
202 for ( int ii = 0; ii < types.size(); ii++ )
203 {
204 type = ( ProducerTypeEnum ) types.get( ii );
205
206 if ( exists( type ) )
207 {
208 continue;
209 }
210
211
212 VelocityContext context = new VelocityContext();
213
214 context.put( "package", schema.getPackageName() );
215
216 context.put( "classname", schema.getUnqualifiedClassName( type ) );
217
218 context.put( "schema", schema.getSchemaName() );
219
220 context.put( "owner", schema.getOwner() ) ;
221
222 context.put( "type", type.getName().substring( 0, type.getName().length() - 8 ) ) ;
223
224 String typeName = null;
225
226 switch( type.getValue() )
227 {
228 case( ProducerTypeEnum.COMPARATOR_PRODUCER_VAL ):
229
230 typeName = "ProducerTypeEnum.COMPARATOR_PRODUCER";
231
232 break;
233
234 case( ProducerTypeEnum.DIT_CONTENT_RULE_PRODUCER_VAL ):
235
236 typeName = "ProducerTypeEnum.DIT_CONTENT_RULE_PRODUCER";
237
238 break;
239
240 case( ProducerTypeEnum.DIT_STRUCTURE_RULE_PRODUCER_VAL ):
241
242 typeName = "ProducerTypeEnum.DIT_STRUCTURE_RULE_PRODUCER";
243
244 break;
245
246 case( ProducerTypeEnum.MATCHING_RULE_PRODUCER_VAL ):
247
248 typeName = "ProducerTypeEnum.MATCHING_RULE_PRODUCER";
249
250 break;
251
252 case( ProducerTypeEnum.MATCHING_RULE_USE_PRODUCER_VAL ):
253
254 typeName = "ProducerTypeEnum.MATCHING_RULE_USE_PRODUCER";
255
256 break;
257
258 case( ProducerTypeEnum.NAME_FORM_PRODUCER_VAL ):
259
260 typeName = "ProducerTypeEnum.NAME_FORM_PRODUCER";
261
262 break;
263
264 case( ProducerTypeEnum.NORMALIZER_PRODUCER_VAL ):
265
266 typeName = "ProducerTypeEnum.NORMALIZER_PRODUCER";
267
268 break;
269
270 case( ProducerTypeEnum.SYNTAX_CHECKER_PRODUCER_VAL ):
271
272 typeName = "ProducerTypeEnum.SYNTAX_CHECKER_PRODUCER";
273
274 break;
275
276 case( ProducerTypeEnum.SYNTAX_PRODUCER_VAL ):
277
278 typeName = "ProducerTypeEnum.SYNTAX_PRODUCER";
279
280 break;
281
282 case( ProducerTypeEnum.STATE_FACTORY_PRODUCER_VAL ):
283
284 typeName = "ProducerTypeEnum.STATE_FACTORY_PRODUCER";
285
286 break;
287
288 case( ProducerTypeEnum.OBJECT_FACTORY_PRODUCER_VAL ):
289
290 typeName = "ProducerTypeEnum.OBJECT_FACTORY_PRODUCER";
291
292 break;
293
294 default:
295
296 throw new IllegalStateException( "Unexpected producer: " + type.getName() );
297
298 }
299
300 context.put( "typeName", typeName ) ;
301
302 runVelocity( context, "typeless.template", type );
303 }
304 }
305
306
307 protected void generateAttributeTypes() throws Exception
308 {
309 final ProducerTypeEnum type = ProducerTypeEnum.ATTRIBUTE_TYPE_PRODUCER;
310
311
312 if ( exists( type ) )
313 {
314 return;
315 }
316
317 int size = parser.getAttributeTypes().size();
318
319 AttributeTypeLiteral[] attributeTypes = new AttributeTypeLiteral[size];
320
321 attributeTypes = ( AttributeTypeLiteral[] ) parser.getAttributeTypes().values().toArray( attributeTypes );
322
323 VelocityContext context = new VelocityContext();
324
325 context.put( "package", schema.getPackageName() );
326
327 context.put( "classname", schema.getUnqualifiedClassName( type ) );
328
329 context.put( "schema", schema.getSchemaName() );
330
331 context.put( "owner", schema.getOwner() ) ;
332
333 context.put( "schemaDepCount", new Integer( schema.getDependencies().length ) );
334
335 context.put( "schemaDeps", new String[] { "dep1", "dep2" } ) ;
336
337 context.put( "attrTypes", attributeTypes );
338
339 runVelocity( context, "AttributeTypes.template", type );
340 }
341
342
343 protected void generateObjectClasses() throws Exception
344 {
345 final ProducerTypeEnum type = ProducerTypeEnum.OBJECT_CLASS_PRODUCER;
346
347
348 if ( exists( type ) )
349 {
350 return;
351 }
352
353 int size = parser.getObjectClassTypes().size();
354
355 ObjectClassLiteral[] objectClasses = new ObjectClassLiteral[size];
356
357 objectClasses = ( ObjectClassLiteral[] ) parser.getObjectClassTypes().values().toArray( objectClasses );
358
359 VelocityContext context = new VelocityContext();
360
361 context.put( "package", schema.getPackageName() );
362
363 context.put( "classname", schema.getUnqualifiedClassName( type ) );
364
365 context.put( "schema", schema.getSchemaName() );
366
367 context.put( "owner", schema.getOwner() ) ;
368
369 context.put( "schemaDepCount", new Integer( schema.getDependencies().length ) );
370
371 context.put( "schemaDeps", new String[] { "dep1", "dep2" } ) ;
372
373 context.put( "objectClasses", objectClasses );
374
375 runVelocity( context, "ObjectClasses.template", type );
376 }
377
378
379
380 protected void runVelocity( VelocityContext context, String template, ProducerTypeEnum type )
381 throws Exception
382 {
383 Reader fileIn = getResourceReader( template );
384
385 Writer writer = getResourceWriter( schema.getUnqualifiedClassName( type ) );
386
387 Velocity.evaluate( context, writer, "LOG", fileIn );
388
389 writer.flush();
390
391 writer.close();
392 }
393
394
395 protected Reader getResourceReader( String res ) throws IOException
396 {
397 return new InputStreamReader( getClass().getResourceAsStream( res ) );
398 }
399
400
401 protected boolean mkdirs( String base, String path )
402 {
403 String[] comps = path.split( "/" );
404
405 File file = new File( base );
406
407 if ( ! file.exists() )
408 {
409 file.mkdirs();
410 }
411
412 for ( int ii = 0; ii < comps.length; ii++ )
413 {
414 file = new File( file, comps[ii] );
415
416 if ( ! file.exists() )
417 {
418 file.mkdirs();
419 }
420 }
421
422 return file.exists();
423 }
424
425
426 protected FileWriter getResourceWriter( String classname ) throws IOException
427 {
428 String pkg = schema.getPackageName();
429
430 mkdirs( schemaTargetDir, pkg.replace( '.', File.separatorChar ) );
431
432 File base = new File( schemaTargetDir );
433
434 String relativePath = pkg.replace( '.', File.separatorChar );
435
436 File dir = new File( base, relativePath );
437
438 return new FileWriter( new File( dir, classname + ".java" ) );
439 }
440
441
442
443 protected boolean exists( ProducerTypeEnum type )
444 {
445 String defaultClass = schema.getFullDefaultBaseClassName( type );
446
447
448
449 File defaultFile = new File( getJavaSrcDir() + File.separator + getFilePath( defaultClass ) );
450
451 return defaultFile.exists();
452 }
453
454
455 private String getFilePath( String fqcn )
456 {
457 String path = fqcn.replace( '.', File.separatorChar );
458
459 path += ".java";
460
461 return path;
462 }
463 }