Daily merge.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@2882 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-05-12 20:22:46 +00:00
parent a22ddfb666
commit 4b881e72ad
15 changed files with 282 additions and 172 deletions

View File

@@ -109,6 +109,10 @@
<prop key="path">/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}</prop> <prop key="path">/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}</prop>
<prop key="location">alfresco/templates/email_templates.acp</prop> <prop key="location">alfresco/templates/email_templates.acp</prop>
</props> </props>
<props>
<prop key="path">/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.scripts.childname}</prop>
<prop key="location">alfresco/bootstrap/example_javascripts.acp</prop>
</props>
</list> </list>
</property> </property>
</bean> </bean>

Binary file not shown.

View File

@@ -124,6 +124,9 @@
<mimetype mimetype="application/mac-binhex40" display=""> <mimetype mimetype="application/mac-binhex40" display="">
<extension>hqx</extension> <extension>hqx</extension>
</mimetype> </mimetype>
<mimetype mimetype="text/calendar" display="iCalendar File">
<extension>ics</extension>
</mimetype>
<mimetype mimetype="image/ief" display="IEF Image"> <mimetype mimetype="image/ief" display="IEF Image">
<extension>ief</extension> <extension>ief</extension>
</mimetype> </mimetype>

View File

@@ -20,6 +20,7 @@
<value>/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.childname}</value> <value>/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.childname}</value>
<value>/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.content.childname}</value> <value>/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.content.childname}</value>
<value>/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}</value> <value>/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}</value>
<value>/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.scripts.childname}</value>
</list> </list>
</property> </property>
</bean> </bean>

View File

