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.script;
010    
011    import java.io.IOException;
012    import java.io.InputStream;
013    import java.io.InputStreamReader;
014    import java.io.Reader;
015    import java.net.URL;
016    
017    import org.picocontainer.PicoContainer;
018    
019    /**
020     * Abstract class for script-based container builders
021     *
022     * @author Aslak Hellesøy
023     * @author Obie Fernandez
024     * @author Mauro Talevi
025     */
026    public abstract class ScriptedContainerBuilder extends AbstractContainerBuilder {
027        
028        private final Reader scriptReader;
029        private final URL scriptURL;
030        private final ClassLoader classLoader;
031        
032        public ScriptedContainerBuilder(Reader script, ClassLoader classLoader) {
033            this(script,classLoader, LifecycleMode.AUTO_LIFECYCLE);
034        }
035    
036        public ScriptedContainerBuilder(Reader script, ClassLoader classLoader, LifecycleMode lifecycleMode) {
037            super(lifecycleMode);
038            this.scriptReader = script;
039            if (script == null) {
040                throw new NullPointerException("script");
041            }
042            this.scriptURL = null;
043            this.classLoader = classLoader;
044            if ( classLoader == null) {
045                throw new NullPointerException("classLoader");
046            }
047        }
048        
049        public ScriptedContainerBuilder(URL script, ClassLoader classLoader)  {
050            this(script,classLoader, LifecycleMode.AUTO_LIFECYCLE);
051        }
052    
053        public ScriptedContainerBuilder(URL script, ClassLoader classLoader, LifecycleMode lifecycleMode) {
054            super(lifecycleMode);
055            this.scriptReader = null;        
056            this.scriptURL = script;
057            if (script == null) {
058                throw new NullPointerException("script");
059            }
060            this.classLoader = classLoader;
061            if ( classLoader == null) {
062                throw new NullPointerException("classLoader");
063            }
064        }
065    
066        protected final PicoContainer createContainer(PicoContainer parentContainer, Object assemblyScope) {
067            try {
068                return createContainerFromScript(parentContainer, assemblyScope);
069            } finally {
070                try {
071                    Reader reader = getScriptReader();
072                    if (reader != null) {
073                        reader.close();
074                    }
075                } catch (IOException e) {
076                    // do nothing. we've given it our best try, now get on with it
077                }
078            }
079        }
080    
081        protected final ClassLoader getClassLoader() {
082            return classLoader;
083        }
084        
085        protected final InputStream getScriptInputStream() throws IOException{
086            if ( scriptReader != null ){
087                return new InputStream() {
088                    public int read() throws IOException {
089                        return scriptReader.read();
090                    }
091                };
092            }
093            return scriptURL.openStream();
094        }
095    
096        protected final Reader getScriptReader() throws IOException{
097            if ( scriptReader != null ){
098                return scriptReader;
099            }
100            return new InputStreamReader(scriptURL.openStream());
101        }
102        
103        protected abstract PicoContainer createContainerFromScript(PicoContainer parentContainer, Object assemblyScope);
104    
105    }