diff --git a/ccm-cms/src/com/arsdigita/cms/AssociationCopier.java b/ccm-cms/src/com/arsdigita/cms/AssociationCopier.java
index 8dd5fc630..8a432bc4b 100644
--- a/ccm-cms/src/com/arsdigita/cms/AssociationCopier.java
+++ b/ccm-cms/src/com/arsdigita/cms/AssociationCopier.java
@@ -1,6 +1,5 @@
package com.arsdigita.cms;
-import com.arsdigita.domain.DomainObject;
import com.arsdigita.persistence.metadata.Property;
/**
@@ -9,12 +8,30 @@ import com.arsdigita.persistence.metadata.Property;
* @version $Id$
*/
public interface AssociationCopier {
-
- boolean copyReverseProperty(CustomCopy source,
- DomainObject target,
- Property property,
- DomainObject value,
- ItemCopier copier);
-
-
+
+ /**
+ *
+ * Return the property which is handled by this implementation. Format:
+ *
+ *
+ * {@code $type::$property}
+ *
+ *
+ * Where {@code $type} is the fully qualified name of the class/type owing
+ * the property and {@code property} is the name the property. Example
+ *
+ *
+ * {@code com.arsdigita.cms.contenttypes.GenericPerson::publications}
+ *
+ *
+ * This indicates that the implementation handles a property
+ * {@code publications} added to the {@code GenericPerson} type by some
+ * module via an PDL association.
+ *
+ *
+ * @return
+ */
+ String forProperty();
+
+ boolean copyProperty(CustomCopy source, Property property, ItemCopier copier);
}
diff --git a/ccm-cms/src/com/arsdigita/cms/AssociationCopierLoader.java b/ccm-cms/src/com/arsdigita/cms/AssociationCopierLoader.java
new file mode 100644
index 000000000..8c9297cb1
--- /dev/null
+++ b/ccm-cms/src/com/arsdigita/cms/AssociationCopierLoader.java
@@ -0,0 +1,77 @@
+package com.arsdigita.cms;
+
+import com.arsdigita.persistence.metadata.Property;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ * @version $Id$
+ */
+public final class AssociationCopierLoader {
+
+ private static final AssociationCopierLoader INSTANCE =
+ new AssociationCopierLoader();
+ private static final Logger logger =
+ Logger.getLogger(AssociationCopierLoader.class);
+ private Map copiers =
+ new HashMap();
+
+ private AssociationCopierLoader() {
+ final String[] assocCopierNames = CMSConfig.getInstance().
+ getAssocCopiers();
+
+ for (String assocCopierName : assocCopierNames) {
+ loadAssocCopier(assocCopierName);
+ }
+ }
+
+ private void loadAssocCopier(final String name) {
+ final Class> clazz;
+ try {
+ clazz = Class.forName(name);
+ } catch (ClassNotFoundException ex) {
+ logger.warn(String.format("No class found for name '%s'. Skiping.",
+ name),
+ ex);
+ return;
+ }
+
+ if (clazz.isAssignableFrom(AssociationCopier.class)) {
+ try {
+ final AssociationCopier copier = (AssociationCopier) clazz.
+ newInstance();
+
+ copiers.put(copier.forProperty(), copier);
+ } catch (InstantiationException ex) {
+ logger.warn(String.format(
+ "Failed to instaniate copier '%s'. Skiping.",
+ name),
+ ex);
+ } catch (IllegalAccessException ex) {
+ logger.warn(String.format(
+ "Failed to instaniate copier '%s'. Skiping.",
+ name),
+ ex);
+ }
+ } else {
+ logger.warn(String.format("Class '%s' is not an implementation of "
+ + "the AssociationCopier interface. "
+ + "Skiping",
+ name));
+ }
+ }
+
+ public static AssociationCopierLoader getInstance() {
+ return INSTANCE;
+ }
+
+ public AssociationCopier getAssociationCopierFor(final Property property,
+ final CustomCopy source) {
+ return copiers.get(String.format("%s::%s",
+ source.getClass().getName(),
+ property.getName()));
+ }
+}
diff --git a/ccm-cms/src/com/arsdigita/cms/CMSConfig.java b/ccm-cms/src/com/arsdigita/cms/CMSConfig.java
index 86bca438d..249eee156 100755
--- a/ccm-cms/src/com/arsdigita/cms/CMSConfig.java
+++ b/ccm-cms/src/com/arsdigita/cms/CMSConfig.java
@@ -620,6 +620,14 @@ public final class CMSConfig extends AbstractConfig {
"com.arsdigita.cms.lifecycle.threaded_publishing",
Parameter.REQUIRED,
true);
+
+ /**
+ * Copiers for associations not known yet. For example for associations
+ * with the generic types defined in this module from another module.
+ */
+ private final Parameter m_assocCopiers = new StringArrayParameter("com.arsdigita.cms.publish.association_copiers",
+ Parameter.REQUIRED,
+ new String[]{});
// ///////////////////////////////////////////
// publishToFile package related parameter
@@ -704,6 +712,7 @@ public final class CMSConfig extends AbstractConfig {
register(m_useOldStyleItemLifecycleItemPane);
register(m_threadPublishing);
+ register(m_assocCopiers);
// publishToFile package related parameter
// Moved to publishToFile.PublishToFileConfig as of version 6.0.2
@@ -1122,4 +1131,8 @@ public final class CMSConfig extends AbstractConfig {
public Boolean getThreadedPublishing() {
return (Boolean) get(m_threadPublishing);
}
+
+ public String[] getAssocCopiers() {
+ return (String[]) get(m_assocCopiers);
+ }
}
diff --git a/ccm-cms/src/com/arsdigita/cms/ContentItem.java b/ccm-cms/src/com/arsdigita/cms/ContentItem.java
index edaa44050..ae539b574 100755
--- a/ccm-cms/src/com/arsdigita/cms/ContentItem.java
+++ b/ccm-cms/src/com/arsdigita/cms/ContentItem.java
@@ -1139,7 +1139,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy {
s_log.debug("Deleting old live version");
oldVersion.delete();
- PublishedLink.refreshOnUnpublish(this);
+ PublishedLink.refreshOnUnpublish(this);
}
if (parent instanceof ContentBundle || parent instanceof Folder) {
@@ -1167,7 +1167,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy {
save();
- PublishedLink.updateLiveLinks(version);
+ PublishedLink.updateLiveLinks(version);
save();
// publish item (as template or html pages) to the file
@@ -1947,6 +1947,14 @@ public class ContentItem extends VersionedACSObject implements CustomCopy {
}
}
+ final AssociationCopierLoader assocCopierLoader =
+ AssociationCopierLoader.getInstance();
+ final AssociationCopier assocCopier = assocCopierLoader.
+ getAssociationCopierFor(property, source);
+ if (assocCopier != null) {
+ return assocCopier.copyProperty(source, property, copier);
+ }
+
return false;
}