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    
020    import javax.sql.DataSource;
021    
022    import org.apache.ojb.broker.util.logging.Logger;
023    import org.apache.ojb.broker.util.logging.LoggerFactory;
024    import org.apache.ojb.broker.PBKey;
025    import org.apache.commons.lang.builder.ToStringBuilder;
026    import org.apache.commons.lang.builder.ToStringStyle;
027    import org.apache.commons.lang.SystemUtils;
028    
029    /**
030     * JdbcConnectionDescriptor describes all relevant parameters of
031     * JDBC Connections used by the PersistenceBroker.
032     *
033     * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
034     * @version $Id: JdbcConnectionDescriptor.java,v 1.1 2007-08-24 22:17:29 ewestfal Exp $
035     */
036    public class JdbcConnectionDescriptor extends DescriptorBase implements Serializable, XmlCapable
037    {
038            private static final long serialVersionUID = -600900924512028960L;
039        private Logger logger = LoggerFactory.getLogger(JdbcConnectionDescriptor.class);
040    
041        public static final int AUTO_COMMIT_IGNORE_STATE = 0;
042        public static final int AUTO_COMMIT_SET_TRUE_AND_TEMPORARY_FALSE = 1;
043        public static final int AUTO_COMMIT_SET_FALSE = 2;
044    
045        private String m_jcdAlias;
046        private String m_Dbms;
047        private String m_Driver;
048        private String m_Protocol;
049        private String m_SubProtocol;
050        private String m_DbAlias;
051        private String m_DatasourceName;
052        private String m_UserName;
053        private String m_Password;
054        private double m_JdbcLevel = 2.0;
055        private boolean m_eagerRelease = false;
056        private boolean m_batchMode = false;
057        private boolean defaultConnection = false;
058        private int useAutoCommit = AUTO_COMMIT_SET_TRUE_AND_TEMPORARY_FALSE;
059        private boolean ignoreAutoCommitExceptions = false;
060        private PBKey pbKey;
061        private ConnectionPoolDescriptor cpd;
062        private SequenceDescriptor sequenceDescriptor;
063        private ObjectCacheDescriptor objectCacheDescriptor;
064        private transient DataSource dataSource;
065    
066        /**
067         * Constructor declaration
068         */
069        public JdbcConnectionDescriptor()
070        {
071            cpd = new ConnectionPoolDescriptor();
072            objectCacheDescriptor = new ObjectCacheDescriptor();
073        }
074    
075        /**
076         * Returns the appropriate {@link ObjectCacheDescriptor}
077         * or <code>null</code> if not specified.
078         */
079        public ObjectCacheDescriptor getObjectCacheDescriptor()
080        {
081            return objectCacheDescriptor;
082        }
083    
084        /**
085         * Sets the {@link ObjectCacheDescriptor} for representing connection/database.
086         */
087        public void setObjectCacheDescriptor(ObjectCacheDescriptor objectCacheDescriptor)
088        {
089            this.objectCacheDescriptor = objectCacheDescriptor;
090        }
091    
092        /**
093         * Returns the data source that this connection descriptor represents if any.
094         * 
095         * @return The data source or <code>null</code>
096         */
097        public DataSource getDataSource()
098        {
099            return dataSource;        
100        }
101    
102        /**
103         * Sets the data source that this connection descriptor represents.
104         * 
105         * @param dataSource The data source
106         */
107        public void setDataSource(DataSource dataSource)
108        {
109            this.dataSource = dataSource;
110        }
111    
112        /**
113         * Get the alias name for this descriptor.
114         */
115        public String getJcdAlias()
116        {
117            return m_jcdAlias;
118        }
119    
120        /**
121         * Set an alias name for this descriptor.
122         */
123        public void setJcdAlias(String jcdAlias)
124        {
125            this.clearPBKey();
126            this.m_jcdAlias = jcdAlias;
127        }
128    
129        /**
130         *
131         */
132        public boolean isDefaultConnection()
133        {
134            return defaultConnection;
135        }
136    
137        public boolean isDataSource()
138        {
139            return (getDataSource() != null) || (getDatasourceName() != null);
140        }
141    
142        /**
143         *
144         */
145        public void setDefaultConnection(boolean defaultConnection)
146        {
147            this.defaultConnection = defaultConnection;
148        }
149    
150        /**
151         * Return the associated <code>SequenceDescriptor</code>
152         * or <code>null</code> if not set.
153         */
154        public SequenceDescriptor getSequenceDescriptor()
155        {
156            return sequenceDescriptor;
157        }
158    
159        /**
160         * Set the <code>SequenceDescriptor</code> for this
161         * connection descriptor.
162         */
163        public void setSequenceDescriptor(SequenceDescriptor sequenceDescriptor)
164        {
165            this.sequenceDescriptor = sequenceDescriptor;
166        }
167    
168        /**
169         * Returns the connection pool descriptor.
170         */
171        public ConnectionPoolDescriptor getConnectionPoolDescriptor()
172        {
173            return cpd;
174        }
175    
176        /**
177         * Sets the connection pool descriptor.
178         */
179        public void setConnectionPoolDescriptor(ConnectionPoolDescriptor cpd)
180        {
181            this.cpd = cpd;
182        }
183    
184        /**
185         * Return a key to identify the connection descriptor.
186         */
187        public PBKey getPBKey()
188        {
189            if (pbKey == null)
190            {
191                this.pbKey = new PBKey(this.getJcdAlias(), this.getUserName(), this.getPassWord());
192            }
193            return pbKey;
194        }
195    
196        private void clearPBKey()
197        {
198            this.pbKey = null;
199        }
200    
201        public int getUseAutoCommit()
202        {
203            return useAutoCommit;
204        }
205    
206        public void setUseAutoCommit(int useAutoCommit)
207        {
208            this.useAutoCommit = useAutoCommit;
209        }
210    
211        public boolean isIgnoreAutoCommitExceptions()
212        {
213            return ignoreAutoCommitExceptions;
214        }
215    
216        public void setIgnoreAutoCommitExceptions(boolean ignoreAutoCommitExceptions)
217        {
218            this.ignoreAutoCommitExceptions = ignoreAutoCommitExceptions;
219        }
220    
221        /**
222         * Returns the database platform name.
223         */
224        public String getDbms()
225        {
226            return m_Dbms;
227        }
228    
229        /**
230         * Sets the database platform name.
231         */
232        public void setDbms(String str)
233        {
234            m_Dbms = str;
235        }
236    
237        /**
238         * Returns the driver name.
239         */
240        public String getDriver()
241        {
242            return m_Driver;
243        }
244    
245        /**
246         * Set the database driver.
247         */
248        public void setDriver(String str)
249        {
250            m_Driver = str;
251        }
252    
253        /**
254         * Returns the database protocol.
255         */
256        public String getProtocol()
257        {
258            return m_Protocol;
259        }
260    
261        /**
262         * Sets the database protocol.
263         */
264        public void setProtocol(String str)
265        {
266            m_Protocol = str;
267        }
268    
269        /**
270         * Returns the database sub-protocol.
271         */
272        public String getSubProtocol()
273        {
274            return m_SubProtocol;
275        }
276    
277        /**
278         * Sets the database sub-protocol.
279         */
280        public void setSubProtocol(String str)
281        {
282            m_SubProtocol = str;
283        }
284    
285        /**
286         * Returns the database alias name
287         * used by OJB.
288         */
289        public String getDbAlias()
290        {
291            return m_DbAlias;
292        }
293    
294        /**
295         * Sets the database alias name. These
296         * names you could find in the repository.dtd.
297         */
298        public void setDbAlias(String str)
299        {
300            m_DbAlias = str;
301        }
302    
303        /**
304         * Returns the database user name.
305         */
306        public String getUserName()
307        {
308            return m_UserName;
309        }
310    
311        /**
312         * Sets the database user name.
313         */
314        public void setUserName(String str)
315        {
316            this.clearPBKey();
317            m_UserName = str;
318        }
319    
320        /**
321         * Returns the database password.
322         */
323        public String getPassWord()
324        {
325            return m_Password;
326        }
327    
328        /**
329         * Sets the database password.
330         */
331        public void setPassWord(String str)
332        {
333            this.clearPBKey();
334            m_Password = str;
335        }
336    
337        /**
338         * Gets the datasourceName.
339         * @return Returns a String
340         */
341        public String getDatasourceName()
342        {
343            return m_DatasourceName;
344        }
345    
346        /**
347         * Sets the datasourceName.
348         * @param datasourceName The datasourceName to set
349         */
350        public void setDatasourceName(String datasourceName)
351        {
352            m_DatasourceName = datasourceName;
353        }
354    
355        /**
356         * Gets the jdbcLevel.
357         * @return Returns a String
358         */
359        public double getJdbcLevel()
360        {
361            return m_JdbcLevel;
362        }
363    
364        /**
365         * Sets the jdbcLevel. parse the string setting and check that it is indeed an integer.
366         * @param jdbcLevel The jdbcLevel to set
367         */
368        public void setJdbcLevel(String jdbcLevel)
369        {
370            if (jdbcLevel != null)
371            {
372                try
373                {
374                    double intLevel = Double.parseDouble(jdbcLevel);
375                    setJdbcLevel(intLevel);
376                }
377                catch(NumberFormatException nfe)
378                {
379                    setJdbcLevel(2.0);
380                    logger.info("Specified JDBC level was not numeric (Value=" + jdbcLevel + "), used default jdbc level of 2.0 ");
381                }
382            }
383            else
384            {
385                setJdbcLevel(2.0);
386                logger.info("Specified JDBC level was null, used default jdbc level of 2.0 ");
387            }
388        }
389    
390        public void setJdbcLevel(double jdbcLevel)
391        {
392            m_JdbcLevel = jdbcLevel;
393        }
394    
395        public boolean getEagerRelease()
396        {
397            return m_eagerRelease;
398        }
399    
400        public void setEagerRelease(boolean flag)
401        {
402            m_eagerRelease = flag;
403        }
404    
405        public boolean getBatchMode()
406        {
407            return m_batchMode;
408        }
409    
410        public void setBatchMode(boolean flag)
411        {
412            m_batchMode = flag;
413        }
414    
415        /**
416         * Returns a String representation of this class.
417         */
418        public String toString()
419        {
420            ToStringBuilder buf = new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE);
421            buf.
422            append("jcd-alias", m_jcdAlias).
423            append("default-connection", defaultConnection).
424            append("dbms", m_Dbms).
425            append("jdbc-level", m_JdbcLevel).
426            append("driver", m_Driver).
427            append("protocol", m_Protocol).
428            append("sub-protocol", m_SubProtocol).
429            append("db-alias", m_DbAlias).
430            append("user", m_UserName).
431            append("password", "*****").
432            append("eager-release", m_eagerRelease).
433            append("ConnectionPoolDescriptor", cpd).
434            append("batchMode", m_batchMode).
435            append("useAutoCommit", getUseAutoCommitAsString(useAutoCommit)).
436            append("ignoreAutoCommitExceptions", ignoreAutoCommitExceptions).
437            append("sequenceDescriptor", sequenceDescriptor);
438            return buf.toString();
439        }
440    
441        /*
442         * @see XmlCapable#toXML()
443         */
444        public String toXML()
445        {
446            RepositoryTags tags = RepositoryTags.getInstance();
447            String eol = SystemUtils.LINE_SEPARATOR;
448    
449            StringBuffer strReturn = new StringBuffer( 1024 );
450            strReturn.append( eol );
451            strReturn.append( "  <!-- Descriptor for Connection " );
452            strReturn.append( getProtocol() );
453            strReturn.append( ":" );
454            strReturn.append( getSubProtocol() );
455            strReturn.append( ":" );
456            strReturn.append( getDbAlias() );
457            strReturn.append( " -->" );
458            strReturn.append( eol );
459    
460            strReturn.append( "  " );
461            strReturn.append( tags.getOpeningTagNonClosingById( JDBC_CONNECTION_DESCRIPTOR ) );
462            strReturn.append( eol );
463            strReturn.append( "    " );
464            strReturn.append( tags.getAttribute( JCD_ALIAS, this.getJcdAlias() ) );
465            strReturn.append( eol );
466            strReturn.append( "    " );
467            strReturn.append( tags.getAttribute( DEFAULT_CONNECTION, "" + this.isDefaultConnection() ) );
468            strReturn.append( eol );
469            strReturn.append( "    " );
470            strReturn.append( tags.getAttribute( DBMS_NAME, this.getDbms() ) );
471            strReturn.append( eol );
472            strReturn.append( "    " );
473            strReturn.append( tags.getAttribute( JDBC_LEVEL, "" + this.getJdbcLevel() ) );
474            strReturn.append( eol );
475    
476            //username is optional
477            String user = getUserName();
478            if( user != null )
479            {
480                strReturn.append( "    " );
481                strReturn.append( tags.getAttribute( USER_NAME, user ) );
482                strReturn.append( eol );
483            }
484            // password is optional
485            String passwd = getPassWord();
486            if( passwd != null )
487            {
488                strReturn.append( "    " );
489                strReturn.append( tags.getAttribute( USER_PASSWD, passwd ) );
490                strReturn.append( eol );
491            }
492    
493            // JDBC Datasource or DriverManager information are alternatives:
494            String dsn = getDatasourceName();
495            if( dsn != null )
496            {
497                strReturn.append( "    " );
498                strReturn.append( tags.getAttribute( DATASOURCE_NAME, this.getDatasourceName() ) );
499                strReturn.append( eol );
500            }
501            else
502            {
503                strReturn.append( "    " );
504                strReturn.append( tags.getAttribute( DRIVER_NAME, this.getDriver() ) );
505                strReturn.append( eol );
506                strReturn.append( "    " );
507                strReturn.append( tags.getAttribute( URL_PROTOCOL, this.getProtocol() ) );
508                strReturn.append( eol );
509                strReturn.append( "    " );
510                strReturn.append( tags.getAttribute( URL_SUBPROTOCOL, this.getSubProtocol() ) );
511                strReturn.append( eol );
512                strReturn.append( "    " );
513                strReturn.append( encode( tags.getAttribute( URL_DBALIAS, this.getDbAlias() ) ) );
514                strReturn.append( eol );
515            }
516            strReturn.append( "    " );
517            strReturn.append( tags.getAttribute( EAGER_RELEASE, "" + this.getEagerRelease() ) );
518            strReturn.append( eol );
519            strReturn.append( "    " );
520            strReturn.append( tags.getAttribute( BATCH_MODE, "" + this.getBatchMode() ) );
521            strReturn.append( eol );
522            strReturn.append( "    " );
523            strReturn.append( tags.getAttribute( USE_AUTOCOMMIT, "" + this.getUseAutoCommit() ) );
524            strReturn.append( eol );
525            strReturn.append( "    " );
526            strReturn.append( tags.getAttribute( IGNORE_AUTOCOMMIT_EXCEPTION, "" + this.isIgnoreAutoCommitExceptions() ) );
527            strReturn.append( eol );
528    
529            strReturn.append( "  >" );
530            strReturn.append( eol );
531            strReturn.append( eol );
532    
533            strReturn.append( this.getConnectionPoolDescriptor().toXML() );
534            strReturn.append( eol );
535            if( this.getSequenceDescriptor() != null )
536            {
537                strReturn.append( this.getSequenceDescriptor().toXML() );
538            }
539            strReturn.append( eol );
540            strReturn.append( "  " );
541            strReturn.append( tags.getClosingTagById( JDBC_CONNECTION_DESCRIPTOR ) );
542            strReturn.append( eol );
543            return strReturn.toString();
544        }
545    
546        private static String encode(String toBeEncoded)
547        {
548            StringBuffer retval = new StringBuffer();
549            char c;
550            for (int i=0; i < toBeEncoded.length(); i++)
551            {
552                c = toBeEncoded.charAt(i);
553                if (c == '<')
554                {
555                    retval.append("&lt;");
556                }
557                else if (c == '>')
558                {
559                    retval.append("&gt;");
560                }
561                //else if (c == '"')
562                //{
563                //    retval.append("&quot;");
564                //}
565                else if (c == '&')
566                {
567                    retval.append("&amp;");
568                }
569                else if (c == ' ')
570                {
571                    retval.append("&nbsp;");
572                }
573                else
574                {
575                    retval.append(c);
576                }
577            }
578            return retval.toString();
579        }
580    
581        private static String getUseAutoCommitAsString(int state)
582        {
583            switch (state)
584            {
585                case AUTO_COMMIT_SET_TRUE_AND_TEMPORARY_FALSE:
586                    return "AUTO_COMMIT_SET_TRUE_AND_TEMPORARY_FALSE";
587                case AUTO_COMMIT_SET_FALSE:
588                    return "AUTO_COMMIT_SET_FALSE";
589                case AUTO_COMMIT_IGNORE_STATE:
590                    return "AUTO_COMMIT_IGNORE_STATE";
591                default: return "UNKOWN_STATE";
592            }
593        }
594    }