/* * Copyright 2006 University of Dundee. All rights reserved. * Use is subject to license terms supplied in LICENSE.txt */ package ome.util; import java.lang.reflect.Method; import java.util.Collection; import java.util.HashMap; import java.util.Map; import ome.conditions.InternalException; import ome.model.IObject; import ome.model.internal.Details; public class ShallowCopy { public <T extends IObject> T copy(T original) { T f = ShallowCopy.reflectiveNewInstance(original); SetValues set = new SetValues(f); original.acceptFilter(set); return f; } @SuppressWarnings("unchecked") public static <T extends IObject> T reflectiveNewInstance(T f) { Method m; T iobj; try { Class<T> c = (Class<T>) Utils.trueClass(f.getClass()); iobj = c.newInstance(); } catch (Exception e) { InternalException ie = new InternalException(e.getMessage()); ie.setStackTrace(e.getStackTrace()); throw ie; } return iobj; } } class SetValues implements Filter { private IObject target; public SetValues(IObject target) { this.target = target; } public Filterable filter(String fieldId, Filterable f) { if (f == null) { return null; } else if (f instanceof Enum) { target.putAt(fieldId, f); } else if (f instanceof ome.model.internal.Primitive) { target.putAt(fieldId, f); } else if (Details.class.isAssignableFrom(f.getClass())) { target.putAt(fieldId, ((Details) f).shallowCopy()); } else if (IObject.class.isAssignableFrom(f.getClass())) { IObject old = (IObject) f; IObject iobj = ShallowCopy.reflectiveNewInstance(old); iobj.setId(old.getId()); iobj.unload(); target.putAt(fieldId, iobj); } else { throw new InternalException("Unknown filterable type:" + f.getClass()); } return f; } public Collection filter(String fieldId, Collection c) { target.putAt(fieldId, null); return c; } public Map filter(String fieldId, Map m) { target.putAt(fieldId, null); return m; } public Object filter(String fieldId, Object o) { if (o == null) { target.putAt(fieldId, null); } // TODO add Object[] filter(Object[]) method to Filterable else if (Object[].class.isAssignableFrom(o.getClass())) { target.putAt(fieldId, null); } else { target.putAt(fieldId, o); } return o; } } class StoreValues implements Filter { public Map values = new HashMap(); public Filterable filter(String fieldId, Filterable f) { if (f == null) { return null; } else if (f instanceof Enum) { values.put(fieldId, f); } else if (Details.class.isAssignableFrom(f.getClass())) { values.put(fieldId, ((Details) f).shallowCopy()); } else if (IObject.class.isAssignableFrom(f.getClass())) { IObject old = (IObject) f; IObject iobj = ShallowCopy.reflectiveNewInstance(old); iobj.setId(old.getId()); iobj.unload(); values.put(fieldId, iobj); } else { throw new InternalException("Unknown filterable type:" + f.getClass()); } return f; } public Collection filter(String fieldId, Collection c) { values.put(fieldId, null); return c; } public Map filter(String fieldId, Map m) { values.put(fieldId, null); return m; } public Object filter(String fieldId, Object o) { if (o == null) { values.put(fieldId, null); } values.put(fieldId, o); return o; } }