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        @Override
067        protected final PicoContainer createContainer(PicoContainer parentContainer, Object assemblyScope) {
068            try {
069                return createContainerFromScript(parentContainer, assemblyScope);
070            } finally {
071                try {
072                    Reader reader = getScriptReader();
073                    if (reader != null) {
074                        reader.close();
075                    }
076                } catch (IOException e) {
077                    // do nothing. we've given it our best try, now get on with it
078                }
079            }
080        }
081    
082        protected final ClassLoader getClassLoader() {
083            return classLoader;
084        }
085        
086        @SuppressWarnings("synthetic-access")
087        protected final InputStream getScriptInputStream() throws IOException{
088            if ( scriptReader != null ){
089                return new InputStream() {
090                    @Override
091                    public int read() throws IOException {
092                        return scriptReader.read();
093                    }
094                };
095            }
096            return scriptURL.openStream();
097        }
098    
099        protected final Reader getScriptReader() throws IOException{
100            if ( scriptReader != null ){
101                return scriptReader;
102            }
103            return new InputStreamReader(scriptURL.openStream());
104        }
105        
106        protected abstract PicoContainer createContainerFromScript(PicoContainer parentContainer, Object assemblyScope);
107    
108    }