All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.picocontainer.gems.adapters.DelegateMethodAdapter Maven / Gradle / Ivy

/*****************************************************************************
 * Copyright (C) PicoContainer Organization. All rights reserved.            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *                                                                           *
 * Original code by Centerline Computers, Inc.                               *
 *****************************************************************************/
package org.picocontainer.gems.adapters;

import java.lang.reflect.Type;

import org.picocontainer.ComponentAdapter;
import org.picocontainer.ComponentMonitor;
import org.picocontainer.PicoCompositionException;
import org.picocontainer.PicoContainer;
import org.picocontainer.PicoVisitor;
import org.picocontainer.gems.util.DelegateMethod;

/**
 * Object construction is sometimes expensive, especially when it is seldom used
 * object. The goal of this adapter is to use the
 * {@link org.picocontainer.gems.util.DelegateMethod} type to allow delayed
 * construction of objects.
 * 

* For example, in a web application, to be able to have classes that depend on * the HttpSession object, you would have to call * HttpServletRequest.getSession(true). This is fine unless you don't want to * create a session until you absolutely have to. *

*

* Enter DelegateMethodAdapter: *

* *
 * //Assumed Variables: request == HttpServletRequest.
 * //Typical PicoContainer
 * MutablePicoContainer pico = new PicoBuilder().withLifecycle().withCaching()
 * 		.build();
 * 
 * //Create a delegate method that will invoke HttpServletRequest.getSession(true) when invoke() is called.
 * DelegateMethod delegateMethod = new DelegateMethod(HttpServletRequest.class,
 * 		"getSession", true);
 * 
 * //Create the Adapter wrapping the delegate method.  
 * DelegateMethodAdapter methodAdapter = new DelegateMethodAdapter(
 * 		HttpSession.class, request, delegateMethod);
 * pico.addAdapter(methodAdapter);
 * 
 * //If only executing this code, the HttpSession should not be created yet.
 * assertNull(request.getSession(false));
 * 
 * //Will get the session object by having the delegate method call HttpServletRequest.getSession(true)
 * HttpSession session = pico.getComponent(HttpSession.class);
 * assertNotNull(session);
 * 
 * //Should demonstrate that the session has now been created.
 * assertNotNull(request.getSession(false));
 * 
* *

* With an adapter like this, you can write classes like: *

* *
 * public class SessionUser {
 * 	public SessionUser(HttpSession session) {
 * 		//.....
 * 	}
 * }
 * 
* *

* With impunity, and are guaranteed that the session would not be created * unless the SessionUser object was constructed. *

* * @author Michael Rimov */ public class DelegateMethodAdapter implements ComponentAdapter { /** * The delegate method instance that will ultimately invoke via reflection some method * on targetInstance. */ private final DelegateMethod factoryMethod; /** * The target instance on which the delegate method's invoke() call will operate. */ private final Object targetInstance; /** * Object key. */ private final Object key; /** * @param componentKey * @param Component * Implementation will be the expected return type of the factory * method. */ public DelegateMethodAdapter(final Object componentKey, final Object targetInstance, final DelegateMethod factoryMethod) { this.factoryMethod = factoryMethod; this.targetInstance = targetInstance; this.key = componentKey; } /** * @param componentKey * @param componentImplementation * @param monitor */ public DelegateMethodAdapter(final Object componentKey, final ComponentMonitor monitor, final Object targetInstance, final DelegateMethod factoryMethod) { this.factoryMethod = factoryMethod; this.targetInstance = targetInstance; this.key = componentKey; } /** * Returns the */ public T getComponentInstance(final PicoContainer container, final Type into) throws PicoCompositionException { try { return (T) factoryMethod.invoke(targetInstance); } catch (RuntimeException e) { throw new PicoCompositionException( "Error invoking delegate for object construction", e); } } /** * {@inheritDoc} * * @see org.picocontainer.ComponentAdapter#getDescriptor() */ public String getDescriptor() { return "Delegate Adapter. Delegate: " + this.factoryMethod.toString(); } /** {@inheritDoc} **/ public void verify(final PicoContainer container) throws PicoCompositionException { // Currently does nothing. } /** {@inheritDoc} **/ public void accept(final PicoVisitor visitor) { visitor.visitComponentAdapter(this); } /** {@inheritDoc} **/ public ComponentAdapter findAdapterOfType(final Class adapterType) { if (adapterType == null) { return null; } if (DelegateMethodAdapter.class.isAssignableFrom(adapterType)) { return this; } return null; } /** {@inheritDoc} **/ @SuppressWarnings("unchecked") public Class getComponentImplementation() { return this.factoryMethod.getReturnType(); } /** {@inheritDoc} **/ @Deprecated public T getComponentInstance(final PicoContainer container) throws PicoCompositionException { return getComponentInstance(container, null); } /** {@inheritDoc} **/ public Object getComponentKey() { return key; } /** * No delegates. */ public ComponentAdapter getDelegate() { return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy