diff --git a/config/alfresco/bootstrap-context.xml b/config/alfresco/bootstrap-context.xml
index a927e8abaf..6e8a3d37a7 100644
--- a/config/alfresco/bootstrap-context.xml
+++ b/config/alfresco/bootstrap-context.xml
@@ -148,6 +148,10 @@
+
+
+
+
diff --git a/config/alfresco/extension/restore-context.xml.sample b/config/alfresco/extension/restore-context.xml.sample
index 5a0c7e25ca..5e29f4e84a 100644
--- a/config/alfresco/extension/restore-context.xml.sample
+++ b/config/alfresco/extension/restore-context.xml.sample
@@ -56,12 +56,26 @@
+
+
+
+
+
+ alfresco/extension/restore/export_models.acp
+
+
+
+ true
+
+
+ true
/
alfresco/extension/restore/export_spaces.acp
+ UPDATE_EXISTING
diff --git a/config/alfresco/import-export-context.xml b/config/alfresco/import-export-context.xml
index 0eb754682a..ad61a362e8 100644
--- a/config/alfresco/import-export-context.xml
+++ b/config/alfresco/import-export-context.xml
@@ -151,6 +151,11 @@
${alfresco_user_store.store}
users
+
+ ${spaces.store}
+ models
+ /app:company_home/app:dictionary/app:models
+
${spaces.store}
spaces
diff --git a/config/alfresco/policy-context.xml b/config/alfresco/policy-context.xml
index 2b49de90b5..c357492d09 100644
--- a/config/alfresco/policy-context.xml
+++ b/config/alfresco/policy-context.xml
@@ -43,4 +43,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${spaces.store}
+ ${spaces.archive.store}
+
+
+
+
diff --git a/config/alfresco/repo-admin-context.xml b/config/alfresco/repo-admin-context.xml
index caf0baf1ab..04e13c3d74 100755
--- a/config/alfresco/repo-admin-context.xml
+++ b/config/alfresco/repo-admin-context.xml
@@ -78,25 +78,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ${spaces.store}
- ${spaces.archive.store}
-
-
-
-
+
diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryModelType.java b/source/java/org/alfresco/repo/dictionary/DictionaryModelType.java
index 82a15ad3ca..9a0ddba465 100644
--- a/source/java/org/alfresco/repo/dictionary/DictionaryModelType.java
+++ b/source/java/org/alfresco/repo/dictionary/DictionaryModelType.java
@@ -265,7 +265,7 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
// Register interest in the onCreateNode policy for the dictionary model type
policyComponent.bindClassBehaviour(
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
- ContentModel.TYPE_DICTIONARY_MODEL,
+ this,
new JavaBehaviour(this, "onCreateNode"));
// Create the transaction listener
diff --git a/source/java/org/alfresco/repo/exporter/ExporterComponent.java b/source/java/org/alfresco/repo/exporter/ExporterComponent.java
index 2d5171e349..4f7c9433ca 100644
--- a/source/java/org/alfresco/repo/exporter/ExporterComponent.java
+++ b/source/java/org/alfresco/repo/exporter/ExporterComponent.java
@@ -361,6 +361,16 @@ public class ExporterComponent
{
return;
}
+
+ // explicitly included ?
+ if (parameters.getIncludedPaths() != null)
+ {
+ String nodePathPrefixString = nodeService.getPath(nodeRef).toPrefixString(namespaceService);
+ if (! (isIncludedPath(parameters.getIncludedPaths(), nodePathPrefixString)))
+ {
+ return;
+ }
+ }
// export node as reference to node, or as the actual node
if (exportAsRef)
@@ -740,6 +750,22 @@ public class ExporterComponent
return false;
}
+ private boolean isIncludedPath(String[] includedPaths, String path)
+ {
+ for (String includePath : includedPaths)
+ {
+ // note: allow parents or children - e.g. if included path is /a/b/c then /, /a, /a/b, /a/b/c, /a/b/c/d, /a/b/c/d/e are all included
+ if (includePath.startsWith(path) || path.startsWith(includePath))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+
/**
* Is the aspect unexportable?
*
diff --git a/source/java/org/alfresco/repo/exporter/RepositoryExporterComponent.java b/source/java/org/alfresco/repo/exporter/RepositoryExporterComponent.java
index 21b53cc396..13c0a35767 100644
--- a/source/java/org/alfresco/repo/exporter/RepositoryExporterComponent.java
+++ b/source/java/org/alfresco/repo/exporter/RepositoryExporterComponent.java
@@ -68,6 +68,7 @@ public class RepositoryExporterComponent implements RepositoryExporterService
{
private static final String STOREREF_KEY = "storeRef";
private static final String PACKAGENAME_KEY = "packageName";
+ private static final String INCLUDED_PATHS = "includedPaths";
// component dependencies
private ExporterService exporterService;
@@ -290,10 +291,15 @@ public class RepositoryExporterComponent implements RepositoryExporterService
storePackageName = storeRef.getIdentifier();
}
String completePackageName = (packageName == null) ? storePackageName : packageName + "_" + storePackageName;
+
+ // retrieve included paths (optional)
+ // note: the default exporter will currently include parents and children, relative to the path (to support bootstrap import of Dynamic Models)
+ String includedPathsStr = (String)store.get(INCLUDED_PATHS);
+ String[] includedPaths = (includedPathsStr != null ? includedPathsStr.split(",\\s*") : null);
// now export
// NOTE: For now, do not provide exporter progress
- ExporterCrawlerParameters exportParameters = getExportParameters(storeRef);
+ ExporterCrawlerParameters exportParameters = getExportParameters(storeRef, includedPaths);
ExportHandleType exportHandle = exportStore.exportStore(exportParameters, completePackageName, null);
exportHandles.add(exportHandle);
}
@@ -308,7 +314,7 @@ public class RepositoryExporterComponent implements RepositoryExporterService
* @param storeRef store reference to export
* @return the parameters for exporting the complete store
*/
- private ExporterCrawlerParameters getExportParameters(StoreRef storeRef)
+ private ExporterCrawlerParameters getExportParameters(StoreRef storeRef, String[] includedPaths)
{
ExporterCrawlerParameters parameters = new ExporterCrawlerParameters();
parameters.setExportFrom(new Location(storeRef));
@@ -318,6 +324,7 @@ public class RepositoryExporterComponent implements RepositoryExporterService
parameters.setCrawlAssociations(true);
parameters.setCrawlNullProperties(true);
parameters.setExcludeNamespaceURIs(new String[] {});
+ parameters.setIncludedPaths(includedPaths);
parameters.setReferenceType(ReferenceType.NODEREF);
return parameters;
}
diff --git a/source/java/org/alfresco/repo/importer/ImporterBootstrap.java b/source/java/org/alfresco/repo/importer/ImporterBootstrap.java
index b9e07c25c6..a483a855e5 100644
--- a/source/java/org/alfresco/repo/importer/ImporterBootstrap.java
+++ b/source/java/org/alfresco/repo/importer/ImporterBootstrap.java
@@ -53,6 +53,7 @@ import org.alfresco.service.cmr.view.ImporterException;
import org.alfresco.service.cmr.view.ImporterProgress;
import org.alfresco.service.cmr.view.ImporterService;
import org.alfresco.service.cmr.view.Location;
+import org.alfresco.service.cmr.view.ImporterBinding.UUID_BINDING;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
@@ -60,9 +61,6 @@ import org.alfresco.util.AbstractLifecycleBean;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.commons.logging.impl.Log4JLogger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.util.FileCopyUtils;
@@ -79,6 +77,7 @@ public class ImporterBootstrap extends AbstractLifecycleBean
public static final String VIEW_MESSAGES_PROPERTY = "messages";
public static final String VIEW_LOCATION_VIEW = "location";
public static final String VIEW_ENCODING = "encoding";
+ public static final String VIEW_UUID_BINDING = "uuidBinding";
// Logger
private static final Log logger = LogFactory.getLog(ImporterBootstrap.class);
@@ -317,10 +316,13 @@ public class ImporterBootstrap extends AbstractLifecycleBean
}
if (storeRef == null)
{
- throw new ImporterException("Store URL must be provided");
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("No Store URL - bootstrap import ignored");
+ }
+ return;
}
-
UserTransaction userTransaction = transactionService.getUserTransaction();
Authentication authentication = authenticationComponent.getCurrentAuthentication();
@@ -409,6 +411,19 @@ public class ImporterBootstrap extends AbstractLifecycleBean
ResourceBundle bundle = ResourceBundle.getBundle(messages, bindingLocale);
binding.setResourceBundle(bundle);
}
+
+ String uuidBinding = bootstrapView.getProperty(VIEW_UUID_BINDING);
+ if (uuidBinding != null && uuidBinding.length() > 0)
+ {
+ try
+ {
+ binding.setUUIDBinding(UUID_BINDING.valueOf(UUID_BINDING.class, uuidBinding));
+ }
+ catch(IllegalArgumentException e)
+ {
+ throw new ImporterException("The value " + uuidBinding + " is an invalid uuidBinding");
+ }
+ }
// Now import...
ImporterProgress importProgress = null;
@@ -522,6 +537,8 @@ public class ImporterBootstrap extends AbstractLifecycleBean
private static final String IMPORT_LOCATION_NODEREF = "bootstrap.location.noderef";
private static final String IMPORT_LOCATION_PATH = "bootstrap.location.path";
+ // by default, use create new strategy for bootstrap import
+ private UUID_BINDING uuidBinding = UUID_BINDING.CREATE_NEW_WITH_UUID;
/**
* Set Import Configuration
@@ -602,8 +619,17 @@ public class ImporterBootstrap extends AbstractLifecycleBean
*/
public UUID_BINDING getUUIDBinding()
{
- // always use create new strategy for bootstrap import
- return UUID_BINDING.CREATE_NEW_WITH_UUID;
+ return uuidBinding;
+ }
+
+ /**
+ * Allow bootstrap to override default Node UUID Binding
+ *
+ * @param uuidBinding UUID_BINDING
+ */
+ private void setUUIDBinding(UUID_BINDING uuidBinding)
+ {
+ this.uuidBinding = uuidBinding;
}
/*
diff --git a/source/java/org/alfresco/service/cmr/view/ExporterCrawlerParameters.java b/source/java/org/alfresco/service/cmr/view/ExporterCrawlerParameters.java
index 9099975de9..b73f96856e 100644
--- a/source/java/org/alfresco/service/cmr/view/ExporterCrawlerParameters.java
+++ b/source/java/org/alfresco/service/cmr/view/ExporterCrawlerParameters.java
@@ -45,7 +45,7 @@ public class ExporterCrawlerParameters
private boolean crawlNullProperties = true;
private ReferenceType referenceType = ReferenceType.PATHREF;
private String[] excludeNamespaceURIs = new String[] { NamespaceService.REPOSITORY_VIEW_1_0_URI };
-
+ private String[] includedPaths = null;
/**
* Crawl and export child nodes
@@ -166,6 +166,26 @@ public class ExporterCrawlerParameters
{
this.excludeNamespaceURIs = excludeNamespaceURIs;
}
+
+ /**
+ * Gets the list of included paths to explicitly include in the Export
+ *
+ * @return the list of included paths
+ */
+ public String[] getIncludedPaths()
+ {
+ return includedPaths;
+ }
+
+ /**
+ * Sets the list of included paths to explicitly include in the Export
+ *
+ * @param includedPaths
+ */
+ public void setIncludedPaths(String[] includedPaths)
+ {
+ this.includedPaths = includedPaths;
+ }
/**
* Gets the path to export from