1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package org.jomc.tools;
32
33 import java.io.File;
34 import java.io.FileOutputStream;
35 import java.io.IOException;
36 import java.io.OutputStream;
37 import java.text.MessageFormat;
38 import java.util.HashMap;
39 import java.util.Locale;
40 import java.util.Map;
41 import java.util.Properties;
42 import java.util.ResourceBundle;
43 import java.util.logging.Level;
44 import org.apache.velocity.VelocityContext;
45 import org.jomc.model.Implementation;
46 import org.jomc.model.Message;
47 import org.jomc.model.Messages;
48 import org.jomc.model.Module;
49 import org.jomc.model.Specification;
50 import org.jomc.model.Text;
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 public class ResourceFileProcessor extends JomcTool
68 {
69
70
71 private Locale resourceBundleDefaultLocale;
72
73
74 public ResourceFileProcessor()
75 {
76 super();
77 }
78
79
80
81
82
83
84
85
86
87
88 public ResourceFileProcessor( final ResourceFileProcessor tool ) throws IOException
89 {
90 super( tool );
91 this.resourceBundleDefaultLocale = tool.resourceBundleDefaultLocale;
92 }
93
94
95
96
97
98
99
100
101 public final Locale getResourceBundleDefaultLocale()
102 {
103 if ( this.resourceBundleDefaultLocale == null )
104 {
105 this.resourceBundleDefaultLocale = Locale.ENGLISH;
106
107 if ( this.isLoggable( Level.CONFIG ) )
108 {
109 this.log( Level.CONFIG,
110 getMessage( "defaultResourceBundleDefaultLocale", this.resourceBundleDefaultLocale ), null );
111
112 }
113 }
114
115 return this.resourceBundleDefaultLocale;
116 }
117
118
119
120
121
122
123
124
125 public final void setResourceBundleDefaultLocale( final Locale value )
126 {
127 this.resourceBundleDefaultLocale = value;
128 }
129
130
131
132
133
134
135
136
137
138
139
140 public void writeResourceBundleResourceFiles( final File resourcesDirectory ) throws IOException
141 {
142 if ( resourcesDirectory == null )
143 {
144 throw new NullPointerException( "resourcesDirectory" );
145 }
146
147 for ( int i = 0, s0 = this.getModules().getModule().size(); i < s0; i++ )
148 {
149 this.writeResourceBundleResourceFiles( this.getModules().getModule().get( i ), resourcesDirectory );
150 }
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165 public void writeResourceBundleResourceFiles( final Module module, final File resourcesDirectory )
166 throws IOException
167 {
168 if ( module == null )
169 {
170 throw new NullPointerException( "module" );
171 }
172 if ( resourcesDirectory == null )
173 {
174 throw new NullPointerException( "resourcesDirectory" );
175 }
176
177 assert this.getModules().getModule( module.getName() ) != null : "Module '" + module.getName() + "' not found.";
178
179 if ( module.getSpecifications() != null )
180 {
181 for ( int i = 0, s0 = module.getSpecifications().getSpecification().size(); i < s0; i++ )
182 {
183 this.writeResourceBundleResourceFiles( module.getSpecifications().getSpecification().get( i ),
184 resourcesDirectory );
185
186 }
187 }
188
189 if ( module.getImplementations() != null )
190 {
191 for ( int i = 0, s0 = module.getImplementations().getImplementation().size(); i < s0; i++ )
192 {
193 this.writeResourceBundleResourceFiles( module.getImplementations().getImplementation().get( i ),
194 resourcesDirectory );
195
196 }
197 }
198 }
199
200
201
202
203
204
205
206
207
208
209
210
211 public void writeResourceBundleResourceFiles( final Specification specification, final File resourcesDirectory )
212 throws IOException
213 {
214 if ( specification == null )
215 {
216 throw new NullPointerException( "implementation" );
217 }
218 if ( resourcesDirectory == null )
219 {
220 throw new NullPointerException( "resourcesDirectory" );
221 }
222
223 assert this.getModules().getSpecification( specification.getIdentifier() ) != null :
224 "Specification '" + specification.getIdentifier() + "' not found.";
225
226 if ( specification.isClassDeclaration() )
227 {
228 if ( !resourcesDirectory.isDirectory() )
229 {
230 throw new IOException( getMessage( "directoryNotFound", resourcesDirectory.getAbsolutePath() ) );
231 }
232
233 this.assertValidTemplates( specification );
234
235 final String bundlePath =
236 this.getJavaTypeName( specification, true ).replace( '.', File.separatorChar );
237
238 this.writeResourceBundleResourceFiles(
239 this.getResourceBundleResources( specification ), resourcesDirectory, bundlePath );
240
241 }
242 }
243
244
245
246
247
248
249
250
251
252
253
254
255 public void writeResourceBundleResourceFiles( final Implementation implementation, final File resourcesDirectory )
256 throws IOException
257 {
258 if ( implementation == null )
259 {
260 throw new NullPointerException( "implementation" );
261 }
262 if ( resourcesDirectory == null )
263 {
264 throw new NullPointerException( "resourcesDirectory" );
265 }
266
267 assert this.getModules().getImplementation( implementation.getIdentifier() ) != null :
268 "Implementation '" + implementation.getIdentifier() + "' not found.";
269
270 if ( implementation.isClassDeclaration() )
271 {
272 if ( !resourcesDirectory.isDirectory() )
273 {
274 throw new IOException( getMessage( "directoryNotFound", resourcesDirectory.getAbsolutePath() ) );
275 }
276
277 this.assertValidTemplates( implementation );
278
279 final String bundlePath =
280 this.getJavaTypeName( implementation, true ).replace( '.', File.separatorChar );
281
282 this.writeResourceBundleResourceFiles(
283 this.getResourceBundleResources( implementation ), resourcesDirectory, bundlePath );
284
285 }
286 }
287
288
289
290
291
292
293
294
295
296
297
298 public Map<Locale, Properties> getResourceBundleResources( final Specification specification )
299 throws IOException
300 {
301 if ( specification == null )
302 {
303 throw new NullPointerException( "specification" );
304 }
305
306 assert this.getModules().getSpecification( specification.getIdentifier() ) != null :
307 "Specification '" + specification.getIdentifier() + "' not found.";
308
309 return new HashMap<Locale, Properties>();
310 }
311
312
313
314
315
316
317
318
319
320
321
322 public Map<Locale, Properties> getResourceBundleResources( final Implementation implementation )
323 throws IOException
324 {
325 if ( implementation == null )
326 {
327 throw new NullPointerException( "implementation" );
328 }
329
330 assert this.getModules().getImplementation( implementation.getIdentifier() ) != null :
331 "Implementation '" + implementation.getIdentifier() + "' not found.";
332
333 final Map<Locale, java.util.Properties> properties = new HashMap<Locale, java.util.Properties>( 10 );
334 final Messages messages = this.getModules().getMessages( implementation.getIdentifier() );
335
336 if ( messages != null )
337 {
338 for ( int i = 0, s0 = messages.getMessage().size(); i < s0; i++ )
339 {
340 final Message message = messages.getMessage().get( i );
341
342 if ( message.getTemplate() != null )
343 {
344 for ( int j = 0, s1 = message.getTemplate().getText().size(); j < s1; j++ )
345 {
346 final Text text = message.getTemplate().getText().get( j );
347 final Locale locale = new Locale( text.getLanguage().toLowerCase() );
348 Properties bundleProperties = properties.get( locale );
349
350 if ( bundleProperties == null )
351 {
352 bundleProperties = new Properties();
353 properties.put( locale, bundleProperties );
354 }
355
356 bundleProperties.setProperty( message.getName(), text.getValue() );
357 }
358 }
359 }
360 }
361
362 return properties;
363 }
364
365 private void writeResourceBundleResourceFiles( final Map<Locale, Properties> resources,
366 final File resourcesDirectory, final String bundlePath )
367 throws IOException
368 {
369 if ( resources == null )
370 {
371 throw new NullPointerException( "resources" );
372 }
373 if ( resourcesDirectory == null )
374 {
375 throw new NullPointerException( "resourcesDirectory" );
376 }
377 if ( bundlePath == null )
378 {
379 throw new NullPointerException( "bundlePath" );
380 }
381
382 Properties defProperties = null;
383 Properties fallbackProperties = null;
384
385 final VelocityContext ctx = this.getVelocityContext();
386 final String toolName = ctx.get( "toolName" ).toString();
387 final String toolVersion = ctx.get( "toolVersion" ).toString();
388 final String toolUrl = ctx.get( "toolUrl" ).toString();
389
390 for ( Map.Entry<Locale, Properties> e : resources.entrySet() )
391 {
392 final String language = e.getKey().getLanguage().toLowerCase();
393 final Properties p = e.getValue();
394 final File file = new File( resourcesDirectory, bundlePath + "_" + language + ".properties" );
395
396 if ( this.getResourceBundleDefaultLocale().getLanguage().equalsIgnoreCase( language ) )
397 {
398 defProperties = p;
399 }
400
401 fallbackProperties = p;
402
403 if ( !file.getParentFile().exists() && !file.getParentFile().mkdirs() )
404 {
405 throw new IOException( getMessage( "failedCreatingDirectory",
406 file.getParentFile().getAbsolutePath() ) );
407
408 }
409
410 if ( this.isLoggable( Level.INFO ) )
411 {
412 this.log( Level.INFO, getMessage( "writing", file.getCanonicalPath() ), null );
413 }
414
415 OutputStream out = null;
416 boolean suppressExceptionOnClose = true;
417 try
418 {
419 out = new FileOutputStream( file );
420 p.store( out, toolName + ' ' + toolVersion + " - See " + toolUrl );
421 suppressExceptionOnClose = false;
422 }
423 finally
424 {
425 try
426 {
427 if ( out != null )
428 {
429 out.close();
430 }
431 }
432 catch ( final IOException ex )
433 {
434 if ( suppressExceptionOnClose )
435 {
436 this.log( Level.SEVERE, getMessage( ex ), ex );
437 }
438 else
439 {
440 throw ex;
441 }
442 }
443 }
444 }
445
446 if ( defProperties == null )
447 {
448 defProperties = fallbackProperties;
449 }
450
451 if ( defProperties != null )
452 {
453 final File file = new File( resourcesDirectory, bundlePath + ".properties" );
454 if ( !file.getParentFile().exists() && !file.getParentFile().mkdirs() )
455 {
456 throw new IOException( getMessage( "failedCreatingDirectory",
457 file.getParentFile().getAbsolutePath() ) );
458
459 }
460
461 if ( this.isLoggable( Level.INFO ) )
462 {
463 this.log( Level.INFO, getMessage( "writing", file.getCanonicalPath() ), null );
464 }
465
466 OutputStream out = null;
467 boolean suppressExceptionOnClose = true;
468 try
469 {
470 out = new FileOutputStream( file );
471 defProperties.store( out, toolName + ' ' + toolVersion + " - See " + toolUrl );
472 suppressExceptionOnClose = false;
473 }
474 finally
475 {
476 try
477 {
478 if ( out != null )
479 {
480 out.close();
481 }
482 }
483 catch ( final IOException e )
484 {
485 if ( suppressExceptionOnClose )
486 {
487 this.log( Level.SEVERE, getMessage( e ), e );
488 }
489 else
490 {
491 throw e;
492 }
493 }
494 }
495 }
496 }
497
498 private void assertValidTemplates( final Specification specification )
499 {
500 if ( specification == null )
501 {
502 throw new NullPointerException( "specification" );
503 }
504 }
505
506 private void assertValidTemplates( final Implementation implementation )
507 {
508 if ( implementation == null )
509 {
510 throw new NullPointerException( "implementation" );
511 }
512
513 final Messages messages = this.getModules().getMessages( implementation.getIdentifier() );
514
515 if ( messages != null )
516 {
517 for ( int i = messages.getMessage().size() - 1; i >= 0; i-- )
518 {
519 final Message m = messages.getMessage().get( i );
520
521 if ( m.getTemplate() != null )
522 {
523 for ( int j = m.getTemplate().getText().size() - 1; j >= 0; j-- )
524 {
525 new MessageFormat( m.getTemplate().getText().get( j ).getValue() );
526 }
527 }
528 }
529 }
530 }
531
532 private static String getMessage( final String key, final Object... arguments )
533 {
534 if ( key == null )
535 {
536 throw new NullPointerException( "key" );
537 }
538
539 return MessageFormat.format( ResourceBundle.getBundle(
540 ResourceFileProcessor.class.getName().replace( '.', '/' ) ).getString( key ), arguments );
541
542 }
543
544 private static String getMessage( final Throwable t )
545 {
546 return t != null ? t.getMessage() != null ? t.getMessage() : getMessage( t.getCause() ) : null;
547 }
548
549 }