exo-jcr SVN: r3816 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/storage/jdbc and 4 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-01-19 02:39:43 -0500 (Wed, 19 Jan 2011)
New Revision: 3816
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/backup/CleanException.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/backup/DataCleaner.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/DBCleanHelper.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/DBCleaner.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/IngresSQLDBCleaner.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/OracleDBCleaner.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/PgSQLDBCleaner.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java
Removed:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/cleaner/
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleanerService.java
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/backup/Backupable.java
Log:
EXOJCR-1146: DBCleanerService should not relate on AbstractCacheableLockManager
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java 2011-01-18 09:18:18 UTC (rev 3815)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java 2011-01-19 07:39:43 UTC (rev 3816)
@@ -17,11 +17,10 @@
package org.exoplatform.services.jcr.impl.core.lock.cacheable;
import org.exoplatform.commons.utils.PrivilegedSystemHelper;
+import org.exoplatform.commons.utils.SecurityHelper;
import org.exoplatform.management.annotations.Managed;
import org.exoplatform.management.annotations.ManagedDescription;
-import org.exoplatform.services.jcr.config.LockManagerEntry;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
-import org.exoplatform.services.jcr.config.SimpleParameterEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.dataflow.ChangesLogIterator;
import org.exoplatform.services.jcr.dataflow.CompositeChangesLog;
@@ -42,8 +41,6 @@
import org.exoplatform.services.jcr.impl.core.lock.LockRemover;
import org.exoplatform.services.jcr.impl.core.lock.LockRemoverHolder;
import org.exoplatform.services.jcr.impl.core.lock.SessionLockManager;
-import org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNCacheableLockManagerImpl;
-import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl;
import org.exoplatform.services.jcr.impl.dataflow.TransientItemData;
import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
@@ -51,10 +48,13 @@
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.BackupException;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.CleanException;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.DataCleaner;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.RestoreException;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.util.BackupTables;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.util.RestoreTableRule;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.util.RestoreTables;
+import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.DBCleaner;
import org.exoplatform.services.jcr.observation.ExtendedEvent;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -65,6 +65,9 @@
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -76,6 +79,10 @@
import javax.jcr.RepositoryException;
import javax.jcr.lock.LockException;
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
@@ -803,42 +810,6 @@
}
/**
- * Return table name for lock data.
- */
- public static List<String> getLockTableNames(LockManagerEntry lockManagerEntry)
- {
- List<String> tableNames = new ArrayList<String>();
-
- if (lockManagerEntry != null)
- {
- for (SimpleParameterEntry entry : lockManagerEntry.getParameters())
- {
- if (entry.getName().equals(CacheableLockManagerImpl.JBOSSCACHE_JDBC_TABLE_NAME))
- {
- tableNames.add(entry.getValue());
- tableNames.add(entry.getValue() + "_D");
-
- return tableNames;
- }
- else if (entry.getName().equals(ISPNCacheableLockManagerImpl.INFINISPAN_JDBC_TABLE_NAME))
- {
- throw new RuntimeException("Not supported");
- }
- }
- }
-
- return tableNames;
- }
-
- /**
- * Return select data script.
- */
- public static String getSelectScript(String tableName)
- {
- return "select * from " + tableName;
- }
-
- /**
* {@inheritDoc}
*/
public void backup(File storageDir) throws BackupException
@@ -883,9 +854,62 @@
RestoreTables restoreTable = new RestoreTables(null, tempDir, maxBufferSize);
restoreTable.restore(storageDir, getDatasourceName(), tables);
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public DataCleaner getDataCleaner() throws CleanException
+ {
+ try
+ {
+ String dsName = getDatasourceName();
+ final DataSource ds = (DataSource)new InitialContext().lookup(dsName);
+ if (ds == null)
+ {
+ throw new NameNotFoundException("Data source " + dsName + " not found");
+ }
+
+ Connection jdbcConn =
+ SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+ {
+ public Connection run() throws Exception
+ {
+ return ds.getConnection();
+
+ }
+ });
+
+ List<String> cleanScripts = new ArrayList<String>();
+ for (String tableName : getTableNames())
+ {
+ cleanScripts.add("drop table " + tableName);
+ }
+
+ return new DBCleaner(jdbcConn, cleanScripts);
+ }
+ catch (SQLException e)
+ {
+ throw new CleanException(e);
+ }
+ catch (NamingException e)
+ {
+ throw new CleanException(e);
+ }
+ }
+
+ /**
+ * Get list of tables names used by CacheableLockManager.
+ *
+ * @return List
+ */
protected abstract List<String> getTableNames();
+ /**
+ * Get data source name used by CacheableLockManager.
+ *
+ * @return String
+ */
protected abstract String getDatasourceName();
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-01-18 09:18:18 UTC (rev 3815)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-01-19 07:39:43 UTC (rev 3816)
@@ -32,10 +32,17 @@
import org.exoplatform.services.jcr.impl.storage.WorkspaceDataContainerBase;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.BackupException;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.CleanException;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.DataCleaner;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.RestoreException;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.util.BackupTables;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.util.RestoreTableRule;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.util.RestoreTables;
+import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.DBCleanHelper;
+import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.DBCleaner;
+import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.IngresSQLDBCleaner;
+import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.OracleDBCleaner;
+import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.PgSQLDBCleaner;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.GenericConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.HSQLDBConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.MySQLConnectionFactory;
@@ -66,14 +73,17 @@
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.jcr.RepositoryException;
import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.sql.DataSource;
@@ -1210,4 +1220,90 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
+ public DataCleaner getDataCleaner() throws CleanException
+ {
+ DataCleaner dbCleaner;
+
+ try
+ {
+ final DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
+ if (ds == null)
+ {
+ throw new NameNotFoundException("Data source " + dbSourceName + " not found");
+ }
+
+ Connection jdbcConn =
+ SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+ {
+ public Connection run() throws Exception
+ {
+ return ds.getConnection();
+
+ }
+ });
+
+ String dialect = DialectDetecter.detect(jdbcConn.getMetaData());
+
+ List<String> cleanScripts = new ArrayList<String>();
+ if (multiDb)
+ {
+ cleanScripts.add("drop table JCR_MREF");
+ cleanScripts.add("drop table JCR_MVALUE");
+ cleanScripts.add("drop table JCR_MITEM");
+ }
+ else
+ {
+ cleanScripts
+ .add("delete from JCR_SVALUE where exists(select * from JCR_SITEM where JCR_SITEM.ID=JCR_SVALUE.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME='"
+ + containerName + "')");
+ cleanScripts
+ .add("delete from JCR_SREF where exists(select * from JCR_SITEM where JCR_SITEM.ID=JCR_SREF.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME='"
+ + containerName + "')");
+ }
+
+ if (!multiDb && dialect.equals(DBConstants.DB_DIALECT_HSQLDB))
+ {
+ cleanScripts.add("delete from JCR_SITEM where I_CLASS=2 and CONTAINER_NAME='" + containerName + "'");
+
+ dbCleaner = new DBCleaner(jdbcConn, cleanScripts, new DBCleanHelper(containerName, jdbcConn));
+ }
+ else
+ {
+ if (!multiDb)
+ {
+ cleanScripts.add("delete from JCR_SITEM where CONTAINER_NAME='" + containerName + "'");
+ }
+
+ if (dialect.equals(DBConstants.DB_DIALECT_PGSQL))
+ {
+ dbCleaner = new PgSQLDBCleaner(jdbcConn, cleanScripts);
+ }
+ else if (dialect.equals(DBConstants.DB_DIALECT_INGRES))
+ {
+ dbCleaner = new IngresSQLDBCleaner(jdbcConn, cleanScripts);
+ }
+ else if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
+ {
+ dbCleaner = new OracleDBCleaner(jdbcConn, cleanScripts);
+ }
+ else
+ {
+ dbCleaner = new DBCleaner(jdbcConn, cleanScripts);
+ }
+ }
+
+ return dbCleaner;
+ }
+ catch (NamingException e)
+ {
+ throw new CleanException(e);
+ }
+ catch (SQLException e)
+ {
+ throw new CleanException(e);
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/backup/Backupable.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/backup/Backupable.java 2011-01-18 09:18:18 UTC (rev 3815)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/backup/Backupable.java 2011-01-19 07:39:43 UTC (rev 3816)
@@ -51,4 +51,13 @@
*/
void restore(File storageDir) throws RestoreException;
+ /**
+ * Returns DataCleaner for two-phase cleaning.
+ *
+ * @return DataCleaner
+ * @throws CleanException
+ * if any exception occurred
+ */
+ DataCleaner getDataCleaner() throws CleanException;
+
}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/backup/CleanException.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/backup/CleanException.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/backup/CleanException.java 2011-01-19 07:39:43 UTC (rev 3816)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.backup;
+
+/**
+ * @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy Bazko</a>
+ * @version $Id: CleanException.java 3679 2010-12-20 09:24:04Z tolusha $
+ */
+public class CleanException extends Exception
+{
+
+ /**
+ * Constructor CleanException.
+ *
+ * @param message
+ * error message
+ * @param cause
+ * caused exception
+ */
+ public CleanException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ /**
+ * Constructor CleanException.
+ *
+ * @param cause
+ * caused exception
+ */
+ public CleanException(Throwable cause)
+ {
+ super(cause);
+ }
+
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/backup/DataCleaner.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/backup/DataCleaner.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/backup/DataCleaner.java 2011-01-19 07:39:43 UTC (rev 3816)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.backup;
+
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date:
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id: DataCleaner.java 3193 2010-09-28 07:19:57Z tolusha $
+ */
+public interface DataCleaner
+{
+
+ /**
+ * Clean data from storage. Calls prepare and commit methods.
+ * In case of errors calls rollback.
+ *
+ * @throws CleanException
+ * if any exception is occurred
+ */
+ void clean() throws CleanException;
+
+ /**
+ * Prepare data clean from storage.
+ *
+ * @throws CleanException
+ * if any exception is occurred
+ */
+ void prepare() throws CleanException;
+
+ /**
+ * Commit changes.
+ *
+ * @throws CleanException
+ * if any exception is occurred
+ */
+ void commit() throws CleanException;
+
+ /**
+ * Rollback changes.
+ *
+ * @throws CleanException
+ * if any exception is occurred
+ */
+ void rollback() throws CleanException;
+
+ /**
+ * Close DataCleaner.
+ *
+ * @throws CleanException
+ * if any exception is occurred
+ */
+ void close() throws CleanException;
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/DBCleanHelper.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/DBCleanHelper.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/DBCleanHelper.java 2011-01-19 07:39:43 UTC (rev 3816)
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.cleaner;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.CleanException;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class DBCleanHelper
+{
+
+ /**
+ * Logger.
+ */
+ protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBCleanHelper");
+
+ /**
+ * SELECT_ITEMS.
+ */
+ private final String SELECT_ITEMS = "select ID from JCR_SITEM where I_CLASS=1 and CONTAINER_NAME=? and PARENT_ID=?";
+
+ /**
+ * REMOVE_ITEMS.
+ */
+ private final String REMOVE_ITEMS = "delete from JCR_SITEM where I_CLASS=1 and CONTAINER_NAME=? and PARENT_ID=?";
+
+ /**
+ * Container name.
+ */
+ protected final String containerName;
+
+ /**
+ * Connection to database.
+ */
+ protected final Connection connection;
+
+ /**
+ * DBCleanerHelper constructor.
+ */
+ public DBCleanHelper(String containerName, Connection connection)
+ {
+ this.connection = connection;
+ this.containerName = containerName;
+ }
+
+ /**
+ * Removing rows from JCR_SITEM table. Some database do not support cascade delete,
+ * or need special sittings, so query "delete from JCR_SITEM where CONTAINER_NAME=?"
+ * may cause constraint violation exception. In such case will be used deleting like
+ * visitor does. First traverse to the bottom of the tree and then go up to the root
+ * and perform deleting children.
+ *
+ * @throws SQLException
+ * SQL exception.
+ */
+ public void clean() throws CleanException
+ {
+ try
+ {
+ connection.setAutoCommit(false);
+
+ recursiveClean(Constants.ROOT_PARENT_UUID);
+
+ connection.commit();
+ }
+ catch (SQLException e)
+ {
+ try
+ {
+ connection.rollback();
+ }
+ catch (SQLException rollbackException)
+ {
+ LOG.error("Can not rollback changes after exception " + e.getMessage(), rollbackException);
+ }
+ throw new CleanException(e.getMessage(), e);
+ }
+ }
+
+ private void recursiveClean(String parentID) throws SQLException
+ {
+ PreparedStatement selectItems = null;
+ PreparedStatement removeItems = null;
+ ResultSet result = null;
+
+ try
+ {
+ selectItems = connection.prepareStatement(SELECT_ITEMS);
+ selectItems.setString(1, containerName);
+ selectItems.setString(2, parentID);
+
+ final PreparedStatement selectStatement = selectItems;
+ result = (ResultSet)SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ return selectStatement.executeQuery();
+ }
+ });
+
+ // recursive traversing to the bottom of the tree
+ if (result.next())
+ {
+ do
+ {
+ recursiveClean(result.getString(1));
+ }
+ while (result.next());
+
+ // go up to the root and remove all nodes
+ removeItems = connection.prepareStatement(REMOVE_ITEMS);
+ removeItems.setString(1, containerName);
+ removeItems.setString(2, parentID);
+
+ final PreparedStatement deleteStatement = removeItems;
+ SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ deleteStatement.executeUpdate();
+ return null;
+ }
+ });
+ }
+ }
+ finally
+ {
+ if (selectItems != null)
+ {
+ selectItems.close();
+ }
+
+ if (removeItems != null)
+ {
+ removeItems.close();
+ }
+
+ if (result != null)
+ {
+ result.close();
+ }
+ }
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/DBCleaner.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/DBCleaner.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/DBCleaner.java 2011-01-19 07:39:43 UTC (rev 3816)
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.cleaner;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.CleanException;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.DataCleaner;
+import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializer;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * The goal of this class is removing workspace data from database.
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id: DBCleaner.java 3769 2011-01-04 15:36:06Z areshetnyak $
+ */
+public class DBCleaner implements DataCleaner
+{
+ /**
+ * Logger.
+ */
+ protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.WorkspaceDBCleaner");
+
+ /**
+ * Connection to database.
+ */
+ protected final Connection connection;
+
+ /**
+ * Pattern for JCR tables.
+ */
+ protected final Pattern dbObjectNamePattern;
+
+ /**
+ * Common clean scripts for database.
+ */
+ protected final List<String> cleanScripts = new ArrayList<String>();
+
+ /**
+ * DB clean helper.
+ */
+ protected final DBCleanHelper dbCleanHelper;
+
+ /**
+ * WorkspaceDBCleaner constructor.
+ *
+ * @param containerName
+ * container name (workspace name)
+ * @param connection
+ * connection to database where workspace tables is placed
+ */
+ public DBCleaner(Connection connection, List<String> cleanScripts)
+ {
+ this(connection, cleanScripts, null);
+ }
+
+ /**
+ * WorkspaceDBCleaner constructor.
+ *
+ * @param containerName
+ * container name (workspace name)
+ * @param connection
+ * connection to database where workspace tables is placed
+ * @param dbCleanHelper
+ * TODO
+ */
+ public DBCleaner(Connection connection, List<String> cleanScripts, DBCleanHelper dbCleanHelper)
+ {
+ this.dbObjectNamePattern = Pattern.compile(DBInitializer.SQL_OBJECTNAME, Pattern.CASE_INSENSITIVE);
+ this.connection = connection;
+ this.cleanScripts.addAll(cleanScripts);
+ this.dbCleanHelper = dbCleanHelper;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void prepare() throws CleanException
+ {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ {
+ security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
+ }
+
+ String sql = null;
+ Statement st = null;
+ try
+ {
+ connection.setAutoCommit(false);
+ st = connection.createStatement();
+ for (String scr : getDBCleanScripts())
+ {
+ String s = cleanWhitespaces(scr.trim());
+ if (s.length() > 0)
+ {
+ if (!canExecuteQuery(sql = s))
+ {
+ // table from query not found, so try drop other
+ continue;
+ }
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("Execute script: \n[" + sql + "]");
+ }
+ executeQuery(st, sql);
+ }
+ }
+
+ if (dbCleanHelper != null)
+ {
+ dbCleanHelper.clean();
+ }
+ }
+ catch (SQLException e)
+ {
+ throw new CleanException(e);
+ }
+ finally
+ {
+ if (st != null)
+ {
+ try
+ {
+ st.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close the Statement." + e);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void commit() throws CleanException
+ {
+ try
+ {
+ connection.commit();
+ }
+ catch (SQLException e)
+ {
+ throw new CleanException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rollback() throws CleanException
+ {
+ try
+ {
+ connection.rollback();
+ }
+ catch (SQLException e)
+ {
+ throw new CleanException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws CleanException
+ {
+ try
+ {
+ connection.close();
+ }
+ catch (SQLException e)
+ {
+ throw new CleanException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clean() throws CleanException
+ {
+ CleanException cleanExc = null;
+
+ try
+ {
+ prepare();
+ commit();
+ }
+ catch (CleanException e)
+ {
+ cleanExc = e;
+ try
+ {
+ rollback();
+ }
+ catch (CleanException rollbackExc)
+ {
+ LOG.error("Can't rollback changes", rollbackExc);
+ }
+ throw cleanExc;
+ }
+ finally
+ {
+ try
+ {
+ close();
+ }
+ catch (CleanException e)
+ {
+ if (cleanExc != null)
+ {
+ LOG.error("Can't close DataCleaner", e);
+ throw cleanExc;
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ }
+ }
+
+ /**
+ * Check if we can execute query.
+ * If tables used in query does not exists, we can not execute query.
+ */
+ protected boolean canExecuteQuery(String sql) throws SQLException
+ {
+ Matcher tMatcher = dbObjectNamePattern.matcher(sql);
+ while (tMatcher.find())
+ {
+ // get table name
+ String tableName = sql.substring(tMatcher.start(), tMatcher.end());
+ if (!isTableExists(connection, tableName))
+ {
+ LOG.warn("Table [" + tableName + "] from query [" + sql + "] was not found. So query will not be executed.");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Execute query.
+ */
+ protected void executeQuery(final Statement statement, final String sql) throws SQLException
+ {
+ SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ statement.executeUpdate(sql);
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Indicates if table exists or not.
+ */
+ protected boolean isTableExists(Connection conn, String tableName) throws SQLException
+ {
+ ResultSet trs = conn.getMetaData().getTables(null, null, tableName, null);
+ try
+ {
+ boolean res = false;
+ while (trs.next())
+ {
+ res = true; // check for columns/table type matching etc.
+ }
+ return res;
+ }
+ finally
+ {
+ try
+ {
+ trs.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close the ResultSet: " + e);
+ }
+ }
+ }
+
+ /**
+ * Cleans redundant whitespaces from query.
+ */
+ private String cleanWhitespaces(String string)
+ {
+ if (string != null)
+ {
+ char[] cc = string.toCharArray();
+ for (int ci = cc.length - 1; ci > 0; ci--)
+ {
+ if (Character.isWhitespace(cc[ci]))
+ {
+ cc[ci] = ' ';
+ }
+ }
+ return new String(cc);
+ }
+ return string;
+ }
+
+ /**
+ * Get SQL scripts for data cleaning.
+ *
+ * @return
+ * List of sql scripts
+ */
+ protected List<String> getDBCleanScripts()
+ {
+ return cleanScripts;
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/IngresSQLDBCleaner.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/IngresSQLDBCleaner.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/IngresSQLDBCleaner.java 2011-01-19 07:39:43 UTC (rev 3816)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.cleaner;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date:
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id: IngresSQLDBCleaner.java 3655 2010-12-10 08:25:41Z tolusha $
+ */
+public class IngresSQLDBCleaner extends DBCleaner
+{
+
+ /**
+ * OracleSingleDBCleaner constructor.
+ */
+ public IngresSQLDBCleaner(Connection connection, List<String> cleanScripts)
+ {
+ super(connection, cleanScripts);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean isTableExists(Connection conn, String tableName) throws SQLException
+ {
+ return super.isTableExists(conn, tableName.toLowerCase());
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/OracleDBCleaner.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/OracleDBCleaner.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/OracleDBCleaner.java 2011-01-19 07:39:43 UTC (rev 3816)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.cleaner;
+
+import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.DBCleaner;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.List;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date:
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id: OracleDBCleaner.java 3655 2010-12-10 08:25:41Z tolusha $
+ */
+public class OracleDBCleaner extends DBCleaner
+{
+
+ /**
+ * OracleSingleDBCleaner constructor.
+ */
+ public OracleDBCleaner(Connection connection, List<String> cleanScripts)
+ {
+ super(connection, cleanScripts);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean isTableExists(Connection conn, String tableName) throws SQLException
+ {
+ Statement st = null;
+ try
+ {
+ st = conn.createStatement();
+ st.executeUpdate("SELECT 1 FROM " + tableName);
+ return true;
+ }
+ catch (SQLException e)
+ {
+ // check: ORA-00942: table or view does not exist
+ if (e.getMessage().indexOf("ORA-00942") >= 0)
+ return false;
+ throw e;
+ }
+ finally
+ {
+ if (st != null)
+ {
+ try
+ {
+ st.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close the Statement: " + e);
+ }
+ }
+ }
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/PgSQLDBCleaner.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/PgSQLDBCleaner.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/cleaner/PgSQLDBCleaner.java 2011-01-19 07:39:43 UTC (rev 3816)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.cleaner;
+
+import org.exoplatform.services.jcr.impl.storage.jdbc.cleaner.DBCleaner;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date:
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id: PgSQLDBCleaner.java 3655 2010-12-10 08:25:41Z tolusha $
+ */
+public class PgSQLDBCleaner extends DBCleaner
+{
+
+ /**
+ * OracleSingleDBCleaner constructor.
+ */
+ public PgSQLDBCleaner(Connection connection, List<String> cleanScripts)
+ {
+ super(connection, cleanScripts);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean isTableExists(Connection conn, String tableName) throws SQLException
+ {
+ return super.isTableExists(conn, tableName.toLowerCase());
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java 2011-01-19 07:39:43 UTC (rev 3816)
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.util.jdbc;
+
+import org.exoplatform.services.jcr.JcrImplBaseTest;
+import org.exoplatform.services.jcr.RepositoryService;
+import org.exoplatform.services.jcr.config.RepositoryEntry;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
+import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
+import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
+import org.exoplatform.services.jcr.util.IdGenerator;
+import org.exoplatform.services.jcr.util.TesterConfigurationHelper;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.Session;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+
+/**
+ * This test uses "testdbcleaner" datasource to create own test repository with workspace.
+ * So, please, check test-configuration.xml or test-configuration-sjdbc.xml does such datasource binded.
+ *
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date:
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id: TestRemoveWorkspace.java 111 2008-11-11 11:11:11Z serg $
+ */
+public class TestDBCleaner extends JcrImplBaseTest
+{
+ private final static String DS_NAME = "testdbcleaner";
+
+ private final TesterConfigurationHelper helper;
+
+ private WorkspaceEntry wsEntry;
+
+ public TestDBCleaner()
+ {
+ super();
+ this.helper = TesterConfigurationHelper.getInstence();
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ wsEntry = (WorkspaceEntry)session.getContainer().getComponentInstanceOfType(WorkspaceEntry.class);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ // drop any table
+ DataSource ds = (DataSource)new InitialContext().lookup(DS_NAME);
+ Connection conn = ds.getConnection();
+ Statement statement = conn.createStatement();
+ try
+ {
+ statement.executeUpdate("drop table JCR_SREF");
+ }
+ catch (SQLException e)
+ {
+ }
+ try
+ {
+ statement.executeUpdate("drop table JCR_SVALUE");
+ }
+ catch (SQLException e)
+ {
+ }
+ try
+ {
+ statement.executeUpdate("drop table JCR_SITEM");
+ }
+ catch (SQLException e)
+ {
+ }
+ try
+ {
+ statement.executeUpdate("drop table JCR_MREF");
+ }
+ catch (SQLException e)
+ {
+ }
+ try
+ {
+ statement.executeUpdate("drop table JCR_MVALUE");
+ }
+ catch (SQLException e)
+ {
+ }
+ try
+ {
+ statement.executeUpdate("drop table JCR_MITEM");
+ }
+ catch (SQLException e)
+ {
+ }
+ try
+ {
+ statement.executeUpdate("drop table JCR_MCONTAINER");
+ }
+ catch (SQLException e)
+ {
+ }
+ try
+ {
+ statement.executeUpdate("drop table JCR_SCONTAINER");
+ }
+ catch (SQLException e)
+ {
+ }
+ if (statement != null)
+ {
+ try
+ {
+ statement.close();
+ }
+ catch (SQLException e)
+ {
+ }
+ }
+ super.tearDown();
+ }
+
+ public void testRemoveRepositoryMultiDB() throws Exception
+ {
+ String repositoryName = "repoTestRemoveMulti";
+
+ RepositoryEntry repositoryEntry = createMultiDB(repositoryName);
+
+ RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
+ RepositoryImpl newRepository = (RepositoryImpl)service.getRepository(repositoryName);
+ assertTrue(service.canRemoveRepository(repositoryName));
+
+ String wsName = repositoryEntry.getWorkspaceEntries().get(0).getName();
+ SessionImpl sess = newRepository.getSystemSession(wsName);
+
+ // add nodes to workspaces and check it via datasource
+ NodeImpl node = (NodeImpl)sess.getRootNode().addNode("testNode");
+ String id = node.getData().getIdentifier();
+ sess.save();
+ sess.logout();
+
+ DataSource ds = (DataSource)new InitialContext().lookup(DS_NAME);
+ Connection conn = ds.getConnection();
+ Statement statement = conn.createStatement();
+ ResultSet res = statement.executeQuery("select * from JCR_MITEM where ID='" + id + "'");
+ assertTrue(res.next());
+
+ // remove content
+ List<Backupable> backupable = new ArrayList<Backupable>();
+ for (String name : repositoryService.getRepository(repositoryName).getWorkspaceNames())
+ {
+ backupable.addAll(repositoryService.getRepository(repositoryName).getWorkspaceContainer(name)
+ .getComponentInstancesOfType(Backupable.class));
+ }
+
+ for (Backupable component : backupable)
+ {
+ component.getDataCleaner().clean();
+ }
+
+ // check - does JCR_SITEM become empty
+ try
+ {
+ res = statement.executeQuery("select * from JCR_MITEM where ID='" + id + "'");
+ fail();
+ }
+ catch (SQLException e)
+ {
+ //ok
+ }
+ statement.close();
+
+ service.removeRepository(repositoryName);
+ }
+
+ public void testRemoveRepositorySingleDB() throws Exception
+ {
+ String repositoryName = "repoTestRemoveSingle";
+
+ RepositoryEntry repositoryEntry = createSingleDB(repositoryName);
+
+ RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
+ RepositoryImpl newRepository = (RepositoryImpl)service.getRepository(repositoryName);
+ assertTrue(service.canRemoveRepository(repositoryName));
+
+ String wsName = repositoryEntry.getWorkspaceEntries().get(0).getName();
+ SessionImpl sess = newRepository.getSystemSession(wsName);
+
+ // now add nodes to workspaces and check it via datasource
+ NodeImpl node = (NodeImpl)sess.getRootNode().addNode("testNode");
+ String id = node.getData().getIdentifier();
+ sess.save();
+ sess.logout();
+
+ DataSource ds = (DataSource)new InitialContext().lookup(DS_NAME);
+ Connection conn = ds.getConnection();
+ Statement statement = conn.createStatement();
+ ResultSet res = statement.executeQuery("select * from JCR_SITEM where ID='" + wsName + id + "'");
+ assertTrue(res.next());
+
+ // remove content
+ List<Backupable> backupable = new ArrayList<Backupable>();
+ for (String name : repositoryService.getRepository(repositoryName).getWorkspaceNames())
+ {
+ backupable.addAll(repositoryService.getRepository(repositoryName).getWorkspaceContainer(name)
+ .getComponentInstancesOfType(Backupable.class));
+ }
+
+ for (Backupable component : backupable)
+ {
+ component.getDataCleaner().clean();
+ }
+
+ // check - does JCR_SITEM become empty
+ res = statement.executeQuery("select * from JCR_SITEM where ID='" + wsName + id + "'");
+ assertFalse(res.next());
+ statement.close();
+
+ service.removeRepository(repositoryName);
+ }
+
+ public void testRemoveWorkspaceMultiDB() throws Exception
+ {
+ String repositoryName = "repoTestRemoveMulti";
+
+ RepositoryEntry repositoryEntry = createMultiDB(repositoryName);
+
+ RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
+ RepositoryImpl newRepository = (RepositoryImpl)service.getRepository(repositoryName);
+ assertTrue(service.canRemoveRepository(repositoryName));
+
+ String wsName = repositoryEntry.getWorkspaceEntries().get(0).getName();
+ SessionImpl sess = newRepository.getSystemSession(wsName);
+
+ // now add nodes to workspaces and check it via datasource
+ NodeImpl node = (NodeImpl)sess.getRootNode().addNode("testNode");
+ String id = node.getData().getIdentifier();
+ sess.save();
+ sess.logout();
+
+ DataSource ds = (DataSource)new InitialContext().lookup(DS_NAME);
+ Connection conn = ds.getConnection();
+ Statement statement = conn.createStatement();
+ ResultSet res = statement.executeQuery("select * from JCR_MITEM where ID='" + id + "'");
+ assertTrue(res.next());
+
+ // remove content
+ List<Backupable> backupable =
+ repositoryService.getRepository(repositoryName).getWorkspaceContainer(wsName)
+ .getComponentInstancesOfType(Backupable.class);
+
+ for (Backupable component : backupable)
+ {
+ component.getDataCleaner().clean();
+ }
+
+ // check - does JCR_SITEM become empty
+ try
+ {
+ res = statement.executeQuery("select * from JCR_MITEM where ID='" + id + "'");
+ fail();
+ }
+ catch (SQLException e)
+ {
+ //ok
+ }
+ statement.close();
+
+ service.removeRepository(repositoryName);
+ }
+
+ public void testRemoveWorkspaceSingleDB() throws Exception
+ {
+ String repositoryName = "repoTestRemoveSingle";
+
+ RepositoryEntry repositoryEntry = createSingleDB(repositoryName);
+
+ WorkspaceEntry workspaceEntry = repositoryEntry.getWorkspaceEntries().get(0);
+
+ RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
+ Session sess = ((RepositoryImpl)service.getRepository(repositoryName)).getSystemSession(workspaceEntry.getName());
+ Node root2 = sess.getRootNode();
+ assertNotNull(root2);
+
+ NodeImpl n = (NodeImpl)root2.addNode("node1");
+ assertTrue(root2.hasNode("node1"));
+
+ String id = n.getData().getIdentifier();
+
+ sess.save();
+
+ n.setProperty("prop", "some value");
+ n.setProperty("prop2", "some value two");
+ sess.save();
+
+ Node n2 = n.addNode("subnode");
+ n2.setProperty("prop", "some value");
+ n2.addNode("subnode1");
+ n2.addNode("subnode2");
+ n2.addNode("subnode2");
+ sess.save();
+ sess.logout();
+
+ DataSource ds = (DataSource)new InitialContext().lookup(DS_NAME);
+ Connection conn = ds.getConnection();
+ Statement statement = conn.createStatement();
+ ResultSet res =
+ statement.executeQuery("select * from JCR_SITEM where ID='" + workspaceEntry.getName() + id + "'");
+ assertTrue(res.next());
+
+ // remove content
+ List<Backupable> backupable =
+ repositoryService.getRepository(repositoryName).getWorkspaceContainer(workspaceEntry.getName())
+ .getComponentInstancesOfType(Backupable.class);
+
+ for (Backupable component : backupable)
+ {
+ component.getDataCleaner().clean();
+ }
+
+ // check - does JCR_SITEM become empty
+ res = statement.executeQuery("select * from JCR_SITEM where ID='" + workspaceEntry.getName() + id + "'");
+ assertFalse(res.next());
+ statement.close();
+
+ service.removeRepository(repositoryName);
+ }
+
+ private RepositoryEntry createMultiDB(String repositoryName) throws Exception
+ {
+ RepositoryEntry repositoryEntry = new RepositoryEntry();
+
+ repositoryEntry.setName(repositoryName);
+ repositoryEntry.setSessionTimeOut(3600000);
+ repositoryEntry.setAuthenticationPolicy("org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator");
+ repositoryEntry.setSecurityDomain("exo-domain");
+ repositoryEntry.setSystemWorkspaceName(repositoryName + "ws");
+ repositoryEntry.setDefaultWorkspaceName(repositoryName + "ws");
+
+ WorkspaceEntry workspaceEntry =
+ helper.getNewWs(repositoryName + "ws", true, DS_NAME, "target/temp/values/" + IdGenerator.generate(),
+ wsEntry.getContainer(), false);
+
+ repositoryEntry.addWorkspace(workspaceEntry);
+
+ RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
+
+ service.createRepository(repositoryEntry);
+ return repositoryEntry;
+ }
+
+ private RepositoryEntry createSingleDB(String repositoryName) throws Exception
+ {
+ RepositoryEntry repositoryEntry = new RepositoryEntry();
+
+ repositoryEntry.setName(repositoryName);
+ repositoryEntry.setSessionTimeOut(3600000);
+ repositoryEntry.setAuthenticationPolicy("org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator");
+ repositoryEntry.setSecurityDomain("exo-domain");
+ repositoryEntry.setSystemWorkspaceName(repositoryName + "ws");
+ repositoryEntry.setDefaultWorkspaceName(repositoryName + "ws");
+
+ WorkspaceEntry workspaceEntry =
+ helper.getNewWs(repositoryName + "ws", false, DS_NAME, "target/temp/values/" + IdGenerator.generate(),
+ wsEntry.getContainer(), false);
+
+ repositoryEntry.addWorkspace(workspaceEntry);
+
+ WorkspaceEntry secondWs =
+ helper.getNewWs(repositoryName + "ws2", false, DS_NAME, "target/temp/values/" + IdGenerator.generate(),
+ wsEntry.getContainer(), false);
+ repositoryEntry.addWorkspace(secondWs);
+
+ RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
+
+ service.createRepository(repositoryEntry);
+ return repositoryEntry;
+ }
+}
Deleted: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleanerService.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleanerService.java 2011-01-18 09:18:18 UTC (rev 3815)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleanerService.java 2011-01-19 07:39:43 UTC (rev 3816)
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2003-2010 eXo Platform SAS.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see<http://www.gnu.org/licenses/>.
- */
-package org.exoplatform.services.jcr.impl.util.jdbc;
-
-import org.exoplatform.services.jcr.JcrImplBaseTest;
-import org.exoplatform.services.jcr.RepositoryService;
-import org.exoplatform.services.jcr.config.RepositoryEntry;
-import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.impl.core.NodeImpl;
-import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
-import org.exoplatform.services.jcr.impl.core.SessionImpl;
-import org.exoplatform.services.jcr.impl.util.jdbc.cleaner.DBCleanerService;
-import org.exoplatform.services.jcr.util.IdGenerator;
-import org.exoplatform.services.jcr.util.TesterConfigurationHelper;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import javax.jcr.Node;
-import javax.jcr.Session;
-import javax.naming.InitialContext;
-import javax.sql.DataSource;
-
-/**
- * This test uses "testdbcleaner" datasource to create own test repository with workspace.
- * So, please, check test-configuration.xml or test-configuration-sjdbc.xml does such datasource binded.
- *
- * Created by The eXo Platform SAS.
- *
- * <br/>Date:
- *
- * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
- * @version $Id: TestRemoveWorkspace.java 111 2008-11-11 11:11:11Z serg $
- */
-public class TestDBCleanerService extends JcrImplBaseTest
-{
- private final static String DS_NAME = "testdbcleaner";
-
- private final TesterConfigurationHelper helper;
-
- private WorkspaceEntry wsEntry;
-
- public TestDBCleanerService()
- {
- super();
- this.helper = TesterConfigurationHelper.getInstence();
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public void setUp() throws Exception
- {
- super.setUp();
- wsEntry = (WorkspaceEntry)session.getContainer().getComponentInstanceOfType(WorkspaceEntry.class);
- }
-
- @Override
- public void tearDown() throws Exception
- {
- // drop any table
- DataSource ds = (DataSource)new InitialContext().lookup(DS_NAME);
- Connection conn = ds.getConnection();
- Statement statement = conn.createStatement();
- try
- {
- statement.executeUpdate("drop table JCR_SREF");
- }
- catch (SQLException e)
- {
- }
- try
- {
- statement.executeUpdate("drop table JCR_SVALUE");
- }
- catch (SQLException e)
- {
- }
- try
- {
- statement.executeUpdate("drop table JCR_SITEM");
- }
- catch (SQLException e)
- {
- }
- try
- {
- statement.executeUpdate("drop table JCR_MREF");
- }
- catch (SQLException e)
- {
- }
- try
- {
- statement.executeUpdate("drop table JCR_MVALUE");
- }
- catch (SQLException e)
- {
- }
- try
- {
- statement.executeUpdate("drop table JCR_MITEM");
- }
- catch (SQLException e)
- {
- }
- try
- {
- statement.executeUpdate("drop table JCR_MCONTAINER");
- }
- catch (SQLException e)
- {
- }
- try
- {
- statement.executeUpdate("drop table JCR_SCONTAINER");
- }
- catch (SQLException e)
- {
- }
- if (statement != null)
- {
- try
- {
- statement.close();
- }
- catch (SQLException e)
- {
- }
- }
- super.tearDown();
- }
-
- public void testRemoveRepositoryMultiDB() throws Exception
- {
- String repositoryName = "repoTestRemoveMulti";
-
- RepositoryEntry repositoryEntry = createMultiDB(repositoryName);
-
- RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
- RepositoryImpl newRepository = (RepositoryImpl)service.getRepository(repositoryName);
- assertTrue(service.canRemoveRepository(repositoryName));
-
- String wsName = repositoryEntry.getWorkspaceEntries().get(0).getName();
- SessionImpl sess = newRepository.getSystemSession(wsName);
-
- // add nodes to workspaces and check it via datasource
- NodeImpl node = (NodeImpl)sess.getRootNode().addNode("testNode");
- String id = node.getData().getIdentifier();
- sess.save();
- sess.logout();
-
- DataSource ds = (DataSource)new InitialContext().lookup(DS_NAME);
- Connection conn = ds.getConnection();
- Statement statement = conn.createStatement();
- ResultSet res = statement.executeQuery("select * from JCR_MITEM where ID='" + id + "'");
- assertTrue(res.next());
-
- // remove repository;
- new DBCleanerService().cleanRepositoryData(repositoryEntry);
-
- // check - does JCR_SITEM become empty
- try
- {
- res = statement.executeQuery("select * from JCR_MITEM where ID='" + id + "'");
- fail();
- }
- catch (SQLException e)
- {
- //ok
- }
- statement.close();
-
- service.removeRepository(repositoryName);
- }
-
- public void testRemoveRepositorySingleDB() throws Exception
- {
- String repositoryName = "repoTestRemoveSingle";
-
- RepositoryEntry repositoryEntry = createSingleDB(repositoryName);
-
- RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
- RepositoryImpl newRepository = (RepositoryImpl)service.getRepository(repositoryName);
- assertTrue(service.canRemoveRepository(repositoryName));
-
- String wsName = repositoryEntry.getWorkspaceEntries().get(0).getName();
- SessionImpl sess = newRepository.getSystemSession(wsName);
-
- // now add nodes to workspaces and check it via datasource
- NodeImpl node = (NodeImpl)sess.getRootNode().addNode("testNode");
- String id = node.getData().getIdentifier();
- sess.save();
- sess.logout();
-
- DataSource ds = (DataSource)new InitialContext().lookup(DS_NAME);
- Connection conn = ds.getConnection();
- Statement statement = conn.createStatement();
- ResultSet res = statement.executeQuery("select * from JCR_SITEM where ID='" + wsName + id + "'");
- assertTrue(res.next());
-
- // remove repository content
- new DBCleanerService().cleanRepositoryData(repositoryEntry);
-
- // check - does JCR_SITEM become empty
- res = statement.executeQuery("select * from JCR_SITEM where ID='" + wsName + id + "'");
- assertFalse(res.next());
- statement.close();
-
- service.removeRepository(repositoryName);
- }
-
- public void testRemoveWorkspaceMultiDB() throws Exception
- {
- String repositoryName = "repoTestRemoveMulti";
-
- RepositoryEntry repositoryEntry = createMultiDB(repositoryName);
-
- RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
- RepositoryImpl newRepository = (RepositoryImpl)service.getRepository(repositoryName);
- assertTrue(service.canRemoveRepository(repositoryName));
-
- String wsName = repositoryEntry.getWorkspaceEntries().get(0).getName();
- SessionImpl sess = newRepository.getSystemSession(wsName);
-
- // now add nodes to workspaces and check it via datasource
- NodeImpl node = (NodeImpl)sess.getRootNode().addNode("testNode");
- String id = node.getData().getIdentifier();
- sess.save();
- sess.logout();
-
- DataSource ds = (DataSource)new InitialContext().lookup(DS_NAME);
- Connection conn = ds.getConnection();
- Statement statement = conn.createStatement();
- ResultSet res = statement.executeQuery("select * from JCR_MITEM where ID='" + id + "'");
- assertTrue(res.next());
-
- // remove workspace data from database
- new DBCleanerService().cleanWorkspaceData(repositoryEntry.getWorkspaceEntries().get(0));
-
- // check - does JCR_SITEM become empty
- try
- {
- res = statement.executeQuery("select * from JCR_MITEM where ID='" + id + "'");
- fail();
- }
- catch (SQLException e)
- {
- //ok
- }
- statement.close();
-
- service.removeRepository(repositoryName);
- }
-
- public void testRemoveWorkspaceSingleDB() throws Exception
- {
- String repositoryName = "repoTestRemoveSingle";
-
- RepositoryEntry repositoryEntry = createSingleDB(repositoryName);
-
- WorkspaceEntry workspaceEntry = repositoryEntry.getWorkspaceEntries().get(0);
-
- RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
- Session sess = ((RepositoryImpl)service.getRepository(repositoryName)).getSystemSession(workspaceEntry.getName());
- Node root2 = sess.getRootNode();
- assertNotNull(root2);
-
- NodeImpl n = (NodeImpl)root2.addNode("node1");
- assertTrue(root2.hasNode("node1"));
-
- String id = n.getData().getIdentifier();
-
- sess.save();
-
- n.setProperty("prop", "some value");
- n.setProperty("prop2", "some value two");
- sess.save();
-
- Node n2 = n.addNode("subnode");
- n2.setProperty("prop", "some value");
- n2.addNode("subnode1");
- n2.addNode("subnode2");
- n2.addNode("subnode2");
- sess.save();
- sess.logout();
-
- DataSource ds = (DataSource)new InitialContext().lookup(DS_NAME);
- Connection conn = ds.getConnection();
- Statement statement = conn.createStatement();
- ResultSet res =
- statement.executeQuery("select * from JCR_SITEM where ID='" + workspaceEntry.getName() + id + "'");
- assertTrue(res.next());
-
- // remove workspace data from database
- new DBCleanerService().cleanWorkspaceData(workspaceEntry);
-
- // check - does JCR_SITEM become empty
- res = statement.executeQuery("select * from JCR_SITEM where ID='" + workspaceEntry.getName() + id + "'");
- assertFalse(res.next());
- statement.close();
-
- service.removeRepository(repositoryName);
- }
-
- private RepositoryEntry createMultiDB(String repositoryName) throws Exception
- {
- RepositoryEntry repositoryEntry = new RepositoryEntry();
-
- repositoryEntry.setName(repositoryName);
- repositoryEntry.setSessionTimeOut(3600000);
- repositoryEntry.setAuthenticationPolicy("org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator");
- repositoryEntry.setSecurityDomain("exo-domain");
- repositoryEntry.setSystemWorkspaceName(repositoryName + "ws");
- repositoryEntry.setDefaultWorkspaceName(repositoryName + "ws");
-
- WorkspaceEntry workspaceEntry =
- helper.getNewWs(repositoryName + "ws", true, DS_NAME, "target/temp/values/" + IdGenerator.generate(),
- wsEntry.getContainer(), false);
-
- repositoryEntry.addWorkspace(workspaceEntry);
-
- RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
-
- service.createRepository(repositoryEntry);
- return repositoryEntry;
- }
-
- private RepositoryEntry createSingleDB(String repositoryName) throws Exception
- {
- RepositoryEntry repositoryEntry = new RepositoryEntry();
-
- repositoryEntry.setName(repositoryName);
- repositoryEntry.setSessionTimeOut(3600000);
- repositoryEntry.setAuthenticationPolicy("org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator");
- repositoryEntry.setSecurityDomain("exo-domain");
- repositoryEntry.setSystemWorkspaceName(repositoryName + "ws");
- repositoryEntry.setDefaultWorkspaceName(repositoryName + "ws");
-
- WorkspaceEntry workspaceEntry =
- helper.getNewWs(repositoryName + "ws", false, DS_NAME, "target/temp/values/" + IdGenerator.generate(),
- wsEntry.getContainer(), false);
-
- repositoryEntry.addWorkspace(workspaceEntry);
-
- WorkspaceEntry secondWs =
- helper.getNewWs(repositoryName + "ws2", false, DS_NAME, "target/temp/values/" + IdGenerator.generate(),
- wsEntry.getContainer(), false);
- repositoryEntry.addWorkspace(secondWs);
-
- RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
-
- service.createRepository(repositoryEntry);
- return repositoryEntry;
- }
-}
13 years, 4 months
exo-jcr SVN: r3815 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-01-18 04:18:18 -0500 (Tue, 18 Jan 2011)
New Revision: 3815
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/DefaultChangesFilter.java
Log:
EXOJCR-1135 : fixed "parentHandler.logErrorChanges(parentRemovedNodes, parentAddedNodes)"
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/DefaultChangesFilter.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/DefaultChangesFilter.java 2011-01-17 11:03:16 UTC (rev 3814)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/DefaultChangesFilter.java 2011-01-18 09:18:18 UTC (rev 3815)
@@ -117,7 +117,7 @@
log.error("Error indexing changes " + e, e);
try
{
- parentHandler.logErrorChanges(removedNodes, addedNodes);
+ parentHandler.logErrorChanges(parentRemovedNodes, parentAddedNodes);
}
catch (IOException ioe)
{
13 years, 4 months
exo-jcr SVN: r3814 - in ws/trunk/exo.ws.rest.core/src: main/java/org/exoplatform/services/rest/impl and 5 other directories.
by do-not-reply@jboss.org
Author: aparfonov
Date: 2011-01-17 06:03:16 -0500 (Mon, 17 Jan 2011)
New Revision: 3814
Added:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/BaseObjectModel.java
Modified:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/FieldInjectorImpl.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/FilterDescriptorImpl.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JsonEntityProvider.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/ProviderDescriptorImpl.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/AbstractResourceDescriptorImpl.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/ResourceDescriptorValidator.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/wadl/WadlProcessor.java
ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/resource/ResourceDescriptorTest.java
ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/wadl/WadlProcessorTest.java
Log:
EXOJCR-1152
Added: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/BaseObjectModel.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/BaseObjectModel.java (rev 0)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/BaseObjectModel.java 2011-01-17 11:03:16 UTC (rev 3814)
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.rest;
+
+import org.exoplatform.services.rest.impl.ConstructorDescriptorImpl;
+import org.exoplatform.services.rest.impl.FieldInjectorImpl;
+import org.exoplatform.services.rest.impl.MultivaluedMapImpl;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+/**
+ * @author <a href="mailto:andrey.parfonov@exoplatform.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public abstract class BaseObjectModel implements ObjectModel
+{
+ protected final Class<?> clazz;
+ /** Resource class constructors. */
+ protected final List<ConstructorDescriptor> constructors;
+ /** Resource class fields. */
+ protected final List<FieldInjector> fields;
+ /** Optional data. */
+ protected MultivaluedMapImpl properties;
+
+ public BaseObjectModel(Class<?> clazz, ComponentLifecycleScope scope)
+ {
+ this.clazz = clazz;
+ this.constructors = new ArrayList<ConstructorDescriptor>();
+ this.fields = new ArrayList<FieldInjector>();
+ if (scope == ComponentLifecycleScope.PER_REQUEST)
+ {
+ Constructor<?>[] jConstructors =
+ AccessController.doPrivileged(new PrivilegedAction<Constructor<?>[]>() {
+ public Constructor<?>[] run()
+ {
+ return BaseObjectModel.this.clazz.getConstructors();
+ }
+ });
+ for (Constructor<?> constructor : jConstructors)
+ {
+ constructors.add(new ConstructorDescriptorImpl(clazz, constructor));
+ }
+ if (constructors.size() == 0)
+ {
+ String msg = "Not found accepted constructors for provider class " + clazz.getName();
+ throw new RuntimeException(msg);
+ }
+ // Sort constructors in number parameters order
+ if (constructors.size() > 1)
+ {
+ Collections.sort(constructors, ConstructorDescriptorImpl.CONSTRUCTOR_COMPARATOR);
+ }
+ // process field
+ java.lang.reflect.Field[] jfields =
+ AccessController.doPrivileged(new PrivilegedAction<java.lang.reflect.Field[]>() {
+ public java.lang.reflect.Field[] run()
+ {
+ return BaseObjectModel.this.clazz.getDeclaredFields();
+ }
+ });
+ for (java.lang.reflect.Field jfield : jfields)
+ {
+ fields.add(new FieldInjectorImpl(clazz, jfield));
+ }
+ Class<?> sc = clazz.getSuperclass();
+ Package _package = clazz.getPackage();
+ String resourcePackageName = _package != null ? _package.getName() : null;
+ while (sc != Object.class)
+ {
+ for (java.lang.reflect.Field jfield : sc.getDeclaredFields())
+ {
+ int modif = jfield.getModifiers();
+ Package package1 = clazz.getPackage();
+ String scPackageName = package1 != null ? package1.getName() : null;
+ if (!Modifier.isPrivate(modif))
+ {
+ if (Modifier.isPublic(modif)
+ || Modifier.isProtected(modif)
+ || (!Modifier.isPrivate(modif) && ((resourcePackageName == null && scPackageName == null) || resourcePackageName
+ .equals(scPackageName))))
+ {
+ FieldInjector inj = new FieldInjectorImpl(clazz, jfield);
+ // Skip not annotated field. They will be not injected from container.
+ if (inj.getAnnotation() != null)
+ {
+ fields.add(new FieldInjectorImpl(clazz, jfield));
+ }
+ }
+ }
+ }
+ sc = sc.getSuperclass();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Class<?> getObjectClass()
+ {
+ return clazz;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<ConstructorDescriptor> getConstructorDescriptors()
+ {
+ return constructors;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<FieldInjector> getFieldInjectors()
+ {
+ return fields;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public MultivaluedMap<String, String> getProperties()
+ {
+ if (properties == null)
+ {
+ properties = new MultivaluedMapImpl();
+ }
+ return properties;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<String> getProperty(String key)
+ {
+ if (properties != null)
+ {
+ return properties.get(key);
+ }
+ return null;
+ }
+}
Property changes on: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/BaseObjectModel.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/FieldInjectorImpl.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/FieldInjectorImpl.java 2011-01-17 10:31:47 UTC (rev 3813)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/FieldInjectorImpl.java 2011-01-17 11:03:16 UTC (rev 3814)
@@ -18,7 +18,6 @@
*/
package org.exoplatform.services.rest.impl;
-import org.exoplatform.commons.utils.SecurityHelper;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.rest.ApplicationContext;
@@ -31,6 +30,7 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
+import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.List;
@@ -66,8 +66,9 @@
private final Annotation annotation;
/**
- * Default value for this parameter, default value can be used if there is not
- * found required parameter in request. See {@link javax.ws.rs.DefaultValue}.
+ * Default value for this parameter, default value can be used if there is
+ * not found required parameter in request. See
+ * {@link javax.ws.rs.DefaultValue}.
*/
private final String defaultValue;
@@ -76,7 +77,6 @@
*/
private final boolean encoded;
-
/** See {@link java.lang.reflect.Field} . */
private final java.lang.reflect.Field jfield;
@@ -214,8 +214,7 @@
{
if (!Modifier.isPublic(jfield.getModifiers()))
{
- SecurityHelper.doPrivilegedAction(new PrivilegedAction<Void>()
- {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run()
{
jfield.setAccessible(true);
@@ -255,9 +254,9 @@
public String toString()
{
StringBuffer sb = new StringBuffer("[ FieldInjectorImpl: ");
- sb.append("annotation: " + getAnnotation()).append("; type: " + getParameterClass()).append(
- "; generic-type : " + getGenericType()).append("; default-value: " + getDefaultValue()).append(
- "; encoded: " + isEncoded()).append(" ]");
+ sb.append("annotation: " + getAnnotation()).append("; type: " + getParameterClass())
+ .append("; generic-type : " + getGenericType()).append("; default-value: " + getDefaultValue())
+ .append("; encoded: " + isEncoded()).append(" ]");
return sb.toString();
}
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/FilterDescriptorImpl.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/FilterDescriptorImpl.java 2011-01-17 10:31:47 UTC (rev 3813)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/FilterDescriptorImpl.java 2011-01-17 11:03:16 UTC (rev 3814)
@@ -18,35 +18,22 @@
*/
package org.exoplatform.services.rest.impl;
+import org.exoplatform.services.rest.BaseObjectModel;
import org.exoplatform.services.rest.ComponentLifecycleScope;
-import org.exoplatform.services.rest.ConstructorDescriptor;
-import org.exoplatform.services.rest.FieldInjector;
import org.exoplatform.services.rest.FilterDescriptor;
import org.exoplatform.services.rest.impl.resource.PathValue;
import org.exoplatform.services.rest.resource.ResourceDescriptorVisitor;
import org.exoplatform.services.rest.uri.UriPattern;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
import javax.ws.rs.Path;
-import javax.ws.rs.core.MultivaluedMap;
/**
* @author <a href="mailto:andrew00x@gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
-public class FilterDescriptorImpl implements FilterDescriptor
+public class FilterDescriptorImpl extends BaseObjectModel implements FilterDescriptor
{
-
/**
- * Filter class.
- */
- private final Class<?> filterClass;
-
- /**
* @see PathValue
*/
private final PathValue path;
@@ -57,21 +44,6 @@
private final UriPattern uriPattern;
/**
- * Filter class constructors.
- *
- * @see ConstructorDescriptor
- */
- private final List<ConstructorDescriptor> constructors;
-
- /**
- * Filter class fields.
- */
- private final List<FieldInjector> fields;
-
- /** Optional data. */
- private MultivaluedMap<String, String> properties;
-
- /**
* @param filterClass {@link Class} of filter
*/
public FilterDescriptorImpl(Class<?> filterClass)
@@ -94,6 +66,7 @@
*/
private FilterDescriptorImpl(Class<?> filterClass, ComponentLifecycleScope scope)
{
+ super(filterClass, scope);
final Path p = filterClass.getAnnotation(Path.class);
if (p != null)
{
@@ -105,33 +78,6 @@
this.path = null;
this.uriPattern = null;
}
-
- this.filterClass = filterClass;
-
- this.constructors = new ArrayList<ConstructorDescriptor>();
- this.fields = new ArrayList<FieldInjector>();
- if (scope == ComponentLifecycleScope.PER_REQUEST)
- {
- for (Constructor<?> constructor : filterClass.getConstructors())
- {
- constructors.add(new ConstructorDescriptorImpl(filterClass, constructor));
- }
- if (constructors.size() == 0)
- {
- String msg = "Not found accepted constructors for filter class " + filterClass.getName();
- throw new RuntimeException(msg);
- }
- // Sort constructors in number parameters order
- if (constructors.size() > 1)
- {
- Collections.sort(constructors, ConstructorDescriptorImpl.CONSTRUCTOR_COMPARATOR);
- }
- // process field
- for (java.lang.reflect.Field jfield : filterClass.getDeclaredFields())
- {
- fields.add(new FieldInjectorImpl(filterClass, jfield));
- }
- }
}
/**
@@ -145,30 +91,6 @@
/**
* {@inheritDoc}
*/
- public List<ConstructorDescriptor> getConstructorDescriptors()
- {
- return constructors;
- }
-
- /**
- * {@inheritDoc}
- */
- public List<FieldInjector> getFieldInjectors()
- {
- return fields;
- }
-
- /**
- * {@inheritDoc}
- */
- public Class<?> getObjectClass()
- {
- return filterClass;
- }
-
- /**
- * {@inheritDoc}
- */
public PathValue getPathValue()
{
return path;
@@ -177,30 +99,6 @@
/**
* {@inheritDoc}
*/
- public MultivaluedMap<String, String> getProperties()
- {
- if (properties == null)
- {
- properties = new MultivaluedMapImpl();
- }
- return properties;
- }
-
- /**
- * {@inheritDoc}
- */
- public List<String> getProperty(String key)
- {
- if (properties != null)
- {
- return properties.get(key);
- }
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
public UriPattern getUriPattern()
{
return uriPattern;
@@ -217,5 +115,4 @@
getConstructorDescriptors() + "; ").append(getFieldInjectors()).append(" ]");
return sb.toString();
}
-
}
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JsonEntityProvider.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JsonEntityProvider.java 2011-01-17 10:31:47 UTC (rev 3813)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JsonEntityProvider.java 2011-01-17 11:03:16 UTC (rev 3814)
@@ -169,7 +169,6 @@
{
try
{
- JsonGeneratorImpl generator = new JsonGeneratorImpl();
JsonValue jsonValue = null;
if (t instanceof JsonValue)
{
@@ -178,6 +177,7 @@
}
else
{
+ JsonGeneratorImpl generator = new JsonGeneratorImpl();
Types jtype = JsonUtils.getType(type);
if (jtype == Types.ARRAY_BOOLEAN || jtype == Types.ARRAY_BYTE || jtype == Types.ARRAY_SHORT
|| jtype == Types.ARRAY_INT || jtype == Types.ARRAY_LONG || jtype == Types.ARRAY_FLOAT
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/ProviderDescriptorImpl.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/ProviderDescriptorImpl.java 2011-01-17 10:31:47 UTC (rev 3813)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/ProviderDescriptorImpl.java 2011-01-17 11:03:16 UTC (rev 3814)
@@ -18,51 +18,25 @@
*/
package org.exoplatform.services.rest.impl.provider;
+import org.exoplatform.services.rest.BaseObjectModel;
import org.exoplatform.services.rest.ComponentLifecycleScope;
-import org.exoplatform.services.rest.ConstructorDescriptor;
-import org.exoplatform.services.rest.FieldInjector;
-import org.exoplatform.services.rest.impl.ConstructorDescriptorImpl;
-import org.exoplatform.services.rest.impl.FieldInjectorImpl;
-import org.exoplatform.services.rest.impl.MultivaluedMapImpl;
import org.exoplatform.services.rest.impl.header.MediaTypeHelper;
import org.exoplatform.services.rest.provider.ProviderDescriptor;
import org.exoplatform.services.rest.resource.ResourceDescriptorVisitor;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
/**
* @author <a href="mailto:andrew00x@gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
-public class ProviderDescriptorImpl implements ProviderDescriptor
+public class ProviderDescriptorImpl extends BaseObjectModel implements ProviderDescriptor
{
-
/**
- * Provider class.
- */
- private final Class<?> providerClass;
-
- /**
- * Resource class constructors.
- *
- * @see {@link ConstructorDescriptor}
- */
- private final List<ConstructorDescriptor> constructors;
-
- /**
- * Resource class fields.
- */
- private final List<FieldInjector> fields;
-
- /**
* List of media types which this method can consume. See
* {@link javax.ws.rs.Consumes} .
*/
@@ -74,9 +48,6 @@
*/
private final List<MediaType> produces;
- /** Optional data. */
- private MultivaluedMap<String, String> properties;
-
/**
* @param providerClass provider class
*/
@@ -99,33 +70,7 @@
*/
private ProviderDescriptorImpl(Class<?> providerClass, ComponentLifecycleScope scope)
{
- this.providerClass = providerClass;
-
- this.constructors = new ArrayList<ConstructorDescriptor>();
- this.fields = new ArrayList<FieldInjector>();
- if (scope == ComponentLifecycleScope.PER_REQUEST)
- {
- for (Constructor<?> constructor : providerClass.getConstructors())
- {
- constructors.add(new ConstructorDescriptorImpl(providerClass, constructor));
- }
- if (constructors.size() == 0)
- {
- String msg = "Not found accepted constructors for provider class " + providerClass.getName();
- throw new RuntimeException(msg);
- }
- // Sort constructors in number parameters order
- if (constructors.size() > 1)
- {
- Collections.sort(constructors, ConstructorDescriptorImpl.CONSTRUCTOR_COMPARATOR);
- }
- // process field
- for (java.lang.reflect.Field jfield : providerClass.getDeclaredFields())
- {
- fields.add(new FieldInjectorImpl(providerClass, jfield));
- }
- }
-
+ super(providerClass, scope);
this.consumes = MediaTypeHelper.createConsumesList(providerClass.getAnnotation(Consumes.class));
this.produces = MediaTypeHelper.createProducesList(providerClass.getAnnotation(Produces.class));
}
@@ -149,54 +94,6 @@
/**
* {@inheritDoc}
*/
- public List<ConstructorDescriptor> getConstructorDescriptors()
- {
- return constructors;
- }
-
- /**
- * {@inheritDoc}
- */
- public List<FieldInjector> getFieldInjectors()
- {
- return fields;
- }
-
- /**
- * {@inheritDoc}
- */
- public Class<?> getObjectClass()
- {
- return providerClass;
- }
-
- /**
- * {@inheritDoc}
- */
- public MultivaluedMap<String, String> getProperties()
- {
- if (properties == null)
- {
- properties = new MultivaluedMapImpl();
- }
- return properties;
- }
-
- /**
- * {@inheritDoc}
- */
- public List<String> getProperty(String key)
- {
- if (properties != null)
- {
- return properties.get(key);
- }
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
public List<MediaType> produces()
{
return produces;
@@ -214,5 +111,4 @@
return sb.toString();
}
-
}
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/AbstractResourceDescriptorImpl.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/AbstractResourceDescriptorImpl.java 2011-01-17 10:31:47 UTC (rev 3813)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/AbstractResourceDescriptorImpl.java 2011-01-17 11:03:16 UTC (rev 3814)
@@ -18,15 +18,10 @@
*/
package org.exoplatform.services.rest.impl.resource;
-import org.exoplatform.commons.utils.SecurityHelper;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import org.exoplatform.services.rest.BaseObjectModel;
import org.exoplatform.services.rest.ComponentLifecycleScope;
-import org.exoplatform.services.rest.ConstructorDescriptor;
-import org.exoplatform.services.rest.FieldInjector;
-import org.exoplatform.services.rest.impl.ConstructorDescriptorImpl;
-import org.exoplatform.services.rest.impl.FieldInjectorImpl;
-import org.exoplatform.services.rest.impl.MultivaluedMapImpl;
import org.exoplatform.services.rest.impl.header.MediaTypeHelper;
import org.exoplatform.services.rest.impl.method.DefaultMethodInvoker;
import org.exoplatform.services.rest.impl.method.MethodInvokerFactory;
@@ -46,10 +41,10 @@
import org.exoplatform.services.rest.uri.UriPattern;
import java.lang.annotation.Annotation;
-import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
+import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collections;
@@ -71,76 +66,53 @@
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
/**
* @author <a href="mailto:andrew00x@gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
-public class AbstractResourceDescriptorImpl implements AbstractResourceDescriptor
+public class AbstractResourceDescriptorImpl extends BaseObjectModel implements AbstractResourceDescriptor
{
-
- /**
- * Logger.
- */
+ /** Logger. */
private static final Log LOG = ExoLogger.getLogger("exo.ws.rest.core.AbstractResourceDescriptorImpl");
- /**
- * @see PathValue
- */
+ /** @see PathValue */
private final PathValue path;
- /**
- * @see UriPattern
- */
+ /** @see UriPattern */
private final UriPattern uriPattern;
/**
- * Resource class.
- */
- private final Class<?> resourceClass;
-
- /**
* Sub-resource methods. Sub-resource method has path annotation.
- *
+ *
* @see SubResourceMethodDescriptor
*/
private final SubResourceMethodMap subResourceMethods;
/**
* Sub-resource locators. Sub-resource locator has path annotation.
- *
+ *
* @see SubResourceLocatorDescriptor
*/
private final SubResourceLocatorMap subResourceLocators;
/**
* Resource methods. Resource method has not own path annotation.
- *
+ *
* @see ResourceMethodDescriptor
*/
private final ResourceMethodMap<ResourceMethodDescriptor> resourceMethods;
- /**
- * Resource class constructors.
- *
- * @see ConstructorDescriptor
- */
- private final List<ConstructorDescriptor> constructors;
-
- /**
- * Resource class fields.
- */
- private final List<FieldInjector> fields;
-
- /** Optional data. */
- private MultivaluedMap<String, String> properties;
-
private final MethodInvokerFactory invokerFactory;
+ public AbstractResourceDescriptorImpl(Class<?> resourceClass, ComponentLifecycleScope scope)
+ {
+ this(resourceClass.getAnnotation(Path.class), resourceClass, scope, null);
+ }
+
/**
* Constructs new instance of AbstractResourceDescriptor.
- *
+ *
* @param resourceClass resource class
* @param invokerFactory invoker factory
*/
@@ -151,7 +123,7 @@
/**
* Constructs new instance of AbstractResourceDescriptor.
- *
+ *
* @param resource resource instance
* @param invokerFactory invoker factory
*/
@@ -163,7 +135,7 @@
/**
* Constructs new instance of AbstractResourceDescriptor.
- *
+ *
* @param resourceClass resource class
*/
public AbstractResourceDescriptorImpl(Class<?> resourceClass)
@@ -173,7 +145,7 @@
/**
* Constructs new instance of AbstractResourceDescriptor.
- *
+ *
* @param resource resource instance
*/
public AbstractResourceDescriptorImpl(Object resource)
@@ -190,6 +162,7 @@
private AbstractResourceDescriptorImpl(Path path, final Class<?> resourceClass, ComponentLifecycleScope scope,
MethodInvokerFactory invokerFactory)
{
+ super(resourceClass, scope);
if (path != null)
{
this.path = new PathValue(path.value());
@@ -200,65 +173,7 @@
this.path = null;
uriPattern = null;
}
-
- this.resourceClass = resourceClass;
-
- this.constructors = new ArrayList<ConstructorDescriptor>();
- this.fields = new ArrayList<FieldInjector>();
- if (scope == ComponentLifecycleScope.PER_REQUEST)
- {
- for (Constructor<?> constructor : resourceClass.getConstructors())
- {
- constructors.add(new ConstructorDescriptorImpl(resourceClass, constructor));
- }
- if (constructors.size() == 0)
- {
- String msg = "Not found accepted constructors for resource class " + resourceClass.getName();
- throw new RuntimeException(msg);
- }
- // Sort constructors in number parameters order
- if (constructors.size() > 1)
- {
- Collections.sort(constructors, ConstructorDescriptorImpl.CONSTRUCTOR_COMPARATOR);
- }
-
- // process field
- java.lang.reflect.Field[] jfields =
- SecurityHelper.doPrivilegedAction(new PrivilegedAction<java.lang.reflect.Field[]>()
- {
- public java.lang.reflect.Field[] run()
- {
- return resourceClass.getDeclaredFields();
- }
- });
-
- for (java.lang.reflect.Field jfield : jfields)
- {
- fields.add(new FieldInjectorImpl(resourceClass, jfield));
- }
- Class<?> sc = resourceClass.getSuperclass();
- while (sc != Object.class)
- {
- for (java.lang.reflect.Field jfield : sc.getDeclaredFields())
- {
- int modif = jfield.getModifiers();
- // TODO process fields with package visibility.
- if (Modifier.isPublic(modif) || Modifier.isProtected(modif))
- {
- FieldInjector inj = new FieldInjectorImpl(resourceClass, jfield);
- // Skip not annotated field. They will be not injected from container.
- if (inj.getAnnotation() != null)
- {
- fields.add(new FieldInjectorImpl(resourceClass, jfield));
- }
- }
- }
- sc = sc.getSuperclass();
- }
- }
-
this.invokerFactory = invokerFactory;
-
this.resourceMethods = new ResourceMethodMap<ResourceMethodDescriptor>();
this.subResourceMethods = new SubResourceMethodMap();
this.subResourceLocators = new SubResourceLocatorMap();
@@ -268,30 +183,6 @@
/**
* {@inheritDoc}
*/
- public MultivaluedMap<String, String> getProperties()
- {
- if (properties == null)
- {
- properties = new MultivaluedMapImpl();
- }
- return properties;
- }
-
- /**
- * {@inheritDoc}
- */
- public List<String> getProperty(String key)
- {
- if (properties != null)
- {
- return properties.get(key);
- }
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
public void accept(ResourceDescriptorVisitor visitor)
{
visitor.visitAbstractResourceDescriptor(this);
@@ -300,30 +191,6 @@
/**
* {@inheritDoc}
*/
- public List<ConstructorDescriptor> getConstructorDescriptors()
- {
- return constructors;
- }
-
- /**
- * {@inheritDoc}
- */
- public List<FieldInjector> getFieldInjectors()
- {
- return fields;
- }
-
- /**
- * {@inheritDoc}
- */
- public Class<?> getObjectClass()
- {
- return resourceClass;
- }
-
- /**
- * {@inheritDoc}
- */
public PathValue getPathValue()
{
return path;
@@ -377,15 +244,13 @@
{
final Class<?> resourceClass = getObjectClass();
- Method[] methods = SecurityHelper.doPrivilegedAction(new PrivilegedAction<Method[]>()
- {
+ Method[] methods = AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
public Method[] run()
{
return resourceClass.getDeclaredMethods();
}
});
-
for (Method method : methods)
{
for (Annotation a : method.getAnnotations())
@@ -437,8 +302,8 @@
new ResourceMethodDescriptorImpl(method, httpMethod.value(), params, this, consumes, produces,
getMethodInvoker());
ResourceMethodDescriptor exist =
- findMethodResourceMediaType(resourceMethods.getList(httpMethod.value()), res.consumes(), res
- .produces());
+ findMethodResourceMediaType(resourceMethods.getList(httpMethod.value()), res.consumes(),
+ res.produces());
if (exist == null)
{
resourceMethods.add(httpMethod.value(), res);
@@ -501,15 +366,6 @@
}
}
}
- int resMethodCount = resourceMethods.size() + subResourceMethods.size() + subResourceLocators.size();
- if (resMethodCount == 0)
- {
- String msg =
- "Not found any resource methods, sub-resource methods" + " or sub-resource locators in "
- + resourceClass.getName();
- throw new RuntimeException(msg);
- }
-
// End method processing.
// Start HEAD and OPTIONS resolving, see JAX-RS (JSR-311) specification
// section 3.3.5
@@ -523,7 +379,7 @@
/**
* Create list of {@link MethodParameter} .
- *
+ *
* @param resourceClass class
* @param method See {@link Method}
* @return list of {@link MethodParameter}
@@ -679,7 +535,7 @@
* Get all method with at least one annotation which has annotation
* <i>annotation</i>. It is useful for annotation {@link javax.ws.rs.GET},
* etc. All HTTP method annotations has annotation {@link HttpMethod}.
- *
+ *
* @param <T> annotation type
* @param m method
* @param annotation annotation class
@@ -701,19 +557,18 @@
/**
* Tries to get JAX-RS annotation on method from the root resource class's
* superclass or implemented interfaces.
- *
+ *
* @param <T> annotation type
* @param method method for discovering
* @param resourceClass class that contains discovered method
* @param annotationClass annotation type what we are looking for
* @param metaAnnotation false if annotation should be on method and true in
- * method should contain annotations that has supplied annotation
+ * method should contain annotations that has supplied annotation
* @return annotation from class or its ancestor or null if nothing found
*/
protected <T extends Annotation> T getMethodAnnotation(Method method, Class<?> resourceClass,
Class<T> annotationClass, boolean metaAnnotation)
{
-
T annotation = null;
if (metaAnnotation)
{
@@ -726,14 +581,19 @@
if (annotation == null)
{
-
Method inhMethod = null;
-
- try
+ Class<?> superclass = resourceClass.getSuperclass();
+ if (superclass != null)
{
- inhMethod = resourceClass.getSuperclass().getMethod(method.getName(), method.getParameterTypes());
+ try
+ {
+ inhMethod = superclass.getMethod(method.getName(), method.getParameterTypes());
+ }
+ catch (NoSuchMethodException e)
+ {
+ }
}
- catch (NoSuchMethodException e)
+ if (inhMethod == null)
{
for (Class<?> intf : resourceClass.getInterfaces())
{
@@ -758,7 +618,6 @@
}
}
}
-
if (inhMethod != null)
{
if (metaAnnotation)
@@ -778,7 +637,7 @@
/**
* Check is collection of {@link ResourceMethodDescriptor} already contains
* ResourceMethodDescriptor with the same media types.
- *
+ *
* @param rmds {@link Set} of {@link ResourceMethodDescriptor}
* @param consumes resource method consumed media type
* @param produces resource method produced media type
@@ -856,8 +715,8 @@
public String toString()
{
StringBuffer sb = new StringBuffer("[ AbstractResourceDescriptorImpl: ");
- sb.append("path: " + getPathValue()).append("; isRootResource: " + isRootResource()).append(
- "; class: " + getObjectClass()).append(" ]");
+ sb.append("path: " + getPathValue()).append("; isRootResource: " + isRootResource())
+ .append("; class: " + getObjectClass()).append(" ]");
return sb.toString();
}
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/ResourceDescriptorValidator.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/ResourceDescriptorValidator.java 2011-01-17 10:31:47 UTC (rev 3813)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/ResourceDescriptorValidator.java 2011-01-17 11:03:16 UTC (rev 3814)
@@ -112,6 +112,16 @@
checkObjectModel(ard);
+ int resMethodCount =
+ ard.getResourceMethods().size() + ard.getSubResourceMethods().size() + ard.getSubResourceLocators().size();
+ if (resMethodCount == 0)
+ {
+ String msg =
+ "Not found any resource methods, sub-resource methods" + " or sub-resource locators in "
+ + ard.getObjectClass().getName();
+ throw new RuntimeException(msg);
+ }
+
// check all resource methods
for (List<ResourceMethodDescriptor> l : ard.getResourceMethods().values())
{
@@ -167,8 +177,8 @@
/**
* Validate SubResourceMethodDescriptor. SubResourceMethodDescriptor is a
- * method which annotated with path annotation and has HTTP method annotation.
- * This method can process the request directly. {@inheritDoc}
+ * method which annotated with path annotation and has HTTP method
+ * annotation. This method can process the request directly. {@inheritDoc}
*/
public void visitSubResourceMethodDescriptor(SubResourceMethodDescriptor srmd)
{
@@ -184,8 +194,8 @@
/**
* Check method parameter for valid annotations. NOTE If a any method
- * parameter is annotated with {@link FormParam} then type of entity parameter
- * must be MultivalueMap<String, String>.
+ * parameter is annotated with {@link FormParam} then type of entity
+ * parameter must be MultivalueMap<String, String>.
*
* @param rmd See {@link ResourceMethodDescriptor}
*/
@@ -261,7 +271,7 @@
* @param type generic type
* @see #checkGenericType(Type)
*/
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("rawtypes")
private static void checkFormParam(Class clazz, Type type)
{
if (MultivaluedMap.class != clazz || !checkGenericType(type))
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/wadl/WadlProcessor.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/wadl/WadlProcessor.java 2011-01-17 10:31:47 UTC (rev 3813)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/wadl/WadlProcessor.java 2011-01-17 11:03:16 UTC (rev 3814)
@@ -18,6 +18,7 @@
*/
package org.exoplatform.services.rest.wadl;
+import org.exoplatform.services.rest.ComponentLifecycleScope;
import org.exoplatform.services.rest.impl.resource.AbstractResourceDescriptorImpl;
import org.exoplatform.services.rest.method.MethodParameter;
import org.exoplatform.services.rest.resource.AbstractResourceDescriptor;
@@ -138,7 +139,7 @@
* Process sub-resource methods.
*
* @param wadlResource see
- * {@link org.exoplatform.services.rest.wadl.research.Resource}
+ * {@link org.exoplatform.services.rest.wadl.research.Resource}
* @param resourceDescriptor see {@link AbstractResourceDescriptor}
*/
private void processSubResourceMethods(org.exoplatform.services.rest.wadl.research.Resource wadlResource,
@@ -207,7 +208,7 @@
* Process sub-resource locators.
*
* @param wadlResource see
- * {@link org.exoplatform.services.rest.wadl.research.Resource}
+ * {@link org.exoplatform.services.rest.wadl.research.Resource}
* @param resourceDescriptor see {@link AbstractResourceDescriptor}
*/
private void processSubResourceLocators(org.exoplatform.services.rest.wadl.research.Resource wadlResource,
@@ -215,8 +216,11 @@
{
for (SubResourceLocatorDescriptor srld : resourceDescriptor.getSubResourceLocators().values())
{
+ // Specify SINGLETON life-cycle to avoid processing constructors and fields.
+ // We are not interested about it since creation instance of resource is
+ // responsibility of sub-resource locator.
AbstractResourceDescriptor subResourceDescriptor =
- new AbstractResourceDescriptorImpl(srld.getMethod().getReturnType());
+ new AbstractResourceDescriptorImpl(srld.getMethod().getReturnType(), ComponentLifecycleScope.SINGLETON);
org.exoplatform.services.rest.wadl.research.Resource wadlSubResource = processResource(subResourceDescriptor);
wadlSubResource.setPath(srld.getPathValue().getPath());
wadlResource.getMethodOrResource().add(wadlSubResource);
Modified: ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/resource/ResourceDescriptorTest.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/resource/ResourceDescriptorTest.java 2011-01-17 10:31:47 UTC (rev 3813)
+++ ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/resource/ResourceDescriptorTest.java 2011-01-17 11:03:16 UTC (rev 3814)
@@ -64,18 +64,19 @@
public class ResourceDescriptorTest extends BaseTest
{
- public void testFailedCreation1()
- {
- try
+ /*
+ public void testFailedCreation1()
{
- new AbstractResourceDescriptorImpl(Resource1.class);
- fail("Should be failed here, resource does not contains JAX-RS methods");
+ try
+ {
+ new AbstractResourceDescriptorImpl(Resource1.class).accept(ResourceDescriptorValidator.getInstance());
+ fail("Should be failed here, resource does not contains JAX-RS methods");
+ }
+ catch (RuntimeException e)
+ {
+ }
}
- catch (RuntimeException e)
- {
- }
- }
-
+ */
public void testFailedCreation2()
{
try
Modified: ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/wadl/WadlProcessorTest.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/wadl/WadlProcessorTest.java 2011-01-17 10:31:47 UTC (rev 3813)
+++ ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/wadl/WadlProcessorTest.java 2011-01-17 11:03:16 UTC (rev 3814)
@@ -106,15 +106,20 @@
@Path("sub/{x}")
public Resource2 m7()
{
- return new Resource2();
+ return new Resource2Impl();
}
}
- public static class Resource2
+ public static interface Resource2
{
@GET
@Produces("text/plain")
+ public String m0(@PathParam("x") String x);
+ }
+
+ public static class Resource2Impl implements Resource2
+ {
public String m0(@PathParam("x") String x)
{
return x;
13 years, 4 months
exo-jcr SVN: r3813 - jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-01-17 05:31:47 -0500 (Mon, 17 Jan 2011)
New Revision: 3813
Modified:
jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerCacheLoader.java
Log:
EXOJCR-1144 : fix: only RW node can remove from cache.
Modified: jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerCacheLoader.java
===================================================================
--- jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerCacheLoader.java 2011-01-14 14:29:52 UTC (rev 3812)
+++ jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerCacheLoader.java 2011-01-17 10:31:47 UTC (rev 3813)
@@ -62,7 +62,7 @@
{
// do nothing. Everything is done on prepare phase.
}
-
+
/**
* This method will register a new Indexer according to the given parameters.
*
@@ -77,7 +77,10 @@
{
indexers.put(Fqn.fromElements(searchManager.getWsId()), new Indexer(searchManager, parentSearchManager, handler,
parentHandler));
- if (log.isDebugEnabled()) log.debug("Register " + searchManager.getWsId() + " " + this + " in " + indexers);
+ if (log.isDebugEnabled())
+ {
+ log.debug("Register " + searchManager.getWsId() + " " + this + " in " + indexers);
+ }
}
/**
@@ -99,22 +102,28 @@
if (indexer == null)
{
log.warn("No indexer could be found for the fqn " + name.getParent());
- if (log.isDebugEnabled()) log.debug("The current content of the map of indexers is " + indexers);
+ if (log.isDebugEnabled())
+ {
+ log.debug("The current content of the map of indexers is " + indexers);
+ }
}
else if (wrapper.withChanges())
{
- indexer.updateIndex(wrapper.getChanges(), wrapper.getParentChanges());
+ indexer.updateIndex(wrapper.getChanges(), wrapper.getParentChanges());
}
else
{
- indexer.updateIndex(wrapper.getAddedNodes(), wrapper.getRemovedNodes(), wrapper.getParentAddedNodes(), wrapper
- .getParentRemovedNodes());
+ indexer.updateIndex(wrapper.getAddedNodes(), wrapper.getRemovedNodes(), wrapper.getParentAddedNodes(),
+ wrapper.getParentRemovedNodes());
}
}
finally
{
- // remove the data from the cache
- cache.removeNode(name);
+ if (modeHandler.getMode() == IndexerIoMode.READ_WRITE)
+ {
+ // remove the data from the cache
+ cache.removeNode(name);
+ }
}
}
return null;
@@ -196,7 +205,7 @@
private final QueryHandler handler;
private final QueryHandler parentHandler;
-
+
public Indexer(SearchManager searchManager, SearchManager parentSearchManager, QueryHandler handler,
QueryHandler parentHandler) throws RepositoryConfigurationException
{
@@ -204,7 +213,8 @@
this.parentSearchManager = parentSearchManager;
this.handler = handler;
this.parentHandler = parentHandler;
- }
+ }
+
/**
* Flushes lists of added/removed nodes to SearchManagers, starting indexing.
*
@@ -264,8 +274,8 @@
}
}
}
- }
-
+ }
+
/**
* Flushes lists of added/removed nodes to SearchManagers, starting indexing.
*/
@@ -287,7 +297,8 @@
log.error("Error indexing changes " + e, e);
try
{
- handler.logErrorChanges(new HashSet<String>(changes.getRemove()), new HashSet<String>(changes.getAddIds()));
+ handler.logErrorChanges(new HashSet<String>(changes.getRemove()), new HashSet<String>(changes
+ .getAddIds()));
}
catch (IOException ioe)
{
@@ -296,7 +307,7 @@
}
}
// pass lists to parent search manager
- if (parentSearchManager != null && parentChanges!= null)
+ if (parentSearchManager != null && parentChanges != null)
{
try
{
@@ -311,7 +322,8 @@
log.error("Error indexing changes " + e, e);
try
{
- parentHandler.logErrorChanges(new HashSet<String>(parentChanges.getRemove()), new HashSet<String>(parentChanges.getAddIds()));
+ parentHandler.logErrorChanges(new HashSet<String>(parentChanges.getRemove()), new HashSet<String>(
+ parentChanges.getAddIds()));
}
catch (IOException ioe)
{
@@ -319,6 +331,6 @@
}
}
}
- }
+ }
}
}
13 years, 4 months
exo-jcr SVN: r3812 - jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-01-14 09:29:52 -0500 (Fri, 14 Jan 2011)
New Revision: 3812
Modified:
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupUseCasesTest.java
Log:
EXOJCR-1081: fix test on hudson
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupUseCasesTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupUseCasesTest.java 2011-01-14 11:01:27 UTC (rev 3811)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupUseCasesTest.java 2011-01-14 14:29:52 UTC (rev 3812)
@@ -517,7 +517,7 @@
Thread.sleep(50);
}
- Thread.sleep(16000);
+ Thread.sleep(32000);
for (BackupChain chain : backup.getCurrentBackups())
if (bch.getBackupId().equals(chain.getBackupId()))
@@ -1128,7 +1128,7 @@
Thread.sleep(50);
}
- Thread.sleep(16000);
+ Thread.sleep(32000);
for (RepositoryBackupChain chain : backup.getCurrentRepositoryBackups())
if (bch.getBackupId().equals(chain.getBackupId()))
13 years, 4 months
exo-jcr SVN: r3811 - jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-01-14 06:01:27 -0500 (Fri, 14 Jan 2011)
New Revision: 3811
Modified:
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupUseCasesTest.java
Log:
EXOJCR-1081: fix test on hudson
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupUseCasesTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupUseCasesTest.java 2011-01-14 08:51:10 UTC (rev 3810)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupUseCasesTest.java 2011-01-14 11:01:27 UTC (rev 3811)
@@ -446,7 +446,7 @@
BackupChain bch = backup.startBackup(config);
- while (!bch.isFinished())
+ while (bch.getFullBackupState() != BackupJob.FINISHED)
{
Thread.yield();
Thread.sleep(50);
@@ -481,6 +481,8 @@
Thread.sleep(50);
}
+ Thread.sleep(6000);
+
boolean isFail = true;
for (BackupChain chain : backup.getCurrentBackups())
@@ -509,13 +511,13 @@
final BackupChain bch = backup.startBackup(config);
- while (!bch.isFinished())
+ while (bch.getFullBackupState() != BackupJob.FINISHED)
{
Thread.yield();
Thread.sleep(50);
}
- Thread.sleep(5000);
+ Thread.sleep(16000);
for (BackupChain chain : backup.getCurrentBackups())
if (bch.getBackupId().equals(chain.getBackupId()))
@@ -1120,13 +1122,13 @@
final RepositoryBackupChain bch = backup.startBackup(config);
- while (!bch.isFinished())
+ while (bch.getState() != RepositoryBackupChain.FINISHED)
{
Thread.yield();
Thread.sleep(50);
}
- Thread.sleep(5000);
+ Thread.sleep(16000);
for (RepositoryBackupChain chain : backup.getCurrentRepositoryBackups())
if (bch.getBackupId().equals(chain.getBackupId()))
13 years, 4 months
exo-jcr SVN: r3810 - ws/trunk/exo.ws.rest.ext.
by do-not-reply@jboss.org
Author: aparfonov
Date: 2011-01-14 03:51:10 -0500 (Fri, 14 Jan 2011)
New Revision: 3810
Modified:
ws/trunk/exo.ws.rest.ext/pom.xml
Log:
EXOJCR-1155
Modified: ws/trunk/exo.ws.rest.ext/pom.xml
===================================================================
--- ws/trunk/exo.ws.rest.ext/pom.xml 2011-01-14 08:39:54 UTC (rev 3809)
+++ ws/trunk/exo.ws.rest.ext/pom.xml 2011-01-14 08:51:10 UTC (rev 3810)
@@ -77,6 +77,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
13 years, 4 months
exo-jcr SVN: r3809 - in jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query: lucene and 1 other directory.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-01-14 03:39:54 -0500 (Fri, 14 Jan 2011)
New Revision: 3809
Modified:
jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerSingletonStoreCacheLoader.java
jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
Log:
EXOJCR-1144 : first, partially hardcoded implementation of prototype. Docs are indexed into the each volatile. Volatile reseted by one of the following conditions:
1. Volatile index goes out of configured memory. To avoid OoM exception. Required for huge updates.
2. When coordinator notifies that persisted update finished. It means, that volatile flush was performed on server side.
Modified: jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerSingletonStoreCacheLoader.java
===================================================================
--- jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerSingletonStoreCacheLoader.java 2011-01-13 15:27:10 UTC (rev 3808)
+++ jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerSingletonStoreCacheLoader.java 2011-01-14 08:39:54 UTC (rev 3809)
@@ -62,7 +62,9 @@
final boolean debugEnabled = log.isDebugEnabled();
if (debugEnabled)
+ {
log.debug("start pushing in-memory state to cache cacheLoader collection");
+ }
// merging all lists stored in memory
Collection<NodeSPI> children = cache.getRoot().getChildren();
@@ -87,13 +89,13 @@
{
// get search manager lists
addedNodes.addAll(listsWrapper.getChanges().getAddIds());
- removedNodes.addAll(listsWrapper.getChanges().getRemove());
+ removedNodes.addAll(listsWrapper.getChanges().getRemove());
}
if (listsWrapper.getParentChanges() != null)
{
// parent search manager lists
parentAddedNodes.addAll(listsWrapper.getParentChanges().getAddIds());
- parentRemovedNodes.addAll(listsWrapper.getParentChanges().getRemove());
+ parentRemovedNodes.addAll(listsWrapper.getParentChanges().getRemove());
}
}
else
@@ -103,14 +105,14 @@
removedNodes.addAll(listsWrapper.getRemovedNodes());
// parent search manager lists
parentAddedNodes.addAll(listsWrapper.getParentAddedNodes());
- parentRemovedNodes.addAll(listsWrapper.getParentAddedNodes());
+ parentRemovedNodes.addAll(listsWrapper.getParentAddedNodes());
}
}
}
//TODO: recover logic is here, lists are: removedNodes and addedNodes String id = IdGenerator.generate();
String id = IdGenerator.generate();
- cache.put(Fqn.fromRelativeElements(wsChildren.getFqn(), id), JBossCacheIndexChangesFilter.LISTWRAPPER, new ChangesFilterListsWrapper(addedNodes,
- removedNodes, parentAddedNodes, parentRemovedNodes));
+ cache.put(Fqn.fromRelativeElements(wsChildren.getFqn(), id), JBossCacheIndexChangesFilter.LISTWRAPPER,
+ new ChangesFilterListsWrapper(addedNodes, removedNodes, parentAddedNodes, parentRemovedNodes));
// Once we put the merged changes into the cache we can remove other changes from the cache
for (NodeSPI aChildren : changes)
{
@@ -120,12 +122,22 @@
}
}
if (debugEnabled)
+ {
log.debug("in-memory state passed to cache cacheLoader successfully");
+ }
return null;
}
};
}
+ @Override
+ public Object put(Fqn name, Object key, Object value) throws Exception
+ {
+ // delegating call to underlying cache loader, skipping SingletonStore cache loader.
+ // Later SingletonStore should completely be removed
+ return getCacheLoader().put(name, key, value);
+ }
+
/**
* Sets/changes indexer mode
*
Modified: jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
===================================================================
--- jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-01-13 15:27:10 UTC (rev 3808)
+++ jcr/branches/1.14-IMPR/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-01-14 08:39:54 UTC (rev 3809)
@@ -49,6 +49,7 @@
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.jcr.ItemNotFoundException;
import javax.jcr.RepositoryException;
@@ -440,6 +441,25 @@
*/
synchronized void update(final Collection remove, final Collection add) throws IOException
{
+ if (modeHandler.getMode() == IndexerIoMode.READ_WRITE)
+ {
+ doUpdateRW(remove, add);
+ }
+ else
+ {
+ doUpdateRO(remove, add);
+ }
+ }
+
+ /**
+ * For investigation purposes only
+ *
+ * @param remove
+ * @param add
+ * @throws IOException
+ */
+ private void doUpdateRO(final Collection remove, final Collection add) throws IOException
+ {
SecurityHelper.doPriviledgedIOExceptionAction(new PrivilegedExceptionAction<Object>()
{
public Object run() throws Exception
@@ -458,6 +478,70 @@
}
}
+ try
+ {
+ long transactionId = nextTransactionId++;
+ new Start(transactionId).execute(MultiIndex.this);
+
+ for (Iterator it = remove.iterator(); it.hasNext();)
+ {
+ new DeleteNode(transactionId, (String)it.next()).execute(MultiIndex.this);
+ }
+ for (Iterator it = add.iterator(); it.hasNext();)
+ {
+ Document doc = (Document)it.next();
+ if (doc != null)
+ {
+ new AddNode(transactionId, doc).execute(MultiIndex.this);
+ // reset volatile index if needed
+ if (volatileIndex.getRamSizeInBytes() >= handler.getMaxVolatileIndexSize())
+ {
+ // not to get out of memory
+ resetVolatileIndex();
+ }
+ }
+ }
+ new Commit(transactionId).execute(MultiIndex.this);
+ }
+ finally
+ {
+ synchronized (updateMonitor)
+ {
+ releaseMultiReader();
+ }
+ }
+ return null;
+ }
+ });
+ }
+
+ /**
+ * For investigation purposes only
+ *
+ * @param remove
+ * @param add
+ * @throws IOException
+ */
+ private void doUpdateRW(final Collection remove, final Collection add) throws IOException
+ {
+ SecurityHelper.doPriviledgedIOExceptionAction(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ // make sure a reader is available during long updates
+ if (add.size() > handler.getBufferSize())
+ {
+ try
+ {
+ getIndexReader().release();
+ }
+ catch (IOException e)
+ {
+ // do not fail if an exception is thrown here
+ log.warn("unable to prepare index reader " + "for queries during update", e);
+ }
+ }
+
synchronized (updateMonitor)
{
//updateInProgress = true;
@@ -2318,7 +2402,8 @@
// if the document cannot be deleted from the volatile index
// delete it from one of the persistent indexes.
int num = index.volatileIndex.removeDocument(idTerm);
- if (num == 0)
+ // Skip modifying persisted indexes in case of RO.
+ if (num == 0 && index.modeHandler.getMode() == IndexerIoMode.READ_WRITE)
{
for (int i = index.indexes.size() - 1; i >= 0; i--)
{
@@ -2625,7 +2710,12 @@
{
synchronized (updateMonitor)
{
+ resetVolatileIndex();
updateMonitor.notifyAll();
+ // Coordinator set cluster-wide updateInProgress only in case of persistent flush, which
+ // invokes volatile reset. So if RO cluster node received this notification, it means that
+ // coordinator flushed volatile.
+
releaseMultiReader();
}
}
13 years, 4 months
exo-jcr SVN: r3808 - jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-01-13 10:27:10 -0500 (Thu, 13 Jan 2011)
New Revision: 3808
Added:
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-clonsole-dist.xml
Log:
EXOJCR-1118 : The problem with thread safe in IncrementalBackupJob was fixed.
Added: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-clonsole-dist.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-clonsole-dist.xml (rev 0)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-clonsole-dist.xml 2011-01-13 15:27:10 UTC (rev 3808)
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.BackupClient">
+ <?dbhtml filename="ch-backup-clonsole.dist.html"?>
+
+ <title>Backup console binary distribution </title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>The backup console binary distribution is script-based front-end to
+ backup client to creation backup, restore, getting status of current or
+ completed backup/restore, etc. </para>
+
+ <para>The backup console binary distribution conatins original backup
+ console and script adaptation for use with GateIn based products like
+ Platform.</para>
+ </section>
+
+ <section>
+ <title>jcrbackup.cmd and jcrbackup.sh</title>
+
+ <para>These scripts suitable for Standalone and flexible for various
+ authentication ways shell scripts.</para>
+
+ <para>Command signature:</para>
+
+ <programlisting> <url_basic_authentication> | <url_form_authentication> <command>
+
+ <url_basic_authentication>: http(s)//login:password@host:port/<context>
+ <url_form_authentication> : http(s)//host:port/<context> <form_auth_parm>
+
+ <form_auth_part> : form <method> <form_path>
+ <method> : POST or GET
+ <form_path> : /path/path?<paramName1>=<paramValue1>&<paramName2>=<paramValue2>...
+
+ Example of <url_form_authentication> - http://127.0.0.1:8080/portal/rest form POST "/portal/login?initialURI=/portal/private&username=root&password=gtn"
+
+ <command> : start <repo[/ws]> <backup_dir> [<incr>]
+ stop <backup_id>
+ status <backup_id>
+ restores <repo[/ws]>
+ restore [remove-exists] [<repo[/ws]>] {<backup_id>|<backup_set_path>} [<pathToConfigFile>]
+ list [completed]
+ info
+ drop [force-close-session] <repo[/ws]>
+ help
+
+ start : start backup of repository or workspace
+ stop : stop backup
+ status : information about the current or completed backup by 'backup_id'
+ restores : information about the last restore on specific repository or workspace
+ restore : restore the repository or workspace from specific backup
+ list : information about the current backups (in progress)
+ list completed : information about the completed (ready to restore) backups
+ info : information about the service backup
+ drop : delete the repository or workspace
+ help : print help information about backup console
+
+ <repo[/ws]> : /<repository-name>[/<workspace-name>] the repository or workspace
+ <backup_dir> : path to folder for backup on remote server
+ <backup_id> : the identifier for backup
+ <incr> : incremental job period
+ <pathToConfigFile> : path (local) to repository or workspace configuration
+ remove-exists : remove fully (db, value storage, index) exists repository/workspace
+ force-close-session : close opened sessions on repository or workspace</programlisting>
+ </section>
+
+ <section>
+ <title>exobackup.sh and exobackup.cmd</title>
+
+ <para>These scripts suitable for use with GateIn based products like
+ Platform</para>
+
+ <para>Command signature:</para>
+
+ <programlisting> -u <user> -p <password> [form_of_authentication] <host:port> <command>
+
+ <form_of_authentication> : -b - is used for basic authentication
+ -f [-c <context>] - is used for form authentication with context portal if parameter context not specified
+ if no authentication set basic authentication is used
+ -c <context> : context, by default context is portal
+
+ <command> : start <repo[/ws]> <backup_dir> [<incr>]
+ stop <backup_id>
+ status <backup_id>
+ restores <repo[/ws]>
+ restore [remove-exists] [<repo[/ws]>] {<backup_id>|<backup_set_path>} [<pathToConfigFile>]
+ list [completed]
+ info
+ drop [force-close-session] <repo[/ws]>
+ help
+
+ start : start backup of repository or workspace
+ stop : stop backup
+ status : information about the current or completed backup by 'backup_id'
+ restores : information about the last restore on specific repository or workspace
+ restore : restore the repository or workspace from specific backup
+ list : information about the current backups (in progress)
+ list completed : information about the completed (ready to restore) backups
+ info : information about the service backup
+ drop : delete the repository or workspace
+ help : print help information about backup console
+
+ <repo[/ws]> : /<repository-name>[/<workspace-name>] the repository or workspace
+ <backup_dir> : path to folder for backup on remote server
+ <backup_id> : the identifier for backup
+ <incr> : incremental job period
+ <pathToConfigFile> : path (local) to repository or workspace configuration
+ remove-exists : remove fully (db, value storage, index) exists repository/workspace
+ force-close-session : close opened sessions on repository or workspace</programlisting>
+ </section>
+
+ <section>
+ <title>Backup console binary distribution usage</title>
+
+ <section>
+ <title>Building application</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Go to folder <emphasis
+ role="bold">${JCR-SRC-HOME}/applications/exo.jcr.applications.backupconsole.dist</emphasis>
+ . - build the application :<programlisting>mvn clean install</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Getting information about backup service</title>
+
+ <para>The context is "portal" by default for FORM authentiaction.</para>
+
+ <programlisting>./exobackup.sh -u root -p gtn -f 192.168.0.15:8080 info</programlisting>
+
+ <para>Return :</para>
+
+ <programlisting>The backup service information :
+ full backup type : org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob
+ incremetal backup type : org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob
+ backup log folder : /home/rainf0x/java/exo-working/JCR-839/new_JCR/exo-tomcat/bin/../temp/backup
+ default incremental job period : 3600</programlisting>
+ </section>
+
+ <section>
+ <title>Getting information about backup service with use not default
+ context</title>
+
+ <para>The context is "exodms-demo".</para>
+
+ <programlisting>./exobackup.sh -u root -p gtn -f -c exodms-demo 192.168.0.15:8080 info</programlisting>
+
+ <para>Return :</para>
+
+ <programlisting>The backup service information :
+ full backup type : org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob
+ incremetal backup type : org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob
+ backup log folder : /home/rainf0x/java/exo-working/JCR-839/new_JCR/exo-tomcat/bin/../temp/backup
+ default incremental job period : 3600</programlisting>
+ </section>
+ </section>
+</chapter>
13 years, 4 months
exo-jcr SVN: r3807 - jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-01-13 10:25:57 -0500 (Thu, 13 Jan 2011)
New Revision: 3807
Added:
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-clonsole-dist.xml
Log:
JCR-1574 : The problem with thread safe in IncrementalBackupJob was fixed.
Added: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-clonsole-dist.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-clonsole-dist.xml (rev 0)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-clonsole-dist.xml 2011-01-13 15:25:57 UTC (rev 3807)
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.BackupClient">
+ <?dbhtml filename="ch-backup-clonsole.dist.html"?>
+
+ <title>Backup console binary distribution </title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>The backup console binary distribution is script-based front-end to
+ backup client to creation backup, restore, getting status of current or
+ completed backup/restore, etc. </para>
+
+ <para>The backup console binary distribution conatins original backup
+ console and script adaptation for use with GateIn based products like
+ Platform.</para>
+ </section>
+
+ <section>
+ <title>jcrbackup.cmd and jcrbackup.sh</title>
+
+ <para>These scripts suitable for Standalone and flexible for various
+ authentication ways shell scripts.</para>
+
+ <para>Command signature:</para>
+
+ <programlisting> <url_basic_authentication> | <url_form_authentication> <command>
+
+ <url_basic_authentication>: http(s)//login:password@host:port/<context>
+ <url_form_authentication> : http(s)//host:port/<context> <form_auth_parm>
+
+ <form_auth_part> : form <method> <form_path>
+ <method> : POST or GET
+ <form_path> : /path/path?<paramName1>=<paramValue1>&<paramName2>=<paramValue2>...
+
+ Example of <url_form_authentication> - http://127.0.0.1:8080/portal/rest form POST "/portal/login?initialURI=/portal/private&username=root&password=gtn"
+
+ <command> : start <repo[/ws]> <backup_dir> [<incr>]
+ stop <backup_id>
+ status <backup_id>
+ restores <repo[/ws]>
+ restore [remove-exists] [<repo[/ws]>] {<backup_id>|<backup_set_path>} [<pathToConfigFile>]
+ list [completed]
+ info
+ drop [force-close-session] <repo[/ws]>
+ help
+
+ start : start backup of repository or workspace
+ stop : stop backup
+ status : information about the current or completed backup by 'backup_id'
+ restores : information about the last restore on specific repository or workspace
+ restore : restore the repository or workspace from specific backup
+ list : information about the current backups (in progress)
+ list completed : information about the completed (ready to restore) backups
+ info : information about the service backup
+ drop : delete the repository or workspace
+ help : print help information about backup console
+
+ <repo[/ws]> : /<repository-name>[/<workspace-name>] the repository or workspace
+ <backup_dir> : path to folder for backup on remote server
+ <backup_id> : the identifier for backup
+ <incr> : incremental job period
+ <pathToConfigFile> : path (local) to repository or workspace configuration
+ remove-exists : remove fully (db, value storage, index) exists repository/workspace
+ force-close-session : close opened sessions on repository or workspace</programlisting>
+ </section>
+
+ <section>
+ <title>exobackup.sh and exobackup.cmd</title>
+
+ <para>These scripts suitable for use with GateIn based products like
+ Platform</para>
+
+ <para>Command signature:</para>
+
+ <programlisting> -u <user> -p <password> [form_of_authentication] <host:port> <command>
+
+ <form_of_authentication> : -b - is used for basic authentication
+ -f [-c <context>] - is used for form authentication with context portal if parameter context not specified
+ if no authentication set basic authentication is used
+ -c <context> : context, by default context is portal
+
+ <command> : start <repo[/ws]> <backup_dir> [<incr>]
+ stop <backup_id>
+ status <backup_id>
+ restores <repo[/ws]>
+ restore [remove-exists] [<repo[/ws]>] {<backup_id>|<backup_set_path>} [<pathToConfigFile>]
+ list [completed]
+ info
+ drop [force-close-session] <repo[/ws]>
+ help
+
+ start : start backup of repository or workspace
+ stop : stop backup
+ status : information about the current or completed backup by 'backup_id'
+ restores : information about the last restore on specific repository or workspace
+ restore : restore the repository or workspace from specific backup
+ list : information about the current backups (in progress)
+ list completed : information about the completed (ready to restore) backups
+ info : information about the service backup
+ drop : delete the repository or workspace
+ help : print help information about backup console
+
+ <repo[/ws]> : /<repository-name>[/<workspace-name>] the repository or workspace
+ <backup_dir> : path to folder for backup on remote server
+ <backup_id> : the identifier for backup
+ <incr> : incremental job period
+ <pathToConfigFile> : path (local) to repository or workspace configuration
+ remove-exists : remove fully (db, value storage, index) exists repository/workspace
+ force-close-session : close opened sessions on repository or workspace</programlisting>
+ </section>
+
+ <section>
+ <title>Backup console binary distribution usage</title>
+
+ <section>
+ <title>Building application</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Go to folder <emphasis
+ role="bold">${JCR-SRC-HOME}/applications/exo.jcr.applications.backupconsole.dist</emphasis>
+ . - build the application :<programlisting>mvn clean install</programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Getting information about backup service</title>
+
+ <para>The context is "portal" by default for FORM authentiaction.</para>
+
+ <programlisting>./exobackup.sh -u root -p gtn -f 192.168.0.15:8080 info</programlisting>
+
+ <para>Return :</para>
+
+ <programlisting>The backup service information :
+ full backup type : org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob
+ incremetal backup type : org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob
+ backup log folder : /home/rainf0x/java/exo-working/JCR-839/new_JCR/exo-tomcat/bin/../temp/backup
+ default incremental job period : 3600</programlisting>
+ </section>
+
+ <section>
+ <title>Getting information about backup service with use not default
+ context</title>
+
+ <para>The context is "exodms-demo".</para>
+
+ <programlisting>./exobackup.sh -u root -p gtn -f -c exodms-demo 192.168.0.15:8080 info</programlisting>
+
+ <para>Return :</para>
+
+ <programlisting>The backup service information :
+ full backup type : org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob
+ incremetal backup type : org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob
+ backup log folder : /home/rainf0x/java/exo-working/JCR-839/new_JCR/exo-tomcat/bin/../temp/backup
+ default incremental job period : 3600</programlisting>
+ </section>
+ </section>
+</chapter>
13 years, 4 months