Merged V3.4-BUG-FIX to HEAD

28158: ALF-8925: Merged V3.3 to V3.4-BUG-FIX
      28121: ALF-8878: Prevent authentication errors in SMBSrvSession.cleanupSession()
   28159: Merged HEAD to V3.4-BUG-FIX (RECORD ONLY)
      27951: Fixed merge issue in ContentDiskDriverTest
   28161: ALF-8861: Fix from Bitrock to kill OpenOffice process on uninstallation if all else fails
   28165: ALF-8260: Corrected French translations of 'Library'
   28166: Fix for ALF-8751 - Dates are not localized in Document Lists dashlet
   28167: Fix for ALF-8493
   28169: ALF-5797: Translation corrections to complex strings
   28171: Merged DEV TO V3.4-BUG-FIX 
      ALF-8808 : CLONE - NFS: User with editor role cannot edit content - unit test required
   28181: Fixed ALF-280: Unfriendly message appears when trying to specify non-existent file-store
   28184: Merged BRANCHES/DEV/BELARUS/V3.4-BUG-FIX-2011_04_12 to BRANCHES/DEV/V3.4-BUG-FIX:
      28179: ALF-8754: Cannot preview content on other webapp folder than ROOT (merged w/ trivial clean-up)
   28185: Fixed ALF-8020: Multivalue date in document details causes error in alfresco share   
      NOTE: We do not support any multi-valued fields other than text currently, this fix is therefore to handle the case where a multivalued date or dateTime field is configured in a form. The form will list the dates in view mode but in create and edit modes the control is not displayed at all when there are multiple values, if there is only one value the control continues to function as it has done previously.
   28188: Fix for ALF-731 - in a cluster environment (high availibility), when a node goes down, the users are asked to login


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28208 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2011-06-06 10:57:20 +00:00
parent 02e3d817de
commit a8f0689c1c
5 changed files with 379 additions and 149 deletions

View File

