mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
ALF-9521 Update the MetadataExtrator OverwritePolicy PRAGMATIC (the default) to always copy media related properties (such as image width), and add a PRUDENT for the previous PRAGMATIC behaviour
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@30702 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -33,6 +33,7 @@ import org.alfresco.repo.content.filestore.FileContentReader;
|
|||||||
import org.alfresco.repo.content.metadata.MetadataExtracter.OverwritePolicy;
|
import org.alfresco.repo.content.metadata.MetadataExtracter.OverwritePolicy;
|
||||||
import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
|
import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
|
||||||
import org.alfresco.service.cmr.repository.ContentReader;
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,10 +72,11 @@ public class MappingMetadataExtracterTest extends TestCase
|
|||||||
{
|
{
|
||||||
destination.clear();
|
destination.clear();
|
||||||
extracter.extract(reader, destination);
|
extracter.extract(reader, destination);
|
||||||
assertEquals(3, destination.size());
|
assertEquals(4, destination.size());
|
||||||
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_A1));
|
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_A1));
|
||||||
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_A2));
|
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_A2));
|
||||||
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_B));
|
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_B));
|
||||||
|
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_IMG));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPropertyMappingOverride() throws Exception
|
public void testPropertyMappingOverride() throws Exception
|
||||||
@@ -103,11 +105,12 @@ public class MappingMetadataExtracterTest extends TestCase
|
|||||||
// Added a3
|
// Added a3
|
||||||
destination.clear();
|
destination.clear();
|
||||||
extracter.extract(reader, destination);
|
extracter.extract(reader, destination);
|
||||||
assertEquals(4, destination.size());
|
assertEquals(5, destination.size());
|
||||||
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_A1));
|
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_A1));
|
||||||
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_A2));
|
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_A2));
|
||||||
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_A3));
|
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_A3));
|
||||||
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_B));
|
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_B));
|
||||||
|
assertTrue(destination.containsKey(DummyMappingMetadataExtracter.QNAME_IMG));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPropertyMappingOverrideExtra() throws Exception
|
public void testPropertyMappingOverrideExtra() throws Exception
|
||||||
@@ -131,27 +134,60 @@ public class MappingMetadataExtracterTest extends TestCase
|
|||||||
{
|
{
|
||||||
extracter.setOverwritePolicy(OverwritePolicy.EAGER);
|
extracter.setOverwritePolicy(OverwritePolicy.EAGER);
|
||||||
extracter.extract(reader, destination);
|
extracter.extract(reader, destination);
|
||||||
assertEquals(3, destination.size());
|
assertEquals(4, destination.size());
|
||||||
assertEquals(DummyMappingMetadataExtracter.VALUE_A, destination.get(DummyMappingMetadataExtracter.QNAME_A1));
|
assertEquals(DummyMappingMetadataExtracter.VALUE_A, destination.get(DummyMappingMetadataExtracter.QNAME_A1));
|
||||||
assertEquals(DummyMappingMetadataExtracter.VALUE_A, destination.get(DummyMappingMetadataExtracter.QNAME_A2));
|
assertEquals(DummyMappingMetadataExtracter.VALUE_A, destination.get(DummyMappingMetadataExtracter.QNAME_A2));
|
||||||
assertEquals(DummyMappingMetadataExtracter.VALUE_B, destination.get(DummyMappingMetadataExtracter.QNAME_B));
|
assertEquals(DummyMappingMetadataExtracter.VALUE_B, destination.get(DummyMappingMetadataExtracter.QNAME_B));
|
||||||
|
assertEquals(DummyMappingMetadataExtracter.VALUE_IMG, destination.get(DummyMappingMetadataExtracter.QNAME_IMG));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOverwritePolicyPragmatic()
|
public void testOverwritePolicyPragmatic()
|
||||||
{
|
{
|
||||||
extracter.setOverwritePolicy(OverwritePolicy.PRAGMATIC);
|
extracter.setOverwritePolicy(OverwritePolicy.PRAGMATIC);
|
||||||
|
|
||||||
|
// Put some values in to start with
|
||||||
|
destination.put(DummyMappingMetadataExtracter.QNAME_C, "Will not change");
|
||||||
|
destination.put(DummyMappingMetadataExtracter.QNAME_IMG, "Will be changed");
|
||||||
|
|
||||||
|
// Extract
|
||||||
extracter.extract(reader, destination);
|
extracter.extract(reader, destination);
|
||||||
assertEquals(3, destination.size());
|
assertEquals(5, destination.size());
|
||||||
|
|
||||||
|
// Check the values as extracted
|
||||||
assertEquals(JunkValue.INSTANCE, destination.get(DummyMappingMetadataExtracter.QNAME_A1));
|
assertEquals(JunkValue.INSTANCE, destination.get(DummyMappingMetadataExtracter.QNAME_A1));
|
||||||
assertEquals(DummyMappingMetadataExtracter.VALUE_A, destination.get(DummyMappingMetadataExtracter.QNAME_A2));
|
assertEquals(DummyMappingMetadataExtracter.VALUE_A, destination.get(DummyMappingMetadataExtracter.QNAME_A2));
|
||||||
assertEquals(DummyMappingMetadataExtracter.VALUE_B, destination.get(DummyMappingMetadataExtracter.QNAME_B));
|
assertEquals(DummyMappingMetadataExtracter.VALUE_B, destination.get(DummyMappingMetadataExtracter.QNAME_B));
|
||||||
|
|
||||||
|
// Normal values not changed
|
||||||
|
assertEquals("Will not change", destination.get(DummyMappingMetadataExtracter.QNAME_C));
|
||||||
|
|
||||||
|
// Media parts are always overridden
|
||||||
|
assertEquals(DummyMappingMetadataExtracter.VALUE_IMG, destination.get(DummyMappingMetadataExtracter.QNAME_IMG));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOverwritePolicyPrudent()
|
||||||
|
{
|
||||||
|
extracter.setOverwritePolicy(OverwritePolicy.PRUDENT);
|
||||||
|
|
||||||
|
// Add a media property, won't be changed
|
||||||
|
destination.put(DummyMappingMetadataExtracter.QNAME_IMG, "Won't be changed");
|
||||||
|
|
||||||
|
// Extract and check
|
||||||
|
extracter.extract(reader, destination);
|
||||||
|
assertEquals(4, destination.size());
|
||||||
|
assertEquals(JunkValue.INSTANCE, destination.get(DummyMappingMetadataExtracter.QNAME_A1));
|
||||||
|
assertEquals(DummyMappingMetadataExtracter.VALUE_A, destination.get(DummyMappingMetadataExtracter.QNAME_A2));
|
||||||
|
assertEquals(DummyMappingMetadataExtracter.VALUE_B, destination.get(DummyMappingMetadataExtracter.QNAME_B));
|
||||||
|
|
||||||
|
// Media behaves the same as the others
|
||||||
|
assertEquals("Won't be changed", destination.get(DummyMappingMetadataExtracter.QNAME_IMG));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOverwritePolicyCautious()
|
public void testOverwritePolicyCautious()
|
||||||
{
|
{
|
||||||
extracter.setOverwritePolicy(OverwritePolicy.CAUTIOUS);
|
extracter.setOverwritePolicy(OverwritePolicy.CAUTIOUS);
|
||||||
extracter.extract(reader, destination);
|
extracter.extract(reader, destination);
|
||||||
assertEquals(3, destination.size());
|
assertEquals(4, destination.size());
|
||||||
assertEquals(JunkValue.INSTANCE, destination.get(DummyMappingMetadataExtracter.QNAME_A1));
|
assertEquals(JunkValue.INSTANCE, destination.get(DummyMappingMetadataExtracter.QNAME_A1));
|
||||||
assertEquals("", destination.get(DummyMappingMetadataExtracter.QNAME_A2));
|
assertEquals("", destination.get(DummyMappingMetadataExtracter.QNAME_A2));
|
||||||
assertEquals(null, destination.get(DummyMappingMetadataExtracter.QNAME_B));
|
assertEquals(null, destination.get(DummyMappingMetadataExtracter.QNAME_B));
|
||||||
@@ -174,10 +210,12 @@ public class MappingMetadataExtracterTest extends TestCase
|
|||||||
public static final String PROP_C = "c";
|
public static final String PROP_C = "c";
|
||||||
public static final String PROP_D = "d";
|
public static final String PROP_D = "d";
|
||||||
public static final String PROP_E = "e";
|
public static final String PROP_E = "e";
|
||||||
|
public static final String PROP_IMG = "exif";
|
||||||
public static final String VALUE_A = "AAA";
|
public static final String VALUE_A = "AAA";
|
||||||
public static final String VALUE_B = "BBB";
|
public static final String VALUE_B = "BBB";
|
||||||
public static final String VALUE_C = "CCC";
|
public static final String VALUE_C = "CCC";
|
||||||
public static final String VALUE_D = "DDD";
|
public static final String VALUE_D = "DDD";
|
||||||
|
public static final String VALUE_IMG = "IMAGE";
|
||||||
|
|
||||||
public static final String NAMESPACE_MY = "http://DummyMappingMetadataExtracter";
|
public static final String NAMESPACE_MY = "http://DummyMappingMetadataExtracter";
|
||||||
public static final QName QNAME_A1 = QName.createQName(NAMESPACE_MY, "a1");
|
public static final QName QNAME_A1 = QName.createQName(NAMESPACE_MY, "a1");
|
||||||
@@ -187,6 +225,7 @@ public class MappingMetadataExtracterTest extends TestCase
|
|||||||
public static final QName QNAME_C = QName.createQName(NAMESPACE_MY, "c");
|
public static final QName QNAME_C = QName.createQName(NAMESPACE_MY, "c");
|
||||||
public static final QName QNAME_D = QName.createQName(NAMESPACE_MY, "d");
|
public static final QName QNAME_D = QName.createQName(NAMESPACE_MY, "d");
|
||||||
public static final QName QNAME_E = QName.createQName(NAMESPACE_MY, "e"); // not extracted
|
public static final QName QNAME_E = QName.createQName(NAMESPACE_MY, "e"); // not extracted
|
||||||
|
public static final QName QNAME_IMG = QName.createQName(NamespaceService.EXIF_MODEL_1_0_URI, "test");
|
||||||
private static final Set<String> MIMETYPES;
|
private static final Set<String> MIMETYPES;
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
@@ -210,6 +249,7 @@ public class MappingMetadataExtracterTest extends TestCase
|
|||||||
defaultMapping = new HashMap<String, Set<QName>>(7);
|
defaultMapping = new HashMap<String, Set<QName>>(7);
|
||||||
defaultMapping.put(PROP_A, new HashSet<QName>(Arrays.asList(QNAME_A1, QNAME_A2)));
|
defaultMapping.put(PROP_A, new HashSet<QName>(Arrays.asList(QNAME_A1, QNAME_A2)));
|
||||||
defaultMapping.put(PROP_B, new HashSet<QName>(Arrays.asList(QNAME_B)));
|
defaultMapping.put(PROP_B, new HashSet<QName>(Arrays.asList(QNAME_B)));
|
||||||
|
defaultMapping.put(PROP_IMG, new HashSet<QName>(Arrays.asList(QNAME_IMG)));
|
||||||
|
|
||||||
initCheck = true;
|
initCheck = true;
|
||||||
|
|
||||||
@@ -232,6 +272,7 @@ public class MappingMetadataExtracterTest extends TestCase
|
|||||||
ret.put(PROP_B, VALUE_B);
|
ret.put(PROP_B, VALUE_B);
|
||||||
ret.put(PROP_C, VALUE_C);
|
ret.put(PROP_C, VALUE_C);
|
||||||
ret.put(PROP_D, VALUE_D);
|
ret.put(PROP_D, VALUE_D);
|
||||||
|
ret.put(PROP_IMG, VALUE_IMG);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ import java.util.Set;
|
|||||||
import org.alfresco.repo.content.ContentWorker;
|
import org.alfresco.repo.content.ContentWorker;
|
||||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||||
import org.alfresco.service.cmr.repository.ContentReader;
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,13 +75,22 @@ public interface MetadataExtracter extends ContentWorker
|
|||||||
return modifiedProperties;
|
return modifiedProperties;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This policy puts the new value if:
|
* This policy puts the new value if:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>the extracted property is not null</li>
|
* <li>the extracted property is not null</li>
|
||||||
* <li>there is no target key for the property</li>
|
* <li>either:
|
||||||
* <li>the target value is null</li>
|
* <ul>
|
||||||
* <li>the string representation of the target value is an empty string</li>
|
* <li>there is no target key for the property</li>
|
||||||
|
* <li>the target value is null</li>
|
||||||
|
* <li>the string representation of the target value is an empty string</li>
|
||||||
|
* </ul>
|
||||||
|
* or:
|
||||||
|
* <ul>
|
||||||
|
* <li>the extracted property is a media related one (eg Image, Audio or Video)</li>
|
||||||
|
* </ul>
|
||||||
|
* </li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* <tt>null</tt> extracted values are return in the 'modified' map.
|
* <tt>null</tt> extracted values are return in the 'modified' map.
|
||||||
*/
|
*/
|
||||||
@@ -97,12 +107,23 @@ public interface MetadataExtracter extends ContentWorker
|
|||||||
{
|
{
|
||||||
QName propertyQName = entry.getKey();
|
QName propertyQName = entry.getKey();
|
||||||
Serializable extractedValue = entry.getValue();
|
Serializable extractedValue = entry.getValue();
|
||||||
|
|
||||||
// Ignore null extracted value
|
// Ignore null extracted value
|
||||||
if (extractedValue == null)
|
if (extractedValue == null)
|
||||||
{
|
{
|
||||||
modifiedProperties.put(propertyQName, extractedValue);
|
modifiedProperties.put(propertyQName, extractedValue);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the property is media related, always extract
|
||||||
|
String propertyNS = propertyQName.getNamespaceURI();
|
||||||
|
if(propertyNS.equals(NamespaceService.EXIF_MODEL_1_0_URI))
|
||||||
|
{
|
||||||
|
targetProperties.put(propertyQName, extractedValue);
|
||||||
|
modifiedProperties.put(propertyQName, extractedValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle the shortcut cases where the target value is missing or null
|
// Handle the shortcut cases where the target value is missing or null
|
||||||
if (!targetProperties.containsKey(propertyQName))
|
if (!targetProperties.containsKey(propertyQName))
|
||||||
{
|
{
|
||||||
@@ -111,10 +132,12 @@ public interface MetadataExtracter extends ContentWorker
|
|||||||
modifiedProperties.put(propertyQName, extractedValue);
|
modifiedProperties.put(propertyQName, extractedValue);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Look at the old value, and decide based on that
|
||||||
Serializable originalValue = targetProperties.get(propertyQName);
|
Serializable originalValue = targetProperties.get(propertyQName);
|
||||||
if (originalValue == null)
|
if (originalValue == null)
|
||||||
{
|
{
|
||||||
// The current value is null
|
// The previous value is null, extract
|
||||||
targetProperties.put(propertyQName, extractedValue);
|
targetProperties.put(propertyQName, extractedValue);
|
||||||
modifiedProperties.put(propertyQName, extractedValue);
|
modifiedProperties.put(propertyQName, extractedValue);
|
||||||
continue;
|
continue;
|
||||||
@@ -136,11 +159,81 @@ public interface MetadataExtracter extends ContentWorker
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have some other object as the original value, so keep it
|
// We have some other object as the original value, so keep it
|
||||||
}
|
}
|
||||||
return modifiedProperties;
|
return modifiedProperties;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This policy puts the new value if:
|
||||||
|
* <ul>
|
||||||
|
* <li>the extracted property is not null</li>
|
||||||
|
* <li>there is no target key for the property</li>
|
||||||
|
* <li>the target value is null</li>
|
||||||
|
* <li>the string representation of the target value is an empty string</li>
|
||||||
|
* </ul>
|
||||||
|
* <tt>null</tt> extracted values are return in the 'modified' map.
|
||||||
|
*/
|
||||||
|
PRUDENT
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Map<QName, Serializable> applyProperties(Map<QName, Serializable> extractedProperties, Map<QName, Serializable> targetProperties)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Negative and positive checks are mixed in the loop.
|
||||||
|
*/
|
||||||
|
Map<QName, Serializable> modifiedProperties = new HashMap<QName, Serializable>(7);
|
||||||
|
for (Map.Entry<QName, Serializable> entry : extractedProperties.entrySet())
|
||||||
|
{
|
||||||
|
QName propertyQName = entry.getKey();
|
||||||
|
Serializable extractedValue = entry.getValue();
|
||||||
|
// Ignore null extracted value
|
||||||
|
if (extractedValue == null)
|
||||||
|
{
|
||||||
|
modifiedProperties.put(propertyQName, extractedValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Handle the shortcut cases where the target value is missing or null
|
||||||
|
if (!targetProperties.containsKey(propertyQName))
|
||||||
|
{
|
||||||
|
// There is nothing currently
|
||||||
|
targetProperties.put(propertyQName, extractedValue);
|
||||||
|
modifiedProperties.put(propertyQName, extractedValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Serializable originalValue = targetProperties.get(propertyQName);
|
||||||
|
if (originalValue == null)
|
||||||
|
{
|
||||||
|
// The current value is null
|
||||||
|
targetProperties.put(propertyQName, extractedValue);
|
||||||
|
modifiedProperties.put(propertyQName, extractedValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Check the string representation
|
||||||
|
if (originalValue instanceof String)
|
||||||
|
{
|
||||||
|
String originalValueStr = (String) originalValue;
|
||||||
|
if (originalValueStr != null && originalValueStr.length() > 0)
|
||||||
|
{
|
||||||
|
// The original value is non-trivial
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The original string is trivial
|
||||||
|
targetProperties.put(propertyQName, extractedValue);
|
||||||
|
modifiedProperties.put(propertyQName, extractedValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We have some other object as the original value, so keep it
|
||||||
|
}
|
||||||
|
return modifiedProperties;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This policy only puts the extracted value if there is no value (null or otherwise) in the properties map.
|
* This policy only puts the extracted value if there is no value (null or otherwise) in the properties map.
|
||||||
* It is assumed that the mere presence of a property key is enough to inidicate that the target property
|
* It is assumed that the mere presence of a property key is enough to inidicate that the target property
|
||||||
|
Reference in New Issue
Block a user