001    /*
002     * Copyright 2000-2004 The Apache Software Foundation.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.apache.commons.scaffold.http;
018    
019    import java.io.IOException;
020    
021    import javax.servlet.ServletException;
022    
023    import org.apache.commons.logging.Log;
024    import org.apache.commons.logging.LogFactory;
025    import org.apache.commons.scaffold.sql.ConnectionAdaptor;
026    import org.apache.commons.scaffold.sql.ServletAdaptor;
027    
028    
029    /**
030     * Initialize a <code>ConnectionAdaptor</code> for this application.
031     * <p>
032     * The servlet itself is <b>not</b> involved in managing the connection.
033     * The ConnectionAdaptor is a standalone object.
034     * This servlet simply provides a means to initialize and load a
035     * ConnectionAdaptor for use by your application.
036     * <p>
037     * This servlet can be configured to use an alternate adaptor or
038     * adaptor key using initialization parameters:
039     * <p>
040     * <b>adaptor</b> The default adaptor is
041     * <code>org.apache.scaffold.sql.ConnectionAdaptor</code>.
042     * Any sublcass of ConnectionAdaptor can be specified instead.
043     * <p>
044     * <b>adaptor.key</b> The default adaptor key is <code>DATA_SOURCE</code>.
045     * Another key can be specified instead. This is the attribute to use
046     * when looking up the datasource in JNDI, the servlet context, or
047     * whatever.
048     * <p>
049     * To use the Struts generic connection pool, specify the adaptor as
050     * <code>org.apache.scaffold.sql.ServletAdaptor</code> and the
051     * adaptor.key as <code>org.apache.struts.action.DATA_SOURCE</code>
052     * <p>
053     * To use the Resin connection pool, specify the <b>res-ref-name</b>
054     * in the Resin conf as the <b>adaptor.key</b>.
055     * <p>
056     * To use Poolman without JNDI, use the Poolman adaptor in the
057     * sql package, and specify the dbName from the poolman.xml as the
058     * <b>adaptor.key</b>
059     *
060     * @see org.apache.scaffold.sql.ConnectionAdaptor
061     * @see org.apache.scaffold.sql.Servletdaptor
062     * @see org.apache.scaffold.sql.PoolmanAdaptor
063     * 
064     * @author Ted Husted
065     * @author Steve Raeburn 
066     * 
067     */
068    public class ConnectionServlet extends ResourceServlet {
069    
070            // ------------------------------------------------------- Class variables
071    
072            /**
073             * Commons logging instance
074             */
075            private static Log log = LogFactory.getLog(ResourceServlet.class);
076    
077    
078            /**
079         * Default parameter for setting a custom adaptor type
080         * in the servlet configuration.
081         */
082        private static String ADAPTOR_PARAMETER = "adaptor";
083    
084    
085        /**
086         * Default type to use if parameter not set
087         * ["org.apache.scaffold.sql.ConnectionAdaptor"].
088         */
089        private static String ADAPTOR_DEFAULT =
090            "org.apache.commons.scaffold.sql.ConnectionAdaptor";
091    
092    
093        /**
094         * Default parameter for setting the default attribute
095         * name, or key, used to retrieve the datasource.
096         * <p>
097         * For the Struts generic connection pool, you would set
098         * this to "org.apache.struts.action.DATA_SOURCE"
099         * [Action.DATA_SOURCE_KEY].
100         */
101        private static String ADAPTOR_KEY = "adaptor.key";
102    
103    
104        /**
105         * Field to hold our instance of the connection adaptor.
106         * Can be initialized to another ConnectionAdaptor at startup.
107         */
108        private static ConnectionAdaptor adaptor;
109    
110        
111            // ------------------------------------------------------ Logging Messages    
112    
113        
114            /**
115             * Message for verbose logging.
116             */
117            private static String ADAPTOR_LOADING_EVENT = 
118            "Loading ConnectionAdaptor";
119    
120    
121            /**
122             * Message to log if connector initialization fails.
123             */
124            private static String ADAPTOR_FAILED_EVENT =
125                    "*** ConnectionAdaptor failed to load: ";
126       
127        
128        // -----------------------------------------------------------------------
129    
130        /**
131         * Initialize the ConnectionAdaptor for this application.
132         * <p>
133         * An alternate ConnectionAdaptor can be specified in the servlet config
134         * by specifying the class type as the <b>adaptor</b> initialization
135         * parameter.
136         *
137         * @exception IOException if an input/output error is encountered
138         * @exception ServletException if we cannot initialize these resources
139         */
140        protected void initDefault() throws IOException, ServletException {
141    
142            super.initDefault();
143            if (log.isDebugEnabled()) {
144                log(ADAPTOR_LOADING_EVENT);
145            }
146    
147                // Check for an adaptor parameter
148            String adaptorClass =
149                getInitString(ADAPTOR_PARAMETER,ADAPTOR_DEFAULT);
150    
151                // Create the default or custom adaptor
152            try {
153                adaptor = (ConnectionAdaptor)
154                    Class.forName(adaptorClass).newInstance();
155            }
156    
157            catch (Throwable t) {
158                log.error(ADAPTOR_FAILED_EVENT,t);
159                t.printStackTrace();
160                throw new ServletException(t);
161            }
162    
163                // Check for an adaptor key
164            String key = getInitString(ADAPTOR_KEY,null);
165            if (null!=key) adaptor.setKey(key);
166    
167                // ** kludge alert **
168                // If its a servlet adaptor, give it a servlet reference
169            if (adaptor instanceof ServletAdaptor) {
170                    // Give adaptor access to servlet context.
171                ServletAdaptor s = (ServletAdaptor) adaptor;
172                s.setServlet(this);
173            }
174        }
175    
176    } // end ConnectionServlet