diff --git a/source/java/org/alfresco/repo/content/metadata/AbstractMappingMetadataExtracter.java b/source/java/org/alfresco/repo/content/metadata/AbstractMappingMetadataExtracter.java
index 8f4c3eab48..bb53c2aa5c 100644
--- a/source/java/org/alfresco/repo/content/metadata/AbstractMappingMetadataExtracter.java
+++ b/source/java/org/alfresco/repo/content/metadata/AbstractMappingMetadataExtracter.java
@@ -1534,10 +1534,12 @@ abstract public class AbstractMappingMetadataExtracter implements MetadataExtrac
* The default implementation looks for the default mapping file in the location
* given by the class name and .properties. If the extracter's class is
* x.y.z.MyExtracter then the default properties will be picked up at
- * classpath:/x/y/z/MyExtracter.properties.
+ * classpath:/alfresco/metadata/MyExtracter.properties.
+ * The previous location of classpath:/x/y/z/MyExtracter.properties is
+ * still supported but may be removed in a future release.
* Inner classes are supported, but the '$' in the class name is replaced with '-', so
* default properties for x.y.z.MyStuff$MyExtracter will be located using
- * x.y.z.MyStuff-MyExtracter.properties.
+ * classpath:/alfresco/metadata/MyStuff-MyExtracter.properties.
*
* The default mapping implementation should include thorough Javadocs so that the
* system administrators can accurately determine how to best enhance or override the
@@ -1560,15 +1562,42 @@ abstract public class AbstractMappingMetadataExtracter implements MetadataExtrac
*/
protected Map> getDefaultMapping()
{
- String className = this.getClass().getName();
- // Replace $
- className = className.replace('$', '-');
- // Replace .
- className = className.replace('.', '/');
- // Append .properties
- String propertiesUrl = className + ".properties";
- // Attempt to load the properties
- return readMappingProperties(propertiesUrl);
+ AlfrescoRuntimeException metadataLocationReadException = null;
+ try
+ {
+ // Can't use getSimpleName here because we lose inner class $ processing
+ String className = this.getClass().getName();
+ String shortClassName = className.split("\\.")[className.split("\\.").length - 1];
+ // Replace $
+ shortClassName = shortClassName.replace('$', '-');
+ // Append .properties
+ String metadataPropertiesUrl = "alfresco/metadata/" + shortClassName + ".properties";
+ // Attempt to load the properties
+ return readMappingProperties(metadataPropertiesUrl);
+ }
+ catch (AlfrescoRuntimeException e)
+ {
+ // We'll save this to throw at someone later
+ metadataLocationReadException = e;
+ }
+ // Try package location
+ try
+ {
+ String canonicalClassName = this.getClass().getName();
+ // Replace $
+ canonicalClassName = canonicalClassName.replace('$', '-');
+ // Replace .
+ canonicalClassName = canonicalClassName.replace('.', '/');
+ // Append .properties
+ String packagePropertiesUrl = canonicalClassName + ".properties";
+ // Attempt to load the properties
+ return readMappingProperties(packagePropertiesUrl);
+ }
+ catch (AlfrescoRuntimeException e)
+ {
+ // Not found in either location, but we want to throw the error for the new metadata location
+ throw metadataLocationReadException;
+ }
}
/**
diff --git a/source/java/org/alfresco/repo/content/metadata/MappingMetadataExtracterTest.java b/source/java/org/alfresco/repo/content/metadata/MappingMetadataExtracterTest.java
index 5fe20fabba..040d6ee80f 100644
--- a/source/java/org/alfresco/repo/content/metadata/MappingMetadataExtracterTest.java
+++ b/source/java/org/alfresco/repo/content/metadata/MappingMetadataExtracterTest.java
@@ -28,6 +28,7 @@ import java.util.Set;
import junit.framework.TestCase;
+import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.filestore.FileContentReader;
import org.alfresco.repo.content.metadata.MetadataExtracter.OverwritePolicy;
@@ -68,6 +69,42 @@ public class MappingMetadataExtracterTest extends TestCase
assertTrue("Extracter not initialized.", extracter.initCheck);
}
+ /** Test the new alfresco/metadata properties location */
+ public void testSetUpPropertiesLocationMetadata()
+ {
+ DummyPropertiesInMetadataLocationMappingMetadataExtracter metadataLocationExtracter =
+ new DummyPropertiesInMetadataLocationMappingMetadataExtracter();
+ metadataLocationExtracter.register();
+ assertNotNull("Extracter not initialized.", metadataLocationExtracter.getMapping());
+ assertNotNull("Mapping not found",
+ metadataLocationExtracter.getMapping().get(DummyMappingMetadataExtracter.PROP_A));
+ }
+
+ /** Test that the old package-based properties location still works */
+ public void testSetUpPropertiesLocationPackage()
+ {
+ DummyPropertiesInPackageLocationMappingMetadataExtracter packageLocationExtracter =
+ new DummyPropertiesInPackageLocationMappingMetadataExtracter();
+ packageLocationExtracter.register();
+ assertNotNull("Extracter not initialized.", packageLocationExtracter.getMapping());
+ assertNotNull("Mapping not found",
+ packageLocationExtracter.getMapping().get(DummyMappingMetadataExtracter.PROP_A));
+ }
+
+ /** Test that an extract with missing location throws the correct error */
+ public void testSetUpPropertiesMissing()
+ {
+ DummyPropertiesMissingMappingMetadataExtracter propertiesMissingExtracter =
+ new DummyPropertiesMissingMappingMetadataExtracter();
+ try
+ {
+ propertiesMissingExtracter.register();
+ } catch (AlfrescoRuntimeException e)
+ {
+ assertTrue(e.getMessage().contains("alfresco/metadata/"));
+ }
+ }
+
public void testDefaultExtract() throws Exception
{
destination.clear();
@@ -277,6 +314,33 @@ public class MappingMetadataExtracterTest extends TestCase
}
}
+ public static class DummyPropertiesInPackageLocationMappingMetadataExtracter extends AbstractMappingMetadataExtracter
+ {
+ @Override
+ protected Map extractRaw(ContentReader reader) throws Throwable
+ {
+ return null;
+ }
+ }
+
+ public static class DummyPropertiesInMetadataLocationMappingMetadataExtracter extends AbstractMappingMetadataExtracter
+ {
+ @Override
+ protected Map extractRaw(ContentReader reader) throws Throwable
+ {
+ return null;
+ }
+ }
+
+ public static class DummyPropertiesMissingMappingMetadataExtracter extends AbstractMappingMetadataExtracter
+ {
+ @Override
+ protected Map extractRaw(ContentReader reader) throws Throwable
+ {
+ return null;
+ }
+ }
+
private static class JunkValue implements Serializable
{
private static final JunkValue INSTANCE = new JunkValue();
diff --git a/source/test-resources/alfresco/metadata/MappingMetadataExtracterTest-DummyPropertiesInMetadataLocationMappingMetadataExtracter.properties b/source/test-resources/alfresco/metadata/MappingMetadataExtracterTest-DummyPropertiesInMetadataLocationMappingMetadataExtracter.properties
new file mode 100644
index 0000000000..95c5408b3c
--- /dev/null
+++ b/source/test-resources/alfresco/metadata/MappingMetadataExtracterTest-DummyPropertiesInMetadataLocationMappingMetadataExtracter.properties
@@ -0,0 +1,9 @@
+#
+# Dummy - default mapping
+#
+# Namespaces
+namespace.prefix.cm=http://www.alfresco.org/model/content/1.0
+namespace.prefix.dum=http://DummyMappingMetadataExtracter
+
+# Mappings
+a=dum:a1,dum:a2,dum:a3
diff --git a/source/test-resources/org/alfresco/repo/content/metadata/MappingMetadataExtracterTest-DummyPropertiesInPackageLocationMappingMetadataExtracter.properties b/source/test-resources/org/alfresco/repo/content/metadata/MappingMetadataExtracterTest-DummyPropertiesInPackageLocationMappingMetadataExtracter.properties
new file mode 100644
index 0000000000..95c5408b3c
--- /dev/null
+++ b/source/test-resources/org/alfresco/repo/content/metadata/MappingMetadataExtracterTest-DummyPropertiesInPackageLocationMappingMetadataExtracter.properties
@@ -0,0 +1,9 @@
+#
+# Dummy - default mapping
+#
+# Namespaces
+namespace.prefix.cm=http://www.alfresco.org/model/content/1.0
+namespace.prefix.dum=http://DummyMappingMetadataExtracter
+
+# Mappings
+a=dum:a1,dum:a2,dum:a3