001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
012: // POSSIBILITY OF SUCH DAMAGE.
013: //
014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
015: package com.metaboss.sdlctools.models.impl;
016:
017: import java.util.HashMap;
018: import java.util.Map;
019:
020: import org.apache.commons.logging.Log;
021: import org.apache.commons.logging.LogFactory;
022: import org.netbeans.api.mdr.events.AssociationEvent;
023: import org.netbeans.api.mdr.events.AttributeEvent;
024: import org.netbeans.api.mdr.events.InstanceEvent;
025: import org.netbeans.api.mdr.events.MDRChangeEvent;
026: import org.netbeans.api.mdr.events.MDRPreChangeListener;
027: import org.netbeans.api.mdr.events.TransactionEvent;
028:
029: /** Base implementation of all MDRPreChangeListeners in this implementation.
030: * Contains some common utility methods. */
031: public abstract class MDRPreChangeListenerImplBase implements
032: MDRPreChangeListener {
033: // Commons Logging instance.
034: private static final Log sLogger = LogFactory
035: .getLog(ModelChangesListenerImpl.class);
036: // The registration id of the next event
037: private long mNextEventRegistrationId = 0;
038: // Flag, which governs if this listener is listening for changes or not
039: private boolean mListeningForChanges = false;
040: // Map of Event Ids by event objects. Event id is generated when
041: // event arrives to the proposedChange() and gets removed only when
042: // it is cancelled or change is fully registered
043: private Map mEventIdsMap = new HashMap(); // Map of Event Ids by event objects
044: // The repository reference
045: protected ModelRepositoryImpl mParentRepository;
046:
047: // The only constructor
048: public MDRPreChangeListenerImplBase(
049: ModelRepositoryImpl pParentRepository) {
050: mParentRepository = pParentRepository;
051: }
052:
053: // This method waits for all events to be consumed
054: public void waitTillAllEventsAreConsumed() {
055: // Synchronise on repository to keep out of trouble
056: // Main issue is changes occurring while saving is in progress
057: synchronized (mEventIdsMap) {
058: int lUnresolvedEventsCount;
059: while ((lUnresolvedEventsCount = mEventIdsMap.size()) > 0) {
060: sLogger
061: .debug("Will wait for all change events to get resolved. Unresolved events count: "
062: + lUnresolvedEventsCount);
063: try {
064: mEventIdsMap.wait();
065: } catch (InterruptedException e) {
066: sLogger
067: .error(
068: "Caught exception while waiting for all changes to get resolved.",
069: e);
070: }
071: }
072: }
073: }
074:
075: // Will ensure that all outstanding events are consumed and than will stop listening
076: public void stopListening() {
077: if (mListeningForChanges) {
078: waitTillAllEventsAreConsumed();
079: mListeningForChanges = false;
080: }
081: }
082:
083: // Will ensure that all outstanding events are consumed and than will start listening
084: public void startListening() {
085: if (!mListeningForChanges) {
086: waitTillAllEventsAreConsumed();
087: mListeningForChanges = true;
088: }
089: }
090:
091: // Returns true if this listener is currently listening for events
092: public boolean isListening() {
093: return mListeningForChanges;
094: }
095:
096: // Logs processing of the event by any of the methods
097: protected void logEvent(String pMethodName, MDRChangeEvent pEvent,
098: Comparable pEventRegistrationId) {
099: if (!sLogger.isDebugEnabled())
100: return; // This should speed things up
101: // Try to come up with meaning for some events
102: String lEventType = null;
103: switch (pEvent.getType()) {
104: case TransactionEvent.EVENT_TRANSACTION_END:
105: lEventType = "TransactionEvent.EVENT_TRANSACTION_END";
106: break;
107: case TransactionEvent.EVENT_TRANSACTION_START:
108: lEventType = "TransactionEvent.EVENT_TRANSACTION_START";
109: break;
110: case InstanceEvent.EVENT_INSTANCE_CREATE:
111: lEventType = "InstanceEvent.EVENT_INSTANCE_CREATE";
112: break;
113: case InstanceEvent.EVENT_INSTANCE_DELETE:
114: lEventType = "InstanceEvent.EVENT_INSTANCE_DELETE";
115: break;
116: case AssociationEvent.EVENT_ASSOCIATION_ADD:
117: lEventType = "AssociationEvent.EVENT_ASSOCIATION_ADD";
118: break;
119: case AssociationEvent.EVENT_ASSOCIATION_REMOVE:
120: lEventType = "AssociationEvent.EVENT_ASSOCIATION_REMOVE";
121: break;
122: case AssociationEvent.EVENT_ASSOCIATION_SET:
123: lEventType = "AssociationEvent.EVENT_ASSOCIATION_SET";
124: break;
125: case AttributeEvent.EVENT_ATTRIBUTE_ADD:
126: lEventType = "AttributeEvent.EVENT_ATTRIBUTE_ADD";
127: break;
128: case AttributeEvent.EVENT_ATTRIBUTE_REMOVE:
129: lEventType = "AttributeEvent.EVENT_ATTRIBUTE_REMOVE";
130: break;
131: case AttributeEvent.EVENT_ATTRIBUTE_SET:
132: lEventType = "AttributeEvent.EVENT_ATTRIBUTE_SET";
133: break;
134: default:
135: lEventType = "Unrecognised";
136: break;
137: }
138: sLogger
139: .debug(pMethodName
140: + " is about to process received event. EventRegistrationId: "
141: + pEventRegistrationId + " Event type: "
142: + lEventType + " Event details: "
143: + pEvent.toString());
144: }
145:
146: // Generates unique Id, with next one is always higher than all the ones generated before that
147: protected Comparable registerEvent(MDRChangeEvent pEvent) {
148: synchronized (mEventIdsMap) {
149: Comparable lEventRegistrationId = new Long(
150: mNextEventRegistrationId++);
151: if (mEventIdsMap.put(pEvent, lEventRegistrationId) != null)
152: throw new IllegalArgumentException(
153: "Event has already been registered. Event: "
154: + pEvent);
155: return lEventRegistrationId;
156: }
157: }
158:
159: // Removes even from the list of registered events
160: protected Comparable unregisterEvent(MDRChangeEvent pEvent) {
161: synchronized (mEventIdsMap) {
162: Comparable lEventRegistrationId = (Comparable) mEventIdsMap
163: .remove(pEvent);
164: // Notify potential waiting saving thread
165: if (mEventIdsMap.size() == 0)
166: mEventIdsMap.notify();
167: return lEventRegistrationId;
168: }
169: }
170:
171: // Retrieves previously generated event id for the event
172: protected Comparable getEventRegistrationId(MDRChangeEvent pEvent) {
173: synchronized (mEventIdsMap) {
174: return (Comparable) mEventIdsMap.get(pEvent);
175: }
176: }
177:
178: }
|