Index: src/main/src/org/compass/core/impl/CascadingManager.java =================================================================== --- src/main/src/org/compass/core/impl/CascadingManager.java (revision 2423) +++ src/main/src/org/compass/core/impl/CascadingManager.java Mon Nov 05 09:52:53 CST 2007 @@ -20,8 +20,12 @@ import java.util.Collection; import java.util.Iterator; +import org.compass.core.CompassCascadeFilter; import org.compass.core.CompassException; +import org.compass.core.config.CompassConfigurable; import org.compass.core.config.CompassEnvironment; +import org.compass.core.config.CompassSettings; +import org.compass.core.config.ConfigurationException; import org.compass.core.mapping.CascadeMapping; import org.compass.core.mapping.CompassMapping; import org.compass.core.mapping.ResourceMapping; @@ -31,17 +35,36 @@ /** * @author kimchy */ -public class CascadingManager { +public class CascadingManager implements CompassConfigurable { private InternalCompassSession session; private CompassMapping mapping; + private CompassCascadeFilter cascadeFilter; + public CascadingManager(InternalCompassSession session) { this.session = session; this.mapping = session.getMapping(); + configure(session.getCompass().getSettings()); } + public void configure(CompassSettings settings) throws CompassException { + String filterName = settings.getSetting(CompassEnvironment.Cascade.FILTER_TYPE); + if (filterName != null) + { + try + { + Class filterClass = settings.getSettingAsClass(CompassEnvironment.Cascade.FILTER_TYPE, CompassCascadeFilter.class); + cascadeFilter = (CompassCascadeFilter) filterClass.newInstance(); + } + catch (Exception e) + { + throw new ConfigurationException("Unable to create cascade filter of class " + filterName, e); + } + } + } + public boolean cascade(Object root, CascadeMapping.Cascade cascade) throws CompassException { if (cascadingDisabled()) return false; if (root instanceof AliasedObject) { @@ -107,10 +130,19 @@ return; } if (cascade == CascadeMapping.Cascade.DELETE) { + if (cascadeFilter != null && cascadeFilter.shouldFilterDelete(value)) { + return; + } session.delete(value); } else if (cascade == CascadeMapping.Cascade.CREATE) { + if (cascadeFilter != null && cascadeFilter.shouldFilterCreate(value)) { + return; + } session.create(value); } else if (cascade == CascadeMapping.Cascade.SAVE) { + if (cascadeFilter != null && cascadeFilter.shouldFilterSave(value)) { + return; + } session.save(value); } else { throw new IllegalArgumentException("Failed to perform cascading unknown type [" + cascade + "]"); @@ -120,5 +152,4 @@ private boolean cascadingDisabled() { return session.getSettings().getSettingAsBoolean(CompassEnvironment.Cascade.DISABLE, false); } - } Index: src/main/src/org/compass/core/config/CompassEnvironment.java =================================================================== --- src/main/src/org/compass/core/config/CompassEnvironment.java (revision 2423) +++ src/main/src/org/compass/core/config/CompassEnvironment.java Mon Nov 05 09:11:18 CST 2007 @@ -566,5 +566,11 @@ * Disable all cascading operations. */ public static final String DISABLE = "compass.cascade.disable"; + + /** + * The fully qualified class name of a class implementing CompassCascadeFilter, which + * allows filtering of create/insert/delete cascade operations. + */ + public static final String FILTER_TYPE = "compass.cascade.filter.type"; } } Index: src/main/src/org/compass/core/CompassCascadeFilter.java =================================================================== --- src/main/src/org/compass/core/CompassCascadeFilter.java Mon Nov 05 09:40:34 CST 2007 +++ src/main/src/org/compass/core/CompassCascadeFilter.java Mon Nov 05 09:40:34 CST 2007 @@ -0,0 +1,31 @@ +package org.compass.core; + +/** + * Allows filtering of create/save/delete cascade operations. + */ +public interface CompassCascadeFilter { + + /** + * Should the create cascade operation be filtered or not + * + * @param obj The object being cascade-created + * @return true if the event should be filtered, false otherwise + */ + boolean shouldFilterCreate(Object obj); + + /** + * Should the save cascade operation be filtered or not + * + * @param obj The object being cascade-saved + * @return true if the event should be filtered, false otherwise + */ + boolean shouldFilterSave(Object obj); + + /** + * Should the delete cascade operation be filtered or not + * + * @param obj The object being cascade-deleted + * @return true if the event should be filtered, false otherwise + */ + boolean shouldFilterDelete(Object obj); +}