view core/src/luan/DeepCloner.java @ 641:252041bc41b5

minor
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 11 Mar 2016 05:59:18 -0700
parents c6bcb8859b93
children
line wrap: on
line source

package luan;

import java.util.Map;
import java.util.HashMap;
import java.util.IdentityHashMap;


public final class DeepCloner {
	private final Map cloned = new IdentityHashMap();

	public DeepCloneable deepClone(DeepCloneable obj) {
		if( obj==null )
			return null;
		DeepCloneable rtn = (DeepCloneable)cloned.get(obj);
		if( rtn == null ) {
			rtn = obj.shallowClone();
			cloned.put(obj,rtn);
			obj.deepenClone(rtn,this);
		}
		return rtn;
	}

	public Object[] deepClone(Object[] obj) {
		if( obj.length == 0 )
			return obj;
		Object[] rtn = (Object[])cloned.get(obj);
		if( rtn == null ) {
			rtn = obj.clone();
			cloned.put(obj,rtn);
			for( int i=0; i<rtn.length; i++ ) {
				rtn[i] = get(rtn[i]);
			}
		}
		return rtn;
	}

	public Map deepClone(Map obj) {
		if( !obj.getClass().equals(HashMap.class) )
			throw new RuntimeException("can only clone HashMap");
		Map rtn = (Map)cloned.get(obj);
		if( rtn == null ) {
			rtn = new HashMap();
			for( Object stupid : obj.entrySet() ) {
				Map.Entry entry = (Map.Entry)stupid;
				rtn.put( get(entry.getKey()), get(entry.getValue()) );
			}
		}
		return rtn;
	}

	public Object get(Object obj) {
		if( obj instanceof DeepCloneable )
			return deepClone((DeepCloneable)obj);
		if( obj instanceof Object[] )
			return deepClone((Object[])obj);
		if( obj instanceof Map )
			return deepClone((Map)obj);
		return obj;
	}
}