view src/luan/LuanCloner.java @ 784:6a7c6879158d

revert shallowClone()
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 30 Aug 2016 12:08:49 -0600
parents 655280eab1e2
children d69d3c51c44e
line wrap: on
line source

package luan;

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


public final class LuanCloner {
	public final boolean deep;
	private final Map cloned = new IdentityHashMap();

	public LuanCloner(boolean deep) {
		this.deep = deep;
	}

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

	public Object[] clone(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 clone(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 LuanCloneable )
			return clone((LuanCloneable)obj);
		if( obj instanceof Object[] )
			return clone((Object[])obj);
		if( obj instanceof Map )
			return clone((Map)obj);
		return obj;
	}
/*
	public Object check(Object obj) {
		if( deep )
			throw new RuntimeException();
		if( !(obj instanceof LuanCloneable) )
			return obj;
		LuanCloneable lc = (LuanCloneable)obj;
		return lc.getCloner() == this ? lc : clone(lc);
	}
*/
}