mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
ML Authentication Issues:
- Everyone, including guest, gets explicit full rights to each new cm:mlContainer instance. - The MultilingualContentService better permission checks against the content nodes that go in and out of it. - Changed some of the API return values to be more explicit about whether the cm:mlContainer or cm:mlDocument is required. - Added explicit tests to ensure that even guest is able to manipulate the cm:mlContainer. ML Languages List: - The default value is now punted to the top of the list. Various neatening. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5816 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -52,6 +52,10 @@ import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.BaseSpringTest;
|
||||
|
||||
/**
|
||||
* @author Andy Hind
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class AuditServiceTest extends BaseSpringTest
|
||||
{
|
||||
|
||||
|
@@ -212,19 +212,29 @@ public class ContentFilterLanguagesMap implements ContentFilterLanguagesService
|
||||
String value = langElem.getValue();
|
||||
String def = langElem.getAttribute(ATTR_DEFAULT);
|
||||
|
||||
orderedLangCodes.add(code);
|
||||
|
||||
languagesByCode.put(code, value);
|
||||
|
||||
if(def != null && Boolean.parseBoolean(def))
|
||||
boolean isDefault = (def != null && Boolean.parseBoolean(def));
|
||||
if(isDefault)
|
||||
{
|
||||
if(defaultLanguage != null)
|
||||
{
|
||||
logger.warn("Ignoring default attribute is not unique le last matched will be used");
|
||||
logger.warn("Content filter default language is not unique: " + code);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.defaultLanguage = code;
|
||||
}
|
||||
|
||||
this.defaultLanguage = code;
|
||||
}
|
||||
if (defaultLanguage == code)
|
||||
{
|
||||
orderedLangCodes.add(0, code);
|
||||
}
|
||||
else
|
||||
{
|
||||
orderedLangCodes.add(code);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// make the collections read-only
|
||||
|
@@ -48,6 +48,7 @@ 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.PermissionService;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
@@ -85,6 +86,7 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
private NodeService nodeService;
|
||||
private SearchService searchService;
|
||||
private VersionService versionService;
|
||||
private PermissionService permissionService;
|
||||
private SearchParameters searchParametersMLRoot;
|
||||
private ContentFilterLanguagesService contentFilterLanguagesService;
|
||||
private FileFolderService fileFolderService;
|
||||
@@ -133,13 +135,30 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
{
|
||||
NodeRef mlContainerRootNodeRef = getMLContainerRoot();
|
||||
// Create the container
|
||||
PropertyMap versionProperties = new PropertyMap();
|
||||
versionProperties.put(ContentModel.PROP_AUTO_VERSION, Boolean.FALSE);
|
||||
versionProperties.put(ContentModel.PROP_INITIAL_VERSION, Boolean.FALSE);
|
||||
ChildAssociationRef assocRef = nodeService.createNode(
|
||||
mlContainerRootNodeRef,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
QNAME_ML_CONTAINER,
|
||||
ContentModel.TYPE_MULTILINGUAL_CONTAINER);
|
||||
// done
|
||||
return assocRef.getChildRef();
|
||||
ContentModel.TYPE_MULTILINGUAL_CONTAINER,
|
||||
versionProperties);
|
||||
NodeRef mlContainerNodeRef = assocRef.getChildRef();
|
||||
// TODO: Examine the usage of versioning - why is autoversioning on and used in the UI?
|
||||
// // The model makes the container versionable by default, but why?
|
||||
// nodeService.addAspect(mlContainerNodeRef, ContentModel.ASPECT_VERSIONABLE, versionProperties);
|
||||
// Set the permissions to allow anything by anyone
|
||||
permissionService.setPermission(
|
||||
mlContainerNodeRef,
|
||||
PermissionService.ALL_AUTHORITIES,
|
||||
PermissionService.ALL_PERMISSIONS, true);
|
||||
permissionService.setPermission(
|
||||
mlContainerNodeRef,
|
||||
PermissionService.GUEST_AUTHORITY,
|
||||
PermissionService.ALL_PERMISSIONS, true);
|
||||
// Done
|
||||
return mlContainerNodeRef;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,7 +274,8 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
{
|
||||
PropertyMap properties = new PropertyMap();
|
||||
properties.put(ContentModel.PROP_LOCALE, locale);
|
||||
nodeService.addAspect(contentNodeRef, ContentModel.ASPECT_MULTILINGUAL_DOCUMENT, properties);
|
||||
nodeService.addAspect(contentNodeRef, ContentModel.ASPECT_LOCALIZED, properties);
|
||||
nodeService.addAspect(contentNodeRef, ContentModel.ASPECT_MULTILINGUAL_DOCUMENT, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -341,7 +361,7 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
public NodeRef makeTranslation(NodeRef contentNodeRef, Locale locale)
|
||||
public void makeTranslation(NodeRef contentNodeRef, Locale locale)
|
||||
{
|
||||
NodeRef mlContainerNodeRef = makeTranslationImpl(null, contentNodeRef, locale);
|
||||
// done
|
||||
@@ -352,7 +372,6 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
" locale: " + locale + "\n" +
|
||||
" container: " + mlContainerNodeRef);
|
||||
}
|
||||
return mlContainerNodeRef;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
@@ -410,32 +429,20 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
public NodeRef addTranslation(NodeRef newTranslationNodeRef, NodeRef translationOfNodeRef, Locale locale)
|
||||
public void addTranslation(NodeRef newTranslationNodeRef, NodeRef translationOfNodeRef, Locale locale)
|
||||
{
|
||||
NodeRef mlContainerNodeRef = null;
|
||||
// Were we given the translation or the container
|
||||
QName typeQName = nodeService.getType(translationOfNodeRef);
|
||||
if (typeQName.equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||
{
|
||||
// We have the container
|
||||
mlContainerNodeRef = translationOfNodeRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the container
|
||||
mlContainerNodeRef = getOrCreateMLContainer(translationOfNodeRef, false);
|
||||
}
|
||||
// Get the container
|
||||
NodeRef mlContainerNodeRef = getOrCreateMLContainer(translationOfNodeRef, false);
|
||||
// Use the existing container to make the new content into a translation
|
||||
makeTranslationImpl(mlContainerNodeRef, newTranslationNodeRef, locale);
|
||||
// done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Added a translation: \n" +
|
||||
" Translation of: " + translationOfNodeRef + " of type " + typeQName + "\n" +
|
||||
" Translation of: " + translationOfNodeRef + "\n" +
|
||||
" New translation: " + newTranslationNodeRef + "\n" +
|
||||
" Locale: " + locale);
|
||||
}
|
||||
return mlContainerNodeRef;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
@@ -661,7 +668,7 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
Locale nearestLocale = I18NUtil.getNearestLocale(containerLocale, locales);
|
||||
if (nearestLocale == null)
|
||||
{
|
||||
// There is pivot translation
|
||||
// There is no pivot translation
|
||||
return null;
|
||||
}
|
||||
else
|
||||
@@ -675,9 +682,8 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
*/
|
||||
public NodeRef addEmptyTranslation(NodeRef translationOfNodeRef, String name, Locale locale)
|
||||
{
|
||||
QName typeQName = nodeService.getType(translationOfNodeRef);
|
||||
boolean hasMLAspect = nodeService.hasAspect(translationOfNodeRef, ContentModel.ASPECT_MULTILINGUAL_DOCUMENT);
|
||||
if (hasMLAspect || typeQName.equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||
if (hasMLAspect)
|
||||
{
|
||||
// Get the pivot translation
|
||||
NodeRef pivotTranslationNodeRef = getPivotTranslation(translationOfNodeRef);
|
||||
@@ -688,22 +694,13 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
}
|
||||
else
|
||||
{
|
||||
// We use the given translation, provided it is an actual translation
|
||||
if (!hasMLAspect)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"The node provided is not associated with a pivot translation " +
|
||||
"and is not in itself a translation: \n" +
|
||||
" Translation: " + translationOfNodeRef + "\n" +
|
||||
" Locale: " + locale);
|
||||
}
|
||||
// We use the given translation
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Node must have aspect " + ContentModel.ASPECT_MULTILINGUAL_DOCUMENT +
|
||||
" or be a " + ContentModel.TYPE_MULTILINGUAL_CONTAINER + ": \n" +
|
||||
"Node must have aspect " + ContentModel.ASPECT_MULTILINGUAL_DOCUMENT + ": \n" +
|
||||
" Translation: " + translationOfNodeRef + "\n" +
|
||||
" Locale: " + locale);
|
||||
}
|
||||
@@ -773,7 +770,7 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Added an empty translation: \n" +
|
||||
" Translation of: " + translationOfNodeRef + " of type " + typeQName + "\n" +
|
||||
" Translation of: " + translationOfNodeRef + "\n" +
|
||||
" New translation: " + newTranslationNodeRef + "\n" +
|
||||
" Locale: " + locale);
|
||||
}
|
||||
@@ -796,6 +793,11 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
this.versionService = versionService;
|
||||
}
|
||||
|
||||
public void setPermissionService(PermissionService permissionService)
|
||||
{
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
public void setContentFilterLanguagesService(ContentFilterLanguagesService contentFilterLanguagesService)
|
||||
{
|
||||
this.contentFilterLanguagesService = contentFilterLanguagesService;
|
||||
@@ -805,9 +807,4 @@ public class MultilingualContentServiceImpl implements MultilingualContentServic
|
||||
{
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
|
||||
public void renameWithMLExtension(NodeRef translationNodeRef)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
@@ -108,7 +108,8 @@ public class EmptyTranslationAspectTest extends AbstractMultilingualTestCases {
|
||||
|
||||
NodeRef empty = null;
|
||||
|
||||
NodeRef mlContainer = multilingualContentService.makeTranslation(pivot, Locale.FRENCH);
|
||||
multilingualContentService.makeTranslation(pivot, Locale.FRENCH);
|
||||
NodeRef mlContainer = multilingualContentService.getTranslationContainer(pivot);
|
||||
multilingualContentService.addTranslation(otherTranslation, pivot, Locale.KOREAN);
|
||||
|
||||
empty = multilingualContentService.addEmptyTranslation(pivot, "empty_" + System.currentTimeMillis(), Locale.CHINESE);
|
||||
|
@@ -49,7 +49,8 @@ public class MLContainerTypeTest extends AbstractMultilingualTestCases
|
||||
NodeRef trans3 = createContent();
|
||||
NodeRef empty = null;
|
||||
|
||||
NodeRef mlContainer = multilingualContentService.makeTranslation(trans1, Locale.FRENCH);
|
||||
multilingualContentService.makeTranslation(trans1, Locale.FRENCH);
|
||||
NodeRef mlContainer = multilingualContentService.getTranslationContainer(trans1);
|
||||
multilingualContentService.addTranslation(trans2, trans1, Locale.GERMAN);
|
||||
multilingualContentService.addTranslation(trans3, trans1, Locale.ITALIAN);
|
||||
empty = multilingualContentService.addEmptyTranslation(trans1, "EMPTY_" + System.currentTimeMillis(), Locale.JAPANESE);
|
||||
|
@@ -30,11 +30,15 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionHistory;
|
||||
|
||||
@@ -49,45 +53,30 @@ public class MultilingualContentServiceImplTest extends AbstractMultilingualTest
|
||||
|
||||
public void testMakeTranslation() throws Exception
|
||||
{
|
||||
NodeRef contentNodeRef = createContent();
|
||||
NodeRef chineseContentNodeRef = createContent();
|
||||
// Turn the content into a translation with the appropriate structures
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.makeTranslation(contentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.getTranslationContainer(chineseContentNodeRef);
|
||||
// Check it
|
||||
assertNotNull("Container not created", mlContainerNodeRef);
|
||||
// Check the container child count
|
||||
assertEquals("Incorrect number of child nodes", 1, nodeService.getChildAssocs(mlContainerNodeRef).size());
|
||||
}
|
||||
|
||||
public void testAddTranslationUsingContainer() throws Exception
|
||||
{
|
||||
// Make a container with a single translation
|
||||
NodeRef chineseContentNodeRef = createContent();
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
// Create some more content
|
||||
NodeRef frenchContentNodeRef = createContent();
|
||||
// Make this a translation of the Chinese
|
||||
NodeRef newMLContainerNodeRef = multilingualContentService.addTranslation(
|
||||
frenchContentNodeRef,
|
||||
mlContainerNodeRef,
|
||||
Locale.FRENCH);
|
||||
// Make sure that the original container was used
|
||||
assertEquals("Existing container should have been used", mlContainerNodeRef, newMLContainerNodeRef);
|
||||
// Check the container child count
|
||||
assertEquals("Incorrect number of child nodes", 2, nodeService.getChildAssocs(mlContainerNodeRef).size());
|
||||
}
|
||||
|
||||
public void testAddTranslationUsingContent() throws Exception
|
||||
{
|
||||
// Make a container with a single translation
|
||||
NodeRef chineseContentNodeRef = createContent();
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.getTranslationContainer(chineseContentNodeRef);
|
||||
// Create some more content
|
||||
NodeRef frenchContentNodeRef = createContent();
|
||||
// Make this a translation of the Chinese
|
||||
NodeRef newMLContainerNodeRef = multilingualContentService.addTranslation(
|
||||
multilingualContentService.addTranslation(
|
||||
frenchContentNodeRef,
|
||||
chineseContentNodeRef,
|
||||
Locale.FRENCH);
|
||||
NodeRef newMLContainerNodeRef = multilingualContentService.getTranslationContainer(frenchContentNodeRef);
|
||||
// Make sure that the original container was used
|
||||
assertEquals("Existing container should have been used", mlContainerNodeRef, newMLContainerNodeRef);
|
||||
// Check the container child count
|
||||
@@ -113,9 +102,9 @@ public class MultilingualContentServiceImplTest extends AbstractMultilingualTest
|
||||
NodeRef nodeRef2 = createContent();
|
||||
NodeRef nodeRef3 = createContent();
|
||||
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.makeTranslation(nodeRef1, loc1);
|
||||
multilingualContentService.makeTranslation(nodeRef1, loc1);
|
||||
|
||||
List<Locale> missing = multilingualContentService.getMissingTranslations(mlContainerNodeRef, false);
|
||||
List<Locale> missing = multilingualContentService.getMissingTranslations(nodeRef1, false);
|
||||
|
||||
// make sure that the missing language list size is correct
|
||||
assertFalse("Missing Translation Size false. " +
|
||||
@@ -124,13 +113,13 @@ public class MultilingualContentServiceImplTest extends AbstractMultilingualTest
|
||||
// make sure that the missing language list is correct
|
||||
assertFalse("Missing Translation List false. Locale " + loc1 + " found", missing.contains(loc1.toString()));
|
||||
|
||||
multilingualContentService.addTranslation(nodeRef2, mlContainerNodeRef, loc2);
|
||||
multilingualContentService.addTranslation(nodeRef3, mlContainerNodeRef, loc3);
|
||||
multilingualContentService.addTranslation(nodeRef2, nodeRef1, loc2);
|
||||
multilingualContentService.addTranslation(nodeRef3, nodeRef1, loc3);
|
||||
|
||||
// Add the missing translations in
|
||||
missing = multilingualContentService.getMissingTranslations(nodeRef1, false);
|
||||
|
||||
missing = multilingualContentService.getMissingTranslations(mlContainerNodeRef, false);
|
||||
|
||||
// make sure that the missing language list size is correct
|
||||
// Make sure that the missing language list size is correct
|
||||
assertFalse("Missing Translation Size false. " +
|
||||
"Real size : " + missing.size() + ". Normal Size " + (langListSize - 3), missing.size() != (langListSize - 3));
|
||||
|
||||
@@ -141,29 +130,30 @@ public class MultilingualContentServiceImplTest extends AbstractMultilingualTest
|
||||
public void testGetTranslationForLocale() throws Exception
|
||||
{
|
||||
NodeRef chineseContentNodeRef = createContent();
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
NodeRef frenchContentNodeRef = createContent();
|
||||
multilingualContentService.addTranslation(frenchContentNodeRef, chineseContentNodeRef, Locale.FRENCH);
|
||||
|
||||
// Get the chinese translation
|
||||
assertEquals("Chinese translation should be present",
|
||||
chineseContentNodeRef,
|
||||
multilingualContentService.getTranslationForLocale(mlContainerNodeRef, Locale.CHINESE));
|
||||
multilingualContentService.getTranslationForLocale(chineseContentNodeRef, Locale.CHINESE));
|
||||
// Get the french translation
|
||||
assertEquals("French translation should be present",
|
||||
frenchContentNodeRef,
|
||||
multilingualContentService.getTranslationForLocale(mlContainerNodeRef, Locale.FRENCH));
|
||||
multilingualContentService.getTranslationForLocale(chineseContentNodeRef, Locale.FRENCH));
|
||||
// The Italian should return the pivot
|
||||
assertEquals("French translation should be present",
|
||||
chineseContentNodeRef,
|
||||
multilingualContentService.getTranslationForLocale(mlContainerNodeRef, Locale.ITALIAN));
|
||||
multilingualContentService.getTranslationForLocale(chineseContentNodeRef, Locale.ITALIAN));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void testGetPivotTranslation() throws Exception
|
||||
{
|
||||
NodeRef chineseContentNodeRef = createContent();
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.getTranslationContainer(chineseContentNodeRef);
|
||||
|
||||
// make sure that the pivot language is set
|
||||
assertNotNull("Pivot language not set", nodeService.getProperty(mlContainerNodeRef, ContentModel.PROP_LOCALE));
|
||||
@@ -189,10 +179,10 @@ public class MultilingualContentServiceImplTest extends AbstractMultilingualTest
|
||||
public void testCreateEmptyTranslation() throws Exception
|
||||
{
|
||||
NodeRef chineseContentNodeRef = createContent("Document.txt");
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
|
||||
// This should use the pivot language
|
||||
NodeRef emptyNodeRef = multilingualContentService.addEmptyTranslation(mlContainerNodeRef, "Document.txt", Locale.CANADA);
|
||||
NodeRef emptyNodeRef = multilingualContentService.addEmptyTranslation(chineseContentNodeRef, "Document.txt", Locale.CANADA);
|
||||
|
||||
// Ensure that the empty translation is not null
|
||||
assertNotNull("The creation of the empty document failed ", emptyNodeRef);
|
||||
@@ -215,7 +205,7 @@ public class MultilingualContentServiceImplTest extends AbstractMultilingualTest
|
||||
public void testCreateEmptyTranslationNames() throws Exception
|
||||
{
|
||||
NodeRef chineseContentNodeRef = createContent("Document.txt");
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
NodeRef koreanContentNodeRef = createContent("Document_ko.txt");
|
||||
multilingualContentService.addTranslation(koreanContentNodeRef, chineseContentNodeRef, Locale.KOREAN);
|
||||
// Create with a null name, and off a non-pivot just to be sure
|
||||
@@ -227,14 +217,14 @@ public class MultilingualContentServiceImplTest extends AbstractMultilingualTest
|
||||
assertEquals("Empty translation name not generated correctly.", "Document_en_CA.txt", nullName);
|
||||
// Create with the same name
|
||||
NodeRef sameNameNodeRef = multilingualContentService.addEmptyTranslation(
|
||||
mlContainerNodeRef,
|
||||
chineseContentNodeRef,
|
||||
"Document.txt",
|
||||
Locale.CANADA_FRENCH);
|
||||
String sameName = fileFolderService.getFileInfo(sameNameNodeRef).getName();
|
||||
assertEquals("Empty translation name not generated correctly.", "Document_fr_CA.txt", sameName);
|
||||
// Create with a different name
|
||||
NodeRef differentNameNodeRef = multilingualContentService.addEmptyTranslation(
|
||||
mlContainerNodeRef,
|
||||
chineseContentNodeRef,
|
||||
"Document2.txt",
|
||||
Locale.JAPANESE);
|
||||
String differentName = fileFolderService.getFileInfo(differentNameNodeRef).getName();
|
||||
@@ -249,9 +239,11 @@ public class MultilingualContentServiceImplTest extends AbstractMultilingualTest
|
||||
NodeRef frenchContentNodeRef = createContent();
|
||||
NodeRef japaneseContentNodeRef = createContent();
|
||||
// Add to container
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.addTranslation(frenchContentNodeRef, mlContainerNodeRef, Locale.FRENCH);
|
||||
multilingualContentService.addTranslation(japaneseContentNodeRef, mlContainerNodeRef, Locale.JAPANESE);
|
||||
multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.addTranslation(frenchContentNodeRef, chineseContentNodeRef, Locale.FRENCH);
|
||||
multilingualContentService.addTranslation(japaneseContentNodeRef, chineseContentNodeRef, Locale.JAPANESE);
|
||||
|
||||
NodeRef mlContainerNodeRef = multilingualContentService.getTranslationContainer(chineseContentNodeRef);
|
||||
// Check the container child count
|
||||
assertEquals("Incorrect number of child nodes", 3, nodeService.getChildAssocs(mlContainerNodeRef).size());
|
||||
|
||||
@@ -290,4 +282,64 @@ public class MultilingualContentServiceImplTest extends AbstractMultilingualTest
|
||||
int count = translationsByLocale.size();
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetTranslationContainerPermissions() throws Exception
|
||||
{
|
||||
// Grant the guest user rights to our working folder
|
||||
PermissionService permissionService = serviceRegistry.getPermissionService();
|
||||
AuthenticationComponent authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
|
||||
permissionService.setPermission(
|
||||
folderNodeRef,
|
||||
PermissionService.GUEST_AUTHORITY,
|
||||
PermissionService.ALL_PERMISSIONS,
|
||||
true);
|
||||
// Get the current authentication
|
||||
Authentication authentication = authenticationComponent.getCurrentAuthentication();
|
||||
try
|
||||
{
|
||||
authenticationComponent.setGuestUserAsCurrentUser();
|
||||
// Create some documents
|
||||
NodeRef chineseContentNodeRef = createContent();
|
||||
// Make a translation
|
||||
multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.getTranslationContainer(chineseContentNodeRef);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { authenticationComponent.setCurrentAuthentication(authentication); } catch (Throwable e) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether non-admin users can take part in ML document manipulation
|
||||
*/
|
||||
public void testPermissions() throws Exception
|
||||
{
|
||||
// Grant the guest user rights to our working folder
|
||||
PermissionService permissionService = serviceRegistry.getPermissionService();
|
||||
AuthenticationComponent authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
|
||||
permissionService.setPermission(
|
||||
folderNodeRef,
|
||||
PermissionService.GUEST_AUTHORITY,
|
||||
PermissionService.ALL_PERMISSIONS,
|
||||
true);
|
||||
// Get the current authentication
|
||||
Authentication authentication = authenticationComponent.getCurrentAuthentication();
|
||||
try
|
||||
{
|
||||
authenticationComponent.setGuestUserAsCurrentUser();
|
||||
// Create some documents
|
||||
NodeRef chineseContentNodeRef = createContent();
|
||||
NodeRef frenchContentNodeRef = createContent();
|
||||
// Do ML work
|
||||
multilingualContentService.makeTranslation(chineseContentNodeRef, Locale.CHINESE);
|
||||
multilingualContentService.addTranslation(frenchContentNodeRef, chineseContentNodeRef, Locale.FRENCH);
|
||||
multilingualContentService.addEmptyTranslation(chineseContentNodeRef, null, Locale.JAPANESE);
|
||||
multilingualContentService.createEdition(chineseContentNodeRef);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { authenticationComponent.setCurrentAuthentication(authentication); } catch (Throwable e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -44,7 +44,8 @@ public class MultilingualDocumentAspectTest extends AbstractMultilingualTestCase
|
||||
public void testCopy() throws Exception
|
||||
{
|
||||
NodeRef original = createContent();
|
||||
NodeRef mlContainer = multilingualContentService.makeTranslation(original, Locale.FRENCH);
|
||||
multilingualContentService.makeTranslation(original, Locale.FRENCH);
|
||||
NodeRef mlContainer = multilingualContentService.getTranslationContainer(original);
|
||||
|
||||
NodeRef copy =
|
||||
fileFolderService.copy(original, nodeService.getPrimaryParent(original).getParentRef(), "COPY" + System.currentTimeMillis()).getNodeRef();
|
||||
@@ -67,7 +68,7 @@ public class MultilingualDocumentAspectTest extends AbstractMultilingualTestCase
|
||||
|
||||
NodeRef parent = nodeService.getPrimaryParent(trad1).getParentRef();
|
||||
|
||||
NodeRef mlContainer = multilingualContentService.makeTranslation(trad1, Locale.FRENCH);
|
||||
multilingualContentService.makeTranslation(trad1, Locale.FRENCH);
|
||||
multilingualContentService.addTranslation(trad2, trad1, Locale.GERMAN);
|
||||
multilingualContentService.addTranslation(trad3, trad1, Locale.ITALIAN);
|
||||
|
||||
@@ -76,7 +77,7 @@ public class MultilingualDocumentAspectTest extends AbstractMultilingualTestCase
|
||||
// Ensure that the deleted node is romoved from its space
|
||||
assertEquals("The deleted node must be removed to the space", 2, nodeService.getChildAssocs(parent).size());
|
||||
// Ensure that the mlContainer doesn't keep an association to the deleted node
|
||||
assertEquals("The deleted node must be removed to the child associations of the mlContainer", 2, multilingualContentService.getTranslations(mlContainer).size());
|
||||
assertEquals("The deleted node must be removed to the child associations of the mlContainer", 2, multilingualContentService.getTranslations(trad1).size());
|
||||
|
||||
// retore the deleted node
|
||||
NodeRef restoredNode = nodeArchiveService.restoreArchivedNode(nodeArchiveService.getArchivedNode(trad3)).getRestoredNodeRef();
|
||||
@@ -84,21 +85,17 @@ public class MultilingualDocumentAspectTest extends AbstractMultilingualTestCase
|
||||
// Ensure that the restored node is restored to it s original space
|
||||
assertEquals("The restored node must be restaured to the the space", 3, nodeService.getChildAssocs(parent).size());
|
||||
// Ensure that the restored node is not linked to the mlContainer
|
||||
assertEquals("The restored node would not be restaured to the mlContainer", 2, multilingualContentService.getTranslations(mlContainer).size());
|
||||
assertEquals("The restored node would not be restaured to the mlContainer", 2, multilingualContentService.getTranslations(trad1).size());
|
||||
// Ensure that the restored node doesn't keep the mlDocument aspect
|
||||
assertFalse("The restored node can't keep the multilingual aspect", nodeService.hasAspect(restoredNode, ContentModel.ASPECT_MULTILINGUAL_DOCUMENT));
|
||||
// DH: The locale is stored on an aspect that is independent of the ML model.
|
||||
// It is therefore not possible to remove the locale just because the node
|
||||
// is being unhooked from the ML structures
|
||||
// // Ensure that the restored node doesn't keep the locale property
|
||||
// assertNull("The restaured node can't keep the locale property", nodeService.getProperty(restoredNode, ContentModel.PROP_LOCALE));
|
||||
}
|
||||
|
||||
public void testDeletePivot() throws Exception
|
||||
{
|
||||
NodeRef pivot = createContent();
|
||||
NodeRef trans1 = createContent();
|
||||
NodeRef mlContainer = multilingualContentService.makeTranslation(pivot, Locale.FRENCH);
|
||||
multilingualContentService.makeTranslation(pivot, Locale.FRENCH);
|
||||
NodeRef mlContainer = multilingualContentService.getTranslationContainer(pivot);
|
||||
multilingualContentService.addTranslation(trans1, pivot, Locale.KOREAN);
|
||||
|
||||
//nodeService.deleteNode(trans1);
|
||||
@@ -112,16 +109,13 @@ public class MultilingualDocumentAspectTest extends AbstractMultilingualTestCase
|
||||
assertTrue("The last translation would not be removed", nodeService.exists(trans1));
|
||||
// Ensure that trans1 has no mlDocument aspect
|
||||
assertFalse("The last translation can't keep the multilingual aspect", nodeService.hasAspect(trans1, ContentModel.ASPECT_MULTILINGUAL_DOCUMENT));
|
||||
// DH: Here too, the sys:locale property must be left alone as it is independent of the
|
||||
// ML model
|
||||
// // Ensure that trans1 has no locale propety
|
||||
// assertNull("The last translation can't keep the locale property", nodeService.getProperty(trans1, ContentModel.PROP_LOCALE));
|
||||
}
|
||||
|
||||
public void testDeleteLastNode() throws Exception
|
||||
{
|
||||
NodeRef pivot = createContent();
|
||||
NodeRef mlContainer = multilingualContentService.makeTranslation(pivot, Locale.FRENCH);
|
||||
multilingualContentService.makeTranslation(pivot, Locale.FRENCH);
|
||||
NodeRef mlContainer = multilingualContentService.getTranslationContainer(pivot);
|
||||
|
||||
nodeService.deleteNode(pivot);
|
||||
|
||||
@@ -139,7 +133,8 @@ public class MultilingualDocumentAspectTest extends AbstractMultilingualTestCase
|
||||
{
|
||||
NodeRef pivot = createContent();
|
||||
NodeRef trans1 = createContent();
|
||||
NodeRef mlContainer = multilingualContentService.makeTranslation(pivot, Locale.FRENCH);
|
||||
multilingualContentService.makeTranslation(pivot, Locale.FRENCH);
|
||||
NodeRef mlContainer = multilingualContentService.getTranslationContainer(pivot);
|
||||
multilingualContentService.addTranslation(trans1, pivot, Locale.KOREAN);
|
||||
|
||||
// modify the locale for the translation
|
||||
|
@@ -198,7 +198,8 @@ public class VersionableAspect implements ContentServicePolicies.OnContentUpdate
|
||||
|
||||
if (initialVersion == true)
|
||||
{
|
||||
Map<NodeRef, NodeRef> versionedNodeRefs = (Map)AlfrescoTransactionSupport.getResource(KEY_VERSIONED_NODEREFS);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<NodeRef, NodeRef> versionedNodeRefs = (Map<NodeRef, NodeRef>) AlfrescoTransactionSupport.getResource(KEY_VERSIONED_NODEREFS);
|
||||
if (versionedNodeRefs == null || versionedNodeRefs.containsKey(nodeRef) == false)
|
||||
{
|
||||
// Queue create version action
|
||||
|
@@ -42,16 +42,6 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@PublicService
|
||||
public interface MultilingualContentService
|
||||
{
|
||||
/**
|
||||
* Rename an existing <b>sys:localized</b> by adding locale suffixes to the base name.
|
||||
* Where there are name clashes with existing documents, a numerical naming scheme will be
|
||||
* adopted.
|
||||
*
|
||||
* @param localizedNodeRef An existing <b>sys:localized</b>
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"localizedNodeRef"})
|
||||
void renameWithMLExtension(NodeRef localizedNodeRef);
|
||||
|
||||
/**
|
||||
* Checks whether an existing document is part of a translation group.
|
||||
*
|
||||
@@ -66,12 +56,11 @@ public interface MultilingualContentService
|
||||
* creating a <b>cm:mlContainer</b> parent. If it is already a translation, then nothing is done.
|
||||
*
|
||||
* @param contentNodeRef An existing <b>cm:content</b>
|
||||
* @return Returns the <b>cm:mlContainer</b> translation parent
|
||||
*
|
||||
* @see org.alfresco.model.ContentModel#ASPECT_MULTILINGUAL_DOCUMENT
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"contentNodeRef", "locale"})
|
||||
NodeRef makeTranslation(NodeRef contentNodeRef, Locale locale);
|
||||
void makeTranslation(NodeRef contentNodeRef, Locale locale);
|
||||
|
||||
/**
|
||||
* Removes the node from any associated translations. If the translation is the
|
||||
@@ -87,14 +76,15 @@ public interface MultilingualContentService
|
||||
* as necessary.
|
||||
*
|
||||
* @param newTranslationNodeRef An existing <b>cm:content</b>
|
||||
* @param translationOfNodeRef An existing <b>cm:mlDocument</b> or <b>cm:mlContainer</b>
|
||||
* @return Returns the <b>cm:mlContainer</b> translation parent
|
||||
* @param translationOfNodeRef An existing <b>cm:mlDocument</b>
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"newTranslationNodeRef", "translationOfNodeRef", "locale"})
|
||||
NodeRef addTranslation(NodeRef newTranslationNodeRef, NodeRef translationOfNodeRef, Locale locale);
|
||||
void addTranslation(NodeRef newTranslationNodeRef, NodeRef translationOfNodeRef, Locale locale);
|
||||
|
||||
/**
|
||||
* Convenience method for super user.
|
||||
*
|
||||
* @param translationNodeRef An existing <b>cm:mlDocument</b>
|
||||
* @return Returns the <b>cm:mlContainer</b> translation parent
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"translationNodeRef"})
|
||||
@@ -139,12 +129,12 @@ public interface MultilingualContentService
|
||||
|
||||
|
||||
/**
|
||||
* Given <b>cm:mlDocument</b> or a <b>cm:mlContainer</b>, this node returns each
|
||||
* locale that the node hasn't a translation yet.
|
||||
* Given a <b>cm:mlDocument</b> or <b>cm:mlContainer</b> this node returns each locale for
|
||||
* which there isn't a translation.
|
||||
*
|
||||
* @param localizedNodeRef the <b>cm:mlDocument</b> or the <b>cm:mlContainer</b>
|
||||
* @param addThisNodeLocale if true, add the locale of the given <b>cm:mlDocument</b> in the list.
|
||||
* @return
|
||||
* @param localizedNodeRef the <b>cm:mlDocument</b> or <b>cm:mlContainer</b>
|
||||
* @param addThisNodeLocale if true, add the locale of the given <b>cm:mlDocument</b> in the list.
|
||||
* @return Returns a list of missng locales
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"localizedNodeRef", "addThisNodeLocale"})
|
||||
List<Locale> getMissingTranslations(NodeRef localizedNodeRef, boolean addThisNodeLocale);
|
||||
@@ -155,7 +145,8 @@ public interface MultilingualContentService
|
||||
* for the translations is stored on the parent, and the child that has the same locale is the
|
||||
* pivot translation.
|
||||
*
|
||||
* @param nodeRef a <b>cm:mlDocument</b>
|
||||
* @param nodeRef a <b>cm:mlDocument</b> translation or <b>cm:mlContainer</b> translation
|
||||
* container
|
||||
* @return Returns a corresponding <b>cm:mlDocument</b> that matches the locale of
|
||||
* of the <b>cm:mlContainer</b>. <tt>null</tt> is returned if there is no
|
||||
* pivot translation.
|
||||
@@ -174,7 +165,7 @@ public interface MultilingualContentService
|
||||
* <p/>
|
||||
* The necessary translation structures will be created as necessary.
|
||||
*
|
||||
* @param translationOfNodeRef An existing <b>cm:mlDocument</b> or <b>cm:mlContainer</b>
|
||||
* @param translationOfNodeRef An existing <b>cm:mlDocument</b>
|
||||
* @param name The name of the file to create, or <tt>null</tt> to use
|
||||
* the default naming convention.
|
||||
* @return Returns the new created <b>cm:mlEmptyTranslation</b>
|
||||
|
Reference in New Issue
Block a user