001/*
002 *  Copyright 2013 Chris Pheby
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.jadira.reflection.cloning.api;
017
018import java.lang.invoke.MethodHandle;
019import java.util.Set;
020
021import org.jadira.reflection.cloning.annotation.Transient;
022
023/**
024 * A clone driver defines the features of a class that is used to bootstrap and provide context to a
025 * cloning operation, typically (but not always), a {@link Cloner} * 
026 */
027public interface CloneDriver extends CloneImplementor {
028
029        /**
030         * Gets the built in implementor for the given class
031         * @param clazz The class
032         * @return A CloneImplementor
033         */
034        public CloneImplementor getBuiltInImplementor(Class<?> clazz);
035        
036        /**
037         * Retrieves the registered implementor for the given class
038         * @param clazz The class
039         * @return A CloneImplementor
040         */
041        CloneImplementor getImplementor(Class<?> clazz);
042
043        /**
044         * Retrieves the registered implementor for the given class
045         * @param clazz The class
046         * @return A CloneImplementor
047         */
048        CloneImplementor getAnnotationImplementor(Class<?> clazz);
049
050        /** 
051         * Put the registered implementor for the given class
052         * @param clazz The class
053         * @param implementor Implementor to register
054         */
055        void putAnnotationImplementor(Class<?> clazz, CloneImplementor implementor);
056
057        
058        /**
059         * If true, then any class that implements {@link Cloneable} will be cloned using the
060         * {@link Object#clone()} method.
061         * @return Default value is false
062         */
063        boolean isUseCloneable();
064        
065        /**
066         * Returns the clone() method for the indicated class
067         * @param clazz The class to obtain the method for
068         * @return The related MethodHandle
069         */
070        MethodHandle getCloneMethod(Class<?> clazz);
071
072        /**
073         * Put the clone() method for the indicated class
074         * @param clazz The class to obtain the method for
075         * @param handle The related MethodHandle
076         */
077        void putCloneMethod(Class<?> clazz, MethodHandle handle);
078        
079        /**
080         * If false, indicates that fields modified by the transient keyword should not be cloned,
081         * instead being replaced with null.
082         * @return Default value is true
083         */
084        boolean isCloneTransientFields();
085
086        /**
087         * If false, indicates that fields annotated by the {@link Transient} annotation should not be
088         * cloned, instead being replaced with null.
089         * @return Default value is false
090         */
091        boolean isCloneTransientAnnotatedFields();
092
093        /**
094         * If false, indicates that classes known to be immutable should be not cloned. Immutables are
095         * identified by the @Immutable annotation; are one of a select set of known JDK immutable
096         * classes; or are detected as immutable by the Mutability Detector tool (if it was found on the
097         * classpath).
098         * @return Default value is false
099         */
100        boolean isCloneImmutable();
101
102        /**
103         * A list of classes that should be treated as immutable.
104         * @return immutableClasses The immutable classes
105         */
106        Set<Class<?>> getImmutableClasses();
107
108        /**
109         * A list of classes that should not be cloned.
110         * @return immutableClasses The classes which should be be cloned
111         */
112        Set<Class<?>> getNonCloneableClasses();
113
114        /**
115         * Indicates whether custom clone implementors are enabled
116         * @return Default value is true
117         */
118        boolean isUseCloneImplementors();
119        
120        /**
121         * Indicates whether synthetic fields should be cloned
122         * @return  cloneSyntheticFields Default is false
123         */
124    boolean isCloneSyntheticFields();
125    
126        /**
127         * Indicates whether the given object <em>instance</em> should be treated as immutable
128         * @param instance The instance to check for whether it is registered as immutable
129         * @return True if the object is registered as immutable
130         */
131        boolean isImmutableInstance(Object instance);
132        
133        /** 
134         * Stores an object instance to be treated as immutable
135         * @param instance Object to be considered immutable
136         */
137        void putImmutableInstance(Object instance);
138        
139        /**
140         * Indicates whether to track references
141         * @return trackReferences Default is true
142         */
143    boolean isTrackReferences();
144        
145        /**
146         * Indicates whether to also track references for flat classes when tracking references.
147         * @return trackReferences Default is false
148         */
149    boolean isTrackReferencesForFlatClasses();
150}