Class DuckWrapper

  • All Implemented Interfaces:
    InvocationHandler

    public class DuckWrapper
    extends Object
    implements InvocationHandler
    Proxy wrapper for duck typing in Java.

    Duck typing is named for the old saying that ‘if it quacks like a duck, it must be a duck’. In dynamically typed languages like JavaScript, method handles are resolved at runtime so any object implementing the appropriate methods can be used.

    This class creates a Proxy that forwards interface methods to the given wrapped object. This allows you to ‘fake’ an interface implementation where you don’t have control over the class’s source code.

    If the object being wrapped doesn’t have a method matching something in your interface, it will just be ignored. Invoking the method will always return null with any arguments.

    Some examples:

    1. Many SailPointObjects have a getAttributes(), but those classes don’t implement a common interface. As a developer, you don’t have access to modify SailPoint’s API classes. To simplify your own code, you could create an AttributesContainer interface and use this class to coerce the SailPointObject to that interface.

    2. IIQ has two different nearly-identical versions of WebServicesClient. One is inaccessible except through the connector classloader. You could construct an instance of the inaccessible client class, exposing any relevant methods to your application via your own interface.

    • Method Detail

      • wrap

        public static <T> T wrap​(Class<? super T> intf,
                                 Object input)
                          throws sailpoint.tools.GeneralException
        Wraps the given object so that it appears to implement the given interface.

        Any calls to the interface methods will forward to the most appropriate method on the object.

        Type Parameters:
        T - The resulting type
        Parameters:
        intf - The interface the resulting proxy needs to implement
        input - The target object to be wrapped within the proxy
        Returns:
        A proxy to the underlying object that appears to implement the given interface
        Throws:
        sailpoint.tools.GeneralException - if any failures occur establishing the proxy
      • wrap

        public static <T> T wrap​(Class<? super T> intf,
                                 Object input,
                                 BiConsumer<Method,​MethodHandle> callback)
                          throws sailpoint.tools.GeneralException
        Wraps the given object in the given interface.

        Any calls to the interface methods will forward to the object.

        Type Parameters:
        T - The resulting type
        Parameters:
        intf - The interface the resulting proxy needs to implement
        input - The target object to be wrapped within the proxy
        callback - An optional callback that will be invoked for every method called (for testing)
        Returns:
        A proxy to the underlying object that appears to implement the given interface
        Throws:
        sailpoint.tools.GeneralException - if any failures occur establishing the proxy