001    package org.apache.ojb.broker.metadata;
002    
003    /* Copyright 2002-2005 The Apache Software Foundation
004     *
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    import java.io.Serializable;
019    import java.util.Properties;
020    
021    import org.apache.commons.lang.SystemUtils;
022    import org.apache.ojb.broker.util.pooling.PoolConfiguration;
023    import org.apache.ojb.broker.util.XmlHelper;
024    
025    /**
026     * Encapsulates connection pooling and JDBC-driver configuration properties managed by
027     * {@link org.apache.ojb.broker.metadata.JdbcConnectionDescriptor}.
028     * <p>
029     * Every new instantiated <code>ConnectionPoolDescriptor</code> is associated with
030     * default connection pool attributes.
031     *
032     * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
033     * @version $Id: ConnectionPoolDescriptor.java,v 1.1 2007-08-24 22:17:29 ewestfal Exp $
034     */
035    public class ConnectionPoolDescriptor extends PoolConfiguration implements Serializable, XmlCapable
036    {
037            private static final long serialVersionUID = -3071461685659671879L;
038    
039        /** String prefix for JDBC properties passed to DriverManager. */
040        public static final String JDBC_PROPERTY_NAME_PREFIX = "jdbc.";
041        private static final int JDBC_PROPERTY_NAME_LENGTH = JDBC_PROPERTY_NAME_PREFIX.length();
042        /**
043         * String prefix for DBCP properties.
044         * Currently OJB only uses this for setting DBCP parameters for pooling of Statement,
045         * not the max/test-parameters etc for the DBCP Connection pool
046         * (since there is only a JDBC2.0+ version of the Basic-classes ie BasicDataSource
047         *  and no DriverManager-based one).
048         */
049        public static final String DBCP_PROPERTY_NAME_PREFIX = "dbcp.";
050        private static final int DBCP_PROPERTY_NAME_LENGTH = DBCP_PROPERTY_NAME_PREFIX.length();
051    
052        /** JDBC properties configured in OJB (not used for DataSource connections). */
053        protected Properties jdbcProperties;
054        /** DBCP Statement cache properties configured in OJB (not used for DataSource connections). */
055        protected Properties dbcpProperties;
056    
057        /** Configuration attribute name for JDBC fetchSize hint. */
058        public static final String FETCH_SIZE = "fetchSize";
059    
060        private Class connectionFactory;
061    
062    
063        public ConnectionPoolDescriptor()
064        {
065            super();
066            init();
067        }
068    
069        /**
070         * Set some initial values.
071         */
072        private void init()
073        {
074            jdbcProperties = new Properties();
075            dbcpProperties = new Properties();
076            setFetchSize(0);
077            this.setTestOnBorrow(true);
078            this.setTestOnReturn(false);
079            this.setTestWhileIdle(false);
080            this.setLogAbandoned(false);
081            this.setRemoveAbandoned(false);
082        }
083    
084        public Class getConnectionFactory()
085        {
086            return this.connectionFactory;
087        }
088    
089        public void setConnectionFactory(Class connectionFactory)
090        {
091            if (connectionFactory == null) throw new MetadataException("Given ConnectionFactory was null");
092            this.connectionFactory = connectionFactory;
093        }
094    
095        /**
096         * Returns the fetchSize hint set for this connection pool.
097         * @return fetchSize hint or 0 if JDBC-driver specific default is used
098         */
099        public int getFetchSize()
100        {
101            // We depend on init() to always set fetchSize hint
102            return Integer.parseInt(getProperty(FETCH_SIZE));
103        }
104    
105        /**
106         * Sets the fetchSize hint for this connection pool.
107         * @param fetchSize fetchSize hint or 0 to use JDBC-driver specific default
108         */
109        public void setFetchSize(int fetchSize)
110        {
111            setProperty(FETCH_SIZE, Integer.toString(fetchSize));
112        }
113    
114        /**
115         * Returns the JDBC properties to be used by the ConnectionFactory
116         * when creating connections from DriverManager.
117         * @return JDBC-driver specific properties (might be empty, never null)
118         */
119        public Properties getJdbcProperties()
120        {
121            return jdbcProperties;
122        }
123    
124        /**
125         * Returns the DBCP properties to be used for Statement caching
126         * when creating DBCP connection pool in OJB ConnectionFactory.
127         * @return DBCP properties (might be empty, never null)
128         */
129        public Properties getDbcpProperties()
130        {
131            return dbcpProperties;
132        }
133    
134        /**
135         * Sets a custom configuration attribute.
136         * @param attributeName the attribute name. Names starting with
137         * {@link #JDBC_PROPERTY_NAME_PREFIX} will be used (without the prefix) by the
138         * ConnectionFactory when creating connections from DriverManager
139         * (not used for external DataSource connections). Names starting with
140         * {@link #DBCP_PROPERTY_NAME_PREFIX} to Commons DBCP (if used, also without prefix).
141         * @param attributeValue the attribute value
142         */
143        public void addAttribute(String attributeName, String attributeValue)
144        {
145            if (attributeName != null && attributeName.startsWith(JDBC_PROPERTY_NAME_PREFIX))
146            {
147                final String jdbcPropertyName = attributeName.substring(JDBC_PROPERTY_NAME_LENGTH);
148                jdbcProperties.setProperty(jdbcPropertyName, attributeValue);
149            }
150            else if (attributeName != null && attributeName.startsWith(DBCP_PROPERTY_NAME_PREFIX))
151            {
152                final String dbcpPropertyName = attributeName.substring(DBCP_PROPERTY_NAME_LENGTH);
153                dbcpProperties.setProperty(dbcpPropertyName, attributeValue);
154            }
155            else
156            {
157                super.addAttribute(attributeName, attributeValue);
158            }
159        }
160    
161        public String toXML()
162        {
163            RepositoryTags tags = RepositoryTags.getInstance();
164            String eol = SystemUtils.LINE_SEPARATOR;
165            StringBuffer buf = new StringBuffer();
166            //opening tag + attributes
167            buf.append("      ").append(tags.getOpeningTagById(CONNECTION_POOL)).append(eol);
168            buf.append("         " + tags.getAttribute(RepositoryElements.CON_MAX_ACTIVE, "" + getMaxActive()) + eol);
169            buf.append("         " + tags.getAttribute(RepositoryElements.CON_MAX_IDLE, "" + getMaxIdle()) + eol);
170            buf.append("         " + tags.getAttribute(RepositoryElements.CON_MAX_WAIT, "" + getMaxWait()) + eol);
171            buf.append("         " + tags.getAttribute(RepositoryElements.CON_MIN_EVICTABLE_IDLE_TIME_MILLIS, "" +
172                    getMinEvictableIdleTimeMillis()) + eol);
173            buf.append("         " + tags.getAttribute(RepositoryElements.CON_NUM_TESTS_PER_EVICTION_RUN, "" +
174                    getNumTestsPerEvictionRun()) + eol);
175            buf.append("         " + tags.getAttribute(RepositoryElements.CON_TEST_ON_BORROW, "" + isTestOnBorrow()) + eol);
176            buf.append("         " + tags.getAttribute(RepositoryElements.CON_TEST_ON_RETURN, "" + isTestOnReturn()) + eol);
177            buf.append("         " + tags.getAttribute(RepositoryElements.CON_TEST_WHILE_IDLE, "" + isTestWhileIdle()) + eol);
178            buf.append("         " + tags.getAttribute(RepositoryElements.CON_TIME_BETWEEN_EVICTION_RUNS_MILLIS, "" +
179                    getTimeBetweenEvictionRunsMillis()) + eol);
180            buf.append("         " + tags.getAttribute(RepositoryElements.CON_WHEN_EXHAUSTED_ACTION, "" +
181                    getWhenExhaustedAction()) + eol);
182            buf.append("         " + tags.getAttribute(RepositoryElements.VALIDATION_QUERY, "" + getValidationQuery()) + eol);
183    
184            buf.append("         " + tags.getAttribute(RepositoryElements.CON_LOG_ABANDONED, "" + isLogAbandoned()) + eol);
185            buf.append("         " + tags.getAttribute(RepositoryElements.CON_REMOVE_ABANDONED, "" +
186                    isRemoveAbandoned()) + eol);
187            buf.append("         " + tags.getAttribute(RepositoryElements.CON_REMOVE_ABANDONED_TIMEOUT, "" +
188                    getRemoveAbandonedTimeout()) + eol);
189    
190            buf.append("         <!-- ");
191            buf.append(eol);
192            buf.append("         Add JDBC-level properties here, like fetchSize.");
193            buf.append("         Attributes with name prefix \"jdbc.\" are passed directly to the JDBC driver.");
194            buf.append(eol);
195            buf.append("         e.g. <attribute attribute-name=\"fetchSize\" attribute-value=\"100\"/>");
196            buf.append(eol);
197            buf.append("         -->");
198            XmlHelper.appendSerializedAttributes(buf, "         ", this);
199    
200            buf.append("      ").append(tags.getClosingTagById(CONNECTION_POOL)).append(eol);
201            return buf.toString();
202        }
203    
204    }