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.Collection;
018: import java.util.Iterator;
019:
020: import org.apache.commons.logging.Log;
021: import org.apache.commons.logging.LogFactory;
022: import org.netbeans.api.mdr.events.MDRChangeEvent;
023: import org.netbeans.api.mdr.events.MDRPreChangeListener;
024: import org.netbeans.api.mdr.events.TransactionEvent;
025:
026: /** Implementation of the MDRPreChangeListener supporting MetaBoss's Model repository.
027: * This helper class implements MDRPreChangeListener, which keeps track of
028: * transactions executed on the repository. It helps to manupulate attachments and
029: * to close transactions properly */
030: public class RepositoryTransactionListenerImpl extends
031: MDRPreChangeListenerImplBase {
032: // Commons Logging instance.
033: private static final Log sLogger = LogFactory
034: .getLog(ModelChangesListenerImpl.class);
035:
036: // The only constructor
037: public RepositoryTransactionListenerImpl(
038: ModelRepositoryImpl pParentRepository) {
039: super (pParentRepository);
040: }
041:
042: /** This method gets called when a repository change is planned to occur.
043: * Any operation that performs a change in MDR has to fire this notification
044: * synchronously on each registered pre-change listener before the change is performed.<p>
045: * Any run-time exception thrown by the implementation of this method should
046: * not affect the events dispatching (i.e. it should be ignored by the event source).
047: * @param pEvent Object describing the planned change.
048: */
049: public void plannedChange(MDRChangeEvent pEvent) {
050: if (!isListening())
051: return;
052: // Synchronise on repository to keep out of trouble
053: // Main issue is changes occurring while saving is in progress
054: try {
055: // Generate event id and register the changes
056: Comparable lEventRegistrationId = registerEvent(pEvent);
057: logEvent("plannedChange()", pEvent, lEventRegistrationId);
058:
059: if (pEvent.isOfType(TransactionEvent.EVENTMASK_TRANSACTION)) {
060: Collection lModelDescriptors = mParentRepository
061: .getModelDescriptors();
062: for (Iterator lModelDescriptorsIterator = lModelDescriptors
063: .iterator(); lModelDescriptorsIterator
064: .hasNext();) {
065: ModelRepositoryImpl.ModelDescriptor lModelDescriptor = (ModelRepositoryImpl.ModelDescriptor) lModelDescriptorsIterator
066: .next();
067: if (lModelDescriptor.mInternalChangeListener != null)
068: lModelDescriptor.mInternalChangeListener
069: .plannedChange(pEvent);
070: else
071: sLogger
072: .warn("Unexpected program condition. ModelDescriptor does not have InternalChangeListener setup. Model '"
073: + lModelDescriptor.ModelName
074: + "'");
075: }
076: }
077: } catch (Throwable t) {
078: // Log throwable as it has no effect in MDR
079: sLogger
080: .error(
081: "Error while processing proposed change to the repository.",
082: t);
083: }
084: }
085:
086: /** This method gets called if a planned change (which was already announced
087: * by calling {@link #plannedChange} was cancelled (e.g. the operation that was
088: * going to perform the change failed). This method is called synchronously by
089: * the operation that tried to perform the change.<p>
090: * Any run-time exception thrown by the implementation of this method should
091: * not affect the events dispatching (i.e. it should be ignored by the event source).
092: * @param pEvent Object describing the cancelled change (has to be the same instance
093: * as passed to the {@link #plannedChange} method).
094: */
095: public void changeCancelled(MDRChangeEvent pEvent) {
096: if (!isListening())
097: return;
098: try {
099: try {
100: // Unregister event id and remove the proposed changes
101: Comparable lEventRegistrationId = getEventRegistrationId(pEvent);
102: if (lEventRegistrationId == null)
103: return; // Unregistered even - must be a left over
104: logEvent("changeCancelled()", pEvent,
105: lEventRegistrationId);
106:
107: if (pEvent
108: .isOfType(TransactionEvent.EVENTMASK_TRANSACTION)) {
109: Collection lModelDescriptors = mParentRepository
110: .getModelDescriptors();
111: for (Iterator lModelDescriptorsIterator = lModelDescriptors
112: .iterator(); lModelDescriptorsIterator
113: .hasNext();) {
114: ModelRepositoryImpl.ModelDescriptor lModelDescriptor = (ModelRepositoryImpl.ModelDescriptor) lModelDescriptorsIterator
115: .next();
116: if (lModelDescriptor.mInternalChangeListener != null)
117: lModelDescriptor.mInternalChangeListener
118: .changeCancelled(pEvent);
119: else
120: sLogger
121: .warn("Unexpected program condition. ModelDescriptor does not have InternalChangeListener setup. Model '"
122: + lModelDescriptor.ModelName
123: + "'");
124: }
125: }
126: } finally {
127: // Only unregfister event here, so all derived operations will have a chance to run to the end too
128: unregisterEvent(pEvent);
129: }
130: } catch (Throwable t) {
131: // Log throwable as it has no effect in MDR
132: sLogger
133: .error(
134: "Error while processing cancellation of change to the repository.",
135: t);
136: }
137: }
138:
139: /** This method gets called after a repository change is performed. This method
140: * is called asynchronously.
141: * If a listener implements {@link MDRPreChangeListener} which is a descedant
142: * of this interface, the event object passed to this method must be the same
143: * instance as the event object previously passed to the corresponding
144: * {@link MDRPreChangeListener#plannedChange} method call of the listener.<p>
145: * Any run-time exception thrown by the implementation of this method should
146: * not affect the events dispatching (i.e. it should be ignored by the event source).
147: *
148: * @param pEvent Object describing the performed change.
149: */
150: public void change(MDRChangeEvent pEvent) {
151: if (!isListening())
152: return;
153: try {
154: try {
155: // Get event id and do some more work on changes
156: Comparable lEventRegistrationId = getEventRegistrationId(pEvent);
157: if (lEventRegistrationId == null)
158: return; // Unregistered even - must be a left over
159: logEvent("change()", pEvent, lEventRegistrationId);
160:
161: if (pEvent
162: .isOfType(TransactionEvent.EVENTMASK_TRANSACTION)) {
163: Collection lModelDescriptors = mParentRepository
164: .getModelDescriptors();
165: for (Iterator lModelDescriptorsIterator = lModelDescriptors
166: .iterator(); lModelDescriptorsIterator
167: .hasNext();) {
168: ModelRepositoryImpl.ModelDescriptor lModelDescriptor = (ModelRepositoryImpl.ModelDescriptor) lModelDescriptorsIterator
169: .next();
170: if (lModelDescriptor.mInternalChangeListener != null)
171: lModelDescriptor.mInternalChangeListener
172: .change(pEvent);
173: else
174: sLogger
175: .warn("Unexpected program condition. ModelDescriptor does not have InternalChangeListener setup. Model '"
176: + lModelDescriptor.ModelName
177: + "'");
178: }
179: }
180: } finally {
181: // Only unregfister event here, so all derived operations will have a chance to run to the end too
182: unregisterEvent(pEvent);
183: }
184: } catch (Throwable t) {
185: // Log throwable as it has no effect in MDR
186: sLogger.error(
187: "Error while processing proposed change to model.",
188: t);
189: }
190: }
191: }
|