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    import java.net.URL;
024    import java.util.List;
025    import java.util.ArrayList;
026    
027    /**
028     * Facade to build ScriptedScriptedPicoContainer
029     *
030     * @author Paul Hammant
031     */
032    public final class ScriptedBuilder {
033    
034        private Class<? extends ClassLoadingPicoContainer> scriptClass = DefaultClassLoadingPicoContainer.class;
035        private final PicoBuilder picoBuilder;
036        private ClassLoader classLoader = DefaultClassLoadingPicoContainer.class.getClassLoader();
037        private List<URL> urls = new ArrayList<URL>();
038    
039        public ScriptedBuilder(PicoContainer parentcontainer, InjectionFactory injectionType) {
040            picoBuilder = new PicoBuilder(parentcontainer, injectionType);
041        }
042    
043        public ScriptedBuilder(PicoContainer parentcontainer) {
044            picoBuilder = new PicoBuilder(parentcontainer);
045        }
046    
047        public ScriptedBuilder(InjectionFactory injectionType) {
048            picoBuilder = new PicoBuilder(injectionType);
049        }
050    
051        public ScriptedBuilder() {
052            picoBuilder = new PicoBuilder();
053        }
054    
055        public ClassLoadingPicoContainer build() {
056            DefaultPicoContainer tpc = new TransientPicoContainer();
057            tpc.addComponent(ClassLoader.class, classLoader);
058            tpc.addComponent("sc", scriptClass);
059            tpc.addComponent(MutablePicoContainer.class, picoBuilder.build());
060            ClassLoadingPicoContainer pico = (ClassLoadingPicoContainer) tpc.getComponent("sc");
061            for (URL url : urls) {
062                pico.addClassLoaderURL(url);
063            }
064            return pico;
065        }
066    
067        public ScriptedBuilder withConsoleMonitor() {
068            picoBuilder.withConsoleMonitor();
069            return this;
070        }
071    
072        public ScriptedBuilder withLifecycle() {
073            picoBuilder.withLifecycle();
074            return this;
075        }
076    
077        public ScriptedBuilder withReflectionLifecycle() {
078            picoBuilder.withReflectionLifecycle();
079            return this;
080        }
081    
082        public ScriptedBuilder withMonitor(Class<? extends ComponentMonitor> clazz) {
083            picoBuilder.withMonitor(clazz);
084            return this;
085        }
086    
087        public ScriptedBuilder withHiddenImplementations() {
088            picoBuilder.withHiddenImplementations();
089            return this;
090        }
091    
092        public ScriptedBuilder withComponentFactory(ComponentFactory componentFactory) {
093            picoBuilder.withComponentFactory(componentFactory);
094            return this;
095        }
096    
097        public ScriptedBuilder withBehaviors(BehaviorFactory... factories) {
098            picoBuilder.withBehaviors(factories);
099            return this;
100        }
101    
102        public ScriptedBuilder withSetterInjection() {
103            picoBuilder.withSetterInjection();
104            return this;
105        }
106    
107        public ScriptedBuilder withAnnotatedMethodInjection() {
108            picoBuilder.withAnnotatedMethodInjection();
109            return this;
110        }
111    
112        public ScriptedBuilder withConstructorInjection() {
113            picoBuilder.withConstructorInjection();
114            return this;
115        }
116    
117        public ScriptedBuilder withCaching() {
118            picoBuilder.withCaching();
119            return this;
120        }
121    
122        public ScriptedBuilder withSynchronizing() {
123            picoBuilder.withSynchronizing();
124            return this;
125        }
126    
127        public ScriptedBuilder implementedBy(Class<? extends ClassLoadingPicoContainer> scriptedContainerClass) {
128            scriptClass = scriptedContainerClass;
129            return this;
130        }
131    
132        public ScriptedBuilder implementedBy(String scriptedContainerClass) {
133            scriptClass = loadClass(scriptedContainerClass, ClassLoadingPicoContainer.class);
134            return this;
135        }
136    
137        public ScriptedBuilder picoImplementedBy(Class<? extends MutablePicoContainer> picoContainerClass) {
138            picoBuilder.implementedBy(picoContainerClass);
139            return this;
140        }
141    
142        public ScriptedBuilder withClassLoader(ClassLoader usingClassloader) {
143            this.classLoader = usingClassloader;
144            return this;
145        }
146    
147        public ScriptedBuilder withComponentFactory(String componentFactoryName) {
148            if (componentFactoryName != null && !componentFactoryName.equals("")) {
149                picoBuilder.withComponentFactory(loadClass(componentFactoryName, ComponentFactory.class));
150            }
151            return this;
152        }
153    
154        private <T> Class<? extends T> loadClass(String className, Class<T> asClass) {
155            try {
156                return classLoader.loadClass(className).asSubclass(asClass);
157            } catch (ClassNotFoundException e) {
158                throw new PicoClassNotFoundException(className, e);
159            }
160        }
161    
162        public ScriptedBuilder withMonitor(String monitorName) {
163            if (monitorName != null && !monitorName.equals("")) {
164                picoBuilder.withMonitor(loadClass(monitorName, ComponentMonitor.class));
165            }
166            return this;
167        }
168    
169        public ScriptedBuilder addClassLoaderURL(URL url) {
170            urls.add(url);
171            return this;
172        }
173    }