From 1d601e1be79308b6064d8394b4deb84e64c596b4 Mon Sep 17 00:00:00 2001 From: Britt Park Date: Sun, 14 May 2006 16:21:55 +0000 Subject: [PATCH] Morning merge. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@2889 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/bootstrap-context.xml | 3 + .../mimetype-map-extension.xml.sample | 21 ++ .../extension/mimetypes-extension.xml.sample | 13 ++ .../extension/restore-context.xml.sample | 17 ++ config/alfresco/import-export-context.xml | 41 ++++ .../messages/action-config.properties | 3 +- config/alfresco/model/systemModel.xml | 5 - project-build.xml | 5 +- project.properties | 3 +- .../java/org/alfresco/model/ContentModel.java | 1 - .../alfresco/repo/domain/VersionCount.java | 7 + .../repo/domain/hibernate/ChildAssocImpl.java | 2 +- .../repo/domain/hibernate/NodeAssocImpl.java | 15 +- .../domain/hibernate/VersionCountImpl.java | 2 +- .../VersionCounterDaoComponentImpl.java | 18 ++ .../exporter/RepositoryExporterComponent.java | 150 +++++++++----- .../RepositoryExporterComponentTest.java | 6 +- .../repo/importer/ImporterBootstrap.java | 1 - .../repo/importer/system/PatchInfo.java | 39 ++++ .../system/SystemExporterImporter.java | 135 ++++++++++++ .../repo/importer/system/SystemInfo.java | 85 ++++++++ .../importer/system/SystemInfoBootstrap.java | 192 ++++++++++++++++++ .../importer/system/VersionCounterInfo.java | 29 +++ .../repo/importer/system/systeminfo.xml | 36 ++++ .../repo/node/BaseNodeServiceTest.java | 18 -- .../node/archive/ArchiveAndRestoreTest.java | 25 ++- .../repo/node/db/DbNodeServiceImpl.java | 17 +- .../cmr/repository/AssociationRef.java | 2 +- .../cmr/view/RepositoryExporterService.java | 1 + 29 files changed, 788 insertions(+), 104 deletions(-) create mode 100644 config/alfresco/extension/mimetype-map-extension.xml.sample create mode 100644 config/alfresco/extension/mimetypes-extension.xml.sample create mode 100644 source/java/org/alfresco/repo/importer/system/PatchInfo.java create mode 100644 source/java/org/alfresco/repo/importer/system/SystemExporterImporter.java create mode 100644 source/java/org/alfresco/repo/importer/system/SystemInfo.java create mode 100644 source/java/org/alfresco/repo/importer/system/SystemInfoBootstrap.java create mode 100644 source/java/org/alfresco/repo/importer/system/VersionCounterInfo.java create mode 100644 source/java/org/alfresco/repo/importer/system/systeminfo.xml diff --git a/config/alfresco/bootstrap-context.xml b/config/alfresco/bootstrap-context.xml index fb5ab31de1..a1b78152ca 100644 --- a/config/alfresco/bootstrap-context.xml +++ b/config/alfresco/bootstrap-context.xml @@ -27,6 +27,9 @@ + + + diff --git a/config/alfresco/extension/mimetype-map-extension.xml.sample b/config/alfresco/extension/mimetype-map-extension.xml.sample new file mode 100644 index 0000000000..253534f262 --- /dev/null +++ b/config/alfresco/extension/mimetype-map-extension.xml.sample @@ -0,0 +1,21 @@ + + + + + + + + + + + classpath:alfresco/mimetype/mimetype-map.xml + classpath:alfresco/mimetype/mimetype-map-openoffice.xml + classpath:alfresco/extension/mimetypes-extension.xml + + + + + + + + \ No newline at end of file diff --git a/config/alfresco/extension/mimetypes-extension.xml.sample b/config/alfresco/extension/mimetypes-extension.xml.sample new file mode 100644 index 0000000000..e34633a983 --- /dev/null +++ b/config/alfresco/extension/mimetypes-extension.xml.sample @@ -0,0 +1,13 @@ + + + + + + + ex + + + + + + diff --git a/config/alfresco/extension/restore-context.xml.sample b/config/alfresco/extension/restore-context.xml.sample index bdfae1b719..5a0c7e25ca 100644 --- a/config/alfresco/extension/restore-context.xml.sample +++ b/config/alfresco/extension/restore-context.xml.sample @@ -3,6 +3,12 @@ + + + alfresco/extension/restore/export_systeminfo.xml + + + @@ -39,6 +45,17 @@ true + + + + + / + alfresco/extension/restore/export_spaces_archive.acp + + + + + diff --git a/config/alfresco/import-export-context.xml b/config/alfresco/import-export-context.xml index 5a9a8dfc36..80e746bd7e 100644 --- a/config/alfresco/import-export-context.xml +++ b/config/alfresco/import-export-context.xml @@ -94,6 +94,9 @@ + + + @@ -108,6 +111,10 @@ ${spaces.store} spaces + + ${spaces.archive.store} + spaces_archive + workspace://lightWeightVersionStore versions @@ -116,6 +123,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${system.store} + + + diff --git a/config/alfresco/messages/action-config.properties b/config/alfresco/messages/action-config.properties index f788ae24ee..90302d5319 100644 --- a/config/alfresco/messages/action-config.properties +++ b/config/alfresco/messages/action-config.properties @@ -69,7 +69,8 @@ export.title=Export a Space export.description=Exports a Space and optionally it's children to an Alfresco export package. export.package.description=Alfresco content package for Space ''{0}''. export.root.package.description=Alfresco content package for complete Repository. -export.store.package.description=Alfresco export of store ''{0}''. +export.store.package.description=Alfresco Repository export of store ''{0}''. +export.generic.package.description=Alfresco Repository export. export.package.error=Failed to find temporary file for export script.title=Execute a script diff --git a/config/alfresco/model/systemModel.xml b/config/alfresco/model/systemModel.xml index c9e64edd1c..b30ed8c1ec 100644 --- a/config/alfresco/model/systemModel.xml +++ b/config/alfresco/model/systemModel.xml @@ -131,11 +131,6 @@ d:childassocref true - - d:any - true - - d:text true diff --git a/project-build.xml b/project-build.xml index 7b6a586e43..dd7b4cf75b 100644 --- a/project-build.xml +++ b/project-build.xml @@ -9,9 +9,12 @@ - + + + + diff --git a/project.properties b/project.properties index 937e555f8c..278df21ebb 100644 --- a/project.properties +++ b/project.properties @@ -1,4 +1,5 @@ -file.jibx.binding=${dir.src.java}/org/alfresco/repo/dictionary/m2binding.xml +file.jibx.binding.m2=${dir.src.java}/org/alfresco/repo/dictionary/m2binding.xml +file.jibx.binding.systeminfo=${dir.src.java}/org/alfresco/repo/importer/system/systeminfo.xml dir.javadoc.api.service=${dir.docs}/java-public-service-api tck.webinf.lib.excludes=${webinf.lib.excludes},jcr-1.0.jar diff --git a/source/java/org/alfresco/model/ContentModel.java b/source/java/org/alfresco/model/ContentModel.java index 1d6c1f1115..8dfdc291ec 100644 --- a/source/java/org/alfresco/model/ContentModel.java +++ b/source/java/org/alfresco/model/ContentModel.java @@ -42,7 +42,6 @@ public interface ContentModel // archived nodes aspect constants static final QName ASPECT_ARCHIVED = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archived"); static final QName PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedOriginalParentAssoc"); - static final QName PROP_ARCHIVED_ORIGINAL_PATH = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedOriginalPath"); static final QName PROP_ARCHIVED_BY = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedBy"); static final QName PROP_ARCHIVED_DATE = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedDate"); static final QName ASPECT_ARCHIVED_ASSOCS = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archived-assocs"); diff --git a/source/java/org/alfresco/repo/domain/VersionCount.java b/source/java/org/alfresco/repo/domain/VersionCount.java index 759b7d1832..05dbc69478 100644 --- a/source/java/org/alfresco/repo/domain/VersionCount.java +++ b/source/java/org/alfresco/repo/domain/VersionCount.java @@ -56,4 +56,11 @@ public interface VersionCount * @see #incrementVersionCount() */ public int getVersionCount(); + + /** + * Sets the current version counter + * + * @param versionCount the new version counter + */ + public void setVersionCount(int versionCount); } diff --git a/source/java/org/alfresco/repo/domain/hibernate/ChildAssocImpl.java b/source/java/org/alfresco/repo/domain/hibernate/ChildAssocImpl.java index c32e0bf1b4..8c338c180e 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/ChildAssocImpl.java +++ b/source/java/org/alfresco/repo/domain/hibernate/ChildAssocImpl.java @@ -114,7 +114,7 @@ public class ChildAssocImpl implements ChildAssoc this.qName, child.getNodeRef(), this.isPrimary, - -1); + index); } return childAssocRef; } diff --git a/source/java/org/alfresco/repo/domain/hibernate/NodeAssocImpl.java b/source/java/org/alfresco/repo/domain/hibernate/NodeAssocImpl.java index be3897e152..881226e691 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/NodeAssocImpl.java +++ b/source/java/org/alfresco/repo/domain/hibernate/NodeAssocImpl.java @@ -74,13 +74,24 @@ public class NodeAssocImpl implements NodeAssoc public AssociationRef getNodeAssocRef() { + boolean trashReference = false; // first check if it is available refReadLock.lock(); try { if (nodeAssocRef != null) { - return nodeAssocRef; + // double check that the parent and child node references match those of our reference + if (nodeAssocRef.getSourceRef() != source.getNodeRef() || + nodeAssocRef.getTargetRef() != target.getNodeRef()) + { + trashReference = true; + } + else + { + // we are sure that the reference is correct + return nodeAssocRef; + } } } finally @@ -92,7 +103,7 @@ public class NodeAssocImpl implements NodeAssoc try { // double check - if (nodeAssocRef == null ) + if (nodeAssocRef == null || trashReference) { nodeAssocRef = new AssociationRef( getSource().getNodeRef(), diff --git a/source/java/org/alfresco/repo/domain/hibernate/VersionCountImpl.java b/source/java/org/alfresco/repo/domain/hibernate/VersionCountImpl.java index 4be08aa2e2..c8c4e930e5 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/VersionCountImpl.java +++ b/source/java/org/alfresco/repo/domain/hibernate/VersionCountImpl.java @@ -85,7 +85,7 @@ public class VersionCountImpl implements VersionCount /** * For Hibernate use */ - private void setVersionCount(int versionCount) + public void setVersionCount(int versionCount) { this.versionCount = versionCount; } diff --git a/source/java/org/alfresco/repo/domain/hibernate/VersionCounterDaoComponentImpl.java b/source/java/org/alfresco/repo/domain/hibernate/VersionCounterDaoComponentImpl.java index 4283639417..a64a572228 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/VersionCounterDaoComponentImpl.java +++ b/source/java/org/alfresco/repo/domain/hibernate/VersionCounterDaoComponentImpl.java @@ -179,4 +179,22 @@ public class VersionCounterDaoComponentImpl // get an incremented count versionCounter.resetVersionCount(); } + + /** + * Sets the version number for a specified store. + * + * WARNING: calling this method will completely reset the current + * version count for the specified store and cannot be undone. + * + * @param storeRef the store reference + * @param versionCount the new version count + */ + public synchronized void setVersionNumber(StoreRef storeRef, int versionCount) + { + // get the version counter + VersionCount versionCounter = getVersionCounter(storeRef); + // get an incremented count + versionCounter.setVersionCount(versionCount); + } + } diff --git a/source/java/org/alfresco/repo/exporter/RepositoryExporterComponent.java b/source/java/org/alfresco/repo/exporter/RepositoryExporterComponent.java index ebbf004c60..1082f9f6ea 100644 --- a/source/java/org/alfresco/repo/exporter/RepositoryExporterComponent.java +++ b/source/java/org/alfresco/repo/exporter/RepositoryExporterComponent.java @@ -30,6 +30,7 @@ import java.util.Properties; import org.alfresco.i18n.I18NUtil; import org.alfresco.model.ContentModel; import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.importer.system.SystemExporterImporter; import org.alfresco.service.cmr.model.FileExistsException; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; @@ -64,6 +65,7 @@ public class RepositoryExporterComponent implements RepositoryExporterService private ExporterService exporterService; private MimetypeService mimetypeService; private FileFolderService fileFolderService; + private SystemExporterImporter systemExporterImporter; private NodeService nodeService; private List exportStores; @@ -82,6 +84,11 @@ public class RepositoryExporterComponent implements RepositoryExporterService { this.fileFolderService = fileFolderService; } + + public void setSystemExporter(SystemExporterImporter systemExporterImporter) + { + this.systemExporterImporter = systemExporterImporter; + } public void setNodeService(NodeService nodeService) { @@ -104,7 +111,7 @@ public class RepositoryExporterComponent implements RepositoryExporterService return exportHandles.toArray(new FileExportHandle[exportHandles.size()]); } - + /* * (non-Javadoc) * @see org.alfresco.service.cmr.view.RepositoryExporterService#export(java.io.File) @@ -136,14 +143,27 @@ public class RepositoryExporterComponent implements RepositoryExporterService } List exportHandles = exportStores(exportStores, packageName, new TempFileExporter()); + Map mimetypeExtensions = mimetypeService.getExtensionsByMimetype(); List repoExportHandles = new ArrayList(exportHandles.size()); for (FileExportHandle exportHandle : exportHandles) { - String description = I18NUtil.getMessage("export.store.package.description", new Object[] { exportHandle.storeRef.getIdentifier() }); - NodeRef repoExportFile = addExportFile(repositoryDestination, exportHandle.packageName, description, exportHandle.exportFile); + String name = exportHandle.packageName + "." + mimetypeExtensions.get(exportHandle.mimeType); + String title = exportHandle.packageName; + String description; + if (exportHandle.storeRef != null) + { + description = I18NUtil.getMessage("export.store.package.description", new Object[] { exportHandle.storeRef.toString() }); + } + else + { + description = I18NUtil.getMessage("export.generic.package.description"); + } + + NodeRef repoExportFile = addExportFile(repositoryDestination, name, title, description, exportHandle.mimeType, exportHandle.exportFile); RepositoryExportHandle handle = new RepositoryExportHandle(); handle.storeRef = exportHandle.storeRef; handle.packageName = exportHandle.packageName; + handle.mimeType = exportHandle.mimeType; handle.exportFile = repoExportFile; repoExportHandles.add(handle); } @@ -161,16 +181,15 @@ public class RepositoryExporterComponent implements RepositoryExporterService * @param exportFile the .acp file * @return node reference to import .acp file */ - private NodeRef addExportFile(NodeRef repoDestination, String packageName, String packageDescription, File exportFile) + private NodeRef addExportFile(NodeRef repoDestination, String name, String title, String description, String mimeType, File exportFile) { // // import temp file into repository // // determine if file already exists - String fileName = packageName + "." + ACPExportPackageHandler.ACP_EXTENSION; List paths = new ArrayList(); - paths.add(fileName); + paths.add(name); try { FileInfo fileInfo = fileFolderService.resolveNamePath(repoDestination, paths); @@ -186,16 +205,16 @@ public class RepositoryExporterComponent implements RepositoryExporterService NodeRef exportFileNodeRef = null; try { - FileInfo fileInfo = fileFolderService.create(repoDestination, fileName, ContentModel.TYPE_CONTENT); + FileInfo fileInfo = fileFolderService.create(repoDestination, name, ContentModel.TYPE_CONTENT); ContentWriter writer = fileFolderService.getWriter(fileInfo.getNodeRef()); - writer.setMimetype(MimetypeMap.MIMETYPE_ACP); + writer.setMimetype(mimeType); writer.putContent(exportFile); exportFileNodeRef = fileInfo.getNodeRef(); // add a title for Web Client viewing Map titledProps = new HashMap(3, 1.0f); - titledProps.put(ContentModel.PROP_TITLE, packageName); - titledProps.put(ContentModel.PROP_DESCRIPTION, packageDescription); + titledProps.put(ContentModel.PROP_TITLE, title); + titledProps.put(ContentModel.PROP_DESCRIPTION, description); nodeService.addAspect(exportFileNodeRef, ContentModel.ASPECT_TITLED, titledProps); } @@ -209,7 +228,7 @@ public class RepositoryExporterComponent implements RepositoryExporterService /** - * Contract for exporting a store + * Contract for exporting a repository * * @author davidc * @@ -218,6 +237,8 @@ public class RepositoryExporterComponent implements RepositoryExporterService private interface ExportStore { public ExportHandleType exportStore(ExporterCrawlerParameters exportParameters, String packageName, Exporter progress); + + public ExportHandleType exportSystem(String packageName); } @@ -231,7 +252,16 @@ public class RepositoryExporterComponent implements RepositoryExporterService */ private List exportStores(List stores, String packageName, ExportStore exportStore) { - List exportHandles = new ArrayList(stores.size()); + List exportHandles = new ArrayList(stores.size() +1); + + // export repository system info + { + String completePackageName = (packageName == null) ? "systeminfo" : packageName + "_systeminfo"; + ExportHandleType systemInfoHandle = exportStore.exportSystem(completePackageName); + exportHandles.add(systemInfoHandle); + } + + // export each store for (Properties store : stores) { // retrieve store reference to export @@ -319,9 +349,39 @@ public class RepositoryExporterComponent implements RepositoryExporterService FileExportHandle handle = new FileExportHandle(); handle.storeRef = exportParameters.getExportFrom().getStoreRef(); handle.packageName = packageName; + handle.mimeType = MimetypeMap.MIMETYPE_ACP; handle.exportFile = tempFile; return handle; - }; + } + + /* + * (non-Javadoc) + * @see org.alfresco.repo.exporter.RepositoryExporterComponent.ExportStore#exportSystem() + */ + public FileExportHandle exportSystem(String packageName) + { + // create a temporary file to hold the system info export + File tempFile = TempFileProvider.createTempFile("repoExpSystemInfo", ".xml"); + + try + { + OutputStream outputStream = new FileOutputStream(tempFile); + systemExporterImporter.exportSystem(outputStream); + } + catch(FileNotFoundException e) + { + tempFile.delete(); + throw new ExporterException("Failed to create temporary file for holding export of system info"); + } + + // return handle onto temp file + FileExportHandle handle = new FileExportHandle(); + handle.storeRef = null; + handle.packageName = packageName; + handle.mimeType = MimetypeMap.MIMETYPE_XML; + handle.exportFile = tempFile; + return handle; + } }; @@ -374,50 +434,40 @@ public class RepositoryExporterComponent implements RepositoryExporterService FileExportHandle handle = new FileExportHandle(); handle.storeRef = exportParameters.getExportFrom().getStoreRef(); handle.packageName = packageName; + handle.mimeType = MimetypeMap.MIMETYPE_ACP; handle.exportFile = file; return handle; - }; - }; - - - /** - * Export a store to Repository File - * - * @author davidc - */ - @SuppressWarnings("unused") - private class RepositoryFileExporter implements ExportStore - { - private TempFileExporter tempFileExporter = new TempFileExporter(); - private NodeRef repoDestination; - - /** - * Construct - * - * @param repoDestination destination within repository to create export file - */ - public RepositoryFileExporter(NodeRef repoDestination) - { - this.repoDestination = repoDestination; } - - /* - * (non-Javadoc) - * @see org.alfresco.repo.exporter.RepositoryExporterComponent.ExportStore#exportStore(org.alfresco.service.cmr.view.ExporterCrawlerParameters, java.lang.String, org.alfresco.service.cmr.view.Exporter) - */ - public RepositoryExportHandle exportStore(ExporterCrawlerParameters exportParameters, String packageName, Exporter progress) - { - // export acp to temporary file - FileExportHandle tempFile = tempFileExporter.exportStore(exportParameters, packageName, progress); - String description = I18NUtil.getMessage("export.store.package.description", new Object[] { tempFile.storeRef.getIdentifier() }); - NodeRef repoExportFile = addExportFile(repoDestination, packageName, description, tempFile.exportFile); - RepositoryExportHandle handle = new RepositoryExportHandle(); - handle.storeRef = exportParameters.getExportFrom().getStoreRef(); + /* + * (non-Javadoc) + * @see org.alfresco.repo.exporter.RepositoryExporterComponent.ExportStore#exportSystem() + */ + public FileExportHandle exportSystem(String packageName) + { + // create a temporary file to hold the system info export + File tempFile = TempFileProvider.createTempFile("repoExpSystemInfo", ".xml"); + + try + { + OutputStream outputStream = new FileOutputStream(tempFile); + systemExporterImporter.exportSystem(outputStream); + } + catch(FileNotFoundException e) + { + tempFile.delete(); + throw new ExporterException("Failed to create temporary file for holding export of system info"); + } + + // return handle onto temp file + FileExportHandle handle = new FileExportHandle(); + handle.storeRef = null; handle.packageName = packageName; - handle.exportFile = repoExportFile; + handle.mimeType = MimetypeMap.MIMETYPE_XML; + handle.exportFile = tempFile; return handle; } }; + } diff --git a/source/java/org/alfresco/repo/exporter/RepositoryExporterComponentTest.java b/source/java/org/alfresco/repo/exporter/RepositoryExporterComponentTest.java index 1172051986..e9f6378e20 100644 --- a/source/java/org/alfresco/repo/exporter/RepositoryExporterComponentTest.java +++ b/source/java/org/alfresco/repo/exporter/RepositoryExporterComponentTest.java @@ -64,13 +64,13 @@ public class RepositoryExporterComponentTest extends BaseSpringTest { FileExportHandle[] handles = repositoryService.export("test"); assertNotNull(handles); - assertEquals(4, handles.length); + assertEquals(6, handles.length); for (FileExportHandle tempFile : handles) { assertTrue(tempFile.exportFile.exists()); } } - + public void xtestRepositoryExport() throws Exception { @@ -82,7 +82,7 @@ public class RepositoryExporterComponentTest extends BaseSpringTest // Export stores RepositoryExportHandle[] handles = repositoryService.export(container.getNodeRef(), "test"); assertNotNull(handles); - assertEquals(4, handles.length); + assertEquals(6, handles.length); for (RepositoryExportHandle handle : handles) { assertTrue(nodeService.exists(handle.exportFile)); diff --git a/source/java/org/alfresco/repo/importer/ImporterBootstrap.java b/source/java/org/alfresco/repo/importer/ImporterBootstrap.java index c0b62d123e..12556807e0 100644 --- a/source/java/org/alfresco/repo/importer/ImporterBootstrap.java +++ b/source/java/org/alfresco/repo/importer/ImporterBootstrap.java @@ -55,7 +55,6 @@ import org.apache.log4j.Logger; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.core.io.ClassPathResource; import org.springframework.util.FileCopyUtils; /** diff --git a/source/java/org/alfresco/repo/importer/system/PatchInfo.java b/source/java/org/alfresco/repo/importer/system/PatchInfo.java new file mode 100644 index 0000000000..92568d7959 --- /dev/null +++ b/source/java/org/alfresco/repo/importer/system/PatchInfo.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.importer.system; + +import java.util.Date; + +/** + * Data holder of patch information that's to be exported and imported + * + * @author davidc + */ +public class PatchInfo +{ + public String id = null; + public String description = null; + public Integer fixesFromSchema = null; + public Integer fixesToSchema = null; + public Integer targetSchema = null; + public Integer appliedToSchema = null; + public String appliedToServer = null; + public Date appliedOnDate = null; + public Boolean wasExecuted = null; + public Boolean succeeded = null; + public String report = null; +} diff --git a/source/java/org/alfresco/repo/importer/system/SystemExporterImporter.java b/source/java/org/alfresco/repo/importer/system/SystemExporterImporter.java new file mode 100644 index 0000000000..20a3271d59 --- /dev/null +++ b/source/java/org/alfresco/repo/importer/system/SystemExporterImporter.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.importer.system; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; + +import org.alfresco.repo.admin.patch.PatchDaoService; +import org.alfresco.repo.domain.AppliedPatch; +import org.alfresco.repo.domain.hibernate.VersionCounterDaoComponentImpl; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; + + +/** + * Exporter and Importer of Repository System Information + * + * @author davidc + */ +public class SystemExporterImporter +{ + // dependencies + private NodeService nodeService; + private PatchDaoService patchDao; + private VersionCounterDaoComponentImpl versionCounterDao; + + + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public void setPatchDao(PatchDaoService patchDaoService) + { + this.patchDao = patchDaoService; + } + + public void setVersionDao(VersionCounterDaoComponentImpl versionCounterDao) + { + this.versionCounterDao = versionCounterDao; + } + + + /** + * Export Repository System Information + * + * @param exportStream output stream to export to + */ + public void exportSystem(OutputStream exportStream) + { + SystemInfo systemInfo = new SystemInfo(); + + // capture applied patches + List patches = patchDao.getAppliedPatches(); + for (AppliedPatch patch : patches) + { + PatchInfo patchInfo = new PatchInfo(); + patchInfo.appliedOnDate = patch.getAppliedOnDate(); + patchInfo.appliedToSchema = patch.getAppliedToSchema(); + patchInfo.appliedToServer = patch.getAppliedToServer(); + patchInfo.description = patch.getDescription(); + patchInfo.fixesFromSchema = patch.getFixesFromSchema(); + patchInfo.fixesToSchema = patch.getFixesToSchema(); + patchInfo.id = patch.getId(); + patchInfo.report = patch.getReport(); + patchInfo.succeeded = patch.getSucceeded(); + patchInfo.targetSchema = patch.getTargetSchema(); + patchInfo.wasExecuted = patch.getWasExecuted(); + systemInfo.patches.add(patchInfo); + } + + // capture version counters + List storeRefs = nodeService.getStores(); + for (StoreRef storeRef : storeRefs) + { + VersionCounterInfo versionCounterInfo = new VersionCounterInfo(); + int versionCount = versionCounterDao.currentVersionNumber(storeRef); + versionCounterInfo.storeRef = storeRef.toString(); + versionCounterInfo.count = versionCount; + systemInfo.versionCounters.add(versionCounterInfo); + } + + systemInfo.toXML(exportStream); + } + + + /** + * Import Repository System Information + * + * @param importStream input stream to import from + */ + public void importSystem(InputStream importStream) + { + SystemInfo systemInfo = SystemInfo.createSystemInfo(importStream); + + // apply patch info + for (PatchInfo patchInfo : systemInfo.patches) + { + AppliedPatch patch = patchDao.newAppliedPatch(patchInfo.id); + patch.setAppliedOnDate(patchInfo.appliedOnDate); + patch.setAppliedToSchema(patchInfo.appliedToSchema); + patch.setAppliedToServer(patchInfo.appliedToServer); + patch.setDescription(patchInfo.description); + patch.setFixesFromSchema(patchInfo.fixesFromSchema); + patch.setFixesToSchema(patchInfo.fixesToSchema); + patch.setReport(patchInfo.report); + patch.setSucceeded(patchInfo.succeeded); + patch.setTargetSchema(patchInfo.targetSchema); + patch.setWasExecuted(patchInfo.wasExecuted); + } + + // apply version counters + for (VersionCounterInfo versionCounterInfo : systemInfo.versionCounters) + { + StoreRef storeRef = new StoreRef(versionCounterInfo.storeRef); + versionCounterDao.setVersionNumber(storeRef, versionCounterInfo.count); + } + } + +} diff --git a/source/java/org/alfresco/repo/importer/system/SystemInfo.java b/source/java/org/alfresco/repo/importer/system/SystemInfo.java new file mode 100644 index 0000000000..88b831ea2d --- /dev/null +++ b/source/java/org/alfresco/repo/importer/system/SystemInfo.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.importer.system; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import org.alfresco.service.cmr.dictionary.DictionaryException; +import org.jibx.runtime.BindingDirectory; +import org.jibx.runtime.IBindingFactory; +import org.jibx.runtime.IMarshallingContext; +import org.jibx.runtime.IUnmarshallingContext; +import org.jibx.runtime.JiBXException; + + +/** + * Root data holder of Repository system information to be exported and imported + * + * @author davidc + */ +public class SystemInfo +{ + public List patches = new ArrayList(); + public List versionCounters = new ArrayList(); + + /** + * Create System Info from XML representation + * + * @param xml xml representation of system info + * @return the System Info + */ + public static SystemInfo createSystemInfo(InputStream xml) + { + try + { + IBindingFactory factory = BindingDirectory.getFactory(SystemInfo.class); + IUnmarshallingContext context = factory.createUnmarshallingContext(); + Object obj = context.unmarshalDocument(xml, null); + return (SystemInfo)obj; + } + catch(JiBXException e) + { + throw new DictionaryException("Failed to parse System Info", e); + } + } + + /** + * Create XML representation of System Info + * + * @param xml xml representation of system info + */ + public void toXML(OutputStream xml) + { + try + { + IBindingFactory factory = BindingDirectory.getFactory(SystemInfo.class); + IMarshallingContext context = factory.createMarshallingContext(); + context.setIndent(4); + context.marshalDocument(this, "UTF-8", null, xml); + } + catch(JiBXException e) + { + throw new DictionaryException("Failed to create System Info", e); + } + } + +} + + diff --git a/source/java/org/alfresco/repo/importer/system/SystemInfoBootstrap.java b/source/java/org/alfresco/repo/importer/system/SystemInfoBootstrap.java new file mode 100644 index 0000000000..e764c2e751 --- /dev/null +++ b/source/java/org/alfresco/repo/importer/system/SystemInfoBootstrap.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */package org.alfresco.repo.importer.system; + +import java.io.InputStream; +import java.util.List; + +import javax.transaction.UserTransaction; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.security.authentication.AuthenticationComponent; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.view.ImporterException; +import org.alfresco.service.transaction.TransactionService; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; + + +/** + * Repository System Information bootstrap + * + * @author davidc + */ +public class SystemInfoBootstrap implements ApplicationListener +{ + // dependencies + private TransactionService transactionService; + private NodeService nodeService; + private AuthenticationComponent authenticationComponent; + private SystemExporterImporter systemImporter; + + private List mustNotExistStoreUrls = null; + private String bootstrapView = null; + + + /** + * Sets the Transaction Service + * + * @param userTransaction the transaction service + */ + public void setTransactionService(TransactionService transactionService) + { + this.transactionService = transactionService; + } + + /** + * Sets the node service + * + * @param nodeService the node service + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * Set the authentication component + * + * @param authenticationComponent + */ + public void setAuthenticationComponent(AuthenticationComponent authenticationComponent) + { + this.authenticationComponent = authenticationComponent; + } + + /** + * Set the System Importer + * + * @param systemImporter + */ + public void setSystemImporter(SystemExporterImporter systemImporter) + { + this.systemImporter = systemImporter; + } + + /** + * If any of the store urls exist, the bootstrap does not take place + * + * @param storeUrls the list of store urls to check + */ + public void setMustNotExistStoreUrls(List storeUrls) + { + this.mustNotExistStoreUrls = storeUrls; + } + + /** + * Set the bootstrap view containing the system information + * + * @param bootstrapView + */ + public void setBootstrapView(String bootstrapView) + { + this.bootstrapView = bootstrapView; + } + + /** + * Bootstrap + */ + public void bootstrap() + { + UserTransaction userTransaction = transactionService.getUserTransaction(); + authenticationComponent.setSystemUserAsCurrentUser(); + + try + { + userTransaction.begin(); + + // check the repository exists, create if it doesn't + if (performBootstrap()) + { + InputStream viewStream = getClass().getClassLoader().getResourceAsStream(bootstrapView); + if (viewStream == null) + { + throw new ImporterException("Could not find system info file " + bootstrapView); + } + try + { + systemImporter.importSystem(viewStream); + } + finally + { + viewStream.close(); + } + } + userTransaction.commit(); + } + catch(Throwable e) + { + // rollback the transaction + try { if (userTransaction != null) {userTransaction.rollback();} } catch (Exception ex) {} + try {authenticationComponent.clearCurrentSecurityContext(); } catch (Exception ex) {} + throw new AlfrescoRuntimeException("System Info Bootstrap failed", e); + } + finally + { + authenticationComponent.clearCurrentSecurityContext(); + } + } + + /** + * Determine if bootstrap should take place + * + * @return true => yes, it should + */ + private boolean performBootstrap() + { + if (bootstrapView == null || bootstrapView.length() == 0) + { + return false; + } + if (mustNotExistStoreUrls != null) + { + for (String storeUrl : mustNotExistStoreUrls) + { + StoreRef storeRef = new StoreRef(storeUrl); + if (nodeService.exists(storeRef)) + { + return false; + } + } + } + return true; + } + + /* + * (non-Javadoc) + * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent) + */ + public void onApplicationEvent(ApplicationEvent event) + { + if (event instanceof ContextRefreshedEvent) + { + bootstrap(); + } + } + +} diff --git a/source/java/org/alfresco/repo/importer/system/VersionCounterInfo.java b/source/java/org/alfresco/repo/importer/system/VersionCounterInfo.java new file mode 100644 index 0000000000..2ca2825839 --- /dev/null +++ b/source/java/org/alfresco/repo/importer/system/VersionCounterInfo.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.importer.system; + + +/** + * Data holder of Version information to be exported and imported + * + * @author davidc + */ +public class VersionCounterInfo +{ + public String storeRef = null; + public Integer count = null; +} diff --git a/source/java/org/alfresco/repo/importer/system/systeminfo.xml b/source/java/org/alfresco/repo/importer/system/systeminfo.xml new file mode 100644 index 0000000000..ef23080d82 --- /dev/null +++ b/source/java/org/alfresco/repo/importer/system/systeminfo.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java b/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java index cdcd66f480..60ad2059cb 100644 --- a/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java +++ b/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java @@ -1206,24 +1206,6 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest return assocRef; } - public void testAssociationToIncorrectNodeType() throws Exception - { - AssociationRef assocRef = createAssociation(); - NodeRef sourceRef = assocRef.getSourceRef(); - NodeRef targetRef = assocRef.getTargetRef(); - QName qname = assocRef.getTypeQName(); - try - { - // attempt the association in reverse - nodeService.createAssociation(sourceRef, targetRef, qname); - fail("Incorrect node type not detected"); - } - catch (RuntimeException e) - { - // expected - } - } - public void testDuplicateAssociationDetection() throws Exception { AssociationRef assocRef = createAssociation(); diff --git a/source/java/org/alfresco/repo/node/archive/ArchiveAndRestoreTest.java b/source/java/org/alfresco/repo/node/archive/ArchiveAndRestoreTest.java index 122d835397..2e6993a0b4 100644 --- a/source/java/org/alfresco/repo/node/archive/ArchiveAndRestoreTest.java +++ b/source/java/org/alfresco/repo/node/archive/ArchiveAndRestoreTest.java @@ -36,7 +36,6 @@ import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.PermissionService; @@ -55,8 +54,9 @@ import org.springframework.context.ApplicationContext; */ public class ArchiveAndRestoreTest extends TestCase { - private static final String USER_A = "AAAAA"; - private static final String USER_B = "BBBBB"; + private static final String USER_A = "aaaaa"; + private static final String USER_B = "bbbbb"; + private static final QName ASPECT_ATTACHABLE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "attachable"); private static final QName ASPECT_ATTACHABLE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "attachable"); private static final QName ASSOC_ATTACHMENTS = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "attachments"); private static final QName QNAME_A = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "a"); @@ -123,11 +123,19 @@ public class ArchiveAndRestoreTest extends TestCase // Map the work store to the archive store. This will already be wired into the NodeService. StoreArchiveMap archiveMap = (StoreArchiveMap) ctx.getBean("storeArchiveMap"); archiveMap.getArchiveMap().put(workStoreRef, archiveStoreRef); + + TestWithUserUtils.createUser(USER_A, USER_A, workStoreRootNodeRef, nodeService, authenticationService); + TestWithUserUtils.createUser(USER_B, USER_B, workStoreRootNodeRef, nodeService, authenticationService); - // grant everyone rights to the work store + // grant A and B rights to the work store permissionService.setPermission( workStoreRootNodeRef, - PermissionService.ALL_AUTHORITIES, + USER_A, + PermissionService.ALL_PERMISSIONS, + true); + permissionService.setPermission( + workStoreRootNodeRef, + USER_B, PermissionService.ALL_PERMISSIONS, true); @@ -137,9 +145,6 @@ public class ArchiveAndRestoreTest extends TestCase PermissionService.ALL_AUTHORITIES, PermissionService.ALL_PERMISSIONS, true); - - TestWithUserUtils.createUser(USER_A, USER_A, workStoreRootNodeRef, nodeService, authenticationService); - TestWithUserUtils.createUser(USER_B, USER_B, workStoreRootNodeRef, nodeService, authenticationService); } finally { @@ -335,8 +340,8 @@ public class ArchiveAndRestoreTest extends TestCase // check that the required properties are present and correct Map bb_Properties = nodeService.getProperties(bb_); - Path bb_originalPath = (Path) bb_Properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_PATH); - assertNotNull("Original path not stored", bb_originalPath); + ChildAssociationRef bb_originalParent = (ChildAssociationRef) bb_Properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC); + assertNotNull("Original parent not stored", bb_originalParent); // restore the node nodeService.restoreNode(bb_, null, null, null); diff --git a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java index 431abbc332..1f753b10e5 100644 --- a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java @@ -1071,14 +1071,20 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl public void removeAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName) throws InvalidNodeRefException { - // Invoke policy behaviours - invokeBeforeUpdateNode(sourceRef); - Node sourceNode = getNodeNotNull(sourceRef); Node targetNode = getNodeNotNull(targetRef); // get the association NodeAssoc assoc = nodeDaoService.getNodeAssoc(sourceNode, targetNode, assocTypeQName); + if (assoc == null) + { + // nothing to remove + return; + } AssociationRef assocRef = assoc.getNodeAssocRef(); + + // Invoke policy behaviours + invokeBeforeUpdateNode(sourceRef); + // delete it nodeDaoService.deleteNodeAssoc(assoc); @@ -1302,7 +1308,6 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl { Node node = getNodeNotNull(nodeRef); ChildAssoc primaryParentAssoc = nodeDaoService.getPrimaryParentAssoc(node); - Path primaryPath = getPath(nodeRef); // add the aspect node.getAspects().add(ContentModel.ASPECT_ARCHIVED); @@ -1319,10 +1324,6 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC), primaryParentAssoc.getChildAssocRef()); properties.put(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC, archivedPrimaryParentNodeRefProperty); - PropertyValue archivedPrimaryPathProperty = makePropertyValue( - dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_PATH), - primaryPath); - properties.put(ContentModel.PROP_ARCHIVED_ORIGINAL_PATH, archivedPrimaryPathProperty); // move the node NodeRef archiveStoreRootNodeRef = getRootNode(archiveStoreRef); diff --git a/source/java/org/alfresco/service/cmr/repository/AssociationRef.java b/source/java/org/alfresco/service/cmr/repository/AssociationRef.java index 31720d79ca..51fd22c368 100644 --- a/source/java/org/alfresco/service/cmr/repository/AssociationRef.java +++ b/source/java/org/alfresco/service/cmr/repository/AssociationRef.java @@ -115,7 +115,7 @@ public class AssociationRef implements EntityRef, Serializable { return true; } - if (!(o instanceof ChildAssociationRef)) + if (!(o instanceof AssociationRef)) { return false; } diff --git a/source/java/org/alfresco/service/cmr/view/RepositoryExporterService.java b/source/java/org/alfresco/service/cmr/view/RepositoryExporterService.java index 29d8bfad6c..99bb20042c 100644 --- a/source/java/org/alfresco/service/cmr/view/RepositoryExporterService.java +++ b/source/java/org/alfresco/service/cmr/view/RepositoryExporterService.java @@ -70,6 +70,7 @@ public interface RepositoryExporterService { public StoreRef storeRef; public String packageName; + public String mimeType; } /**