EMMA Coverage Report (generated Wed Feb 03 01:24:19 UTC 2010)
[all classes][org.jomc.tools]

COVERAGE SUMMARY FOR SOURCE FILE [JavaBundles.java]

nameclass, %method, %block, %line, %
JavaBundles.java100% (1/1)88%  (14/16)85%  (622/732)87%  (124.2/143)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class JavaBundles100% (1/1)88%  (14/16)85%  (622/732)87%  (124.2/143)
JavaBundles (JavaBundles): void 0%   (0/1)0%   (0/8)0%   (0/3)
setDefaultLocale (Locale): void 0%   (0/1)0%   (0/4)0%   (0/2)
getMessage (String, Object []): String 100% (1/1)72%  (13/18)67%  (2/3)
writeBundleSources (Implementation, File): void 100% (1/1)76%  (78/102)82%  (13.9/17)
writeBundleResources (Implementation, File): void 100% (1/1)78%  (201/259)84%  (36.3/43)
getResourceBundleSources (Implementation): String 100% (1/1)86%  (37/43)83%  (10/12)
assertValidTemplates (Implementation): void 100% (1/1)90%  (45/50)89%  (8/9)
<static initializer> 100% (1/1)100% (4/4)100% (1/1)
JavaBundles (): void 100% (1/1)100% (3/3)100% (2/2)
getDefaultLocale (): Locale 100% (1/1)100% (26/26)100% (5/5)
getResourceBundleResources (Implementation): Map 100% (1/1)100% (80/80)100% (16/16)
getVelocityContext (): VelocityContext 100% (1/1)100% (15/15)100% (4/4)
writeBundleResources (File): void 100% (1/1)100% (25/25)100% (5/5)
writeBundleResources (Module, File): void 100% (1/1)100% (35/35)100% (8/8)
writeBundleSources (File): void 100% (1/1)100% (25/25)100% (5/5)
writeBundleSources (Module, File): void 100% (1/1)100% (35/35)100% (8/8)

