view src/luan/LuanCloner.java @ 1304:5b947f29ea87 0.23

minor
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 13 Jan 2019 18:22:14 -0700
parents d69d3c51c44e
children e0cf0d108a77
line wrap: on
line source

package luan;

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


public final class LuanCloner {
	public enum Type { COMPLETE, INCREMENTAL }

	public final Type type;
	private final Map cloned = new IdentityHashMap();

	public LuanCloner(Type type) {
		this.type = type;
	}

	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;
	}
}