exo-jcr SVN: r5026 - in jcr/trunk/exo.jcr.component.ext/src: test/resources/conf/standalone and 1 other directory.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-10-06 02:20:28 -0400 (Thu, 06 Oct 2011)
New Revision: 5026
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java
jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml
Log:
EXOJCR-1564 : mandatory parameters now are only backup dir. the rest is set by default.
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java 2011-10-05 13:37:30 UTC (rev 5025)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java 2011-10-06 06:20:28 UTC (rev 5026)
@@ -122,6 +122,23 @@
public final static String INCREMENTAL_BACKUP_TYPE = "incremental-backup-type";
/**
+ * Default value of incremental job period parameter in configuration.
+ */
+ public final static String DEFAULT_VALUE_INCREMENTAL_JOB_PERIOD = "3600";
+
+ /**
+ * Default value of incremental backup type parameter in configuration.
+ */
+ public final static String DEFAULT_VALUE_INCREMENTAL_BACKUP_TYPE =
+ org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob.class.getName();
+
+ /**
+ * Default value of incremental backup type parameter in configuration.
+ */
+ public final static String DEFAULT_VALUE_FULL_BACKUP_TYPE =
+ org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob.class.getName();
+
+ /**
* Name of backup dir parameter in configuration.
*/
public final static String BACKUP_DIR = "backup-dir";
@@ -197,7 +214,6 @@
private final RegistryService registryService;
-
private BackupScheduler scheduler;
private final BackupMessagesLog messages;
@@ -207,7 +223,7 @@
private final WorkspaceBackupAutoStopper workspaceBackupStopper;
private final RepositoryBackupAutoStopper repositoryBackupStopper;
-
+
/**
* Temporary directory;
*/
@@ -226,7 +242,9 @@
{
messages.addMessage(makeJobInfo(job, null));
if (log.isDebugEnabled())
+ {
log.debug(makeJobInfo(job, null));
+ }
}
private String makeJobInfo(BackupJob job, Throwable error)
@@ -266,7 +284,9 @@
jobInfo += "]";
if (error != null)
+ {
jobInfo += " Error: " + error.getMessage();
+ }
try
{
@@ -314,7 +334,7 @@
{
super("WorkspaceBackupAutoStopper" + (ctx == null ? "" : " " + ctx.getName()));
}
-
+
/**
* {@inheritDoc}
*/
@@ -336,7 +356,9 @@
boolean isFinished = (chain.getBackupJobs().get(0).getState() == BackupJob.FINISHED);
for (int i = 1; i < chain.getBackupJobs().size(); i++)
+ {
isFinished &= (chain.getBackupJobs().get(i).getState() == BackupJob.FINISHED);
+ }
if (isFinished)
{
@@ -403,7 +425,9 @@
// STOP backups
for (RepositoryBackupChain chain : stopedList)
+ {
stopBackup(chain);
+ }
}
catch (InterruptedException e)
{
@@ -461,7 +485,7 @@
{
this(null, initParams, repoService, registryService);
}
-
+
/**
* BackupManagerImpl constructor.
*
@@ -472,7 +496,7 @@
* RegistryService, the registry service
*/
public BackupManagerImpl(ExoContainerContext ctx, InitParams initParams, RepositoryService repoService,
- RegistryService registryService)
+ RegistryService registryService)
{
this.messagesListener = new MessagesListener();
this.repoService = repoService;
@@ -497,7 +521,7 @@
this.repositoryBackupStopper = new RepositoryBackupAutoStopper(ctx);
this.repositoryBackupStopper.start();
}
-
+
/**
* {@inheritDoc}
*/
@@ -528,7 +552,9 @@
try
{
if (!isCurrentBackup(cf))
+ {
logs.add(new BackupChainLog(cf));
+ }
}
catch (BackupOperationException e)
{
@@ -555,7 +581,9 @@
try
{
if (!isCurrentRepositoryBackup(cf))
+ {
logs.add(new RepositoryBackupChainLog(cf));
+ }
}
catch (BackupOperationException e)
{
@@ -578,8 +606,12 @@
private boolean isCurrentBackup(File log)
{
for (BackupChain chain : currentBackups)
+ {
if (log.getName().equals(new File(chain.getLogFilePath()).getName()))
+ {
return true;
+ }
+ }
return false;
}
@@ -594,8 +626,12 @@
private boolean isCurrentRepositoryBackup(File log)
{
for (RepositoryBackupChain chain : currentRepositoryBackups)
+ {
if (log.getName().equals(new File(chain.getLogFilePath()).getName()))
+ {
return true;
+ }
+ }
return false;
}
@@ -659,7 +695,9 @@
}
}
else
+ {
throw new BackupConfigurationException("Workspace should exists " + workspaceName);
+ }
}
protected void restoreOverInitializer(BackupChainLog log, String repositoryName, WorkspaceEntry workspaceEntry)
@@ -674,7 +712,7 @@
String workspaceName = workspaceEntry.getName();
String fullbackupType = null;
-
+
try
{
if ((Class.forName(log.getFullBackupType()).equals(FullBackupJob.class)))
@@ -682,18 +720,19 @@
fullbackupType = log.getFullBackupType();
}
else if ((Class.forName(log.getFullBackupType())
- .equals(org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob.class)))
+ .equals(org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob.class)))
{
fullbackupType = log.getFullBackupType();
- }
- else
+ }
+ else
{
- throw new BackupOperationException("Class \"" + log.getFullBackupType() + "\" is not support as full backup.");
- }
+ throw new BackupOperationException("Class \"" + log.getFullBackupType()
+ + "\" is not support as full backup.");
+ }
}
catch (ClassNotFoundException e)
{
- throw new BackupOperationException("Class \"" + log.getFullBackupType() + "\" is not found." , e);
+ throw new BackupOperationException("Class \"" + log.getFullBackupType() + "\" is not found.", e);
}
// ws should not exists.
@@ -707,7 +746,7 @@
try
{
fullRestoreOverInitializer(list.get(i).getURL().getPath(), reposytoryName, workspaceEntry,
- fullbackupType);
+ fullbackupType);
}
catch (FileNotFoundException e)
{
@@ -748,7 +787,9 @@
}
}
else
+ {
throw new BackupConfigurationException("Workspace \"" + workspaceName + "\" should not exists.");
+ }
}
private boolean workspaceAlreadyExist(String repository, String workspace) throws RepositoryException,
@@ -757,8 +798,12 @@
String[] ws = repoService.getRepository(repository).getWorkspaceNames();
for (int i = 0; i < ws.length; i++)
+ {
if (ws[i].equals(workspace))
+ {
return true;
+ }
+ }
return false;
}
@@ -787,17 +832,17 @@
BackupConfigurationException, RepositoryException, RepositoryConfigurationException
{
validateBackupConfig(config);
-
+
Calendar startTime = Calendar.getInstance();
File dir =
- FileNameProducer.generateBackupSetDir(config.getRepository(), config.getWorkspace(), config
- .getBackupDir().getPath(), startTime);
+ FileNameProducer.generateBackupSetDir(config.getRepository(), config.getWorkspace(), config.getBackupDir()
+ .getPath(), startTime);
PrivilegedFileHelper.mkdirs(dir);
config.setBackupDir(dir);
BackupChain bchain =
- new BackupChainImpl(config, logsDirectory, repoService,
- fullBackupType, incrementalBackupType, IdGenerator.generate(), logsDirectory, startTime);
+ new BackupChainImpl(config, logsDirectory, repoService, fullBackupType, incrementalBackupType, IdGenerator
+ .generate(), logsDirectory, startTime);
bchain.addListener(messagesListener);
bchain.addListener(jobListener);
@@ -821,13 +866,19 @@
private void validateBackupConfig(RepositoryBackupConfig config) throws BackupConfigurationException
{
if (config.getIncrementalJobPeriod() < 0)
+ {
throw new BackupConfigurationException("The parameter 'incremental job period' can not be negative.");
+ }
if (config.getIncrementalJobNumber() < 0)
+ {
throw new BackupConfigurationException("The parameter 'incremental job number' can not be negative.");
+ }
if (config.getIncrementalJobPeriod() == 0 && config.getBackupType() == BackupManager.FULL_AND_INCREMENTAL)
+ {
config.setIncrementalJobPeriod(defaultIncrementalJobPeriod);
+ }
}
/**
@@ -851,7 +902,7 @@
{
PrivilegedFileHelper.delete(files[i]);
}
-
+
// start all scheduled before tasks
if (registryService != null && !registryService.getForceXMLConfigurationValue(initParams))
{
@@ -964,14 +1015,14 @@
wiEntry.setParameters(wieParams);
}
else if ((Class.forName(fBackupType)
- .equals(org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob.class)))
+ .equals(org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob.class)))
{
// set the initializer RdbmsWorkspaceInitializer
wiEntry.setType(RdbmsWorkspaceInitializer.class.getCanonicalName());
List<SimpleParameterEntry> wieParams = new ArrayList<SimpleParameterEntry>();
wieParams.add(new SimpleParameterEntry(RdbmsWorkspaceInitializer.RESTORE_PATH_PARAMETER, new File(
- pathBackupFile).getParent()));
+ pathBackupFile).getParent()));
wiEntry.setParameters(wieParams);
}
@@ -984,7 +1035,7 @@
//set original workspace initializer
WorkspaceContainerFacade wcf = defRep.getWorkspaceContainer(workspaceEntry.getName());
- WorkspaceEntry createdWorkspaceEntry = (WorkspaceEntry) wcf.getComponent(WorkspaceEntry.class);
+ WorkspaceEntry createdWorkspaceEntry = (WorkspaceEntry)wcf.getComponent(WorkspaceEntry.class);
createdWorkspaceEntry.setInitializer(wieOriginal);
}
@@ -992,11 +1043,12 @@
throws RepositoryException, RepositoryConfigurationException, BackupOperationException, FileNotFoundException,
IOException, ClassNotFoundException
{
- WorkspaceContainerFacade workspaceContainer = repoService.getRepository(repositoryName).getWorkspaceContainer(workspaceName);
+ WorkspaceContainerFacade workspaceContainer =
+ repoService.getRepository(repositoryName).getWorkspaceContainer(workspaceName);
WorkspacePersistentDataManager dataManager =
- (WorkspacePersistentDataManager)workspaceContainer
- .getComponent(WorkspacePersistentDataManager.class);
- FileCleaner fileCleaner = ((FileCleanerHolder)workspaceContainer.getComponent(FileCleanerHolder.class)).getFileCleaner();
+ (WorkspacePersistentDataManager)workspaceContainer.getComponent(WorkspacePersistentDataManager.class);
+ FileCleaner fileCleaner =
+ ((FileCleanerHolder)workspaceContainer.getComponent(FileCleanerHolder.class)).getFileCleaner();
JCRRestore restorer = new JCRRestore(dataManager, fileCleaner);
restorer.incrementalRestore(new File(pathBackupFile));
}
@@ -1111,14 +1163,21 @@
PropertiesParam pps = initParams.getPropertiesParam(BACKUP_PROPERTIES);
backupDir = pps.getProperty(BACKUP_DIR);
- defIncrPeriod = pps.getProperty(DEFAULT_INCREMENTAL_JOB_PERIOD);
- fullBackupType = pps.getProperty(FULL_BACKUP_TYPE);
- incrementalBackupType = pps.getProperty(INCREMENTAL_BACKUP_TYPE);
+ // full backup type can be not defined. Using default.
+ fullBackupType =
+ pps.getProperty(FULL_BACKUP_TYPE) == null ? DEFAULT_VALUE_FULL_BACKUP_TYPE : pps.getProperty(FULL_BACKUP_TYPE);
+ // incremental backup can be not configured. Using default values.
+ defIncrPeriod =
+ pps.getProperty(DEFAULT_INCREMENTAL_JOB_PERIOD) == null ? DEFAULT_VALUE_INCREMENTAL_JOB_PERIOD : pps
+ .getProperty(DEFAULT_INCREMENTAL_JOB_PERIOD);
+ incrementalBackupType =
+ pps.getProperty(INCREMENTAL_BACKUP_TYPE) == null ? DEFAULT_VALUE_INCREMENTAL_BACKUP_TYPE : pps
+ .getProperty(INCREMENTAL_BACKUP_TYPE);
log.info("Backup dir from configuration file: " + backupDir);
- log.info("Default incremental job period from configuration file: " + defIncrPeriod);
log.info("Full backup type from configuration file: " + fullBackupType);
- log.info("Incremental backup type from configuration file: " + incrementalBackupType);
+ log.info("(Experimental) Incremental backup type from configuration file: " + incrementalBackupType);
+ log.info("(Experimental) Default incremental job period from configuration file: " + defIncrPeriod);
checkParams();
}
@@ -1129,22 +1188,32 @@
private void checkParams()
{
if (backupDir == null)
+ {
throw new RuntimeException(BACKUP_DIR + " not specified");
+ }
logsDirectory = new File(backupDir);
if (!PrivilegedFileHelper.exists(logsDirectory))
+ {
PrivilegedFileHelper.mkdirs(logsDirectory);
+ }
if (defIncrPeriod == null)
+ {
throw new RuntimeException(DEFAULT_INCREMENTAL_JOB_PERIOD + " not specified");
+ }
defaultIncrementalJobPeriod = Integer.valueOf(defIncrPeriod);
if (fullBackupType == null)
+ {
throw new RuntimeException(FULL_BACKUP_TYPE + " not specified");
+ }
if (incrementalBackupType == null)
+ {
throw new RuntimeException(INCREMENTAL_BACKUP_TYPE + " not specified");
+ }
}
/**
@@ -1158,7 +1227,9 @@
BackupChain chain = it.next();
if (repository.equals(chain.getBackupConfig().getRepository())
&& workspace.equals(chain.getBackupConfig().getWorkspace()))
+ {
return chain;
+ }
}
return null;
}
@@ -1173,7 +1244,9 @@
{
BackupChain chain = it.next();
if (backupId.equals(chain.getBackupId()))
+ {
return chain;
+ }
}
return null;
}
@@ -1292,17 +1365,17 @@
{
if (!log.getBackupConfig().getRepository().equals(repositoryName))
{
- throw new WorkspaceRestoreException("If workspaceEntry is null, so will be restored with original configuration. " +
- "The repositoryName (\"" + repositoryName +"\") should be equals original repository name (\""
- + log.getBackupConfig().getRepository() +"\"). " );
+ throw new WorkspaceRestoreException(
+ "If workspaceEntry is null, so will be restored with original configuration. "
+ + "The repositoryName (\"" + repositoryName + "\") should be equals original repository name (\""
+ + log.getBackupConfig().getRepository() + "\"). ");
}
-
+
if (log.getOriginalWorkspaceEntry() == null)
{
throw new RepositoryRestoreExeption("The backup log is not contains original repository log : "
- + log.getLogFilePath());
+ + log.getLogFilePath());
}
-
this.restore(log, log.getBackupConfig().getRepository(), log.getOriginalWorkspaceEntry(), asynchronous);
return;
@@ -1333,7 +1406,7 @@
if (log.getOriginalRepositoryEntry() == null)
{
throw new RepositoryRestoreExeption("The backup log is not contains original repository log : "
- + log.getLogFilePath());
+ + log.getLogFilePath());
}
this.restore(log, log.getOriginalRepositoryEntry(), asynchronous);
@@ -1482,9 +1555,8 @@
config.setBackupDir(dir);
RepositoryBackupChain repositoryBackupChain =
- new RepositoryBackupChainImpl(config, logsDirectory, repoService, fullBackupType,
- incrementalBackupType,
- IdGenerator.generate());
+ new RepositoryBackupChainImpl(config, logsDirectory, repoService, fullBackupType, incrementalBackupType,
+ IdGenerator.generate());
repositoryBackupChain.startBackup();
@@ -1512,7 +1584,9 @@
{
RepositoryBackupChain chain = it.next();
if (repository.equals(chain.getBackupConfig().getRepository()))
+ {
return chain;
+ }
}
return null;
}
@@ -1535,7 +1609,9 @@
{
RepositoryBackupChain chain = it.next();
if (backupId.equals(chain.getBackupId()))
+ {
return chain;
+ }
}
return null;
}
@@ -1550,16 +1626,16 @@
{
// repository should be existed
repoService.getRepository(repositoryEntry.getName());
- }
+ }
catch (RepositoryException e)
{
- throw new RepositoryRestoreExeption("Repository \"" + repositoryEntry.getName() + "\" should be existed", e);
+ throw new RepositoryRestoreExeption("Repository \"" + repositoryEntry.getName() + "\" should be existed", e);
}
catch (RepositoryConfigurationException e)
{
throw new RepositoryRestoreExeption("Repository \"" + repositoryEntry.getName() + "\" should be existed", e);
}
-
+
Map<String, BackupChainLog> workspacesMapping = new HashedMap();
Map<String, BackupChainLog> backups = new HashedMap();
@@ -1573,15 +1649,15 @@
if (!rblog.getSystemWorkspace().equals(repositoryEntry.getSystemWorkspaceName()))
{
throw new BackupConfigurationException(
- "The backup to system workspace is not system workspace in repository entry: "
- + rblog.getSystemWorkspace() + " is not equal " + repositoryEntry.getSystemWorkspaceName());
+ "The backup to system workspace is not system workspace in repository entry: " + rblog.getSystemWorkspace()
+ + " is not equal " + repositoryEntry.getSystemWorkspaceName());
}
if (backups.size() != repositoryEntry.getWorkspaceEntries().size())
{
throw new BackupConfigurationException(
- "The repository entry is contains more or less workspace entry than backups of workspace in "
- + rblog.getLogFilePath());
+ "The repository entry is contains more or less workspace entry than backups of workspace in "
+ + rblog.getLogFilePath());
}
for (WorkspaceEntry wsEntry : repositoryEntry.getWorkspaceEntries())
@@ -1589,7 +1665,7 @@
if (!backups.containsKey(wsEntry.getName()))
{
throw new BackupConfigurationException("The workspace '" + wsEntry.getName() + "' is not found in backup "
- + rblog.getLogFilePath());
+ + rblog.getLogFilePath());
}
else
{
@@ -1597,8 +1673,6 @@
}
}
-
-
// check if we have deal with RDBMS backup
boolean isSameConfigRestore = false;
try
@@ -1652,11 +1726,11 @@
* {@inheritDoc}
*/
public void restoreExistingRepository(String repositoryBackupIdentifier, RepositoryEntry repositoryEntry,
- boolean asynchronous) throws BackupOperationException, BackupConfigurationException
+ boolean asynchronous) throws BackupOperationException, BackupConfigurationException
{
RepositoryBackupChainLog backupChainLog = null;
-
- for(RepositoryBackupChainLog chainLog : getRepositoryBackupsLogs())
+
+ for (RepositoryBackupChainLog chainLog : getRepositoryBackupsLogs())
{
if (chainLog.getBackupId().equals(repositoryBackupIdentifier))
{
@@ -1664,13 +1738,13 @@
break;
}
}
-
+
if (backupChainLog == null)
{
throw new BackupConfigurationException("Can not found backup of repository with id \""
- + repositoryBackupIdentifier + "\"");
+ + repositoryBackupIdentifier + "\"");
}
-
+
this.restoreExistingRepository(backupChainLog, repositoryEntry, asynchronous);
}
@@ -1680,18 +1754,18 @@
public void restoreExistingWorkspace(BackupChainLog log, String repositoryName, WorkspaceEntry workspaceEntry,
boolean asynchronous) throws BackupOperationException, BackupConfigurationException
{
- try
+ try
{
// repository should be existed
repoService.getRepository(repositoryName);
-
+
// workspace should be existed
if (!workspaceAlreadyExist(repositoryName, workspaceEntry.getName()))
{
throw new WorkspaceRestoreException("Workspace \"" + workspaceEntry.getName()
- + "\" should be existed in repository \"" + repositoryName + "\".");
+ + "\" should be existed in repository \"" + repositoryName + "\".");
}
- }
+ }
catch (RepositoryException e)
{
throw new WorkspaceRestoreException("Repository \"" + repositoryName + "\" should be existed", e);
@@ -1770,12 +1844,12 @@
* {@inheritDoc}
*/
public void restoreExistingWorkspace(String workspaceBackupIdentifier, String repositoryName,
- WorkspaceEntry workspaceEntry, boolean asynchronous) throws BackupOperationException,
- BackupConfigurationException
+ WorkspaceEntry workspaceEntry, boolean asynchronous) throws BackupOperationException,
+ BackupConfigurationException
{
BackupChainLog backupChainLog = null;
-
- for(BackupChainLog chainLog : getBackupsLogs())
+
+ for (BackupChainLog chainLog : getBackupsLogs())
{
if (chainLog.getBackupId().equals(workspaceBackupIdentifier))
{
@@ -1783,13 +1857,13 @@
break;
}
}
-
+
if (backupChainLog == null)
{
throw new BackupConfigurationException("Can not found backup of workspace with id \""
- + workspaceBackupIdentifier + "\"");
+ + workspaceBackupIdentifier + "\"");
}
-
+
this.restoreExistingWorkspace(backupChainLog, repositoryName, workspaceEntry, asynchronous);
}
@@ -1797,7 +1871,7 @@
* {@inheritDoc}
*/
public void restoreExistingRepository(String repositoryBackupIdentifier, boolean asynchronous)
- throws BackupOperationException, BackupConfigurationException
+ throws BackupOperationException, BackupConfigurationException
{
RepositoryBackupChainLog backupChainLog = null;
@@ -1813,7 +1887,7 @@
if (backupChainLog == null)
{
throw new BackupConfigurationException("Can not found backup of repository with id \""
- + repositoryBackupIdentifier + "\"");
+ + repositoryBackupIdentifier + "\"");
}
this.restoreExistingRepository(backupChainLog, backupChainLog.getOriginalRepositoryEntry(), asynchronous);
@@ -1824,7 +1898,7 @@
* {@inheritDoc}
*/
public void restoreExistingWorkspace(String workspaceBackupIdentifier, boolean asynchronous)
- throws BackupOperationException, BackupConfigurationException
+ throws BackupOperationException, BackupConfigurationException
{
BackupChainLog backupChainLog = null;
@@ -1840,18 +1914,18 @@
if (backupChainLog == null)
{
throw new BackupConfigurationException("Can not found backup of workspace with id \""
- + workspaceBackupIdentifier + "\"");
+ + workspaceBackupIdentifier + "\"");
}
this.restoreExistingWorkspace(backupChainLog, backupChainLog.getBackupConfig().getRepository(), backupChainLog
- .getOriginalWorkspaceEntry(), asynchronous);
+ .getOriginalWorkspaceEntry(), asynchronous);
}
/**
* {@inheritDoc}
*/
public void restoreRepository(String repositoryBackupIdentifier, boolean asynchronous)
- throws BackupOperationException, BackupConfigurationException
+ throws BackupOperationException, BackupConfigurationException
{
RepositoryBackupChainLog backupChainLog = null;
@@ -1867,7 +1941,7 @@
if (backupChainLog == null)
{
throw new BackupConfigurationException("Can not found backup of repository with id \""
- + repositoryBackupIdentifier + "\"");
+ + repositoryBackupIdentifier + "\"");
}
try
@@ -1877,12 +1951,12 @@
catch (RepositoryException e)
{
throw new RepositoryRestoreExeption("Repository \"" + backupChainLog.getOriginalRepositoryEntry().getName()
- + "\" was not restored", e);
+ + "\" was not restored", e);
}
catch (RepositoryConfigurationException e)
{
throw new RepositoryRestoreExeption("Repository \"" + backupChainLog.getOriginalRepositoryEntry().getName()
- + "\" was not restored", e);
+ + "\" was not restored", e);
}
}
@@ -1890,7 +1964,7 @@
* {@inheritDoc}
*/
public void restoreWorkspace(String workspaceBackupIdentifier, boolean asynchronous)
- throws BackupOperationException, BackupConfigurationException
+ throws BackupOperationException, BackupConfigurationException
{
BackupChainLog backupChainLog = null;
@@ -1906,24 +1980,24 @@
if (backupChainLog == null)
{
throw new BackupConfigurationException("Can not found backup of workspace with id \""
- + workspaceBackupIdentifier + "\"");
+ + workspaceBackupIdentifier + "\"");
}
try
{
this.restore(backupChainLog, backupChainLog.getBackupConfig().getRepository(), backupChainLog
- .getOriginalWorkspaceEntry(), asynchronous);
+ .getOriginalWorkspaceEntry(), asynchronous);
}
catch (RepositoryException e)
{
throw new WorkspaceRestoreException("Workapce \"" + backupChainLog.getOriginalWorkspaceEntry().getName()
- + "\" was not restored in repository \"" + backupChainLog.getBackupConfig().getRepository() + "\"", e);
+ + "\" was not restored in repository \"" + backupChainLog.getBackupConfig().getRepository() + "\"", e);
}
catch (RepositoryConfigurationException e)
{
throw new WorkspaceRestoreException("Workapce \"" + backupChainLog.getOriginalWorkspaceEntry().getName()
- + "\" was not restored in repository \"" + backupChainLog.getBackupConfig().getRepository() + "\"", e);
+ + "\" was not restored in repository \"" + backupChainLog.getBackupConfig().getRepository() + "\"", e);
}
}
@@ -1932,21 +2006,20 @@
* {@inheritDoc}
*/
public void restoreExistingRepository(File repositoryBackupSetDir, boolean asynchronous)
- throws BackupOperationException, BackupConfigurationException
+ throws BackupOperationException, BackupConfigurationException
{
File[] cfs = PrivilegedFileHelper.listFiles(repositoryBackupSetDir, new RepositoryBackupLogsFilter());
if (cfs.length == 0)
{
throw new BackupConfigurationException("Can not found repository backup log in directory : "
- + repositoryBackupSetDir.getPath());
+ + repositoryBackupSetDir.getPath());
}
if (cfs.length > 1)
{
throw new BackupConfigurationException(
- "Backup set directory should contains only one repository backup log : "
- + repositoryBackupSetDir.getPath());
+ "Backup set directory should contains only one repository backup log : " + repositoryBackupSetDir.getPath());
}
RepositoryBackupChainLog backupChainLog = new RepositoryBackupChainLog(cfs[0]);
@@ -1958,48 +2031,46 @@
* {@inheritDoc}
*/
public void restoreExistingWorkspace(File workspaceBackupSetDir, boolean asynchronous)
- throws BackupOperationException, BackupConfigurationException
+ throws BackupOperationException, BackupConfigurationException
{
File[] cfs = PrivilegedFileHelper.listFiles(workspaceBackupSetDir, new BackupLogsFilter());
if (cfs.length == 0)
{
throw new BackupConfigurationException("Can not found workspace backup log in directory : "
- + workspaceBackupSetDir.getPath());
+ + workspaceBackupSetDir.getPath());
}
if (cfs.length > 1)
{
- throw new BackupConfigurationException(
- "Backup set directory should contains only one workspace backup log : "
- + workspaceBackupSetDir.getPath());
+ throw new BackupConfigurationException("Backup set directory should contains only one workspace backup log : "
+ + workspaceBackupSetDir.getPath());
}
BackupChainLog backupChainLog = new BackupChainLog(cfs[0]);
this.restoreExistingWorkspace(backupChainLog, backupChainLog.getBackupConfig().getRepository(), backupChainLog
- .getOriginalWorkspaceEntry(), asynchronous);
+ .getOriginalWorkspaceEntry(), asynchronous);
}
/**
* {@inheritDoc}
*/
public void restoreRepository(File repositoryBackupSetDir, boolean asynchronous) throws BackupOperationException,
- BackupConfigurationException
+ BackupConfigurationException
{
File[] cfs = PrivilegedFileHelper.listFiles(repositoryBackupSetDir, new RepositoryBackupLogsFilter());
if (cfs.length == 0)
{
throw new BackupConfigurationException("Can not found repository backup log in directory : "
- + repositoryBackupSetDir.getPath());
+ + repositoryBackupSetDir.getPath());
}
if (cfs.length > 1)
{
throw new BackupConfigurationException(
- "Backup set directory should contains only one repository backup log : "
- + repositoryBackupSetDir.getPath());
+ "Backup set directory should contains only one repository backup log : " + repositoryBackupSetDir.getPath());
}
RepositoryBackupChainLog backupChainLog = new RepositoryBackupChainLog(cfs[0]);
@@ -2011,12 +2082,12 @@
catch (RepositoryException e)
{
throw new RepositoryRestoreExeption("Repository \"" + backupChainLog.getOriginalRepositoryEntry().getName()
- + "\" was not restored", e);
+ + "\" was not restored", e);
}
catch (RepositoryConfigurationException e)
{
throw new RepositoryRestoreExeption("Repository \"" + backupChainLog.getOriginalRepositoryEntry().getName()
- + "\" was not restored", e);
+ + "\" was not restored", e);
}
}
@@ -2024,20 +2095,20 @@
* {@inheritDoc}
*/
public void restoreWorkspace(File workspaceBackupSetDir, boolean asynchronous) throws BackupOperationException,
- BackupConfigurationException
+ BackupConfigurationException
{
File[] cfs = PrivilegedFileHelper.listFiles(workspaceBackupSetDir, new BackupLogsFilter());
if (cfs.length == 0)
{
throw new BackupConfigurationException("Can not found workspace backup log in directory : "
- + workspaceBackupSetDir.getPath());
+ + workspaceBackupSetDir.getPath());
}
if (cfs.length > 1)
{
throw new BackupConfigurationException("Backup set directory should contains only one workspace backup log : "
- + workspaceBackupSetDir.getPath());
+ + workspaceBackupSetDir.getPath());
}
BackupChainLog backupChainLog = new BackupChainLog(cfs[0]);
@@ -2045,20 +2116,20 @@
try
{
this.restore(backupChainLog, backupChainLog.getBackupConfig().getRepository(), backupChainLog
- .getOriginalWorkspaceEntry(), asynchronous);
+ .getOriginalWorkspaceEntry(), asynchronous);
}
catch (RepositoryException e)
{
throw new WorkspaceRestoreException("Workapce \"" + backupChainLog.getOriginalWorkspaceEntry().getName()
- + "\" was not restored in repository \"" + backupChainLog.getBackupConfig().getRepository() + "\"", e);
+ + "\" was not restored in repository \"" + backupChainLog.getBackupConfig().getRepository() + "\"", e);
}
catch (RepositoryConfigurationException e)
{
throw new WorkspaceRestoreException("Workapce \"" + backupChainLog.getOriginalWorkspaceEntry().getName()
- + "\" was not restored in repository \"" + backupChainLog.getBackupConfig().getRepository() + "\"", e);
+ + "\" was not restored in repository \"" + backupChainLog.getBackupConfig().getRepository() + "\"", e);
}
}
-
+
}
Modified: jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml 2011-10-05 13:37:30 UTC (rev 5025)
+++ jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml 2011-10-06 06:20:28 UTC (rev 5026)
@@ -141,7 +141,7 @@
<init-params>
<properties-param>
<name>backup-properties</name>
- <property name="default-incremental-job-period" value="3600" /><!-- set default incremental periond = 60 minutes -->
+ <property name="default-incremental-job-period" value="3600" />
<property name="full-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob" />
<property name="incremental-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob" />
<property name="backup-dir" value="target/backup" />
14 years, 6 months
exo-jcr SVN: r5025 - jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-10-05 09:37:30 -0400 (Wed, 05 Oct 2011)
New Revision: 5025
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistingRepositorySameConfigRestore.java
Log:
EXOJCR-1531 : Restoring operation for single-db configuration by optimization cleaning db was improved
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistingRepositorySameConfigRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistingRepositorySameConfigRestore.java 2011-10-05 13:36:58 UTC (rev 5024)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistingRepositorySameConfigRestore.java 2011-10-05 13:37:30 UTC (rev 5025)
@@ -31,7 +31,12 @@
import org.exoplatform.services.jcr.impl.backup.DataRestore;
import org.exoplatform.services.jcr.impl.backup.JCRRestore;
import org.exoplatform.services.jcr.impl.backup.rdbms.DataRestoreContext;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DummyDBCleaner;
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DialectDetecter;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
@@ -83,7 +88,14 @@
// define one common connection for all restores and cleaners for single db case
Connection jdbcConn = null;
- if (!Boolean.parseBoolean(wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.MULTIDB)))
+
+ // define one common database cleaner for all restores for single db case
+ DBCleaner dbCleaner = null;
+
+ Boolean isMultiDb =
+ Boolean.parseBoolean(wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.MULTIDB));
+
+ if (!isMultiDb)
{
String dsName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
@@ -102,10 +114,17 @@
}
});
jdbcConn.setAutoCommit(false);
+
+ if (!(DialectDetecter.detect(jdbcConn.getMetaData()).equals(DBConstants.DB_DIALECT_SYBASE)))
+ {
+ dbCleaner = DBCleanService.getRepositoryDBCleaner(jdbcConn, repositoryEntry);
+ }
}
repositoryService.getRepository(this.repositoryEntry.getName()).setState(ManageableRepository.SUSPENDED);
+ boolean isSharedDbCleaner = false;
+
// collect all restorers
for (WorkspaceEntry wEntry : repositoryEntry.getWorkspaceEntries())
{
@@ -121,9 +140,45 @@
if (jdbcConn != null)
{
- context = new DataRestoreContext(
- new String[] {DataRestoreContext.STORAGE_DIR, DataRestoreContext.DB_CONNECTION},
- new Object[] {fullBackupDir, jdbcConn});
+ if (dbCleaner != null)
+ {
+ if (isSharedDbCleaner)
+ {
+ context = new DataRestoreContext(
+ new String[]{
+ DataRestoreContext.STORAGE_DIR,
+ DataRestoreContext.DB_CONNECTION,
+ DataRestoreContext.DB_CLEANER},
+ new Object[]{
+ fullBackupDir,
+ jdbcConn,
+ new DummyDBCleaner(jdbcConn, new ArrayList<String>())});
+ }
+ else
+ {
+ context = new DataRestoreContext(
+ new String[]{
+ DataRestoreContext.STORAGE_DIR,
+ DataRestoreContext.DB_CONNECTION,
+ DataRestoreContext.DB_CLEANER},
+ new Object[]{
+ fullBackupDir,
+ jdbcConn,
+ dbCleaner});
+
+ isSharedDbCleaner = true;
+ }
+ }
+ else
+ {
+ context = new DataRestoreContext(
+ new String[]{
+ DataRestoreContext.STORAGE_DIR,
+ DataRestoreContext.DB_CONNECTION},
+ new Object[]{
+ fullBackupDir,
+ jdbcConn});
+ }
}
else
{
@@ -152,7 +207,7 @@
{
restorer.commit();
}
-
+
// resume components
repositoryService.getRepository(this.repositoryEntry.getName()).setState(ManageableRepository.ONLINE);
14 years, 7 months
exo-jcr SVN: r5024 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/clean/rdbms and 4 other directories.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-10-05 09:36:58 -0400 (Wed, 05 Oct 2011)
New Revision: 5024
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DB2DBRestore.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/H2DBRestore.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/MySQLDBRestore.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/OracleDBRestore.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleaner.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DummyDBCleaner.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/RecursiveDBCleanHelper.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializerHelper.java
Removed:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/IngresSQLDBClean.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/OracleDBClean.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/PgSQLDBClean.java
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/SybaseDBRestore.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanService.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/init/StorageDBInitializer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializer.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java
Log:
EXOJCR-1531 : Restoring operation for single-db configuration by optimization cleaning db was improved
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DB2DBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DB2DBRestore.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DB2DBRestore.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2003-2011 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.backup.rdbms;
+
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+
+import javax.naming.NamingException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
+ * @version $Id: DB2DBRestore.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class DB2DBRestore extends DBRestore
+{
+ /**
+ * The constraint name is limited by 18 symbols.
+ */
+ private static final int DB2_CONSTRAINT_NAME_LENGTH_LIMIT = 18;
+
+ /**
+ * Constructor DB2DBRestore.
+ */
+ public DB2DBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
+ WorkspaceEntry wsConfig, FileCleaner fileCleaner, DBCleaner dbCleaner) throws NamingException, SQLException,
+ RepositoryConfigurationException
+ {
+ super(storageDir, jdbcConn, tables, wsConfig, fileCleaner, dbCleaner);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected String validateConstraintName(String string)
+ {
+ return string.substring(0, DB2_CONSTRAINT_NAME_LENGTH_LIMIT);
+ }
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java 2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -28,8 +28,7 @@
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.backup.BackupException;
import org.exoplatform.services.jcr.impl.backup.DataRestore;
-import org.exoplatform.services.jcr.impl.clean.rdbms.DBClean;
-import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectZipReaderImpl;
import org.exoplatform.services.jcr.impl.storage.jdbc.DialectDetecter;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
@@ -50,6 +49,7 @@
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -62,7 +62,7 @@
* Date: 22 01 2011
*
* @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
- * @version $Id: DBRestor.java 34360 2010-11-11 11:11:11Z tolusha $
+ * @version $Id: DBRestore.java 34360 2010-11-11 11:11:11Z tolusha $
*/
public class DBRestore implements DataRestore
{
@@ -102,7 +102,7 @@
protected final Connection jdbcConn;
/**
- * Directory with tables dump.
+ * Directory for dumps.
*/
private final File storageDir;
@@ -114,7 +114,7 @@
/**
* Database cleaner.
*/
- private final DBClean dbClean;
+ private final DBCleaner dbCleaner;
/**
* Database dialect.
@@ -122,11 +122,21 @@
protected final int dialect;
/**
- * Contains constraint for JCR_SITEM or JCR_MITEM table.
+ * Contains queries for adding constraints and indexes.
*/
- private String constraint;
+ protected Map<String, String> addQueries = new LinkedHashMap<String, String>();
/**
+ * Contains queries for dropping constraints and indexes.
+ */
+ protected Map<String, String> dropQueries = new LinkedHashMap<String, String>();
+
+ /**
+ * Contains object names which executed queries.
+ */
+ protected List<String> successfulExecuted;
+
+ /**
* Constructor DBRestor.
*
* @throws NamingException
@@ -134,7 +144,7 @@
* @throws RepositoryConfigurationException
*/
public DBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
- WorkspaceEntry wsConfig, FileCleaner fileCleaner) throws NamingException, SQLException,
+ WorkspaceEntry wsConfig, FileCleaner fileCleaner, DBCleaner dbCleaner) throws NamingException, SQLException,
RepositoryConfigurationException
{
this.jdbcConn = jdbcConn;
@@ -145,7 +155,7 @@
this.storageDir = storageDir;
this.tables = tables;
- this.dbClean = DBCleanService.getDBCleaner(this.jdbcConn, wsConfig);
+ this.dbCleaner = dbCleaner;
this.dialect = DialectDetecter.detect(jdbcConn.getMetaData()).hashCode();
}
@@ -156,7 +166,7 @@
{
try
{
- dbClean.clean();
+ dbCleaner.executeCleanScripts();
}
catch (SQLException e)
{
@@ -171,17 +181,20 @@
{
try
{
+ boolean isMultiDb = tables.entrySet().iterator().next().getValue().getDstMultiDb();
+ prepareQueries(isMultiDb);
+
+ preRestoreTables(isMultiDb);
+
for (Entry<String, RestoreTableRule> entry : tables.entrySet())
{
String tableName = entry.getKey();
RestoreTableRule restoreRule = entry.getValue();
- preRestoreTable(tableName, restoreRule);
-
restoreTable(storageDir, jdbcConn, tableName, restoreRule);
+ }
- postRestoreTable(tableName, restoreRule);
- }
+ postRestoreTables(isMultiDb);
}
catch (IOException e)
{
@@ -194,106 +207,135 @@
}
/**
- * Prepare of restore table. (Drop constraint, etc...)
+ * Prepare queries for restoring.
*
- * @param tableName
- * name of table
- * @param restoreRule
- * rule of table
- * @throws SQLException
- * Will throw SQLException if fail.
+ * @param isMultiDb
+ * indicates if we have multi-db configuration or not
*/
- public void preRestoreTable(String tableName, RestoreTableRule restoreRule) throws SQLException
+ protected void prepareQueries(boolean isMultiDb)
{
- Statement st = null;
+ String multiDb = isMultiDb ? "M" : "S";
+
+ String constraintName = validateConstraintName("JCR_PK_" + multiDb + "VALUE");
+ String constraint = "CONSTRAINT " + constraintName + " PRIMARY KEY(ID)";
+ addQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "VALUE ADD " + constraint);
+ dropQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "VALUE " + dropCommand(true, constraintName));
- try
- {
- if (tableName.equals("JCR_SITEM") || tableName.equals("JCR_MITEM"))
- {
- // resolve constraint name depends on database
- String constraintName;
- if (dialect == DBBackup.DB_DIALECT_DB2 || dialect == DBBackup.DB_DIALECT_DB2V8)
- {
- constraintName = "JCR_FK_" + (restoreRule.getDstMultiDb() ? "M" : "S") + "ITEM_PAREN";
- }
- else
- {
- constraintName = "JCR_FK_" + (restoreRule.getDstMultiDb() ? "M" : "S") + "ITEM_PARENT";
- }
- constraint = "CONSTRAINT " + constraintName + " FOREIGN KEY(PARENT_ID) REFERENCES " + tableName + "(ID)";
+ constraintName = validateConstraintName("JCR_PK_" + multiDb + "ITEM");
+ constraint = "CONSTRAINT " + constraintName + " PRIMARY KEY(ID)";
+ addQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "ITEM ADD " + constraint);
- // drop constraint
- st = jdbcConn.createStatement();
+ constraintName = validateConstraintName("JCR_FK_" + multiDb + "VALUE_PROPERTY");
+ constraint = "CONSTRAINT " + constraintName + " FOREIGN KEY(PROPERTY_ID) REFERENCES JCR_" + multiDb + "ITEM(ID)";
+ addQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "VALUE ADD " + constraint);
+ dropQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "VALUE " + dropCommand(false, constraintName));
- if (dialect == DBBackup.DB_DIALECT_MYSQL || dialect == DBBackup.DB_DIALECT_MYSQL_UTF8)
- {
- st.execute("ALTER TABLE " + tableName + " DROP FOREIGN KEY " + constraintName);
- }
- else
- {
- st.execute("ALTER TABLE " + tableName + " DROP CONSTRAINT " + constraintName);
- }
- }
- }
- finally
- {
- if (st != null)
- {
- try
- {
- st.close();
- }
- catch (SQLException e)
- {
- LOG.warn("Can't close statemnt", e);
- }
- }
- }
+ constraintName = validateConstraintName("JCR_FK_" + multiDb + "ITEM_PARENT");
+ constraint = "CONSTRAINT " + constraintName + " FOREIGN KEY(PARENT_ID) REFERENCES JCR_" + multiDb + "ITEM(ID)";
+ addQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "ITEM ADD " + constraint);
+ dropQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "ITEM " + dropCommand(false, constraintName));
+
+ constraintName = validateConstraintName("JCR_PK_" + multiDb + "ITEM");
+ dropQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "ITEM " + dropCommand(true, constraintName));
+
+ constraintName = validateConstraintName("JCR_PK_" + multiDb + "REF");
+ constraint = "CONSTRAINT " + constraintName + " PRIMARY KEY(NODE_ID, PROPERTY_ID, ORDER_NUM)";
+ addQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "REF ADD " + constraint);
+ dropQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "REF " + dropCommand(true, constraintName));
+
+ constraintName = validateConstraintName("JCR_PK_" + multiDb + "CONTAINER");
+ constraint = "CONSTRAINT " + constraintName + " PRIMARY KEY(VERSION)";
+ addQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "CONTAINER ADD " + constraint);
+ dropQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "CONTAINER " + dropCommand(true, constraintName));
}
/**
- * After of restore table. (Add constraint, etc...)
+ * Validate name of constraint. For some DBs constrains name is limited.
*
- * @param tableName
- * name of table
- * @param restoreRule
- * rule of table
+ * @param string
+ * the constraint name
+ * @return the constraint name accepted for specific DB
+ */
+ protected String validateConstraintName(String string)
+ {
+ return string;
+ }
+
+ /**
+ * Return the command to drop primary or foreign key.
+ *
+ * @param isPrimaryKey
+ * boolean
+ * @return String
+ */
+ protected String dropCommand(boolean isPrimaryKey, String constraintName)
+ {
+ return "DROP CONSTRAINT " + constraintName;
+ }
+
+ /**
+ * Prepare of restore tables. (Drop constraint, etc...)
+ *
+ * @param isMultiDb
+ * boolean
* @throws SQLException
+ * will throw SQLException if fail.
+ */
+ public void preRestoreTables(boolean isMultiDb) throws SQLException
+ {
+ executeQueries(dropQueries);
+ }
+
+ /**
+ * After of restore tables. (Add constraint, etc...)
+ *
+ * @param isMultiDb
+ * boolean
+ * @throws SQLException
* Will throw SQLException if fail.
*/
- public void postRestoreTable(String tableName, RestoreTableRule restoreRule) throws SQLException
+ public void postRestoreTables(boolean isMultiDb) throws SQLException
{
+ executeQueries(addQueries);
+ }
+
+ /**
+ * Execute queries.
+ *
+ * @param queries
+ * the map with queries.
+ * @throws SQLException
+ */
+ protected List<String> executeQueries(final Map<String, String> queries) throws SQLException
+ {
+ successfulExecuted = new ArrayList<String>();
Statement st = null;
- try
+ for (String constraintName : queries.keySet())
{
- if (tableName.equals("JCR_SITEM") || tableName.equals("JCR_MITEM"))
+ try
{
- if (constraint != null)
- {
- // add constraint
- st = jdbcConn.createStatement();
- st.execute("ALTER TABLE " + tableName + " ADD " + constraint);
- }
+ st = jdbcConn.createStatement();
+ st.execute(queries.get(constraintName));
+ successfulExecuted.add(constraintName);
}
- }
- finally
- {
- constraint = null;
-
- if (st != null)
+ finally
{
- try
+ if (st != null)
{
- st.close();
+ try
+ {
+ st.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.warn("Can't close statemnt", e);
+ }
}
- catch (SQLException e)
- {
- LOG.warn("Can't close statemnt", e);
- }
}
}
+
+ return successfulExecuted;
}
/**
@@ -303,6 +345,16 @@
{
try
{
+ try
+ {
+ // don't care about any exception here
+ dbCleaner.executeCommitScripts();
+ }
+ catch (Exception e)
+ {
+ LOG.error("Can't remove temporary objects after cleaning", e);
+ }
+
jdbcConn.commit();
}
catch (SQLException e)
@@ -319,6 +371,9 @@
try
{
jdbcConn.rollback();
+
+ dbCleaner.executeRollbackScripts();
+ jdbcConn.commit();
}
catch (SQLException e)
{
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/H2DBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/H2DBRestore.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/H2DBRestore.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2003-2011 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.backup.rdbms;
+
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+
+import javax.naming.NamingException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
+ * @version $Id: H2DBRestore.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class H2DBRestore extends DBRestore
+{
+
+ /**
+ * Constructor H2DBRestore.
+ */
+ public H2DBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
+ WorkspaceEntry wsConfig, FileCleaner fileCleaner, DBCleaner dbCleaner) throws NamingException, SQLException,
+ RepositoryConfigurationException
+ {
+ super(storageDir, jdbcConn, tables, wsConfig, fileCleaner, dbCleaner);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void prepareQueries(boolean isMultiDb)
+ {
+ super.prepareQueries(isMultiDb);
+
+ // H2 doesn't contain primary key for JCR_SVALUE (JCR_MVALUE) table
+ String constraintName = "JCR_PK_" + (isMultiDb ? "M" : "S") + "VALUE";
+ addQueries.remove(constraintName);
+ dropQueries.remove(constraintName);
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/MySQLDBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/MySQLDBRestore.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/MySQLDBRestore.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2003-2011 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.backup.rdbms;
+
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+
+import javax.naming.NamingException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
+ * @version $Id: MySQLDBRestore.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class MySQLDBRestore extends DBRestore
+{
+
+ /**
+ * Constructor MySQLDBRestore.
+ */
+ public MySQLDBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
+ WorkspaceEntry wsConfig, FileCleaner fileCleaner, DBCleaner dbCleaner) throws NamingException, SQLException,
+ RepositoryConfigurationException
+ {
+ super(storageDir, jdbcConn, tables, wsConfig, fileCleaner, dbCleaner);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected String dropCommand(boolean isPrimaryKey, String constraintName)
+ {
+ return isPrimaryKey == true ? "DROP PRIMARY KEY" : "DROP FOREIGN KEY " + constraintName;
+ }
+
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/OracleDBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/OracleDBRestore.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/OracleDBRestore.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2003-2011 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.backup.rdbms;
+
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+
+import javax.naming.NamingException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
+ * @version $Id: OracleDBRestore.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class OracleDBRestore extends DBRestore
+{
+
+ /**
+ * OracleDBRestore constructor.
+ */
+ public OracleDBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
+ WorkspaceEntry wsConfig, FileCleaner fileCleaner, DBCleaner dbCleaner) throws NamingException, SQLException,
+ RepositoryConfigurationException
+ {
+ super(storageDir, jdbcConn, tables, wsConfig, fileCleaner, dbCleaner);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void prepareQueries(boolean isMultiDb)
+ {
+ String multiDb = isMultiDb ? "M" : "S";
+
+ String indexName = "JCR_IDX_" + multiDb + "ITEM_PARENT_FK";
+ addQueries.put(indexName, "CREATE INDEX " + indexName + " ON JCR_" + multiDb + "ITEM(PARENT_ID)");
+ dropQueries.put(indexName, "DROP INDEX " + indexName);
+
+ indexName = "JCR_IDX_" + multiDb + "ITEM_PARENT";
+ addQueries.put(indexName, "CREATE UNIQUE INDEX " + indexName + " ON JCR_" + multiDb
+ + "ITEM(CONTAINER_NAME, PARENT_ID, NAME, I_INDEX, I_CLASS, VERSION DESC)");
+ dropQueries.put(indexName, "DROP INDEX " + indexName);
+
+ indexName = "JCR_IDX_" + multiDb + "ITEM_PARENT_NAME";
+ addQueries.put(indexName, "CREATE UNIQUE INDEX " + indexName + " ON JCR_" + multiDb
+ + "ITEM(I_CLASS, CONTAINER_NAME, PARENT_ID, NAME, I_INDEX, VERSION DESC)");
+ dropQueries.put(indexName, "DROP INDEX " + indexName);
+
+ indexName = "JCR_IDX_" + multiDb + "ITEM_PARENT_ID";
+ addQueries.put(indexName, "CREATE UNIQUE INDEX " + indexName + " ON JCR_" + multiDb
+ + "ITEM(I_CLASS, CONTAINER_NAME, PARENT_ID, ID, VERSION DESC)");
+ dropQueries.put(indexName, "DROP INDEX " + indexName);
+
+ indexName = "JCR_IDX_" + multiDb + "VALUE_PROPERTY";
+ addQueries.put(indexName, "CREATE UNIQUE INDEX " + indexName + " ON JCR_" + multiDb
+ + "VALUE(PROPERTY_ID, ORDER_NUM)");
+ dropQueries.put(indexName, "DROP INDEX " + indexName);
+
+ indexName = "JCR_IDX_" + multiDb + "REF_PROPERTY";
+ addQueries.put(indexName, "CREATE UNIQUE INDEX " + indexName + " ON JCR_" + multiDb
+ + "REF(PROPERTY_ID, ORDER_NUM)");
+ dropQueries.put(indexName, "DROP INDEX " + indexName);
+
+ super.prepareQueries(isMultiDb);
+ }
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/SybaseDBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/SybaseDBRestore.java 2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/SybaseDBRestore.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -20,13 +20,14 @@
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.Map;
-import java.util.Map.Entry;
import javax.naming.NamingException;
@@ -38,16 +39,19 @@
* @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
* @version $Id: SybaseDBRestore.java 111 2011-11-11 11:11:11Z rainf0x $
*/
-public class SybaseDBRestore
- extends DBRestore
+public class SybaseDBRestore extends DBRestore
{
- private String restoreConstraint = null;
-
+ private final Boolean isMultiDb;
+
+ /**
+ * Constructor SybaseDBRestore.
+ */
public SybaseDBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
- WorkspaceEntry wsConfig, FileCleaner fileCleaner) throws NamingException, SQLException,
+ WorkspaceEntry wsConfig, FileCleaner fileCleaner, DBCleaner dbCleaner) throws NamingException, SQLException,
RepositoryConfigurationException
{
- super(storageDir, jdbcConn, tables, wsConfig, fileCleaner);
+ super(storageDir, jdbcConn, tables, wsConfig, fileCleaner, dbCleaner);
+ this.isMultiDb = tables.entrySet().iterator().next().getValue().getDstMultiDb();
}
/**
@@ -55,19 +59,13 @@
*/
public void clean() throws BackupException
{
-
try
{
// the Sybase is not allowed DDL query (CREATE TABLE, DROP TABLE, etc. ) within a multi-statement transaction
jdbcConn.setAutoCommit(true);
- for (Entry<String, RestoreTableRule> entry : tables.entrySet())
- {
- String tableName = entry.getKey();
- RestoreTableRule restoreRule = entry.getValue();
-
- super.preRestoreTable(tableName, restoreRule);
- }
+ super.prepareQueries(isMultiDb);
+ super.executeQueries(dropQueries);
}
catch (SQLException e)
{
@@ -148,12 +146,22 @@
// restore constraint
jdbcConn.setAutoCommit(true);
- for (Entry<String, RestoreTableRule> entry : tables.entrySet())
+ if (successfulExecuted.size() == addQueries.size())
{
- String tableName = entry.getKey();
- RestoreTableRule restoreRule = entry.getValue();
+ executeQueries(addQueries);
+ }
+ else
+ {
+ ArrayList<String> notDeletedConstraints = new ArrayList<String>();
+ notDeletedConstraints.addAll(addQueries.keySet());
+ notDeletedConstraints.removeAll(successfulExecuted);
- super.postRestoreTable(tableName, restoreRule);
+ for (String notDeletedConstraint : notDeletedConstraints)
+ {
+ addQueries.remove(notDeletedConstraint);
+ }
+
+ executeQueries(addQueries);
}
}
catch (SQLException e)
@@ -176,14 +184,27 @@
/**
* {@inheritDoc}
*/
- public void preRestoreTable(String tableName, RestoreTableRule restoreRule) throws SQLException
+ public void preRestoreTables(boolean isMultiDb) throws SQLException
{
}
/**
* {@inheritDoc}
*/
- public void postRestoreTable(String tableName, RestoreTableRule restoreRule) throws SQLException
+ public void postRestoreTables(boolean isMultiDb) throws SQLException
{
}
+
+ /**
+ * {@inheritDoc}
+ */
+ protected String validateConstraintName(String string)
+ {
+ if (string.equals("JCR_PK_SCONTAINER"))
+ {
+ return "JCR_PK_MCONTAINER";
+ }
+
+ return super.validateConstraintName(string);
+ }
}
Deleted: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java 2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -1,219 +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.clean.rdbms;
-
-import org.exoplatform.commons.utils.SecurityHelper;
-import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
-import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCUtils;
-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.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: DBClean.java 3769 2011-01-04 15:36:06Z areshetnyak $
- */
-public class DBClean
-{
- /**
- * Logger.
- */
- protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBClean");
-
- /**
- * 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 DBClean(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
- */
- public DBClean(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;
- }
-
- /**
- * Clean data from database. The method doesn't close connection or perform commit.
- *
- * @throws SQLException
- * if any errors occurred
- */
- public void clean() throws SQLException
- {
- SecurityManager security = System.getSecurityManager();
- if (security != null)
- {
- security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
- }
-
- String sql = null;
- Statement st = null;
- try
- {
- st = connection.createStatement();
- for (String scr : cleanScripts)
- {
- 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();
- }
- }
- finally
- {
- if (st != null)
- {
- try
- {
- st.close();
- }
- catch (SQLException e)
- {
- LOG.error("Can't close the Statement." + 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
- {
- return JDBCUtils.tableExists(tableName, conn);
- }
-
- /**
- * 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;
- }
-}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java 2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2010 eXo Platform SAS.
+ * Copyright (C) 2003-2011 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
@@ -16,133 +16,23 @@
*/
package org.exoplatform.services.jcr.impl.clean.rdbms;
-import org.exoplatform.commons.utils.SecurityHelper;
-import org.exoplatform.services.jcr.impl.Constants;
-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;
/**
- *
* Created by The eXo Platform SAS.
- *
- * Date: 21.01.2011
*
- * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
- * @version $Id: DBCleanHelper.java.java 34360 2010-11-11 11:11:11Z tolusha $
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
+ * @version $Id: DBCleanHelper.java 111 2011-11-11 11:11:11Z rainf0x $
*/
-public class DBCleanHelper
+public interface DBCleanHelper
{
-
/**
- * Logger.
- */
- protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBCleanHelper");
-
- /**
- * Select items query.
- */
- private final String selectItems;
-
- /**
- * Remove items query.
- */
- private final String removeItems;
-
- /**
- * Connection to database.
- */
- protected final Connection connection;
-
- /**
- * DBCleanerHelper constructor.
- */
- public DBCleanHelper(Connection connection, String selectItemds, String removeItems)
- {
- this.connection = connection;
- this.selectItems = selectItemds;
- this.removeItems = removeItems;
- }
-
- /**
- * Removing rows from table. Some database do not support cascade delete,
- * or need special sittings. 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.
+ * Clean data from database. The method doesn't close connection or perform commit.
*
- * @throws SQLException
- * SQL exception.
+ * @throws SQLException
+ * if any errors occurred
*/
- public void clean() throws SQLException
- {
- recursiveClean(Constants.ROOT_PARENT_UUID);
- }
-
- private void recursiveClean(String parentID) throws SQLException
- {
- PreparedStatement selectStatement = null;
- PreparedStatement removeStatement = null;
- ResultSet result = null;
-
- try
- {
- selectStatement = connection.prepareStatement(this.selectItems);
- selectStatement.setString(1, parentID);
-
- final PreparedStatement fSelectStatement = selectStatement;
- result = (ResultSet)SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
- {
- public Object run() throws Exception
- {
- return fSelectStatement.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
- removeStatement = connection.prepareStatement(this.removeItems);
- removeStatement.setString(1, parentID);
-
- final PreparedStatement fRemoveStatement = removeStatement;
- SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
- {
- public Object run() throws Exception
- {
- fRemoveStatement.executeUpdate();
- return null;
- }
- });
- }
- }
- finally
- {
- if (selectStatement != null)
- {
- selectStatement.close();
- }
-
- if (removeStatement != null)
- {
- removeStatement.close();
- }
-
- if (result != null)
- {
- result.close();
- }
- }
- }
+ public void executeCleanScripts() throws SQLException;
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanService.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanService.java 2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanService.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -24,7 +24,11 @@
import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
import org.exoplatform.services.jcr.impl.storage.jdbc.DialectDetecter;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
+import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerHelper;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import java.io.IOException;
import java.security.PrivilegedExceptionAction;
import java.sql.Connection;
import java.sql.ResultSet;
@@ -49,6 +53,16 @@
public class DBCleanService
{
/**
+ * Logger.
+ */
+ protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBCleanService");
+
+ /**
+ * Old object suffix. Will using in rename.
+ */
+ public static final String OLD_OBJECT_SUFFIX = "_OLD";
+
+ /**
* Cleans workspace data from database.
*
* @param wsEntry
@@ -78,14 +92,26 @@
});
jdbcConn.setAutoCommit(false);
+ DBCleaner dbCleaner = getWorkspaceDBCleaner(jdbcConn, wsEntry);
try
{
- getDBCleaner(jdbcConn, wsEntry).clean();
+ dbCleaner.executeCleanScripts();
+ try
+ {
+ dbCleaner.executeCommitScripts();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't remove temporary objects", e);
+ }
jdbcConn.commit();
}
catch (SQLException e)
{
jdbcConn.rollback();
+
+ dbCleaner.executeRollbackScripts();
+ jdbcConn.commit();
}
finally
{
@@ -112,17 +138,307 @@
}
/**
- * Returns database cleaner for manual cleaning.
+ * Returns database cleaner for manual cleaning for repository.
*
* @param jdbcConn
* database connection which need to use
* @param wsEntry
* workspace configuration
+ * @return database cleaner or null in case of multi-db configuration
+ * @throws SQLException
+ * @throws RepositoryConfigurationException
+ */
+ public static DBCleaner getRepositoryDBCleaner(Connection jdbcConn, RepositoryEntry repoEntry) throws SQLException,
+ RepositoryConfigurationException
+ {
+ final boolean isMultiDB =
+ Boolean.parseBoolean(repoEntry.getWorkspaceEntries().get(0).getContainer().getParameterValue(
+ JDBCWorkspaceDataContainer.MULTIDB));
+
+ if (isMultiDB)
+ {
+ return null;
+ }
+
+ String dialect = DialectDetecter.detect(jdbcConn.getMetaData());
+
+ if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
+ {
+ ArrayList<String> dbCleanerScripts = new ArrayList<String>();
+ dbCleanerScripts.addAll(getRenameScripts(isMultiDB, dialect));
+ dbCleanerScripts.addAll(getInitializationDBScript(isMultiDB, dialect));
+
+ return new DBCleaner(jdbcConn, dbCleanerScripts, getRollbackRenamedScript(isMultiDB, dialect),
+ getAfterRestoreScript(isMultiDB, dialect));
+ }
+ else if (dialect.equals(DBConstants.DB_DIALECT_HSQLDB))
+ {
+ ArrayList<String> dbCleanerScripts = new ArrayList<String>();
+ dbCleanerScripts.add("delete from JCR_" + (isMultiDB ? "M" : "S") + "VALUE");
+ dbCleanerScripts.add("delete from JCR_" + (isMultiDB ? "M" : "S") + "ITEM");
+ dbCleanerScripts.add("delete from JCR_" + (isMultiDB ? "M" : "S") + "REF");
+ dbCleanerScripts.add("delete from JCR_" + (isMultiDB ? "M" : "S") + "CONTAINER");
+ dbCleanerScripts.add(DBInitializerHelper.getRootNodeInitializeScript(isMultiDB));
+
+ return new DBCleaner(jdbcConn, dbCleanerScripts);
+ }
+
+ ArrayList<String> dbCleanerScripts = new ArrayList<String>();
+ dbCleanerScripts.addAll(getDropTableScripts(isMultiDB, dialect));
+ dbCleanerScripts.addAll(getInitializationDBScript(isMultiDB, dialect));
+
+ return new DBCleaner(jdbcConn, dbCleanerScripts);
+
+ }
+
+ /**
+ * Create list with queries to drop tables, etc...
+ *
+ * @param multiDb
+ * @return List
+ * return list with query
+ */
+ protected static List<String> getDropTableScripts(boolean multiDb, String dialect)
+ {
+ final String isMultiDB = (multiDb ? "M" : "S");
+
+ List<String> cleanScripts = new ArrayList<String>();
+
+ if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
+ {
+ cleanScripts.add("drop trigger BI_JCR_" + isMultiDB + "VALUE");
+ cleanScripts.add("drop sequence JCR_" + isMultiDB + "VALUE_SEQ");
+ }
+
+ cleanScripts.add("drop table JCR_" + isMultiDB + "VALUE");
+ cleanScripts.add("drop table JCR_" + isMultiDB + "ITEM");
+ cleanScripts.add("drop table JCR_" + isMultiDB + "REF");
+ cleanScripts.add("drop table JCR_" + isMultiDB + "CONTAINER");
+
+ return cleanScripts;
+ }
+
+ /**
+ * Create script to rename tables, indexes, etc...
+ *
+ * @param multiDb
+ * boolean
+ * @param dialect
+ * string
+ * @return List
+ * return list with query
+ */
+ protected static List<String> getRenameScripts(boolean multiDb, String dialect)
+ {
+ final String isMultiDB = (multiDb ? "M" : "S");
+
+ List<String> renameScripts = new ArrayList<String>();
+
+ // JCR_[S,M]VALUE
+ renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "VALUE RENAME TO JCR_" + isMultiDB + "VALUE"
+ + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "VALUE" + OLD_OBJECT_SUFFIX + " RENAME CONSTRAINT JCR_PK_"
+ + isMultiDB + "VALUE TO JCR_PK_" + isMultiDB + "VALUE" + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "VALUE" + OLD_OBJECT_SUFFIX + " RENAME CONSTRAINT JCR_FK_"
+ + isMultiDB + "VALUE_PROPERTY TO JCR_FK_" + isMultiDB + "VALUE_PROPERTY" + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "VALUE RENAME TO JCR_PK_" + isMultiDB + "VALUE"
+ + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "VALUE_PROPERTY RENAME TO JCR_IDX_" + isMultiDB
+ + "VALUE_PROPERTY" + OLD_OBJECT_SUFFIX);
+
+ if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
+ {
+ renameScripts.add("RENAME JCR_" + isMultiDB + "VALUE_SEQ TO JCR_" + isMultiDB + "VALUE_SEQ"
+ + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER TRIGGER BI_JCR_" + isMultiDB + "VALUE RENAME TO BI_JCR_" + isMultiDB + "VALUE"
+ + OLD_OBJECT_SUFFIX);
+ }
+
+ // JCR_[S,M]ITEM
+ renameScripts
+ .add("ALTER TABLE JCR_" + isMultiDB + "ITEM RENAME TO JCR_" + isMultiDB + "ITEM" + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "ITEM" + OLD_OBJECT_SUFFIX + " RENAME CONSTRAINT JCR_PK_"
+ + isMultiDB + "ITEM TO JCR_PK_" + isMultiDB + "ITEM" + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "ITEM" + OLD_OBJECT_SUFFIX + " RENAME CONSTRAINT JCR_FK_"
+ + isMultiDB + "ITEM_PARENT TO JCR_FK_" + isMultiDB + "ITEM_PARENT" + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "ITEM RENAME TO JCR_PK_" + isMultiDB + "ITEM"
+ + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT_FK RENAME TO JCR_IDX_" + isMultiDB
+ + "ITEM_PARENT_FK" + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT RENAME TO JCR_IDX_" + isMultiDB
+ + "ITEM_PARENT" + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT_NAME RENAME TO JCR_IDX_" + isMultiDB
+ + "ITEM_PARENT_NAME" + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT_ID RENAME TO JCR_IDX_" + isMultiDB
+ + "ITEM_PARENT_ID" + OLD_OBJECT_SUFFIX);
+
+ // JCR_[S,M]CONTAINER
+ renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "CONTAINER RENAME TO JCR_" + isMultiDB + "CONTAINER"
+ + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "CONTAINER" + OLD_OBJECT_SUFFIX + " RENAME CONSTRAINT JCR_PK_"
+ + isMultiDB + "CONTAINER TO JCR_PK_" + isMultiDB + "CONTAINER" + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "CONTAINER RENAME TO JCR_PK_" + isMultiDB + "CONTAINER"
+ + OLD_OBJECT_SUFFIX);
+
+ // JCR_[S,M]REF
+ renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "REF RENAME TO JCR_" + isMultiDB + "REF" + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "REF" + OLD_OBJECT_SUFFIX + " RENAME CONSTRAINT JCR_PK_"
+ + isMultiDB + "REF TO JCR_PK_" + isMultiDB + "REF" + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "REF RENAME TO JCR_PK_" + isMultiDB + "REF"
+ + OLD_OBJECT_SUFFIX);
+ renameScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "REF_PROPERTY RENAME TO JCR_IDX_" + isMultiDB
+ + "REF_PROPERTY" + OLD_OBJECT_SUFFIX);
+
+ return renameScripts;
+ }
+
+ /**
+ * Create script to rollback changes after rename.
+ *
+ * @param multiDb
+ * boolean
+ * @param dialect
+ * string
+ * @return List
+ * return list with query
+ */
+ protected static List<String> getRollbackRenamedScript(boolean multiDb, String dialect)
+ {
+ final String isMultiDB = (multiDb ? "M" : "S");
+
+ List<String> rollbackScripts = new ArrayList<String>();
+
+ rollbackScripts.addAll(getDropTableScripts(multiDb, dialect));
+
+ // JCR_[S,M]VALUE
+ rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "VALUE" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_" + isMultiDB
+ + "VALUE");
+ rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "VALUE RENAME CONSTRAINT JCR_PK_" + isMultiDB
+ + "VALUE" + OLD_OBJECT_SUFFIX + " TO JCR_PK_" + isMultiDB + "VALUE");
+ rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "VALUE RENAME CONSTRAINT JCR_FK_" + isMultiDB
+ + "VALUE_PROPERTY" + OLD_OBJECT_SUFFIX + " TO JCR_FK_" + isMultiDB + "VALUE_PROPERTY");
+ rollbackScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "VALUE" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_PK_"
+ + isMultiDB + "VALUE");
+ rollbackScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "VALUE_PROPERTY" + OLD_OBJECT_SUFFIX
+ + " RENAME TO JCR_IDX_" + isMultiDB + "VALUE_PROPERTY");
+
+ if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
+ {
+ rollbackScripts.add("RENAME JCR_" + isMultiDB + "VALUE_SEQ" + OLD_OBJECT_SUFFIX + " TO JCR_" + isMultiDB
+ + "VALUE_SEQ");
+ rollbackScripts.add("ALTER TRIGGER BI_JCR_" + isMultiDB + "VALUE" + OLD_OBJECT_SUFFIX + " RENAME TO BI_JCR_"
+ + isMultiDB + "VALUE");
+ }
+
+ // JCR_[S,M]ITEM
+ rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "ITEM" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_" + isMultiDB
+ + "ITEM");
+ rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "ITEM RENAME CONSTRAINT JCR_PK_" + isMultiDB
+ + "ITEM" + OLD_OBJECT_SUFFIX + " TO JCR_PK_" + isMultiDB + "ITEM");
+ rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "ITEM RENAME CONSTRAINT JCR_FK_" + isMultiDB
+ + "ITEM_PARENT" + OLD_OBJECT_SUFFIX + " TO JCR_FK_" + isMultiDB + "ITEM_PARENT");
+ rollbackScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "ITEM" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_PK_"
+ + isMultiDB + "ITEM");
+ rollbackScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT_FK" + OLD_OBJECT_SUFFIX
+ + " RENAME TO JCR_IDX_" + isMultiDB + "ITEM_PARENT_FK");
+ rollbackScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT" + OLD_OBJECT_SUFFIX
+ + " RENAME TO JCR_IDX_" + isMultiDB + "ITEM_PARENT");
+ rollbackScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT_NAME" + OLD_OBJECT_SUFFIX
+ + " RENAME TO JCR_IDX_" + isMultiDB + "ITEM_PARENT_NAME");
+ rollbackScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT_ID" + OLD_OBJECT_SUFFIX
+ + " RENAME TO JCR_IDX_" + isMultiDB + "ITEM_PARENT_ID");
+
+ // JCR_[S,M]CONTAINER
+ rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "CONTAINER" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_"
+ + isMultiDB + "CONTAINER");
+ rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "CONTAINER RENAME CONSTRAINT JCR_PK_" + isMultiDB
+ + "CONTAINER" + OLD_OBJECT_SUFFIX + " TO JCR_PK_" + isMultiDB + "CONTAINER");
+ rollbackScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "CONTAINER" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_PK_"
+ + isMultiDB + "CONTAINER");
+
+ // JCR_[S,M]REF
+ rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "REF" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_" + isMultiDB
+ + "REF");
+ rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "REF RENAME CONSTRAINT JCR_PK_" + isMultiDB
+ + "REF" + OLD_OBJECT_SUFFIX + " TO JCR_PK_" + isMultiDB + "REF");
+ rollbackScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "REF" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_PK_"
+ + isMultiDB + "REF");
+ rollbackScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "REF_PROPERTY" + OLD_OBJECT_SUFFIX
+ + " RENAME TO JCR_IDX_" + isMultiDB + "REF_PROPERTY");
+
+ return rollbackScripts;
+ }
+
+ /**
+ * Create script to drop old tables, indexes, etc...after successful restore DB.
+ *
+ * @param multiDb
+ * boolean
+ * @param dialect
+ * string
+ * @return List
+ * return list with query
+ */
+ protected static List<String> getAfterRestoreScript(boolean multiDb, String dialect)
+ {
+ List<String> afterRetoreScripts = new ArrayList<String>();
+
+ for (String query : getDropTableScripts(multiDb, dialect))
+ {
+ afterRetoreScripts.add(query + OLD_OBJECT_SUFFIX);
+ }
+
+ return afterRetoreScripts;
+ }
+
+ /**
+ * Create list with queries to initialization database.
+ *
+ * @param multiDb
+ * @param dialect
* @return
+ * @throws RepositoryConfigurationException
+ */
+ protected static List<String> getInitializationDBScript(boolean multiDb, String dialect)
+ throws RepositoryConfigurationException
+ {
+ String scriptsPath = DBInitializerHelper.scriptPath(dialect, multiDb);
+ String script;
+ try
+ {
+ script = DBInitializerHelper.readScriptResource(scriptsPath);
+ }
+ catch (IOException e)
+ {
+ throw new RepositoryConfigurationException("Can not read script file " + scriptsPath, e);
+ }
+
+ List<String> scripts = new ArrayList<String>();
+
+ for (String query : DBInitializerHelper.scripts(script))
+ {
+ scripts.add(DBInitializerHelper.cleanWhitespaces(query));
+ }
+
+ String rootParent_container = DBInitializerHelper.getRootNodeInitializeScript(multiDb);
+
+ scripts.add(rootParent_container);
+
+ return scripts;
+ }
+
+ /**
+ * Returns database cleaner for manual cleaning for workspace.
+ *
+ * @param jdbcConn
+ * database connection which need to use
+ * @param wsEntry
+ * workspace configuration
+ * @return
* @throws SQLException
* @throws RepositoryConfigurationException
*/
- public static DBClean getDBCleaner(Connection jdbcConn, WorkspaceEntry wsEntry) throws SQLException,
+ public static DBCleaner getWorkspaceDBCleaner(Connection jdbcConn, WorkspaceEntry wsEntry) throws SQLException,
RepositoryConfigurationException
{
boolean multiDb =
@@ -139,7 +455,7 @@
else if (dialect.equals(DBConstants.DB_DIALECT_MYSQL) || dialect.equals(DBConstants.DB_DIALECT_MYSQL_UTF8))
{
cleanWithHelper = true;
-
+
Statement st = jdbcConn.createStatement();
st.execute("SELECT ENGINE FROM information_schema.TABLES where TABLE_SCHEMA='" + jdbcConn.getCatalog()
+ "' and (TABLE_NAME='JCR_SITEM' or TABLE_NAME='JCR_MITEM')");
@@ -155,30 +471,40 @@
}
List<String> cleanScripts = new ArrayList<String>();
+
if (multiDb)
{
- cleanScripts.add("delete from JCR_MVALUE");
- cleanScripts.add("delete from JCR_MREF");
-
- if (cleanWithHelper)
+ if (dialect.equals(DBConstants.DB_DIALECT_SYBASE) || dialect.equals(DBConstants.DB_DIALECT_HSQLDB))
{
- cleanScripts.add("delete from JCR_MITEM where I_CLASS=2");
+ cleanScripts.add("delete from JCR_MVALUE");
+ cleanScripts.add("delete from JCR_MREF");
- String selectItems = "select ID from JCR_MITEM where I_CLASS=1 and PARENT_ID=?";
- String deleteItems = "delete from JCR_MITEM where I_CLASS=1 and PARENT_ID=?";
+ if (cleanWithHelper)
+ {
+ cleanScripts.add("delete from JCR_MITEM where I_CLASS=2");
- return new DBClean(jdbcConn, cleanScripts, new DBCleanHelper(jdbcConn, selectItems, deleteItems));
+ String selectItems = "select ID from JCR_MITEM where I_CLASS=1 and PARENT_ID=?";
+ String deleteItems = "delete from JCR_MITEM where I_CLASS=1 and PARENT_ID=?";
+
+ return new DBCleaner(jdbcConn, cleanScripts, new RecursiveDBCleanHelper(jdbcConn, selectItems,
+ deleteItems));
+ }
+
+ cleanScripts.add("delete from JCR_MITEM where JCR_MITEM.name <> '" + Constants.ROOT_PARENT_NAME + "'");
}
-
- cleanScripts.add("delete from JCR_MITEM where JCR_MITEM.NAME <> '" + Constants.ROOT_PARENT_NAME + "'");
+ else
+ {
+ cleanScripts.addAll(getDropTableScripts(multiDb, dialect));
+ cleanScripts.addAll(getInitializationDBScript(multiDb, dialect));
+ }
}
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='"
+ .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='"
+ .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 (cleanWithHelper)
@@ -190,27 +516,24 @@
String deleteItems =
"delete from JCR_SITEM where I_CLASS=1 and CONTAINER_NAME='" + containerName + "' and PARENT_ID=?";
- return new DBClean(jdbcConn, cleanScripts, new DBCleanHelper(jdbcConn, selectItems, deleteItems));
+ return new DBCleaner(jdbcConn, cleanScripts, new RecursiveDBCleanHelper(jdbcConn, selectItems, deleteItems));
}
cleanScripts.add("delete from JCR_SITEM where CONTAINER_NAME='" + containerName + "'");
}
- if (dialect.equals(DBConstants.DB_DIALECT_PGSQL))
+ if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
{
- return new PgSQLDBClean(jdbcConn, cleanScripts);
+ ArrayList<String> dbCleanerScripts = new ArrayList<String>();
+ dbCleanerScripts.addAll(getRenameScripts(multiDb, dialect));
+ dbCleanerScripts.addAll(getInitializationDBScript(multiDb, dialect));
+
+ return new DBCleaner(jdbcConn, dbCleanerScripts, getRollbackRenamedScript(multiDb, dialect),
+ getAfterRestoreScript(multiDb, dialect));
}
- else if (dialect.equals(DBConstants.DB_DIALECT_INGRES))
- {
- return new IngresSQLDBClean(jdbcConn, cleanScripts);
- }
- else if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
- {
- return new OracleDBClean(jdbcConn, cleanScripts);
- }
else
{
- return new DBClean(jdbcConn, cleanScripts);
+ return new DBCleaner(jdbcConn, cleanScripts);
}
}
}
Copied: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleaner.java (from rev 4913, jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java)
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleaner.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleaner.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,245 @@
+/*
+ * 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.clean.rdbms;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
+import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializer;
+import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerHelper;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+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
+{
+ /**
+ * Logger.
+ */
+ protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBClean");
+
+ /**
+ * 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>();
+
+ /**
+ * Rollback scripts for database.
+ */
+ protected final List<String> rollbackScripts = new ArrayList<String>();
+
+ /**
+ * Commit scripts for database.
+ */
+ protected final List<String> commitScripts = new ArrayList<String>();
+
+ /**
+ * DB clean helper.
+ */
+ protected final DBCleanHelper dbCleanHelper;
+
+ /**
+ * DBCleaner constructor.
+ *
+ * @param connection
+ * connection to database where workspace tables is placed
+ * @param cleanScripts
+ * scripts for cleaning database
+ */
+ public DBCleaner(Connection connection, List<String> cleanScripts)
+ {
+ this(connection, cleanScripts, null);
+ }
+
+ /**
+ * DBCleaner constructor.
+ *
+ * @param connection
+ * connection to database where workspace tables is placed
+ * @param cleanScripts
+ * scripts for cleaning database
+ * @param dbCleanHelper
+ * class which help to clean database by executing special queries
+ */
+ 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;
+ }
+
+ /**
+ * DBCleaner constructor.
+ *
+ * @param connection
+ * connection to database where workspace tables is placed
+ * @param cleanScripts
+ * scripts for cleaning database
+ * @param rollbackScripts
+ * scripts for execution when something failed
+ * @param commitScripts
+ * scripts for removing temporary objects
+ * @param dbCleanHelper
+ * class which help to clean database by executing special queries
+ */
+ public DBCleaner(Connection connection, List<String> cleanScripts, List<String> rollbackScripts,
+ List<String> commitScripts, DBCleanHelper cleanHelper)
+ {
+ this(connection, cleanScripts, cleanHelper);
+ this.rollbackScripts.addAll(rollbackScripts);
+ this.commitScripts.addAll(commitScripts);
+ }
+
+ /**
+ * DBCleaner constructor.
+ *
+ * @param connection
+ * connection to database where workspace tables is placed
+ * @param cleanScripts
+ * scripts for cleaning database
+ * @param rollbackScripts
+ * scripts for execution when something failed
+ * @param commitScripts
+ * scripts for removing temporary objects
+ */
+ public DBCleaner(Connection connection, List<String> cleanScripts, List<String> rollbackScripts,
+ List<String> commitScripts)
+ {
+ this(connection, cleanScripts, rollbackScripts, commitScripts, null);
+ }
+
+ /**
+ * Clean data from database. The method doesn't close connection or perform commit.
+ *
+ * @throws SQLException
+ * if any errors occurred
+ */
+ public void executeCleanScripts() throws SQLException
+ {
+ executeScripts(cleanScripts);
+
+ if (dbCleanHelper != null)
+ {
+ dbCleanHelper.executeCleanScripts();
+ }
+ }
+
+ /**
+ * Rollback changes. The method doesn't close connection or perform commit.
+ *
+ * @throws SQLException
+ * if any errors occurred
+ */
+ public void executeRollbackScripts() throws SQLException
+ {
+ executeScripts(rollbackScripts);
+ }
+
+ /**
+ * Cleaning temporary objects. The method doesn't close connection or perform commit.
+ *
+ * @throws SQLException
+ * if any errors occurred
+ */
+ public void executeCommitScripts() throws SQLException
+ {
+ executeScripts(commitScripts);
+ }
+
+ /**
+ * Execute script on database.
+ *
+ * @param scripts
+ * the scripts for execution
+ * @throws SQLException
+ * if any exception occurred
+ */
+ protected void executeScripts(List<String> scripts) throws SQLException
+ {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ {
+ security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
+ }
+
+ Statement st = connection.createStatement();
+ try
+ {
+ for (String scr : scripts)
+ {
+ String sql = DBInitializerHelper.cleanWhitespaces(scr.trim());
+ if (sql.length() > 0)
+ {
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("Execute script: \n[" + sql + "]");
+ }
+ executeQuery(st, sql);
+ }
+ }
+ }
+ finally
+ {
+ try
+ {
+ st.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close the Statement." + e);
+ }
+ }
+ }
+
+ /**
+ * 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;
+ }
+ });
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DummyDBCleaner.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DummyDBCleaner.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DummyDBCleaner.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2003-2011 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.clean.rdbms;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
+ * @version $Id: DummyDBCleaner.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class DummyDBCleaner extends DBCleaner
+{
+
+ /**
+ * DummyDBCleaner constructor.
+ */
+ public DummyDBCleaner(Connection connection, List<String> cleanScripts)
+ {
+ super(connection, cleanScripts);
+ }
+
+ /**
+ * DummyDBCleaner constructor.
+ */
+ public DummyDBCleaner(Connection connection, List<String> cleanScripts, DBCleanHelper dbCleanHelper)
+ {
+ super(connection, cleanScripts, dbCleanHelper);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void executeCleanScripts() throws SQLException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void executeCommitScripts() throws SQLException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void executeRollbackScripts() throws SQLException
+ {
+ }
+}
Deleted: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/IngresSQLDBClean.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/IngresSQLDBClean.java 2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/IngresSQLDBClean.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -1,50 +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.clean.rdbms;
-
-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: IngresSQLDBClean.java 3655 2010-12-10 08:25:41Z tolusha $
- */
-public class IngresSQLDBClean extends DBClean
-{
-
- /**
- * IngresSQLDBClean constructor.
- */
- public IngresSQLDBClean(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());
- }
-}
Deleted: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/OracleDBClean.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/OracleDBClean.java 2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/OracleDBClean.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -1,78 +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.clean.rdbms;
-
-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: OracleDBClean.java 3655 2010-12-10 08:25:41Z tolusha $
- */
-public class OracleDBClean extends DBClean
-{
-
- /**
- * PgSQLDBClean constructor.
- */
- public OracleDBClean(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);
- }
- }
- }
- }
-}
Deleted: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/PgSQLDBClean.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/PgSQLDBClean.java 2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/PgSQLDBClean.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -1,50 +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.clean.rdbms;
-
-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: PgSQLDBClean.java 3655 2010-12-10 08:25:41Z tolusha $
- */
-public class PgSQLDBClean extends DBClean
-{
-
- /**
- * PgSQLDBClean constructor.
- */
- public PgSQLDBClean(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());
- }
-}
Copied: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/RecursiveDBCleanHelper.java (from rev 4913, jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java)
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/RecursiveDBCleanHelper.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/RecursiveDBCleanHelper.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,148 @@
+/*
+ * 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.clean.rdbms;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.impl.Constants;
+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;
+
+/**
+ *
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 21.01.2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: RecursiveDBCleanHelper.java.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class RecursiveDBCleanHelper implements DBCleanHelper
+{
+
+ /**
+ * Logger.
+ */
+ protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.RecursiveDBCleanHelper");
+
+ /**
+ * Select items query.
+ */
+ private final String selectItems;
+
+ /**
+ * Remove items query.
+ */
+ private final String removeItems;
+
+ /**
+ * Connection to database.
+ */
+ protected final Connection connection;
+
+ /**
+ * DBCleanerHelper constructor.
+ */
+ public RecursiveDBCleanHelper(Connection connection, String selectItemds, String removeItems)
+ {
+ this.connection = connection;
+ this.selectItems = selectItemds;
+ this.removeItems = removeItems;
+ }
+
+ /**
+ * Removing rows from table. Some database do not support cascade delete,
+ * or need special sittings. 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 executeCleanScripts() throws SQLException
+ {
+ recursiveClean(Constants.ROOT_PARENT_UUID);
+ }
+
+ private void recursiveClean(String parentID) throws SQLException
+ {
+ PreparedStatement selectStatement = null;
+ PreparedStatement removeStatement = null;
+ ResultSet result = null;
+
+ try
+ {
+ selectStatement = connection.prepareStatement(this.selectItems);
+ selectStatement.setString(1, parentID);
+
+ final PreparedStatement fSelectStatement = selectStatement;
+ result = (ResultSet)SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ return fSelectStatement.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
+ removeStatement = connection.prepareStatement(this.removeItems);
+ removeStatement.setString(1, parentID);
+
+ final PreparedStatement fRemoveStatement = removeStatement;
+ SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ fRemoveStatement.executeUpdate();
+ return null;
+ }
+ });
+ }
+ }
+ finally
+ {
+ if (selectStatement != null)
+ {
+ selectStatement.close();
+ }
+
+ if (removeStatement != null)
+ {
+ removeStatement.close();
+ }
+
+ if (result != null)
+ {
+ result.close();
+ }
+ }
+ }
+}
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-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -32,13 +32,18 @@
import org.exoplatform.services.jcr.impl.backup.Backupable;
import org.exoplatform.services.jcr.impl.backup.ComplexDataRestore;
import org.exoplatform.services.jcr.impl.backup.DataRestore;
+import org.exoplatform.services.jcr.impl.backup.rdbms.DB2DBRestore;
import org.exoplatform.services.jcr.impl.backup.rdbms.DBBackup;
import org.exoplatform.services.jcr.impl.backup.rdbms.DBRestore;
import org.exoplatform.services.jcr.impl.backup.rdbms.DataRestoreContext;
import org.exoplatform.services.jcr.impl.backup.rdbms.DirectoryRestore;
+import org.exoplatform.services.jcr.impl.backup.rdbms.H2DBRestore;
+import org.exoplatform.services.jcr.impl.backup.rdbms.MySQLDBRestore;
+import org.exoplatform.services.jcr.impl.backup.rdbms.OracleDBRestore;
import org.exoplatform.services.jcr.impl.backup.rdbms.RestoreTableRule;
import org.exoplatform.services.jcr.impl.backup.rdbms.SybaseDBRestore;
import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
import org.exoplatform.services.jcr.impl.core.query.NodeDataIndexingIterator;
import org.exoplatform.services.jcr.impl.core.query.Reindexable;
import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectReaderImpl;
@@ -61,6 +66,7 @@
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerException;
+import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerHelper;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
@@ -270,7 +276,7 @@
String pDbDialect = null;
try
{
- pDbDialect = validateDialect(wsConfig.getContainer().getParameterValue(DB_DIALECT));
+ pDbDialect = DBInitializerHelper.validateDialect(wsConfig.getContainer().getParameterValue(DB_DIALECT));
}
catch (RepositoryConfigurationException e)
{
@@ -642,7 +648,7 @@
valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
}
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ora.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
// a particular db initializer may be configured here too
dbInitilizer = new OracleDBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
@@ -650,13 +656,13 @@
else if (dbDialect == DBConstants.DB_DIALECT_ORACLE)
{
this.connFactory = defaultConnectionFactory();
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ora.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
dbInitilizer = new OracleDBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
}
else if (dbDialect == DBConstants.DB_DIALECT_PGSQL)
{
this.connFactory = defaultConnectionFactory();
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.pgsql.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
dbInitilizer = new PgSQLDBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
}
else if (dbDialect == DBConstants.DB_DIALECT_MYSQL)
@@ -675,7 +681,7 @@
valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
}
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mysql.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
dbInitilizer = defaultDBInitializer(sqlPath);
}
else if (dbDialect == DBConstants.DB_DIALECT_MYSQL_UTF8)
@@ -694,43 +700,43 @@
valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
}
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mysql-utf8.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
dbInitilizer = defaultDBInitializer(sqlPath);
}
else if (dbDialect == DBConstants.DB_DIALECT_MSSQL)
{
this.connFactory = defaultConnectionFactory();
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mssql.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
dbInitilizer = defaultDBInitializer(sqlPath);
}
else if (dbDialect == DBConstants.DB_DIALECT_DERBY)
{
this.connFactory = defaultConnectionFactory();
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.derby.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
dbInitilizer = defaultDBInitializer(sqlPath);
}
else if (dbDialect == DBConstants.DB_DIALECT_DB2)
{
this.connFactory = defaultConnectionFactory();
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.db2.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
dbInitilizer = defaultDBInitializer(sqlPath);
}
else if (dbDialect == DBConstants.DB_DIALECT_DB2V8)
{
this.connFactory = defaultConnectionFactory();
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.db2v8.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
dbInitilizer = defaultDBInitializer(sqlPath);
}
else if (dbDialect == DBConstants.DB_DIALECT_SYBASE)
{
this.connFactory = defaultConnectionFactory();
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sybase.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
dbInitilizer = defaultDBInitializer(sqlPath);
}
else if (dbDialect == DBConstants.DB_DIALECT_INGRES)
{
this.connFactory = defaultConnectionFactory();
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ingres.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
// using Postgres initializer
dbInitilizer =
new IngresSQLDBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
@@ -749,14 +755,14 @@
new HSQLDBConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
}
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
dbInitilizer = defaultDBInitializer(sqlPath);
}
else
{
// generic, DB_HSQLDB
this.connFactory = defaultConnectionFactory();
- sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sql";
+ sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
dbInitilizer = defaultDBInitializer(sqlPath);
}
@@ -781,19 +787,6 @@
return connFactory;
}
- protected String validateDialect(String confParam)
- {
- for (String dbType : DBConstants.DB_DIALECTS)
- {
- if (dbType.equalsIgnoreCase(confParam))
- {
- return dbType;
- }
- }
-
- return DBConstants.DB_DIALECT_GENERIC; // by default
- }
-
/**
* {@inheritDoc}
*/
@@ -1294,15 +1287,43 @@
}
tables.put(dstTableName, restoreTableRule);
- if (dbDialect == DBConstants.DB_DIALECT_SYBASE)
+ DBCleaner dbCleaner = null;
+ if (context.getObject(DataRestoreContext.DB_CLEANER) != null)
{
- restorers.add(new SybaseDBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner));
+ dbCleaner = (DBCleaner)context.getObject(DataRestoreContext.DB_CLEANER);
}
else
{
- restorers.add(new DBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner));
+ dbCleaner = DBCleanService.getWorkspaceDBCleaner(jdbcConn, wsConfig);
}
+ if (dbDialect == DBConstants.DB_DIALECT_DB2 || dbDialect == DBConstants.DB_DIALECT_DB2V8)
+ {
+ restorers.add(new DB2DBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner, dbCleaner));
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_MYSQL || dbDialect == DBConstants.DB_DIALECT_MYSQL_UTF8)
+ {
+ restorers.add(new MySQLDBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner, dbCleaner));
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_H2)
+ {
+ restorers.add(new H2DBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner, dbCleaner));
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_SYBASE)
+ {
+ restorers.add(new SybaseDBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner, dbCleaner));
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_ORACLE || dbDialect == DBConstants.DB_DIALECT_ORACLEOCI)
+ {
+ restorers.add(new OracleDBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner, dbCleaner));
+ }
+ else
+ {
+ restorers.add(new DBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner, dbCleaner));
+ }
+
+ // prepare value storage restorer
+ File backupValueStorageDir = new File(storageDir, "values");
if (wsConfig.getContainer().getValueStorages() != null)
{
List<File> dataDirs = new ArrayList<File>();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/init/StorageDBInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/init/StorageDBInitializer.java 2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/init/StorageDBInitializer.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -20,6 +20,7 @@
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializer;
+import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerHelper;
import java.io.IOException;
import java.sql.Connection;
@@ -58,11 +59,7 @@
if (!connection.createStatement().executeQuery(select).next())
{
- String insert =
- "insert into JCR_" + MDB + "ITEM(ID, PARENT_ID, NAME, " + (multiDb ? "" : "CONTAINER_NAME, ")
- + "VERSION, I_CLASS, I_INDEX, N_ORDER_NUM)" + " VALUES('" + Constants.ROOT_PARENT_UUID + "', '"
- + Constants.ROOT_PARENT_UUID + "', '" + Constants.ROOT_PARENT_NAME + "', "
- + (multiDb ? "" : "'" + Constants.ROOT_PARENT_CONAINER_NAME + "', ") + "0, 0, 0, 0)";
+ String insert = DBInitializerHelper.getRootNodeInitializeScript(multiDb);
connection.createStatement().executeUpdate(insert);
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializer.java 2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializer.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -25,8 +25,6 @@
import org.exoplatform.services.log.Log;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.sql.Connection;
@@ -47,10 +45,6 @@
public class DBInitializer
{
- static public String SQL_DELIMITER = ";";
-
- static public String SQL_DELIMITER_COMMENT_PREFIX = "/*$DELIMITER:";
-
static public String SQL_CREATETABLE = "^(CREATE(\\s)+TABLE(\\s)+(IF(\\s)+NOT(\\s)+EXISTS(\\s)+)*){1}";
static public String SQL_CREATEVIEW = "^(CREATE(\\s)+VIEW(\\s)+(IF(\\s)+NOT(\\s)+EXISTS(\\s)+)*){1}";
@@ -109,70 +103,9 @@
protected String script(String scriptPath) throws IOException
{
- return readScriptResource(scriptPath);
+ return DBInitializerHelper.readScriptResource(scriptPath);
}
- protected String readScriptResource(final String path) throws IOException
- {
- PrivilegedAction<InputStream> action = new PrivilegedAction<InputStream>()
- {
- public InputStream run()
- {
- return this.getClass().getResourceAsStream(path);
- }
- };
- final InputStream is = SecurityHelper.doPrivilegedAction(action);
-
- PrivilegedAction<InputStreamReader> actionGetReader = new PrivilegedAction<InputStreamReader>()
- {
- public InputStreamReader run()
- {
- return new InputStreamReader(is);
- }
- };
- InputStreamReader isr = SecurityHelper.doPrivilegedAction(actionGetReader);
-
- try
- {
- StringBuilder sbuff = new StringBuilder();
- char[] buff = new char[is.available()];
- int r = 0;
- while ((r = isr.read(buff)) > 0)
- {
- sbuff.append(buff, 0, r);
- }
-
- return sbuff.toString();
- }
- finally
- {
- try
- {
- is.close();
- }
- catch (IOException e)
- {
- }
- }
- }
-
- public 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;
- }
-
protected boolean isTableExists(final Connection conn, final String tableName) throws SQLException
{
return SecurityHelper.doPrivilegedAction(new PrivilegedAction<Boolean>()
@@ -317,32 +250,7 @@
public void init() throws DBInitializerException
{
- String[] scripts = null;
- if (script.startsWith(SQL_DELIMITER_COMMENT_PREFIX))
- {
- // read custom prefix
- try
- {
- String s = script.substring(SQL_DELIMITER_COMMENT_PREFIX.length());
- int endOfDelimIndex = s.indexOf("*/");
- String delim = s.substring(0, endOfDelimIndex).trim();
- s = s.substring(endOfDelimIndex + 2).trim();
- scripts = s.split(delim);
- }
- catch (IndexOutOfBoundsException e)
- {
- LOG.warn("Error of parse SQL-script file. Invalid DELIMITER configuration. Valid format is '"
- + SQL_DELIMITER_COMMENT_PREFIX + "XXX*/' at begin of the SQL-script file, where XXX - DELIMITER string."
- + " Spaces will be trimed. ", e);
- LOG.info("Using DELIMITER:[" + SQL_DELIMITER + "]");
- scripts = script.split(SQL_DELIMITER);
- }
- }
- else
- {
- scripts = script.split(SQL_DELIMITER);
- }
-
+ String[] scripts = DBInitializerHelper.scripts(script);
String sql = null;
Statement st = null;
Set<String> existingTables = new HashSet<String>();
@@ -355,7 +263,7 @@
connection.setAutoCommit(true);
for (String scr : scripts)
{
- String s = cleanWhitespaces(scr.trim());
+ String s = DBInitializerHelper.cleanWhitespaces(scr.trim());
if (s.length() > 0)
{
if (isObjectExists(connection, sql = s, existingTables))
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializerHelper.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializerHelper.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializerHelper.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2003-2011 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.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.security.PrivilegedAction;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
+ * @version $Id: DBInitializerHelper.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class DBInitializerHelper
+{
+ /**
+ * Logger.
+ */
+ protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBInitializerHelper");
+
+ /**
+ * Default SQL delimiter.
+ */
+ static public String SQL_DELIMITER = ";";
+
+ /**
+ * SQL delimiter comment prefix.
+ */
+ static public String SQL_DELIMITER_COMMENT_PREFIX = "/*$DELIMITER:";
+
+ /**
+ * Getting path to initialization by specific dialect and multidb.
+ *
+ * @param dbDialect
+ * String
+ * @param multiDb
+ * Boolean
+ * @return String
+ * Path to DB initialization script.
+ */
+ public static String scriptPath(String dbDialect, boolean multiDb)
+ {
+ String sqlPath = null;
+ if (dbDialect == DBConstants.DB_DIALECT_ORACLEOCI)
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ora.sql";
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_ORACLE)
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ora.sql";
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_PGSQL)
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.pgsql.sql";
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_MYSQL)
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mysql.sql";
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_MYSQL_UTF8)
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mysql-utf8.sql";
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_MSSQL)
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mssql.sql";
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_DERBY)
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.derby.sql";
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_DB2)
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.db2.sql";
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_DB2V8)
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.db2v8.sql";
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_SYBASE)
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sybase.sql";
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_INGRES)
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ingres.sql";
+ }
+ else if (dbDialect == DBConstants.DB_DIALECT_HSQLDB)
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sql";
+ }
+ else
+ {
+ sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sql";
+ }
+
+ return sqlPath;
+ }
+
+ /**
+ * Validate dialect.
+ *
+ * @param confParam
+ * String, dialect from configuration.
+ * @return String
+ * return dialect. By default return DB_DIALECT_GENERIC.
+ *
+ */
+ public static String validateDialect(String confParam)
+ {
+ for (String dbType : DBConstants.DB_DIALECTS)
+ {
+ if (dbType.equalsIgnoreCase(confParam))
+ {
+ return dbType;
+ }
+ }
+
+ return DBConstants.DB_DIALECT_GENERIC; // by default
+ }
+
+ /**
+ * Read DB initialization script as string.
+ *
+ * @param path
+ * String, path to DB initialization script.
+ * @return String,
+ * DB initialization script as string.
+ * @throws IOException
+ * Will throw IOException if file with DB initialization script is not exists.
+ */
+ public static String readScriptResource(final String path) throws IOException
+ {
+ PrivilegedAction<InputStream> action = new PrivilegedAction<InputStream>()
+ {
+ public InputStream run()
+ {
+ return this.getClass().getResourceAsStream(path);
+ }
+ };
+ final InputStream is = SecurityHelper.doPrivilegedAction(action);
+
+ PrivilegedAction<InputStreamReader> actionGetReader = new PrivilegedAction<InputStreamReader>()
+ {
+ public InputStreamReader run()
+ {
+ return new InputStreamReader(is);
+ }
+ };
+ InputStreamReader isr = SecurityHelper.doPrivilegedAction(actionGetReader);
+
+ try
+ {
+ StringBuilder sbuff = new StringBuilder();
+ char[] buff = new char[is.available()];
+ int r = 0;
+ while ((r = isr.read(buff)) > 0)
+ {
+ sbuff.append(buff, 0, r);
+ }
+
+ return sbuff.toString();
+ }
+ finally
+ {
+ try
+ {
+ is.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+
+ /**
+ * Determinate DB initialization script by separate query.
+ *
+ * @param script
+ * String, DB initialization script as String.
+ * @return String[]
+ * Queries to DB initialization.
+ */
+ public static String[] scripts(String script)
+ {
+ if (script.startsWith(SQL_DELIMITER_COMMENT_PREFIX))
+ {
+ // read custom prefix
+ try
+ {
+ String s = script.substring(SQL_DELIMITER_COMMENT_PREFIX.length());
+ int endOfDelimIndex = s.indexOf("*/");
+ String delim = s.substring(0, endOfDelimIndex).trim();
+ s = s.substring(endOfDelimIndex + 2).trim();
+ return s.split(delim);
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ LOG.warn("Error of parse SQL-script file. Invalid DELIMITER configuration. Valid format is '"
+ + SQL_DELIMITER_COMMENT_PREFIX
+ + "XXX*/' at begin of the SQL-script file, where XXX - DELIMITER string."
+ + " Spaces will be trimed. ", e);
+ LOG.info("Using DELIMITER:[" + SQL_DELIMITER + "]");
+ return script.split(SQL_DELIMITER);
+ }
+ }
+ else
+ {
+ return script.split(SQL_DELIMITER);
+ }
+ }
+
+ /**
+ * Initialization script for root node.
+ *
+ * @param multiDb
+ * indicates if we have multi-db configuration or not
+ * @return SQL script
+ */
+ public static String getRootNodeInitializeScript(boolean multiDb)
+ {
+ return "insert into JCR_" + (multiDb ? "M" : "S") + "ITEM(ID, PARENT_ID, NAME, " + (multiDb ? "" : "CONTAINER_NAME, ")
+ + "VERSION, I_CLASS, I_INDEX, N_ORDER_NUM)" + " VALUES('"
+ + Constants.ROOT_PARENT_UUID + "', '" + Constants.ROOT_PARENT_UUID + "', '" + Constants.ROOT_PARENT_NAME
+ + "', " + (multiDb ? "" : "'" + Constants.ROOT_PARENT_CONAINER_NAME + "', ") + "0, 0, 0, 0)";
+ }
+
+ /**
+ * Cleans redundant whitespaces from query.
+ */
+ public static 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;
+ }
+}
Modified: 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 2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java 2011-10-05 13:36:58 UTC (rev 5024)
@@ -21,6 +21,7 @@
import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
import org.exoplatform.services.jcr.impl.core.NodeImpl;
import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
@@ -219,6 +220,96 @@
service.removeRepository(repositoryName);
}
+ public void testRemoveRepositorySingleDBRepositoryDBCleaner() throws Exception
+ {
+ String repositoryName = "repoTestRemoveSingleRepositoryDBCleaner";
+
+ 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
+ Connection jdbcConn = ds.getConnection();
+ jdbcConn.setAutoCommit(false);
+ DBCleaner repositoryDBCleaner = DBCleanService.getRepositoryDBCleaner(jdbcConn, repositoryEntry);
+
+ repositoryDBCleaner.executeCleanScripts();
+ jdbcConn.commit();
+ repositoryDBCleaner.executeCommitScripts();
+
+ // check - does JCR_SITEM become empty
+ res = statement.executeQuery("select * from JCR_SITEM where ID='" + wsName + id + "'");
+ assertFalse(res.next());
+
+ res = statement.executeQuery("select * from JCR_SITEM");
+ assertTrue(res.next());
+ assertFalse(res.next());
+
+ statement.close();
+
+ service.removeRepository(repositoryName);
+ }
+
+ public void testRemoveRepositorySingleDBRepositoryDBCleanerRollBack() throws Exception
+ {
+ String repositoryName = "repoTestRemoveSingleRepositoryDBCleanerRollBack";
+
+ 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
+ Connection jdbcConn = ds.getConnection();
+ jdbcConn.setAutoCommit(false);
+ DBCleaner repositoryDBCleaner = DBCleanService.getRepositoryDBCleaner(jdbcConn, repositoryEntry);
+
+ repositoryDBCleaner.executeCleanScripts();
+ jdbcConn.rollback();
+ repositoryDBCleaner.executeRollbackScripts();
+
+ // check - does JCR_SITEM become empty
+ res = statement.executeQuery("select * from JCR_SITEM where ID='" + wsName + id + "'");
+ assertTrue(res.next());
+
+ statement.close();
+
+ service.removeRepository(repositoryName);
+ }
+
public void testRemoveWorkspaceMultiDB() throws Exception
{
String repositoryName = "repoTestRemoveMulti";
@@ -317,8 +408,8 @@
repositoryEntry.setDefaultWorkspaceName(repositoryName + "ws");
WorkspaceEntry workspaceEntry =
- helper.getNewWs(repositoryName + "ws", true, DS_NAME, "target/temp/values/" + IdGenerator.generate(),
- wsEntry.getContainer(), false);
+ helper.getNewWs(repositoryName + "ws", true, DS_NAME, "target/temp/values/" + IdGenerator.generate(), wsEntry
+ .getContainer(), false);
repositoryEntry.addWorkspace(workspaceEntry);
@@ -340,8 +431,8 @@
repositoryEntry.setDefaultWorkspaceName(repositoryName + "ws");
WorkspaceEntry workspaceEntry =
- helper.getNewWs(repositoryName + "ws", false, DS_NAME, "target/temp/values/" + IdGenerator.generate(),
- wsEntry.getContainer(), false);
+ helper.getNewWs(repositoryName + "ws", false, DS_NAME, "target/temp/values/" + IdGenerator.generate(), wsEntry
+ .getContainer(), false);
repositoryEntry.addWorkspace(workspaceEntry);
14 years, 7 months
exo-jcr SVN: r5023 - in jcr/branches/1.12.x/patch/1.12.11-GA: JCR-1678 and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-10-05 08:23:45 -0400 (Wed, 05 Oct 2011)
New Revision: 5023
Added:
jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1678/
jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1678/JCR-1678.patch
Log:
JCR-1678: patch proposed
Added: jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1678/JCR-1678.patch
===================================================================
--- jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1678/JCR-1678.patch (rev 0)
+++ jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1678/JCR-1678.patch 2011-10-05 12:23:45 UTC (rev 5023)
@@ -0,0 +1,496 @@
+Index: exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/TestQueryMoveNode.java
+===================================================================
+--- exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/TestQueryMoveNode.java (revision 0)
++++ exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/TestQueryMoveNode.java (revision 0)
+@@ -0,0 +1,85 @@
++/*
++ * Copyright (C) 2003-2011 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.api.core.query;
++
++import org.exoplatform.services.jcr.usecases.BaseUsecasesTest;
++
++import javax.jcr.Node;
++import javax.jcr.NodeIterator;
++import javax.jcr.query.Query;
++import javax.jcr.query.QueryManager;
++import javax.jcr.query.QueryResult;
++
++/**
++ * Created by The eXo Platform SAS.
++ *
++ * <br/>Date:
++ *
++ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
++ * @version $Id: TestQueryMoveNode.java 111 2011-28-01 11:11:11Z serg $
++ */
++public class TestQueryMoveNode extends BaseUsecasesTest
++{
++
++ public void testReordering() throws Exception
++ {
++ Node testRoot = this.root.addNode("testSameNameSiblingDelete");
++
++ Node subNode_1 = testRoot.addNode("node", "nt:unstructured"); // 1
++ subNode_1.addMixin("mix:referenceable");
++ session.save();
++
++ //check the index
++ String sqlQuery;
++ Query query;
++ QueryResult queryResult;
++ NodeIterator iterator;
++ Node node;
++ QueryManager qm = session.getWorkspace().getQueryManager();
++
++ sqlQuery = "SELECT * FROM nt:unstructured WHERE jcr:path = '/testSameNameSiblingDelete/node[1]'";
++ query = qm.createQuery(sqlQuery, Query.SQL);
++ queryResult = query.execute();
++ iterator = queryResult.getNodes();
++ assertTrue("Node expected ", iterator.getSize() == 1);
++ node = iterator.nextNode();
++ assertEquals("Wrong id ", subNode_1.getUUID(), node.getUUID());
++ assertEquals("Wrong path ", subNode_1.getPath(), node.getPath());
++
++ // move
++ testRoot.addNode("folder");
++ session.save();
++ session.move("/testSameNameSiblingDelete/node", "/testSameNameSiblingDelete/folder/node");
++ session.save();
++
++ sqlQuery = "SELECT * FROM nt:unstructured WHERE jcr:path = '/testSameNameSiblingDelete/node[1]'";
++ query = qm.createQuery(sqlQuery, Query.SQL);
++ queryResult = query.execute();
++ iterator = queryResult.getNodes();
++ assertTrue("There must be no node ", iterator.getSize() == 0);
++
++ sqlQuery = "SELECT * FROM nt:unstructured WHERE jcr:path = '/testSameNameSiblingDelete/folder/node[1]'";
++ query = qm.createQuery(sqlQuery, Query.SQL);
++ queryResult = query.execute();
++ iterator = queryResult.getNodes();
++ assertTrue("Node expected ", iterator.getSize() == 1);
++ node = iterator.nextNode();
++ assertEquals("Wrong id ", subNode_1.getUUID(), node.getUUID());
++ assertEquals("Wrong path ", subNode_1.getPath(), node.getPath());
++ }
++
++}
+Index: exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/usecases/query/TestQueryChilds.java
+===================================================================
+--- exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/usecases/query/TestQueryChilds.java (revision 0)
++++ exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/usecases/query/TestQueryChilds.java (revision 0)
+@@ -0,0 +1,124 @@
++/*
++ * 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.jcr.usecases.query;
++
++import org.exoplatform.services.jcr.impl.core.ItemImpl;
++import org.exoplatform.services.jcr.usecases.BaseUsecasesTest;
++
++import java.util.ArrayList;
++import java.util.Iterator;
++import java.util.List;
++
++import javax.jcr.Node;
++import javax.jcr.NodeIterator;
++import javax.jcr.RepositoryException;
++import javax.jcr.query.Query;
++import javax.jcr.query.QueryManager;
++import javax.jcr.query.QueryResult;
++
++/**
++ * @author <a href="mailto:skarpenko@exoplatform.com">Sergiy Karpenko</a>
++ * @version $Id: exo-jboss-codetemplates.xml 34360 16 ????. 2011 skarpenko $
++ *
++ */
++public class TestQueryChilds extends BaseUsecasesTest
++{
++ public void testGetChilds() throws Exception
++ {
++ Node testRoot = this.root.addNode("testSameNameSiblingDelete");
++
++ Node subNode_1 = testRoot.addNode("node", "nt:unstructured"); // 1
++ Node subNode_1_1 = subNode_1.addNode("node1", "nt:unstructured");
++ Node subNode_1_2 = subNode_1.addNode("node2", "nt:unstructured");
++ Node subNode_1_1_1 = subNode_1_1.addNode("node11", "nt:unstructured");
++ //Node subNode_1_1_2 = subNode_1_1.addNode("node12", "nt:unstructured");
++ Node subNode_2 = testRoot.addNode("node", "nt:unstructured"); // 2
++ Node subNode_2_1 = subNode_2.addNode("node3", "nt:unstructured");
++ Node subNode_2_2 = subNode_2.addNode("node4", "nt:unstructured");
++
++ session.save();
++
++ //check the index
++ String sqlQuery;
++ Query query;
++ QueryResult queryResult;
++ NodeIterator iterator;
++ Node node;
++ QueryManager qm = session.getWorkspace().getQueryManager();
++
++ sqlQuery = "SELECT * FROM nt:unstructured WHERE jcr:path LIKE '/testSameNameSiblingDelete/node/%'";
++ query = qm.createQuery(sqlQuery, Query.SQL);
++ queryResult = query.execute();
++ iterator = queryResult.getNodes();
++ assertTrue("Node expected ", iterator.getSize() == 3);
++ // node = iterator.nextNode();
++ // assertEquals("Wrong id ", subNode_1.getUUID(), node.getUUID());
++ // assertEquals("Wrong path ", subNode_1.getPath(), node.getPath());
++ testNames(iterator, new String[]{"node1", "node2", "node11"}); //, "node3", "node4"
++
++ // // move
++ // testRoot.addNode("folder");
++ // session.save();
++ // session.move("/testSameNameSiblingDelete/node", "/testSameNameSiblingDelete/folder/node");
++ // session.save();
++ //
++ // sqlQuery = "SELECT * FROM nt:unstructured WHERE jcr:path = '/testSameNameSiblingDelete/node[1]'";
++ // query = qm.createQuery(sqlQuery, Query.SQL);
++ // queryResult = query.execute();
++ // iterator = queryResult.getNodes();
++ // assertTrue("There must be no node ", iterator.getSize() == 0);
++ //
++ // sqlQuery = "SELECT * FROM nt:unstructured WHERE jcr:path = '/testSameNameSiblingDelete/folder/node[1]'";
++ // query = qm.createQuery(sqlQuery, Query.SQL);
++ // queryResult = query.execute();
++ // iterator = queryResult.getNodes();
++ // assertTrue("Node expected ", iterator.getSize() == 1);
++ // node = iterator.nextNode();
++ // assertEquals("Wrong id ", subNode_1.getUUID(), node.getUUID());
++ // assertEquals("Wrong path ", subNode_1.getPath(), node.getPath());
++ }
++
++ protected void testNames(Iterator iterator, String[] expectedNames) throws RepositoryException
++ {
++
++ List<String> names = new ArrayList<String>();
++ while (iterator.hasNext())
++ {
++ ItemImpl item = (ItemImpl)iterator.next();
++ names.add(item.getName());
++ }
++
++ //compare names
++ assertEquals(expectedNames.length, names.size());
++
++ for (String expectedName : expectedNames)
++ {
++ boolean finded = false;
++ for (String name : names)
++ {
++ if (expectedName.equals(name))
++ {
++ finded = true;
++ break;
++ }
++ }
++ assertTrue(finded);
++ }
++ }
++}
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/FieldNames.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/FieldNames.java (revision 5022)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/FieldNames.java (working copy)
+@@ -64,6 +64,16 @@
+ public static final String LOCAL_NAME = "_:LOCAL_NAME".intern();
+
+ /**
++ * Name of the field that contains the index of the item.
++ */
++ public static final String INDEX = "_:INDEX".intern();
++
++ /**
++ * Name of the field that contains the relative path of the item.
++ */
++ public static final String PATH = "_:PATH".intern();
++
++ /**
+ * Name of the field that contains the namespace URI of the node name. Terms
+ * are not tokenized.
+ */
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/FieldSelectors.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/FieldSelectors.java (revision 5022)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/FieldSelectors.java (working copy)
+@@ -63,4 +63,41 @@
+ }
+ }
+ };
++
++ public static final FieldSelector UUID_AND_PARENT_AND_INDEX = new FieldSelector() {
++ /**
++ * Accepts {@link FieldNames#UUID}, {@link FieldNames#PARENT}
++ * and {@link FieldNames#INDEX}.
++ *
++ * @param fieldName the field name to check.
++ * @return result.
++ */
++ public FieldSelectorResult accept(String fieldName) {
++ if (FieldNames.UUID == fieldName) {
++ return FieldSelectorResult.LOAD;
++ } else if (FieldNames.PARENT == fieldName) {
++ return FieldSelectorResult.LOAD;
++ } else if (FieldNames.INDEX == fieldName) {
++ return FieldSelectorResult.LOAD;
++ } else {
++ return FieldSelectorResult.NO_LOAD;
++ }
++ }
++ };
++
++ public static final FieldSelector PATH = new FieldSelector() {
++ /**
++ * Accepts {@link FieldNames#PATH}.
++ *
++ * @param fieldName the field name to check.
++ * @return result.
++ */
++ public FieldSelectorResult accept(String fieldName) {
++ if (FieldNames.PATH == fieldName) {
++ return FieldSelectorResult.LOAD;
++ } else {
++ return FieldSelectorResult.NO_LOAD;
++ }
++ }
++ };
+ }
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexFormatVersion.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexFormatVersion.java (revision 5022)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexFormatVersion.java (working copy)
+@@ -16,10 +16,10 @@
+ */
+ package org.exoplatform.services.jcr.impl.core.query.lucene;
+
++import org.apache.lucene.index.IndexReader;
++
+ import java.util.Collection;
+
+-import org.apache.lucene.index.IndexReader;
+-
+ /**
+ * This class indicates the lucene index format that is used.
+ * <ul>
+@@ -52,11 +52,16 @@
+ public static final IndexFormatVersion V2 = new IndexFormatVersion(2);
+
+ /**
+- * V3 is the index format for Jackrabbit releases >= 1.5
++ * V3 is the index format for Jackrabbit releases 1.5.x
+ */
+ public static final IndexFormatVersion V3 = new IndexFormatVersion(3);
+
+ /**
++ * V4 is the index format for Jackrabbit releases >= 1.6
++ */
++ public static final IndexFormatVersion V4 = new IndexFormatVersion(4);
++
++ /**
+ * The used version of the index format
+ */
+ private final int version;
+@@ -104,7 +109,9 @@
+ public static IndexFormatVersion getVersion(IndexReader indexReader) {
+ Collection fields = indexReader.getFieldNames(
+ IndexReader.FieldOption.ALL);
+- if (fields.contains(FieldNames.LOCAL_NAME) || indexReader.numDocs() == 0) {
++ if ((fields.contains(FieldNames.INDEX) && fields.contains(FieldNames.PATH))|| indexReader.numDocs() == 0) {
++ return IndexFormatVersion.V4;
++ } else if (fields.contains(FieldNames.LOCAL_NAME)) {
+ return IndexFormatVersion.V3;
+ } else if (fields.contains(FieldNames.PROPERTIES_SET)) {
+ return IndexFormatVersion.V2;
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChildAxisQuery.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChildAxisQuery.java (revision 5022)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChildAxisQuery.java (working copy)
+@@ -519,15 +519,14 @@
+ {
+ if (position != LocationStepQueryNode.NONE)
+ {
+- Document node = reader.document(i, FieldSelectors.UUID_AND_PARENT);
++ Document node = reader.document(i, FieldSelectors.UUID_AND_PARENT_AND_INDEX);
+ String parentId = node.get(FieldNames.PARENT);
+ String id = node.get(FieldNames.UUID);
+ try
+ {
+- //NodeState state = (NodeState) itemMgr.getItemState(parentId);
+- NodeData state = (NodeData)itemMgr.getItemData(parentId);
+ if (nameTest == null)
+ {
++ NodeData state = (NodeData)itemMgr.getItemData(parentId);
+ // only select this node if it is the child at
+ // specified position
+ if (position == LocationStepQueryNode.LAST)
+@@ -555,6 +554,7 @@
+ // specified position
+ if (position == LocationStepQueryNode.LAST)
+ {
++ NodeData state = (NodeData)itemMgr.getItemData(parentId);
+ // only select last
+
+ if (state == null)
+@@ -572,6 +572,11 @@
+ }
+ }
+ }
++ else if (version.getVersion() >= IndexFormatVersion.V4.getVersion())
++ {
++ if (Integer.valueOf(node.get(FieldNames.INDEX)) != position)
++ return false;
++ }
+ else
+ {
+ NodeData nodeData = (NodeData)itemMgr.getItemData(id);
+@@ -693,49 +698,70 @@
+ //NodeId id = new NodeId(UUID.fromString(uuid));
+ try
+ {
+- long time = System.currentTimeMillis();
+- NodeData state = (NodeData)itemMgr.getItemData(uuid);
+- time = System.currentTimeMillis() - time;
+- log.debug("got NodeState with id {} in {} ms.", uuid, new Long(time));
+- Iterator<NodeData> entries;
+- if (nameTest != null)
++ if (nameTest != null && version.getVersion() >= IndexFormatVersion.V4.getVersion())
+ {
+- //NodeData childNodeData = (NodeData)itemMgr.getItemData(state, new QPathEntry(nameTest, 1));//state.getChildNodeEntries(nameTest).iterator();
+- List<NodeData> childs = itemMgr.getChildNodesData(state);
+-
+- List<NodeData> datas = new ArrayList<NodeData>();
+- if (childs != null)
++ StringBuilder path = new StringBuilder(256);
++ path.append(uuid == null ? "" : uuid).append('/').append(nameTest.getAsString());
++ TermDocs docs = reader.termDocs(new Term(FieldNames.PATH, path.toString()));
++ try
+ {
+- for (NodeData nodeData : childs)
++ while (docs.next())
+ {
+- if (nameTest.equals(nodeData.getQPath().getName()))
+- datas.add(nodeData);
++ childrenHits.set(docs.doc());
+ }
+-
+ }
+- entries = datas.iterator();//itemMgr.getChildNodesData(childNodeData).iterator();
++ finally
++ {
++ docs.close();
++ }
+ }
+ else
+ {
+- // get all children
+- entries = itemMgr.getChildNodesData(state).iterator();
+- }
+- while (entries.hasNext())
+- {
+- String childId = entries.next().getIdentifier();
+- Term uuidTerm = new Term(FieldNames.UUID, childId);
+- TermDocs docs = reader.termDocs(uuidTerm);
+- try
++ long time = System.currentTimeMillis();
++ NodeData state = (NodeData)itemMgr.getItemData(uuid);
++ time = System.currentTimeMillis() - time;
++ log.debug("got NodeState with id {} in {} ms.", uuid, new Long(time));
++ Iterator<NodeData> entries;
++ if (nameTest != null)
+ {
+- if (docs.next())
++ List<NodeData> childs = itemMgr.getChildNodesData(state);
++
++ List<NodeData> datas = new ArrayList<NodeData>();
++ if (childs != null)
+ {
+- childrenHits.set(docs.doc());
++ for (NodeData nodeData : childs)
++ {
++ if (nameTest.equals(nodeData.getQPath().getName()))
++ {
++ datas.add(nodeData);
++ }
++ }
+ }
++ entries = datas.iterator();
+ }
+- finally
++ else
+ {
+- docs.close();
++ // get all children
++ entries = itemMgr.getChildNodesData(state).iterator();
+ }
++ while (entries.hasNext())
++ {
++ String childId = entries.next().getIdentifier();
++ Term uuidTerm = new Term(FieldNames.UUID, childId);
++ TermDocs docs = reader.termDocs(uuidTerm);
++ try
++ {
++ if (docs.next())
++ {
++ childrenHits.set(docs.doc());
++ }
++ }
++ finally
++
++ {
++ docs.close();
++ }
++ }
+ }
+ }
+ catch (RepositoryException e)
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NodeIndexer.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NodeIndexer.java (revision 5022)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NodeIndexer.java (working copy)
+@@ -215,6 +215,17 @@
+ // unknown uri<->prefix mappings
+ }
+
++ if (indexFormatVersion.getVersion() >= IndexFormatVersion.V4.getVersion())
++ {
++ doc.add(new Field(FieldNames.INDEX, Integer.toString(node.getQPath().getIndex()), Field.Store.YES,
++ Field.Index.NOT_ANALYZED_NO_NORMS));
++
++ StringBuilder path = new StringBuilder(256);
++ path.append(node.getParentIdentifier() == null ? "" : node.getParentIdentifier()).append('/')
++ .append(node.getQPath().getName().getAsString());
++ doc.add(new Field(FieldNames.PATH, path.toString(), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS));
++ }
++
+ for (PropertyData prop : stateProvider.listChildPropertiesData(node))
+ {
+
14 years, 7 months
exo-jcr SVN: r5022 - jcr/tags/1.12.10-GA.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-10-05 04:00:39 -0400 (Wed, 05 Oct 2011)
New Revision: 5022
Added:
jcr/tags/1.12.10-GA/readme.txt
Log:
JCR-1679: add release notes
Added: jcr/tags/1.12.10-GA/readme.txt
===================================================================
--- jcr/tags/1.12.10-GA/readme.txt (rev 0)
+++ jcr/tags/1.12.10-GA/readme.txt 2011-10-05 08:00:39 UTC (rev 5022)
@@ -0,0 +1,587 @@
+JCR 1.12.10-GA release notes
+===========================
+
+eXoPlatform Java Content Repository (JSR-170) implementation and Extension services with clustering support.
+
+Changes of 1.12.10-GA
+=====================
+
+Bug
+ * [JCR-1630] - Impossible to move files in Webdav when the destination path contains space (Windows)
+ * [JCR-1639] - Delay in replication of Nodes data in JBoss EPP Cluster
+ * [JCR-1643] - Fetching exo:symlinks node in JCR repostiory in clustering environment.
+ * [JCR-1650] - Lists stored into the cache can be inconsistent in cluster environment
+ * [JCR-1652] - Empty multi-values properties should processed properly
+
+Feedback
+ * [JCR-1653] - Performance issue with Oracle DB 11.2.0.2
+
+Improvement
+ * [JCR-1654] - Performance issues met due to SecureRandom.nextBytes under heavy load
+ * [COR-34] - Improve performance of ldap organization service
+ * [KER-175] - [Backport]Find a way to have a name for MBeans of JBossCaches used by the JCR
+
+Task
+ * [JCR-1633] - [Backport]Allow to keep missing values into the JCR Cache
+ * [JCR-1634] - [Backport]Find a way to have a name for MBeans of JBossCaches used by the JCR
+ * [JCR-1636] - [Backport]Allow to create sessions from ACLs
+ * [JCR-1656] - Remove all the explicit GC calls
+ * [WS-269] - Remove all the explicit GC calls
+
+Sub-task
+ * [COR-238] - Validate and apply patch
+ * [COR-239] - Implementation CacheHandler
+ * [COR-240] - Testing LDAPOrganizationService with cache support
+
+
+Changes of 1.12.9-GA
+=====================
+
+Bug
+ * [JCR-1501] - Problems with dispalying non-latin names (ar,fr,ua,ru,vn) after restore in backup
+ * [JCR-1545] - Can't open a document with a name containing non-latin characters (ru,ua,fr,vn,ar)
+ * [JCR-1577] - Check in DefaultChangesFilter if we use the right ids in case of a IOException while updating the index of the parentSearchManager
+ * [JCR-1593] - Incorrect parsing destination header in MOVE and COPY webdav methods
+ * [JCR-1594] - Problem of renaming folders in WebDav
+ * [JCR-1597] - Problem of webdav on windows 7
+ * [JCR-1602] - File with non-latin name can't be open: Can't open remote file.ErrorCode:500
+ * [JCR-1604] - JCR addNode within a transaction causes javax.transaction.HeuristicMixedException in the first access to the node
+ * [JCR-1605] - Can't access file containing special characters in file name via Webdav
+ * [JCR-1614] - system view exporting has a problem when the exported node contains the properties that are multiple value type but have only one value.
+ * [JCR-1615] - Still check lock on parent while isDeep = false
+ * [JCR-1616] - Error when get node definition for node
+ * [JCR-1618] - javax.jcr.InvalidItemStateException: Node can't be saved No same-name sibling exists with index 2
+ * [JCR-1622] - Thread not stopped when the application is stopped
+ * [JCR-1629] - No eviction policy is allowed in case of the cache for indexing
+ * [JCR-1631] - Violation de contrainte unique (SYSTEM.JCR_IDX_SITEM_PARENT) error during concurrent ADD NODE transaction
+ * [COR-236] - Case sensitivityProblem with Oracle Virtual Directory and SQL Server
+ * [WS-265] - Stop the StandaloneContainer on context destroyed
+
+Improvement
+ * [JCR-1543] - Dialog window "About" has incorrect version of jcr in webdav ms office plugin
+ * [JCR-1571] - Query with path is too slow in case the db is big
+ * [JCR-1572] - Improve the re-indexing mechanism to take advantage of multi-cores
+ * [JCR-1579] - Query with path is too slow when we have a node with a lot of subnodes
+ * [COR-216] - User profiles initialization listeners are not triggered for LDAP users (LDAP Users can not access to any File Explorer drive)
+ * [COR-235] - Return only exptected attributes in SimpleLdapUserListAccess
+
+Task
+ * [JCR-1563] - Use QueryParam to parameter "backup-set-path" in methods of HTTPBackupAgent
+ * [JCR-1586] - Configure time-outs for tests
+ * [JCR-1611] - Backporting EXOJCR-1234 to JCR 1.12.x
+ * [JCR-1613] - Backporting EXOJCR-1305 to JCR 1.12.x
+ * [JCR-1632] - Cleanup build
+ * [COR-228] - Make PdfDocumentReader.getProperties() using PdfBox instead iText
+ * [WS-266] - Do not generate files in src directory of a project
+
+Changes of 1.12.8-GA
+=====================
+Bug
+ * [JCR-1560] - BackupManager restore : Temporary files not deleted
+ * [JCR-1562] - Check problem with compatibility of incremental backup for JCR 1.12.x to JCR 1.14.x.
+ * [JCR-1581] - NFS stale handle
+ * [JCR-1584] - ConstraintViolationException when Importing Version history of a nt:folder node having a nt:file child node
+
+Documentation
+ * [JCR-1561] - Document Repository or Workspace initialization from backup [apply patch]
+ * [JCR-1580] - Fix webdav docbook section since webdav bug with Mac OS Finder is fixed
+ * [JCR-1582] - Improve JCR Doc
+
+Improvement
+ * [JCR-1496] - remove some unncessary jars
+ * [JCR-1538] - Webdav: files icons is the same as folder icons
+ * [JCR-1573] - Reduce the time spent in ParentNodeEvictionActionPolicy
+ * [KER-168] - MimeTypeResolver does not work well with IE7
+
+Task
+ * [JCR-1578] - Check in IndexerSingletonStoreCacheLoader if the children should not be removed
+ * [JCR-1583] - Upgrade to exo-parent 8.1
+
+
+Changes of 1.12.7-GA
+=====================
+
+Bug
+ * [JCR-1483] - When a folder is cut server->client, folder on server doesn't remove.
+ * [JCR-1508] - Property not found dc:title during testing RandomReadNtFileWithMetadataTest
+ * [JCR-1529] - Node restore result depends on cache eviction
+ * [JCR-1541] - SessionDataManager.listChildPropertiesData(NodeData parent) must not return ValueDatas
+ * [JCR-1542] - XML elements are incorrectly parsed while using Woodstox XML processor
+ * [JCR-1544] - Exception error during edit content
+ * [JCR-1549] - Problems in JCR content after being imported
+ * [JCR-1552] - Corrupted data if the server is stopped while document is locked
+ * [JCR-1556] - The If-Modified-Since property in the HTTP header doesn't exist
+ * [JCR-1557] - If Groovy REST service deploy fails on JCR startup other workable services may not be deployed
+ * [JCR-1558] - FileCleaner is null in SysViewWorkspaceInitializer and BackupWorkapceInitializer
+ * [JCR-1564] - FORM authentication doesn't work with jcrbackup tool and Platform
+ * [JCR-1565] - Repository restore fails using exobackup tool with Component unregister error
+ * [JCR-1566] - Restored version nodes get id from jcr:uuid property instead fetch generated id
+ * [JCR-1574] - IncrementalBackupJob should be thread safe
+ * [WS-261] - Platform Packaging fails due to mistake in WS packaging JS file
+
+Documentation
+ * [JCR-1559] - Document databases supported by eXo JCR
+
+Improvement
+ * [JCR-1054] - Make Backup restore easier
+ * [JCR-1499] - Backup console binary distribution
+ * [JCR-1547] - Avoid to get an item from the DB if the parent node is new
+ * [JCR-1550] - Changes log traversing is under optimized
+ * [JCR-1567] - Code review of ACL managment in case of copy/moving nodes
+ * [JCR-1570] - DB clean on MySQL should not use iterating over all db
+ * [COR-217] - remove some unncessary jars
+ * [COR-218] - Support more MIME types
+ * [WS-258] - remove some unncessary jars
+
+Task
+ * [JCR-1463] - Lock operations does not checks any permission.
+ * [JCR-1502] - JCR backupset should be fully independent
+ * [JCR-1519] - Update XPath query ordering chapter in jcr documents
+ * [JCR-1568] - Check portability and compatibility backup in JCR 1.14.x and 1.12.x
+
+
+Changes of 1.12.6-GA
+=====================
+
+Bug
+ * [JCR-1497] - Backup console throws NPE if backup agent isn't deployed on server
+ * [JCR-1522] - Not correct MBean components registration when PortalContainer contains more then one repository
+ * [JCR-1527] - Create Group personnal folder should be after Group creation
+ * [JCR-1530] - Wrong Content-Type header for files over a certain size
+ * [JCR-1532] - MySQL-UTF8 dialect default collation can be case-insensitive - need case-sensitive set explicitly
+ * [JCR-1533] - Remove permission on child isn't used
+ * [JCR-1534] - Problem with uploading files via MacOS client
+ * [JCR-1539] - Webdav doesn't work on JBoss
+
+Improvement
+ * [JCR-1506] - Reduce contention on read in NodeTypeDataHierarchyHolder if possible
+ * [JCR-1523] - Avoid iterating over a List thanks to its iterator when it is possible [Part #2]
+
+Task
+ * [JCR-1521] - Adopt webdav-clients to eXo JCR 1.12.6-GA
+ * [JCR-1524] - Move JCR framework commands list configuration to it right place
+ * [JCR-1525] - Publish the reference guide in docbook format
+
+
+Changes of 1.12.6-CR02
+=====================
+
+Bug
+ * [JCR-1468] - Index already present error during cluster start
+ * [JCR-1504] - Indexer doesn't fully release resources on stop
+ * [JCR-1509] - Access Denied in jcr:content with anonim__ permission
+ * [JCR-1511] - WEBDav view in a webbrowser has hardcoded image links
+ * [JCR-1513] - Problems when start backup-console
+
+Improvement
+ * [JCR-1505] - Avoid iterating over a List thanks to its iterator when it is possible
+
+Task
+ * [JCR-1488] - Limit the total amount of WorkerThreads: apply patch
+
+Changes of 1.12.6-CR01
+=====================
+
+Bug
+ * [JCR-1470] - refresh breaks webdav published files
+ * [JCR-1482] - Corrupted Data if the server is stopped while somebobdy is editing a document in ECMS
+ * [JCR-1485] - Unknown error and strange behavior when mary edits a webcontent
+ * [JCR-1490] - Some Unit Tests on DB2 related to the CAS plugin fail
+ * [JCR-1494] - FTP server doesn't show list of workspaces after repository restoring
+
+Documentation
+ * [JCR-1433] - jcr backup/restore
+
+Improvement
+ * [KER-164] - Allow to use variables to define the realm, the rest context and the portal container name of a PortalContainerDefinition
+ * [WS-256] - Allow to use a String as entity for a JSON response
+ * [JCR-1459] - Whole Repository backup support in Backup Console tool
+ * [JCR-1469] - JCR clustering consumes lot of native threads
+ * [JCR-1491] - The result of the method getReferencesData is never stored into the cache
+
+Task
+ * [JCR-1489] - eXo JCR doesn't work with Oracle 11g R2 RAC
+ * [JCR-1495] - Bind slf4j-log4j and log4j dependencies onto the test phase of the various modules of JCR [part #2]
+
+Sub-task
+ * [JCR-1481] - Adding support form authentication in backup console
+
+Changes of 1.12.5-GA
+=====================
+
+Bug
+ * [KER-162] - Simple skin from examples folder doesn't appear at list
+ * [KER-163] - CachingContainer returns unregistered components
+ * [COR-213] - User logged-out and cannot login after some inactivity
+ * [WS-254] - Add org.exoplatform.services.rest.ext.method.filter.MethodAccessFilter in container configuration by default
+ * [JCR-1438] - Problem with JCR versionning
+ * [JCR-1449] - Can't get property of a node if it has a child node with the same name with the property
+ * [JCR-1450] - JCROrganizationService contains nodetype with same name as in CS
+ * [JCR-1453] - Missed nodetypes in cluster testing configuration
+ * [JCR-1462] - Problems during testing of backup on jcr 1.12.5-GA-SNAPSHOT
+ * [JCR-1466] - RepositoryException: URI is not hierarchical on remove workspace via backup console
+ * [JCR-1474] - NPE when try to import data via WorkspaceContentImporter
+
+Improvement
+ * [KER-160] - Prevent the JobSchedulerServiceImpl to launch jobs that rely on non started services in JBoss AS
+ * [KER-161] - Make the JobSchedulerServiceImpl support multi portal containers
+
+Task
+ * [JCR-1455] - Doc's title should be rename from eXoJCR Reference Manual to eXo JCR Developer Guide
+ * [JCR-1461] - Remove timestamp from names of jar-files in application bundles
+ * [JCR-1467] - Cannot use webdav service with a version of jcr:content
+ * [JCR-1471] - Updating eXo JCR version in ra.xml automatically
+ * [JCR-1472] - Adopt Backup client article
+ * [JCR-1473] - merge performance improvements
+
+Changes of 1.12.4-GA
+=====================
+
+Bug
+ * [EXOJCR-688] - Some entries in the eXo JCR cache are not evicted properly
+ * [EXOJCR-843] - Exceptions after importing file with version history
+ * [EXOJCR-849] - "Permission denied" on client side, when trying to move file(s) to another workspace through FTP
+ * [EXOJCR-856] - Problems while recopying same files via webdav
+ * [EXOJCR-865] - Data corrupt after restore a node which has been imported with version history
+ * [EXOJCR-878] - WebDAV doesn't work with nt:file
+ * [EXOJCR-879] - TestCaching.testNotModifiedSince failed in same cases
+ * [EXOJCR-888] - The problems with restore version node
+ * [EXOJCR-890] - JSON framework don't work with beans created in groovy
+ * [EXOJCR-891] - Snaphosts IDs make the applications build improperly
+ * [EXOJCR-908] - Used wrong delimiter during parsing permission value
+ * [EXOJCR-909] - In LDAPService, InitialContext is not safely closed in authenticate method
+ * [EXOJCR-912] - Unable to convert the JCR documentation to pdf
+ * [EXOJCR-916] - Duplicate instantiation of some services
+ * [EXOJCR-921] - Workspace.copy(srcWS, srcAbsPath, destAbsPath) can not copy root child to another workspace root child
+ * [EXOJCR-924] - Unable to coerce 'Event' into a LONG: java.lang.NumberFormatException: For input string: "Event"
+ * [EXOJCR-933] - Determine property type from nodetype definition in DocumentViewImport for version history.
+ * [EXOJCR-936] - Avoid converting binary value to String in tests
+
+Feature Request
+ * [EXOJCR-842] - Allow to disable a given PortalContainer
+ * [EXOJCR-880] - Determine property is multi or single value from nodetype definition in import.
+ * [EXOJCR-886] - Update the document handler to manage MS Office 2007 meta data extraction (docx, ...)
+ * [EXOJCR-934] - Decouple event name from listener name in ListenerService.
+ * [EXOJCR-935] - Add "dav:isreadonly" property management
+
+Task
+ * [EXOJCR-896] - Port Manageability article into docbook
+ * [EXOJCR-905] - Merge the reference guide and the user guide in one single guide
+ * [EXOJCR-913] - Abuse of INFO level logging for DocNumberCache.get()
+ * [EXOJCR-914] - excessive INFO logging by IndexMerger.run()
+ * [EXOJCR-915] - excessive INFO logging by IndexMerger.run()
+ * [EXOJCR-917] - core.packaging.module.js error when in deploy phase
+ * [EXOJCR-919] - maxVolatileTime should be checked on checkFlush()
+ * [EXOJCR-927] - Add "application/x-groovy+html" to HTMLDocumentReader and "application/x-jaxrs+groovy" to TextPlainDocumentReader
+ * [EXOJCR-892] - Remove Fake Chapters
+
+Changes of 1.12.3-GA
+=====================
+
+Bug
+ * [EXOJCR-754] - JDBC Statements left open : Use of Datasources instead of DBCP and C3P0 pools
+ * [EXOJCR-763] - Reordering samename sibling nodes does not update path of child nodes
+ * [EXOJCR-766] - QPath isDescendantOf returns wrong result on samename siblings
+ * [EXOJCR-774] - If-Modified-Since doesn't seem to be well managed in the Wevdav
+ * [EXOJCR-781] - LockManagerImpl should call InitialContextInitializer.recall
+ * [EXOJCR-784] - DOC : wrong examples in profiles section
+ * [EXOJCR-785] - Parameter maxVolatileTime is not working correctly
+ * [EXOJCR-788] - Inconsistency issue cans occur on default portal container parameters
+ * [EXOJCR-795] - Unexpected behavior of the method PortalContainer.isScopeValid()
+ * [EXOJCR-796] - Data corruption
+ * [EXOJCR-804] - "No such file or directory" exception for value storage when using MySQL or Postgres DB in WCM demo 2.0
+ * [EXOJCR-806] - Problems while copying "ftp-ftp"
+ * [EXOJCR-810] - TestRemoveFromValueStorage failed in configuration without ValueStorage
+ * [EXOJCR-813] - ItemImpl.getParent method must return session pooled parent
+ * [EXOJCR-817] - max-buffer-size from configuration should be use to TransientValueData in import (docview and sysview)
+ * [EXOJCR-835] - TestMultiDbJDBCConnection and TestSingleDbJDBCConnection must drop also JCR_xCONTAINER table on tearDown
+ * [EXOJCR-857] - Exception during PROPFIND request if some property content "%" and after not hex chracters
+ * [EXOJCR-865] - Data corrupt after restore a node which has been imported with version history
+ * [EXOJCR-882] - TestCaching fails on Windows XP SP 2 with Russian locale
+
+Feature Request
+ * [EXOJCR-230] - Refactore and move in main part of exo.ws.rest.core project class AbstractResourceTest
+ * [EXOJCR-782] - No longer force extension developers to redefine the whole dependencies list
+ * [EXOJCR-783] - Use cached table for HSLQLDB tables
+ * [EXOJCR-797] - Unable see error message from ProxyService if remote server does not provide Content-Type header.
+
+Task
+ * [EXOJCR-392] - Siblings reordering may update not all the child-items in cache
+ * [EXOJCR-751] - Prepare maintenance branch for jcr 1.12
+ * [EXOJCR-808] - For Sybase DB "check-sns-new-connection" should be set to false by default
+ * [EXOJCR-809] - OrganizationService's tests should not be excluded
+ * [EXOJCR-815] - Document how to use AS Managed DataSource
+ * [EXOJCR-867] - Port documentation for Kernel from wiki to docbook
+ * [EXOJCR-868] - Port documentation for Core from wiki to docbook
+ * [EXOJCR-869] - Port documentation for JCR from wiki to docbook
+ * [EXOJCR-870] - Cleanup WS documentation
+ * [EXOJCR-871] - Document RestServicesList service
+ * [EXOJCR-881] - Port functionality of EXOJCR-482 in jcr-1.12.x
+ * [EXOJCR-884] - Rename JCR documentation artifacts to exo.jcr.* form
+
+Changes of 1.12.2-GA
+====================
+
+Bug
+ * [EXOJCR-497] - JCR serialization test wrong logic with CASable storage
+ * [EXOJCR-730] - Restored repository not accessible after restart Tomcat
+ * [EXOJCR-731] - Deploy error (500 - Unexpected error. null) of REST Service with annotation inheritance.
+ * [EXOJCR-735] - JCR repositories created in runtime is not available after eXo Social restart
+ * [EXOJCR-736] - Problems with anonymous entrance on FTP and NPE
+ * [EXOJCR-743] - InitialContextBinder bind twice same datasource in some case
+ * [EXOJCR-762] - Check whether the repository with the given name doesn't exists before starting restore from backup
+
+Feature Request
+ * [EXOJCR-640] - Migrate to newer version of Apache PDFBox ( and FontBox ) if possible;
+
+Task
+ * [EXOJCR-596] - Upload eXoJCR documentation on jboss.org
+ * [EXOJCR-668] - Validate format of the default values of the property definition during the nodetype registration
+ * [EXOJCR-738] - Search does not work with source in CDATA tag in XML document
+ * [EXOJCR-740] - Constrains ranges are not used in NodeTypeImpl.canSetProperty() validation
+ * [EXOJCR-741] - Backupconsole build improvements
+ * [EXOJCR-765] - Use StringBuilder instead of String concatenation in MSExcelDocumentReader.getContentAsText
+ * [EXOJCR-681] - Decreasing perfomance while running WebdavReadWriteTest tests several times in row
+
+
+
+Changes of 1.12.2-CR1
+=====================
+
+Bug
+ * [EXOJCR-175] - Problems with HTTPBackupAgent - Cyrillic symbols aren't showing after restore
+ * [EXOJCR-683] - java.io.IOException: Socket read failed on heavy loaded WebdavAddBLOBTest benchmark test
+ * [EXOJCR-697] - SQL search by date doesn't work
+ * [EXOJCR-698] - URL encoding in SEARCH and PROPFIND responces differs.
+ * [EXOJCR-700] - Problem in user search with MySql and PostgresDB
+ * [EXOJCR-704] - JCR testuite hangs on sybase
+ * [EXOJCR-708] - Problem with full text searching in text files with non-latin content.
+ * [EXOJCR-712] - Concurrent service creation leads to duplicate service instantiation
+ * [EXOJCR-724] - Bad URL in the error message when a component cannot be instantiated
+ * [EXOJCR-726] - Improper conversion of jboss.server.config.url system property value into File (spaces in filename problem)
+ * [EXOJCR-729] - The FileNotFoundException in restore workspace over BackupWorkspaceinitializer
+ * [EXOJCR-734] - The binary values was not stored in incremental backup.
+
+Feature Request
+ * [EXOJCR-705] - Expose listeners in OrganizationService
+ * [EXOJCR-707] - Check repository management operations on thread safety
+ * [EXOJCR-718] - Allow to get the complete configuration at runtime
+ * [EXOJCR-719] - Better debugging of components loaded
+ * [EXOJCR-721] - Add possibility to use customized GroovyClassLoader in org.exoplatform.services.script.groovy.GroovyScriptInstantiator
+ * [EXOJCR-722] - Make it possible to use other then org.exoplatform.services.rest.impl.method.DefaultMethodInvoker
+
+Task
+ * [EXOJCR-354] - Invoke post read after permissions check
+ * [EXOJCR-663] - Make possibility extends classes RequestDispatcher and ResourceBinder.
+ * [EXOJCR-691] - Fix your missing dependencies
+ * [EXOJCR-692] - Find the reason why the method of type Node.hasNodes is much slower since beta5
+ * [EXOJCR-694] - Change JBC dependencies to use 3.2.4.GA
+ * [EXOJCR-696] - Reduce the concurrency Level in the JBoss Cache Config
+ * [EXOJCR-711] - Misleading error message appears when the external settings cannot be found
+ * [EXOJCR-714] - Improve the usability of the ContainerLifecyclePlugin
+ * [EXOJCR-715] - Ensure that the ExoContainer is fully ThreadSafe
+ * [EXOJCR-716] - Prevent the JobSchedulerServiceImpl to launch jobs that rely on non started services
+ * [EXOJCR-717] - Add to RestRegistryService method without repositoryName in PathParam, insted use current repository. Methods with repositoryName in PathParam marks as Deprecated.
+ * [EXOJCR-720] - Make possibility extends classe GroovyScript2RestLoader
+ * [EXOJCR-723] - JCR Statistics: Describe the arguments of the methods exposed through JMX
+ * [EXOJCR-728] - implementing RequestLifecycle for REST services
+
+
+Changes of 1.12.1-GA
+=====================
+
+Bug
+ * [EXOJCR-612] - JBoss Cache Implementation for the Cache Service test TestAbstractExoCache fails
+ * [EXOJCR-638] - get mixin types through the NodeTypeUtil class
+ * [EXOJCR-661] - Cannot access to the MBeans through the JConsole in Standalone mode
+ * [EXOJCR-662] - Processing SQLException may cause infinite loop.
+ * [EXOJCR-664] - org.exoplatform.services.jcr.impl.storage.value.fs.TestFileIOChannel.testConcurrentRead fail with MSSQL and DB2
+ * [EXOJCR-667] - Temporary spooled file can be not found on save
+ * [EXOJCR-671] - ConcurrentModificationException in FileCleaner with heavy load
+ * [EXOJCR-672] - An eXoCache clear should be local
+ * [EXOJCR-687] - Some JCR parameters that are time parameter are retrieved as number instead of time
+
+Feature Request
+ * [EXOJCR-498] - Provide more details when a JCR query is invalid
+ * [EXOJCR-634] - Upload of a file with special characters like " ' " in filename is not supported by the FTPservice
+ * [EXOJCR-645] - Add ExtHttpHeaders.JAXRS_BODY_PROVIDED header for unhandled exception in REST services and set error message to body responce
+
+Task
+ * [EXOJCR-578] - Use Fisheye in SCM urls used in maven
+ * [EXOJCR-611] - Provide a way to collect statistics around the JCR API accesses
+ * [EXOJCR-639] - Find the reason why the methods of type Property.setValue are much slower since beta5
+ * [EXOJCR-685] - Change JBC dependencies to use 3.2.3.GA
+ * [EXOJCR-689] - Standartize eXo JCR docnmentation projects description.
+ * [EXOJCR-690] - Apply changes in the eXo JCR project in order to be able to publish artifacts in the nexus of JBoss
+ * [EXOJCR-545] - Checking performance on SearchNodesByPropertyTest
+ * [EXOJCR-643] - Improve the performances of the lucene indexing in a cluster by removing contention for read operations
+
+
+Changes of 1.12.1-CR1
+=====================
+
+Bug
+ * [EXOJCR-256] - There are server errors "500 Internal Server Error:" during creation repository or workspace by RestRepositoryService
+ * [EXOJCR-348] - Test problem: TestCleanableFileStreamValueData failed
+ * [EXOJCR-519] - DAILY TESTS are going too long (avg time=5hours)
+ * [EXOJCR-531] - Problems with Lock operations
+ * [EXOJCR-546] - TESTING: Performance testing problems. LockUnlockOwnNodeTest - TPS fell down
+ * [EXOJCR-548] - problem with import & export node
+ * [EXOJCR-555] - NPE with cache eviction at startup
+ * [EXOJCR-557] - Problem while uploading *.pdf to WebDAV server using Mac OS Finder
+ * [EXOJCR-558] - Files uploaded by Mac OS finder are displayed with size "0"
+ * [EXOJCR-559] - Problems with daily performance testing - on PostgreSQL 8.2.9
+ * [EXOJCR-567] - The REST servlet dump errors when the client cut the socket too early should be only a debug log
+ * [EXOJCR-572] - Can not create workspace with default configuration of lock manager
+ * [EXOJCR-581] - Listing the directory in TreeFile may return null during race condition, causing NPE.
+ * [EXOJCR-584] - User's research is case sensitive
+ * [EXOJCR-586] - Missed slf4j dependency for jcr applications on tomcat AS
+ * [EXOJCR-587] - session.save() throws NPE after node reordering
+ * [EXOJCR-588] - Tests errors in eXo XML Processing Services on MACOS
+ * [EXOJCR-591] - Problem with ObservationManager
+ * [EXOJCR-599] - deadlock during dashboard editing
+ * [EXOJCR-600] - Concurrency problem (java.util.HashMap.put called from CacheableLockManagerImpl.getSessionLockManager(CacheableLockManagerImpl.java:473))
+ * [EXOJCR-601] - gatein sample extension should not be required
+ * [EXOJCR-602] - StackOverflow on JsonGeneratorImpl
+ * [EXOJCR-603] - impossible to change user password
+ * [EXOJCR-607] - Sybase Issue with GateIn
+ * [EXOJCR-608] - XaSessionImpl as XA resource should be unique per user, workspace and repository
+ * [EXOJCR-614] - Node.getReferences fail in some cases
+ * [EXOJCR-615] - Need check nodedata to avoid exception in method NodeImpl.isNodeType(String).
+ * [EXOJCR-619] - Log record forging (Security Issue)
+ * [EXOJCR-621] - Conflict between symlink feature and Jbosscache
+ * [EXOJCR-623] - Unable to get a version of document using WebDAV (HTTP Response 404 returned).
+ * [EXOJCR-633] - Problems with manual testing - tomcat-server on ftp -.IndexOutOfBoundsException
+
+Feature Request
+ * [EXOJCR-549] - Backup and Restore of a whole Repository
+ * [EXOJCR-571] - Change PersitedValueDataReader/Writer
+ * [EXOJCR-573] - Create database and bind DataSource in runtime
+ * [EXOJCR-582] - DB script modification for oracle11 compatibility
+ * [EXOJCR-585] - Allow to get statistics on Database Access without using a Profiler
+ * [EXOJCR-616] - Remove repository container from repositoryContainers map when repository container start fail.
+ * [EXOJCR-617] - Map environment parameters for all String fields in Repository configuration
+
+Task
+ * [EXOJCR-150] - Ftp client tests failute
+ * [EXOJCR-250] - Add human readable message in case Workspace creation error via HTTPBackupAgent
+ * [EXOJCR-393] - Create indexer load test
+ * [EXOJCR-523] - Upgrade to JBoss Cache 3.2.3.GA
+ * [EXOJCR-550] - Bind slf4j-log4j and log4j dependencies onto the test phase of the various modules of JCR
+ * [EXOJCR-552] - Allow to Test eXo JCR 1.12 on EC2
+ * [EXOJCR-575] - Remove unused PairChangesLog class
+ * [EXOJCR-589] - Limit network traffic and thread blocking for the Lucene Indexer in a cluster
+ * [EXOJCR-590] - DO NOT exclude tests from a parent pom
+ * [EXOJCR-598] - Allow to disable the hints used for the Complex Queries on oracle
+ * [EXOJCR-605] - Normalize logging categories
+ * [EXOJCR-631] - Find a reason, why functional tests fails under Tornado.MySQL with "Cannot create PoolableConnectionFactory (Too many connections)" message.
+ * [EXOJCR-632] - svn: File 'jcr.packaging.module/1.12.0-CP01/jcr.packaging.module-1.12.0-CP01.js' has inconsistent newlines
+
+
+Features of eXoJCR 1.12 comparing to 1.11
+=========================================
+
+- Repository clustering based on JBossCache and JBoss Transactions.
+- Lazy-load option for child nodes and properties read, improved items dataflow for read/write operations
+- Alternative data container optimized for read operations (consuming less database queries)
+- Database dialect can be autodetected (if not pointed in the configuration)
+- Support for Values large of 2GiB
+- Portal container configuration improvements (default definitions, link and externaly loaded parameters)
+- Concurrency improvements for Session registry and Values stroage
+- Concurrency improvements for XA transactions support (Repository login and logout faster now)
+- Improved serach based on Lucene 2.4
+- Support of MySQL/InnoDB database for multi-language content
+- Standalone container can use configuration stored in JBossAS server configuration directory by default
+- WebDAV server update-policy can be configured to different versioning behaviour
+- Lot of WebDAV server bugfixes
+- HTTP (RESTful) Backup agent with concole client
+- HTTP (RESTful) Repository management service
+- Support of Java6 and Java5 runtime and development environment
+
+Since version of 1.12 eXoJCR available under LGPL license (version 2.1).
+
+eXoJCR 1.12 tested in on the databases:
+ MySQL 5.1 MYSQL Connector/J 5.1.8
+ Oracle DB 10g (10.2.0.1) Oracle 10g (10.2.0.1)
+ PostgresSQL 8.3.7 JDBC4 Driver, Version 8.3-605
+ DB2 9,7 IBM Data Server Driver for JDBC and SQLJ (JCC Driver) Version: 9.1 (fixpack 3a)
+ MS SQL Server 2005 SP3 JDBC Driver 2.0
+ MS SQL Server 2008 SP1 JDBC Driver 2.0
+ Sybase 15.0.2 JConnect v6.0.5 (Build 26564 / 11 Jun 2009)
+
+
+Release includes:
+* eXo Kernel 2.2.10-GA
+* eXo Core 2.3.10-GA
+* eXo WS 2.1.10-GA
+* eXo JCR 1.12.10-GA
+
+1.12.10-GA tasks:
+https://jira.exoplatform.org/browse/KER/fixforversion/13102
+https://jira.exoplatform.org/browse/COR/fixforversion/13099
+https://jira.exoplatform.org/browse/WS/fixforversion/13104
+https://jira.exoplatform.org/browse/JCR/fixforversion/13100
+
+JCR Samples
+===========
+
+1. Start Up (Tomcat)
+ Tomcat 6 bundled can be started by executing the following commands:
+
+ $CATALINA_HOME\bin\eXo.bat run (Windows)
+
+ $CATALINA_HOME/bin/eXo.sh run (Unix)
+
+2. After startup, the sample applications will be available by visiting:
+
+ http://localhost:8080/browser - Simple JCR browser
+ Browse the JCR repository that was started with Tomcat
+ http://localhost:8080/fckeditor - FCK editor sample
+ Edits the sample node using FCKEditor and browse it JCR browser
+ http://localhost:8080/rest/jcr/repository/production - WebDAV service,
+ Open in Microsoft Explorer, File-Open-OpenAsWebFolder with url http://localhost:8080/rest/jcr/repository/production
+ Add/read/remove files there and browse it in the JCR browser or FTP.
+ User name/password: root/exo
+ ftp://localhost:2121 - FTP server
+ Open the repository in FTP client and browse the JCR repository started with Tomcat as FTP content,
+ add/read/remove files there and browse it in the JCR browser or WebDAV.
+
+EAR deploy
+==========
+
+eXo JCR was tested under JBoss-5.1.0.GA application server
+
+JBoss-5.1.0.GA
+
+ 1. Configuration
+
+ * Copy jcr.ear into $jboss_home/server/default/deploy
+ * Create $jboss_home/server/default/conf/exo-conf folder if it doesn't exist.
+ * Put exo-configuration.xml into $jboss_home/server/default/conf/exo-conf/exo-configuration.xml
+ * Configure JAAS by inserting XML fragment shown below into $jboss_home/server/default/conf/login-config.xml
+
+---------
+<application-policy name="exo-domain">
+ <authentication>
+ <login-module code="org.exoplatform.services.security.j2ee.JbossLoginModule" flag="required"></login-module>
+ </authentication>
+ </application-policy>
+---------
+
+ 2. Start Up
+
+ Execute
+ * bin/run.bat on Windows
+ or
+ * bin/run.sh on Unix
+
+Resources
+=========
+
+ Company site http://www.exoplatform.com
+ Documentation wiki http://wiki.exoplatform.org
+ Community JIRA https://jira.jboss.org/jira/browse/EXOJCR, http://jira.exoplatform.org
+ Comminity site http://www.exoplatform.org
+ Community forum http://www.exoplatform.com/portal/public/en/forum
+ JavaDoc site http://docs.exoplatform.org
+
\ No newline at end of file
14 years, 7 months
exo-jcr SVN: r5021 - 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-10-04 09:07:38 -0400 (Tue, 04 Oct 2011)
New Revision: 5021
Modified:
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-client.xml
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-clonsole-dist.xml
Log:
EXOJCR-1531 : Help information in backup client was extended and fixed.
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-client.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-client.xml 2011-10-04 13:07:08 UTC (rev 5020)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-client.xml 2011-10-04 13:07:38 UTC (rev 5021)
@@ -1006,13 +1006,13 @@
stop <backup_id>
status <backup_id>
restores <repo[/ws]>
- restore [remove-exists] [<repo[/ws]>] {<backup_id>|<backup_set_path>} [<pathToConfigFile>]
+ restore [remove-exists] {{<backup_id>|<backup_set_path>} | {<repo[/ws]> {<backup_id>|<backup_set_path>} [<pathToConfigFile>]}}
list [completed]
info
drop [force-close-session] <repo[/ws]>
help
- start - start backup of repositpry or workspace
+ 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
@@ -1029,8 +1029,23 @@
<backup_set_dir> - path to folder with backup set on remote server
<incr> - incemental job period
<pathToConfigFile> - path (local) to repository or workspace configuration
- remove-exists - removed fully (db, value storage, index) existed repository/workspace
- force-close-session - close opened sessions on repositpry or workspace.</programlisting>
+ remove-exists - remove fully (db, value storage, index) exists repository/workspace
+ force-close-session - close opened sessions on repository or workspace.
+
+ All valid combination of parameters for command restore:
+ 1. restore remove-exists <repo/ws> <backup_id> <pathToConfigFile>
+ 2. restore remove-exists <repo> <backup_id> <pathToConfigFile>
+ 3. restore remove-exists <repo/ws> <backup_set_path> <pathToConfigFile>
+ 4. restore remove-exists <repo> <backup_set_path> <pathToConfigFile>
+ 5. restore remove-exists <backup_id>
+ 6. restore remove-exists <backup_set_path>
+ 7. restore <repo/ws> <backup_id> <pathToConfigFile>
+ 8. restore <repo> <backup_id> <pathToConfigFile>
+ 9. restore <repo/ws> <backup_set_path> <pathToConfigFile>
+ 10. restore <repo> <backup_set_path> <pathToConfigFile>
+ 11. restore <backup_id>
+ 12. restore <backup_set_path>
+</programlisting>
</section>
<section>
@@ -1563,10 +1578,11 @@
status code = 200</programlisting>The
/home/rainf0x/java/exo-working/JCR-839/exo-jcr-config_backup.xml
content the configuration for restored workspace <emphasis
- role="bold">"backup"</emphasis>:</para></listitem>
+ role="bold">"backup"</emphasis>:</para>
+ </listitem>
</itemizedlist>
-
- <programlisting language="xml"><repository-service default-repository="repository">
+
+ <programlisting language="xml"><repository-service default-repository="repository">
<repositories>
<repository name="repository" system-workspace="production" default-workspace="production">
<security-domain>exo-domain</security-domain>
@@ -1650,7 +1666,7 @@
<para>This usecase needs RestRepositoryService enabled. (Deleting the
repository needs it)</para>
-
+
<programlisting language="xml"><component>
<type>org.exoplatform.services.jcr.ext.repository.RestRepositoryService</type>
</component></programlisting>
@@ -1738,8 +1754,8 @@
role="bold">"repository"</emphasis>:</para>
</listitem>
</itemizedlist>
-
- <programlisting language="xml"><repository-service default-repository="repository">
+
+ <programlisting language="xml"><repository-service default-repository="repository">
<repositories>
<repository name="repository" system-workspace="production" default-workspace="production">
<security-domain>exo-domain</security-domain>
@@ -1873,7 +1889,6 @@
</repositories>
</repository-service>
</programlisting>
-
</section>
<section>
Modified: 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 2011-10-04 13:07:08 UTC (rev 5020)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/backup-clonsole-dist.xml 2011-10-04 13:07:38 UTC (rev 5021)
@@ -4,14 +4,14 @@
<chapter id="JCR.BackupClient">
<?dbhtml filename="ch-backup-clonsole.dist.html"?>
- <title>Backup console binary distribution </title>
+ <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>
+ 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
@@ -41,7 +41,7 @@
stop <backup_id>
status <backup_id>
restores <repo[/ws]>
- restore [remove-exists] [<repo[/ws]>] {<backup_id>|<backup_set_path>} [<pathToConfigFile>]
+ restore [remove-exists] {{<backup_id>|<backup_set_path>} | {<repo[/ws]> {<backup_id>|<backup_set_path>} [<pathToConfigFile>]}}
list [completed]
info
drop [force-close-session] <repo[/ws]>
@@ -64,7 +64,23 @@
<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>
+ force-close-session : close opened sessions on repository or workspace
+
+
+ All valid combination of parameters for command restore:
+ 1. restore remove-exists <repo/ws> <backup_id> <pathToConfigFile>
+ 2. restore remove-exists <repo> <backup_id> <pathToConfigFile>
+ 3. restore remove-exists <repo/ws> <backup_set_path> <pathToConfigFile>
+ 4. restore remove-exists <repo> <backup_set_path> <pathToConfigFile>
+ 5. restore remove-exists <backup_id>
+ 6. restore remove-exists <backup_set_path>
+ 7. restore <repo/ws> <backup_id> <pathToConfigFile>
+ 8. restore <repo> <backup_id> <pathToConfigFile>
+ 9. restore <repo/ws> <backup_set_path> <pathToConfigFile>
+ 10. restore <repo> <backup_set_path> <pathToConfigFile>
+ 11. restore <backup_id>
+ 12. restore <backup_set_path>
+</programlisting>
</section>
<section>
@@ -86,7 +102,7 @@
stop <backup_id>
status <backup_id>
restores <repo[/ws]>
- restore [remove-exists] [<repo[/ws]>] {<backup_id>|<backup_set_path>} [<pathToConfigFile>]
+ restore [remove-exists] {{<backup_id>|<backup_set_path>} | {<repo[/ws]> {<backup_id>|<backup_set_path>} [<pathToConfigFile>]}}
list [completed]
info
drop [force-close-session] <repo[/ws]>
@@ -109,7 +125,22 @@
<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>
+ force-close-session : close opened sessions on repository or workspace
+
+
+ All valid combination of parameters for command restore:
+ 1. restore remove-exists <repo/ws> <backup_id> <pathToConfigFile>
+ 2. restore remove-exists <repo> <backup_id> <pathToConfigFile>
+ 3. restore remove-exists <repo/ws> <backup_set_path> <pathToConfigFile>
+ 4. restore remove-exists <repo> <backup_set_path> <pathToConfigFile>
+ 5. restore remove-exists <backup_id>
+ 6. restore remove-exists <backup_set_path>
+ 7. restore <repo/ws> <backup_id> <pathToConfigFile>
+ 8. restore <repo> <backup_id> <pathToConfigFile>
+ 9. restore <repo/ws> <backup_set_path> <pathToConfigFile>
+ 10. restore <repo> <backup_set_path> <pathToConfigFile>
+ 11. restore <backup_id>
+ 12. restore <backup_set_path> </programlisting>
</section>
<section>
14 years, 7 months
exo-jcr SVN: r5020 - in jcr/trunk/applications: exo.jcr.applications.backupconsole.dist/bin and 1 other directory.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-10-04 09:07:08 -0400 (Tue, 04 Oct 2011)
New Revision: 5020
Modified:
jcr/trunk/applications/exo.jcr.applications.backupconsole.dist/bin/exobackup.cmd
jcr/trunk/applications/exo.jcr.applications.backupconsole.dist/bin/exobackup.sh
jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupConsole.java
Log:
EXOJCR-1531 : Help information in backup client was extended and fixed.
Modified: jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupConsole.java
===================================================================
--- jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupConsole.java 2011-10-04 11:52:31 UTC (rev 5019)
+++ jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupConsole.java 2011-10-04 13:07:08 UTC (rev 5020)
@@ -72,13 +72,13 @@
+ " stop <backup_id> \n"
+ " status <backup_id> \n"
+ " restores <repo[/ws]> \n"
- + " restore [remove-exists] [<repo[/ws]>] {<backup_id>|<backup_set_path>} [<pathToConfigFile>] \n"
+ + " restore [remove-exists] {{<backup_id>|<backup_set_path>} | {<repo[/ws]> {<backup_id>|<backup_set_path>} [<pathToConfigFile>]}} \n"
+ " list [completed] \n"
+ " info \n"
+ " drop [force-close-session] <repo[/ws]> \n"
+ " help \n\n"
- + " start - start backup of repositpry or workspace \n"
+ + " start - start backup of repository or workspace \n"
+ " stop - stop backup \n"
+ " status - information about the current or completed backup by 'backup_id' \n"
+ " restores - information about the last restore on specific repository or workspace \n"
@@ -96,7 +96,20 @@
+ " <incr> - incemental job period \n"
+ " <pathToConfigFile> - path (local) to repository or workspace configuration \n"
+ " remove-exists - remove fully (db, value storage, index) exists repository/workspace \n"
- + " force-close-session - close opened sessions on repositpry or workspace. \n\n";
+ + " force-close-session - close opened sessions on repository or workspace. \n\n"
+ + " All valid combination of parameters for command restore: \n"
+ + " 1. restore remove-exists <repo/ws> <backup_id> <pathToConfigFile> \n"
+ + " 2. restore remove-exists <repo> <backup_id> <pathToConfigFile> \n"
+ + " 3. restore remove-exists <repo/ws> <backup_set_path> <pathToConfigFile> \n"
+ + " 4. restore remove-exists <repo> <backup_set_path> <pathToConfigFile> \n"
+ + " 5. restore remove-exists <backup_id> \n"
+ + " 6. restore remove-exists <backup_set_path> \n"
+ + " 7. restore <repo/ws> <backup_id> <pathToConfigFile> \n"
+ + " 8. restore <repo> <backup_id> <pathToConfigFile> \n"
+ + " 9. restore <repo/ws> <backup_set_path> <pathToConfigFile> \n"
+ + " 10. restore <repo> <backup_set_path> <pathToConfigFile> \n"
+ + " 11. restore <backup_id> \n"
+ + " 12. restore <backup_set_path> \n";
/**
* Main.
@@ -445,7 +458,7 @@
{
/*
- All valid combination of paramter.
+ All valid combination of parameters for command restore.
1. restore remove-exists <repo/ws> <backup_id> <pathToConfigFile>
2. restore remove-exists <repo> <backup_id> <pathToConfigFile>
3. restore remove-exists <repo/ws> <backup_set_path> <pathToConfigFile>
@@ -551,7 +564,7 @@
if (curArg == args.length)
{
- System.out.println(INCORRECT_PARAM + "There is no path to config file parameter."); //NOSONAR
+ System.out.println(INCORRECT_PARAM + "The path to the configuration file is missing."); //NOSONAR
return;
}
String pathToConf = args[curArg++];
Modified: jcr/trunk/applications/exo.jcr.applications.backupconsole.dist/bin/exobackup.cmd
===================================================================
--- jcr/trunk/applications/exo.jcr.applications.backupconsole.dist/bin/exobackup.cmd 2011-10-04 11:52:31 UTC (rev 5019)
+++ jcr/trunk/applications/exo.jcr.applications.backupconsole.dist/bin/exobackup.cmd 2011-10-04 13:07:08 UTC (rev 5020)
@@ -71,7 +71,7 @@
echo stop ^<backup_id^>
echo status ^<backup_id^>
echo restores ^<repo[/ws]^>
-echo restore ^<repo[/ws]^> ^<backup_id^> ^<pathToConfigFile^>
+echo restore [remove-exists] {{^<backup_id^>|^<backup_set_path^>} | {^<repo[/ws]^> {^<backup_id^>|^<backup_set_path^>} [^<pathToConfigFile^>]}}
echo list [completed]
echo info
echo drop [force-close-session] ^<repo[/ws]^>
@@ -94,3 +94,18 @@
echo ^<incr^> : incremental job period
echo ^<pathToConfigFile^> : path (local) to repository or workspace configuration
echo force-close-session : close opened sessions on repository or workspace
+echo
+echo All valid combination of parameters for command restore:
+echo 1. restore remove-exists ^<repo/ws^> ^<backup_id^> ^<pathToConfigFile^>
+echo 2. restore remove-exists ^<repo^> ^<backup_id^> ^<pathToConfigFile^>
+echo 3. restore remove-exists ^<repo/ws^> ^<backup_set_path^> ^<pathToConfigFile^>
+echo 4. restore remove-exists ^<repo^> ^<backup_set_path^> ^<pathToConfigFile^>
+echo 5. restore remove-exists ^<backup_id^>
+echo 6. restore remove-exists ^<backup_set_path^>
+echo 7. restore ^<repo/ws^> ^<backup_id^> ^<pathToConfigFile^>
+echo 8. restore ^<repo^> ^<backup_id^> ^<pathToConfigFile^>
+echo 9. restore ^<repo/ws^> ^<backup_set_path^> ^<pathToConfigFile^>
+echo 10. restore ^<repo^> ^<backup_set_path^> ^<pathToConfigFile^>
+echo 11. restore ^<backup_id^>
+echo 12. restore ^<backup_set_path^>
+
\ No newline at end of file
Modified: jcr/trunk/applications/exo.jcr.applications.backupconsole.dist/bin/exobackup.sh
===================================================================
--- jcr/trunk/applications/exo.jcr.applications.backupconsole.dist/bin/exobackup.sh 2011-10-04 11:52:31 UTC (rev 5019)
+++ jcr/trunk/applications/exo.jcr.applications.backupconsole.dist/bin/exobackup.sh 2011-10-04 13:07:08 UTC (rev 5020)
@@ -14,7 +14,7 @@
echo " stop <backup_id> "
echo " status <backup_id> "
echo " restores <repo[/ws]> "
-echo " restore [remove-exists] [<repo[/ws]>] {<backup_id>|<backup_set_path>} [<pathToConfigFile>] "
+echo " restore [remove-exists] {{<backup_id>|<backup_set_path>} | {<repo[/ws]> {<backup_id>|<backup_set_path>} [<pathToConfigFile>]}} "
echo " list [completed] "
echo " info "
echo " drop [force-close-session] <repo[/ws]> "
@@ -38,7 +38,21 @@
echo " <pathToConfigFile> : path (local) to repository or workspace configuration "
echo " remove-exists : remove fully (db, value storage, index) exists repository/workspace "
echo " force-close-session : close opened sessions on repository or workspace "
-exit 1
+echo " "
+echo " All valid combination of parameters for command restore: "
+echo " 1. restore remove-exists <repo/ws> <backup_id> <pathToConfigFile> "
+echo " 2. restore remove-exists <repo> <backup_id> <pathToConfigFile> "
+echo " 3. restore remove-exists <repo/ws> <backup_set_path> <pathToConfigFile> "
+echo " 4. restore remove-exists <repo> <backup_set_path> <pathToConfigFile> "
+echo " 5. restore remove-exists <backup_id> "
+echo " 6. restore remove-exists <backup_set_path> "
+echo " 7. restore <repo/ws> <backup_id> <pathToConfigFile> "
+echo " 8. restore <repo> <backup_id> <pathToConfigFile> "
+echo " 9. restore <repo/ws> <backup_set_path> <pathToConfigFile> "
+echo " 10. restore <repo> <backup_set_path> <pathToConfigFile> "
+echo " 11. restore <backup_id> "
+echo " 12. restore <backup_set_path> "
+exit 1
fi
user="$2"
14 years, 7 months
exo-jcr SVN: r5019 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl: core/query and 2 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-10-04 07:52:31 -0400 (Tue, 04 Oct 2011)
New Revision: 5019
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DirectoryRestore.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.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/util/io/DirectoryHelper.java
Log:
EXOJCR-1565: backward compatibility
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DirectoryRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DirectoryRestore.java 2011-10-04 09:58:19 UTC (rev 5018)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DirectoryRestore.java 2011-10-04 11:52:31 UTC (rev 5019)
@@ -131,7 +131,14 @@
try
{
- DirectoryHelper.uncompressDirectory(zipFile, dataDir);
+ if (PrivilegedFileHelper.isDirectory(zipFile))
+ {
+ DirectoryHelper.uncompressEveryFileFromDirectory(zipFile, dataDir);
+ }
+ else
+ {
+ DirectoryHelper.uncompressDirectory(zipFile, dataDir);
+ }
}
catch (IOException e)
{
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2011-10-04 09:58:19 UTC (rev 5018)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2011-10-04 11:52:31 UTC (rev 5019)
@@ -1615,14 +1615,22 @@
{
File zipFile = new File((File)context.getObject(DataRestoreContext.STORAGE_DIR), getStorageName() + ".zip");
- if (!PrivilegedFileHelper.exists(zipFile))
+ if (PrivilegedFileHelper.exists(zipFile))
{
- throw new RepositoryConfigurationException("Can't restore index. File " + zipFile.getName()
- + " doesn't exists");
+ return new DirectoryRestore(getIndexDirectory(), zipFile);
}
else
{
- return new DirectoryRestore(getIndexDirectory(), zipFile);
+ // try to check if we have deal with old backup format
+ zipFile = new File((File)context.getObject(DataRestoreContext.STORAGE_DIR), getStorageName());
+ if (PrivilegedFileHelper.exists(zipFile))
+ {
+ return new DirectoryRestore(getIndexDirectory(), zipFile);
+ }
+ else
+ {
+ throw new BackupException("There is no backup data for index");
+ }
}
}
catch (RepositoryConfigurationException e)
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-10-04 09:58:19 UTC (rev 5018)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-10-04 11:52:31 UTC (rev 5019)
@@ -73,7 +73,6 @@
import java.io.File;
import java.io.FileNotFoundException;
-import java.io.FilenameFilter;
import java.io.IOException;
import java.security.PrivilegedExceptionAction;
import java.sql.Connection;
@@ -1304,56 +1303,40 @@
restorers.add(new DBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner));
}
-
- // prepare value storage restorer
- List<ValueStorageEntry> valueStorages = wsConfig.getContainer().getValueStorages();
- String[] valueStoragesFiles = PrivilegedFileHelper.list(storageDir, new FilenameFilter()
- {
- public boolean accept(File dir, String name)
- {
- return name.startsWith("values-") && name.endsWith(".zip");
- }
- });
-
if (wsConfig.getContainer().getValueStorages() != null)
{
List<File> dataDirs = new ArrayList<File>();
List<File> backupDirs = new ArrayList<File>();
- if ((valueStoragesFiles == null && valueStorages.size() != 0)
- || (valueStoragesFiles != null && valueStoragesFiles.length != valueStorages.size()))
- {
- throw new RepositoryConfigurationException("Workspace configuration [" + wsConfig.getName()
- + "] has a different amount of value storages than exist in backup");
- }
-
+ List<ValueStorageEntry> valueStorages = wsConfig.getContainer().getValueStorages();
for (ValueStorageEntry valueStorage : valueStorages)
{
+ File dataDir = new File(valueStorage.getParameterValue(FileValueStorage.PATH));
+ dataDirs.add(dataDir);
+
File zipFile = new File(storageDir, "values-" + valueStorage.getId() + ".zip");
- if (!PrivilegedFileHelper.exists(zipFile))
+ if (PrivilegedFileHelper.exists(zipFile))
{
- throw new RepositoryConfigurationException("Can't restore value storage. File " + zipFile.getName()
- + " doesn't exists");
+ backupDirs.add(zipFile);
}
else
{
- File dataDir = new File(valueStorage.getParameterValue(FileValueStorage.PATH));
-
- dataDirs.add(dataDir);
- backupDirs.add(zipFile);
+ // try to check if we have deal with old backup format
+ zipFile = new File(storageDir, "values/" + valueStorage.getId());
+ if (PrivilegedFileHelper.exists(zipFile))
+ {
+ backupDirs.add(zipFile);
+ }
+ else
+ {
+ throw new RepositoryConfigurationException("There is no backup data for value storage with id "
+ + valueStorage.getId());
+ }
}
}
restorers.add(new DirectoryRestore(dataDirs, backupDirs));
}
- else
- {
- if (valueStoragesFiles != null && valueStoragesFiles.length != 0)
- {
- throw new RepositoryConfigurationException("Value storage didn't configure in workspace ["
- + wsConfig.getName() + "] configuration but value storage backup files exist");
- }
- }
return new ComplexDataRestore(restorers);
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/DirectoryHelper.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/DirectoryHelper.java 2011-10-04 09:58:19 UTC (rev 5018)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/DirectoryHelper.java 2011-10-04 11:52:31 UTC (rev 5019)
@@ -236,9 +236,7 @@
}
/**
- * Uncompress data to the destination directory. If <code>srcZipPath</code> is the directory we assume
- * that every file in the directory is compressed, in other case <code>srcZipPath</code> should contain
- * the compress data.
+ * Uncompress data to the destination directory.
*
* @param srcZipPath
* path to the compressed file, could be the file or the directory
@@ -249,55 +247,54 @@
*/
public static void uncompressDirectory(File srcZipPath, File dstDirPath) throws IOException
{
- if (PrivilegedFileHelper.isDirectory(srcZipPath))
- {
- uncompressEveryFileInDirectory(srcZipPath, dstDirPath);
- }
- else
- {
+ ZipInputStream in = PrivilegedFileHelper.zipInputStream(srcZipPath);
+ ZipEntry entry = null;
- ZipInputStream in = PrivilegedFileHelper.zipInputStream(srcZipPath);
- ZipEntry entry = null;
-
- try
+ try
+ {
+ while ((entry = in.getNextEntry()) != null)
{
- while ((entry = in.getNextEntry()) != null)
- {
- File dstFile = new File(dstDirPath, entry.getName());
- PrivilegedFileHelper.mkdirs(dstFile.getParentFile());
+ File dstFile = new File(dstDirPath, entry.getName());
+ PrivilegedFileHelper.mkdirs(dstFile.getParentFile());
- if (entry.isDirectory())
+ if (entry.isDirectory())
+ {
+ PrivilegedFileHelper.mkdirs(dstFile);
+ }
+ else
+ {
+ OutputStream out = PrivilegedFileHelper.fileOutputStream(dstFile);
+ try
{
- PrivilegedFileHelper.mkdirs(dstFile);
+ transfer(in, out);
}
- else
+ finally
{
- OutputStream out = PrivilegedFileHelper.fileOutputStream(dstFile);
- try
- {
- transfer(in, out);
- }
- finally
- {
- out.close();
- }
+ out.close();
}
}
}
- finally
+ }
+ finally
+ {
+ if (in != null)
{
- if (in != null)
- {
- in.close();
- }
+ in.close();
}
}
}
/**
- * Uncompress data in case when every file in the directory is compressed.
+ * Uncompress data to the destination directory.
+ *
+ * @param srcZipPath
+ * path to the compressed file, could be the file or the directory
+ * @param dstDirPath
+ * destination path
+ * @throws IOException
+ * if any exception occurred
*/
- private static void uncompressEveryFileInDirectory(File srcPath, File dstPath) throws IOException
+ public static void uncompressEveryFileFromDirectory(File srcPath, File dstPath) throws IOException
{
if (PrivilegedFileHelper.isDirectory(srcPath))
{
@@ -309,7 +306,7 @@
String files[] = PrivilegedFileHelper.list(srcPath);
for (int i = 0; i < files.length; i++)
{
- uncompressEveryFileInDirectory(new File(srcPath, files[i]), new File(dstPath, files[i]));
+ uncompressEveryFileFromDirectory(new File(srcPath, files[i]), new File(dstPath, files[i]));
}
}
else
14 years, 7 months
exo-jcr SVN: r5018 - 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-10-04 05:58:19 -0400 (Tue, 04 Oct 2011)
New Revision: 5018
Modified:
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsFullBackupJob.java
Log:
EXOJCR-1565: compress all dumps into single file
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsFullBackupJob.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsFullBackupJob.java 2011-10-04 09:57:12 UTC (rev 5017)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsFullBackupJob.java 2011-10-04 09:58:19 UTC (rev 5018)
@@ -50,13 +50,8 @@
assertTrue(new File(url.getFile(), "values-draft.zip").exists());
assertTrue(new File(url.getFile(), "index.zip").exists());
- assertTrue(new File(url.getFile(), "index_system.zip").exists());
- assertTrue(new File(url.getFile(), "JCR_MITEM.dump").exists());
- assertTrue(new File(url.getFile(), "JCR_MITEM.len").exists());
- assertTrue(new File(url.getFile(), "JCR_MVALUE.dump").exists());
- assertTrue(new File(url.getFile(), "JCR_MVALUE.len").exists());
- assertTrue(new File(url.getFile(), "JCR_MREF.dump").exists());
- assertTrue(new File(url.getFile(), "JCR_MREF.len").exists());
+ assertTrue(new File(url.getFile(), "dump.zip").exists());
+ assertTrue(new File(url.getFile(), "dump-len.zip").exists());
}
public void testRDBMSFullBackupJob() throws Exception
@@ -78,15 +73,7 @@
assertFalse(new File(url.getFile(), "values-draft.zip").exists());
assertTrue(new File(url.getFile(), "index.zip").exists());
assertFalse(new File(url.getFile(), "index_system.zip").exists());
-
- assertTrue(new File(url.getFile(), "JCR_MITEM.dump").exists());
- assertTrue(new File(url.getFile(), "JCR_MITEM.len").exists());
-
- assertTrue(new File(url.getFile(), "JCR_MVALUE.dump").exists());
- assertTrue(new File(url.getFile(), "JCR_MVALUE.len").exists());
-
- assertTrue(new File(url.getFile(), "JCR_MREF.dump").exists());
- assertTrue(new File(url.getFile(), "JCR_MREF.len").exists());
-
+ assertTrue(new File(url.getFile(), "dump.zip").exists());
+ assertTrue(new File(url.getFile(), "dump-len.zip").exists());
}
}
14 years, 7 months
exo-jcr SVN: r5017 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl: storage/jdbc and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-10-04 05:57:12 -0400 (Tue, 04 Oct 2011)
New Revision: 5017
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBBackup.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/RestoreTableRule.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
Log:
EXOJCR-1565: compress all dumps into single file
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBBackup.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBBackup.java 2011-10-04 09:03:41 UTC (rev 5016)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBBackup.java 2011-10-04 09:57:12 UTC (rev 5017)
@@ -25,6 +25,8 @@
import org.exoplatform.services.jcr.impl.backup.BackupException;
import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectZipWriterImpl;
import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -47,16 +49,33 @@
public class DBBackup
{
/**
+ * Logger.
+ */
+ protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBBackup");
+
+ /**
* Suffix for content file.
*/
+ @Deprecated
public static final String CONTENT_FILE_SUFFIX = ".dump";
/**
* Suffix for content length file.
*/
+ @Deprecated
public static final String CONTENT_LEN_FILE_SUFFIX = ".len";
/**
+ * Suffix for content file.
+ */
+ public static final String CONTENT_ZIP_FILE = "dump.zip";
+
+ /**
+ * Suffix for content length file.
+ */
+ public static final String CONTENT_LEN_ZIP_FILE = "dump-len.zip";
+
+ /**
* MySQL dialect.
*/
public static final int DB_DIALECT_MYSQL = DBConstants.DB_DIALECT_MYSQL.hashCode();
@@ -100,19 +119,32 @@
*/
public static void backup(File storageDir, Connection jdbcConn, Map<String, String> scripts) throws BackupException
{
+ Exception exc = null;
+
+ ObjectZipWriterImpl contentWriter = null;
+ ObjectZipWriterImpl contentLenWriter = null;
+
try
{
+ contentWriter =
+ new ObjectZipWriterImpl(PrivilegedFileHelper.zipOutputStream(new File(storageDir, CONTENT_ZIP_FILE)));
+
+ contentLenWriter =
+ new ObjectZipWriterImpl(PrivilegedFileHelper.zipOutputStream(new File(storageDir, CONTENT_LEN_ZIP_FILE)));
+
for (Entry<String, String> entry : scripts.entrySet())
{
- dumpTable(jdbcConn, entry.getKey(), entry.getValue(), storageDir);
+ dumpTable(jdbcConn, entry.getKey(), entry.getValue(), storageDir, contentWriter, contentLenWriter);
}
}
catch (IOException e)
{
+ exc = e;
throw new BackupException(e);
}
catch (SQLException e)
{
+ exc = e;
throw new BackupException("SQL Exception: " + ExceptionManagementHelper.getFullSQLExceptionMessage(e), e);
}
finally
@@ -125,6 +157,39 @@
}
catch (SQLException e)
{
+ if (exc != null)
+ {
+ LOG.error("Can't close connection", e);
+ throw new BackupException(exc);
+ }
+ else
+ {
+ throw new BackupException(e);
+ }
+ }
+ }
+
+ try
+ {
+ if (contentWriter != null)
+ {
+ contentWriter.close();
+ }
+
+ if (contentLenWriter != null)
+ {
+ contentLenWriter.close();
+ }
+ }
+ catch (Exception e)
+ {
+ if (exc != null)
+ {
+ LOG.error("Can't close zip", e);
+ throw new BackupException(exc);
+ }
+ else
+ {
throw new BackupException(e);
}
}
@@ -137,8 +202,8 @@
* @throws IOException
* @throws SQLException
*/
- private static void dumpTable(Connection jdbcConn, String tableName, String script, File storageDir)
- throws IOException, SQLException
+ private static void dumpTable(Connection jdbcConn, String tableName, String script, File storageDir,
+ ObjectZipWriterImpl contentWriter, ObjectZipWriterImpl contentLenWriter) throws IOException, SQLException
{
// Need privileges
SecurityManager security = System.getSecurityManager();
@@ -147,18 +212,11 @@
security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
}
- ObjectZipWriterImpl contentWriter = null;
- ObjectZipWriterImpl contentLenWriter = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try
{
- File contentFile = new File(storageDir, tableName + CONTENT_FILE_SUFFIX);
- contentWriter = new ObjectZipWriterImpl(PrivilegedFileHelper.zipOutputStream(contentFile));
contentWriter.putNextEntry(new ZipEntry(tableName));
-
- File contentLenFile = new File(storageDir, tableName + CONTENT_LEN_FILE_SUFFIX);
- contentLenWriter = new ObjectZipWriterImpl(PrivilegedFileHelper.zipOutputStream(contentLenFile));
contentLenWriter.putNextEntry(new ZipEntry(tableName));
stmt = jdbcConn.prepareStatement(script);
@@ -212,21 +270,12 @@
}
}
}
+
+ contentWriter.closeEntry();
+ contentLenWriter.closeEntry();
}
finally
{
- if (contentWriter != null)
- {
- contentWriter.closeEntry();
- contentWriter.close();
- }
-
- if (contentLenWriter != null)
- {
- contentLenWriter.closeEntry();
- contentLenWriter.close();
- }
-
if (rs != null)
{
rs.close();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java 2011-10-04 09:03:41 UTC (rev 5016)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java 2011-10-04 09:57:12 UTC (rev 5017)
@@ -372,13 +372,33 @@
try
{
- contentReader = new ObjectZipReaderImpl(PrivilegedFileHelper.zipInputStream(restoreRule.getContentFile()));
- contentReader.getNextEntry();
+ File contentFile = new File(storageDir, restoreRule.getSrcTableName() + DBBackup.CONTENT_FILE_SUFFIX);
- contentLenReader =
- new ObjectZipReaderImpl(PrivilegedFileHelper.zipInputStream(restoreRule.getContentLenFile()));
- contentLenReader.getNextEntry();
+ // check old style backup format, when for every table was dedicated zip file
+ if (PrivilegedFileHelper.exists(contentFile))
+ {
+ contentReader = new ObjectZipReaderImpl(PrivilegedFileHelper.zipInputStream(contentFile));
+ contentReader.getNextEntry();
+ File contentLenFile =
+ new File(storageDir, restoreRule.getSrcTableName() + DBBackup.CONTENT_LEN_FILE_SUFFIX);
+
+ contentLenReader = new ObjectZipReaderImpl(PrivilegedFileHelper.zipInputStream(contentLenFile));
+ contentLenReader.getNextEntry();
+ }
+ else
+ {
+ contentFile = new File(storageDir, DBBackup.CONTENT_ZIP_FILE);
+ contentReader = new ObjectZipReaderImpl(PrivilegedFileHelper.zipInputStream(contentFile));
+
+ while (!contentReader.getNextEntry().getName().equals(restoreRule.getSrcTableName()));
+
+ File contentLenFile = new File(storageDir, DBBackup.CONTENT_LEN_ZIP_FILE);
+ contentLenReader = new ObjectZipReaderImpl(PrivilegedFileHelper.zipInputStream(contentLenFile));
+
+ while (!contentLenReader.getNextEntry().getName().equals(restoreRule.getSrcTableName()));
+ }
+
// get information about source table
int sourceColumnCount = contentReader.readInt();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/RestoreTableRule.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/RestoreTableRule.java 2011-10-04 09:03:41 UTC (rev 5016)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/RestoreTableRule.java 2011-10-04 09:57:12 UTC (rev 5017)
@@ -18,7 +18,6 @@
*/
package org.exoplatform.services.jcr.impl.backup.rdbms;
-import java.io.File;
import java.util.HashSet;
import java.util.Set;
@@ -28,10 +27,8 @@
*/
public class RestoreTableRule
{
- private File contentFile;
+ private String srcTableName;
- private File contentLenFile;
-
private Integer deleteColumnIndex = null;
private Integer skipColumnIndex = null;
@@ -52,26 +49,16 @@
private Boolean dstMultiDb = null;
- public File getContentFile()
+ public String getSrcTableName()
{
- return contentFile;
+ return srcTableName;
}
- public void setContentFile(File contentFile)
+ public void setSrcTableName(String srcTableName)
{
- this.contentFile = contentFile;
+ this.srcTableName = srcTableName;
}
- public File getContentLenFile()
- {
- return contentLenFile;
- }
-
- public void setContentLenFile(File contentLenFile)
- {
- this.contentLenFile = contentLenFile;
- }
-
public Integer getDeleteColumnIndex()
{
return deleteColumnIndex;
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-10-04 09:03:41 UTC (rev 5016)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-10-04 09:57:12 UTC (rev 5017)
@@ -1208,8 +1208,7 @@
restoreTableRule.setSrcMultiDb(srcMultiDb);
restoreTableRule.setDstContainerName(containerName);
restoreTableRule.setDstMultiDb(multiDb);
- restoreTableRule.setContentFile(new File(storageDir, srcTableName + DBBackup.CONTENT_FILE_SUFFIX));
- restoreTableRule.setContentLenFile(new File(storageDir, srcTableName + DBBackup.CONTENT_LEN_FILE_SUFFIX));
+ restoreTableRule.setSrcTableName(srcTableName);
if (multiDb)
{
@@ -1261,8 +1260,7 @@
restoreTableRule.setSrcMultiDb(srcMultiDb);
restoreTableRule.setDstContainerName(containerName);
restoreTableRule.setDstMultiDb(multiDb);
- restoreTableRule.setContentFile(new File(storageDir, srcTableName + DBBackup.CONTENT_FILE_SUFFIX));
- restoreTableRule.setContentLenFile(new File(storageDir, srcTableName + DBBackup.CONTENT_LEN_FILE_SUFFIX));
+ restoreTableRule.setSrcTableName(srcTableName);
// auto increment ID column
restoreTableRule.setSkipColumnIndex(0);
@@ -1285,8 +1283,7 @@
restoreTableRule.setSrcMultiDb(srcMultiDb);
restoreTableRule.setDstContainerName(containerName);
restoreTableRule.setDstMultiDb(multiDb);
- restoreTableRule.setContentFile(new File(storageDir, srcTableName + DBBackup.CONTENT_FILE_SUFFIX));
- restoreTableRule.setContentLenFile(new File(storageDir, srcTableName + DBBackup.CONTENT_LEN_FILE_SUFFIX));
+ restoreTableRule.setSrcTableName(srcTableName);
if (!multiDb || !srcMultiDb)
{
14 years, 7 months