net.sf.navel.beans
Class ProxyFactory

java.lang.Object
  extended by net.sf.navel.beans.ProxyFactory

public class ProxyFactory
extends java.lang.Object

This is the starting point for working with Navel. It encapsulates the creation of dynamic proxies, constructing them with the supplied delegation pieces and the common data backing code.

Author:
thomas

Method Summary
static java.lang.Class<?>[] additionalTypes(java.lang.Class<?> primaryType, java.lang.Class<?>[] secondaryTypes)
          Find out for a set of interfaces what additional interfaces would be implemented were these types constructed and backed by a proxy.
static void attach(java.lang.Object bean, InterfaceDelegate... delegates)
          Convenience method for attaching multiple delegates at once.
static void attach(java.lang.Object bean, InterfaceDelegate delegate)
          Utility method that exposes the runtime delegation attachment code.
static void attach(java.lang.Object bean, java.lang.String propertyName, PropertyDelegate<?> delegate)
          Utility method that exposes the runtime delegation attachment code.
static java.lang.Object copy(java.lang.Object source, boolean deep)
          Performs a deep copy of all the proxy support code and a shallow copy of the internal bean state.
static
<T> T
copyAs(java.lang.Class<T> primaryType, java.lang.Object source)
          An overload that assumes shallow copy.
static
<T> T
copyAs(java.lang.Class<T> primaryType, java.lang.Object source, boolean deep)
          A convenience version that also checks to see if the cast to T is safe, then casts and returns as T.
static java.lang.Object create(java.lang.Class<?>... allTypes)
          Overload that does not set any initial values or constructor arguments.
static java.lang.Object create(java.util.Map<java.lang.String,java.lang.Object> initialValues, java.lang.Class<?>[] allTypes)
          Overload that uses the initial values to set the beans initial state and the same values to pass in as constructor arguments for any registered instances of ConstructionDelegate.
static java.lang.Object create(java.util.Map<java.lang.String,java.lang.Object> constructorArguments, java.util.Map<java.lang.String,java.lang.Object> initialValues, java.lang.Class<?>[] allTypes)
          Fully specified factory method for generating a new Navel backed dynamic proxy.
static
<B> B
createAs(java.lang.Class<B> primaryType, java.lang.Class<?>... additionalTypes)
          Overload that narrows the new bean down to the primary type of interest and set the initial values.
static
<B> B
createAs(java.lang.Class<B> primaryType, java.util.Map<java.lang.String,java.lang.Object> initialValues, java.lang.Class<?>... additionalTypes)
          Overload that narrows the new bean down to the primary type of interest and does not set any initial values.
static
<B> B
createAs(java.lang.Class<B> primaryType, java.util.Map<java.lang.String,java.lang.Object> constructorArguments, java.util.Map<java.lang.String,java.lang.Object> initialValues, java.lang.Class<?>... additionalTypes)
          Overload that narrows the new bean down to the primary type of interest and does not set any initial values.
static boolean detach(java.lang.Object bean, java.lang.Class<?> delegatingInterface)
          Removes a delegate, if any, mapped to the specific interface.
static boolean detach(java.lang.Object bean, java.lang.String propertyName)
          Removes a delegate, if any, mapped to the specific property.
static JavaBeanHandler getHandler(java.lang.Object bean)
          A convenience method to get the underlying Navel bean handler, if the passed in object is a Navel bean.
static ProxyDescriptor getProxyDescriptor(java.lang.Object bean)
          Allows retrieval of the reflection information provided at construction time, including the primary interface out of all the supported interfaces.
static boolean isAttached(java.lang.Object bean, java.lang.Class<?> delegatingInterface)
          Checks to see if there is a delegate for the specified interface.
static boolean isAttached(java.lang.Object bean, java.lang.String propertyName)
          Checks to see if there is a delegate for the specified property.
static void register(java.lang.Class<?> forType, ConstructionDelegate delegate)
          Register custom construction logic, to give Navel beans the ability to behave more closely to concrete Java Beans that can have whatever constructions scheme is required.
static void registerDefault(ConstructionDelegate delegate)
          Register a single constructor to be called on all proxies, unconditionally.
static void registerResolver(NestedResolver resolver)
          Register an alternate strategy for handling the mass setting of values on any beans instantiated during the course of evaluating dot notations.
