001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.core.cascade;
018:
019: import java.lang.reflect.Array;
020: import java.util.Collection;
021:
022: import org.compass.core.CompassException;
023: import org.compass.core.config.CompassConfigurable;
024: import org.compass.core.config.CompassEnvironment;
025: import org.compass.core.config.CompassSettings;
026: import org.compass.core.config.ConfigurationException;
027: import org.compass.core.mapping.CascadeMapping;
028: import org.compass.core.mapping.CompassMapping;
029: import org.compass.core.mapping.ResourceMapping;
030: import org.compass.core.spi.AliasedObject;
031: import org.compass.core.spi.InternalCompassSession;
032:
033: /**
034: * @author kimchy
035: */
036: public class CascadingManager implements CompassConfigurable {
037:
038: private InternalCompassSession session;
039:
040: private CompassMapping mapping;
041:
042: private CompassCascadeFilter cascadeFilter;
043:
044: public CascadingManager(InternalCompassSession session) {
045: this .session = session;
046: this .mapping = session.getMapping();
047: configure(session.getCompass().getSettings());
048: }
049:
050: public void configure(CompassSettings settings)
051: throws CompassException {
052: String filterName = settings
053: .getSetting(CompassEnvironment.Cascade.FILTER_TYPE);
054: if (filterName != null) {
055: try {
056: Class filterClass = settings.getSettingAsClass(
057: CompassEnvironment.Cascade.FILTER_TYPE,
058: CompassCascadeFilter.class);
059: cascadeFilter = (CompassCascadeFilter) filterClass
060: .newInstance();
061: } catch (Exception e) {
062: throw new ConfigurationException(
063: "Unable to create cascade filter of class "
064: + filterName, e);
065: }
066: }
067: }
068:
069: public boolean cascade(Object root, CascadeMapping.Cascade cascade)
070: throws CompassException {
071: if (cascadingDisabled())
072: return false;
073: if (root instanceof AliasedObject) {
074: return cascade(((AliasedObject) root).getAlias(), root,
075: cascade);
076: }
077: return cascade(root.getClass(), root, cascade);
078: }
079:
080: public boolean cascade(String alias, Object root,
081: CascadeMapping.Cascade cascade) throws CompassException {
082: if (cascadingDisabled())
083: return false;
084: ResourceMapping resourceMapping = mapping
085: .getMappingByAlias(alias);
086: return resourceMapping != null
087: && cascade(resourceMapping, root, cascade);
088: }
089:
090: public boolean cascade(Class clazz, Object root,
091: CascadeMapping.Cascade cascade) throws CompassException {
092: if (cascadingDisabled())
093: return false;
094: ResourceMapping resourceMapping = mapping
095: .getMappingByClass(clazz);
096: return resourceMapping != null
097: && cascade(resourceMapping, root, cascade);
098: }
099:
100: private boolean cascade(ResourceMapping resourceMapping,
101: Object root, CascadeMapping.Cascade cascade)
102: throws CompassException {
103: if (cascadingDisabled())
104: return false;
105: CascadeMapping[] cascadeMappings = resourceMapping
106: .getCascadeMappings();
107: if (cascadeMappings == null) {
108: return false;
109: }
110: boolean retVal = false;
111: for (CascadeMapping cascadeMapping : cascadeMappings) {
112: if (cascadeMapping.shouldCascade(cascade)) {
113: retVal = true;
114: Object value = cascadeMapping.getCascadeValue(root);
115: if (value == null) {
116: continue;
117: }
118: if (value instanceof Object[]) {
119: int length = Array.getLength(value);
120: for (int j = 0; j < length; j++) {
121: cascadeOperation(cascade, Array.get(value, j));
122: }
123: } else if (value instanceof Collection) {
124: for (Object o : ((Collection) value)) {
125: cascadeOperation(cascade, o);
126: }
127: } else {
128: cascadeOperation(cascade, value);
129: }
130:
131: }
132: }
133: return retVal;
134: }
135:
136: private void cascadeOperation(CascadeMapping.Cascade cascade,
137: Object value) {
138: // TODO what happens if there are several aliases for value
139: if (value == null) {
140: return;
141: }
142: if (cascade == CascadeMapping.Cascade.DELETE) {
143: if (cascadeFilter != null
144: && cascadeFilter.shouldFilterDelete(value)) {
145: return;
146: }
147: session.delete(value);
148: } else if (cascade == CascadeMapping.Cascade.CREATE) {
149: if (cascadeFilter != null
150: && cascadeFilter.shouldFilterCreate(value)) {
151: return;
152: }
153: session.create(value);
154: } else if (cascade == CascadeMapping.Cascade.SAVE) {
155: if (cascadeFilter != null
156: && cascadeFilter.shouldFilterSave(value)) {
157: return;
158: }
159: session.save(value);
160: } else {
161: throw new IllegalArgumentException(
162: "Failed to perform cascading unknown type ["
163: + cascade + "]");
164: }
165: }
166:
167: private boolean cascadingDisabled() {
168: return session.getSettings().getSettingAsBoolean(
169: CompassEnvironment.Cascade.DISABLE, false);
170: }
171: }
|