@@ -23,6 +23,7 @@ import java.net.Socket;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.security.Provider; import java.security.Provider;
import java.security.Security; import java.security.Security;
import java.util.ArrayList;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
@@ -1430,7 +1431,15 @@ public class ServerConfiguration implements ApplicationListener
{ {
// Check for the old style configuration // 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<ConfigElement>(1);
filesysElems.add(filesysElem);
}
// Warn that the configuration is using the old format // Warn that the configuration is using the old format

View File

@@ -203,7 +203,6 @@
<id name="id" column="id" type="long" > <id name="id" column="id" type="long" >
<generator class="native" /> <generator class="native" />
</id> </id>
<natural-id mutable="true">
<!-- forward assoc to source node --> <!-- forward assoc to source node -->
<many-to-one <many-to-one
name="source" name="source"
@@ -223,7 +222,6 @@
<column name="target_node_id" /> <column name="target_node_id" />
</many-to-one> </many-to-one>
<property name="typeQName" column="type_qname" type="QName" length="255" not-null="true" /> <property name="typeQName" column="type_qname" type="QName" length="255" not-null="true" />
</natural-id>
</class> </class>
<query name="store.GetAllStores"> <query name="store.GetAllStores">

View File

@@ -26,6 +26,8 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.alfresco.model.ContentModel; 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.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData; 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.cmr.security.AuthenticationService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -55,6 +58,8 @@ public class FileImporterImpl implements FileImporter
private DictionaryService dictionaryService; private DictionaryService dictionaryService;
private ContentService contentService; private ContentService contentService;
private MimetypeService mimetypeService; private MimetypeService mimetypeService;
private TransactionService transactionService;
private boolean txnPerFile = false;
public FileImporterImpl() public FileImporterImpl()
{ {
@@ -62,32 +67,77 @@ public class FileImporterImpl implements FileImporter
} }
public int loadFile(NodeRef container, File file, boolean recurse) throws FileImporterException public int loadFile(NodeRef container, File file, boolean recurse) throws FileImporterException
{
try
{ {
Counter counter = new Counter(); Counter counter = new Counter();
create(counter, container, file, null, recurse, null); create(counter, container, file, null, recurse, null);
return counter.getCount(); 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 public int loadNamedFile(NodeRef container, File file, boolean recurse, String name) throws FileImporterException
{
try
{ {
Counter counter = new Counter(); Counter counter = new Counter();
create(counter, container, file, null, recurse, name); create(counter, container, file, null, recurse, name);
return counter.getCount(); 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 public int loadFile(NodeRef container, File file, FileFilter filter, boolean recurse) throws FileImporterException
{
try
{ {
Counter counter = new Counter(); Counter counter = new Counter();
create(counter, container, file, filter, recurse, null); create(counter, container, file, filter, recurse, null);
return counter.getCount(); 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 public int loadFile(NodeRef container, File file) throws FileImporterException
{
try
{ {
Counter counter = new Counter(); Counter counter = new Counter();
create(counter, container, file, null, false, null); create(counter, container, file, null, false, null);
return counter.getCount(); 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 */ /** Helper class for mutable int */
private static class Counter private static class Counter
@@ -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); NodeRef newContainer = createDirectory(container, containerName, containerName);
return create(counter, newContainer, file, filter, recurse, null); return create(counter, newContainer, file, filter, recurse, null);
@@ -113,10 +169,27 @@ public class FileImporterImpl implements FileImporter
} }
if (file.isDirectory()) if (file.isDirectory())
{ {
NodeRef directoryNodeRef = createDirectory(container, file);
counter.increment(); counter.increment();
TransactionWork<NodeRef> createDirectoryWork = new TransactionWork<NodeRef>()
{
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)); File[] files = ((filter == null) ? file.listFiles() : file.listFiles(filter));
for(int i = 0; i < files.length; i++) for(int i = 0; i < files.length; i++)
@@ -130,8 +203,26 @@ public class FileImporterImpl implements FileImporter
else else
{ {
counter.increment(); counter.increment();
TransactionWork<NodeRef> createFileWork = new TransactionWork<NodeRef>()
{
public NodeRef doWork() throws Exception
{
return createFile(container, file); 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; 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;
}
} }

View File

@@ -31,7 +31,6 @@ import javax.transaction.UserTransaction;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.transform.AbstractContentTransformerTest; import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.service.ServiceRegistry; 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.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
@@ -64,6 +61,7 @@ public class FileImporterTest extends TestCase
private PermissionService permissionService; private PermissionService permissionService;
private MimetypeService mimetypeService; private MimetypeService mimetypeService;
private NamespaceService namespaceService; private NamespaceService namespaceService;
private TransactionService transactionService;
private ServiceRegistry serviceRegistry; private ServiceRegistry serviceRegistry;
private NodeRef rootNodeRef; private NodeRef rootNodeRef;
@@ -91,13 +89,14 @@ public class FileImporterTest extends TestCase
permissionService = serviceRegistry.getPermissionService(); permissionService = serviceRegistry.getPermissionService();
mimetypeService = serviceRegistry.getMimetypeService(); mimetypeService = serviceRegistry.getMimetypeService();
namespaceService = serviceRegistry.getNamespaceService(); namespaceService = serviceRegistry.getNamespaceService();
transactionService = serviceRegistry.getTransactionService();
authenticationComponent.setSystemUserAsCurrentUser(); authenticationComponent.setSystemUserAsCurrentUser();
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis()); StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
rootNodeRef = nodeService.getRootNode(storeRef); rootNodeRef = nodeService.getRootNode(storeRef);
} }
private FileImporter createFileImporter() private FileImporter createFileImporter(boolean txnPerFile)
{ {
FileImporterImpl fileImporter = new FileImporterImpl(); FileImporterImpl fileImporter = new FileImporterImpl();
fileImporter.setAuthenticationService(authenticationService); fileImporter.setAuthenticationService(authenticationService);
@@ -105,19 +104,21 @@ public class FileImporterTest extends TestCase
fileImporter.setMimetypeService(mimetypeService); fileImporter.setMimetypeService(mimetypeService);
fileImporter.setNodeService(nodeService); fileImporter.setNodeService(nodeService);
fileImporter.setDictionaryService(dictionaryService); fileImporter.setDictionaryService(dictionaryService);
fileImporter.setTransactionService(transactionService);
fileImporter.setTxnPerFile(txnPerFile);
return fileImporter; return fileImporter;
} }
public void testCreateFile() throws Exception public void testCreateFile() throws Exception
{ {
FileImporter fileImporter = createFileImporter(); FileImporter fileImporter = createFileImporter(false);
File file = AbstractContentTransformerTest.loadQuickTestFile("xml"); File file = AbstractContentTransformerTest.loadQuickTestFile("xml");
fileImporter.loadFile(rootNodeRef, file); fileImporter.loadFile(rootNodeRef, file);
} }
public void testLoadRootNonRecursive1() public void testLoadRootNonRecursive1()
{ {
FileImporter fileImporter = createFileImporter(); FileImporter fileImporter = createFileImporter(false);
URL url = this.getClass().getClassLoader().getResource(""); URL url = this.getClass().getClassLoader().getResource("");
File rootFile = new File(url.getFile()); File rootFile = new File(url.getFile());
int count = fileImporter.loadFile(rootNodeRef, rootFile); int count = fileImporter.loadFile(rootNodeRef, rootFile);
@@ -126,7 +127,7 @@ public class FileImporterTest extends TestCase
public void testLoadRootNonRecursive2() public void testLoadRootNonRecursive2()
{ {
FileImporter fileImporter = createFileImporter(); FileImporter fileImporter = createFileImporter(false);
URL url = this.getClass().getClassLoader().getResource(""); URL url = this.getClass().getClassLoader().getResource("");
File root = new File(url.getFile()); File root = new File(url.getFile());
int count = fileImporter.loadFile(rootNodeRef, root, null, false); int count = fileImporter.loadFile(rootNodeRef, root, null, false);
@@ -135,7 +136,7 @@ public class FileImporterTest extends TestCase
public void testLoadXMLFiles() public void testLoadXMLFiles()
{ {
FileImporter fileImporter = createFileImporter(); FileImporter fileImporter = createFileImporter(false);
URL url = this.getClass().getClassLoader().getResource(""); URL url = this.getClass().getClassLoader().getResource("");
FileFilter filter = new XMLFileFilter(); FileFilter filter = new XMLFileFilter();
fileImporter.loadFile(rootNodeRef, new File(url.getFile()), filter, true); fileImporter.loadFile(rootNodeRef, new File(url.getFile()), filter, true);
@@ -143,7 +144,7 @@ public class FileImporterTest extends TestCase
public void testLoadSourceTestResources() public void testLoadSourceTestResources()
{ {
FileImporter fileImporter = createFileImporter(); FileImporter fileImporter = createFileImporter(false);
URL url = this.getClass().getClassLoader().getResource("quick"); URL url = this.getClass().getClassLoader().getResource("quick");
FileFilter filter = new QuickFileFilter(); FileFilter filter = new QuickFileFilter();
fileImporter.loadFile(rootNodeRef, new File(url.getFile()), filter, true); fileImporter.loadFile(rootNodeRef, new File(url.getFile()), filter, true);
@@ -173,6 +174,7 @@ public class FileImporterTest extends TestCase
* <li>String: Directory to use as source (e.g. c:/temp) * <li>String: Directory to use as source (e.g. c:/temp)
* <li>String: New name to give the source. It may have a suffix added (e.g. upload_xxx) * <li>String: New name to give the source. It may have a suffix added (e.g. upload_xxx)
* <li>Integer: Number of times to repeat the load. * <li>Integer: Number of times to repeat the load.
* <li>Boolean: (optional - default 'false') Create each file/folder in a new transaction
* <li>String: (optional) user to authenticate as * <li>String: (optional) user to authenticate as
* <li>String: (optional) password for authentication * <li>String: (optional) password for authentication
* </ol> * </ol>
@@ -191,8 +193,9 @@ public class FileImporterTest extends TestCase
File sourceFile = new File(args[2]); File sourceFile = new File(args[2]);
String baseName = args[3]; String baseName = args[3];
int target = Integer.parseInt(args[4]); int target = Integer.parseInt(args[4]);
String userName = args.length > 5 ? args[5] : null; Boolean txnPerFile = args.length > 5 ? Boolean.parseBoolean(args[5]) : false;
String userPwd = args.length > 6 ? args[6] : ""; String userName = args.length > 6 ? args[6] : null;
String userPwd = args.length > 7 ? args[7] : "";
while (count < target) while (count < target)
{ {
count++; count++;
@@ -240,13 +243,19 @@ public class FileImporterTest extends TestCase
userPwd, userPwd,
test.authenticationService, test.authenticationService,
test.authenticationComponent); test.authenticationComponent);
}
tx.commit(); tx.commit();
// only begin if we are doing it all in one transaction
if (!txnPerFile)
{
tx = transactionService.getUserTransaction(); tx = transactionService.getUserTransaction();
tx.begin(); tx.begin();
} }
long start = System.nanoTime(); long start = System.nanoTime();
int importCount = test.createFileImporter().loadNamedFile( FileImporter importer = test.createFileImporter(txnPerFile);
int importCount = importer.loadNamedFile(
importLocation, importLocation,
sourceFile, sourceFile,
true, true,
@@ -257,7 +266,10 @@ public class FileImporterTest extends TestCase
System.out.println("Created in: " + ((end - start) / 1000000.0) + "ms"); System.out.println("Created in: " + ((end - start) / 1000000.0) + "ms");
start = System.nanoTime(); start = System.nanoTime();
if (!txnPerFile)
{
tx.commit(); tx.commit();
}
end = System.nanoTime(); end = System.nanoTime();
long second = end-start; long second = end-start;
System.out.println("Committed in: " + ((end - start) / 1000000.0) + "ms"); 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("Grand Total: "+ grandTotal);
System.out.println("Imported: " + importCount + " files or directories"); System.out.println("Imported: " + importCount + " files or directories");
System.out.println("Average: " + (importCount / (total / 1000.0)) + " files per second"); 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) catch (Throwable e)
{ {

View File

@@ -30,6 +30,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.node.StoreArchiveMap; import org.alfresco.repo.node.StoreArchiveMap;
import org.alfresco.repo.node.archive.RestoreNodeReport.RestoreStatus; import org.alfresco.repo.node.archive.RestoreNodeReport.RestoreStatus;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef; 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_A = "AAAAA";
private static final String USER_B = "BBBBB"; 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 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_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"); 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, QNAME_A,
ContentModel.TYPE_FOLDER, ContentModel.TYPE_FOLDER,
properties).getChildRef(); properties).getChildRef();
nodeService.addAspect(a, ASPECT_ATTACHABLE, null);
properties.put(ContentModel.PROP_NODE_UUID, "aa"); properties.put(ContentModel.PROP_NODE_UUID, "aa");
childAssocAtoAA = nodeService.createNode( childAssocAtoAA = nodeService.createNode(
a, a,
@@ -202,6 +205,7 @@ public class ArchiveAndRestoreTest extends TestCase
ContentModel.TYPE_CONTENT, ContentModel.TYPE_CONTENT,
properties); properties);
aa = childAssocAtoAA.getChildRef(); aa = childAssocAtoAA.getChildRef();
nodeService.addAspect(aa, ASPECT_ATTACHABLE, null);
properties.put(ContentModel.PROP_NODE_UUID, "b"); properties.put(ContentModel.PROP_NODE_UUID, "b");
b = nodeService.createNode( b = nodeService.createNode(
workStoreRootNodeRef, workStoreRootNodeRef,
@@ -326,6 +330,9 @@ public class ArchiveAndRestoreTest extends TestCase
verifyNodeExistence(b_, false); verifyNodeExistence(b_, false);
verifyNodeExistence(bb_, true); verifyNodeExistence(bb_, true);
// flush
AlfrescoTransactionSupport.flush();
// check that the required properties are present and correct // check that the required properties are present and correct
Map<QName, Serializable> bb_Properties = nodeService.getProperties(bb_); Map<QName, Serializable> bb_Properties = nodeService.getProperties(bb_);
Path bb_originalPath = (Path) bb_Properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_PATH); Path bb_originalPath = (Path) bb_Properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_PATH);
@@ -351,6 +358,9 @@ public class ArchiveAndRestoreTest extends TestCase
verifyNodeExistence(bb_, true); verifyNodeExistence(bb_, true);
verifyChildAssocExistence(childAssocBtoBB_, true); verifyChildAssocExistence(childAssocBtoBB_, true);
// flush
AlfrescoTransactionSupport.flush();
// restore the node // restore the node
nodeService.restoreNode(b_, null, null, null); nodeService.restoreNode(b_, null, null, null);
// check // check
@@ -362,6 +372,10 @@ public class ArchiveAndRestoreTest extends TestCase
// delete both trees in order 'b', 'a' // delete both trees in order 'b', 'a'
nodeService.deleteNode(b); nodeService.deleteNode(b);
nodeService.deleteNode(a); nodeService.deleteNode(a);
// flush
AlfrescoTransactionSupport.flush();
// restore in reverse order // restore in reverse order
nodeService.restoreNode(a_, null, null, null); nodeService.restoreNode(a_, null, null, null);
nodeService.restoreNode(b_, 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' // delete both trees in order 'b', 'a'
nodeService.deleteNode(a); nodeService.deleteNode(a);
nodeService.deleteNode(b); nodeService.deleteNode(b);
// flush
AlfrescoTransactionSupport.flush();
// restore in reverse order // restore in reverse order
nodeService.restoreNode(b_, null, null, null); nodeService.restoreNode(b_, null, null, null);
nodeService.restoreNode(a_, null, null, null); nodeService.restoreNode(a_, null, null, null);
@@ -386,6 +404,10 @@ public class ArchiveAndRestoreTest extends TestCase
// delete a then b // delete a then b
nodeService.deleteNode(a); nodeService.deleteNode(a);
nodeService.deleteNode(b); nodeService.deleteNode(b);
// flush
AlfrescoTransactionSupport.flush();
// in restoring 'a' first, there will be some associations that won't be recreated // in restoring 'a' first, there will be some associations that won't be recreated
nodeService.restoreNode(a_, null, null, null); nodeService.restoreNode(a_, null, null, null);
nodeService.restoreNode(b_, null, null, null); nodeService.restoreNode(b_, null, null, null);
@@ -438,6 +460,10 @@ public class ArchiveAndRestoreTest extends TestCase
nodeService.deleteNode(b); nodeService.deleteNode(b);
long end = System.nanoTime(); long end = System.nanoTime();
cumulatedArchiveTimeNs += (end - start); cumulatedArchiveTimeNs += (end - start);
// flush
AlfrescoTransactionSupport.flush();
// now restore // now restore
start = System.nanoTime(); start = System.nanoTime();
nodeService.restoreNode(b_, null, null, null); nodeService.restoreNode(b_, null, null, null);
@@ -565,4 +591,21 @@ public class ArchiveAndRestoreTest extends TestCase
// List<RestoreNodeReport> restoredByB = nodeArchiveService.restoreAllArchivedNodes(workStoreRef); // List<RestoreNodeReport> restoredByB = nodeArchiveService.restoreAllArchivedNodes(workStoreRef);
// assertEquals("User B should not have seen A's delete", 1, restoredByB.size()); // 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());
// }
} }

View File

@@ -1559,6 +1559,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
// remove the aspect archived aspect // remove the aspect archived aspect
aspects.remove(ContentModel.ASPECT_ARCHIVED); aspects.remove(ContentModel.ASPECT_ARCHIVED);
properties.remove(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC); 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_BY);
properties.remove(ContentModel.PROP_ARCHIVED_DATE); properties.remove(ContentModel.PROP_ARCHIVED_DATE);

View File

@@ -16,7 +16,6 @@
*/ */
package org.alfresco.repo.node.db; package org.alfresco.repo.node.db;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.alfresco.repo.domain.ChildAssoc; import org.alfresco.repo.domain.ChildAssoc;
@@ -42,6 +41,11 @@ public interface NodeDaoService
*/ */
public boolean isDirty(); public boolean isDirty();
/**
* Flush the data changes to the persistence layer.
*/
public void flush();
/** /**
* Fetch a list of all stores in the repository * Fetch a list of all stores in the repository
* *
@@ -168,16 +172,6 @@ public interface NodeDaoService
Node targetNode, Node targetNode,
QName assocTypeQName); QName assocTypeQName);
/**
* @return Returns the target nodes for the association
*/
public Collection<Node> getNodeAssocTargets(Node sourceNode, QName assocTypeQName);
/**
* @return Returns the source nodes for the association
*/
public Collection<Node> getNodeAssocSources(Node targetNode, QName assocTypeQName);
/** /**
* @param assoc the node association to remove * @param assoc the node association to remove
*/ */

View File

@@ -36,6 +36,7 @@ import org.alfresco.repo.domain.hibernate.StoreImpl;
import org.alfresco.repo.node.db.NodeDaoService; import org.alfresco.repo.node.db.NodeDaoService;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.dictionary.InvalidTypeException; 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.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
@@ -56,9 +57,6 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements NodeDaoService public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements NodeDaoService
{ {
private static final String QUERY_GET_ALL_STORES = "store.GetAllStores"; 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"; private static final String QUERY_GET_CONTENT_DATA_STRINGS = "node.GetContentDataStrings";
/** a uuid identifying this unique instance */ /** a uuid identifying this unique instance */
@@ -117,6 +115,14 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
return ((Boolean)getHibernateTemplate().execute(callback)).booleanValue(); return ((Boolean)getHibernateTemplate().execute(callback)).booleanValue();
} }
/**
* Just flushes the session
*/
public void flush()
{
getSession().flush();
}
/** /**
* @see #QUERY_GET_ALL_STORES * @see #QUERY_GET_ALL_STORES
*/ */
@@ -337,7 +343,6 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
assoc.setTypeQName(assocTypeQName); assoc.setTypeQName(assocTypeQName);
assoc.setIsPrimary(isPrimary); assoc.setIsPrimary(isPrimary);
assoc.setQname(qname); assoc.setQname(qname);
// assoc.setIsArchived(false);
assoc.buildAssociation(parentNode, childNode); assoc.buildAssociation(parentNode, childNode);
// persist // persist
getHibernateTemplate().save(assoc); getHibernateTemplate().save(assoc);
@@ -450,7 +455,6 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
{ {
NodeAssoc assoc = new NodeAssocImpl(); NodeAssoc assoc = new NodeAssocImpl();
assoc.setTypeQName(assocTypeQName); assoc.setTypeQName(assocTypeQName);
// assoc.setIsArchived(false);
assoc.buildAssociation(sourceNode, targetNode); assoc.buildAssociation(sourceNode, targetNode);
// persist // persist
getHibernateTemplate().save(assoc); getHibernateTemplate().save(assoc);
@@ -463,62 +467,27 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
final Node targetNode, final Node targetNode,
final QName assocTypeQName) final QName assocTypeQName)
{ {
HibernateCallback callback = new HibernateCallback() AssociationRef nodeAssocRef = new AssociationRef(
sourceNode.getNodeRef(),
assocTypeQName,
targetNode.getNodeRef());
// get all the source's target associations
Collection<NodeAssoc> 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); continue;
query.setEntity("sourceNode", sourceNode)
.setEntity("targetNode", targetNode)
.setString("assocTypeQName", assocTypeQName.toString())
.setMaxResults(1);
return query.uniqueResult();
} }
}; else
Object queryResult = getHibernateTemplate().execute(callback);
if (queryResult == null)
{ {
return null;
}
NodeAssoc assoc = (NodeAssoc) queryResult;
// done
return assoc; return assoc;
} }
@SuppressWarnings("unchecked")
public Collection<Node> 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();
} }
}; // not found
List<Node> queryResults = (List) getHibernateTemplate().execute(callback); return null;
// done
return queryResults;
}
@SuppressWarnings("unchecked")
public Collection<Node> 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<Node> queryResults = (List) getHibernateTemplate().execute(callback);
// done
return queryResults;
} }
public void deleteNodeAssoc(NodeAssoc assoc) public void deleteNodeAssoc(NodeAssoc assoc)

View File

@@ -116,7 +116,6 @@ public class LuceneIndexerImpl extends LuceneBase implements LuceneIndexer
* *
* TODO: Consider if this information needs to be persisted for recovery * TODO: Consider if this information needs to be persisted for recovery
*/ */
private Set<NodeRef> deletions = new LinkedHashSet<NodeRef>(); private Set<NodeRef> deletions = new LinkedHashSet<NodeRef>();
/** /**
@@ -1738,6 +1737,11 @@ public class LuceneIndexerImpl extends LuceneBase implements LuceneIndexer
{ {
// Document document = helper.document; // Document document = helper.document;
NodeRef ref = helper.nodeRef; NodeRef ref = helper.nodeRef;
// bypass nodes that have disappeared
if (!nodeService.exists(ref))
{
continue;
}
List<Document> docs = createDocuments(ref, false, true, false); List<Document> docs = createDocuments(ref, false, true, false);
for (Document doc : docs) for (Document doc : docs)

View File

@@ -69,6 +69,17 @@ public abstract class AbstractPermissionEntry implements PermissionEntry
return hashCode; 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();
}
} }

View File

@@ -523,6 +523,11 @@ public abstract class AlfrescoTransactionSupport
{ {
listener.flush(); listener.flush();
} }
// flush changes
for (NodeDaoService nodeDaoServices : getNodeDaoServices())
{
nodeDaoServices.flush();
}
} }
/** /**