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.modelassistant.metabossmodel.implicitmessages;
016:
017: import java.util.ArrayList;
018: import java.util.Collection;
019: import java.util.Collections;
020: import java.util.Iterator;
021: import java.util.List;
022:
023: import javax.jmi.reflect.RefObject;
024: import javax.naming.Context;
025: import javax.naming.InitialContext;
026: import javax.naming.NamingException;
027:
028: import com.metaboss.sdlctools.models.ModelAssistant;
029: import com.metaboss.sdlctools.models.ModelRepository;
030: import com.metaboss.sdlctools.models.ModelRepositoryException;
031: import com.metaboss.sdlctools.models.ModelRepositoryInternalException;
032: import com.metaboss.sdlctools.models.metabossmodel.MetaBossModelPackage;
033: import com.metaboss.sdlctools.models.metabossmodel.ModelElementClass;
034: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.EnterpriseModelPackage;
035: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.EventSubscriptionOperation;
036: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.EventSubscriptionOperationClass;
037: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Message;
038: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.MessageClass;
039: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.MessageFieldClass;
040: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Operation;
041: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.OperationClass;
042: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.OperationOutputMessageClass;
043: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.ServicemoduleClass;
044: import com.metaboss.sdlctools.models.modelassistant.metabossmodel.SingleModelAssistantImplBase;
045:
046: /** Implementation of the assistant to MetaBoss models. Looks after some implicit operation output messages.
047: * This implementation is always only serving one model. This is guaranteed by special factory implementation */
048: public class ModelAssistantImpl extends SingleModelAssistantImplBase {
049: /** String constant which is used to identify this assistant as an owner of certain model elements */
050: public static final String ASSISTANT_IDENTIFIER = ModelAssistant.OWNER_IDENTIFIER_PRREFIX
051: + "MetaBoss.ImplicitMessages";
052:
053: public interface ModelElementLifecycleListener {
054: // Called when corresponding model element has been created
055: public void onElementJustCreated(
056: RefObject pModelElementJustCreated);
057:
058: // Called when corresponding model element about to be deleted
059: public void onElementBeingDeleted(
060: RefObject pModelElementBeingDeleted);
061: }
062:
063: private class ModelElementLifecycleListenerDescriptor {
064: public Class mModelElementClass;
065: public ModelElementLifecycleListener mListener;
066: }
067:
068: private List mLifecycleListeners = new ArrayList();
069:
070: public void addLifecycleListener(Class pModelElementClass,
071: ModelElementLifecycleListener pListener) {
072: ModelElementLifecycleListenerDescriptor lDescriptor = new ModelElementLifecycleListenerDescriptor();
073: lDescriptor.mModelElementClass = pModelElementClass;
074: lDescriptor.mListener = pListener;
075: mLifecycleListeners.add(lDescriptor);
076: }
077:
078: public interface ModelElementAttributeChangeListener {
079: // Called when corresponding attribute has been updated
080: public void onAttributeBeingUpdated(
081: RefObject pModelElementBeingUpdated,
082: String pAttributeName, Object pOldAttributeValue,
083: Object pNewAttributeValue);
084: }
085:
086: private class ModelElementAttributeChangeListenerDescriptor {
087: public Class mModelElementClass;
088: public String mAttributeName;
089: public ModelElementAttributeChangeListener mListener;
090: }
091:
092: private List mAttributeChangeListeners = new ArrayList();
093:
094: public void addAttributeChangeListener(Class pModelElementClass,
095: String pAttributeName,
096: ModelElementAttributeChangeListener pListener) {
097: ModelElementAttributeChangeListenerDescriptor lDescriptor = new ModelElementAttributeChangeListenerDescriptor();
098: lDescriptor.mModelElementClass = pModelElementClass;
099: lDescriptor.mAttributeName = pAttributeName;
100: lDescriptor.mListener = pListener;
101: mAttributeChangeListeners.add(lDescriptor);
102: }
103:
104: public interface ModelElementReferenceChangeListener {
105: // Called when corresponding reference has been updated
106: public void onReferenceBeingUpdated(
107: RefObject pModelElementBeingUpdated,
108: String pReferenceName,
109: RefObject pReferencedModelElementToRemove,
110: RefObject pReferencedModelElementToAdd);
111: }
112:
113: private class ModelElementReferenceChangeListenerDescriptor {
114: public Class mModelElementClass;
115: public String mReferenceName;
116: public ModelElementReferenceChangeListener mListener;
117: }
118:
119: private List mReferenceChangeListeners = new ArrayList();
120:
121: public void addReferenceChangeListener(Class pModelElementClass,
122: String pReferenceName,
123: ModelElementReferenceChangeListener pListener) {
124: ModelElementReferenceChangeListenerDescriptor lDescriptor = new ModelElementReferenceChangeListenerDescriptor();
125: lDescriptor.mModelElementClass = pModelElementClass;
126: lDescriptor.mReferenceName = pReferenceName;
127: lDescriptor.mListener = pListener;
128: mReferenceChangeListeners.add(lDescriptor);
129: }
130:
131: // Variables below are cached for whole session with the model regardless of the kind of model it is
132: ModelRepository mModelRepository = null;
133: MetaBossModelPackage mRootPackage = null;
134: ModelElementClass mModelElementClass = null;
135: // ModelElementConstraintClass mModelElementConstraintClass = null;
136: EnterpriseModelPackage mEnterpriseModelPackage = null;
137: // DataDictionaryModelPackage mDataDictionaryModelPackage = null;
138: ServicemoduleClass mServicemoduleClass = null;
139: // ServiceClass mServiceClass = null;
140: // StructureClass mStructureClass = null;
141: // StructureFieldClass mStructureFieldClass = null;
142: MessageClass mMessageClass = null;
143: MessageFieldClass mMessageFieldClass = null;
144: OperationClass mOperationClass = null;
145: EventSubscriptionOperationClass mEventSubscriptionOperationClass = null;
146: // OperationInputFieldClass mOperationInputFieldClass = null;
147: OperationOutputMessageClass mOperationOutputMessageClass = null;
148: // Access via the getter. This gives a chance to do find every time
149: private Message mInvalidOperationInputErrorMessage = null;
150:
151: // Target model element helpers
152: TargetInvalidOperationInputErrorOperationOutputMessageHelper mTargetIllegalOperationInputErrorOperationMessageHelper = null;
153:
154: public ModelAssistantImpl() {
155: // Create helpers
156: mTargetIllegalOperationInputErrorOperationMessageHelper = new TargetInvalidOperationInputErrorOperationOutputMessageHelper(
157: this );
158: }
159:
160: // As per interface
161: public void assignToModel(String pModelName)
162: throws ModelRepositoryException {
163: super .assignToModel(pModelName);
164: try {
165: Context lContext = new InitialContext();
166: mModelRepository = (ModelRepository) lContext
167: .lookup(ModelRepository.COMPONENT_URL);
168: mRootPackage = (MetaBossModelPackage) mModelRepository
169: .getModelExtent(pModelName);
170: mModelElementClass = mRootPackage.getModelElement();
171: mEnterpriseModelPackage = mRootPackage.getEnterpriseModel();
172: mServicemoduleClass = mEnterpriseModelPackage
173: .getServicemodule();
174: mMessageClass = mEnterpriseModelPackage.getMessage();
175: mMessageFieldClass = mEnterpriseModelPackage
176: .getMessageField();
177: mOperationClass = mEnterpriseModelPackage.getOperation();
178: mEventSubscriptionOperationClass = mEnterpriseModelPackage
179: .getEventSubscriptionOperation();
180: mOperationOutputMessageClass = mEnterpriseModelPackage
181: .getOperationOutputMessage();
182: mInvalidOperationInputErrorMessage = (Message) mRootPackage
183: .getModelElement()
184: .findByRef(
185: StylesheetImpl
186: .getInvalidOperationInputErrorMessageRef());
187: } catch (NamingException e) {
188: throw new ModelRepositoryInternalException(
189: "Unable to lookup repository", e);
190: }
191: }
192:
193: // As per interface
194: public void dismissFromModel(String pModelName) {
195: mRootPackage = null;
196: mModelElementClass = null;
197: mModelRepository = null;
198: mMessageClass = null;
199: mMessageFieldClass = null;
200: mEnterpriseModelPackage = null;
201: mServicemoduleClass = null;
202: mOperationClass = null;
203: mEventSubscriptionOperationClass = null;
204: mOperationOutputMessageClass = null;
205: mInvalidOperationInputErrorMessage = null;
206: super .dismissFromModel(pModelName);
207: }
208:
209: // As per interface
210: public void onModelElementAttributeBeingUpdated(String pModelName,
211: RefObject pModelElementBeingUpdated, String pAttributeName,
212: Object pOldAttributeValue, Object pNewAttributeValue)
213: throws ModelRepositoryException {
214: // Dispatch to generic listeners
215: Class pModelElementBeingUpdatedClass = pModelElementBeingUpdated
216: .getClass();
217: for (Iterator lAttributeChangeListenerDescriptorsIterator = mAttributeChangeListeners
218: .iterator(); lAttributeChangeListenerDescriptorsIterator
219: .hasNext();) {
220: ModelElementAttributeChangeListenerDescriptor lDescriptor = (ModelElementAttributeChangeListenerDescriptor) lAttributeChangeListenerDescriptorsIterator
221: .next();
222: if (lDescriptor.mModelElementClass
223: .isAssignableFrom(pModelElementBeingUpdatedClass)
224: && lDescriptor.mAttributeName
225: .equals(pAttributeName))
226: lDescriptor.mListener.onAttributeBeingUpdated(
227: pModelElementBeingUpdated, pAttributeName,
228: pOldAttributeValue, pNewAttributeValue);
229: }
230: }
231:
232: // As per interface
233: public void onModelElementReferenceBeingUpdated(String pModelName,
234: RefObject pModelElementBeingUpdated, String pReferenceName,
235: RefObject pReferencedModelElementToRemove,
236: RefObject pReferencedModelElementToAdd)
237: throws ModelRepositoryException {
238: // Dispatch to generic listeners
239: Class pModelElementBeingUpdatedClass = pModelElementBeingUpdated
240: .getClass();
241: for (Iterator lReferenceChangeListenerDescriptorsIterator = mReferenceChangeListeners
242: .iterator(); lReferenceChangeListenerDescriptorsIterator
243: .hasNext();) {
244: ModelElementReferenceChangeListenerDescriptor lDescriptor = (ModelElementReferenceChangeListenerDescriptor) lReferenceChangeListenerDescriptorsIterator
245: .next();
246: if (lDescriptor.mModelElementClass
247: .isAssignableFrom(pModelElementBeingUpdatedClass)
248: && lDescriptor.mReferenceName
249: .equals(pReferenceName))
250: lDescriptor.mListener.onReferenceBeingUpdated(
251: pModelElementBeingUpdated, pReferenceName,
252: pReferencedModelElementToRemove,
253: pReferencedModelElementToAdd);
254: }
255: }
256:
257: // As per interface
258: public void onModelElementBeingDeleted(String pModelName,
259: RefObject pModelElementToBeDeleted)
260: throws ModelRepositoryException {
261: // Dispatch to generic listeners
262: Class lModelElementToBeDeletedClass = pModelElementToBeDeleted
263: .getClass();
264: for (Iterator lLifecycleListenerDescriptorsIterator = mLifecycleListeners
265: .iterator(); lLifecycleListenerDescriptorsIterator
266: .hasNext();) {
267: ModelElementLifecycleListenerDescriptor lDescriptor = (ModelElementLifecycleListenerDescriptor) lLifecycleListenerDescriptorsIterator
268: .next();
269: if (lDescriptor.mModelElementClass
270: .isAssignableFrom(lModelElementToBeDeletedClass))
271: lDescriptor.mListener
272: .onElementBeingDeleted(pModelElementToBeDeleted);
273: }
274: }
275:
276: // As per interface
277: public void onModelElementJustCreated(String pModelName,
278: RefObject pModelElementJustCreated)
279: throws ModelRepositoryException {
280: // Dispatch to generic listeners
281: Class pModelElementJustCreatedClass = pModelElementJustCreated
282: .getClass();
283: for (Iterator lLifecycleListenerDescriptorsIterator = mLifecycleListeners
284: .iterator(); lLifecycleListenerDescriptorsIterator
285: .hasNext();) {
286: ModelElementLifecycleListenerDescriptor lDescriptor = (ModelElementLifecycleListenerDescriptor) lLifecycleListenerDescriptorsIterator
287: .next();
288: if (lDescriptor.mModelElementClass
289: .isAssignableFrom(pModelElementJustCreatedClass))
290: lDescriptor.mListener
291: .onElementJustCreated(pModelElementJustCreated);
292: }
293: }
294:
295: // As per interface
296: public void rectifyModel(String pModelName)
297: throws ModelRepositoryException {
298: // Ensure that all operations which do have inputs have the illegal operation inputs message and all opertions
299: // which do not have inputs do not have this message
300: for (Iterator lOperationsIterator = mOperationClass
301: .refAllOfType().iterator(); lOperationsIterator
302: .hasNext();) {
303: Operation lOperation = (Operation) lOperationsIterator
304: .next();
305: mTargetIllegalOperationInputErrorOperationMessageHelper
306: .rectifyModel(lOperation);
307: }
308:
309: // Ensure that all susbscription operations which do have inputs have the illegal operation inputs message and all operations
310: // which do not have inputs do not have this message
311: for (Iterator lOperationsIterator = mEventSubscriptionOperationClass
312: .refAllOfType().iterator(); lOperationsIterator
313: .hasNext();) {
314: EventSubscriptionOperation lOperation = (EventSubscriptionOperation) lOperationsIterator
315: .next();
316: mTargetIllegalOperationInputErrorOperationMessageHelper
317: .rectifyModel(lOperation);
318: }
319: }
320:
321: // As per interface
322: public Collection verifyConstraints(String pModelName) {
323: List lViolations = new ArrayList();
324: // Validate that all operations which do have inputs have the illegal operation inputs message and all opertions
325: // which do not have inputs do not have this message
326: for (Iterator lOperationsIterator = mOperationClass
327: .refAllOfType().iterator(); lOperationsIterator
328: .hasNext();) {
329: Operation lOperation = (Operation) lOperationsIterator
330: .next();
331: mTargetIllegalOperationInputErrorOperationMessageHelper
332: .verifyConstraints(lViolations, lOperation);
333: }
334: // Validate that all susbscription operations which do have inputs have the illegal operation inputs message and all opertions
335: // which do not have inputs do not have this message
336: for (Iterator lOperationsIterator = mEventSubscriptionOperationClass
337: .refAllOfType().iterator(); lOperationsIterator
338: .hasNext();) {
339: EventSubscriptionOperation lOperation = (EventSubscriptionOperation) lOperationsIterator
340: .next();
341: mTargetIllegalOperationInputErrorOperationMessageHelper
342: .verifyConstraints(lViolations, lOperation);
343: }
344: // Return what we have
345: return Collections.unmodifiableCollection(lViolations);
346: }
347: }
|