001    /*******************************************************************************
002     * Copyright (C) PicoContainer Organization. All rights reserved.
003     * ---------------------------------------------------------------------------
004     * The software in this package is published under the terms of the BSD style
005     * license a copy of which has been included with this distribution in the
006     * LICENSE.txt file.
007     ******************************************************************************/
008    package org.picocontainer.script;
009    
010    import org.picocontainer.BehaviorFactory;
011    import org.picocontainer.ComponentFactory;
012    import org.picocontainer.DefaultPicoContainer;
013    import org.picocontainer.MutablePicoContainer;
014    import org.picocontainer.PicoBuilder;
015    import org.picocontainer.PicoContainer;
016    import org.picocontainer.ComponentMonitor;
017    import org.picocontainer.PicoClassNotFoundException;
018    import org.picocontainer.InjectionFactory;
019    import org.picocontainer.classname.ClassLoadingPicoContainer;
020    import org.picocontainer.classname.DefaultClassLoadingPicoContainer;
021    import org.picocontainer.containers.TransientPicoContainer;
022    
023    /**
024     * Facade to build ScriptedScriptedPicoContainer
025     *
026     * @author Paul Hammant
027     */
028    public final class ScriptedBuilder {
029    
030        private Class<? extends ClassLoadingPicoContainer> scriptClass = DefaultClassLoadingPicoContainer.class;
031        private final PicoBuilder picoBuilder;
032        private ClassLoader classLoader = DefaultClassLoadingPicoContainer.class.getClassLoader();
033    
034        public ScriptedBuilder(PicoContainer parentcontainer, InjectionFactory injectionType) {
035            picoBuilder = new PicoBuilder(parentcontainer, injectionType);
036        }
037    
038        public ScriptedBuilder(PicoContainer parentcontainer) {
039            picoBuilder = new PicoBuilder(parentcontainer);
040        }
041    
042        public ScriptedBuilder(InjectionFactory injectionType) {
043            picoBuilder = new PicoBuilder(injectionType);
044        }
045    
046        public ScriptedBuilder() {
047            picoBuilder = new PicoBuilder();
048        }
049    
050        public ClassLoadingPicoContainer build() {
051            DefaultPicoContainer tpc = new TransientPicoContainer();
052            tpc.addComponent(ClassLoader.class, classLoader);
053            tpc.addComponent("sc", scriptClass);
054            tpc.addComponent(MutablePicoContainer.class, buildPico());
055            return (ClassLoadingPicoContainer)tpc.getComponent("sc");
056        }
057    
058        public MutablePicoContainer buildPico() {
059            return picoBuilder.build();
060        }
061    
062        public ScriptedBuilder withConsoleMonitor() {
063            picoBuilder.withConsoleMonitor();
064            return this;
065        }
066    
067        public ScriptedBuilder withLifecycle() {
068            picoBuilder.withLifecycle();
069            return this;
070        }
071    
072        public ScriptedBuilder withReflectionLifecycle() {
073            picoBuilder.withReflectionLifecycle();
074            return this;
075        }
076    
077        public ScriptedBuilder withMonitor(Class<? extends ComponentMonitor> clazz) {
078            picoBuilder.withMonitor(clazz);
079            return this;
080        }
081    
082        public ScriptedBuilder withHiddenImplementations() {
083            picoBuilder.withHiddenImplementations();
084            return this;
085        }
086    
087        public ScriptedBuilder withComponentFactory(ComponentFactory componentFactory) {
088            picoBuilder.withComponentFactory(componentFactory);
089            return this;
090        }
091    
092        public ScriptedBuilder withComponentAdapterFactories(BehaviorFactory... factories) {
093            picoBuilder.withBehaviors(factories);
094            return this;
095        }
096    
097        public ScriptedBuilder withSetterInjection() {
098            picoBuilder.withSetterInjection();
099            return this;
100        }
101    
102        public ScriptedBuilder withAnnotatedMethodInjection() {
103            picoBuilder.withAnnotatedMethodInjection();
104            return this;
105        }
106    
107        public ScriptedBuilder withConstructorInjection() {
108            picoBuilder.withConstructorInjection();
109            return this;
110        }
111    
112        public ScriptedBuilder withCaching() {
113            picoBuilder.withCaching();
114            return this;
115        }
116    
117        public ScriptedBuilder withThreadSafety() {
118            picoBuilder.withSynchronizing();
119            return this;
120        }
121    
122        public ScriptedBuilder implementedBy(Class<? extends ClassLoadingPicoContainer> scriptedContainerClass) {
123            scriptClass = scriptedContainerClass;
124            return this;
125        }
126    
127        public ScriptedBuilder picoImplementedBy(Class<? extends MutablePicoContainer> picoContainerClass) {
128            picoBuilder.implementedBy(picoContainerClass);
129            return this;
130        }
131    
132        public ScriptedBuilder withClassLoader(ClassLoader classLoader) {
133            this.classLoader = classLoader;
134            return this;
135        }
136    
137        public ScriptedBuilder withComponentFactory(String componentFactoryName) {
138            if (componentFactoryName != null && !componentFactoryName.equals("")) {
139                picoBuilder.withComponentFactory(loadClass(componentFactoryName, ComponentFactory.class));
140            }
141            return this;
142        }
143    
144        private <T> Class<? extends T> loadClass(String className, Class<T> asClass) {
145            try {
146                return classLoader.loadClass(className).asSubclass(asClass);
147            } catch (ClassNotFoundException e) {
148                throw new PicoClassNotFoundException(className, e);
149            }
150        }
151    
152        public ScriptedBuilder withMonitor(String monitorName) {
153            if (monitorName != null && !monitorName.equals("")) {
154                picoBuilder.withMonitor(loadClass(monitorName, ComponentMonitor.class));
155            }
156            return this;
157        }
158    }