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 * Original code by                                                          *
009 *****************************************************************************/
010package org.picocontainer.gems.containers;
011
012import org.apache.commons.logging.Log;
013import org.apache.commons.logging.LogFactory;
014import org.picocontainer.ComponentAdapter;
015import org.picocontainer.Converters;
016import org.picocontainer.Converting;
017import org.picocontainer.MutablePicoContainer;
018import org.picocontainer.NameBinding;
019import org.picocontainer.Parameter;
020import org.picocontainer.PicoContainer;
021import org.picocontainer.PicoVisitor;
022import org.picocontainer.converters.ConvertsNothing;
023import org.picocontainer.lifecycle.LifecycleState;
024
025import java.io.Serializable;
026import java.lang.annotation.Annotation;
027import java.lang.reflect.Type;
028import java.util.Collection;
029import java.util.List;
030import java.util.Properties;
031
032/** @author Michael Rimov 
033 * @deprecated As of PicoContainer 2.3  ComponentMonitor now can do all jobs of tracing container.
034 */
035@Deprecated
036@SuppressWarnings("serial")
037public class CommonsLoggingTracingContainerDecorator implements MutablePicoContainer, Converting, Serializable {
038
039
040        /** Wrapped container. */
041    private final MutablePicoContainer delegate;
042
043    /** Logger instance used for writing events. */
044    private transient Log log;
045
046    /** Serialized log category. */
047    private final String logCategory;
048
049    /**
050     * Default typical wrapper that wraps another MutablePicoContainer.
051     *
052     * @param delegate Container to be decorated.
053     *
054     * @throws NullPointerException if delegate is null.
055     */
056    public CommonsLoggingTracingContainerDecorator(final MutablePicoContainer delegate) {
057        this(delegate, PicoContainer.class.getName());
058    }
059
060
061    /**
062     * Alternate constructor that allows specification of the Logger to
063     * use.
064     *
065     * @param delegate        Container to be decorated.
066     * @param loggingCategory specific Log4j Logger to use.
067     *
068     * @throws NullPointerException if delegate or log is null.
069     */
070    public CommonsLoggingTracingContainerDecorator(final MutablePicoContainer delegate, final String loggingCategory) {
071        if (delegate == null) {
072            throw new NullPointerException("delegate");
073        }
074
075        if (loggingCategory == null) {
076            throw new NullPointerException("loggingCategory");
077        }
078
079        log = LogFactory.getLog(loggingCategory);
080
081        this.delegate = delegate;
082        logCategory = loggingCategory;
083    }
084
085
086    /**
087     * Standard message handling for cases when a null object is returned
088     * for a given key.
089     *
090     * @param componentKey Component key that does not exist
091     * @param target Logger to log into
092     */
093    protected void onKeyOrTypeDoesNotExistInContainer(final Object componentKey, final Log target) {
094        log.info("Could not find component "
095                 + (componentKey instanceof Class ? ((Class)componentKey).getName() : componentKey)
096                 + " in container or parent container.");
097    }
098
099    /**
100     * {@inheritDoc}
101     *
102     * @param visitor
103     *
104     * @see org.picocontainer.PicoContainer#accept(org.picocontainer.PicoVisitor)
105     */
106    public void accept(final PicoVisitor visitor) {
107        if (log.isDebugEnabled()) {
108            log.debug("Visiting Container " + delegate
109                      + " with visitor " + visitor);
110        }
111        delegate.accept(visitor);
112    }
113
114    /**
115     * {@inheritDoc}
116     *
117     * @param child
118     *
119     * @return
120     *
121     * @see org.picocontainer.MutablePicoContainer#addChildContainer(org.picocontainer.PicoContainer)
122     */
123    public MutablePicoContainer addChildContainer(final PicoContainer child) {
124        if (log.isDebugEnabled()) {
125            log.debug("Adding child container: " + child + " to container " + delegate);
126        }
127        return delegate.addChildContainer(child);
128    }
129
130    /**
131     * {@inheritDoc}
132     *
133     * @see org.picocontainer.Disposable#dispose()
134     */
135    public void dispose() {
136        if (log.isDebugEnabled()) {
137            log.debug("Disposing container " + delegate);
138        }
139        delegate.dispose();
140    }
141
142    /**
143     * {@inheritDoc}
144     *
145     * @param componentKey
146     *
147     * @return
148     *
149     * @see org.picocontainer.PicoContainer#getComponentAdapter(java.lang.Object)
150     */
151    public ComponentAdapter<?> getComponentAdapter(final Object componentKey) {
152        if (log.isDebugEnabled()) {
153            log.debug("Locating component adapter with key " + componentKey);
154        }
155
156        ComponentAdapter adapter = delegate.getComponentAdapter(componentKey);
157        if (adapter == null) {
158            onKeyOrTypeDoesNotExistInContainer(componentKey, log);
159        }
160        return adapter;
161    }
162
163    /**
164     * {@inheritDoc}
165     *
166     * @param componentType
167     * @return ComponentAdapter or null.
168     * @see org.picocontainer.PicoContainer#getComponentAdapter(java.lang.Class, NameBinding)
169     */
170
171    public <T> ComponentAdapter<T> getComponentAdapter(final Class<T> componentType, final NameBinding componentNameBinding) {
172        if (log.isDebugEnabled()) {
173            log.debug("Locating component adapter with type " + componentType);
174        }
175
176        ComponentAdapter<T> ca = delegate.getComponentAdapter(componentType, componentNameBinding);
177
178        if (ca == null) {
179            onKeyOrTypeDoesNotExistInContainer(ca, log);
180        }
181        return ca;
182    }
183
184    /**
185     * {@inheritDoc}
186     *
187     * @return Collection or null.
188     *
189     * @see org.picocontainer.PicoContainer#getComponentAdapters()
190     */
191    public Collection<ComponentAdapter<?>> getComponentAdapters() {
192        if (log.isDebugEnabled()) {
193            log.debug("Grabbing all component adapters for container: " + delegate);
194        }
195        return delegate.getComponentAdapters();
196    }
197
198    /**
199     * {@inheritDoc}
200     *
201     * @param componentType
202     *
203     * @return List of ComponentAdapters
204     *
205     * @see org.picocontainer.PicoContainer#getComponentAdapters(java.lang.Class)
206     */
207    public <T>List<ComponentAdapter<T>> getComponentAdapters(final Class<T> componentType) {
208        if (log.isDebugEnabled()) {
209            log.debug("Grabbing all component adapters for container: "
210                      + delegate + " of type: " + componentType.getName());
211        }
212        return delegate.getComponentAdapters(componentType);
213    }
214
215    public <T> List<ComponentAdapter<T>> getComponentAdapters(final Class<T> componentType, final Class<? extends Annotation> binding) {
216        if (log.isDebugEnabled()) {
217            log.debug("Grabbing all component adapters for container: "
218                      + delegate + " of type: " + componentType.getName() + ", binding:" + binding.getName());
219        }
220        return delegate.getComponentAdapters(componentType, binding);
221    }
222
223    public <T> ComponentAdapter<T> getComponentAdapter(final Class<T> componentType, final Class<? extends Annotation> binding) {
224        if (log.isDebugEnabled()) {
225            log.debug("Grabbing component adapter for container: "
226                      + delegate + " of type: " + componentType.getName() + ", binding:" + binding.getName());
227        }
228        return delegate.getComponentAdapter(componentType, binding);
229    }
230
231    /**
232     * {@inheritDoc}
233     *
234     * @param componentKeyOrType
235     *
236     * @return
237     *
238     * @see org.picocontainer.PicoContainer#getComponent(java.lang.Object)
239     */
240    public Object getComponent(final Object componentKeyOrType) {
241
242        if (log.isDebugEnabled()) {
243            log.debug("Attempting to load component instance with "
244                      + (componentKeyOrType instanceof Class ? "type" : "key")
245                      + ": " + componentKeyOrType + " for container " + delegate);
246
247        }
248
249        Object result = delegate.getComponent(componentKeyOrType);
250        if (result == null) {
251            onKeyOrTypeDoesNotExistInContainer(componentKeyOrType, log);
252        }
253
254        return result;
255    }
256
257    public Object getComponent(final Object componentKeyOrType, final Type into) {
258        if (log.isDebugEnabled()) {
259            log.debug("Attempting to load component instance with "
260                      + (componentKeyOrType instanceof Class ? "type" : "key")
261                      + ": " + componentKeyOrType + " for container " + delegate);
262
263        }
264
265        Object result = delegate.getComponent(componentKeyOrType, into);
266        if (result == null) {
267            onKeyOrTypeDoesNotExistInContainer(componentKeyOrType, log);
268        }
269
270        return result;
271    }
272
273    public <T> T getComponent(final Class<T> componentType) {
274        return componentType.cast(getComponent((Object)componentType));
275    }
276
277    public <T> T getComponent(final Class<T> componentType, final Class<? extends Annotation> binding) {
278        if (log.isDebugEnabled()) {
279            log.debug("Grabbing component for container: "
280                      + delegate + " of type: " + componentType.getName() + ", binding:" + binding.getName());
281        }
282        return delegate.getComponent(componentType, binding);
283    }
284
285    /**
286     * {@inheritDoc}
287     *
288     * @return
289     *
290     * @see org.picocontainer.PicoContainer#getComponents()
291     */
292    public List getComponents() {
293        if (log.isDebugEnabled()) {
294            log.debug("Retrieving all component instances for container "
295                      + delegate);
296        }
297        return delegate.getComponents();
298    }
299
300    /**
301     * {@inheritDoc}
302     *
303     * @param componentType
304     *
305     * @return
306     *
307     * @see org.picocontainer.PicoContainer#getComponents(java.lang.Class)
308     */
309    public <T> List<T> getComponents(final Class<T> componentType) {
310        if (log.isDebugEnabled()) {
311            log.debug("Loading all component instances of type " + componentType
312                      + " for container " + delegate);
313        }
314        List<T> result = delegate.getComponents(componentType);
315        if (result == null || result.isEmpty()) {
316            if (log.isInfoEnabled()) {
317                log.info("Could not find any components  "
318                         + " in container or parent container.");
319            }
320        }
321
322        return result;
323    }
324
325    /**
326     * {@inheritDoc}
327     *
328     * @return
329     *
330     * @see org.picocontainer.PicoContainer#getParent()
331     */
332    public PicoContainer getParent() {
333        if (log.isDebugEnabled()) {
334            log.debug("Retrieving the parent for container " + delegate);
335        }
336
337        return delegate.getParent();
338    }
339
340    /**
341     * {@inheritDoc}
342     *
343     * @return
344     *
345     * @see org.picocontainer.MutablePicoContainer#makeChildContainer()
346     */
347    public MutablePicoContainer makeChildContainer() {
348        if (log.isDebugEnabled()) {
349            log.debug("Making child container for container " + delegate);
350        }
351
352        //Wrap the new delegate
353        return new Log4jTracingContainerDecorator(delegate.makeChildContainer());
354    }
355
356    /**
357     * {@inheritDoc}
358     *
359     * @param componentAdapter
360     *
361     * @return
362     *
363     * @see org.picocontainer.MutablePicoContainer#addAdapter(org.picocontainer.ComponentAdapter)
364     */
365    public MutablePicoContainer addAdapter(final ComponentAdapter componentAdapter) {
366        if (log.isDebugEnabled()) {
367            log.debug("Registering component adapter " + componentAdapter);
368        }
369
370        return delegate.addAdapter(componentAdapter);
371    }
372
373    /**
374     * {@inheritDoc}
375     *
376     * @param componentKey
377     * @param componentImplementationOrInstance
378     *
379     * @param parameters
380     *
381     * @return
382     */
383    public MutablePicoContainer addComponent(final Object componentKey, final Object componentImplementationOrInstance,
384                                             final Parameter... parameters)
385    {
386        if (log.isDebugEnabled()) {
387            log.debug("Registering component "
388                      + (componentImplementationOrInstance instanceof Class ? "implementation" : "instance")
389                      + " with key "
390                      + componentKey
391                      + " and implementation "
392                      + (componentImplementationOrInstance instanceof Class
393                         ? ((Class)componentImplementationOrInstance).getCanonicalName()
394                         : componentImplementationOrInstance.getClass())
395                      + " using parameters "
396                      + parameters);
397        }
398
399        return delegate.addComponent(componentKey, componentImplementationOrInstance, parameters);
400    }
401
402    /**
403     * {@inheritDoc}
404     *
405     * @param implOrInstance
406     *
407     * @return
408     *
409     * @see org.picocontainer.MutablePicoContainer#addComponent(java.lang.Object)
410     */
411    public MutablePicoContainer addComponent(final Object implOrInstance) {
412        if (log.isDebugEnabled()) {
413            log.debug("Registering component impl or instance "
414                      + implOrInstance + "(class: "
415                      + ((implOrInstance != null) ? implOrInstance.getClass().getName() : " null "));
416        }
417
418        return delegate.addComponent(implOrInstance);
419    }
420
421    public MutablePicoContainer addConfig(final String name, final Object val) {
422        if (log.isDebugEnabled()) {
423            log.debug("Registering config: " + name);
424        }
425
426        return delegate.addConfig(name, val);
427    }
428
429    /**
430     * {@inheritDoc}
431     *
432     * @param child
433     *
434     * @return
435     *
436     * @see org.picocontainer.MutablePicoContainer#removeChildContainer(org.picocontainer.PicoContainer)
437     */
438    public boolean removeChildContainer(final PicoContainer child) {
439        if (log.isDebugEnabled()) {
440            log.debug("Removing child container: " + child
441                      + " from parent: " + delegate);
442        }
443        return delegate.removeChildContainer(child);
444    }
445
446    /**
447     * {@inheritDoc}
448     *
449     * @see org.picocontainer.Startable#start()
450     */
451    public void start() {
452        if (log.isInfoEnabled()) {
453            log.info("Starting Container " + delegate);
454        }
455
456        delegate.start();
457    }
458
459    /**
460     * {@inheritDoc}
461     *
462     * @see org.picocontainer.Startable#stop()
463     */
464    public void stop() {
465        if (log.isInfoEnabled()) {
466            log.info("Stopping Container " + delegate);
467        }
468        delegate.stop();
469    }
470
471    /**
472     * {@inheritDoc}
473     *
474     * @param componentKey
475     *
476     * @return
477     *
478     * @see org.picocontainer.MutablePicoContainer#removeComponent(java.lang.Object)
479     */
480    public ComponentAdapter removeComponent(final Object componentKey) {
481        if (log.isDebugEnabled()) {
482            log.debug("Unregistering component " + componentKey + " from container " + delegate);
483        }
484
485        return delegate.removeComponent(componentKey);
486    }
487
488    /**
489     * {@inheritDoc}
490     *
491     * @param componentInstance
492     *
493     * @return
494     *
495     * @see org.picocontainer.MutablePicoContainer#removeComponentByInstance(java.lang.Object)
496     */
497    public ComponentAdapter removeComponentByInstance(final Object componentInstance) {
498        if (log.isDebugEnabled()) {
499            log.debug("Unregistering component by instance (" + componentInstance + ") from container " + delegate);
500        }
501
502        return delegate.removeComponentByInstance(componentInstance);
503    }
504
505
506    /**
507     * Retrieves the log instance used by this decorator.
508     *
509     * @return Logger instance.
510     */
511    public Log getLoggerUsed() {
512        return this.log;
513    }
514
515    private void readObject(final java.io.ObjectInputStream s)
516        throws java.io.IOException, java.lang.ClassNotFoundException {
517                s.defaultReadObject();                                    
518                log = LogFactory.getLog(this.logCategory);
519        }
520
521    public MutablePicoContainer change(final Properties... properties) {
522        return delegate.change(properties);
523    }
524
525    public MutablePicoContainer as(final Properties... properties) {
526        return delegate.as(properties);
527    }
528
529    public void setName(String name) {
530        delegate.setName(name);
531    }
532    
533    public String getName() {
534        return delegate.getName();
535    }
536    
537    public LifecycleState getLifecycleState() {
538        return delegate.getLifecycleState();
539    }
540
541    public void setLifecycleState(LifecycleState lifecycleState) {
542        delegate.setLifecycleState(lifecycleState);
543    }
544
545    /**
546     * {@inheritDoc} 
547     */
548    public Converters getConverters() {
549        if (delegate instanceof Converting) {
550            return ((Converting) delegate).getConverters();
551        }
552        return new ConvertsNothing();
553    }
554}