mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-15 15:02:20 +00:00
Merged V3.1 to HEAD
13625: Fix ETHREEOH-1644 13634: Merged V2.2 to V3.1 13632: Preparation for fix of ETHREEOH-1663: ML Document Editions Broken by Upgrade to 3.1 13636: Fixed ETHREEOH-1663: ML Document Editions Broken by Upgrade to 3.1 13638: Fixed ETHREEOH-1665: Copy/pasting a Specialised Folder changes the assoc qname 13639: Fixed ETHREEOH-1663: ML Document Editions Broken by Upgrade to 3.1 13640: Fixed ETHREEOH-1672: Manage Multilingual Content JSP breaks when viewing all Related Content 13641: Fixed ETHREEOH-1657: Manage Multilingual Content fails with NPE when document was previously versionable 13774: Fix for ETHREEOH-1629 13775: Fix for ETHREEOH-1645 13784: SchemaBootstrap now auto-generates a mostly-canonical schema description on new DB and on upgrades 13804: Added option to finish schema bootstrap, dump schema structure and exit 13807: Further pretty formatting of schema dump ___________________________________________________________________ Modified: svn:mergeinfo Merged /alfresco/BRANCHES/V2.2:r13632 Merged /alfresco/BRANCHES/V3.1:r13625,13634,13636,13638-13641,13774-13775,13784,13804,13807 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13912 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -54,12 +54,19 @@
|
|||||||
<property name="updateSchema">
|
<property name="updateSchema">
|
||||||
<value>${db.schema.update}</value>
|
<value>${db.schema.update}</value>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="stopAfterSchemaBootstrap">
|
||||||
|
<value>${db.schema.stopAfterSchemaBootstrap}</value>
|
||||||
|
</property>
|
||||||
<property name="schemaUpdateLockRetryCount">
|
<property name="schemaUpdateLockRetryCount">
|
||||||
<value>${db.schema.update.lockRetryCount}</value>
|
<value>${db.schema.update.lockRetryCount}</value>
|
||||||
</property>
|
</property>
|
||||||
<property name="schemaUpdateLockRetryWaitSeconds">
|
<property name="schemaUpdateLockRetryWaitSeconds">
|
||||||
<value>${db.schema.update.lockRetryWaitSeconds}</value>
|
<value>${db.schema.update.lockRetryWaitSeconds}</value>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="preCreateScriptUrls">
|
||||||
|
<list>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
<property name="postCreateScriptUrls">
|
<property name="postCreateScriptUrls">
|
||||||
<list>
|
<list>
|
||||||
<value>classpath:alfresco/dbscripts/create/2.2/${db.script.dialect}/AlfrescoPostCreate-2.2-MappedFKIndexes.sql</value>
|
<value>classpath:alfresco/dbscripts/create/2.2/${db.script.dialect}/AlfrescoPostCreate-2.2-MappedFKIndexes.sql</value>
|
||||||
|
@@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
schema.update.msg.dialect_used=Schema managed by database dialect {0}.
|
schema.update.msg.dialect_used=Schema managed by database dialect {0}.
|
||||||
schema.update.msg.bypassing=Bypassing schema update checks.
|
schema.update.msg.bypassing=Bypassing schema update checks.
|
||||||
schema.update.msg.all_statements=All executed statements written to file {0}.
|
schema.update.msg.normalized_schema=Normalized schema dumped to file {0}.
|
||||||
|
schema.update.msg.normalized_schema_pre=Normalized schema (pre-bootstrap) dumped to file {0}.
|
||||||
|
schema.update.msg.normalized_schema_post=Normalized schema (post-bootstrap) dumped to file {0}.
|
||||||
|
schema.update.msg.all_statements=All executed statements: {0}.
|
||||||
schema.update.msg.no_changes=No changes were made to the schema.
|
schema.update.msg.no_changes=No changes were made to the schema.
|
||||||
schema.update.msg.executing_generated_script=Executing database script {0} (Generated).
|
schema.update.msg.executing_generated_script=Executing database script {0} (Generated).
|
||||||
schema.update.msg.executing_copied_script=Executing database script {0} (Copied from {1}).
|
schema.update.msg.executing_copied_script=Executing database script {0} (Copied from {1}).
|
||||||
@@ -12,6 +15,7 @@ schema.update.warn.dialect_unsupported=Alfresco should not be used with database
|
|||||||
schema.update.warn.dialect_hsql=Alfresco is using the HSQL default database. Please only use this while evaluating Alfresco, it is NOT recommended for production or deployment!
|
schema.update.warn.dialect_hsql=Alfresco is using the HSQL default database. Please only use this while evaluating Alfresco, it is NOT recommended for production or deployment!
|
||||||
schema.update.warn.dialect_derby=Alfresco is using the Apache Derby default database. Please only use this while evaluating Alfresco, it is NOT recommended for production or deployment!
|
schema.update.warn.dialect_derby=Alfresco is using the Apache Derby default database. Please only use this while evaluating Alfresco, it is NOT recommended for production or deployment!
|
||||||
schema.update.warn.dialect_substituting=The dialect ''{0}'' is being changed to ''{1}''.
|
schema.update.warn.dialect_substituting=The dialect ''{0}'' is being changed to ''{1}''.
|
||||||
|
schema.update.err.forced_stop=The property 'stopAfterSchemaBootstrap' has been set. The bootstrap process is being terminated.
|
||||||
schema.update.err.dialect_should_use=The dialect ''{0}'' is unsupported. Please use ''{1}'' instead.
|
schema.update.err.dialect_should_use=The dialect ''{0}'' is unsupported. Please use ''{1}'' instead.
|
||||||
schema.update.err.found_multiple=\nMore than one Alfresco schema was found when querying the database metadata.\n Limit the database user's permissions or set the 'hibernate.default_schema' property in 'custom-hibernate-dialect.properties'.
|
schema.update.err.found_multiple=\nMore than one Alfresco schema was found when querying the database metadata.\n Limit the database user's permissions or set the 'hibernate.default_schema' property in 'custom-hibernate-dialect.properties'.
|
||||||
schema.update.err.previous_failed=A previous schema upgrade failed or was not completed. Revert to the original database before attempting the upgrade again.
|
schema.update.err.previous_failed=A previous schema upgrade failed or was not completed. Revert to the original database before attempting the upgrade again.
|
||||||
|
@@ -79,6 +79,9 @@
|
|||||||
<property name="fileFolderService">
|
<property name="fileFolderService">
|
||||||
<ref bean="fileFolderService" />
|
<ref bean="fileFolderService" />
|
||||||
</property>
|
</property>
|
||||||
|
<property name="versionService">
|
||||||
|
<ref bean="versionService" />
|
||||||
|
</property>
|
||||||
<property name="policyBehaviourFilter">
|
<property name="policyBehaviourFilter">
|
||||||
<ref bean="policyBehaviourFilter" />
|
<ref bean="policyBehaviourFilter" />
|
||||||
</property>
|
</property>
|
||||||
|
@@ -171,6 +171,7 @@ lucene.commit.lock.timeout=100000
|
|||||||
lucene.lock.poll.interval=100
|
lucene.lock.poll.interval=100
|
||||||
|
|
||||||
# Database configuration
|
# Database configuration
|
||||||
|
db.schema.stopAfterSchemaBootstrap=false
|
||||||
db.schema.update=true
|
db.schema.update=true
|
||||||
db.schema.update.lockRetryCount=24
|
db.schema.update.lockRetryCount=24
|
||||||
db.schema.update.lockRetryWaitSeconds=5
|
db.schema.update.lockRetryWaitSeconds=5
|
||||||
|
@@ -43,6 +43,7 @@ import java.util.List;
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.i18n.I18NUtil;
|
||||||
import org.alfresco.repo.admin.patch.Patch;
|
import org.alfresco.repo.admin.patch.Patch;
|
||||||
import org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch;
|
import org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch;
|
||||||
import org.alfresco.repo.content.filestore.FileContentWriter;
|
import org.alfresco.repo.content.filestore.FileContentWriter;
|
||||||
@@ -58,6 +59,7 @@ import org.alfresco.util.AbstractLifecycleBean;
|
|||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
import org.alfresco.util.LogUtil;
|
import org.alfresco.util.LogUtil;
|
||||||
import org.alfresco.util.TempFileProvider;
|
import org.alfresco.util.TempFileProvider;
|
||||||
|
import org.alfresco.util.schemadump.Main;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
@@ -101,6 +103,9 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
|
|
||||||
private static final String MSG_DIALECT_USED = "schema.update.msg.dialect_used";
|
private static final String MSG_DIALECT_USED = "schema.update.msg.dialect_used";
|
||||||
private static final String MSG_BYPASSING_SCHEMA_UPDATE = "schema.update.msg.bypassing";
|
private static final String MSG_BYPASSING_SCHEMA_UPDATE = "schema.update.msg.bypassing";
|
||||||
|
private static final String MSG_NORMALIZED_SCHEMA = "schema.update.msg.normalized_schema";
|
||||||
|
private static final String MSG_NORMALIZED_SCHEMA_PRE = "schema.update.msg.normalized_schema_pre";
|
||||||
|
private static final String MSG_NORMALIZED_SCHEMA_POST = "schema.update.msg.normalized_schema_post";
|
||||||
private static final String MSG_NO_CHANGES = "schema.update.msg.no_changes";
|
private static final String MSG_NO_CHANGES = "schema.update.msg.no_changes";
|
||||||
private static final String MSG_ALL_STATEMENTS = "schema.update.msg.all_statements";
|
private static final String MSG_ALL_STATEMENTS = "schema.update.msg.all_statements";
|
||||||
private static final String MSG_EXECUTING_GENERATED_SCRIPT = "schema.update.msg.executing_generated_script";
|
private static final String MSG_EXECUTING_GENERATED_SCRIPT = "schema.update.msg.executing_generated_script";
|
||||||
@@ -111,6 +116,7 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
private static final String WARN_DIALECT_SUBSTITUTING = "schema.update.warn.dialect_substituting";
|
private static final String WARN_DIALECT_SUBSTITUTING = "schema.update.warn.dialect_substituting";
|
||||||
private static final String WARN_DIALECT_HSQL = "schema.update.warn.dialect_hsql";
|
private static final String WARN_DIALECT_HSQL = "schema.update.warn.dialect_hsql";
|
||||||
private static final String WARN_DIALECT_DERBY = "schema.update.warn.dialect_derby";
|
private static final String WARN_DIALECT_DERBY = "schema.update.warn.dialect_derby";
|
||||||
|
private static final String ERR_FORCED_STOP = "schema.update.err.forced_stop";
|
||||||
private static final String ERR_DIALECT_SHOULD_USE = "schema.update.err.dialect_should_use";
|
private static final String ERR_DIALECT_SHOULD_USE = "schema.update.err.dialect_should_use";
|
||||||
private static final String ERR_MULTIPLE_SCHEMAS = "schema.update.err.found_multiple";
|
private static final String ERR_MULTIPLE_SCHEMAS = "schema.update.err.found_multiple";
|
||||||
private static final String ERR_PREVIOUS_FAILED_BOOTSTRAP = "schema.update.err.previous_failed";
|
private static final String ERR_PREVIOUS_FAILED_BOOTSTRAP = "schema.update.err.previous_failed";
|
||||||
@@ -156,6 +162,8 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
private LocalSessionFactoryBean localSessionFactory;
|
private LocalSessionFactoryBean localSessionFactory;
|
||||||
private String schemaOuputFilename;
|
private String schemaOuputFilename;
|
||||||
private boolean updateSchema;
|
private boolean updateSchema;
|
||||||
|
private boolean stopAfterSchemaBootstrap;
|
||||||
|
private List<String> preCreateScriptUrls;
|
||||||
private List<String> postCreateScriptUrls;
|
private List<String> postCreateScriptUrls;
|
||||||
private List<SchemaUpgradeScriptPatch> validateUpdateScriptPatches;
|
private List<SchemaUpgradeScriptPatch> validateUpdateScriptPatches;
|
||||||
private List<SchemaUpgradeScriptPatch> preUpdateScriptPatches;
|
private List<SchemaUpgradeScriptPatch> preUpdateScriptPatches;
|
||||||
@@ -168,6 +176,7 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
|
|
||||||
public SchemaBootstrap()
|
public SchemaBootstrap()
|
||||||
{
|
{
|
||||||
|
preCreateScriptUrls = new ArrayList<String>(1);
|
||||||
postCreateScriptUrls = new ArrayList<String>(1);
|
postCreateScriptUrls = new ArrayList<String>(1);
|
||||||
validateUpdateScriptPatches = new ArrayList<SchemaUpgradeScriptPatch>(4);
|
validateUpdateScriptPatches = new ArrayList<SchemaUpgradeScriptPatch>(4);
|
||||||
preUpdateScriptPatches = new ArrayList<SchemaUpgradeScriptPatch>(4);
|
preUpdateScriptPatches = new ArrayList<SchemaUpgradeScriptPatch>(4);
|
||||||
@@ -207,7 +216,34 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the scripts that must be executed after the schema has been created.
|
* Set whether this component should terminate the bootstrap process after running all the
|
||||||
|
* usual checks and scripts. This has the additional effect of dumping a final schema
|
||||||
|
* structure file just before exiting.
|
||||||
|
* <p>
|
||||||
|
* <b>WARNING: </b>USE FOR DEBUG AND UPGRADE TESTING ONLY
|
||||||
|
*
|
||||||
|
* @param stopAfterSchemaBootstrap <tt>true</tt> to terminate (with exception) after
|
||||||
|
* running all the usual schema updates and checks.
|
||||||
|
*/
|
||||||
|
public void setStopAfterSchemaBootstrap(boolean stopAfterSchemaBootstrap)
|
||||||
|
{
|
||||||
|
this.stopAfterSchemaBootstrap = stopAfterSchemaBootstrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the scripts that must be executed <b>before</b> the schema has been created.
|
||||||
|
*
|
||||||
|
* @param postCreateScriptUrls file URLs
|
||||||
|
*
|
||||||
|
* @see #PLACEHOLDER_SCRIPT_DIALECT
|
||||||
|
*/
|
||||||
|
public void setPreCreateScriptUrls(List<String> preUpdateScriptUrls)
|
||||||
|
{
|
||||||
|
this.preCreateScriptUrls = preUpdateScriptUrls;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the scripts that must be executed <b>after</b> the schema has been created.
|
||||||
*
|
*
|
||||||
* @param postCreateScriptUrls file URLs
|
* @param postCreateScriptUrls file URLs
|
||||||
*
|
*
|
||||||
@@ -345,6 +381,23 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
{
|
{
|
||||||
private static final long serialVersionUID = 5574280159910824660L;
|
private static final long serialVersionUID = 5574280159910824660L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to indicate a forced stop of the bootstrap.
|
||||||
|
*
|
||||||
|
* @see SchemaBootstrap#setStopAfterSchemaBootstrap(boolean)
|
||||||
|
*
|
||||||
|
* @author Derek Hulley
|
||||||
|
* @since 3.1.1
|
||||||
|
*/
|
||||||
|
private static class BootstrapStopException extends RuntimeException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 4250016675538442181L;
|
||||||
|
private BootstrapStopException()
|
||||||
|
{
|
||||||
|
super(I18NUtil.getMessage(ERR_FORCED_STOP));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count applied patches. This fails if multiple applied patch tables are found,
|
* Count applied patches. This fails if multiple applied patch tables are found,
|
||||||
@@ -618,13 +671,18 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
}
|
}
|
||||||
// Get the dialect
|
// Get the dialect
|
||||||
final Dialect dialect = Dialect.getDialect(cfg.getProperties());
|
final Dialect dialect = Dialect.getDialect(cfg.getProperties());
|
||||||
String dialectStr = dialect.getClass().getName();
|
String dialectStr = dialect.getClass().getSimpleName();
|
||||||
|
|
||||||
if (create)
|
if (create)
|
||||||
{
|
{
|
||||||
|
// execute pre-create scripts (not patches)
|
||||||
|
for (String scriptUrl : this.preCreateScriptUrls)
|
||||||
|
{
|
||||||
|
executeScriptUrl(cfg, connection, scriptUrl);
|
||||||
|
}
|
||||||
// the applied patch table is missing - we assume that all other tables are missing
|
// the applied patch table is missing - we assume that all other tables are missing
|
||||||
// perform a full update using Hibernate-generated statements
|
// perform a full update using Hibernate-generated statements
|
||||||
File tempFile = TempFileProvider.createTempFile("AlfrescoSchemaCreate-" + dialectStr + "-", ".sql");
|
File tempFile = TempFileProvider.createTempFile("AlfrescoSchema-" + dialectStr + "-Update-", ".sql");
|
||||||
SchemaBootstrap.dumpSchemaCreate(cfg, tempFile);
|
SchemaBootstrap.dumpSchemaCreate(cfg, tempFile);
|
||||||
executeScriptFile(cfg, connection, tempFile, null);
|
executeScriptFile(cfg, connection, tempFile, null);
|
||||||
// execute post-create scripts (not patches)
|
// execute post-create scripts (not patches)
|
||||||
@@ -649,7 +707,7 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
String[] sqls = cfg.generateSchemaUpdateScript(dialect, metadata);
|
String[] sqls = cfg.generateSchemaUpdateScript(dialect, metadata);
|
||||||
if (sqls.length > 0)
|
if (sqls.length > 0)
|
||||||
{
|
{
|
||||||
tempFile = TempFileProvider.createTempFile("AlfrescoSchemaUpdate-" + dialectStr + "-", ".sql");
|
tempFile = TempFileProvider.createTempFile("AlfrescoSchema-" + dialectStr + "-Update-", ".sql");
|
||||||
writer = new BufferedWriter(new FileWriter(tempFile));
|
writer = new BufferedWriter(new FileWriter(tempFile));
|
||||||
for (String sql : sqls)
|
for (String sql : sqls)
|
||||||
{
|
{
|
||||||
@@ -743,7 +801,7 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
private void executeScriptUrl(Configuration cfg, Connection connection, String scriptUrl) throws Exception
|
private void executeScriptUrl(Configuration cfg, Connection connection, String scriptUrl) throws Exception
|
||||||
{
|
{
|
||||||
Dialect dialect = Dialect.getDialect(cfg.getProperties());
|
Dialect dialect = Dialect.getDialect(cfg.getProperties());
|
||||||
String dialectStr = dialect.getClass().getName();
|
String dialectStr = dialect.getClass().getSimpleName();
|
||||||
InputStream scriptInputStream = getScriptInputStream(dialect.getClass(), scriptUrl);
|
InputStream scriptInputStream = getScriptInputStream(dialect.getClass(), scriptUrl);
|
||||||
// check that it exists
|
// check that it exists
|
||||||
if (scriptInputStream == null)
|
if (scriptInputStream == null)
|
||||||
@@ -754,7 +812,7 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
File tempFile = null;
|
File tempFile = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
tempFile = TempFileProvider.createTempFile("AlfrescoSchemaUpdate-" + dialectStr + "-", ".sql");
|
tempFile = TempFileProvider.createTempFile("AlfrescoSchema-" + dialectStr + "-Update-", ".sql");
|
||||||
ContentWriter writer = new FileContentWriter(tempFile);
|
ContentWriter writer = new FileContentWriter(tempFile);
|
||||||
writer.putContent(scriptInputStream);
|
writer.putContent(scriptInputStream);
|
||||||
}
|
}
|
||||||
@@ -1115,6 +1173,15 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
// Update the schema, if required.
|
// Update the schema, if required.
|
||||||
if (updateSchema)
|
if (updateSchema)
|
||||||
{
|
{
|
||||||
|
// Dump the normalized, pre-upgrade Alfresco schema. We keep the file for later reporting.
|
||||||
|
File xmlPreSchemaOutputFile = dumpSchema(
|
||||||
|
connection,
|
||||||
|
dialect,
|
||||||
|
TempFileProvider.createTempFile(
|
||||||
|
"AlfrescoSchema-" + dialect.getClass().getSimpleName() + "-",
|
||||||
|
"-Startup.xml").getPath(),
|
||||||
|
"Failed to dump normalized, pre-upgrade schema to file.");
|
||||||
|
|
||||||
// Retries are required here as the DB lock will be applied lazily upon first statement execution.
|
// Retries are required here as the DB lock will be applied lazily upon first statement execution.
|
||||||
// So if the schema is up to date (no statements executed) then the LockFailException cannot be
|
// So if the schema is up to date (no statements executed) then the LockFailException cannot be
|
||||||
// thrown. If it is thrown, the the update needs to be rerun as it will probably generate no SQL
|
// thrown. If it is thrown, the the update needs to be rerun as it will probably generate no SQL
|
||||||
@@ -1150,8 +1217,11 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
schemaOutputFile = TempFileProvider.createTempFile("AlfrescoSchemaUpdate-All_Statements-", ".sql");
|
schemaOutputFile = TempFileProvider.createTempFile(
|
||||||
|
"AlfrescoSchema-" + dialect.getClass().getSimpleName() + "-All_Statements-",
|
||||||
|
".sql");
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder executedStatements = executedStatementsThreadLocal.get();
|
StringBuilder executedStatements = executedStatementsThreadLocal.get();
|
||||||
if (executedStatements == null)
|
if (executedStatements == null)
|
||||||
{
|
{
|
||||||
@@ -1179,11 +1249,61 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
// Remove the flag indicating a running bootstrap
|
// Remove the flag indicating a running bootstrap
|
||||||
setBootstrapCompleted(connection);
|
setBootstrapCompleted(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dump the normalized, post-upgrade Alfresco schema.
|
||||||
|
File xmlPostSchemaOutputFile = dumpSchema(
|
||||||
|
connection,
|
||||||
|
dialect,
|
||||||
|
TempFileProvider.createTempFile(
|
||||||
|
"AlfrescoSchema-" + dialect.getClass().getSimpleName() + "-",
|
||||||
|
".xml").getPath(),
|
||||||
|
"Failed to dump normalized, post-upgrade schema to file.");
|
||||||
|
|
||||||
|
// Report normalized dumps
|
||||||
|
if (createdSchema)
|
||||||
|
{
|
||||||
|
// This is a new schema
|
||||||
|
if (xmlPostSchemaOutputFile != null)
|
||||||
|
{
|
||||||
|
LogUtil.info(logger, MSG_NORMALIZED_SCHEMA, xmlPostSchemaOutputFile.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (executedStatements != null)
|
||||||
|
{
|
||||||
|
// We upgraded, so have to report pre- and post- schema dumps
|
||||||
|
if (xmlPreSchemaOutputFile != null)
|
||||||
|
{
|
||||||
|
LogUtil.info(logger, MSG_NORMALIZED_SCHEMA_PRE, xmlPreSchemaOutputFile.getPath());
|
||||||
|
}
|
||||||
|
if (xmlPostSchemaOutputFile != null)
|
||||||
|
{
|
||||||
|
LogUtil.info(logger, MSG_NORMALIZED_SCHEMA_POST, xmlPostSchemaOutputFile.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogUtil.info(logger, MSG_BYPASSING_SCHEMA_UPDATE);
|
LogUtil.info(logger, MSG_BYPASSING_SCHEMA_UPDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stopAfterSchemaBootstrap)
|
||||||
|
{
|
||||||
|
// We have been forced to stop, so we do one last dump of the schema and throw an exception to
|
||||||
|
// escape further startup procedures
|
||||||
|
File xmlStopSchemaOutputFile = dumpSchema(
|
||||||
|
connection,
|
||||||
|
dialect,
|
||||||
|
TempFileProvider.createTempFile(
|
||||||
|
"AlfrescoSchema-" + dialect.getClass().getSimpleName() + "-",
|
||||||
|
"-ForcedExit.xml").getPath(),
|
||||||
|
"Failed to dump normalized, post-upgrade, forced-exit schema to file.");
|
||||||
|
if (xmlStopSchemaOutputFile != null)
|
||||||
|
{
|
||||||
|
LogUtil.info(logger, MSG_NORMALIZED_SCHEMA, xmlStopSchemaOutputFile);
|
||||||
|
}
|
||||||
|
LogUtil.error(logger, ERR_FORCED_STOP);
|
||||||
|
throw new BootstrapStopException();
|
||||||
|
}
|
||||||
|
|
||||||
// Reset the configuration
|
// Reset the configuration
|
||||||
cfg.setProperty(Environment.CONNECTION_PROVIDER, defaultConnectionProviderFactoryClass);
|
cfg.setProperty(Environment.CONNECTION_PROVIDER, defaultConnectionProviderFactoryClass);
|
||||||
@@ -1191,6 +1311,11 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
// all done successfully
|
// all done successfully
|
||||||
((ApplicationContext) event.getSource()).publishEvent(new SchemaAvailableEvent(this));
|
((ApplicationContext) event.getSource()).publishEvent(new SchemaAvailableEvent(this));
|
||||||
}
|
}
|
||||||
|
catch (BootstrapStopException e)
|
||||||
|
{
|
||||||
|
// We just let this out
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
catch (Throwable e)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
LogUtil.error(logger, e, ERR_UPDATE_FAILED);
|
LogUtil.error(logger, e, ERR_UPDATE_FAILED);
|
||||||
@@ -1221,6 +1346,33 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the file that was written to or <tt>null</tt> if it failed
|
||||||
|
*/
|
||||||
|
private File dumpSchema(Connection connection, Dialect dialect, String fileName, String err)
|
||||||
|
{
|
||||||
|
File xmlSchemaOutputFile = new File(fileName);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Main xmlSchemaOutputMain = new Main(connection, dialect);
|
||||||
|
xmlSchemaOutputMain.execute(xmlSchemaOutputFile);
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
xmlSchemaOutputFile = null;
|
||||||
|
// Don't fail the upgrade on this
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug(err, e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.error(err + " Error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return xmlSchemaOutputFile;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onShutdown(ApplicationEvent event)
|
protected void onShutdown(ApplicationEvent event)
|
||||||
|
@@ -544,6 +544,8 @@ public class FileFolderServiceImpl implements FileFolderService
|
|||||||
newName = beforeFileInfo.getName();
|
newName = beforeFileInfo.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean nameChanged = (newName.equals(beforeFileInfo.getName()) == false);
|
||||||
|
|
||||||
// we need the current association type
|
// we need the current association type
|
||||||
ChildAssociationRef assocRef = nodeService.getPrimaryParent(sourceNodeRef);
|
ChildAssociationRef assocRef = nodeService.getPrimaryParent(sourceNodeRef);
|
||||||
if (targetParentRef == null)
|
if (targetParentRef == null)
|
||||||
@@ -570,9 +572,21 @@ public class FileFolderServiceImpl implements FileFolderService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QName qname = QName.createQName(
|
QName qname;
|
||||||
NamespaceService.CONTENT_MODEL_1_0_URI,
|
if (nameChanged)
|
||||||
QName.createValidLocalName(newName));
|
{
|
||||||
|
// Change the localname to match the new name
|
||||||
|
qname = QName.createQName(
|
||||||
|
assocRef.getQName().getNamespaceURI(),
|
||||||
|
QName.createValidLocalName(newName));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Keep the localname
|
||||||
|
qname = QName.createQName(
|
||||||
|
assocRef.getQName().getNamespaceURI(),
|
||||||
|
assocRef.getQName().getLocalName());
|
||||||
|
}
|
||||||
|
|
||||||
QName targetParentType = nodeService.getType(targetParentRef);
|
QName targetParentType = nodeService.getType(targetParentRef);
|
||||||
|
|
||||||
|
@@ -46,6 +46,7 @@ import org.alfresco.service.cmr.model.FileNotFoundException;
|
|||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.cmr.version.Version;
|
import org.alfresco.service.cmr.version.Version;
|
||||||
import org.alfresco.service.cmr.version.VersionHistory;
|
import org.alfresco.service.cmr.version.VersionHistory;
|
||||||
import org.alfresco.service.cmr.version.VersionService;
|
import org.alfresco.service.cmr.version.VersionService;
|
||||||
@@ -222,6 +223,11 @@ public class EditionServiceImpl implements EditionService
|
|||||||
public Map<QName, Serializable> getVersionedMetadatas(Version version)
|
public Map<QName, Serializable> getVersionedMetadatas(Version version)
|
||||||
{
|
{
|
||||||
NodeRef frozenNodeRef = version.getFrozenStateNodeRef();
|
NodeRef frozenNodeRef = version.getFrozenStateNodeRef();
|
||||||
|
if (frozenNodeRef.getStoreRef().getIdentifier().equals("lightWeightVersionStore"))
|
||||||
|
{
|
||||||
|
// The data stored belonged to the old version store
|
||||||
|
Map<String, Serializable> versionProps = version.getVersionProperties();
|
||||||
|
}
|
||||||
|
|
||||||
if(ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(nodeService.getType(frozenNodeRef)))
|
if(ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(nodeService.getType(frozenNodeRef)))
|
||||||
{
|
{
|
||||||
|
@@ -51,6 +51,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
|
import org.alfresco.service.cmr.version.VersionService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
@@ -89,6 +90,7 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
|||||||
private PermissionService permissionService;
|
private PermissionService permissionService;
|
||||||
private ContentFilterLanguagesService contentFilterLanguagesService;
|
private ContentFilterLanguagesService contentFilterLanguagesService;
|
||||||
private FileFolderService fileFolderService;
|
private FileFolderService fileFolderService;
|
||||||
|
private VersionService versionService;
|
||||||
|
|
||||||
private BehaviourFilter policyBehaviourFilter;
|
private BehaviourFilter policyBehaviourFilter;
|
||||||
|
|
||||||
@@ -259,6 +261,11 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
|||||||
|
|
||||||
private NodeRef makeTranslationImpl(NodeRef mlContainerNodeRef, NodeRef contentNodeRef, Locale locale)
|
private NodeRef makeTranslationImpl(NodeRef mlContainerNodeRef, NodeRef contentNodeRef, Locale locale)
|
||||||
{
|
{
|
||||||
|
// Previous versions of the document are not compatible with the versioning requirements
|
||||||
|
// dictated by the aspects about to be added. A version has to be forced if the aspect
|
||||||
|
// already exists.
|
||||||
|
// https://issues.alfresco.com/jira/browse/ETHREEOH-1657
|
||||||
|
boolean forceNewVersion = nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE);
|
||||||
// Add the aspect using the given locale, of necessary
|
// Add the aspect using the given locale, of necessary
|
||||||
if (!nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
|
if (!nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
|
||||||
{
|
{
|
||||||
@@ -272,6 +279,11 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
|||||||
// The aspect is present, so just ensure that the locale is correct
|
// The aspect is present, so just ensure that the locale is correct
|
||||||
nodeService.setProperty(contentNodeRef, ContentModel.PROP_LOCALE, locale);
|
nodeService.setProperty(contentNodeRef, ContentModel.PROP_LOCALE, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (forceNewVersion)
|
||||||
|
{
|
||||||
|
versionService.createVersion(contentNodeRef, null);
|
||||||
|
}
|
||||||
|
|
||||||
// Do we make use of an existing container?
|
// Do we make use of an existing container?
|
||||||
if (mlContainerNodeRef == null)
|
if (mlContainerNodeRef == null)
|
||||||
@@ -963,6 +975,11 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
|||||||
this.fileFolderService = fileFolderService;
|
this.fileFolderService = fileFolderService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setVersionService(VersionService versionService)
|
||||||
|
{
|
||||||
|
this.versionService = versionService;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPolicyBehaviourFilter(BehaviourFilter policyBehaviourFilter)
|
public void setPolicyBehaviourFilter(BehaviourFilter policyBehaviourFilter)
|
||||||
{
|
{
|
||||||
this.policyBehaviourFilter = policyBehaviourFilter;
|
this.policyBehaviourFilter = policyBehaviourFilter;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -28,6 +28,7 @@ import java.io.InputStream;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -122,7 +123,6 @@ public abstract class BaseVersionStoreTest extends BaseSpringTest
|
|||||||
* Test user details
|
* Test user details
|
||||||
*/
|
*/
|
||||||
private static final String PWD = "admin";
|
private static final String PWD = "admin";
|
||||||
// private static final String USER_NAME = "admin";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the meta model dao
|
* Sets the meta model dao
|
||||||
@@ -254,6 +254,11 @@ public abstract class BaseVersionStoreTest extends BaseSpringTest
|
|||||||
ContentWriter contentWriter = this.contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
ContentWriter contentWriter = this.contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
||||||
contentWriter.putContent(TEST_CONTENT);
|
contentWriter.putContent(TEST_CONTENT);
|
||||||
|
|
||||||
|
// Set author
|
||||||
|
Map<QName, Serializable> authorProps = new HashMap<QName, Serializable>(1, 1.0f);
|
||||||
|
authorProps.put(ContentModel.PROP_AUTHOR, "Charles Dickens");
|
||||||
|
this.dbNodeService.addAspect(nodeRef, ContentModel.ASPECT_AUTHOR, authorProps);
|
||||||
|
|
||||||
// Add some children to the node
|
// Add some children to the node
|
||||||
NodeRef child1 = this.dbNodeService.createNode(
|
NodeRef child1 = this.dbNodeService.createNode(
|
||||||
nodeRef,
|
nodeRef,
|
||||||
@@ -323,8 +328,8 @@ public abstract class BaseVersionStoreTest extends BaseSpringTest
|
|||||||
int nextVersion = peekNextVersionNumber();
|
int nextVersion = peekNextVersionNumber();
|
||||||
String nextVersionLabel = peekNextVersionLabel(versionableNode, nextVersion, versionProperties);
|
String nextVersionLabel = peekNextVersionLabel(versionableNode, nextVersion, versionProperties);
|
||||||
|
|
||||||
// Snap-shot the date-time
|
// Snap-shot the node created date-time
|
||||||
long beforeVersionTime = System.currentTimeMillis();
|
long beforeVersionTime = ((Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED)).getTime();
|
||||||
|
|
||||||
// Now lets create a new version for this node
|
// Now lets create a new version for this node
|
||||||
Version newVersion = versionService.createVersion(versionableNode, this.versionProperties);
|
Version newVersion = versionService.createVersion(versionableNode, this.versionProperties);
|
||||||
@@ -340,8 +345,8 @@ public abstract class BaseVersionStoreTest extends BaseSpringTest
|
|||||||
int nextVersion = peekNextVersionNumber();
|
int nextVersion = peekNextVersionNumber();
|
||||||
String nextVersionLabel = peekNextVersionLabel(versionableNode, nextVersion, versionProperties);
|
String nextVersionLabel = peekNextVersionLabel(versionableNode, nextVersion, versionProperties);
|
||||||
|
|
||||||
// Snap-shot the date-time
|
// Snap-shot the node created date-time
|
||||||
long beforeVersionTime = System.currentTimeMillis();
|
long beforeVersionTime = ((Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED)).getTime();
|
||||||
|
|
||||||
// Now lets create new version for this node (optionally with children)
|
// Now lets create new version for this node (optionally with children)
|
||||||
Collection<Version> versions = versionService.createVersion(versionableNode, this.versionProperties, versionChildren);
|
Collection<Version> versions = versionService.createVersion(versionableNode, this.versionProperties, versionChildren);
|
||||||
|
@@ -110,9 +110,6 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe
|
|||||||
return new StoreRef(StoreRef.PROTOCOL_WORKSPACE, Version2Model.STORE_ID);
|
return new StoreRef(StoreRef.PROTOCOL_WORKSPACE, Version2Model.STORE_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.alfresco.repo.service.cmr.version.VersionService#createVersion(org.alfresco.service.cmr.repository.NodeRef, java.util.Map)
|
|
||||||
*/
|
|
||||||
public Version createVersion(
|
public Version createVersion(
|
||||||
NodeRef nodeRef,
|
NodeRef nodeRef,
|
||||||
Map<String, Serializable> versionProperties)
|
Map<String, Serializable> versionProperties)
|
||||||
@@ -343,14 +340,11 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe
|
|||||||
|
|
||||||
VersionHistory versionHistory = null;
|
VersionHistory versionHistory = null;
|
||||||
|
|
||||||
// get version history, if the 'live' (versioned) node exists
|
// Get the version history regardless of whether the node is still 'live' or not
|
||||||
if (this.nodeService.exists(nodeRef) == true)
|
NodeRef versionHistoryRef = getVersionHistoryNodeRef(nodeRef);
|
||||||
|
if (versionHistoryRef != null)
|
||||||
{
|
{
|
||||||
NodeRef versionHistoryRef = getVersionHistoryNodeRef(nodeRef);
|
versionHistory = buildVersionHistory(versionHistoryRef, nodeRef);
|
||||||
if (versionHistoryRef != null)
|
|
||||||
{
|
|
||||||
versionHistory = buildVersionHistory(versionHistoryRef, nodeRef);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return versionHistory;
|
return versionHistory;
|
||||||
|
@@ -111,8 +111,8 @@ public class VersionMigratorTest extends BaseVersionStoreTest
|
|||||||
int nextVersion = peekNextVersionNumber();
|
int nextVersion = peekNextVersionNumber();
|
||||||
String nextVersionLabel = peekNextVersionLabel(versionableNode, nextVersion, versionProperties);
|
String nextVersionLabel = peekNextVersionLabel(versionableNode, nextVersion, versionProperties);
|
||||||
|
|
||||||
// Snap-shot the date-time
|
// Snap-shot the node created date-time
|
||||||
Date beforeVersionDate = new Date();
|
Date beforeVersionDate = (Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED);
|
||||||
long beforeVersionTime = beforeVersionDate.getTime();
|
long beforeVersionTime = beforeVersionDate.getTime();
|
||||||
logger.info("beforeVersion Date/Time: " + beforeVersionDate + " [" + beforeVersionTime + "]");
|
logger.info("beforeVersion Date/Time: " + beforeVersionDate + " [" + beforeVersionTime + "]");
|
||||||
|
|
||||||
@@ -205,7 +205,9 @@ public class VersionMigratorTest extends BaseVersionStoreTest
|
|||||||
// Get the next version number, next version label and snapshot the date-time
|
// Get the next version number, next version label and snapshot the date-time
|
||||||
int nextVersion1 = peekNextVersionNumber();
|
int nextVersion1 = peekNextVersionNumber();
|
||||||
String nextVersionLabel1 = peekNextVersionLabel(versionableNode, nextVersion1, versionProperties);
|
String nextVersionLabel1 = peekNextVersionLabel(versionableNode, nextVersion1, versionProperties);
|
||||||
long beforeVersionTime1 = System.currentTimeMillis();
|
|
||||||
|
// Snap-shot the node created date-time
|
||||||
|
long beforeVersionTime1 = ((Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED)).getTime();
|
||||||
|
|
||||||
Version version1 = createVersion(versionableNode);
|
Version version1 = createVersion(versionableNode);
|
||||||
logger.info(version1);
|
logger.info(version1);
|
||||||
@@ -213,7 +215,9 @@ public class VersionMigratorTest extends BaseVersionStoreTest
|
|||||||
// Get the next version number, next version label and snapshot the date-time
|
// Get the next version number, next version label and snapshot the date-time
|
||||||
int nextVersion2 = peekNextVersionNumber();
|
int nextVersion2 = peekNextVersionNumber();
|
||||||
String nextVersionLabel2 = peekNextVersionLabel(versionableNode, nextVersion2, versionProperties);
|
String nextVersionLabel2 = peekNextVersionLabel(versionableNode, nextVersion2, versionProperties);
|
||||||
long beforeVersionTime2 = System.currentTimeMillis();
|
|
||||||
|
// Snap-shot the node created date-time
|
||||||
|
long beforeVersionTime2 = ((Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED)).getTime();
|
||||||
|
|
||||||
Version version2 = createVersion(versionableNode);
|
Version version2 = createVersion(versionableNode);
|
||||||
logger.info(version2);
|
logger.info(version2);
|
||||||
@@ -221,7 +225,9 @@ public class VersionMigratorTest extends BaseVersionStoreTest
|
|||||||
// Get the next version number, next version label and snapshot the date-time
|
// Get the next version number, next version label and snapshot the date-time
|
||||||
int nextVersion3 = peekNextVersionNumber();
|
int nextVersion3 = peekNextVersionNumber();
|
||||||
String nextVersionLabel3 = peekNextVersionLabel(versionableNode, nextVersion3, versionProperties);
|
String nextVersionLabel3 = peekNextVersionLabel(versionableNode, nextVersion3, versionProperties);
|
||||||
long beforeVersionTime3 = System.currentTimeMillis();
|
|
||||||
|
// Snap-shot the node created date-time
|
||||||
|
long beforeVersionTime3 = ((Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED)).getTime();
|
||||||
|
|
||||||
Version version3 = createVersion(versionableNode);
|
Version version3 = createVersion(versionableNode);
|
||||||
logger.info(version3);
|
logger.info(version3);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -27,6 +27,7 @@ package org.alfresco.repo.version;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -144,7 +145,9 @@ public class VersionServiceImplTest extends BaseVersionStoreTest
|
|||||||
// Snap shot data
|
// Snap shot data
|
||||||
int expectedVersionNumber = peekNextVersionNumber();
|
int expectedVersionNumber = peekNextVersionNumber();
|
||||||
String expectedVersionLabel = peekNextVersionLabel(versionableNode, expectedVersionNumber, versionProperties);
|
String expectedVersionLabel = peekNextVersionLabel(versionableNode, expectedVersionNumber, versionProperties);
|
||||||
long beforeVersionTime = System.currentTimeMillis();
|
|
||||||
|
// Snap-shot the node created date-time
|
||||||
|
long beforeVersionTime = ((Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED)).getTime();
|
||||||
|
|
||||||
// Version the node and its children
|
// Version the node and its children
|
||||||
Collection<Version> versions = this.versionService.createVersion(
|
Collection<Version> versions = this.versionService.createVersion(
|
||||||
@@ -167,8 +170,10 @@ public class VersionServiceImplTest extends BaseVersionStoreTest
|
|||||||
|
|
||||||
// Snap shot data
|
// Snap shot data
|
||||||
int expectedVersionNumber = peekNextVersionNumber();
|
int expectedVersionNumber = peekNextVersionNumber();
|
||||||
String expectedVersionLabel = peekNextVersionLabel(versionableNode, expectedVersionNumber, versionProperties);
|
String expectedVersionLabel = peekNextVersionLabel(versionableNode, expectedVersionNumber, versionProperties);
|
||||||
long beforeVersionTime = System.currentTimeMillis();
|
|
||||||
|
// Snap-shot the node created date-time
|
||||||
|
long beforeVersionTime = ((Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED)).getTime();
|
||||||
|
|
||||||
// Version the list of nodes created
|
// Version the list of nodes created
|
||||||
Collection<Version> versions = this.versionService.createVersion(
|
Collection<Version> versions = this.versionService.createVersion(
|
||||||
|
@@ -24,7 +24,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.version.common;
|
package org.alfresco.repo.version.common;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.io.ObjectInputStream.GetField;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -45,9 +48,6 @@ import org.alfresco.util.VersionNumber;
|
|||||||
*/
|
*/
|
||||||
public class VersionHistoryImpl implements VersionHistory
|
public class VersionHistoryImpl implements VersionHistory
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* Serial version UID
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 3257001051558326840L;
|
private static final long serialVersionUID = 3257001051558326840L;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -56,9 +56,10 @@ public class VersionHistoryImpl implements VersionHistory
|
|||||||
private static final String ERR_MSG = "The root version must be specified when creating a version history object.";
|
private static final String ERR_MSG = "The root version must be specified when creating a version history object.";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The root version label
|
* Field is left here to aid in detection of old serialized versions
|
||||||
*/
|
*/
|
||||||
private String rootVersionLabel = null;
|
@SuppressWarnings("unused")
|
||||||
|
private transient List<Version> versions;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Version history tree structure map
|
* Version history tree structure map
|
||||||
@@ -74,7 +75,6 @@ public class VersionHistoryImpl implements VersionHistory
|
|||||||
* Versions ordered by creation date (descending)
|
* Versions ordered by creation date (descending)
|
||||||
*/
|
*/
|
||||||
private static Comparator<Version> versionComparatorDesc = new VersionComparatorDesc();
|
private static Comparator<Version> versionComparatorDesc = new VersionComparatorDesc();
|
||||||
private List<Version> versions = new ArrayList<Version>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Root version
|
* Root version
|
||||||
@@ -101,7 +101,6 @@ public class VersionHistoryImpl implements VersionHistory
|
|||||||
this.versionsByLabel = new HashMap<String, Version>();
|
this.versionsByLabel = new HashMap<String, Version>();
|
||||||
|
|
||||||
this.rootVersion = rootVersion;
|
this.rootVersion = rootVersion;
|
||||||
this.rootVersionLabel = rootVersion.getVersionLabel();
|
|
||||||
addVersion(rootVersion, null);
|
addVersion(rootVersion, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,8 +124,10 @@ public class VersionHistoryImpl implements VersionHistory
|
|||||||
*/
|
*/
|
||||||
public Collection<Version> getAllVersions()
|
public Collection<Version> getAllVersions()
|
||||||
{
|
{
|
||||||
Collections.sort(versions, versionComparatorDesc);
|
Collection<Version> versions = versionsByLabel.values();
|
||||||
return versions;
|
List<Version> sortedVersions = new ArrayList<Version>(versions);
|
||||||
|
Collections.sort(sortedVersions, versionComparatorDesc);
|
||||||
|
return sortedVersions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,7 +212,6 @@ public class VersionHistoryImpl implements VersionHistory
|
|||||||
// TODO cope with exception case where duplicate version labels have been specified
|
// TODO cope with exception case where duplicate version labels have been specified
|
||||||
|
|
||||||
this.versionsByLabel.put(version.getVersionLabel(), version);
|
this.versionsByLabel.put(version.getVersionLabel(), version);
|
||||||
this.versions.add(version);
|
|
||||||
|
|
||||||
if (predecessor != null)
|
if (predecessor != null)
|
||||||
{
|
{
|
||||||
@@ -222,7 +222,7 @@ public class VersionHistoryImpl implements VersionHistory
|
|||||||
/**
|
/**
|
||||||
* Version Comparator
|
* Version Comparator
|
||||||
*
|
*
|
||||||
* Note: Descending create date order
|
* Note: Descending (last modified) date order
|
||||||
*/
|
*/
|
||||||
public static class VersionComparatorDesc implements Comparator<Version>, Serializable
|
public static class VersionComparatorDesc implements Comparator<Version>, Serializable
|
||||||
{
|
{
|
||||||
@@ -230,7 +230,7 @@ public class VersionHistoryImpl implements VersionHistory
|
|||||||
|
|
||||||
public int compare(Version v1, Version v2)
|
public int compare(Version v1, Version v2)
|
||||||
{
|
{
|
||||||
int result = v2.getCreatedDate().compareTo(v1.getCreatedDate());
|
int result = v2.getFrozenModifiedDate().compareTo(v1.getFrozenModifiedDate());
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
result = new VersionNumber(v2.getVersionLabel()).compareTo(new VersionNumber(v1.getVersionLabel()));
|
result = new VersionNumber(v2.getVersionLabel()).compareTo(new VersionNumber(v1.getVersionLabel()));
|
||||||
@@ -242,7 +242,7 @@ public class VersionHistoryImpl implements VersionHistory
|
|||||||
/**
|
/**
|
||||||
* Version Comparator
|
* Version Comparator
|
||||||
*
|
*
|
||||||
* Note: Ascending create date order
|
* Note: Ascending (last modified) date order
|
||||||
*/
|
*/
|
||||||
public static class VersionComparatorAsc implements Comparator<Version>, Serializable
|
public static class VersionComparatorAsc implements Comparator<Version>, Serializable
|
||||||
{
|
{
|
||||||
@@ -250,7 +250,7 @@ public class VersionHistoryImpl implements VersionHistory
|
|||||||
|
|
||||||
public int compare(Version v1, Version v2)
|
public int compare(Version v1, Version v2)
|
||||||
{
|
{
|
||||||
int result = v1.getCreatedDate().compareTo(v2.getCreatedDate());
|
int result = v1.getFrozenModifiedDate().compareTo(v2.getFrozenModifiedDate());
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
result = new VersionNumber(v1.getVersionLabel()).compareTo(new VersionNumber(v2.getVersionLabel()));
|
result = new VersionNumber(v1.getVersionLabel()).compareTo(new VersionNumber(v2.getVersionLabel()));
|
||||||
@@ -259,4 +259,29 @@ public class VersionHistoryImpl implements VersionHistory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException
|
||||||
|
{
|
||||||
|
GetField fields = is.readFields();
|
||||||
|
if (fields.defaulted("versionsByLabel"))
|
||||||
|
{
|
||||||
|
// This is a V2.2 class
|
||||||
|
// The old 'rootVersion' maps to the current 'rootVersion'
|
||||||
|
this.rootVersion = (Version) fields.get("rootVersion", null);;
|
||||||
|
// The old 'versions' maps to the current 'versionsByLabel'
|
||||||
|
this.versionsByLabel = (HashMap<String, Version>) fields.get("versions", new HashMap<String, Version>());
|
||||||
|
// The old 'versionHistory' maps to the current 'versionHistory'
|
||||||
|
this.versionHistory = (HashMap<String, String>) fields.get("versionHistory", new HashMap<String, String>());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This is a V3.1.0 to ... class
|
||||||
|
// The old 'rootVersion' maps to the current 'rootVersion'
|
||||||
|
this.rootVersion = (Version) fields.get("rootVersion", null);
|
||||||
|
// The old 'versionsByLabel' maps to the current 'versionsByLabel'
|
||||||
|
this.versionsByLabel = (HashMap<String, Version>) fields.get("versionsByLabel", new HashMap<String, Version>());
|
||||||
|
// The old 'versionHistory' maps to the current 'versionHistory'
|
||||||
|
this.versionHistory = (HashMap<String, String>) fields.get("versionHistory", new HashMap<String, String>());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.version.common;
|
package org.alfresco.repo.version.common;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -37,6 +42,9 @@ import org.alfresco.service.cmr.repository.StoreRef;
|
|||||||
import org.alfresco.service.cmr.version.Version;
|
import org.alfresco.service.cmr.version.Version;
|
||||||
import org.alfresco.service.cmr.version.VersionDoesNotExistException;
|
import org.alfresco.service.cmr.version.VersionDoesNotExistException;
|
||||||
import org.alfresco.service.cmr.version.VersionServiceException;
|
import org.alfresco.service.cmr.version.VersionServiceException;
|
||||||
|
import org.alfresco.util.TempFileProvider;
|
||||||
|
import org.springframework.core.io.DefaultResourceLoader;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VersionHistoryImpl Unit Test Class
|
* VersionHistoryImpl Unit Test Class
|
||||||
@@ -208,6 +216,7 @@ public class VersionHistoryImplTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* Test getSuccessors
|
* Test getSuccessors
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public void testGetSuccessors()
|
public void testGetSuccessors()
|
||||||
{
|
{
|
||||||
VersionHistoryImpl vh = testAddVersionImpl();
|
VersionHistoryImpl vh = testAddVersionImpl();
|
||||||
@@ -260,4 +269,75 @@ public class VersionHistoryImplTest extends TestCase
|
|||||||
System.out.println("Error message: " + exception.getMessage());
|
System.out.println("Error message: " + exception.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that the current version can be serialized and deserialized.
|
||||||
|
*/
|
||||||
|
public void testSerialize() throws Exception
|
||||||
|
{
|
||||||
|
File file = TempFileProvider.createTempFile(getName(), ".bin");
|
||||||
|
System.out.println("Test " + getName() + " writing to " + file.getPath());
|
||||||
|
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(file));
|
||||||
|
|
||||||
|
VersionHistoryImpl vh = testAddVersionImpl();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
os.writeObject(vh);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try { os.close(); } catch (Throwable e) {}
|
||||||
|
}
|
||||||
|
ObjectInputStream is = new ObjectInputStream(new FileInputStream(file));
|
||||||
|
VersionHistoryImpl vhObj;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
vhObj = (VersionHistoryImpl) is.readObject();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try { is.close(); } catch (Throwable e) {}
|
||||||
|
}
|
||||||
|
assertNotNull(vhObj);
|
||||||
|
assertNotNull("No root version", vhObj.getRootVersion());
|
||||||
|
assertEquals(
|
||||||
|
"Deserialized object does not match original",
|
||||||
|
vh.getRootVersion().getFrozenStateNodeRef(),
|
||||||
|
vhObj.getRootVersion().getFrozenStateNodeRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String DESERIALIZE_V22SP4 = "classpath:version-history/VersionHistoryImplTest-testSerialize-V2.2.4.bin";
|
||||||
|
public static final String DESERIALIZE_V310_DEV = "classpath:version-history/VersionHistoryImplTest-testSerialize-V3.1.0-dev.bin";
|
||||||
|
public static final String DESERIALIZE_V310 = "classpath:version-history/VersionHistoryImplTest-testSerialize-V3.1.0.bin";
|
||||||
|
/**
|
||||||
|
* @see {@link #DESERIALIZE_V22SP4}
|
||||||
|
* @see {@link #DESERIALIZE_V310_DEV}
|
||||||
|
* @see {@link #DESERIALIZE_V310}
|
||||||
|
*/
|
||||||
|
public void testDeserializeV22SP4() throws Exception
|
||||||
|
{
|
||||||
|
String[] resourceLocations = new String[] {
|
||||||
|
DESERIALIZE_V22SP4,
|
||||||
|
DESERIALIZE_V310_DEV,
|
||||||
|
DESERIALIZE_V310
|
||||||
|
};
|
||||||
|
for (String resourceLocation : resourceLocations)
|
||||||
|
{
|
||||||
|
Resource resource = new DefaultResourceLoader().getResource(resourceLocation);
|
||||||
|
assertNotNull("Unable to find " + resourceLocation, resource);
|
||||||
|
assertTrue("Unable to find " + resourceLocation, resource.exists());
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
VersionHistoryImpl vhObj;
|
||||||
|
ObjectInputStream is = new ObjectInputStream(resource.getInputStream());
|
||||||
|
try
|
||||||
|
{
|
||||||
|
vhObj = (VersionHistoryImpl) is.readObject();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try { is.close(); } catch (Throwable e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -96,69 +96,61 @@ public class VersionImpl implements Version
|
|||||||
{
|
{
|
||||||
return versionProperties.toString();
|
return versionProperties.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Date getFrozenModifiedDate()
|
||||||
/**
|
{
|
||||||
* Helper method to get the created date from the version property data.
|
Date modifiedDate = (Date)this.versionProperties.get(Version2Model.PROP_FROZEN_MODIFIED);
|
||||||
*
|
if (modifiedDate == null)
|
||||||
* @return the date the version was created (note: not the date of the original node)
|
{
|
||||||
*/
|
// Assume deprecated V1 version store
|
||||||
|
modifiedDate = (Date)this.versionProperties.get(VersionBaseModel.PROP_CREATED_DATE);
|
||||||
|
}
|
||||||
|
return modifiedDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFrozenModifier()
|
||||||
|
{
|
||||||
|
String modifier = (String)this.versionProperties.get(Version2Model.PROP_FROZEN_MODIFIER);
|
||||||
|
if (modifier == null)
|
||||||
|
{
|
||||||
|
// Assume deprecated V1 version store
|
||||||
|
modifier = (String)this.versionProperties.get(VersionBaseModel.PROP_CREATOR);
|
||||||
|
}
|
||||||
|
return modifier;
|
||||||
|
}
|
||||||
|
|
||||||
public Date getCreatedDate()
|
public Date getCreatedDate()
|
||||||
{
|
{
|
||||||
return (Date)this.versionProperties.get(VersionBaseModel.PROP_CREATED_DATE);
|
// note: internal version node created date can be retrieved via standard node service
|
||||||
|
return getFrozenModifiedDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to get the creator from the version property data.
|
|
||||||
*
|
|
||||||
* @return the creator of the version (note: not the creator of the original node)
|
|
||||||
*/
|
|
||||||
public String getCreator()
|
public String getCreator()
|
||||||
{
|
{
|
||||||
return (String)this.versionProperties.get(VersionBaseModel.PROP_CREATOR);
|
// note: internal version node creator can be retrieved via standard node service
|
||||||
|
return getFrozenModifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to get the version label from the version property data.
|
|
||||||
*
|
|
||||||
* @return the version label
|
|
||||||
*/
|
|
||||||
public String getVersionLabel()
|
public String getVersionLabel()
|
||||||
{
|
{
|
||||||
return (String)this.versionProperties.get(VersionBaseModel.PROP_VERSION_LABEL);
|
return (String)this.versionProperties.get(VersionBaseModel.PROP_VERSION_LABEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to get the version type.
|
|
||||||
*
|
|
||||||
* @return the value of the version type as an enum value
|
|
||||||
*/
|
|
||||||
public VersionType getVersionType()
|
public VersionType getVersionType()
|
||||||
{
|
{
|
||||||
return (VersionType)this.versionProperties.get(VersionBaseModel.PROP_VERSION_TYPE);
|
return (VersionType)this.versionProperties.get(VersionBaseModel.PROP_VERSION_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to get the version description.
|
|
||||||
*
|
|
||||||
* @return the version description
|
|
||||||
*/
|
|
||||||
public String getDescription()
|
public String getDescription()
|
||||||
{
|
{
|
||||||
return (String)this.versionProperties.get(Version.PROP_DESCRIPTION);
|
return (String)this.versionProperties.get(Version.PROP_DESCRIPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.alfresco.service.cmr.version.Version#getVersionProperties()
|
|
||||||
*/
|
|
||||||
public Map<String, Serializable> getVersionProperties()
|
public Map<String, Serializable> getVersionProperties()
|
||||||
{
|
{
|
||||||
return this.versionProperties;
|
return this.versionProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.alfresco.service.cmr.version.Version#getVersionProperty(java.lang.String)
|
|
||||||
*/
|
|
||||||
public Serializable getVersionProperty(String name)
|
public Serializable getVersionProperty(String name)
|
||||||
{
|
{
|
||||||
Serializable result = null;
|
Serializable result = null;
|
||||||
@@ -169,9 +161,6 @@ public class VersionImpl implements Version
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.alfresco.service.cmr.version.Version#getVersionedNodeRef()
|
|
||||||
*/
|
|
||||||
public NodeRef getVersionedNodeRef()
|
public NodeRef getVersionedNodeRef()
|
||||||
{
|
{
|
||||||
NodeRef versionedNodeRef = null;
|
NodeRef versionedNodeRef = null;
|
||||||
@@ -193,10 +182,7 @@ public class VersionImpl implements Version
|
|||||||
|
|
||||||
return versionedNodeRef;
|
return versionedNodeRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.alfresco.service.cmr.version.Version#getFrozenStateNodeRef()
|
|
||||||
*/
|
|
||||||
public NodeRef getFrozenStateNodeRef()
|
public NodeRef getFrozenStateNodeRef()
|
||||||
{
|
{
|
||||||
return this.nodeRef;
|
return this.nodeRef;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -38,7 +38,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
* Allows access to version property values and frozen state node references.
|
* Allows access to version property values and frozen state node references.
|
||||||
* The version history tree can also be navigated.
|
* The version history tree can also be navigated.
|
||||||
*
|
*
|
||||||
* @author Roy Wetherall
|
* @author Roy Wetherall, janv
|
||||||
*/
|
*/
|
||||||
public interface Version extends Serializable
|
public interface Version extends Serializable
|
||||||
{
|
{
|
||||||
@@ -51,6 +51,7 @@ public interface Version extends Serializable
|
|||||||
* Helper method to get the created date from the version property data.
|
* Helper method to get the created date from the version property data.
|
||||||
*
|
*
|
||||||
* @return the date the version was created
|
* @return the date the version was created
|
||||||
|
* @deprecated use getFrozenModifiedDate
|
||||||
*/
|
*/
|
||||||
public Date getCreatedDate();
|
public Date getCreatedDate();
|
||||||
|
|
||||||
@@ -58,8 +59,24 @@ public interface Version extends Serializable
|
|||||||
* Helper method to get the creator of the version.
|
* Helper method to get the creator of the version.
|
||||||
*
|
*
|
||||||
* @return the creator of the version
|
* @return the creator of the version
|
||||||
|
* @deprecated use getFrozenModifier
|
||||||
*/
|
*/
|
||||||
public String getCreator();
|
public String getCreator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to get the frozen (original) modified date for this version of the node
|
||||||
|
*
|
||||||
|
* @return the modified date
|
||||||
|
*/
|
||||||
|
public Date getFrozenModifiedDate();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to get the frozen (original) modifier for this version of the node
|
||||||
|
*
|
||||||
|
* @return the modifier
|
||||||
|
*/
|
||||||
|
public String getFrozenModifier();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to get the version label from the version property data.
|
* Helper method to get the version label from the version property data.
|
||||||
|
@@ -70,7 +70,7 @@ public interface VersionService
|
|||||||
*
|
*
|
||||||
* @param nodeRef a node reference
|
* @param nodeRef a node reference
|
||||||
* @param versionProperties the version properties that are stored with the newly created
|
* @param versionProperties the version properties that are stored with the newly created
|
||||||
* version
|
* version, or <tt>null</tt> if there are no relevant properties
|
||||||
* @return the created version object
|
* @return the created version object
|
||||||
* @throws ReservedVersionNameException
|
* @throws ReservedVersionNameException
|
||||||
* thrown if a reserved property name is used int he version properties
|
* thrown if a reserved property name is used int he version properties
|
||||||
|
@@ -24,13 +24,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.util.schemadump;
|
package org.alfresco.util.schemadump;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.File;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -72,32 +71,35 @@ public class Main
|
|||||||
private final Map<String, Integer> reverseTypeMap = new TreeMap<String, Integer>();
|
private final Map<String, Integer> reverseTypeMap = new TreeMap<String, Integer>();
|
||||||
|
|
||||||
/** Should we scale down string field widths (assuming 4 bytes to one character?). */
|
/** Should we scale down string field widths (assuming 4 bytes to one character?). */
|
||||||
private final boolean scaleCharacters;
|
private boolean scaleCharacters;
|
||||||
|
|
||||||
/** The JDBC connection. */
|
/** The JDBC connection. */
|
||||||
private final Connection con;
|
private Connection con;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of this tool..
|
* The main method.
|
||||||
*
|
*
|
||||||
* @param contextPath
|
* @param args
|
||||||
* path to the context xml file
|
* the args: <context.xml> <output.xml>
|
||||||
* @throws SQLException
|
*/
|
||||||
* the SQL exception
|
public static void main(final String[] args) throws Exception
|
||||||
* @throws IOException
|
{
|
||||||
* Signals that an I/O exception has occurred.
|
if (args.length != 2)
|
||||||
* @throws InstantiationException
|
{
|
||||||
* the instantiation exception
|
System.out.println("Usage:");
|
||||||
* @throws IllegalAccessException
|
System.out.println("java " + Main.class.getName() + " <context.xml> <output.xml>");
|
||||||
* the illegal access exception
|
System.exit(1);
|
||||||
* @throws ClassNotFoundException
|
}
|
||||||
* the class not found exception
|
|
||||||
* @throws NoSuchFieldException
|
final File outputFile = new File(args[1]);
|
||||||
* the no such field exception
|
new Main(args[0]).execute(outputFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of this tool by starting up a full context.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Main(final String contextPath) throws SQLException, IOException, InstantiationException, IllegalAccessException,
|
public Main(final String contextPath) throws Exception
|
||||||
ClassNotFoundException, NoSuchFieldException
|
|
||||||
{
|
{
|
||||||
final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]
|
final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]
|
||||||
{
|
{
|
||||||
@@ -109,6 +111,32 @@ public class Main
|
|||||||
// Use Java reflection to bypass accessibility rules and get hold of hibernate's type mapping!
|
// Use Java reflection to bypass accessibility rules and get hold of hibernate's type mapping!
|
||||||
final Properties hibProps = (Properties) context.getBean("hibernateConfigProperties");
|
final Properties hibProps = (Properties) context.getBean("hibernateConfigProperties");
|
||||||
final Dialect dialect = (Dialect) Class.forName(hibProps.getProperty("hibernate.dialect")).newInstance();
|
final Dialect dialect = (Dialect) Class.forName(hibProps.getProperty("hibernate.dialect")).newInstance();
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
init(dialect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of the tool within the context of an existing database connection
|
||||||
|
*
|
||||||
|
* @param connection the database connection to use for metadata queries
|
||||||
|
* @param dialect the Hibernate dialect
|
||||||
|
*/
|
||||||
|
public Main(final Connection connection, final Dialect dialect) throws Exception
|
||||||
|
{
|
||||||
|
this.con = connection;
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
init(dialect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the fields ready to perform the database metadata reading
|
||||||
|
* @param dialect the Hibernate dialect
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void init(final Dialect dialect) throws Exception
|
||||||
|
{
|
||||||
this.scaleCharacters = dialect instanceof Oracle8iDialect;
|
this.scaleCharacters = dialect instanceof Oracle8iDialect;
|
||||||
final Field typeNamesField = Dialect.class.getDeclaredField("typeNames");
|
final Field typeNamesField = Dialect.class.getDeclaredField("typeNames");
|
||||||
typeNamesField.setAccessible(true);
|
typeNamesField.setAccessible(true);
|
||||||
@@ -135,22 +163,13 @@ public class Main
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main method.
|
* Execute, writing the result to the given file.
|
||||||
*
|
*
|
||||||
* @param args
|
* @param outputFile the file to write to
|
||||||
* the args
|
|
||||||
* @throws Exception
|
|
||||||
* the exception
|
|
||||||
*/
|
*/
|
||||||
public static void main(final String[] args) throws Exception
|
public void execute(File outputFile) throws Exception
|
||||||
{
|
{
|
||||||
if (args.length != 2)
|
final NamedElementCollection result = execute();
|
||||||
{
|
|
||||||
System.out.println("Usage:");
|
|
||||||
System.out.println("java " + Main.class.getName() + " <context.xml> <output.xml>");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
final NamedElementCollection result = new Main(args[0]).execute();
|
|
||||||
|
|
||||||
// Set up a SAX TransformerHandler for outputting XML
|
// Set up a SAX TransformerHandler for outputting XML
|
||||||
final SAXTransformerFactory stf = (SAXTransformerFactory) TransformerFactory.newInstance();
|
final SAXTransformerFactory stf = (SAXTransformerFactory) TransformerFactory.newInstance();
|
||||||
@@ -165,7 +184,7 @@ public class Main
|
|||||||
// It was worth a try
|
// It was worth a try
|
||||||
}
|
}
|
||||||
t.setOutputProperty(OutputKeys.INDENT, "yes");
|
t.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||||
xmlOut.setResult(new StreamResult(args[1]));
|
xmlOut.setResult(new StreamResult(outputFile));
|
||||||
|
|
||||||
xmlOut.startDocument();
|
xmlOut.startDocument();
|
||||||
result.output(xmlOut);
|
result.output(xmlOut);
|
||||||
@@ -175,28 +194,10 @@ public class Main
|
|||||||
/**
|
/**
|
||||||
* Execute.
|
* Execute.
|
||||||
*
|
*
|
||||||
* @return the named element collection
|
* @return Returns the named XML elements
|
||||||
* @throws SQLException
|
|
||||||
* the SQL exception
|
|
||||||
* @throws IllegalArgumentException
|
|
||||||
* the illegal argument exception
|
|
||||||
* @throws IllegalAccessException
|
|
||||||
* the illegal access exception
|
|
||||||
* @throws IOException
|
|
||||||
* Signals that an I/O exception has occurred.
|
|
||||||
* @throws InstantiationException
|
|
||||||
* the instantiation exception
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
* the class not found exception
|
|
||||||
* @throws SecurityException
|
|
||||||
* the security exception
|
|
||||||
* @throws NoSuchFieldException
|
|
||||||
* the no such field exception
|
|
||||||
*/
|
*/
|
||||||
public NamedElementCollection execute() throws SQLException, IllegalArgumentException, IllegalAccessException,
|
public NamedElementCollection execute() throws Exception
|
||||||
IOException, InstantiationException, ClassNotFoundException, SecurityException, NoSuchFieldException
|
|
||||||
{
|
{
|
||||||
|
|
||||||
final NamedElementCollection schemaCol = new NamedElementCollection("schema", "table");
|
final NamedElementCollection schemaCol = new NamedElementCollection("schema", "table");
|
||||||
|
|
||||||
final DatabaseMetaData dbmd = this.con.getMetaData();
|
final DatabaseMetaData dbmd = this.con.getMetaData();
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user