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.impl;
018:
019: import java.util.HashMap;
020:
021: import org.apache.commons.logging.Log;
022: import org.apache.commons.logging.LogFactory;
023: import org.compass.core.Compass;
024: import org.compass.core.mapping.CascadeMapping;
025: import org.compass.core.mapping.ResourceMapping;
026: import org.compass.core.spi.InternalCompass;
027: import org.compass.core.util.ClassUtils;
028: import org.compass.gps.CompassGpsDevice;
029: import org.compass.gps.CompassGpsException;
030: import org.compass.gps.spi.CompassGpsInterfaceDevice;
031:
032: /**
033: * A simple base class for {@link org.compass.gps.CompassGps}
034: * implementations.
035: *
036: * @author kimchy
037: */
038: public abstract class AbstractCompassGps implements
039: CompassGpsInterfaceDevice {
040:
041: protected Log log = LogFactory.getLog(getClass());
042:
043: protected HashMap<String, CompassGpsDevice> devices = new HashMap<String, CompassGpsDevice>();
044:
045: private boolean started = false;
046:
047: private boolean performingIndexOperation = false;
048:
049: public void addGpsDevice(CompassGpsDevice gpsDevice) {
050: checkDeviceValidity(gpsDevice);
051: gpsDevice.injectGps(this );
052: devices.put(gpsDevice.getName(), gpsDevice);
053: }
054:
055: public void setGpsDevices(CompassGpsDevice[] devices) {
056: this .devices.clear();
057: for (CompassGpsDevice device : devices) {
058: checkDeviceValidity(device);
059: device.injectGps(this );
060: this .devices.put(device.getName(), device);
061: }
062: }
063:
064: protected CompassGpsDevice getGpsDevice(String name) {
065: return devices.get(name);
066: }
067:
068: private void checkDeviceValidity(CompassGpsDevice device) {
069: if (device.getName() == null) {
070: throw new IllegalArgumentException(
071: "Must specify a name for a gps device");
072: }
073: if (devices.get(device.getName()) != null) {
074: throw new IllegalArgumentException(
075: "A gps device with the name [" + device.getName()
076: + "] is defined twice. It is not allowed.");
077: }
078: }
079:
080: protected boolean hasRootMappingForEntity(Class clazz,
081: Compass checkedCompass) {
082: return getRootMappingForEntity(clazz, checkedCompass) != null;
083: }
084:
085: protected boolean hasMappingForEntity(Class clazz,
086: Compass checkedCompass, CascadeMapping.Cascade cascade) {
087: ResourceMapping resourceMapping = ((InternalCompass) checkedCompass)
088: .getMapping().getRootMappingByClass(clazz);
089: if (resourceMapping != null) {
090: return true;
091: }
092: resourceMapping = ((InternalCompass) checkedCompass)
093: .getMapping().getNonRootMappingByClass(clazz);
094: return resourceMapping != null
095: && resourceMapping.operationAllowed(cascade);
096: }
097:
098: protected boolean hasMappingForEntity(String name,
099: Compass checkedCompass, CascadeMapping.Cascade cascade) {
100: ResourceMapping resourceMapping = ((InternalCompass) checkedCompass)
101: .getMapping().getRootMappingByAlias(name);
102: if (resourceMapping != null) {
103: return true;
104: }
105: resourceMapping = ((InternalCompass) checkedCompass)
106: .getMapping().getNonRootMappingByAlias(name);
107: return resourceMapping != null
108: && resourceMapping.operationAllowed(cascade);
109: }
110:
111: protected ResourceMapping getRootMappingForEntity(Class clazz,
112: Compass checkedCompass) {
113: return ((InternalCompass) checkedCompass).getMapping()
114: .getRootMappingByClass(clazz);
115: }
116:
117: protected boolean hasRootMappingForEntity(String name,
118: Compass checkedCompass) {
119: return getRootMappingForEntity(name, checkedCompass) != null;
120: }
121:
122: protected ResourceMapping getMappingForEntity(String name,
123: Compass checkedCompass) {
124: ResourceMapping resourceMapping = ((InternalCompass) checkedCompass)
125: .getMapping().getMappingByAlias(name);
126: if (resourceMapping != null) {
127: return resourceMapping;
128: }
129: try {
130: Class clazz = ClassUtils.forName(name, checkedCompass
131: .getSettings().getClassLoader());
132: return ((InternalCompass) checkedCompass).getMapping()
133: .getMappingByClass(clazz);
134: } catch (Exception e) {
135: // do nothing
136: }
137: return null;
138: }
139:
140: protected ResourceMapping getRootMappingForEntity(String name,
141: Compass checkedCompass) {
142: ResourceMapping resourceMapping = ((InternalCompass) checkedCompass)
143: .getMapping().getRootMappingByAlias(name);
144: if (resourceMapping != null) {
145: return resourceMapping;
146: }
147: try {
148: Class clazz = ClassUtils.forName(name, checkedCompass
149: .getSettings().getClassLoader());
150: return ((InternalCompass) checkedCompass).getMapping()
151: .getRootMappingByClass(clazz);
152: } catch (Exception e) {
153: // do nothing
154: }
155: return null;
156: }
157:
158: public synchronized void index() throws CompassGpsException,
159: IllegalStateException {
160: if (!isRunning()) {
161: throw new IllegalStateException(
162: "CompassGps must be running in order to perform the index operation");
163: }
164: if (((InternalCompass) getMirrorCompass())
165: .getTransactionFactory().getTransactionBoundSession() != null) {
166: throw new CompassGpsException(
167: "index() operation is not allowed to be called within a transaction (mirror)");
168: }
169: if (((InternalCompass) getIndexCompass())
170: .getTransactionFactory().getTransactionBoundSession() != null) {
171: throw new CompassGpsException(
172: "index() operation is not allowed to be called within a transaction (index)");
173: }
174: if (isPerformingIndexOperation()) {
175: throw new IllegalArgumentException(
176: "Indexing alredy in process, not allowed to call index()");
177: }
178: try {
179: performingIndexOperation = true;
180: doIndex();
181: } finally {
182: performingIndexOperation = false;
183: }
184: }
185:
186: protected abstract void doIndex() throws CompassGpsException;
187:
188: public synchronized void start() throws CompassGpsException {
189: doStart();
190: if (!started) {
191: for (CompassGpsDevice device : devices.values()) {
192: device.start();
193: }
194: started = true;
195: }
196: }
197:
198: protected abstract void doStart() throws CompassGpsException;
199:
200: protected abstract void doStop() throws CompassGpsException;
201:
202: public synchronized void stop() throws CompassGpsException {
203: if (started) {
204: for (CompassGpsDevice device : devices.values()) {
205: device.stop();
206: }
207: started = false;
208: }
209: doStop();
210: }
211:
212: public boolean isRunning() {
213: return started;
214: }
215:
216: public boolean isPerformingIndexOperation() {
217: return performingIndexOperation;
218: }
219: }
|