diff --git a/config/alfresco/model/contentModel.xml b/config/alfresco/model/contentModel.xml index 8a38d44596..8070df71d9 100644 --- a/config/alfresco/model/contentModel.xml +++ b/config/alfresco/model/contentModel.xml @@ -230,11 +230,11 @@ - true + false false - cm:mlTranslation + sys:localized true true @@ -694,18 +694,6 @@ - - - Translation - - - Language - d:mltext - true - - - - diff --git a/config/alfresco/model/dictionaryModel.xml b/config/alfresco/model/dictionaryModel.xml index b761bbb364..1149379a40 100644 --- a/config/alfresco/model/dictionaryModel.xml +++ b/config/alfresco/model/dictionaryModel.xml @@ -103,6 +103,11 @@ org.alfresco.service.cmr.repository.NodeRef + + org.alfresco.repo.search.impl.lucene.analysis.VerbatimAnalyser + java.util.Locale + + diff --git a/config/alfresco/model/systemModel.xml b/config/alfresco/model/systemModel.xml index be70ff601e..9cc0b93204 100644 --- a/config/alfresco/model/systemModel.xml +++ b/config/alfresco/model/systemModel.xml @@ -186,6 +186,22 @@ + + + Translation + + + Locale + d:locale + true + + + + \ No newline at end of file diff --git a/source/java/org/alfresco/repo/domain/PropertyValue.java b/source/java/org/alfresco/repo/domain/PropertyValue.java index f61a6f1cde..341dcc7724 100644 --- a/source/java/org/alfresco/repo/domain/PropertyValue.java +++ b/source/java/org/alfresco/repo/domain/PropertyValue.java @@ -22,6 +22,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import org.alfresco.error.AlfrescoRuntimeException; @@ -241,6 +242,20 @@ public class PropertyValue implements Cloneable, Serializable { return DefaultTypeConverter.INSTANCE.convert(Path.class, value); } + }, + LOCALE + { + @Override + protected ValueType getPersistedType(Serializable value) + { + return ValueType.STRING; + } + + @Override + Serializable convert(Serializable value) + { + return DefaultTypeConverter.INSTANCE.convert(Locale.class, value); + } }; /** @@ -343,6 +358,10 @@ public class PropertyValue implements Cloneable, Serializable { return ValueType.PATH; } + else if (value instanceof Locale) + { + return ValueType.LOCALE; + } else { // type is not recognised as belonging to any particular slot @@ -373,6 +392,7 @@ public class PropertyValue implements Cloneable, Serializable valueTypesByPropertyType.put(DataTypeDefinition.ASSOC_REF, ValueType.ASSOC_REF); valueTypesByPropertyType.put(DataTypeDefinition.PATH, ValueType.PATH); valueTypesByPropertyType.put(DataTypeDefinition.QNAME, ValueType.QNAME); + valueTypesByPropertyType.put(DataTypeDefinition.LOCALE, ValueType.LOCALE); } /** the type of the property, prior to serialization persistence */ diff --git a/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java b/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java index 52850e7bac..ffa948a44d 100644 --- a/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java +++ b/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java @@ -24,6 +24,7 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -106,6 +107,7 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest public static final QName PROP_QNAME_CONTENT_VALUE = QName.createQName(NAMESPACE, "contentValue"); public static final QName PROP_QNAME_PATH_VALUE = QName.createQName(NAMESPACE, "pathValue"); public static final QName PROP_QNAME_CATEGORY_VALUE = QName.createQName(NAMESPACE, "categoryValue"); + public static final QName PROP_QNAME_LOCALE_VALUE = QName.createQName(NAMESPACE, "localeValue"); public static final QName PROP_QNAME_NULL_VALUE = QName.createQName(NAMESPACE, "nullValue"); public static final QName PROP_QNAME_MULTI_VALUE = QName.createQName(NAMESPACE, "multiValue"); public static final QName PROP_QNAME_PROP1 = QName.createQName(NAMESPACE, "prop1"); @@ -1014,6 +1016,7 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest properties.put(PROP_QNAME_PATH_VALUE, pathProperty); properties.put(PROP_QNAME_CONTENT_VALUE, new ContentData("url", "text/plain", 88L, "UTF-8")); properties.put(PROP_QNAME_CATEGORY_VALUE, rootNodeRef); + properties.put(PROP_QNAME_LOCALE_VALUE, Locale.CHINESE); properties.put(PROP_QNAME_NULL_VALUE, null); properties.put(PROP_QNAME_MULTI_VALUE, listProperty); diff --git a/source/java/org/alfresco/repo/node/BaseNodeServiceTest_model.xml b/source/java/org/alfresco/repo/node/BaseNodeServiceTest_model.xml index 5c727aeadd..18137d1e01 100644 --- a/source/java/org/alfresco/repo/node/BaseNodeServiceTest_model.xml +++ b/source/java/org/alfresco/repo/node/BaseNodeServiceTest_model.xml @@ -259,6 +259,10 @@ d:category true + + d:locale + true + d:text true diff --git a/source/java/org/alfresco/service/cmr/dictionary/DataTypeDefinition.java b/source/java/org/alfresco/service/cmr/dictionary/DataTypeDefinition.java index f8d04f96f7..ce35bfa5bb 100644 --- a/source/java/org/alfresco/service/cmr/dictionary/DataTypeDefinition.java +++ b/source/java/org/alfresco/service/cmr/dictionary/DataTypeDefinition.java @@ -49,6 +49,7 @@ public interface DataTypeDefinition public QName CHILD_ASSOC_REF = QName.createQName(NamespaceService.DICTIONARY_MODEL_1_0_URI, "childassocref"); public QName ASSOC_REF = QName.createQName(NamespaceService.DICTIONARY_MODEL_1_0_URI, "assocref"); public QName PATH = QName.createQName(NamespaceService.DICTIONARY_MODEL_1_0_URI, "path"); + public QName LOCALE = QName.createQName(NamespaceService.DICTIONARY_MODEL_1_0_URI, "locale"); /** diff --git a/source/java/org/alfresco/service/cmr/ml/MultilingualContentService.java b/source/java/org/alfresco/service/cmr/ml/MultilingualContentService.java new file mode 100644 index 0000000000..fcab74ddd2 --- /dev/null +++ b/source/java/org/alfresco/service/cmr/ml/MultilingualContentService.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.service.cmr.ml; + +import java.util.Locale; + +import org.alfresco.service.Auditable; +import org.alfresco.service.PublicService; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * The API to manage multilingual content and related structures. + * + * @author Derek Hulley + */ +@PublicService +public interface MultilingualContentService +{ + /** + * Rename an existing cm:translation by adding locale suffixes to the base name. + * Where there are name clashes with existing documents, a numerical naming scheme will be + * adopted. + * + * @param translationNodeRef An existing cm:translation + */ + @Auditable(key = Auditable.Key.ARG_0, parameters = {"translationNodeRef"}) + void renameWithMLExtension(NodeRef translationNodeRef); + + /** + * Make an existing document translatable. If it is already translatable, then nothing is done. + * + * @param contentNodeRef An existing cm:content + * @return Returns the cm:mlContainer translation parent + */ + @Auditable(key = Auditable.Key.ARG_0, parameters = {"contentNodeRef", "locale"}) + NodeRef makeTranslatable(NodeRef contentNodeRef, Locale locale); + + /** + * Make a translation out of an existing document. The necessary translation structures will be created + * as necessary. + * + * @param newTranslationNodeRef An existing cm:content + * @param translationOfNodeRef An existing cm:translation or cm:mlContainer + * @return Returns the cm:mlContainer translation parent + */ + @Auditable(key = Auditable.Key.ARG_0, parameters = {"newTranslationNodeRef", "translationOfNodeRef", "locale"}) + NodeRef addTranslation(NodeRef newTranslationNodeRef, NodeRef translationOfNodeRef, Locale locale); + + /** + * + * @return Returns the cm:mlContainer translation parent + */ + @Auditable(key = Auditable.Key.ARG_0, parameters = {"translationNodeRef"}) + NodeRef getTranslationContainer(NodeRef translationNodeRef); + + /** + * Create a new edition of an existing cm:mlContainer. + * + * @param mlContainerNodeRef An existing cm:mlContainer + * @param translationNodeRef The specific cm:translation to use as the starting point + * of the new edition. + * @return Returns the cm:mlContainer + */ + @Auditable(key = Auditable.Key.ARG_0, parameters = {"mlContainerNodeRef", "translationNodeRef"}) + NodeRef createEdition(NodeRef mlContainerNodeRef, NodeRef translationNodeRef); +} diff --git a/source/java/org/alfresco/service/cmr/repository/datatype/DefaultTypeConverter.java b/source/java/org/alfresco/service/cmr/repository/datatype/DefaultTypeConverter.java index b1421ef95b..fa519c488a 100644 --- a/source/java/org/alfresco/service/cmr/repository/datatype/DefaultTypeConverter.java +++ b/source/java/org/alfresco/service/cmr/repository/datatype/DefaultTypeConverter.java @@ -28,8 +28,10 @@ import java.text.DecimalFormat; import java.text.ParseException; import java.util.Calendar; import java.util.Date; +import java.util.Locale; import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.i18n.I18NUtil; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; @@ -268,7 +270,28 @@ public class DefaultTypeConverter } }); + INSTANCE.addConverter(String.class, Locale.class, new TypeConverter.Converter() + { + public Locale convert(String source) + { + return I18NUtil.parseLocale(source); + } + }); + + // + // From Locale + // + + INSTANCE.addConverter(Locale.class, String.class, new TypeConverter.Converter() + { + public String convert(Locale source) + { + return source.toString(); + } + }); + + // // From MLText //