/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.glassfish.pfl.dynamic.copyobject.impl ;

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

import org.glassfish.pfl.dynamic.copyobject.spi.ObjectCopier ;
import org.glassfish.pfl.dynamic.copyobject.spi.Immutable ;
import org.glassfish.pfl.dynamic.copyobject.spi.ReflectiveCopyException ;


Class used to deep copy arbitrary data. A single ObjectCopierImpl instance will preserve all object aliasing across multiple calls to copy.
/** Class used to deep copy arbitrary data. A single * ObjectCopierImpl * instance will preserve all object aliasing across multiple calls * to copy. */
public class ObjectCopierImpl implements ObjectCopier { // It is very important that ccf be static. This means that // ccf is shared across all instances of the object copier, // so that any class is analyzed only once, instead of once per // copier instance. This is worth probably 20%+ in microbenchmark // performance. private static PipelineClassCopierFactory ccf = DefaultClassCopierFactories.getPipelineClassCopierFactory() ; static { ccf.setSpecialClassCopierFactory( new ClassCopierFactory() { @Override public ClassCopier getClassCopier( Class<?> cls ) throws ReflectiveCopyException { if (cls.isAnnotationPresent( Immutable.class )) { return DefaultClassCopiers.getIdentityClassCopier(); } else { return null; } } } ) ; } private Map<Object,Object> oldToNew ; public ObjectCopierImpl() { if (DefaultClassCopierFactories.USE_FAST_CACHE) { oldToNew = new FastCache<Object,Object>( new IdentityHashMap<Object,Object>()); } else { oldToNew = new IdentityHashMap<Object,Object>(); } }
Return a deep copy of obj. Aliasing is preserved within obj and between objects passed in multiple calls to the same instance of ReflectObjectCopierImpl.
/** Return a deep copy of obj. Aliasing is preserved within * obj and between objects passed in multiple calls to the * same instance of ReflectObjectCopierImpl. */
@Override public Object copy( Object obj ) throws ReflectiveCopyException { if (obj == null) { return null; } Class<?> cls = obj.getClass() ; ClassCopier copier = ccf.getClassCopier( cls ) ; return copier.copy( oldToNew, obj ) ; } }