DefaultConvertor.java

/*******************************************************************************
 *   Copyright (c) 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.
 *  
 *******************************************************************************/
package org.flasby.util;

import java.util.HashMap;

public class DefaultConvertor {

	private static final Registry REGISTRY = new Registry();
	static {
		REGISTRY.register(String.class,Boolean.class,new ConvertorStub<String,Boolean>(String.class,Boolean.class) {
			@Override public Boolean convert(Object from) {
				return Boolean.valueOf( fromClass.cast(from) );
			}
		});
		REGISTRY.register(Boolean.class,String.class,new ConvertorStub<Boolean,String>(Boolean.class,String.class) {
			@Override public String convert(Object from) {
				return from.toString();
			}
		});
	}
	
	static abstract class ConvertorStub<From, To> implements Convertor<From, To> {
		protected final Class<From> fromClass;
		protected final Class<To> toClass;
		ConvertorStub(Class<From> from, Class<To> to) {
			fromClass = from;
			toClass = to;
		}
	}
	
	static class Registry {
		HashMap<String, Convertor<?,?>> registry = new HashMap<>();
		void register(Class<?> from, Class<?> to, Convertor<?, ?> convertor) {
			registry.put(from.getName()+to.getName(), convertor);
		}
		Convertor<?,?> find(final Class<?> from, final Class<?> to) {
			return registry.get(from.getName()+to.getName());
		}
	}
	
	@SuppressWarnings("unchecked")
	public static <From,To> Convertor<From,To> find(final Class<From> from, final Class<To> to) {
		if ( from.equals(to) ) {
			return new Convertor<From, To>() {
				@Override
				public To convert(Object from) {
					return to.cast( from );
				}
			};
		}
		Convertor<From, To> retval = (Convertor<From, To>) REGISTRY.find(from,to);
		if ( retval==null ) {
			throw new RuntimeException("Cannot convert between "+from+" -> "+to+" - no convertor registered");
		}
		return retval;
	}

}