@@ -3448,8 +3448,10 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Check permissions on the file/folder node // Check permissions on the file/folder node
if ( permissionService.hasPermission(nodeRef, PermissionService.WRITE) == AccessStatus.DENIED) if ( permissionService.hasPermission(nodeRef, PermissionService.WRITE) == AccessStatus.DENIED)
throw new org.alfresco.repo.security.permissions.AccessDeniedException("No write access to " + name); {
throw new AccessDeniedException("No write access to " + name);
}
// Inhibit versioning for this transaction // Inhibit versioning for this transaction
getPolicyFilter().disableBehaviour( ContentModel.ASPECT_VERSIONABLE); getPolicyFilter().disableBehaviour( ContentModel.ASPECT_VERSIONABLE);
@@ -3459,7 +3461,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
if ( info.hasSetFlag(FileInfo.SetDeleteOnClose) && info.hasDeleteOnClose()) if ( info.hasSetFlag(FileInfo.SetDeleteOnClose) && info.hasDeleteOnClose())
{ {
// Check deleting permissions on the node if action of deleting was configured only // Check deleting permissions on the node if action of deleting was configured only
if ((AccessStatus.DENIED == permissionService.hasPermission(nodeRef, PermissionService.DELETE)) && (null == fstate.findAttribute(CanDeleteWithoutPerms))) if ((AccessStatus.DENIED == permissionService.hasPermission(nodeRef, PermissionService.DELETE))
&& ((null == fstate) || (null == fstate.findAttribute(CanDeleteWithoutPerms))))
{ {
throw new org.alfresco.repo.security.permissions.AccessDeniedException("No delete access to " + name); throw new org.alfresco.repo.security.permissions.AccessDeniedException("No delete access to " + name);
} }

View File

@@ -23,13 +23,13 @@ import java.io.InputStream;
import java.io.Serializable; import java.io.Serializable;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.transaction.UserTransaction; import javax.transaction.UserTransaction;
import javax.xml.ws.Holder;
import junit.framework.TestCase; import junit.framework.TestCase;
@@ -39,6 +39,7 @@ import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.jlan.server.core.DeviceContext; import org.alfresco.jlan.server.core.DeviceContext;
import org.alfresco.jlan.server.core.DeviceContextException; import org.alfresco.jlan.server.core.DeviceContextException;
import org.alfresco.jlan.server.core.SharedDevice; import org.alfresco.jlan.server.core.SharedDevice;
import org.alfresco.jlan.server.filesys.AccessDeniedException;
import org.alfresco.jlan.server.filesys.AccessMode; import org.alfresco.jlan.server.filesys.AccessMode;
import org.alfresco.jlan.server.filesys.DiskSharedDevice; import org.alfresco.jlan.server.filesys.DiskSharedDevice;
import org.alfresco.jlan.server.filesys.FileAction; import org.alfresco.jlan.server.filesys.FileAction;
@@ -56,6 +57,7 @@ import org.alfresco.repo.action.evaluator.NoConditionEvaluator;
import org.alfresco.repo.management.subsystems.ApplicationContextFactory; import org.alfresco.repo.management.subsystems.ApplicationContextFactory;
import org.alfresco.repo.model.Repository; import org.alfresco.repo.model.Repository;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.transfer.TransferModel; import org.alfresco.repo.transfer.TransferModel;
@@ -63,6 +65,7 @@ import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionCondition; import org.alfresco.service.cmr.action.ActionCondition;
import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.action.CompositeAction; import org.alfresco.service.cmr.action.CompositeAction;
import org.alfresco.service.cmr.model.FileFolderService;
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;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
@@ -70,13 +73,19 @@ import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.MLText; import org.alfresco.service.cmr.repository.MLText;
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.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.rule.Rule; import org.alfresco.service.cmr.rule.Rule;
import org.alfresco.service.cmr.rule.RuleService; import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.service.cmr.rule.RuleType; import org.alfresco.service.cmr.rule.RuleType;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
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.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.Pair;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@@ -88,6 +97,12 @@ import org.springframework.extensions.config.element.GenericConfigElement;
*/ */
public class ContentDiskDriverTest extends TestCase public class ContentDiskDriverTest extends TestCase
{ {
private static final String TEST_PROTOTYPE_NAME = "test";
private static final String TEST_REMOTE_NAME = "remoteName";
private static final String TEST_SERVER_NAME = "testServer";
private static final String TEST_USER_AUTHORITY = "userx";
private Repository repositoryHelper; private Repository repositoryHelper;
private CifsHelper cifsHelper; private CifsHelper cifsHelper;
private ContentDiskDriver driver; private ContentDiskDriver driver;
@@ -97,6 +112,11 @@ public class ContentDiskDriverTest extends TestCase
private ContentService contentService; private ContentService contentService;
private RuleService ruleService; private RuleService ruleService;
private ActionService actionService; private ActionService actionService;
private PersonService personService;
private MutableAuthenticationService authenticationService;
private PermissionService permissionService;
private OwnableService ownableService;
private FileFolderService fileFolderService;
private static Log logger = LogFactory.getLog(ContentDiskDriverTest.class); private static Log logger = LogFactory.getLog(ContentDiskDriverTest.class);
@@ -123,6 +143,11 @@ public class ContentDiskDriverTest extends TestCase
contentService = (ContentService)applicationContext.getBean("contentService"); contentService = (ContentService)applicationContext.getBean("contentService");
ruleService = (RuleService)applicationContext.getBean("ruleService"); ruleService = (RuleService)applicationContext.getBean("ruleService");
actionService = (ActionService)this.applicationContext.getBean("actionService"); actionService = (ActionService)this.applicationContext.getBean("actionService");
personService = (PersonService) this.applicationContext.getBean("personService");
authenticationService = (MutableAuthenticationService) this.applicationContext.getBean("authenticationService");
permissionService = (PermissionService) this.applicationContext.getBean("permissionService");
ownableService = (OwnableService) this.applicationContext.getBean("ownableService");
fileFolderService = (FileFolderService) this.applicationContext.getBean("fileFolderService");
assertNotNull("content disk driver is null", driver); assertNotNull("content disk driver is null", driver);
assertNotNull("repositoryHelper is null", repositoryHelper); assertNotNull("repositoryHelper is null", repositoryHelper);
@@ -441,158 +466,158 @@ public class ContentDiskDriverTest extends TestCase
/* /*
* MER : I can't see what DeleteOnClose does. Test commented out * MER : I can't see what DeleteOnClose does. Test commented out
*/ */
public void testSetFileInfo() throws Exception // public void testSetFileInfo() throws Exception
{ // {
logger.debug("testSetFileInfo"); // logger.debug("testSetFileInfo");
ServerConfiguration scfg = new ServerConfiguration("testServer"); // ServerConfiguration scfg = new ServerConfiguration("testServer");
TestServer testServer = new TestServer("testServer", scfg); // TestServer testServer = new TestServer("testServer", scfg);
final SrvSession testSession = new TestSrvSession(666, testServer, "test", "remoteName"); // final SrvSession testSession = new TestSrvSession(666, testServer, "test", "remoteName");
DiskSharedDevice share = getDiskSharedDevice(); // DiskSharedDevice share = getDiskSharedDevice();
final TreeConnection testConnection = testServer.getTreeConnection(share); // final TreeConnection testConnection = testServer.getTreeConnection(share);
final RetryingTransactionHelper tran = transactionService.getRetryingTransactionHelper(); // final RetryingTransactionHelper tran = transactionService.getRetryingTransactionHelper();
//
Date now = new Date(); // Date now = new Date();
//
// CREATE 6 hours ago // // CREATE 6 hours ago
final Date CREATED = new Date(now.getTime() - 1000 * 60 * 60 * 6); // final Date CREATED = new Date(now.getTime() - 1000 * 60 * 60 * 6);
// Modify one hour ago // // Modify one hour ago
final Date MODIFIED = new Date(now.getTime() - 1000 * 60 * 60 * 1); // final Date MODIFIED = new Date(now.getTime() - 1000 * 60 * 60 * 1);
//
class TestContext // class TestContext
{ // {
NodeRef testNodeRef; // NodeRef testNodeRef;
}; // };
//
final TestContext testContext = new TestContext(); // final TestContext testContext = new TestContext();
//
/**
* Step 1 : Create a new file in read/write mode and add some content.
* Call SetInfo to set the creation date
*/
int openAction = FileAction.CreateNotExist;
final String FILE_NAME="testSetFileInfo.txt";
final String FILE_PATH="\\"+FILE_NAME;
final FileOpenParams params = new FileOpenParams(FILE_PATH, openAction, AccessMode.ReadWrite, FileAttribute.NTNormal, 0);
final NetworkFile file = driver.createFile(testSession, testConnection, params);
assertNotNull("file is null", file);
assertFalse("file is read only, should be read-write", file.isReadOnly());
RetryingTransactionCallback<Void> writeStuffCB = new RetryingTransactionCallback<Void>() {
@Override
public Void execute() throws Throwable
{
byte[] stuff = "Hello World".getBytes();
file.writeFile(stuff, stuff.length, 0, 0);
file.close(); // needed to actually flush content to node
FileInfo info = driver.getFileInformation(testSession, testConnection, FILE_PATH);
info.setFileInformationFlags(FileInfo.SetModifyDate);
info.setModifyDateTime(MODIFIED.getTime());
driver.setFileInformation(testSession, testConnection, FILE_PATH, info);
return null;
}
};
tran.doInTransaction(writeStuffCB);
RetryingTransactionCallback<Void> validateCB = new RetryingTransactionCallback<Void>() {
@Override
public Void execute() throws Throwable
{
NodeRef companyHome = repositoryHelper.getCompanyHome();
NodeRef newNode = nodeService.getChildByName(companyHome, ContentModel.ASSOC_CONTAINS, FILE_NAME);
testContext.testNodeRef = newNode;
assertNotNull("can't find new node", newNode);
Serializable content = nodeService.getProperty(newNode, ContentModel.PROP_CONTENT);
assertNotNull("content is null", content);
Date modified = (Date)nodeService.getProperty(newNode, ContentModel.PROP_MODIFIED);
assertEquals("modified time not set correctly", MODIFIED, modified);
return null;
}
};
tran.doInTransaction(validateCB);
/**
* Step 2: Change the created date
*/
logger.debug("Step 2: Change the created date");
RetryingTransactionCallback<Void> changeCreatedCB = new RetryingTransactionCallback<Void>() {
@Override
public Void execute() throws Throwable
{
FileInfo info = driver.getFileInformation(testSession, testConnection, FILE_PATH);
info.setFileInformationFlags(FileInfo.SetCreationDate);
info.setCreationDateTime(CREATED.getTime());
driver.setFileInformation(testSession, testConnection, FILE_PATH, info);
return null;
}
};
tran.doInTransaction(changeCreatedCB);
RetryingTransactionCallback<Void> validateCreatedCB = new RetryingTransactionCallback<Void>() {
@Override
public Void execute() throws Throwable
{
NodeRef companyHome = repositoryHelper.getCompanyHome();
NodeRef newNode = nodeService.getChildByName(companyHome, ContentModel.ASSOC_CONTAINS, FILE_NAME);
testContext.testNodeRef = newNode;
assertNotNull("can't find new node", newNode);
Serializable content = nodeService.getProperty(newNode, ContentModel.PROP_CONTENT);
assertNotNull("content is null", content);
Date created = (Date)nodeService.getProperty(newNode, ContentModel.PROP_CREATED);
assertEquals("created time not set correctly", CREATED, created);
return null;
}
};
tran.doInTransaction(validateCreatedCB);
// /** // /**
// * Step 3: Test // * Step 1 : Create a new file in read/write mode and add some content.
// */ // * Call SetInfo to set the creation date
// logger.debug("Step 3: test deleteOnClose"); // */
// RetryingTransactionCallback<Void> deleteOnCloseCB = new RetryingTransactionCallback<Void>() { // int openAction = FileAction.CreateNotExist;
//
// final String FILE_NAME="testSetFileInfo.txt";
// final String FILE_PATH="\\"+FILE_NAME;
//
// final FileOpenParams params = new FileOpenParams(FILE_PATH, openAction, AccessMode.ReadWrite, FileAttribute.NTNormal, 0);
//
// final NetworkFile file = driver.createFile(testSession, testConnection, params);
// assertNotNull("file is null", file);
// assertFalse("file is read only, should be read-write", file.isReadOnly());
//
// RetryingTransactionCallback<Void> writeStuffCB = new RetryingTransactionCallback<Void>() {
// //
// @Override // @Override
// public Void execute() throws Throwable // public Void execute() throws Throwable
// { // {
// NetworkFile f2 = driver.openFile(testSession, testConnection, params); // byte[] stuff = "Hello World".getBytes();
// // file.writeFile(stuff, stuff.length, 0, 0);
// FileInfo info = driver.getFileInformation(testSession, testConnection, FILE_PATH); // file.close(); // needed to actually flush content to node
// info.setFileInformationFlags(FileInfo.SetDeleteOnClose); //
// driver.setFileInformation(testSession, testConnection, FILE_PATH, info); // FileInfo info = driver.getFileInformation(testSession, testConnection, FILE_PATH);
// // info.setFileInformationFlags(FileInfo.SetModifyDate);
// byte[] stuff = "Update".getBytes(); // info.setModifyDateTime(MODIFIED.getTime());
// f2.writeFile(stuff, stuff.length, 0, 0); // driver.setFileInformation(testSession, testConnection, FILE_PATH, info);
// f2.close(); // needed to actually flush content to node // return null;
//
// return null;
// } // }
// }; // };
// tran.doInTransaction(deleteOnCloseCB); // tran.doInTransaction(writeStuffCB);
// //
// RetryingTransactionCallback<Void> validateDeleteOnCloseCB = new RetryingTransactionCallback<Void>() { // RetryingTransactionCallback<Void> validateCB = new RetryingTransactionCallback<Void>() {
// //
// @Override // @Override
// public Void execute() throws Throwable // public Void execute() throws Throwable
// { // {
// NodeRef companyHome = repositoryHelper.getCompanyHome(); // NodeRef companyHome = repositoryHelper.getCompanyHome();
// NodeRef newNode = nodeService.getChildByName(companyHome, ContentModel.ASSOC_CONTAINS, FILE_NAME); // NodeRef newNode = nodeService.getChildByName(companyHome, ContentModel.ASSOC_CONTAINS, FILE_NAME);
// assertNull("can still find new node", newNode); // testContext.testNodeRef = newNode;
// assertNotNull("can't find new node", newNode);
// Serializable content = nodeService.getProperty(newNode, ContentModel.PROP_CONTENT);
// assertNotNull("content is null", content);
// Date modified = (Date)nodeService.getProperty(newNode, ContentModel.PROP_MODIFIED);
// assertEquals("modified time not set correctly", MODIFIED, modified);
// return null; // return null;
// } // }
// }; // };
// tran.doInTransaction(validateDeleteOnCloseCB); // tran.doInTransaction(validateCB);
//
// clean up so we could run the test again // /**
driver.deleteFile(testSession, testConnection, FILE_PATH); // * Step 2: Change the created date
// */
} // test set file info // logger.debug("Step 2: Change the created date");
// RetryingTransactionCallback<Void> changeCreatedCB = new RetryingTransactionCallback<Void>() {
//
// @Override
// public Void execute() throws Throwable
// {
// FileInfo info = driver.getFileInformation(testSession, testConnection, FILE_PATH);
// info.setFileInformationFlags(FileInfo.SetCreationDate);
// info.setCreationDateTime(CREATED.getTime());
// driver.setFileInformation(testSession, testConnection, FILE_PATH, info);
// return null;
// }
// };
// tran.doInTransaction(changeCreatedCB);
//
// RetryingTransactionCallback<Void> validateCreatedCB = new RetryingTransactionCallback<Void>() {
//
// @Override
// public Void execute() throws Throwable
// {
// NodeRef companyHome = repositoryHelper.getCompanyHome();
// NodeRef newNode = nodeService.getChildByName(companyHome, ContentModel.ASSOC_CONTAINS, FILE_NAME);
// testContext.testNodeRef = newNode;
// assertNotNull("can't find new node", newNode);
// Serializable content = nodeService.getProperty(newNode, ContentModel.PROP_CONTENT);
// assertNotNull("content is null", content);
// Date created = (Date)nodeService.getProperty(newNode, ContentModel.PROP_CREATED);
// assertEquals("created time not set correctly", CREATED, created);
// return null;
// }
// };
// tran.doInTransaction(validateCreatedCB);
//
//// /**
//// * Step 3: Test
//// */
//// logger.debug("Step 3: test deleteOnClose");
//// RetryingTransactionCallback<Void> deleteOnCloseCB = new RetryingTransactionCallback<Void>() {
////
//// @Override
//// public Void execute() throws Throwable
//// {
//// NetworkFile f2 = driver.openFile(testSession, testConnection, params);
////
//// FileInfo info = driver.getFileInformation(testSession, testConnection, FILE_PATH);
//// info.setFileInformationFlags(FileInfo.SetDeleteOnClose);
//// driver.setFileInformation(testSession, testConnection, FILE_PATH, info);
////
//// byte[] stuff = "Update".getBytes();
//// f2.writeFile(stuff, stuff.length, 0, 0);
//// f2.close(); // needed to actually flush content to node
////
//// return null;
//// }
//// };
//// tran.doInTransaction(deleteOnCloseCB);
////
//// RetryingTransactionCallback<Void> validateDeleteOnCloseCB = new RetryingTransactionCallback<Void>() {
////
//// @Override
//// public Void execute() throws Throwable
//// {
//// NodeRef companyHome = repositoryHelper.getCompanyHome();
//// NodeRef newNode = nodeService.getChildByName(companyHome, ContentModel.ASSOC_CONTAINS, FILE_NAME);
//// assertNull("can still find new node", newNode);
//// return null;
//// }
//// };
//// tran.doInTransaction(validateDeleteOnCloseCB);
//
// // clean up so we could run the test again
// driver.deleteFile(testSession, testConnection, FILE_PATH);
//
// } // test set file info
/** /**
@@ -2512,7 +2537,177 @@ public class ContentDiskDriverTest extends TestCase
}; };
tran.doInTransaction(deleteNodeCB, false, true); tran.doInTransaction(deleteNodeCB, false, true);
} //testDirListing } //testDirListing
public void testFileInformationUpdatingByEditorUserForAlf8808() throws Exception
{
final Holder<org.alfresco.service.cmr.model.FileInfo> editorFolder = new Holder<org.alfresco.service.cmr.model.FileInfo>();
final Holder<org.alfresco.service.cmr.model.FileInfo> testFile = new Holder<org.alfresco.service.cmr.model.FileInfo>();
// Configuring test server with test server configuration and getting test tree connection for test shared device
ServerConfiguration config = new ServerConfiguration(ContentDiskDriverTest.TEST_SERVER_NAME);
TestServer server = new TestServer(ContentDiskDriverTest.TEST_SERVER_NAME, config);
DiskSharedDevice device = getDiskSharedDevice();
final TreeConnection treeConnection = server.getTreeConnection(device);
// Getting target entity for testing - ContentDiskDriver
final ContentDiskDriver deviceInterface = (ContentDiskDriver) treeConnection.getInterface();
// Creating mock-session
final SrvSession session = new TestSrvSession(13, server, ContentDiskDriverTest.TEST_PROTOTYPE_NAME, ContentDiskDriverTest.TEST_REMOTE_NAME);
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
{
@Override
public Void execute() throws Throwable
{
try
{
NodeRef rootNode = repositoryHelper.getCompanyHome();
// Creating test user to invite him as Editor for test content. This user will be created correctly (with person and authentication options)
createUser(ContentDiskDriverTest.TEST_USER_AUTHORITY, ContentDiskDriverTest.TEST_USER_AUTHORITY, rootNode);
// Safely creating folder for test content
editorFolder.value = getOrCreateNode(rootNode, PermissionService.EDITOR, ContentModel.TYPE_FOLDER).getFirst();
// Creating test content which will be editable by user created above
testFile.value = getOrCreateNode(rootNode, "Test.txt", ContentModel.TYPE_CONTENT).getFirst();
// Applying 'Editor' role for test user to test file
permissionService.setPermission(testFile.value.getNodeRef(), ContentDiskDriverTest.TEST_USER_AUTHORITY, PermissionService.EDITOR, true);
try
{
// Creating data for target method invocation
final FileInfo updatedInfo = new FileInfo();
updatedInfo.setFileName(testFile.value.getName());
updatedInfo.setFileId(DefaultTypeConverter.INSTANCE.intValue(testFile.value.getProperties().get(ContentModel.PROP_NODE_DBID)));
// Testing ContentDiskDriver.setFileInformation() with test user authenticated who has 'Editor' role for test content.
// This method should fail if check on 'DELETE' permission was not moved to 'DeleteOnClose' context
AuthenticationUtil.runAs(new RunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
deviceInterface.setFileInformation(session, treeConnection, testFile.value.getName(), updatedInfo);
return null;
}
}, ContentDiskDriverTest.TEST_USER_AUTHORITY);
}
catch (Exception e)
{
// Informing about test failure. Expected exception is 'org.alfresco.jlan.server.filesys.AccessDeniedException'
if (e.getCause() instanceof AccessDeniedException)
{
fail("For user='" + TEST_USER_AUTHORITY + "' " + e.getCause().toString());
}
else
{
fail("Unexpected exception was caught: " + e.toString());
}
}
}
finally
{
// Cleaning all test data and rolling back transaction to revert all introduced changes during testing
if (authenticationService.authenticationExists(ContentDiskDriverTest.TEST_USER_AUTHORITY))
{
authenticationService.deleteAuthentication(ContentDiskDriverTest.TEST_USER_AUTHORITY);
}
if (personService.personExists(ContentDiskDriverTest.TEST_USER_AUTHORITY))
{
personService.deletePerson(ContentDiskDriverTest.TEST_USER_AUTHORITY);
}
try
{
if (null != testFile.value)
{
nodeService.deleteNode(testFile.value.getNodeRef());
}
}
catch (Exception e)
{
// Doing nothing
}
try
{
if (null != editorFolder.value)
{
nodeService.deleteNode(editorFolder.value.getNodeRef());
}
}
catch (Exception e)
{
// Doing nothing
}
}
return null;
}
}, false, true);
}
/**
* Searching for file object with specified name or creating new one if such object is not exist
*
* @param parentRef - {@link NodeRef} of desired parent object
* @param name - {@link String} value for name of desired file object
* @param type - {@link QName} instance which determines type of the object. It may be cm:content, cm:folder etc (see {@link ContentModel})
* @return {@link Pair}&lt;{@link org.alfresco.service.cmr.model.FileInfo}, {@link Boolean}> instance which contains {@link NodeRef} of newly created object and
* <code>true</code> value if file object with specified name was not found or {@link NodeRef} of existent file object and <code>false</code> in other case
*/
private Pair<org.alfresco.service.cmr.model.FileInfo, Boolean> getOrCreateNode(NodeRef parentRef, String name, QName type)
{
NodeRef result = nodeService.getChildByName(parentRef, ContentModel.ASSOC_CONTAINS, name);
Boolean created = false;
if (null == result)
{
result = nodeService.getChildByName(parentRef, ContentModel.ASSOC_CHILDREN, name);
}
if (created = (null == result))
{
result = fileFolderService.create(parentRef, name, type).getNodeRef();
}
return new Pair<org.alfresco.service.cmr.model.FileInfo, Boolean>(fileFolderService.getFileInfo(result), created);
}
/**
* Creates correct user entity with correct user home space, person and authentication with password equal to '<code>password</code>' options if these options are not exist.
* Method searches for space with name equal to '<code>name</code>' to make it user home space or creates new folder with name equal to '<code>name</code>'. All required
* permissions and roles will be applied to user home space
*
* @param name - {@link String} value which contains new user name
* @param password - {@link String} value of text password for new user
* @param parentNodeRef - {@link NodeRef} instance of parent folder where user home space should be found or created
*/
private void createUser(String name, String password, NodeRef parentNodeRef)
{
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_USERNAME, name);
Pair<org.alfresco.service.cmr.model.FileInfo, Boolean> userHome = getOrCreateNode(parentNodeRef, name, ContentModel.TYPE_FOLDER);
if (userHome.getSecond())
{
NodeRef nodeRef = userHome.getFirst().getNodeRef();
permissionService.setPermission(nodeRef, name, permissionService.getAllPermission(), true);
permissionService.setPermission(nodeRef, permissionService.getAllAuthorities(), PermissionService.CONSUMER, true);
permissionService.setPermission(nodeRef, permissionService.getOwnerAuthority(), permissionService.getAllPermission(), true);
ownableService.setOwner(nodeRef, name);
permissionService.setInheritParentPermissions(nodeRef, false);
properties.put(ContentModel.PROP_HOMEFOLDER, nodeRef);
if (!personService.personExists(name))
{
personService.createPerson(properties);
}
if (!authenticationService.authenticationExists(name))
{
authenticationService.createAuthentication(name, password.toCharArray());
}
}
}
/** /**
* Test server * Test server
*/ */

View File

@@ -24,6 +24,7 @@ import static org.alfresco.repo.forms.processor.node.FormFieldConstants.PROP_DAT
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -42,6 +43,7 @@ import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.Period; import org.alfresco.service.cmr.repository.Period;
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.util.ISO8601DateFormat;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@@ -116,6 +118,26 @@ public class PropertyFieldProcessor extends QNameFieldProcessor<PropertyDefiniti
// a separate field for each value once we have full // a separate field for each value once we have full
// UI support in place. // UI support in place.
Collection<?> values = (Collection<?>) value; Collection<?> values = (Collection<?>) value;
// if the non empty collection is a List of Date objects
// we need to convert each date to a ISO8601 format
if (value instanceof List<?> && !values.isEmpty())
{
List<?> list = (List<?>)values;
if (list.get(0) instanceof Date)
{
List<String> isoDates = new ArrayList<String>(list.size());
for (Object date : list)
{
isoDates.add(ISO8601DateFormat.format((Date)date));
}
// return the ISO formatted dates as a comma delimited string
return StringUtils.collectionToCommaDelimitedString(isoDates);
}
}
// return everything else using toString()
return StringUtils.collectionToCommaDelimitedString(values); return StringUtils.collectionToCommaDelimitedString(values);
} }
else if (value instanceof ContentData) else if (value instanceof ContentData)

View File

@@ -38,9 +38,11 @@ import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.service.cmr.repository.TemplateValueConverter; import org.alfresco.service.cmr.repository.TemplateValueConverter;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
import freemarker.cache.MruCacheStorage; import freemarker.cache.MruCacheStorage;
import freemarker.cache.StringTemplateLoader; import freemarker.cache.StringTemplateLoader;
import freemarker.core.Environment;
import freemarker.template.Configuration; import freemarker.template.Configuration;
import freemarker.template.Template; import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler; import freemarker.template.TemplateExceptionHandler;
@@ -194,7 +196,10 @@ public class FreeMarkerProcessor extends BaseProcessor implements TemplateProces
{ {
// perform the template processing against supplied data model // perform the template processing against supplied data model
Object freeMarkerModel = convertToFreeMarkerModel(model); Object freeMarkerModel = convertToFreeMarkerModel(model);
t.process(freeMarkerModel, out); Environment env = t.createProcessingEnvironment(freeMarkerModel, out);
// set the locale to ensure dates etc. are appropriate localised
env.setLocale(I18NUtil.getLocale());
env.process();
} }
catch (Throwable err) catch (Throwable err)
{ {

View File

@@ -305,7 +305,7 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
inviteWebUser(wpNodeRef, AuthenticationUtil.getFullyAuthenticatedUser(), WCMUtil.ROLE_CONTENT_MANAGER, true); inviteWebUser(wpNodeRef, AuthenticationUtil.getFullyAuthenticatedUser(), WCMUtil.ROLE_CONTENT_MANAGER, true);
// Bind the post-commit transaction listener with data required for virtualization server notification // Bind the post-commit transaction listener with data required for virtualization server notification
CreateWebProjectTransactionListener tl = new CreateWebProjectTransactionListener(wpStoreId); CreateWebAppTransactionListener tl = new CreateWebAppTransactionListener(wpStoreId, WCMUtil.DIR_ROOT);
AlfrescoTransactionSupport.bindListener(tl); AlfrescoTransactionSupport.bindListener(tl);
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
@@ -357,7 +357,7 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
new PropertyValue(DataTypeDefinition.TEXT, new PropertyValue(DataTypeDefinition.TEXT,
webAppDescription)); webAppDescription));
} }
// Snapshot the store with the empty webapp // Snapshot the store with the empty webapp
avmService.createSnapshot(stagingStoreId, null, null); avmService.createSnapshot(stagingStoreId, null, null);
@@ -365,6 +365,9 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
} }
}, AuthenticationUtil.getSystemUserName()); }, AuthenticationUtil.getSystemUserName());
CreateWebAppTransactionListener tl = new CreateWebAppTransactionListener(wpInfo.getStoreId(), webAppName);
AlfrescoTransactionSupport.bindListener(tl);
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logger.debug("Created web app: "+webAppName+" in "+(System.currentTimeMillis()-start)+" ms (store id: "+wpInfo.getStoreId()+")"); logger.debug("Created web app: "+webAppName+" in "+(System.currentTimeMillis()-start)+" ms (store id: "+wpInfo.getStoreId()+")");
@@ -1541,15 +1544,17 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
/** /**
* Transaction listener - invoked after commit * Create WebProject/WebApp Transaction listener - invoked after commit
*/ */
private class CreateWebProjectTransactionListener extends TransactionListenerAdapter private class CreateWebAppTransactionListener extends TransactionListenerAdapter
{ {
private String wpStoreId; private String wpStoreId;
private String webApp;
public CreateWebProjectTransactionListener(String wpStoreId) public CreateWebAppTransactionListener(String wpStoreId, String webApp)
{ {
this.wpStoreId = wpStoreId; this.wpStoreId = wpStoreId;
this.webApp = webApp;
} }
/** /**
@@ -1561,11 +1566,11 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
// post-commit // post-commit
if (wpStoreId != null) if (wpStoreId != null)
{ {
// update the virtualisation server with the default ROOT webapp path // update the virtualisation server with webapp
// performed after the main txn has committed successfully // performed after the main txn has committed successfully
String newStoreName = WCMUtil.buildStagingStoreName(wpStoreId); String newStoreName = WCMUtil.buildStagingStoreName(wpStoreId);
String path = WCMUtil.buildStoreWebappPath(newStoreName, WCMUtil.DIR_ROOT); String path = WCMUtil.buildStoreWebappPath(newStoreName, webApp);
WCMUtil.updateVServerWebapp(virtServerRegistry, path, true); WCMUtil.updateVServerWebapp(virtServerRegistry, path, true);
} }