mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Fixed AR-1361: MLText persistence doesn't use serialization
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5767 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -60,7 +60,6 @@ public class ContentTestSuite extends TestSuite
|
||||
{
|
||||
TestSuite suite = new TestSuite();
|
||||
|
||||
suite.addTestSuite(ContentStoreCleanerTest.class);
|
||||
suite.addTestSuite(ContentStoreCleanerTest.class);
|
||||
suite.addTestSuite(FileContentStoreTest.class);
|
||||
suite.addTestSuite(NoRandomAccessFileContentStoreTest.class);
|
||||
|
@@ -34,10 +34,13 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.attributes.Attribute;
|
||||
import org.alfresco.repo.attributes.AttributeConverter;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.MLText;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.Path;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
@@ -49,8 +52,6 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Immutable property value storage class.
|
||||
* <p>
|
||||
* The
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
@@ -160,6 +161,18 @@ public class PropertyValue implements Cloneable, Serializable
|
||||
return DefaultTypeConverter.INSTANCE.convert(Date.class, value);
|
||||
}
|
||||
},
|
||||
DB_ATTRIBUTE
|
||||
{
|
||||
/** class that is able to convert from persisted attributes to normal attributes */
|
||||
private AttributeConverter attributeConverter = new AttributeConverter();
|
||||
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
Attribute attribute = DefaultTypeConverter.INSTANCE.convert(Attribute.class, value);
|
||||
return attributeConverter.toPersistent(attribute);
|
||||
}
|
||||
},
|
||||
SERIALIZABLE
|
||||
{
|
||||
@Override
|
||||
@@ -168,6 +181,20 @@ public class PropertyValue implements Cloneable, Serializable
|
||||
return value;
|
||||
}
|
||||
},
|
||||
MLTEXT
|
||||
{
|
||||
@Override
|
||||
protected ValueType getPersistedType(Serializable value)
|
||||
{
|
||||
return ValueType.DB_ATTRIBUTE;
|
||||
}
|
||||
|
||||
@Override
|
||||
Serializable convert(Serializable value)
|
||||
{
|
||||
return DefaultTypeConverter.INSTANCE.convert(MLText.class, value);
|
||||
}
|
||||
},
|
||||
CONTENT
|
||||
{
|
||||
@Override
|
||||
@@ -292,6 +319,9 @@ public class PropertyValue implements Cloneable, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a value to this type. The implementation must be able to cope with any legitimate
|
||||
* source value.
|
||||
*
|
||||
* @see DefaultTypeConverter.INSTANCE#convert(Class, Object)
|
||||
*/
|
||||
abstract Serializable convert(Serializable value);
|
||||
@@ -389,6 +419,14 @@ public class PropertyValue implements Cloneable, Serializable
|
||||
{
|
||||
return ValueType.VERSION_NUMBER;
|
||||
}
|
||||
else if (value instanceof Attribute)
|
||||
{
|
||||
return ValueType.DB_ATTRIBUTE;
|
||||
}
|
||||
else if (value instanceof MLText)
|
||||
{
|
||||
return ValueType.MLTEXT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// type is not recognised as belonging to any particular slot
|
||||
@@ -412,8 +450,7 @@ public class PropertyValue implements Cloneable, Serializable
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.CATEGORY, ValueType.NODEREF);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.CONTENT, ValueType.CONTENT);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.TEXT, ValueType.STRING);
|
||||
// TODO: Re-examine storage of MLTEXT data type
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.MLTEXT, ValueType.SERIALIZABLE);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.MLTEXT, ValueType.MLTEXT);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.NODE_REF, ValueType.NODEREF);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.CHILD_ASSOC_REF, ValueType.CHILD_ASSOC_REF);
|
||||
valueTypesByPropertyType.put(DataTypeDefinition.ASSOC_REF, ValueType.ASSOC_REF);
|
||||
@@ -434,6 +471,7 @@ public class PropertyValue implements Cloneable, Serializable
|
||||
private Float floatValue;
|
||||
private Double doubleValue;
|
||||
private String stringValue;
|
||||
private Attribute attributeValue;
|
||||
private Serializable serializableValue;
|
||||
|
||||
/**
|
||||
@@ -534,6 +572,7 @@ public class PropertyValue implements Cloneable, Serializable
|
||||
EqualsHelper.nullSafeEquals(this.floatValue, that.floatValue) &&
|
||||
EqualsHelper.nullSafeEquals(this.doubleValue, that.doubleValue) &&
|
||||
EqualsHelper.nullSafeEquals(this.stringValue, that.stringValue) &&
|
||||
EqualsHelper.nullSafeEquals(this.attributeValue, that.attributeValue) &&
|
||||
EqualsHelper.nullSafeEquals(this.serializableValue, that.serializableValue)
|
||||
);
|
||||
|
||||
@@ -636,6 +675,9 @@ public class PropertyValue implements Cloneable, Serializable
|
||||
case STRING:
|
||||
this.stringValue = (String) value;
|
||||
break;
|
||||
case DB_ATTRIBUTE:
|
||||
this.attributeValue = (Attribute) value;
|
||||
break;
|
||||
case SERIALIZABLE:
|
||||
this.serializableValue = (Serializable) value;
|
||||
break;
|
||||
@@ -679,6 +721,8 @@ public class PropertyValue implements Cloneable, Serializable
|
||||
{
|
||||
return this.stringValue;
|
||||
}
|
||||
case DB_ATTRIBUTE:
|
||||
return this.attributeValue;
|
||||
case SERIALIZABLE:
|
||||
return this.serializableValue;
|
||||
default:
|
||||
@@ -819,6 +863,15 @@ public class PropertyValue implements Cloneable, Serializable
|
||||
this.stringValue = value;
|
||||
}
|
||||
|
||||
public Attribute getAttributeValue()
|
||||
{
|
||||
return attributeValue;
|
||||
}
|
||||
public void setAttributeValue(Attribute value)
|
||||
{
|
||||
this.attributeValue = value;
|
||||
}
|
||||
|
||||
public Serializable getSerializableValue()
|
||||
{
|
||||
return serializableValue;
|
||||
|
52
source/java/org/alfresco/repo/domain/PropertyValueTest.java
Normal file
52
source/java/org/alfresco/repo/domain/PropertyValueTest.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing
|
||||
*/
|
||||
package org.alfresco.repo.domain;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.MLText;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* @see PropertyValue
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class PropertyValueTest extends TestCase
|
||||
{
|
||||
@SuppressWarnings("unused")
|
||||
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||
|
||||
public void testMLText()
|
||||
{
|
||||
MLText mlText = new MLText(Locale.FRENCH, "bonjour");
|
||||
PropertyValue propertyValue = new PropertyValue(DataTypeDefinition.MLTEXT, mlText);
|
||||
assertNotNull("MLText not persisted as an attribute", propertyValue.getAttributeValue());
|
||||
}
|
||||
}
|
@@ -70,6 +70,7 @@
|
||||
<property name="floatValue" column="float_value" type="float" />
|
||||
<property name="doubleValue" column="double_value" type="double" />
|
||||
<property name="stringValue" column="string_value" type="string" length="1024"/>
|
||||
<many-to-one name="attributeValue" column="attribute_value" class="org.alfresco.repo.attributes.AttributeImpl" />
|
||||
<property name="serializableValue" column="serializable_value" type="serializable" length="16384"/>
|
||||
</composite-element>
|
||||
</map>
|
||||
|
@@ -75,7 +75,6 @@ import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
|
@@ -50,8 +50,6 @@ public class MLText extends HashMap<Locale, String>
|
||||
{
|
||||
private static final long serialVersionUID = -3696135175650511841L;
|
||||
|
||||
private Locale defaultLocale;
|
||||
|
||||
public MLText()
|
||||
{
|
||||
super(3, 0.75F);
|
||||
@@ -82,7 +80,6 @@ public class MLText extends HashMap<Locale, String>
|
||||
public MLText(Locale locale, String value)
|
||||
{
|
||||
super(3, 0.75F);
|
||||
defaultLocale = locale;
|
||||
super.put(locale, value);
|
||||
}
|
||||
|
||||
@@ -164,7 +161,7 @@ public class MLText extends HashMap<Locale, String>
|
||||
if (match == null)
|
||||
{
|
||||
// No close matches for the locale - go for the default locale
|
||||
locale = defaultLocale;
|
||||
locale = I18NUtil.getLocale();
|
||||
match = I18NUtil.getNearestLocale(locale, options);
|
||||
if (match == null)
|
||||
{
|
||||
|
@@ -37,9 +37,15 @@ import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.repo.attributes.Attribute;
|
||||
import org.alfresco.repo.attributes.MapAttribute;
|
||||
import org.alfresco.repo.attributes.MapAttributeValue;
|
||||
import org.alfresco.repo.attributes.StringAttribute;
|
||||
import org.alfresco.repo.attributes.StringAttributeValue;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
@@ -73,7 +79,6 @@ import org.alfresco.util.VersionNumber;
|
||||
*/
|
||||
public class DefaultTypeConverter
|
||||
{
|
||||
|
||||
/**
|
||||
* Default Type Converter
|
||||
*/
|
||||
@@ -295,6 +300,41 @@ public class DefaultTypeConverter
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// Attributes
|
||||
//
|
||||
INSTANCE.addConverter(MapAttribute.class, MLText.class, new TypeConverter.Converter<MapAttribute, MLText>()
|
||||
{
|
||||
public MLText convert(MapAttribute source)
|
||||
{
|
||||
MLText ret = new MLText();
|
||||
for (Map.Entry<String, Attribute> entry : source.entrySet())
|
||||
{
|
||||
String localeStr = entry.getKey();
|
||||
Locale locale;
|
||||
try
|
||||
{
|
||||
locale = INSTANCE.convert(Locale.class, localeStr);
|
||||
}
|
||||
catch (TypeConversionException e)
|
||||
{
|
||||
throw new TypeConversionException(
|
||||
"MapAttribute string key cannot be converted to a locales:" + localeStr, e);
|
||||
}
|
||||
Attribute valueAttribute = entry.getValue();
|
||||
if (valueAttribute instanceof StringAttribute)
|
||||
{
|
||||
ret.put(locale, valueAttribute.getStringValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new TypeConversionException(
|
||||
"MapAttribute must contain Locale-String mappings to convert to MLText");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// From Locale
|
||||
@@ -339,6 +379,20 @@ public class DefaultTypeConverter
|
||||
}
|
||||
});
|
||||
|
||||
INSTANCE.addConverter(MLText.class, Attribute.class, new TypeConverter.Converter<MLText, Attribute>()
|
||||
{
|
||||
public Attribute convert(MLText source)
|
||||
{
|
||||
Attribute attribute = new MapAttributeValue();
|
||||
for (Map.Entry<Locale, String> entry : source.entrySet())
|
||||
{
|
||||
String localeStr = INSTANCE.convert(String.class, entry.getKey());
|
||||
Attribute stringAttribute = new StringAttributeValue(entry.getValue());
|
||||
attribute.put(localeStr, stringAttribute);
|
||||
}
|
||||
return attribute;
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// From enum
|
||||
|
@@ -34,6 +34,10 @@ import java.util.Locale;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.repo.attributes.Attribute;
|
||||
import org.alfresco.repo.attributes.MapAttributeValue;
|
||||
import org.alfresco.repo.attributes.StringAttribute;
|
||||
import org.alfresco.repo.attributes.StringAttributeValue;
|
||||
import org.alfresco.service.cmr.repository.MLText;
|
||||
import org.alfresco.util.ISO8601DateFormat;
|
||||
import org.alfresco.util.VersionNumber;
|
||||
@@ -145,6 +149,32 @@ public class DefaultTypeConverterTest extends TestCase
|
||||
|
||||
assertEquals(new VersionNumber("1.2.3"), DefaultTypeConverter.INSTANCE.convert(VersionNumber.class, "1.2.3"));
|
||||
}
|
||||
|
||||
String localeStrEn = DefaultTypeConverter.INSTANCE.convert(String.class, Locale.ENGLISH);
|
||||
String localeStrFr = DefaultTypeConverter.INSTANCE.convert(String.class, Locale.FRENCH);
|
||||
public void testToMLText()
|
||||
{
|
||||
StringAttribute stringAttributeEn = new StringAttributeValue("English text");
|
||||
StringAttribute stringAttributeFr = new StringAttributeValue("French text");
|
||||
MapAttributeValue mapAttributeValue = new MapAttributeValue();
|
||||
mapAttributeValue.put(localeStrEn, stringAttributeEn);
|
||||
mapAttributeValue.put(localeStrFr, stringAttributeFr);
|
||||
|
||||
MLText mlText = DefaultTypeConverter.INSTANCE.convert(MLText.class, mapAttributeValue);
|
||||
assertEquals("MapAttribute to MLText failed", "English text", mlText.getValue(Locale.ENGLISH));
|
||||
assertEquals("MapAttribute to MLText failed", "French text", mlText.getValue(Locale.FRENCH));
|
||||
}
|
||||
|
||||
public void testFromMLText()
|
||||
{
|
||||
MLText mlText = new MLText();
|
||||
mlText.put(Locale.ENGLISH, "English");
|
||||
mlText.put(Locale.FRENCH, "French");
|
||||
Attribute attribute = DefaultTypeConverter.INSTANCE.convert(Attribute.class, mlText);
|
||||
assertTrue("Attribute is of the wrong type", attribute instanceof MapAttributeValue);
|
||||
assertNotNull("ML value not mapped", attribute.get(localeStrEn));
|
||||
assertNotNull("ML value not mapped", attribute.get(localeStrFr));
|
||||
}
|
||||
|
||||
public void testPrimativeAccessors()
|
||||
{
|
||||
|
Reference in New Issue
Block a user