001 /***************************************************************************** 002 * Copyright (C) PicoContainer Organization. All rights reserved. * 003 * ------------------------------------------------------------------------- * 004 * The software in this package is published under the terms of the BSD * 005 * style license a copy of which has been included with this distribution in * 006 * the LICENSE.txt file. * 007 * * 008 *****************************************************************************/ 009 package org.picocontainer.injectors; 010 011 import org.picocontainer.*; 012 import org.picocontainer.behaviors.Cached; 013 import org.picocontainer.lifecycle.NullLifecycleStrategy; 014 015 import java.lang.reflect.Method; 016 import java.lang.reflect.Type; 017 import java.util.Properties; 018 019 /** 020 * Providers are a type of Injector that can participate in Injection via a custom method. 021 * 022 * Implementers of this class must implement a single method called provide. That method must return 023 * the component type intended to be provided. The method can accept parameters that PicoContainer 024 * will satisfy. 025 */ 026 public class ProviderAdapter implements org.picocontainer.Injector, Provider, LifecycleStrategy { 027 028 private final Object provider; 029 private final Method provideMethod; 030 private final Class key; 031 private Properties properties; 032 private LifecycleStrategy lifecycleStrategy; 033 034 protected ProviderAdapter() { 035 provider = this; 036 provideMethod = getProvideMethod(this.getClass()); 037 key = provideMethod.getReturnType(); 038 setUseNames(useNames()); 039 } 040 041 public ProviderAdapter(LifecycleStrategy lifecycleStrategy, Object provider) { 042 this(lifecycleStrategy, provider, false); 043 } 044 045 public ProviderAdapter(Object provider) { 046 this(new NullLifecycleStrategy(), provider, false); 047 } 048 049 public ProviderAdapter(Object provider, boolean useNames) { 050 this(new NullLifecycleStrategy(), provider, useNames); 051 } 052 053 public ProviderAdapter(LifecycleStrategy lifecycleStrategy, Object provider, boolean useNames) { 054 this.lifecycleStrategy = lifecycleStrategy; 055 this.provider = provider; 056 provideMethod = getProvideMethod(provider.getClass()); 057 key = provideMethod.getReturnType(); 058 setUseNames(useNames); 059 } 060 061 062 private void setUseNames(boolean b) { 063 if (b) { 064 properties = Characteristics.USE_NAMES; 065 } else { 066 properties = Characteristics.NONE; 067 } 068 } 069 070 protected boolean useNames() { 071 return false; 072 } 073 074 public Object decorateComponentInstance(PicoContainer container, Type into, Object instance) { 075 return null; 076 } 077 078 public Object getComponentKey() { 079 return key; 080 } 081 082 public Class getComponentImplementation() { 083 return key; 084 } 085 086 @Deprecated 087 public Object getComponentInstance(PicoContainer container) throws PicoCompositionException { 088 return getComponentInstance(container, NOTHING.class); 089 } 090 091 public Object getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { 092 return new Reinjector(container).reinject(key, provider.getClass(), provider, properties, new MethodInjection(provideMethod)); 093 } 094 095 public static Method getProvideMethod(Class clazz) { 096 Method provideMethod = null; 097 // TODO doPrivileged 098 for (Method method : clazz.getDeclaredMethods()) { 099 if (method.getName().equals("provide")) { 100 if (provideMethod != null) { 101 throw newProviderMethodException("only one"); 102 } 103 provideMethod = method; 104 } 105 } 106 if (provideMethod == null) { 107 throw newProviderMethodException("a"); 108 } 109 if (provideMethod.getReturnType() == void.class) { 110 throw newProviderMethodException("a non void returning"); 111 } 112 return provideMethod; 113 } 114 115 private static PicoCompositionException newProviderMethodException(String str) { 116 return new PicoCompositionException("There must be "+ str +" method named 'provide' in the AbstractProvider implementation"); 117 } 118 119 public void verify(PicoContainer container) throws PicoCompositionException { 120 } 121 122 public void accept(PicoVisitor visitor) { 123 } 124 125 public ComponentAdapter getDelegate() { 126 return null; 127 } 128 129 public ComponentAdapter findAdapterOfType(Class adapterType) { 130 return null; 131 } 132 133 public String getDescriptor() { 134 return "ProviderAdapter"; 135 } 136 137 public void start(Object component) { 138 lifecycleStrategy.start(component); 139 } 140 141 public void stop(Object component) { 142 lifecycleStrategy.stop(component); 143 } 144 145 public void dispose(Object component) { 146 lifecycleStrategy.dispose(component); 147 } 148 149 150 public boolean hasLifecycle(Class<?> type) { 151 return lifecycleStrategy.hasLifecycle(type); 152 } 153 154 public boolean isLazy(ComponentAdapter<?> adapter) { 155 return lifecycleStrategy.isLazy(adapter); 156 } 157 }