static java.lang.Object unmodifiableObject(java.lang.Object source)
          Creates a new instance, that cannot be changed, which is a copy of all the proxy support code, a deep copy of the internal bean state, and a shallow copy of any property delegates, to keep synthetic properties consistent with the source.
static
<T> T
unmodifiableObjectAs(java.lang.Class<T> primaryType, java.lang.Object source)
          Generic version that helps ensure type safety; the same adviso applie as the non-generic method.
static ConstructionDelegate unregister(java.lang.Class<?> forType)
          Useful for testing but should not be necessary, otherwise.
static
<T> T
viewAs(java.lang.Class<T> primaryType, java.lang.Object source, boolean deepCopy, java.lang.Class<?>... subTypes)
          Generates a view, as a copy, of the source that is a safe subset of the properties on the original.
static
<T> T
viewAs(java.lang.Class<T> primaryType, java.lang.Object source, java.lang.Class<?>... subTypes)
          Overload that assumes shallow copy.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

register

public static void register(java.lang.Class<?> forType,
                            ConstructionDelegate delegate)
Register custom construction logic, to give Navel beans the ability to behave more closely to concrete Java Beans that can have whatever constructions scheme is required.

Parameters:
forType - Interface for which the custom logic will be registered.
delegate - Implementation that provides the custom logic.

registerDefault

public static void registerDefault(ConstructionDelegate delegate)
Register a single constructor to be called on all proxies, unconditionally. The ConstructionDelegate interface still provides enough information in the formal arguments that an arbitrary implementation can do conditional work on its own.

Parameters:
delegate - Delegate to be called for every proxy, in case an application has rules to be executed everywhere.

registerResolver

public static void registerResolver(NestedResolver resolver)
Register an alternate strategy for handling the mass setting of values on any beans instantiated during the course of evaluating dot notations.

Parameters:
resolver - Implementation that should handle the derived maps for a new or existing bean to pass property validation.

unregister

public static ConstructionDelegate unregister(java.lang.Class<?> forType)
Useful for testing but should not be necessary, otherwise.

Parameters:
forType - Type for which a delegate, if it exists, will be removed.
Returns:
The delegate instance, if there is one, or null.

createAs

public static <B> B createAs(java.lang.Class<B> primaryType,
                             java.lang.Class<?>... additionalTypes)
Overload that narrows the new bean down to the primary type of interest and set the initial values.

Type Parameters:
B - The preferred return type.
Parameters:
primaryType - Class argument to fulfill the return type generic parameter.
additionalTypes - Optional, additional types this object will implement.
Returns:
An instance of the primary type that also extends all of the optionalTypes.

createAs

public static <B> B createAs(java.lang.Class<B> primaryType,
                             java.util.Map<java.lang.String,java.lang.Object> initialValues,
                             java.lang.Class<?>... additionalTypes)
Overload that narrows the new bean down to the primary type of interest and does not set any initial values.

Type Parameters:
B - The preferred return type.
Parameters:
primaryType - Class argument to fulfill the return type generic parameter.
initialValues - Initial property values the proxy will have, checked to see if they are valid.
additionalTypes - Optional, additional types this object will implement.
Returns:
An instance of the primary type that also extends all of the optionalTypes.

createAs

public static <B> B createAs(java.lang.Class<B> primaryType,
                             java.util.Map<java.lang.String,java.lang.Object> constructorArguments,
                             java.util.Map<java.lang.String,java.lang.Object> initialValues,
                             java.lang.Class<?>... additionalTypes)
Overload that narrows the new bean down to the primary type of interest and does not set any initial values.

Type Parameters:
B - The preferred return type.
Parameters:
primaryType - Class argument to fulfill the return type generic parameter.
constructorArguments - Not required, may be null; just passed to constructor delegates to provide an optional set of state for construction but not to be directly added to internal storage. If not supplied, the initial values argument will be passed to any ConstructionDelegate instances registered for the proxy's types, instead.
initialValues - Initial property values the proxy will have, checked to see if they are valid.
additionalTypes - Optional, additional types this object will implement.
Returns:
An instance of the primary type that also extends all of the optionalTypes.

create

public static java.lang.Object create(java.lang.Class<?>... allTypes)
Overload that does not set any initial values or constructor arguments.

Parameters:
allTypes - All of the interfaces the proxy will implement.
Returns:
A proxy that extends all of the specified types and has no initial property values.

create

public static java.lang.Object create(java.util.Map<java.lang.String,java.lang.Object> initialValues,
                                      java.lang.Class<?>[] allTypes)
Overload that uses the initial values to set the beans initial state and the same values to pass in as constructor arguments for any registered instances of ConstructionDelegate.

Parameters:
initialValues - Initial property values the proxy will have, checked to see if they are valid.
allTypes - All of the interfaces the proxy will implement.
Returns:
A proxy that extends all of the specified types and has the specified initial property values.

create

public static java.lang.Object create(java.util.Map<java.lang.String,java.lang.Object> constructorArguments,
                                      java.util.Map<java.lang.String,java.lang.Object> initialValues,
                                      java.lang.Class<?>[] allTypes)
Fully specified factory method for generating a new Navel backed dynamic proxy.

Parameters:
constructorArguments - Not required, may be null; just passed to constructor delegates to provide an optional set of state for construction but not to be directly added to internal storage. If not supplied, the initial values argument will be passed to any ConstructionDelegate instances registered for the proxy's types, instead.
initialValues - Initial property values the proxy will have, checked to see if they are valid.
allTypes - All of the interfaces the proxy will implement.
Returns:
A proxy that extends all of the specified types and has the specified initial property values.

additionalTypes

public static java.lang.Class<?>[] additionalTypes(java.lang.Class<?> primaryType,
                                                   java.lang.Class<?>[] secondaryTypes)
Find out for a set of interfaces what additional interfaces would be implemented were these types constructed and backed by a proxy.

Parameters:
primaryType - Required, the primary type of interest.
secondaryTypes - Optional, any additional types if known.
Returns:
Full array of types, useful to introspect in the absence of an already existing proxy.

viewAs

public static <T> T viewAs(java.lang.Class<T> primaryType,
                           java.lang.Object source,
                           java.lang.Class<?>... subTypes)
Overload that assumes shallow copy.

Type Parameters:
T - Desired interface, must be one the source proxy supports.
Parameters:
primaryType - For pegging the generic parameter.
source - Source to copy, performs a shallow copy.
subTypes - Subset of types out of all supported by the original.
Returns:
A copy of the original whose data is the subset supported by the new primary type and subTypes.

viewAs

public static <T> T viewAs(java.lang.Class<T> primaryType,
                           java.lang.Object source,
                           boolean deepCopy,
                           java.lang.Class<?>... subTypes)
Generates a view, as a copy, of the source that is a safe subset of the properties on the original.

Type Parameters:
T - Desired interface, must be one the source proxy supports.
Parameters:
primaryType - For pegging the generic parameter.
source - Source to copy.
deepCopy - Perform a deep copy if true, otherwise a shallow copy
subTypes - Subset of types out of all supported by the original.
Returns:
A copy of the original whose data is the subset supported by the new primary type and subTypes.

copyAs

public static <T> T copyAs(java.lang.Class<T> primaryType,
                           java.lang.Object source)
An overload that assumes shallow copy. Also performs a shallow copy of any property delegates, to keep synthetic properties consistent with the source. This means the new bean will share the exact same PropertyDelegate instances as the source, but those delegates should be stateless so should not be a problem.

Type Parameters:
T - Desired interface, must be one the source proxy supports.
Parameters:
primaryType - For pegging the generic parameter.
source - Source to copy, performs a shallow copy.
Returns:
A copy, safely type as T.

copyAs

public static <T> T copyAs(java.lang.Class<T> primaryType,
                           java.lang.Object source,
                           boolean deep)
A convenience version that also checks to see if the cast to T is safe, then casts and returns as T. Also performs a shallow copy of any property delegates, to keep synthetic properties consistent with the source. This means the new bean will share the exact same PropertyDelegate instances as the source, but those delegates should be stateless so should not be a problem.

Type Parameters:
T - Desired interface, must be one the source proxy supports.
Parameters:
primaryType - For pegging the generic parameter.
source - Source to copy, performs a shallow copy.
deep - Perform a deep copy.
Returns:
A copy, safely type as T.

copy

public static java.lang.Object copy(java.lang.Object source,
                                    boolean deep)
Performs a deep copy of all the proxy support code and a shallow copy of the internal bean state. Also performs a shallow copy of any property delegates, to keep synthetic properties consistent with the source. This means the new bean will share the exact same PropertyDelegate instances as the source, but those delegates should be stateless so should not be a problem.

