Example usage for java.lang.reflect Proxy getInvocationHandler

List of usage examples for java.lang.reflect Proxy getInvocationHandler

Introduction

In this page you can find the example usage for java.lang.reflect Proxy getInvocationHandler.

Prototype

@CallerSensitive
public static InvocationHandler getInvocationHandler(Object proxy) throws IllegalArgumentException 

Source Link

Document

Returns the invocation handler for the specified proxy instance.

Usage

From source file:org.wso2.carbon.apimgt.webapp.publisher.lifecycle.util.AnnotationProcessor.java

private Map<String, ApiScope> processAPIScopes(Annotation annotation) throws Throwable {
    Map<String, ApiScope> scopes = new HashMap<>();

    InvocationHandler methodHandler = Proxy.getInvocationHandler(annotation);
    Annotation[] annotatedScopes = (Annotation[]) methodHandler.invoke(annotation,
            scopesClass.getMethod(ANNOTATIONS_SCOPES, null), null);

    ApiScope scope;/*  w  w  w. j  a v a  2s .  com*/
    String permissions[];
    StringBuilder aggregatedPermissions;
    for (int i = 0; i < annotatedScopes.length; i++) {
        aggregatedPermissions = new StringBuilder();
        methodHandler = Proxy.getInvocationHandler(annotatedScopes[i]);
        scope = new ApiScope();
        scope.setName(invokeMethod(scopeClass.getMethod(SWAGGER_ANNOTATIONS_PROPERTIES_NAME),
                annotatedScopes[i], STRING));
        scope.setDescription(invokeMethod(scopeClass.getMethod(SWAGGER_ANNOTATIONS_PROPERTIES_DESCRIPTION),
                annotatedScopes[i], STRING));
        scope.setKey(invokeMethod(scopeClass.getMethod(SWAGGER_ANNOTATIONS_PROPERTIES_KEY), annotatedScopes[i],
                STRING));
        permissions = (String[]) methodHandler.invoke(annotatedScopes[i],
                scopeClass.getMethod(SWAGGER_ANNOTATIONS_PROPERTIES_PERMISSIONS, null), null);
        for (String permission : permissions) {
            aggregatedPermissions.append(PERMISSION_PREFIX);
            aggregatedPermissions.append(permission);
            aggregatedPermissions.append(" ");
        }
        scope.setRoles(aggregatedPermissions.toString().trim());
        scopes.put(scope.getKey(), scope);
    }
    return scopes;
}

From source file:com.msopentech.odatajclient.proxy.api.impl.BatchContainer.java

