Author: nzamosenchuk
Date: 2010-02-08 09:40:45 -0500 (Mon, 08 Feb 2010)
New Revision: 1724
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DialectDetecter.java
Log:
EXOJCR-470: If column types are not defined in CL configuration, then datasource's
dialect is detected and suitable datatypes are injected into configuration.
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java 2010-02-08
14:29:31 UTC (rev 1723)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java 2010-02-08
14:40:45 UTC (rev 1724)
@@ -22,6 +22,7 @@
import org.exoplatform.management.jmx.annotations.NameTemplate;
import org.exoplatform.management.jmx.annotations.Property;
import org.exoplatform.services.jcr.access.SystemIdentity;
+import org.exoplatform.services.jcr.config.MappedParametrizedObjectEntry;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.SimpleParameterEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
@@ -45,6 +46,8 @@
import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
import
org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DialectDetecter;
import org.exoplatform.services.jcr.jbosscache.ExoJBossCacheFactory;
import org.exoplatform.services.jcr.observation.ExtendedEvent;
import org.exoplatform.services.log.ExoLogger;
@@ -74,6 +77,8 @@
import javax.jcr.RepositoryException;
import javax.jcr.lock.LockException;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
@@ -99,6 +104,12 @@
*/
public static final String JBOSSCACCHE_CONFIG = "jbosscache-configuration";
+ public static final String JBOSSCACHE_JDBC_CL_DATASOURCE =
"jbosscache-cl-cache.jdbc.datasource";
+
+ public static final String JBOSSCACHE_JDBC_CL_NODE_COLUMN =
"jbosscache-cl-cache.jdbc.node.type";
+
+ public static final String JBOSSCACHE_JDBC_CL_FQN_COLUMN =
"jbosscache-cl-cache.jdbc.fqn.type";
+
/**
* Default lock time out. 30min
*/
@@ -160,7 +171,7 @@
*/
public CacheableLockManagerImpl(WorkspacePersistentDataManager dataManager,
WorkspaceEntry config,
InitialContextInitializer context, TransactionService transactionService,
ConfigurationManager cfm)
- throws RepositoryConfigurationException
+ throws RepositoryConfigurationException, RepositoryException
{
this(dataManager, config, context, transactionService.getTransactionManager(),
cfm);
}
@@ -174,7 +185,8 @@
* @throws RepositoryConfigurationException
*/
public CacheableLockManagerImpl(WorkspacePersistentDataManager dataManager,
WorkspaceEntry config,
- InitialContextInitializer context, ConfigurationManager cfm) throws
RepositoryConfigurationException
+ InitialContextInitializer context, ConfigurationManager cfm) throws
RepositoryConfigurationException,
+ RepositoryException
{
this(dataManager, config, context, (TransactionManager)null, cfm);
@@ -192,7 +204,7 @@
*/
public CacheableLockManagerImpl(WorkspacePersistentDataManager dataManager,
WorkspaceEntry config,
InitialContextInitializer context, TransactionManager transactionManager,
ConfigurationManager cfm)
- throws RepositoryConfigurationException
+ throws RepositoryConfigurationException, RepositoryException
{
lockRoot = Fqn.fromElements(LOCKS);
@@ -229,6 +241,8 @@
// create cache using custom factory
ExoJBossCacheFactory<Serializable, Object> factory =
new ExoJBossCacheFactory<Serializable, Object>(cfm,
transactionManager);
+ // configure cache loader parameters with correct DB data-types
+ configureJDBCCacheLoader(config.getLockManager());
cache = factory.createCache(config.getLockManager());
@@ -249,6 +263,88 @@
}
/**
+ * If JDBC cache loader is used, then fills-in column types. If column type configured
from jcr-configuration file,
+ * then nothing is overridden. Parameters are injected into the given parameterEntry.
+ */
+ public void configureJDBCCacheLoader(MappedParametrizedObjectEntry parameterEntry)
throws RepositoryException
+ {
+ String dataSourceName =
parameterEntry.getParameterValue(JBOSSCACHE_JDBC_CL_DATASOURCE, null);
+ // if data source is not defined, i.e. no cache loader is used (possibly pattern is
changed, to used another cache loader)
+ if (dataSourceName != null)
+ {
+ String dialect;
+ // detect dialect of data-source
+ try
+ {
+ DataSource dataSource = (DataSource)new
InitialContext().lookup(dataSourceName);
+ dialect = DialectDetecter.detect(dataSource);
+ }
+ catch (Exception e)
+ {
+ throw new RepositoryException("Error configuring JDBC cache
loader", e);
+ }
+ // default values, will be overridden with types suitable for concrete data
base.
+ String blobType = "BLOB";
+ String charType = "VARCHAR(512)";
+ // HSSQL
+ if (dialect.equals(DBConstants.DB_DIALECT_HSQLDB))
+ {
+ blobType = "OBJECT";
+ }
+ // MYSQL
+ else if (dialect.equals(DBConstants.DB_DIALECT_MYSQL) ||
dialect.equals(DBConstants.DB_DIALECT_MYSQL_UTF8))
+ {
+ blobType = "LONGBLOB";
+ }
+ // ORACLE
+ else if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) ||
dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
+ {
+ // Oracle suggests the use VARCHAR2 instead of VARCHAR while declaring data
type.
+ charType = "VARCHAR2(512)";
+ blobType = "BLOB";
+ }
+ // POSTGRE SQL
+ else if (dialect.equals(DBConstants.DB_DIALECT_PGSQL))
+ {
+ blobType = "bytea";
+ }
+ // Microsoft SQL
+ else if (dialect.equals(DBConstants.DB_DIALECT_MSSQL))
+ {
+ blobType = "VARBINARY(MAX)";
+ }
+ // SYBASE
+ else if (dialect.equals(DBConstants.DB_DIALECT_SYBASE))
+ {
+ blobType = "IMAGE";
+ }
+ // INGRES
+ else if (dialect.equals(DBConstants.DB_DIALECT_INGRES))
+ {
+ blobType = "long byte";
+ }
+ // GENERIC or DB2
+ else
+ {
+ charType = "VARCHAR(512)";
+ blobType = "BLOB";
+ }
+
+ // set parameters if not defined
+ if (parameterEntry.getParameterValue(JBOSSCACHE_JDBC_CL_NODE_COLUMN, null) ==
null)
+ {
+ parameterEntry.putParameterValue(JBOSSCACHE_JDBC_CL_NODE_COLUMN, blobType);
+ }
+
+ if (parameterEntry.getParameterValue(JBOSSCACHE_JDBC_CL_FQN_COLUMN, null) ==
null)
+ {
+ parameterEntry.putParameterValue(JBOSSCACHE_JDBC_CL_FQN_COLUMN, charType);
+ }
+
+ }
+ }
+
+ /**
* This methods adds programmatically the required {@link CacheLoader} needed to
prevent
* any {@link TimeoutException}
*/
@@ -1009,5 +1105,4 @@
{
R execute(A arg) throws LockException;
}
-
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DialectDetecter.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DialectDetecter.java 2010-02-08
14:29:31 UTC (rev 1723)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DialectDetecter.java 2010-02-08
14:40:45 UTC (rev 1724)
@@ -18,9 +18,13 @@
*/
package org.exoplatform.services.jcr.impl.storage.jdbc;
+import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
+import javax.jcr.RepositoryException;
+import javax.sql.DataSource;
+
/**
* JDBC dialect detecter based on database metadata and vendor product name.
*
@@ -30,7 +34,7 @@
*/
public class DialectDetecter
{
-
+
/**
* Detect databse dialect using JDBC metadata. Based on code of
*
http://svn.jboss.org/repos/hibernate/core/trunk/core/src/main/java/org/hi...
@@ -125,4 +129,34 @@
return DBConstants.DB_DIALECT_GENERIC;
}
+ /**
+ * Tries to detect dialect of DataSource
+ *
+ * @param dataSourceName
+ * @return
+ * @throws RepositoryException
+ */
+ public static String detect(DataSource dataSource) throws SQLException
+ {
+ // if no datasource provided
+ if (dataSource == null)
+ {
+ throw new SQLException("DataSource can't be null");
+ }
+ // try to detect dialect
+ Connection jdbcConn = null;
+ try
+ {
+ jdbcConn = dataSource.getConnection();
+ return detect(jdbcConn.getMetaData());
+ }
+ finally
+ {
+ if (jdbcConn != null && !jdbcConn.isClosed())
+ {
+ jdbcConn.close();
+ }
+ }
+
+ }
}