Parameters:
source - Bean to copy, must be a Navel bean.
deep - Perform a deep copy.
Returns:
A copy of the original bean.

unmodifiableObjectAs

public static <T> T unmodifiableObjectAs(java.lang.Class<T> primaryType,
                                         java.lang.Object source)
Generic version that helps ensure type safety; the same adviso applie as the non-generic method.

Parameters:
source - Bean to copy, must be a Navel bean.
Returns:
An immutable copy of the original bean.
See Also:
unmodifiableObject(Object)

unmodifiableObject

public static java.lang.Object unmodifiableObject(java.lang.Object source)
Creates a new instance, that cannot be changed, which is a copy of all the proxy support code, a deep copy of the internal bean state, and a shallow copy of any property delegates, to keep synthetic properties consistent with the source. This means the new bean will share the exact same PropertyDelegate instances as the source, but those delegates should be stateless so should not be a problem. The immutable quality protects the internal PropertyValues which includes its collection of PropertyDelegate instnaces. Any attempts to change the value portion of the return object will throw an unchecked exception. Any attempt to alter the PropertyDelegate mapping will also cause an unchecked exception to be thrown as doing so would introduce an inconsistent view of the internal state. InterfaceDelegate instances may be attached and detached as this affects the behavior of the instance but not its state as such.

Parameters:
source - Bean to copy, must be a Navel bean.
Returns:
An immutable copy of the original bean.

isAttached

public static boolean isAttached(java.lang.Object bean,
                                 java.lang.Class<?> delegatingInterface)
Checks to see if there is a delegate for the specified interface.

Parameters:
bean - Proxy to check.
delegatingInterface - Interface to check.
Returns:
Whether there is a delegate for the specified interface.

isAttached

public static boolean isAttached(java.lang.Object bean,
                                 java.lang.String propertyName)
Checks to see if there is a delegate for the specified property.

Parameters:
bean - Proxy to check.
propertyName - Property to check.
Returns:
Whether there is a delegate for the specified property.

attach

public static void attach(java.lang.Object bean,
                          InterfaceDelegate delegate)
Utility method that exposes the runtime delegation attachment code.

Parameters:
bean - Target to which the delegate will be attached, if applicable.
delegate - Delegate to attach.

attach

public static void attach(java.lang.Object bean,
                          InterfaceDelegate... delegates)
Convenience method for attaching multiple delegates at once.

Parameters:
bean - Existing bean instance to which new delegates will be attached.
delegates - New delegates to attach.

attach

public static void attach(java.lang.Object bean,
                          java.lang.String propertyName,
                          PropertyDelegate<?> delegate)
Utility method that exposes the runtime delegation attachment code.

Parameters:
bean - Target to which the delegate will be attached, if applicable.
propertyName - Property this delegate should support.
delegate - Delegate to attach.

detach

public static boolean detach(java.lang.Object bean,
                             java.lang.Class<?> delegatingInterface)
Removes a delegate, if any, mapped to the specific interface. Useful, for instance, to participate in a State or Strategy pattern where at different times or under different conditions different delegates, or none at all, might be desirable.

Parameters:
bean - Bean from which the delegate should be detached.
delegatingInterface - If there is a delegate for this interface, remove it.
Returns:
Indicate whether a delegate was removed.

detach

public static boolean detach(java.lang.Object bean,
                             java.lang.String propertyName)
Removes a delegate, if any, mapped to the specific property. Useful, for instance, to participate in a State or Strategy pattern where at different times or under different conditions different delegates, or none at all, might be desirable.

Parameters:
bean - Bean from which the delegate should be detached.
propertyName - If there is a delegate for this property, remove it.
Returns:
Indicate whether a delegate was removed.

getHandler

public static JavaBeanHandler getHandler(java.lang.Object bean)
A convenience method to get the underlying Navel bean handler, if the passed in object is a Navel bean. The bean argument is tested and if any of the tests to figure out if it is a Navel bean fail, null is returned.

Parameters:
bean - Object to test for being a Navel bean.
Returns:
Null if the bean argument is not a Navel bean, otherwise, the Navel handler for the bean proxy.

getProxyDescriptor

public static ProxyDescriptor getProxyDescriptor(java.lang.Object bean)
Allows retrieval of the reflection information provided at construction time, including the primary interface out of all the supported interfaces.

Parameters:
bean - Must be a navel bean.
Returns:
The reflection descriptor for the proxy.