private int processEntityContext(final EntityTypeInvocationHandler handler, int pos,
        final TransactionItems items, final List<EntityLinkDesc> delayedUpdates,
        final ODataChangeset changeset) {

    LOG.debug("Process '{}'", handler);

    items.put(handler, null);//www  . j av a  2s . c om

    //TODO: this change hasn't been tested as Exchange server doesn't support Batch requests.
    //final ODataEntity entity = (ODataEntity) xstream.fromXML(xstream.toXML(handler.getEntity()));
    final ODataEntity entity = handler.getEntity();

    entity.getNavigationLinks().clear();

    final AttachedEntityStatus currentStatus = EntityContainerFactory.getContext().entityContext()
            .getStatus(handler);

    if (AttachedEntityStatus.DELETED != currentStatus) {
        entity.getProperties().clear();
        EngineUtils.addProperties(client, factory.getMetadata(), handler.getPropertyChanges(), entity);
    }

    for (Map.Entry<NavigationProperty, Object> property : handler.getLinkChanges().entrySet()) {
        final ODataLinkType type = Collection.class.isAssignableFrom(property.getValue().getClass())
                ? ODataLinkType.ENTITY_SET_NAVIGATION
                : ODataLinkType.ENTITY_NAVIGATION;

        final Set<EntityTypeInvocationHandler> toBeLinked = new HashSet<EntityTypeInvocationHandler>();
        final String serviceRoot = factory.getServiceRoot();

        for (Object proxy : type == ODataLinkType.ENTITY_SET_NAVIGATION ? (Collection) property.getValue()
                : Collections.singleton(property.getValue())) {

            final EntityTypeInvocationHandler target = (EntityTypeInvocationHandler) Proxy
                    .getInvocationHandler(proxy);

            final AttachedEntityStatus status;

            try {
                status = EntityContainerFactory.getContext().entityContext().getStatus(target);
            } catch (IllegalStateException e) {
                // this case takes place if we iterate through collection and current item does not have any changes
                // TODO find another way to look for changes in collection
                continue;
            }

            final URI editLink = target.getEntity().getEditLink();

            if ((status == AttachedEntityStatus.ATTACHED || status == AttachedEntityStatus.LINKED)
                    && !target.isChanged()) {
                entity.addLink(buildNavigationLink(property.getKey().name(),
                        URIUtils.getURI(serviceRoot, editLink.toASCIIString()), type));
            } else {
                if (!items.contains(target)) {
                    pos = processEntityContext(target, pos, items, delayedUpdates, changeset);
                    pos++;
                }

                final Integer targetPos = items.get(target);
                if (targetPos == null) {
                    // schedule update for the current object
                    LOG.debug("Schedule '{}' from '{}' to '{}'", type.name(), handler, target);
                    toBeLinked.add(target);
                } else if (status == AttachedEntityStatus.CHANGED) {
                    entity.addLink(buildNavigationLink(property.getKey().name(),
                            URIUtils.getURI(serviceRoot, editLink.toASCIIString()), type));
                } else {
                    // create the link for the current object
                    LOG.debug("'{}' from '{}' to (${}) '{}'", type.name(), handler, targetPos, target);

                    entity.addLink(
                            buildNavigationLink(property.getKey().name(), URI.create("$" + targetPos), type));
                }
            }
        }

        if (!toBeLinked.isEmpty()) {
            delayedUpdates.add(new EntityLinkDesc(property.getKey().name(), handler, toBeLinked, type));
        }
    }

    // insert into the batch
    LOG.debug("{}: Insert '{}' into the batch", pos, handler);
    batch(handler, entity, changeset);

    items.put(handler, pos);

    int startingPos = pos;

    if (handler.getEntity().isMediaEntity()) {

        // update media properties
        if (!handler.getPropertyChanges().isEmpty()) {
            final URI targetURI = currentStatus == AttachedEntityStatus.NEW ? URI.create("$" + startingPos)
                    : URIUtils.getURI(factory.getServiceRoot(),
                            handler.getEntity().getEditLink().toASCIIString());
            batchUpdate(handler, targetURI, entity, changeset);
            pos++;
            items.put(handler, pos);
        }

        // update media content
        if (handler.getStreamChanges() != null) {
            final URI targetURI = currentStatus == AttachedEntityStatus.NEW
                    ? URI.create("$" + startingPos + "/$value")
                    : URIUtils.getURI(factory.getServiceRoot(),
                            handler.getEntity().getEditLink().toASCIIString() + "/$value");

            batchUpdateMediaEntity(handler, targetURI, handler.getStreamChanges(), changeset);

            // update media info (use null key)
            pos++;
            items.put(null, pos);
        }
    }

    for (Map.Entry<String, InputStream> streamedChanges : handler.getStreamedPropertyChanges().entrySet()) {
        final URI targetURI = currentStatus == AttachedEntityStatus.NEW ? URI.create("$" + startingPos)
                : URIUtils.getURI(factory.getServiceRoot(),
                        EngineUtils.getEditMediaLink(streamedChanges.getKey(), entity).toASCIIString());

        batchUpdateMediaResource(handler, targetURI, streamedChanges.getValue(), changeset);

        // update media info (use null key)
        pos++;
        items.put(handler, pos);
    }

    return pos;
}

From source file:org.wso2.andes.server.management.JMXManagedObjectRegistry.java

