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.gps.device.jpa;
018:
019: import javax.persistence.PostPersist;
020: import javax.persistence.PostRemove;
021: import javax.persistence.PostUpdate;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.compass.core.Compass;
026: import org.compass.core.CompassCallbackWithoutResult;
027: import org.compass.core.CompassException;
028: import org.compass.core.CompassSession;
029: import org.compass.core.CompassTemplate;
030: import org.compass.core.mapping.CascadeMapping;
031: import org.compass.core.mapping.ResourceMapping;
032: import org.compass.core.spi.InternalCompass;
033: import org.compass.core.util.ClassUtils;
034:
035: /**
036: * An abstract support class for event lifecycle JPA spec support. Requires the <code>Compass<code>
037: * instance to be provided (usual sub classes will simple fetch it from the Jndi location). This
038: * is the least prefereable way to use lifecycle event listerens, please see
039: * {@link JpaGpsDevice} and {@link org.compass.gps.device.jpa.lifecycle.JpaEntityLifecycleInjector}.
040: *
041: * @author kimchy
042: */
043: public abstract class AbstractCompassJpaEntityListener {
044:
045: protected Log log = LogFactory.getLog(getClass());
046:
047: protected abstract Compass getCompass();
048:
049: private CompassTemplate compassTemplate;
050:
051: /**
052: * Should exception be thrown during the mirroring operation, or just logged.
053: * Defaults to <code>true</code>.
054: */
055: protected boolean throwExceptionOnError() {
056: return true;
057: }
058:
059: protected boolean disable() {
060: return false;
061: }
062:
063: protected boolean hasMappingForEntity(Class clazz,
064: CascadeMapping.Cascade cascade) {
065: ResourceMapping resourceMapping = ((InternalCompass) getCompass())
066: .getMapping().getMappingByClass(clazz);
067: if (resourceMapping == null) {
068: return false;
069: }
070: if (resourceMapping.isRoot()) {
071: return true;
072: }
073: return resourceMapping.operationAllowed(cascade);
074: }
075:
076: protected boolean hasMappingForEntity(String name,
077: CascadeMapping.Cascade cascade) {
078: ResourceMapping resourceMapping = ((InternalCompass) getCompass())
079: .getMapping().getMappingByAlias(name);
080: if (resourceMapping != null) {
081: if (resourceMapping.isRoot()) {
082: return true;
083: }
084: return resourceMapping.operationAllowed(cascade);
085: }
086: try {
087: Class clazz = ClassUtils.forName(name, getCompass()
088: .getSettings().getClassLoader());
089: resourceMapping = ((InternalCompass) getCompass())
090: .getMapping().getMappingByClass(clazz);
091: if (resourceMapping.isRoot()) {
092: return true;
093: }
094: return resourceMapping.operationAllowed(cascade);
095: } catch (Exception e) {
096: // do nothing
097: }
098: return false;
099: }
100:
101: @PostPersist
102: public void postPersist(final Object entity)
103: throws CompassException {
104: if (disable()) {
105: return;
106: }
107: if (!hasMappingForEntity(entity.getClass(),
108: CascadeMapping.Cascade.CREATE)) {
109: return;
110: }
111:
112: try {
113: if (log.isDebugEnabled()) {
114: log.debug("Creating [" + entity + "]");
115: }
116: getCompassTemplate().execute(
117: new CompassCallbackWithoutResult() {
118: protected void doInCompassWithoutResult(
119: CompassSession session)
120: throws CompassException {
121: session.create(entity);
122: }
123: });
124: } catch (Exception e) {
125: log.error("Failed while creating [" + entity + "]", e);
126: if (throwExceptionOnError()) {
127: throw new JpaGpsDeviceException(
128: "Failed while creating [" + entity + "]", e);
129: }
130: }
131: }
132:
133: @PostUpdate
134: public void postUpdate(final Object entity) throws CompassException {
135: if (disable()) {
136: return;
137: }
138: if (!hasMappingForEntity(entity.getClass(),
139: CascadeMapping.Cascade.SAVE)) {
140: return;
141: }
142:
143: try {
144: if (log.isDebugEnabled()) {
145: log.debug("Updating [" + entity + "]");
146: }
147: getCompassTemplate().execute(
148: new CompassCallbackWithoutResult() {
149: protected void doInCompassWithoutResult(
150: CompassSession session)
151: throws CompassException {
152: session.save(entity);
153: }
154: });
155: } catch (Exception e) {
156: log.error("Failed while updating [" + entity + "]", e);
157: if (throwExceptionOnError()) {
158: throw new JpaGpsDeviceException(
159: "Failed while unpdating [" + entity + "]", e);
160: }
161: }
162: }
163:
164: @PostRemove
165: public void postRemove(final Object entity) throws CompassException {
166: if (disable()) {
167: return;
168: }
169: if (!hasMappingForEntity(entity.getClass(),
170: CascadeMapping.Cascade.DELETE)) {
171: return;
172: }
173:
174: try {
175: if (log.isDebugEnabled()) {
176: log.debug("Removing [" + entity + "]");
177: }
178: getCompassTemplate().execute(
179: new CompassCallbackWithoutResult() {
180: protected void doInCompassWithoutResult(
181: CompassSession session)
182: throws CompassException {
183: session.delete(entity);
184: }
185: });
186: } catch (Exception e) {
187: log.error("Failed while removing [" + entity + "]", e);
188: if (throwExceptionOnError()) {
189: throw new JpaGpsDeviceException(
190: "Failed while removing [" + entity + "]", e);
191: }
192: }
193: }
194:
195: private CompassTemplate getCompassTemplate() {
196: if (compassTemplate == null) {
197: compassTemplate = new CompassTemplate(getCompass());
198: }
199: return compassTemplate;
200: }
201:
202: }
|