1/*
2 *   Copyright (c) 2009 The JOMC Project
3 *   Copyright (c) 2005 Christian Schulte <cs@jomc.org>
4 *   All rights reserved.
5 *
6 *   Redistribution and use in source and binary forms, with or without
7 *   modification, are permitted provided that the following conditions
8 *   are met:
9 *
10 *     o Redistributions of source code must retain the above copyright
11 *       notice, this list of conditions and the following disclaimer.
12 *
13 *     o Redistributions in binary form must reproduce the above copyright
14 *       notice, this list of conditions and the following disclaimer in
15 *       the documentation and/or other materials provided with the
16 *       distribution.
17 *
18 *   THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
19 *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
22 *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 *   $Id: JavaBundles.java 1435 2010-01-30 01:52:40Z schulte2005 $
31 *
32 */
33package org.jomc.tools;
34 
35import java.io.File;
36import java.io.FileOutputStream;
37import java.io.IOException;
38import java.io.OutputStream;
39import java.io.StringWriter;
40import java.text.MessageFormat;
41import java.util.HashMap;
42import java.util.Locale;
43import java.util.Map;
44import java.util.Properties;
45import java.util.ResourceBundle;
46import java.util.logging.Level;
47import org.apache.commons.io.FileUtils;
48import org.apache.velocity.Template;
49import org.apache.velocity.VelocityContext;
50import org.jomc.model.Implementation;
51import org.jomc.model.Message;
52import org.jomc.model.Messages;
53import org.jomc.model.Module;
54import org.jomc.model.Text;
55 
56/**
57 * Generates Java bundles.
58 *
59 * <p><b>Use cases</b><br/><ul>
60 * <li>{@link #writeBundleResources(java.io.File) }</li>
61 * <li>{@link #writeBundleResources(org.jomc.model.Module, java.io.File) }</li>
62 * <li>{@link #writeBundleResources(org.jomc.model.Implementation, java.io.File) }</li>
63 * <li>{@link #writeBundleSources(java.io.File) }</li>
64 * <li>{@link #writeBundleSources(org.jomc.model.Module, java.io.File) }</li>
65 * <li>{@link #writeBundleSources(org.jomc.model.Implementation, java.io.File) }</li>
66 * </ul></p>
67 *
68 * @author <a href="mailto:cs@jomc.org">Christian Schulte</a>
69 * @version $Id: JavaBundles.java 1435 2010-01-30 01:52:40Z schulte2005 $
70 *
71 * @see #getModules()
72 */
73public class JavaBundles extends JomcTool
74{
75 
76    /** Name of the generator. */
77    private static final String GENERATOR_NAME = JavaBundles.class.getName();
78 
79    /** Constant for the version of the generator. */
80    private static final String GENERATOR_VERSION = "1.0";
81 
82    /** Location of the {@code Bundle.java.vm} template. */
83    private static final String BUNDLE_TEMPLATE = "Bundle.java.vm";
84 
85    /** Constant for the suffix appended to implementation identifiers. */
86    private static final String BUNDLE_SUFFIX = "Bundle";
87 
88    /** The language of the default language properties file of the bundle. */
89    private Locale defaultLocale;
90 
91    /** Creates a new {@code JavaBundles} instance. */
92    public JavaBundles()
93    {
94        super();
95    }
96 
97    /**
98     * Creates a new {@code JavaBundles} instance taking a {@code JavaBundles} instance to initialize the instance with.
99     *
100     * @param tool The instance to initialize the new instance with,
101     */
102    public JavaBundles( final JavaBundles tool )
103    {
104        super( tool );
105        this.setDefaultLocale( tool.getDefaultLocale() );
106    }
107 
108    /**
109     * Gets the language of the default language properties file of the bundle.
110     *
111     * @return The language of the default language properties file of the bundle.
112     *
113     * @see #setDefaultLocale(java.util.Locale)
114     */
115    public Locale getDefaultLocale()
116    {
117        if ( this.defaultLocale == null )
118        {
119            this.defaultLocale = Locale.getDefault();
120            if ( this.isLoggable( Level.CONFIG ) )
121            {
122                this.log( Level.CONFIG, getMessage( "defaultLocale", this.defaultLocale ), null );
123            }
124        }
125 
126        return this.defaultLocale;
127    }
128 
129    /**
130     * Sets the language of the default language properties file of the bundle.
131     *
132     * @param value The language of the default language properties file of the bundle.
133     *
134     * @see #getDefaultLocale()
135     */
136    public void setDefaultLocale( final Locale value )
137    {
138        this.defaultLocale = value;
139    }
140 
141    /**
142     * Writes bundle sources of the modules of the instance to a given directory.
143     *
144     * @param sourcesDirectory The directory to write sources to.
145     *
146     * @throws NullPointerException if {@code sourcesDirectory} is {@code null}.
147     * @throws ToolException if writing fails.
148     *
149     * @see #writeBundleSources(org.jomc.model.Module, java.io.File)
150     */
151    public void writeBundleSources( final File sourcesDirectory ) throws ToolException
152    {
153        if ( sourcesDirectory == null )
154        {
155            throw new NullPointerException( "sourcesDirectory" );
156        }
157 
158        for ( Module m : this.getModules().getModule() )
159        {
160            this.writeBundleSources( m, sourcesDirectory );
161        }
162    }
163 
164    /**
165     * Writes bundle sources of a given module from the modules of the instance to a given directory.
166     *
167     * @param module The module to process.
168     * @param sourcesDirectory The directory to write sources to.
169     *
170     * @throws NullPointerException if {@code module} or {@code sourcesDirectory} is {@code null}.
171     * @throws ToolException if writing fails.
172     *
173     * @see #writeBundleSources(org.jomc.model.Implementation, java.io.File)
174     */
175    public void writeBundleSources( final Module module, final File sourcesDirectory ) throws ToolException
176    {
177        if ( module == null )
178        {
179            throw new NullPointerException( "module" );
180        }
181        if ( sourcesDirectory == null )
182        {
183            throw new NullPointerException( "sourcesDirectory" );
184        }
185 
186        if ( module.getImplementations() != null )
187        {
188            for ( Implementation i : module.getImplementations().getImplementation() )
189            {
190                this.writeBundleSources( i, sourcesDirectory );
191            }
192        }
193    }
194 
195    /**
196     * Writes bundle sources of a given implementation from the modules of the instance to a given directory.
197     *
198     * @param implementation The implementation to process.
199     * @param sourcesDirectory The directory to write sources to.
200     *
201     * @throws NullPointerException if {@code implementation} or {@code sourcesDirectory} is {@code null}.
202     * @throws ToolException if writing fails.
203     *
204     * @see #getResourceBundleSources(org.jomc.model.Implementation)
205     */
206    public void writeBundleSources( final Implementation implementation, final File sourcesDirectory )
207        throws ToolException
208    {
209        if ( implementation == null )
210        {
211            throw new NullPointerException( "implementation" );
212        }
213        if ( sourcesDirectory == null )
214        {
215            throw new NullPointerException( "sourcesDirectory" );
216        }
217 
218        try
219        {
220            if ( implementation.isClassDeclaration() )
221            {
222                this.assertValidTemplates( implementation );
223 
224                final String bundlePath =
225                    ( this.getJavaTypeName( implementation, true ) + BUNDLE_SUFFIX ).replace( '.', File.separatorChar );
226 
227                final File bundleFile = new File( sourcesDirectory, bundlePath + ".java" );
228 
229                if ( !bundleFile.getParentFile().exists() && !bundleFile.getParentFile().mkdirs() )
230                {
231                    throw new ToolException( getMessage( "failedCreatingDirectory",
232                                                         bundleFile.getParentFile().getAbsolutePath() ) );
233 
234                }
235 
236                if ( this.isLoggable( Level.INFO ) )
237                {
238                    this.log( Level.INFO, getMessage( "writing", bundleFile.getCanonicalPath() ), null );
239                }
240 
241                FileUtils.writeStringToFile( bundleFile, this.getResourceBundleSources( implementation ),
242                                             this.getOutputEncoding() );
243 
244            }
245        }
246        catch ( final IOException e )
247        {
248            throw new ToolException( e );
249        }
250    }
251 
252    /**
253     * Writes bundle resources of the modules of the instance to a given directory.
254     *
255     * @param resourcesDirectory The directory to write resources to.
256     *
257     * @throws NullPointerException if {@code resourcesDirectory} is {@code null}.
258     * @throws ToolException if writing fails.
259     *
260     * @see #writeBundleResources(org.jomc.model.Module, java.io.File)
261     */
262    public void writeBundleResources( final File resourcesDirectory ) throws ToolException
263    {
264        if ( resourcesDirectory == null )
265        {
266            throw new NullPointerException( "resourcesDirectory" );
267        }
268 
269        for ( Module m : this.getModules().getModule() )
270        {
271            this.writeBundleResources( m, resourcesDirectory );
272        }
273    }
274 
275    /**
276     * Writes bundle resources of a given module from the modules of the instance to a given directory.
277     *
278     * @param module The module to process.
279     * @param resourcesDirectory The directory to write resources to.
280     *
281     * @throws NullPointerException if {@code module} or {@code resourcesDirectory} is {@code null}.
282     * @throws ToolException if writing fails.
283     *
284     * @see #writeBundleResources(org.jomc.model.Implementation, java.io.File)
285     */
286    public void writeBundleResources( final Module module, final File resourcesDirectory ) throws ToolException
287    {
288        if ( module == null )
289        {
290            throw new NullPointerException( "module" );
291        }
292        if ( resourcesDirectory == null )
293        {
294            throw new NullPointerException( "resourcesDirectory" );
295        }
296 
297        if ( module.getImplementations() != null )
298        {
299            for ( Implementation i : module.getImplementations().getImplementation() )
300            {
301                this.writeBundleResources( i, resourcesDirectory );
302            }
303        }
304    }
305 
306    /**
307     * Writes the bundle resources of a given implementation from the modules of the instance to a directory.
308     *
309     * @param implementation The implementation to process.
310     * @param resourcesDirectory The directory to write resources to.
311     *
312     * @throws NullPointerException if {@code implementation} or {@code resourcesDirectory} is {@code null}.
313     * @throws ToolException if writing fails.
314     *
315     * @see #getResourceBundleResources(org.jomc.model.Implementation)
316     */
317    public void writeBundleResources( final Implementation implementation, final File resourcesDirectory )
318        throws ToolException
319    {
320        if ( implementation == null )
321        {
322            throw new NullPointerException( "implementation" );
323        }
324        if ( resourcesDirectory == null )
325        {
326            throw new NullPointerException( "resourcesDirectory" );
327        }
328 
329        try
330        {
331            if ( implementation.isClassDeclaration() )
332            {
333                this.assertValidTemplates( implementation );
334 
335                final String bundlePath =
336                    ( this.getJavaTypeName( implementation, true ) + BUNDLE_SUFFIX ).replace( '.', File.separatorChar );
337 
338                Properties defProperties = null;
339                Properties fallbackProperties = null;
340 
341                for ( Map.Entry<Locale, Properties> e : this.getResourceBundleResources( implementation ).entrySet() )
342                {
343                    final String language = e.getKey().getLanguage().toLowerCase();
344                    final java.util.Properties p = e.getValue();
345                    final File file = new File( resourcesDirectory, bundlePath + "_" + language + ".properties" );
346 
347                    if ( !file.getParentFile().exists() && !file.getParentFile().mkdirs() )
348                    {
349                        throw new ToolException( getMessage( "failedCreatingDirectory",
350                                                             file.getParentFile().getAbsolutePath() ) );
351 
352                    }
353 
354                    if ( this.isLoggable( Level.INFO ) )
355                    {
356                        this.log( Level.INFO, getMessage( "writing", file.getCanonicalPath() ), null );
357                    }
358 
359                    OutputStream out = null;
360                    try
361                    {
362                        out = new FileOutputStream( file );
363                        p.store( out, GENERATOR_NAME + ' ' + GENERATOR_VERSION );
364                    }
365                    finally
366                    {
367                        if ( out != null )
368                        {
369                            out.close();
370                        }
371                    }
372 
373                    if ( this.getDefaultLocale().getLanguage().equalsIgnoreCase( language ) )
374                    {
375                        defProperties = p;
376                    }
377 
378                    fallbackProperties = p;
379                }
380 
381                if ( defProperties == null )
382                {
383                    defProperties = fallbackProperties;
384                }
385 
386                if ( defProperties != null )
387                {
388                    final File file = new File( resourcesDirectory, bundlePath + ".properties" );
389                    if ( !file.getParentFile().exists() && !file.getParentFile().mkdirs() )
390                    {
391                        throw new ToolException( getMessage( "failedCreatingDirectory",
392                                                             file.getParentFile().getAbsolutePath() ) );
393 
394                    }
395 
396                    if ( this.isLoggable( Level.INFO ) )
397                    {
398                        this.log( Level.INFO, getMessage( "writing", file.getCanonicalPath() ), null );
399                    }
400 
401                    OutputStream out = null;
402                    try
403                    {
404                        out = new FileOutputStream( file );
405                        defProperties.store( out, GENERATOR_NAME + ' ' + GENERATOR_VERSION );
406                    }
407                    finally
408                    {
409                        if ( out != null )
410                        {
411                            out.close();
412                        }
413                    }
414                }
415            }
416        }
417        catch ( final IOException e )
418        {
419            throw new ToolException( e );
420        }
421    }
422 
423    /**
424     * Gets the source code of the Java class for accessing the resource bundle of a given implementation.
425     *
426     * @param implementation The implementation to get the source code of.
427     *
428     * @return The source code of the Java class for accessing the resource bundle of {@code implementation}.
429     *
430     * @throws NullPointerException if {@code implementation} is {@code null}.
431     * @throws ToolException if getting the source code fails.
432     */
433    public String getResourceBundleSources( final Implementation implementation ) throws ToolException
434    {
435        if ( implementation == null )
436        {
437            throw new NullPointerException( "implementation" );
438        }
439 
440        try
441        {
442            final StringWriter writer = new StringWriter();
443            final VelocityContext ctx = this.getVelocityContext();
444            final Template template = this.getVelocityTemplate( BUNDLE_TEMPLATE );
445            ctx.put( "implementation", implementation );
446            ctx.put( "template", template );
447            template.merge( ctx, writer );
448            writer.close();
449            return writer.toString();
450        }
451        catch ( final IOException e )
452        {
453            throw new ToolException( e );
454        }
455    }
456 
457    /**
458     * Gets the resource bundle properties of a given implementation.
459     *
460     * @param implementation The implementation to get resource bundle properties of.
461     *
462     * @return Resource bundle properties of {@code implementation}.
463     *
464     * @throws NullPointerException if {@code implementation} is {@code null}.
465     * @throws ToolException if getting the resources fails.
466     */
467    public Map<Locale, Properties> getResourceBundleResources( final Implementation implementation )
468        throws ToolException
469    {
470        if ( implementation == null )
471        {
472            throw new NullPointerException( "implementation" );
473        }
474 
475        final Map<Locale, java.util.Properties> properties = new HashMap<Locale, java.util.Properties>( 10 );
476        final Messages messages = this.getModules().getMessages( implementation.getIdentifier() );
477 
478        if ( messages != null )
479        {
480            for ( Message message : messages.getMessage() )
481            {
482                if ( message.getTemplate() != null )
483                {
484                    for ( Text text : message.getTemplate().getText() )
485                    {
486                        final Locale locale = new Locale( text.getLanguage().toLowerCase() );
487                        Properties bundleProperties = properties.get( locale );
488 
489                        if ( bundleProperties == null )
490                        {
491                            bundleProperties = new Properties();
492                            properties.put( locale, bundleProperties );
493                        }
494 
495                        bundleProperties.setProperty( message.getName(), text.getValue() );
496                    }
497                }
498            }
499        }
500 
501        return properties;
502    }
503 
504    /**
505     * Gets the velocity context used for merging templates.
506     *
507     * @return The velocity context used for merging templates.
508     */
509    @Override
510    public VelocityContext getVelocityContext()
511    {
512        final VelocityContext ctx = super.getVelocityContext();
513        ctx.put( "classSuffix", BUNDLE_SUFFIX );
514        ctx.put( "comment", Boolean.TRUE );
515        return ctx;
516    }
517 
518    private void assertValidTemplates( final Implementation implementation )
519    {
520        if ( implementation == null )
521        {
522            throw new NullPointerException( "implementation" );
523        }
524 
525        final Messages messages = this.getModules().getMessages( implementation.getIdentifier() );
526        if ( messages != null )
527        {
528            for ( Message m : messages.getMessage() )
529            {
530                if ( m.getTemplate() != null )
531                {
532                    for ( Text t : m.getTemplate().getText() )
533                    {
534                        new MessageFormat( t.getValue() );
535                    }
536                }
537            }
538        }
539    }
540 
541    private static String getMessage( final String key, final Object... arguments )
542    {
543        if ( key == null )
544        {
545            throw new NullPointerException( "key" );
546        }
547 
548        return MessageFormat.format( ResourceBundle.getBundle( JavaBundles.class.getName().replace( '.', '/' ) ).
549            getString( key ), arguments );
550 
551    }
552 
553}

[all classes][org.jomc.tools]
EMMA 2.0.5312 (C) Vladimir Roubtsov