From 4b881e72adbe46b9904d537110942f0e597806fe Mon Sep 17 00:00:00 2001 From: Britt Park Date: Fri, 12 May 2006 20:22:46 +0000 Subject: [PATCH] Daily merge. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@2882 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/bootstrap-context.xml | 4 + .../bootstrap/example_javascripts.acp | Bin 0 -> 4380 bytes config/alfresco/mimetype/mimetype-map.xml | 3 + .../model-specific-services-context.xml | 1 + .../server/config/ServerConfiguration.java | 11 +- .../repo/domain/hibernate/Node.hbm.xml | 40 +++-- .../repo/importer/FileImporterImpl.java | 139 +++++++++++++++--- .../repo/importer/FileImporterTest.java | 91 ++++-------- .../node/archive/ArchiveAndRestoreTest.java | 43 ++++++ .../repo/node/db/DbNodeServiceImpl.java | 1 + .../alfresco/repo/node/db/NodeDaoService.java | 16 +- .../HibernateNodeDaoServiceImpl.java | 83 ++++------- .../search/impl/lucene/LuceneIndexerImpl.java | 6 +- .../impl/AbstractPermissionEntry.java | 11 ++ .../AlfrescoTransactionSupport.java | 5 + 15 files changed, 282 insertions(+), 172 deletions(-) create mode 100644 config/alfresco/bootstrap/example_javascripts.acp diff --git a/config/alfresco/bootstrap-context.xml b/config/alfresco/bootstrap-context.xml index 00e106f8c6..fb5ab31de1 100644 --- a/config/alfresco/bootstrap-context.xml +++ b/config/alfresco/bootstrap-context.xml @@ -109,6 +109,10 @@ /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} alfresco/templates/email_templates.acp + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.scripts.childname} + alfresco/bootstrap/example_javascripts.acp + diff --git a/config/alfresco/bootstrap/example_javascripts.acp b/config/alfresco/bootstrap/example_javascripts.acp new file mode 100644 index 0000000000000000000000000000000000000000..f954936f0814a9766f93a6d0f6f04fe6d29c1891 GIT binary patch literal 4380 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 literal 0 HcmV?d00001 diff --git a/config/alfresco/mimetype/mimetype-map.xml b/config/alfresco/mimetype/mimetype-map.xml index 9c033c883a..17340ab60e 100644 --- a/config/alfresco/mimetype/mimetype-map.xml +++ b/config/alfresco/mimetype/mimetype-map.xml @@ -124,6 +124,9 @@ hqx + + ics + ief diff --git a/config/alfresco/model-specific-services-context.xml b/config/alfresco/model-specific-services-context.xml index 1f788b0ea2..0bfedcde96 100644 --- a/config/alfresco/model-specific-services-context.xml +++ b/config/alfresco/model-specific-services-context.xml @@ -20,6 +20,7 @@ /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.childname} /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.content.childname} /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.scripts.childname} diff --git a/source/java/org/alfresco/filesys/server/config/ServerConfiguration.java b/source/java/org/alfresco/filesys/server/config/ServerConfiguration.java index d24edcd9ea..82eceba926 100644 --- a/source/java/org/alfresco/filesys/server/config/ServerConfiguration.java +++ b/source/java/org/alfresco/filesys/server/config/ServerConfiguration.java @@ -23,6 +23,7 @@ import java.net.Socket; import java.net.UnknownHostException; import java.security.Provider; import java.security.Security; +import java.util.ArrayList; import java.util.EnumSet; import java.util.Enumeration; import java.util.List; @@ -1430,7 +1431,15 @@ public class ServerConfiguration implements ApplicationListener { // Check for the old style configuration - filesysElems = config.getConfigElementList( "filesystem"); + ConfigElement filesysElem = config.getConfigElement( "filesystem"); + + if (filesysElem != null) + { + // create a list with the single filesys element in + + filesysElems = new ArrayList(1); + filesysElems.add(filesysElem); + } // Warn that the configuration is using the old format diff --git a/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml b/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml index b02a880151..6c7b1d4f58 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml +++ b/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml @@ -203,27 +203,25 @@ - - - - - - - - - - - + + + + + + + + + diff --git a/source/java/org/alfresco/repo/importer/FileImporterImpl.java b/source/java/org/alfresco/repo/importer/FileImporterImpl.java index 41e865044e..c510ca9bae 100644 --- a/source/java/org/alfresco/repo/importer/FileImporterImpl.java +++ b/source/java/org/alfresco/repo/importer/FileImporterImpl.java @@ -26,6 +26,8 @@ import java.util.HashMap; import java.util.Map; import org.alfresco.model.ContentModel; +import org.alfresco.repo.transaction.TransactionUtil; +import org.alfresco.repo.transaction.TransactionUtil.TransactionWork; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; @@ -38,6 +40,7 @@ import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; +import org.alfresco.service.transaction.TransactionService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -55,6 +58,8 @@ public class FileImporterImpl implements FileImporter private DictionaryService dictionaryService; private ContentService contentService; private MimetypeService mimetypeService; + private TransactionService transactionService; + private boolean txnPerFile = false; public FileImporterImpl() { @@ -63,30 +68,75 @@ public class FileImporterImpl implements FileImporter public int loadFile(NodeRef container, File file, boolean recurse) throws FileImporterException { - Counter counter = new Counter(); - create(counter, container, file, null, recurse, null); - return counter.getCount(); + try + { + Counter counter = new Counter(); + create(counter, container, file, null, recurse, null); + return counter.getCount(); + } + catch (Throwable e) + { + throw new FileImporterException("Failed to load file: \n" + + " container: " + container + "\n" + + " file: " + file + "\n" + + " recurse: " + recurse, + e); + } } public int loadNamedFile(NodeRef container, File file, boolean recurse, String name) throws FileImporterException { - Counter counter = new Counter(); - create(counter, container, file, null, recurse, name); - return counter.getCount(); + try + { + Counter counter = new Counter(); + create(counter, container, file, null, recurse, name); + return counter.getCount(); + } + catch (Throwable e) + { + throw new FileImporterException("Failed to load file: \n" + + " container: " + container + "\n" + + " file: " + file + "\n" + + " name: " + name + "\n" + + " recurse: " + recurse, + e); + } } public int loadFile(NodeRef container, File file, FileFilter filter, boolean recurse) throws FileImporterException { - Counter counter = new Counter(); - create(counter, container, file, filter, recurse, null); - return counter.getCount(); + try + { + Counter counter = new Counter(); + create(counter, container, file, filter, recurse, null); + return counter.getCount(); + } + catch (Throwable e) + { + throw new FileImporterException("Failed to load file: \n" + + " container: " + container + "\n" + + " file: " + file + "\n" + + " filter: " + filter + "\n" + + " recurse: " + recurse, + e); + } } public int loadFile(NodeRef container, File file) throws FileImporterException { - Counter counter = new Counter(); - create(counter, container, file, null, false, null); - return counter.getCount(); + try + { + Counter counter = new Counter(); + create(counter, container, file, null, false, null); + return counter.getCount(); + } + catch (Throwable e) + { + throw new FileImporterException("Failed to load file: \n" + + " container: " + container + "\n" + + " file: " + file, + e); + } } /** Helper class for mutable int */ @@ -103,9 +153,15 @@ public class FileImporterImpl implements FileImporter } } - private NodeRef create(Counter counter, NodeRef container, File file, FileFilter filter, boolean recurse, String containerName) + private NodeRef create( + Counter counter, + final NodeRef container, + final File file, + FileFilter filter, + boolean recurse, + String containerName) throws Exception { - if(containerName != null) + if (containerName != null) { NodeRef newContainer = createDirectory(container, containerName, containerName); return create(counter, newContainer, file, filter, recurse, null); @@ -113,10 +169,27 @@ public class FileImporterImpl implements FileImporter } if (file.isDirectory()) { - NodeRef directoryNodeRef = createDirectory(container, file); counter.increment(); + TransactionWork createDirectoryWork = new TransactionWork() + { + public NodeRef doWork() throws Exception + { + return createDirectory(container, file); + } + }; + NodeRef directoryNodeRef = null; + if (txnPerFile) + { + directoryNodeRef = TransactionUtil.executeInUserTransaction( + transactionService, + createDirectoryWork); + } + else + { + directoryNodeRef = createDirectoryWork.doWork(); + } - if(recurse) + if (recurse) { File[] files = ((filter == null) ? file.listFiles() : file.listFiles(filter)); for(int i = 0; i < files.length; i++) @@ -130,7 +203,25 @@ public class FileImporterImpl implements FileImporter else { counter.increment(); - return createFile(container, file); + TransactionWork createFileWork = new TransactionWork() + { + public NodeRef doWork() throws Exception + { + return createFile(container, file); + } + }; + NodeRef fileNodeRef = null; + if (txnPerFile) + { + fileNodeRef = TransactionUtil.executeInUserTransaction( + transactionService, + createFileWork); + } + else + { + fileNodeRef = createFileWork.doWork(); + } + return fileNodeRef; } } @@ -291,4 +382,18 @@ public class FileImporterImpl implements FileImporter { this.dictionaryService = dictionaryService; } + + public void setTransactionService(TransactionService transactionService) + { + this.transactionService = transactionService; + } + + /** + * @param txnPerFile true to force each file or directory creation to be in its + * own file + */ + public void setTxnPerFile(boolean txnPerFile) + { + this.txnPerFile = txnPerFile; + } } diff --git a/source/java/org/alfresco/repo/importer/FileImporterTest.java b/source/java/org/alfresco/repo/importer/FileImporterTest.java index 30fa98a608..c017674437 100644 --- a/source/java/org/alfresco/repo/importer/FileImporterTest.java +++ b/source/java/org/alfresco/repo/importer/FileImporterTest.java @@ -31,7 +31,6 @@ import javax.transaction.UserTransaction; import junit.framework.TestCase; import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.model.ContentModel; import org.alfresco.repo.content.transform.AbstractContentTransformerTest; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.service.ServiceRegistry; @@ -41,8 +40,6 @@ import org.alfresco.service.cmr.repository.MimetypeService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.SearchParameters; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.PermissionService; @@ -64,6 +61,7 @@ public class FileImporterTest extends TestCase private PermissionService permissionService; private MimetypeService mimetypeService; private NamespaceService namespaceService; + private TransactionService transactionService; private ServiceRegistry serviceRegistry; private NodeRef rootNodeRef; @@ -91,13 +89,14 @@ public class FileImporterTest extends TestCase permissionService = serviceRegistry.getPermissionService(); mimetypeService = serviceRegistry.getMimetypeService(); namespaceService = serviceRegistry.getNamespaceService(); + transactionService = serviceRegistry.getTransactionService(); authenticationComponent.setSystemUserAsCurrentUser(); StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis()); rootNodeRef = nodeService.getRootNode(storeRef); } - private FileImporter createFileImporter() + private FileImporter createFileImporter(boolean txnPerFile) { FileImporterImpl fileImporter = new FileImporterImpl(); fileImporter.setAuthenticationService(authenticationService); @@ -105,19 +104,21 @@ public class FileImporterTest extends TestCase fileImporter.setMimetypeService(mimetypeService); fileImporter.setNodeService(nodeService); fileImporter.setDictionaryService(dictionaryService); + fileImporter.setTransactionService(transactionService); + fileImporter.setTxnPerFile(txnPerFile); return fileImporter; } public void testCreateFile() throws Exception { - FileImporter fileImporter = createFileImporter(); + FileImporter fileImporter = createFileImporter(false); File file = AbstractContentTransformerTest.loadQuickTestFile("xml"); fileImporter.loadFile(rootNodeRef, file); } public void testLoadRootNonRecursive1() { - FileImporter fileImporter = createFileImporter(); + FileImporter fileImporter = createFileImporter(false); URL url = this.getClass().getClassLoader().getResource(""); File rootFile = new File(url.getFile()); int count = fileImporter.loadFile(rootNodeRef, rootFile); @@ -126,7 +127,7 @@ public class FileImporterTest extends TestCase public void testLoadRootNonRecursive2() { - FileImporter fileImporter = createFileImporter(); + FileImporter fileImporter = createFileImporter(false); URL url = this.getClass().getClassLoader().getResource(""); File root = new File(url.getFile()); int count = fileImporter.loadFile(rootNodeRef, root, null, false); @@ -135,7 +136,7 @@ public class FileImporterTest extends TestCase public void testLoadXMLFiles() { - FileImporter fileImporter = createFileImporter(); + FileImporter fileImporter = createFileImporter(false); URL url = this.getClass().getClassLoader().getResource(""); FileFilter filter = new XMLFileFilter(); fileImporter.loadFile(rootNodeRef, new File(url.getFile()), filter, true); @@ -143,7 +144,7 @@ public class FileImporterTest extends TestCase public void testLoadSourceTestResources() { - FileImporter fileImporter = createFileImporter(); + FileImporter fileImporter = createFileImporter(false); URL url = this.getClass().getClassLoader().getResource("quick"); FileFilter filter = new QuickFileFilter(); fileImporter.loadFile(rootNodeRef, new File(url.getFile()), filter, true); @@ -173,6 +174,7 @@ public class FileImporterTest extends TestCase *
  • String: Directory to use as source (e.g. c:/temp) *
  • String: New name to give the source. It may have a suffix added (e.g. upload_xxx) *
  • Integer: Number of times to repeat the load. + *
  • Boolean: (optional - default 'false') Create each file/folder in a new transaction *
  • String: (optional) user to authenticate as *
  • String: (optional) password for authentication * @@ -191,8 +193,9 @@ public class FileImporterTest extends TestCase File sourceFile = new File(args[2]); String baseName = args[3]; int target = Integer.parseInt(args[4]); - String userName = args.length > 5 ? args[5] : null; - String userPwd = args.length > 6 ? args[6] : ""; + Boolean txnPerFile = args.length > 5 ? Boolean.parseBoolean(args[5]) : false; + String userName = args.length > 6 ? args[6] : null; + String userPwd = args.length > 7 ? args[7] : ""; while (count < target) { count++; @@ -240,13 +243,19 @@ public class FileImporterTest extends TestCase userPwd, test.authenticationService, test.authenticationComponent); - tx.commit(); + } + tx.commit(); + + // only begin if we are doing it all in one transaction + if (!txnPerFile) + { tx = transactionService.getUserTransaction(); tx.begin(); } - + long start = System.nanoTime(); - int importCount = test.createFileImporter().loadNamedFile( + FileImporter importer = test.createFileImporter(txnPerFile); + int importCount = importer.loadNamedFile( importLocation, sourceFile, true, @@ -257,7 +266,10 @@ public class FileImporterTest extends TestCase System.out.println("Created in: " + ((end - start) / 1000000.0) + "ms"); start = System.nanoTime(); - tx.commit(); + if (!txnPerFile) + { + tx.commit(); + } end = System.nanoTime(); long second = end-start; System.out.println("Committed in: " + ((end - start) / 1000000.0) + "ms"); @@ -265,55 +277,6 @@ public class FileImporterTest extends TestCase System.out.println("Grand Total: "+ grandTotal); System.out.println("Imported: " + importCount + " files or directories"); System.out.println("Average: " + (importCount / (total / 1000.0)) + " files per second"); - - tx = transactionService.getUserTransaction(); - tx.begin(); - SearchParameters sp = new SearchParameters(); - sp.setLanguage("lucene"); - sp.setQuery("ISNODE:T"); - sp.addStore(spacesStore); - start = System.nanoTime(); - ResultSet rs = test.searchService.query(sp); - end = System.nanoTime(); - System.out.println("Find all in: " + ((end - start) / 1000000.0) + "ms"); - System.out.println(" = "+rs.length() +"\n\n"); - rs.close(); - - sp = new SearchParameters(); - sp.setLanguage("lucene"); - sp.setQuery("TEXT:\"andy\""); - sp.addStore(spacesStore); - start = System.nanoTime(); - rs = test.searchService.query(sp); - end = System.nanoTime(); - System.out.println("Find andy in: " + ((end - start) / 1000000.0) + "ms"); - System.out.println(" = "+rs.length() +"\n\n"); - rs.close(); - - sp = new SearchParameters(); - sp.setLanguage("lucene"); - sp.setQuery("TYPE:\"" + ContentModel.TYPE_CONTENT.toString() + "\""); - sp.addStore(spacesStore); - start = System.nanoTime(); - rs = test.searchService.query(sp); - end = System.nanoTime(); - System.out.println("Find content in: " + ((end - start) / 1000000.0) + "ms"); - System.out.println(" = "+rs.length() +"\n\n"); - rs.close(); - - sp = new SearchParameters(); - sp.setLanguage("lucene"); - sp.setQuery("PATH:\"/*/*/*\""); - sp.addStore(spacesStore); - start = System.nanoTime(); - rs = test.searchService.query(sp); - end = System.nanoTime(); - System.out.println("Find /*/*/* in: " + ((end - start) / 1000000.0) + "ms"); - System.out.println(" = "+rs.length() +"\n\n"); - rs.close(); - - tx.commit(); - } catch (Throwable e) { diff --git a/source/java/org/alfresco/repo/node/archive/ArchiveAndRestoreTest.java b/source/java/org/alfresco/repo/node/archive/ArchiveAndRestoreTest.java index f74b8bfabe..122d835397 100644 --- a/source/java/org/alfresco/repo/node/archive/ArchiveAndRestoreTest.java +++ b/source/java/org/alfresco/repo/node/archive/ArchiveAndRestoreTest.java @@ -30,6 +30,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.node.StoreArchiveMap; import org.alfresco.repo.node.archive.RestoreNodeReport.RestoreStatus; import org.alfresco.repo.security.authentication.AuthenticationComponent; +import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; @@ -56,6 +57,7 @@ public class ArchiveAndRestoreTest extends TestCase { 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 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"); private static final QName QNAME_B = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "b"); @@ -194,6 +196,7 @@ public class ArchiveAndRestoreTest extends TestCase QNAME_A, ContentModel.TYPE_FOLDER, properties).getChildRef(); + nodeService.addAspect(a, ASPECT_ATTACHABLE, null); properties.put(ContentModel.PROP_NODE_UUID, "aa"); childAssocAtoAA = nodeService.createNode( a, @@ -202,6 +205,7 @@ public class ArchiveAndRestoreTest extends TestCase ContentModel.TYPE_CONTENT, properties); aa = childAssocAtoAA.getChildRef(); + nodeService.addAspect(aa, ASPECT_ATTACHABLE, null); properties.put(ContentModel.PROP_NODE_UUID, "b"); b = nodeService.createNode( workStoreRootNodeRef, @@ -326,6 +330,9 @@ public class ArchiveAndRestoreTest extends TestCase verifyNodeExistence(b_, false); verifyNodeExistence(bb_, true); + // flush + AlfrescoTransactionSupport.flush(); + // 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); @@ -351,6 +358,9 @@ public class ArchiveAndRestoreTest extends TestCase verifyNodeExistence(bb_, true); verifyChildAssocExistence(childAssocBtoBB_, true); + // flush + AlfrescoTransactionSupport.flush(); + // restore the node nodeService.restoreNode(b_, null, null, null); // check @@ -362,6 +372,10 @@ public class ArchiveAndRestoreTest extends TestCase // delete both trees in order 'b', 'a' nodeService.deleteNode(b); nodeService.deleteNode(a); + + // flush + AlfrescoTransactionSupport.flush(); + // restore in reverse order nodeService.restoreNode(a_, null, null, null); nodeService.restoreNode(b_, null, null, null); @@ -374,6 +388,10 @@ public class ArchiveAndRestoreTest extends TestCase // delete both trees in order 'b', 'a' nodeService.deleteNode(a); nodeService.deleteNode(b); + + // flush + AlfrescoTransactionSupport.flush(); + // restore in reverse order nodeService.restoreNode(b_, null, null, null); nodeService.restoreNode(a_, null, null, null); @@ -386,6 +404,10 @@ public class ArchiveAndRestoreTest extends TestCase // delete a then b nodeService.deleteNode(a); nodeService.deleteNode(b); + + // flush + AlfrescoTransactionSupport.flush(); + // in restoring 'a' first, there will be some associations that won't be recreated nodeService.restoreNode(a_, null, null, null); nodeService.restoreNode(b_, null, null, null); @@ -438,6 +460,10 @@ public class ArchiveAndRestoreTest extends TestCase nodeService.deleteNode(b); long end = System.nanoTime(); cumulatedArchiveTimeNs += (end - start); + + // flush + AlfrescoTransactionSupport.flush(); + // now restore start = System.nanoTime(); nodeService.restoreNode(b_, null, null, null); @@ -565,4 +591,21 @@ public class ArchiveAndRestoreTest extends TestCase // List restoredByB = nodeArchiveService.restoreAllArchivedNodes(workStoreRef); // assertEquals("User B should not have seen A's delete", 1, restoredByB.size()); // } +// +// /** +// * Deny the current user the rights to write to the destination location +// * and ensure that the use-case is handled properly. +// */ +// public void testPermissionsLackingOnDestination() throws Exception +// { +// // remove 'b', deny permissions to workspace root and attempt a restore +// nodeService.deleteNode(b); +// permissionService.setPermission(workStoreRootNodeRef, USER_B, PermissionService.ADD_CHILDREN, false); +// commitAndBeginNewTransaction(); +// +// // the restore of b should fail for user B +// authenticationService.authenticate(USER_B, USER_B.toCharArray()); +// RestoreNodeReport report = nodeArchiveService.restoreArchivedNode(b_); +// assertEquals("Expected permission denied status", RestoreStatus.FAILURE_PERMISSION, report.getStatus()); +// } } diff --git a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java index 53dbdefca2..431abbc332 100644 --- a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java @@ -1559,6 +1559,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl // remove the aspect archived aspect aspects.remove(ContentModel.ASPECT_ARCHIVED); properties.remove(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC); + properties.remove(ContentModel.PROP_ARCHIVED_ORIGINAL_PATH); properties.remove(ContentModel.PROP_ARCHIVED_BY); properties.remove(ContentModel.PROP_ARCHIVED_DATE); diff --git a/source/java/org/alfresco/repo/node/db/NodeDaoService.java b/source/java/org/alfresco/repo/node/db/NodeDaoService.java index 9dbdaccffc..474ba27a81 100644 --- a/source/java/org/alfresco/repo/node/db/NodeDaoService.java +++ b/source/java/org/alfresco/repo/node/db/NodeDaoService.java @@ -16,7 +16,6 @@ */ package org.alfresco.repo.node.db; -import java.util.Collection; import java.util.List; import org.alfresco.repo.domain.ChildAssoc; @@ -42,6 +41,11 @@ public interface NodeDaoService */ public boolean isDirty(); + /** + * Flush the data changes to the persistence layer. + */ + public void flush(); + /** * Fetch a list of all stores in the repository * @@ -168,16 +172,6 @@ public interface NodeDaoService Node targetNode, QName assocTypeQName); - /** - * @return Returns the target nodes for the association - */ - public Collection getNodeAssocTargets(Node sourceNode, QName assocTypeQName); - - /** - * @return Returns the source nodes for the association - */ - public Collection getNodeAssocSources(Node targetNode, QName assocTypeQName); - /** * @param assoc the node association to remove */ diff --git a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java index e670eadf59..a9f298b566 100644 --- a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java @@ -36,6 +36,7 @@ import org.alfresco.repo.domain.hibernate.StoreImpl; import org.alfresco.repo.node.db.NodeDaoService; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.service.cmr.dictionary.InvalidTypeException; +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.namespace.QName; @@ -56,9 +57,6 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements NodeDaoService { private static final String QUERY_GET_ALL_STORES = "store.GetAllStores"; - private static final String QUERY_GET_NODE_ASSOC = "node.GetNodeAssoc"; - private static final String QUERY_GET_NODE_ASSOC_TARGETS = "node.GetNodeAssocTargets"; - private static final String QUERY_GET_NODE_ASSOC_SOURCES = "node.GetNodeAssocSources"; private static final String QUERY_GET_CONTENT_DATA_STRINGS = "node.GetContentDataStrings"; /** a uuid identifying this unique instance */ @@ -117,6 +115,14 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements return ((Boolean)getHibernateTemplate().execute(callback)).booleanValue(); } + /** + * Just flushes the session + */ + public void flush() + { + getSession().flush(); + } + /** * @see #QUERY_GET_ALL_STORES */ @@ -337,7 +343,6 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements assoc.setTypeQName(assocTypeQName); assoc.setIsPrimary(isPrimary); assoc.setQname(qname); -// assoc.setIsArchived(false); assoc.buildAssociation(parentNode, childNode); // persist getHibernateTemplate().save(assoc); @@ -450,7 +455,6 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements { NodeAssoc assoc = new NodeAssocImpl(); assoc.setTypeQName(assocTypeQName); -// assoc.setIsArchived(false); assoc.buildAssociation(sourceNode, targetNode); // persist getHibernateTemplate().save(assoc); @@ -463,62 +467,27 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements final Node targetNode, final QName assocTypeQName) { - HibernateCallback callback = new HibernateCallback() + AssociationRef nodeAssocRef = new AssociationRef( + sourceNode.getNodeRef(), + assocTypeQName, + targetNode.getNodeRef()); + // get all the source's target associations + Collection assocs = sourceNode.getTargetNodeAssocs(); + // hunt down the desired assoc + for (NodeAssoc assoc : assocs) { - public Object doInHibernate(Session session) + // is it a match? + if (!assoc.getNodeAssocRef().equals(nodeAssocRef)) // not a match { - Query query = session.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_NODE_ASSOC); - query.setEntity("sourceNode", sourceNode) - .setEntity("targetNode", targetNode) - .setString("assocTypeQName", assocTypeQName.toString()) - .setMaxResults(1); - return query.uniqueResult(); + continue; + } + else + { + return assoc; } - }; - Object queryResult = getHibernateTemplate().execute(callback); - if (queryResult == null) - { - return null; } - NodeAssoc assoc = (NodeAssoc) queryResult; - // done - return assoc; - } - - @SuppressWarnings("unchecked") - public Collection getNodeAssocTargets(final Node sourceNode, final QName assocTypeQName) - { - HibernateCallback callback = new HibernateCallback() - { - public Object doInHibernate(Session session) - { - Query query = session.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_NODE_ASSOC_TARGETS); - query.setEntity("sourceNode", sourceNode) - .setString("assocTypeQName", assocTypeQName.toString()); - return query.list(); - } - }; - List queryResults = (List) getHibernateTemplate().execute(callback); - // done - return queryResults; - } - - @SuppressWarnings("unchecked") - public Collection getNodeAssocSources(final Node targetNode, final QName assocTypeQName) - { - HibernateCallback callback = new HibernateCallback() - { - public Object doInHibernate(Session session) - { - Query query = session.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_NODE_ASSOC_SOURCES); - query.setEntity("targetNode", targetNode) - .setString("assocTypeQName", assocTypeQName.toString()); - return query.list(); - } - }; - List queryResults = (List) getHibernateTemplate().execute(callback); - // done - return queryResults; + // not found + return null; } public void deleteNodeAssoc(NodeAssoc assoc) diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl.java index 80258c6883..a5676090de 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl.java @@ -116,7 +116,6 @@ public class LuceneIndexerImpl extends LuceneBase implements LuceneIndexer * * TODO: Consider if this information needs to be persisted for recovery */ - private Set deletions = new LinkedHashSet(); /** @@ -1738,6 +1737,11 @@ public class LuceneIndexerImpl extends LuceneBase implements LuceneIndexer { // Document document = helper.document; NodeRef ref = helper.nodeRef; + // bypass nodes that have disappeared + if (!nodeService.exists(ref)) + { + continue; + } List docs = createDocuments(ref, false, true, false); for (Document doc : docs) diff --git a/source/java/org/alfresco/repo/security/permissions/impl/AbstractPermissionEntry.java b/source/java/org/alfresco/repo/security/permissions/impl/AbstractPermissionEntry.java index adb09bb274..a1e0616d9f 100644 --- a/source/java/org/alfresco/repo/security/permissions/impl/AbstractPermissionEntry.java +++ b/source/java/org/alfresco/repo/security/permissions/impl/AbstractPermissionEntry.java @@ -69,6 +69,17 @@ public abstract class AbstractPermissionEntry implements PermissionEntry return hashCode; } + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(200); + sb.append("PermissionEntry") + .append("[ authority=").append(getAuthority()) + .append(", permission=").append(getPermissionReference()) + .append(", access=").append(getAccessStatus()) + .append("]"); + return sb.toString(); + } } diff --git a/source/java/org/alfresco/repo/transaction/AlfrescoTransactionSupport.java b/source/java/org/alfresco/repo/transaction/AlfrescoTransactionSupport.java index 620da5aeba..1e7885a43a 100644 --- a/source/java/org/alfresco/repo/transaction/AlfrescoTransactionSupport.java +++ b/source/java/org/alfresco/repo/transaction/AlfrescoTransactionSupport.java @@ -523,6 +523,11 @@ public abstract class AlfrescoTransactionSupport { listener.flush(); } + // flush changes + for (NodeDaoService nodeDaoServices : getNodeDaoServices()) + { + nodeDaoServices.flush(); + } } /**