public void start() throws IOException, ConfigurationException {

    CurrentActor.get().message(ManagementConsoleMessages.STARTUP());

    //check if system properties are set to use the JVM's out-of-the-box JMXAgent
    if (areOutOfTheBoxJMXOptionsSet()) {
        CurrentActor.get().message(ManagementConsoleMessages.READY(true));
        return;//from  ww  w. j  a  va2 s .com
    }

    IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
    int port = appRegistry.getConfiguration().getJMXManagementPort();

    //Socket factories for the RMIConnectorServer, either default or SLL depending on configuration
    RMIClientSocketFactory csf;
    RMIServerSocketFactory ssf;

    //check ssl enabled option in config, default to true if option is not set
    boolean sslEnabled = appRegistry.getConfiguration().getManagementSSLEnabled();

    if (sslEnabled) {
        //set the SSL related system properties used by the SSL RMI socket factories to the values
        //given in the configuration file, unless command line settings have already been specified
        String keyStorePath;

        if (System.getProperty("javax.net.ssl.keyStore") != null) {
            keyStorePath = System.getProperty("javax.net.ssl.keyStore");
        } else {
            keyStorePath = appRegistry.getConfiguration().getManagementKeyStorePath();
        }

        //check the keystore path value is valid
        if (keyStorePath == null) {
            throw new ConfigurationException("JMX management SSL keystore path not defined, "
                    + "unable to start SSL protected JMX ConnectorServer");
        } else {
            //ensure the system property is set
            System.setProperty("javax.net.ssl.keyStore", keyStorePath);

            //check the file is usable
            File ksf = new File(keyStorePath);

            if (!ksf.exists()) {
                throw new FileNotFoundException("Cannot find JMX management SSL keystore file " + ksf + "\n"
                        + "Check broker configuration, or see create-example-ssl-stores script"
                        + "in the bin/ directory if you need to generate an example store.");
            }
            if (!ksf.canRead()) {
                throw new FileNotFoundException(
                        "Cannot read JMX management SSL keystore file: " + ksf + ". Check permissions.");
            }

            CurrentActor.get().message(ManagementConsoleMessages.SSL_KEYSTORE(ksf.getAbsolutePath()));
        }

        //check the key store password is set
        if (System.getProperty("javax.net.ssl.keyStorePassword") == null) {

            if (appRegistry.getConfiguration().getManagementKeyStorePassword() == null) {
                throw new ConfigurationException("JMX management SSL keystore password not defined, "
                        + "unable to start requested SSL protected JMX server");
            } else {
                System.setProperty("javax.net.ssl.keyStorePassword",
                        appRegistry.getConfiguration().getManagementKeyStorePassword());
            }
        }

        //create the SSL RMI socket factories
        csf = new SslRMIClientSocketFactory();
        ssf = new SslRMIServerSocketFactory();
    } else {
        //Do not specify any specific RMI socket factories, resulting in use of the defaults.
        csf = null;
        ssf = null;
    }

    //add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server
    RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator();
    rmipa.setAuthenticationManager(appRegistry.getAuthenticationManager());
    HashMap<String, Object> env = new HashMap<String, Object>();
    env.put(JMXConnectorServer.AUTHENTICATOR, rmipa);

    /*
     * Start a RMI registry on the management port, to hold the JMX RMI ConnectorServer stub. 
     * Using custom socket factory to prevent anyone (including us unfortunately) binding to the registry using RMI.
     * As a result, only binds made using the object reference will succeed, thus securing it from external change. 
     */
    System.setProperty("java.rmi.server.randomIDs", "true");
    if (_useCustomSocketFactory) {
        _rmiRegistry = LocateRegistry.createRegistry(port, null, new CustomRMIServerSocketFactory());
    } else {
        _rmiRegistry = LocateRegistry.createRegistry(port, null, null);
    }

    CurrentActor.get().message(ManagementConsoleMessages.LISTENING("RMI Registry", port));

    /*
     * We must now create the RMI ConnectorServer manually, as the JMX Factory methods use RMI calls 
     * to bind the ConnectorServer to the registry, which will now fail as for security we have
     * locked it from any RMI based modifications, including our own. Instead, we will manually bind 
     * the RMIConnectorServer stub to the registry using its object reference, which will still succeed.
     * 
     * The registry is exported on the defined management port 'port'. We will export the RMIConnectorServer
     * on 'port +1'. Use of these two well-defined ports will ease any navigation through firewall's. 
     */
    final RMIServerImpl rmiConnectorServerStub = new RMIJRMPServerImpl(port + PORT_EXPORT_OFFSET, csf, ssf,
            env);
    String localHost;
    try {
        localHost = InetAddress.getLocalHost().getHostName();
    } catch (UnknownHostException ex) {
        localHost = "127.0.0.1";
    }
    final String hostname = localHost;
    final JMXServiceURL externalUrl = new JMXServiceURL("service:jmx:rmi://" + hostname + ":"
            + (port + PORT_EXPORT_OFFSET) + "/jndi/rmi://" + hostname + ":" + port + "/jmxrmi");

    final JMXServiceURL internalUrl = new JMXServiceURL("rmi", hostname, port + PORT_EXPORT_OFFSET);
    _cs = new RMIConnectorServer(internalUrl, env, rmiConnectorServerStub, _mbeanServer) {
        @Override
        public synchronized void start() throws IOException {
            try {
                //manually bind the connector server to the registry at key 'jmxrmi', like the out-of-the-box agent                        
                _rmiRegistry.bind("jmxrmi", rmiConnectorServerStub);
            } catch (AlreadyBoundException abe) {
                //key was already in use. shouldnt happen here as its a new registry, unbindable by normal means.

                //IOExceptions are the only checked type throwable by the method, wrap and rethrow
                IOException ioe = new IOException(abe.getMessage());
                ioe.initCause(abe);
                throw ioe;
            }

            //now do the normal tasks
            super.start();
        }

        @Override
        public synchronized void stop() throws IOException {
            try {
                if (_rmiRegistry != null) {
                    _rmiRegistry.unbind("jmxrmi");
                }
            } catch (NotBoundException nbe) {
                //ignore
            }

            //now do the normal tasks
            super.stop();
        }

        @Override
        public JMXServiceURL getAddress() {
            //must return our pre-crafted url that includes the full details, inc JNDI details
            return externalUrl;
        }

    };

    //Add the custom invoker as an MBeanServerForwarder, and start the RMIConnectorServer.
    MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance();
    _cs.setMBeanServerForwarder(mbsf);

    NotificationFilterSupport filter = new NotificationFilterSupport();
    filter.enableType(JMXConnectionNotification.OPENED);
    filter.enableType(JMXConnectionNotification.CLOSED);
    filter.enableType(JMXConnectionNotification.FAILED);
    // Get the handler that is used by the above MBInvocationHandler Proxy.
    // which is the MBeanInvocationHandlerImpl and so also a NotificationListener
    _cs.addNotificationListener((NotificationListener) Proxy.getInvocationHandler(mbsf), filter, null);

    _cs.start();

    String connectorServer = (sslEnabled ? "SSL " : "") + "JMX RMIConnectorServer";
    CurrentActor.get().message(ManagementConsoleMessages.LISTENING(connectorServer, port + PORT_EXPORT_OFFSET));

    CurrentActor.get().message(ManagementConsoleMessages.READY(false));
}

