All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jomc.tools.ResourceFileProcessor Maven / Gradle / Ivy

There is a newer version: 1.10.1
Show newest version
/*
 *   Copyright (C) Christian Schulte , 2005-206
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *
 *     o Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *
 *     o Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *
 *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *   $JOMC: ResourceFileProcessor.java 5043 2015-05-27 07:03:39Z schulte $
 *
 */
package org.jomc.tools;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.logging.Level;
import org.apache.velocity.VelocityContext;
import org.jomc.model.Implementation;
import org.jomc.model.JavaTypeName;
import org.jomc.model.Message;
import org.jomc.model.Messages;
import org.jomc.model.ModelObjectException;
import org.jomc.model.Module;
import org.jomc.model.Specification;
import org.jomc.model.Text;

/**
 * Processes resource files.
 *
 * 

* Use Cases:

    *
  • {@link #writeResourceBundleResourceFiles(File) }
  • *
  • {@link #writeResourceBundleResourceFiles(Module, File) }
  • *
  • {@link #writeResourceBundleResourceFiles(Specification, File) }
  • *
  • {@link #writeResourceBundleResourceFiles(Implementation, File) }
  • *

* * @author Christian Schulte * @version $JOMC: ResourceFileProcessor.java 5043 2015-05-27 07:03:39Z schulte $ * * @see #getModules() */ public class ResourceFileProcessor extends JomcTool { /** * The language of the default language properties file of generated resource bundle resources. */ private Locale resourceBundleDefaultLocale; /** * Creates a new {@code ResourceFileProcessor} instance. */ public ResourceFileProcessor() { super(); } /** * Creates a new {@code ResourceFileProcessor} instance taking a {@code ResourceFileProcessor} instance to * initialize the instance with. * * @param tool The instance to initialize the new instance with. * * @throws NullPointerException if {@code tool} is {@code null}. * @throws IOException if copying {@code tool} fails. */ public ResourceFileProcessor( final ResourceFileProcessor tool ) throws IOException { super( tool ); this.resourceBundleDefaultLocale = tool.resourceBundleDefaultLocale; } /** * Gets the language of the default language properties file of generated resource bundle resource files. * * @return The language of the default language properties file of generated resource bundle resource files. * * @see #setResourceBundleDefaultLocale(java.util.Locale) */ public final Locale getResourceBundleDefaultLocale() { if ( this.resourceBundleDefaultLocale == null ) { this.resourceBundleDefaultLocale = Locale.ENGLISH; if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "defaultResourceBundleDefaultLocale", this.resourceBundleDefaultLocale ), null ); } } return this.resourceBundleDefaultLocale; } /** * Sets the language of the default language properties file of generated resource bundle resource files. * * @param value The language of the default language properties file of generated resource bundle resource files. * * @see #getResourceBundleDefaultLocale() */ public final void setResourceBundleDefaultLocale( final Locale value ) { this.resourceBundleDefaultLocale = value; } /** * Writes resource bundle resource files of the modules of the instance to a given directory. * * @param resourcesDirectory The directory to write resource bundle resource files to. * * @throws NullPointerException if {@code resourcesDirectory} is {@code null}. * @throws IOException if writing resource bundle resource files fails. * @throws ModelObjectException if compiling the name of a referenced type fails. * * @see #writeResourceBundleResourceFiles(org.jomc.model.Module, java.io.File) */ public void writeResourceBundleResourceFiles( final File resourcesDirectory ) throws IOException, ModelObjectException { if ( resourcesDirectory == null ) { throw new NullPointerException( "resourcesDirectory" ); } if ( this.getModules() != null ) { for ( int i = 0, s0 = this.getModules().getModule().size(); i < s0; i++ ) { this.writeResourceBundleResourceFiles( this.getModules().getModule().get( i ), resourcesDirectory ); } } else if ( this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "modulesNotFound", this.getModel().getIdentifier() ), null ); } } /** * Writes resource bundle resource files of a given module from the modules of the instance to a given directory. * * @param module The module to process. * @param resourcesDirectory The directory to write resource bundle resource files to. * * @throws NullPointerException if {@code module} or {@code resourcesDirectory} is {@code null}. * @throws IOException if writing resource bundle resource files fails. * @throws ModelObjectException if compiling the name of a referenced type fails. * * @see #writeResourceBundleResourceFiles(org.jomc.model.Specification, java.io.File) * @see #writeResourceBundleResourceFiles(org.jomc.model.Implementation, java.io.File) */ public void writeResourceBundleResourceFiles( final Module module, final File resourcesDirectory ) throws IOException, ModelObjectException { if ( module == null ) { throw new NullPointerException( "module" ); } if ( resourcesDirectory == null ) { throw new NullPointerException( "resourcesDirectory" ); } if ( this.getModules() != null && this.getModules().getModule( module.getName() ) != null ) { if ( module.getSpecifications() != null ) { for ( int i = 0, s0 = module.getSpecifications().getSpecification().size(); i < s0; i++ ) { this.writeResourceBundleResourceFiles( module.getSpecifications().getSpecification().get( i ), resourcesDirectory ); } } if ( module.getImplementations() != null ) { for ( int i = 0, s0 = module.getImplementations().getImplementation().size(); i < s0; i++ ) { this.writeResourceBundleResourceFiles( module.getImplementations().getImplementation().get( i ), resourcesDirectory ); } } } else if ( this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "moduleNotFound", module.getName() ), null ); } } /** * Writes resource bundle resource files of a given specification from the modules of the instance to a directory. * * @param specification The specification to process. * @param resourcesDirectory The directory to write resource bundle resource files to. * * @throws NullPointerException if {@code specification} or {@code resourcesDirectory} is {@code null}. * @throws IOException if writing resource bundle resource files fails. * @throws ModelObjectException if compiling the name of the type referenced by the specification fails. * * @see #getResourceBundleResources(org.jomc.model.Specification) */ public void writeResourceBundleResourceFiles( final Specification specification, final File resourcesDirectory ) throws IOException, ModelObjectException { if ( specification == null ) { throw new NullPointerException( "implementation" ); } if ( resourcesDirectory == null ) { throw new NullPointerException( "resourcesDirectory" ); } if ( this.getModules() != null && this.getModules().getSpecification( specification.getIdentifier() ) != null ) { if ( specification.isClassDeclaration() ) { if ( !resourcesDirectory.isDirectory() ) { throw new IOException( getMessage( "directoryNotFound", resourcesDirectory.getAbsolutePath() ) ); } this.assertValidTemplates( specification ); final JavaTypeName javaTypeName = specification.getJavaTypeName(); if ( javaTypeName != null ) { final String bundlePath = javaTypeName.getQualifiedName().replace( '.', File.separatorChar ); this.writeResourceBundleResourceFiles( this.getResourceBundleResources( specification ), resourcesDirectory, bundlePath ); } } } else if ( this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "specificationNotFound", specification.getIdentifier() ), null ); } } /** * Writes resource bundle resource files of a given implementation from the modules of the instance to a directory. * * @param implementation The implementation to process. * @param resourcesDirectory The directory to write resource bundle resource files to. * * @throws NullPointerException if {@code implementation} or {@code resourcesDirectory} is {@code null}. * @throws IOException if writing resource bundle resource files fails. * @throws ModelObjectException if compiling the name of the type referenced by the implementation fails. * * @see #getResourceBundleResources(org.jomc.model.Implementation) */ public void writeResourceBundleResourceFiles( final Implementation implementation, final File resourcesDirectory ) throws IOException, ModelObjectException { if ( implementation == null ) { throw new NullPointerException( "implementation" ); } if ( resourcesDirectory == null ) { throw new NullPointerException( "resourcesDirectory" ); } if ( this.getModules() != null && this.getModules().getImplementation( implementation.getIdentifier() ) != null ) { if ( implementation.isClassDeclaration() ) { if ( !resourcesDirectory.isDirectory() ) { throw new IOException( getMessage( "directoryNotFound", resourcesDirectory.getAbsolutePath() ) ); } this.assertValidTemplates( implementation ); final JavaTypeName javaTypeName = implementation.getJavaTypeName(); if ( javaTypeName != null ) { final String bundlePath = javaTypeName.getQualifiedName().replace( '.', File.separatorChar ); this.writeResourceBundleResourceFiles( this.getResourceBundleResources( implementation ), resourcesDirectory, bundlePath ); } } } else if ( this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "implementationNotFound", implementation.getIdentifier() ), null ); } } /** * Gets resource bundle properties resources of a given specification. * * @param specification The specification to get resource bundle properties resources of. * * @return Resource bundle properties resources of {@code specification} or {@code null}, if no model objects are * found. * * @throws NullPointerException if {@code specification} is {@code null}. * @throws IOException if getting the resource bundle properties resources fails. */ public Map getResourceBundleResources( final Specification specification ) throws IOException { if ( specification == null ) { throw new NullPointerException( "specification" ); } Map properties = null; if ( this.getModules() != null && this.getModules().getSpecification( specification.getIdentifier() ) != null ) { properties = new HashMap(); } else if ( this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "specificationNotFound", specification.getIdentifier() ), null ); } return properties; } /** * Gets resource bundle properties resources of a given implementation. * * @param implementation The implementation to get resource bundle properties resources of. * * @return Resource bundle properties resources of {@code implementation} or {@code null}, if no model objects are * found. * * @throws NullPointerException if {@code implementation} is {@code null}. * @throws IOException if getting the resource bundle properties resources fails. */ public Map getResourceBundleResources( final Implementation implementation ) throws IOException { if ( implementation == null ) { throw new NullPointerException( "implementation" ); } Map properties = null; if ( this.getModules() != null && this.getModules().getImplementation( implementation.getIdentifier() ) != null ) { properties = new HashMap( 10 ); final Messages messages = this.getModules().getMessages( implementation.getIdentifier() ); if ( messages != null ) { for ( int i = 0, s0 = messages.getMessage().size(); i < s0; i++ ) { final Message message = messages.getMessage().get( i ); if ( message.getTemplate() != null ) { for ( int j = 0, s1 = message.getTemplate().getText().size(); j < s1; j++ ) { final Text text = message.getTemplate().getText().get( j ); final Locale locale = new Locale( text.getLanguage().toLowerCase() ); Properties bundleProperties = properties.get( locale ); if ( bundleProperties == null ) { bundleProperties = new Properties(); properties.put( locale, bundleProperties ); } bundleProperties.setProperty( message.getName(), text.getValue() ); } } } } } else if ( this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "implementationNotFound", implementation.getIdentifier() ), null ); } return properties; } private void writeResourceBundleResourceFiles( final Map resources, final File resourcesDirectory, final String bundlePath ) throws IOException { if ( resources == null ) { throw new NullPointerException( "resources" ); } if ( resourcesDirectory == null ) { throw new NullPointerException( "resourcesDirectory" ); } if ( bundlePath == null ) { throw new NullPointerException( "bundlePath" ); } Properties defProperties = null; Properties fallbackProperties = null; final VelocityContext ctx = this.getVelocityContext(); final String toolName = ctx.get( "toolName" ).toString(); final String toolVersion = ctx.get( "toolVersion" ).toString(); final String toolUrl = ctx.get( "toolUrl" ).toString(); for ( final Map.Entry e : resources.entrySet() ) { final String language = e.getKey().getLanguage().toLowerCase(); final Properties p = e.getValue(); final File file = new File( resourcesDirectory, bundlePath + "_" + language + ".properties" ); if ( this.getResourceBundleDefaultLocale().getLanguage().equalsIgnoreCase( language ) ) { defProperties = p; } fallbackProperties = p; if ( !file.getParentFile().exists() && !file.getParentFile().mkdirs() ) { throw new IOException( getMessage( "failedCreatingDirectory", file.getParentFile().getAbsolutePath() ) ); } if ( this.isLoggable( Level.INFO ) ) { this.log( Level.INFO, getMessage( "writing", file.getCanonicalPath() ), null ); } this.writePropertiesFile( p, toolName + ' ' + toolVersion + " - See " + toolUrl, file ); } if ( defProperties == null ) { defProperties = fallbackProperties; } if ( defProperties != null ) { final File file = new File( resourcesDirectory, bundlePath + ".properties" ); if ( !file.getParentFile().exists() && !file.getParentFile().mkdirs() ) { throw new IOException( getMessage( "failedCreatingDirectory", file.getParentFile().getAbsolutePath() ) ); } if ( this.isLoggable( Level.INFO ) ) { this.log( Level.INFO, getMessage( "writing", file.getCanonicalPath() ), null ); } this.writePropertiesFile( defProperties, toolName + ' ' + toolVersion + " - See " + toolUrl, file ); } } private void assertValidTemplates( final Specification specification ) { if ( specification == null ) { throw new NullPointerException( "specification" ); } } private void assertValidTemplates( final Implementation implementation ) { if ( implementation == null ) { throw new NullPointerException( "implementation" ); } final Messages messages = this.getModules().getMessages( implementation.getIdentifier() ); if ( messages != null ) { for ( int i = messages.getMessage().size() - 1; i >= 0; i-- ) { final Message m = messages.getMessage().get( i ); if ( m.getTemplate() != null ) { for ( int j = m.getTemplate().getText().size() - 1; j >= 0; j-- ) { new MessageFormat( m.getTemplate().getText().get( j ).getValue() ); } } } } } private void writePropertiesFile( final Properties properties, final String comments, final File propertiesFile ) throws IOException { RandomAccessFile randomAccessFile = null; FileChannel fileChannel = null; FileLock fileLock = null; boolean suppressExceptionOnClose = true; final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); properties.store( byteStream, comments ); byteStream.close(); final byte[] bytes = byteStream.toByteArray(); try { randomAccessFile = new RandomAccessFile( propertiesFile, "rw" ); fileChannel = randomAccessFile.getChannel(); fileLock = fileChannel.lock(); fileChannel.truncate( bytes.length ); fileChannel.position( 0L ); fileChannel.write( ByteBuffer.wrap( bytes ) ); fileChannel.force( true ); suppressExceptionOnClose = false; } finally { this.releaseAndClose( fileLock, fileChannel, randomAccessFile, suppressExceptionOnClose ); } } private void releaseAndClose( final FileLock fileLock, final FileChannel fileChannel, final Closeable closeable, final boolean suppressExceptions ) throws IOException { try { if ( fileLock != null ) { fileLock.release(); } } catch ( final IOException e ) { if ( suppressExceptions ) { this.log( Level.SEVERE, null, e ); } else { throw e; } } finally { try { if ( fileChannel != null ) { fileChannel.close(); } } catch ( final IOException e ) { if ( suppressExceptions ) { this.log( Level.SEVERE, null, e ); } else { throw e; } } finally { try { if ( closeable != null ) { closeable.close(); } } catch ( final IOException e ) { if ( suppressExceptions ) { this.log( Level.SEVERE, null, e ); } else { throw e; } } } } } private static String getMessage( final String key, final Object... arguments ) { if ( key == null ) { throw new NullPointerException( "key" ); } return MessageFormat.format( ResourceBundle.getBundle( ResourceFileProcessor.class.getName().replace( '.', '/' ) ).getString( key ), arguments ); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy