Message.java

/*******************************************************************************
 * Copyright (c) 2004, 2013 Steve Flasby
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * <ul>
 *     <li>Redistributions of source code must retain the above copyright notice,
 *         this list of conditions and the following disclaimer.</li>
 *     <li>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.</li>
 * </ul>
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
 ******************************************************************************/
/*
 * Created on 20-Jul-2004
 *
 */
package org.flasby.util;

import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;


/**
 * @author flasbyst
 *
 */
public class Message {
	
	public static interface KeyDecorator {
		public String decorateKey( String key );
	}
	
	static class BangKeyDecorator implements KeyDecorator {
	    private static String PACKAGE = "org.flasby.cli.";
	    private static final int PACKAGE_LENGTH = PACKAGE.length(); 
		@Override
		public String decorateKey( String key ){
		    if ( key.startsWith( PACKAGE ) )
		    {
		        return "!"+key.substring( PACKAGE_LENGTH )+"!";
		    }
		    System.out.println("Missing key: "+key);
			return "!"+key+"!";
		}
	}
	static class Bundle {
		private String			mBaseName;
		private ResourceBundle	mBundle;
		private Bundle			mNextBundle;
		private KeyDecorator	mKeyDecorator;
		
	    public Bundle( String baseName, KeyDecorator keyDecorator ) {
			mBaseName = baseName;
			mKeyDecorator = keyDecorator;
		}
        /**
         * @return Returns the bundle.
         */
        public ResourceBundle getBundle() {
            return mBundle;
        }
        /**
         * @param bundle The bundle to set.
         */
        public void setBundle(ResourceBundle bundle) {
            mBundle = bundle;
        }
        /**
         * @return Returns the nextBundle.
         */
        public Bundle getNextBundle() {
            return mNextBundle;
        }
        /**
         * @param nextBundle The nextBundle to set.
         */
        public void setNextBundle(Bundle nextBundle) {
            mNextBundle = nextBundle;
        }
        /**
         * @return Returns the baseName.
         */
        public String getBaseName() {
            return mBaseName;
        }
        /**
         * @return Returns the keyDecorator.
         */
        public KeyDecorator getKeyDecorator() {
            return mKeyDecorator;
        }
	}
	
	
	public Message() {
		addBundle( "flasbymls", new BangKeyDecorator() );
	}
	
	private Bundle ROOT = null;

	public String getMLS( String key ) {
		return getMLS( key, ROOT );
	}
	public String getMLS( String key, Object... args ) {
	    MessageFormat f = new MessageFormat(
			getMLS( key, ROOT )
			);
	    return f.format( args );
	}
	public String getMLS( String key, String arg ) {
	    MessageFormat f = new MessageFormat(
			getMLS( key, ROOT )
			);
	    return f.format( new String[] { arg } );
	}
	private String getMLS( String key, Bundle bundle ) {
		if ( bundle==null ) {
			throw new MissingResourceException(
					"Oh dear, couldn't find a resource at the end of the resource chain," +
					" internal error.",
					String.class.getName(),
					key			
			);
		}
		try {
			return bundle.getBundle().getString( key );
		} catch ( MissingResourceException ex ) {
			if ( bundle.getKeyDecorator()==null) {
				return getMLS( key, bundle.getNextBundle() );
			}
			return bundle.getKeyDecorator().decorateKey( key );
		}
	}
	public synchronized Message addBundle( String baseName ) {
	    return addBundle( baseName, null );
	}
	public synchronized Message addBundle( String baseName, KeyDecorator keyDecorator ) {
		ResourceBundle newBundle = ResourceBundle.getBundle( baseName );
		Bundle newRoot = new Bundle( baseName, keyDecorator );
		newRoot.setNextBundle( ROOT );
		newRoot.setBundle( newBundle );
		ROOT = newRoot;
		return this;
	}
}