From source file:org.springmodules.xt.model.generator.factory.FactoryGeneratorInterceptor.java

private int doHashCode(Object proxy) {
    return Proxy.getInvocationHandler(proxy).hashCode();
}

From source file:org.kuali.kra.questionnaire.QuestionnaireLookupableHelperServiceTest.java

/**
 * //  w ww  .j  av  a  2 s  .c  o m
 * This method to test getCustomActionUrls for someone with no permission to modify/view questionnaire.
 * @throws Exception
 */
@Test
public void testCustomActionUrlWithNoPermission() throws Throwable {
    final QuestionnaireAuthorizationService questionnaireAuthorizationService = context
            .mock(QuestionnaireAuthorizationService.class);
    Method m = QuestionnaireLookupableHelperServiceImpl.class.getMethod("setQuestionnaireAuthorizationService",
            QuestionnaireAuthorizationService.class);
    Proxy.getInvocationHandler(questionnaireLookupableHelperServiceImpl).invoke(
            questionnaireLookupableHelperServiceImpl, m, new Object[] { questionnaireAuthorizationService });

    context.checking(new Expectations() {
        {
            one(questionnaireAuthorizationService).hasPermission(PermissionConstants.MODIFY_QUESTIONNAIRE);
            will(returnValue(false));
            one(questionnaireAuthorizationService).hasPermission(PermissionConstants.VIEW_QUESTIONNAIRE);
            will(returnValue(false));
        }
    });

    MaintenanceDocumentBase maintDocument = (MaintenanceDocumentBase) documentService
            .getNewDocument(KcServiceLocator.getService(MaintenanceDocumentDictionaryService.class)
                    .getDocumentTypeName(Questionnaire.class));
    maintDocument.getDocumentHeader().setDocumentDescription("test 1");
    maintDocument.getNewMaintainableObject().setBusinessObject(createQuestionnaire("test1", "desc 1"));
    maintDocument.getNewMaintainableObject().setMaintenanceAction(KRADConstants.MAINTENANCE_NEW_ACTION);
    documentService.routeDocument(maintDocument, null, null);
    // not sure why it is not persisted in DB.  also need to do this save, so getcustomactionurls can retrieve it with bos
    Questionnaire questionnaire = (Questionnaire) maintDocument.getNewMaintainableObject().getDataObject();
    questionnaire.setDocumentNumber(maintDocument.getDocumentNumber());
    KNSServiceLocator.getBusinessObjectService()
            .save((Questionnaire) maintDocument.getNewMaintainableObject().getDataObject());
    List pkNames = new ArrayList();
    pkNames.add("id");

    List<HtmlData> htmldata = questionnaireLookupableHelperServiceImpl
            .getCustomActionUrls(maintDocument.getNewMaintainableObject().getBusinessObject(), pkNames);
    Assert.assertEquals(htmldata.size(), 0);
}

