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 0000000000..f954936f08 Binary files /dev/null and b/config/alfresco/bootstrap/example_javascripts.acp differ 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(); + } } /**