From source file:org.springmodules.xt.model.generator.factory.FactoryGeneratorInterceptor.java

private String doToString(Object proxy) {
    return Proxy.getInvocationHandler(proxy).toString();
}

From source file:com.msopentech.odatajclient.proxy.api.impl.Container.java

private int processEntityContext(final EntityTypeInvocationHandler handler, int pos,
        final TransactionItems items, final List<EntityLinkDesc> delayedUpdates,
        final ODataChangeset changeset) {

    LOG.debug("Process '{}'", handler);

    items.put(handler, null);//from w ww. jav a2  s.  co  m

    final ODataEntity entity = handler.getEntity();
    entity.getNavigationLinks().clear();

    final AttachedEntityStatus currentStatus = EntityContainerFactory.getContext().entityContext()
            .getStatus(handler);

    if (AttachedEntityStatus.DELETED != currentStatus) {
        entity.getProperties().clear();
        EngineUtils.addProperties(client, factory.getMetadata(), handler.getPropertyChanges(), entity);
    }

    for (Map.Entry<NavigationProperty, Object> property : handler.getLinkChanges().entrySet()) {
        final ODataLinkType type = Collection.class.isAssignableFrom(property.getValue().getClass())
                ? ODataLinkType.ENTITY_SET_NAVIGATION
                : ODataLinkType.ENTITY_NAVIGATION;

        final Set<EntityTypeInvocationHandler> toBeLinked = new HashSet<EntityTypeInvocationHandler>();
        final String serviceRoot = factory.getServiceRoot();

        for (Object proxy : type == ODataLinkType.ENTITY_SET_NAVIGATION ? (Collection) property.getValue()
                : Collections.singleton(property.getValue())) {

            final EntityTypeInvocationHandler target = (EntityTypeInvocationHandler) Proxy
                    .getInvocationHandler(proxy);

            final AttachedEntityStatus status = EntityContainerFactory.getContext().entityContext()
                    .getStatus(target);

            final URI editLink = target.getEntity().getEditLink();

            if ((status == AttachedEntityStatus.ATTACHED || status == AttachedEntityStatus.LINKED)
                    && !target.isChanged()) {
                entity.addLink(buildNavigationLink(property.getKey().name(),
                        URIUtils.getURI(serviceRoot, editLink.toASCIIString()), type));
            } else {
                if (!items.contains(target)) {
                    pos = processEntityContext(target, pos, items, delayedUpdates, changeset);
                    pos++;
                }

                final Integer targetPos = items.get(target);
                if (targetPos == null) {
                    // schedule update for the current object
                    LOG.debug("Schedule '{}' from '{}' to '{}'", type.name(), handler, target);
                    toBeLinked.add(target);
                } else if (status == AttachedEntityStatus.CHANGED) {
                    entity.addLink(buildNavigationLink(property.getKey().name(),
                            URIUtils.getURI(serviceRoot, editLink.toASCIIString()), type));
                } else {
                    // create the link for the current object
                    LOG.debug("'{}' from '{}' to (${}) '{}'", type.name(), handler, targetPos, target);

                    entity.addLink(
                            buildNavigationLink(property.getKey().name(), URI.create("$" + targetPos), type));
                }
            }
        }

        if (!toBeLinked.isEmpty()) {
            delayedUpdates.add(new EntityLinkDesc(property.getKey().name(), handler, toBeLinked, type));
        }
    }

    // insert into the batch
    LOG.debug("{}: Insert '{}' into the batch", pos, handler);
    batch(handler, entity, changeset);

    items.put(handler, pos);

    int startingPos = pos;

    if (handler.getEntity().isMediaEntity()) {

        // update media properties
        if (!handler.getPropertyChanges().isEmpty()) {
            final URI targetURI = currentStatus == AttachedEntityStatus.NEW ? URI.create("$" + startingPos)
                    : URIUtils.getURI(factory.getServiceRoot(),
                            handler.getEntity().getEditLink().toASCIIString());
            batchUpdate(handler, targetURI, entity, changeset);
            pos++;
            items.put(handler, pos);
        }

        // update media content
        if (handler.getStreamChanges() != null) {
            final URI targetURI = currentStatus == AttachedEntityStatus.NEW
                    ? URI.create("$" + startingPos + "/$value")
                    : URIUtils.getURI(factory.getServiceRoot(),
                            handler.getEntity().getEditLink().toASCIIString() + "/$value");

            batchUpdateMediaEntity(handler, targetURI, handler.getStreamChanges(), changeset);

            // update media info (use null key)
            pos++;
            items.put(null, pos);
        }
    }

    for (Map.Entry<String, InputStream> streamedChanges : handler.getStreamedPropertyChanges().entrySet()) {
        final URI targetURI = currentStatus == AttachedEntityStatus.NEW ? URI.create("$" + startingPos)
                : URIUtils.getURI(factory.getServiceRoot(),
                        EngineUtils.getEditMediaLink(streamedChanges.getKey(), entity).toASCIIString());

        batchUpdateMediaResource(handler, targetURI, streamedChanges.getValue(), changeset);

        // update media info (use null key)
        pos++;
        items.put(handler, pos);
    }

    return pos;
}

From source file:org.apache.camel.component.cxf.CxfEndpoint.java

/**
 * Create a CXF client object//from w ww .ja v a 2s.c  om
 */
Client createClient() throws Exception {

    // get service class
    if (getDataFormat().equals(DataFormat.POJO)) {
        ObjectHelper.notEmpty(getServiceClass(), CxfConstants.SERVICE_CLASS);
    }

    Class<?> cls = null;
    if (getServiceClass() != null) {
        cls = ClassLoaderUtils.loadClass(getServiceClass(), getClass());
        // create client factory bean
        ClientProxyFactoryBean factoryBean = createClientFactoryBean(cls);
        // setup client factory bean
        setupClientFactoryBean(factoryBean, cls);
        return ((ClientProxy) Proxy.getInvocationHandler(factoryBean.create())).getClient();
    } else {
        checkName(portName, "endpoint/port name");
        checkName(serviceName, "service name");
        ClientFactoryBean factoryBean = createClientFactoryBean();
        // setup client factory bean
        setupClientFactoryBean(factoryBean);
        return factoryBean.create();
    }

}

From source file:org.wso2.carbon.apimgt.webapp.publisher.lifecycle.util.AnnotationUtil.java

/**
 * When an annotation and method is passed, this method invokes that executes said method against the annotation
 *//*from  ww w. j  av a  2s .c  o m*/
private String[] invokeMethod(Method method, Annotation annotation) throws Throwable {
    InvocationHandler methodHandler = Proxy.getInvocationHandler(annotation);
    return ((String[]) methodHandler.invoke(annotation, method, null));
}

From source file:org.apache.olingo.ext.proxy.commons.EntityInvocationHandler.java

@Override
public void addAnnotation(final Class<? extends AbstractTerm> term, final Object value) {
    this.annotations.put(term, value);

    if (value != null) {
        Collection<?> coll;
        if (Collection.class.isAssignableFrom(value.getClass())) {
            coll = Collection.class.cast(value);
        } else {//from  w  w w . j a v  a 2  s  .c  o  m
            coll = Collections.singleton(value);
        }

        for (Object item : coll) {
            if (item instanceof Proxy) {
                final InvocationHandler handler = Proxy.getInvocationHandler(item);
                if ((handler instanceof ComplexInvocationHandler)
                        && ((ComplexInvocationHandler) handler).getEntityHandler() == null) {
                    ((ComplexInvocationHandler) handler).setEntityHandler(this);
                }
            }
        }
    }

    attach(AttachedEntityStatus.CHANGED);
}