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.domainsupport;
016:
017: import java.util.ArrayList;
018: import java.util.Collection;
019: import java.util.Iterator;
020: import java.util.List;
021:
022: import javax.jmi.reflect.ConstraintViolationException;
023: import javax.jmi.reflect.RefObject;
024:
025: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Message;
026: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.MessageField;
027: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.MessageTypeEnum;
028: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Servicemodule;
029: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Domain;
030: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Entity;
031: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.EntityStereotypeEnum;
032:
033: /** This class containse helper methods dealing with the VersionMismatch error message model element */
034: class TargetVersionMismatchMessageHelper {
035: private ModelAssistantImpl mModelAssistantImpl;
036:
037: TargetVersionMismatchMessageHelper(
038: ModelAssistantImpl pModelAssistantImpl) {
039: mModelAssistantImpl = pModelAssistantImpl;
040:
041: // Add entity Name attribute change listener
042: mModelAssistantImpl
043: .addAttributeChangeListener(
044: Entity.class,
045: "Name",
046: new ModelAssistantImpl.ModelElementAttributeChangeListener() {
047: public void onAttributeBeingUpdated(
048: RefObject pModelElementBeingUpdated,
049: String pAttributeName,
050: Object pOldValue, Object pNewValue) {
051: Entity lEntity = (Entity) pModelElementBeingUpdated;
052: Domain lDomain = lEntity.getDomain();
053: if (lDomain == null)
054: return; // Entity is not associated with domain
055: String lDomainName = lDomain.getName();
056: if (lDomainName == null)
057: return; // Domain does not have a name
058: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
059: .getSystem();
060: if (lSystem == null)
061: return; // Domain is not associated with system
062: Servicemodule lServicemodule = lSystem
063: .findServicemodule(StylesheetImpl
064: .getDomainSupportServicemoduleName(lDomainName));
065: if (lServicemodule == null)
066: return; // There is no support servicemodule yet
067: if (pNewValue == null) {
068: // Only old value is known - ensure that the element is deleted
069: ensureAbsent(lServicemodule,
070: (String) pOldValue);
071: } else {
072: // New value is known - analyse the criteria and deal with the element accordingly
073: if (lEntity.isModifiable()) {
074: // The element must be present - rename or create
075: if (pOldValue != null)
076: ensureRenamedPresent(
077: lServicemodule,
078: lEntity,
079: (String) pOldValue,
080: (String) pNewValue);
081: else
082: ensurePresent(
083: lServicemodule,
084: lEntity,
085: (String) pNewValue);
086: } else {
087: // The element must be absent - delete
088: ensureAbsent(lServicemodule,
089: (String) pNewValue);
090: if (pOldValue != null)
091: ensureAbsent(
092: lServicemodule,
093: (String) pOldValue);
094: }
095: }
096: }
097: });
098:
099: // Add entity stereotype attribute change listener
100: mModelAssistantImpl
101: .addAttributeChangeListener(
102: Entity.class,
103: "stereotype",
104: new ModelAssistantImpl.ModelElementAttributeChangeListener() {
105: public void onAttributeBeingUpdated(
106: RefObject pModelElementBeingUpdated,
107: String pAttributeName,
108: Object pOldValue, Object pNewValue) {
109: Entity lEntity = (Entity) pModelElementBeingUpdated;
110: String lEntityName = lEntity.getName();
111: if (lEntityName == null)
112: return; // Entity does not have a name
113: Domain lDomain = lEntity.getDomain();
114: if (lDomain == null)
115: return; // Entity is not associated with domain
116: String lDomainName = lDomain.getName();
117: if (lDomainName == null)
118: return; // Domain does not have a name
119: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
120: .getSystem();
121: if (lSystem == null)
122: return; // Domain is not associated with system
123: Servicemodule lServicemodule = lSystem
124: .findServicemodule(StylesheetImpl
125: .getDomainSupportServicemoduleName(lDomainName));
126: if (lServicemodule == null)
127: return; // There is no support servicemodule yet
128: // Analyse the criteria and deal with the element accordingly
129: if (EntityStereotypeEnum.CARD_FILE
130: .equals(pNewValue))
131: ensurePresent(lServicemodule,
132: lEntity, lEntityName);
133: else
134: ensureAbsent(lServicemodule,
135: lEntityName);
136: }
137: });
138: }
139:
140: // This helper verifies constraints
141: void verifyConstraints(Collection pViolations,
142: Servicemodule pServicemodule, Entity pEntity,
143: Collection pUnclaimedMessages) {
144: // Work on the VersionMismatch message
145: {
146: String lMessageName = StylesheetImpl
147: .getEntityVersionIdMismatchMessageName(pEntity
148: .getName());
149: Message lMessage = pServicemodule.findMessage(lMessageName);
150: if (pEntity.isModifiable()) {
151: if (lMessage == null)
152: pViolations
153: .add(new ConstraintViolationException(
154: pServicemodule,
155: pServicemodule.refMetaObject(),
156: "A Domain Support Servicemodule must have 'Version Mismatch' Message for every editable Entity. The '"
157: + lMessageName
158: + "' Message not found."));
159: else
160: pUnclaimedMessages.remove(lMessage); // Claim the message
161: }
162: }
163: }
164:
165: // This helper is doing everything necessary to rectify errors reported in verifyConstraints()
166: void rectifyModel(Servicemodule pServicemodule, Entity pEntity,
167: Collection pUnclaimedMessages) {
168: // Check if we have a message and than just call ensurePresent
169: String lMessageName = StylesheetImpl
170: .getEntityVersionIdMismatchMessageName(pEntity
171: .getName());
172: Message lMessage = pServicemodule.findMessage(lMessageName);
173: if (lMessage != null)
174: pUnclaimedMessages.remove(lMessage); // Claim the message
175: // Now just call ensurePresent or absent depending on condition
176: if (pEntity.isModifiable())
177: ensurePresent(pServicemodule, pEntity, pEntity.getName());
178: else
179: ensureAbsent(pServicemodule, pEntity.getName());
180: }
181:
182: // This helper renames the message
183: void ensureRenamedPresent(Servicemodule pServicemodule,
184: Entity pEntity, String pOldEntityName, String pNewEntityName) {
185: // Note that this method only deals with renaming and than calls the ensure present method
186:
187: // Work on the VersionMismatch message
188: {
189: String lOldMessageName = StylesheetImpl
190: .getEntityVersionIdMismatchMessageName(pOldEntityName);
191: Message lOldMessage = pServicemodule
192: .findMessage(lOldMessageName);
193: String lNewMessageName = StylesheetImpl
194: .getEntityVersionIdMismatchMessageName(pNewEntityName);
195: Message lNewMessage = pServicemodule
196: .findMessage(lNewMessageName);
197: // Be relaxed here - allow for all sorts of mishaps
198: if (lOldMessage != null) {
199: if (lNewMessage != null) {
200: // New and old mesages are present - just delete the old one
201: lOldMessage.refDelete();
202: } else {
203: // Old message is present - new one is not - rename
204: lOldMessage.setName(lNewMessageName);
205: }
206: }
207: }
208:
209: // Call the ensure present bit
210: ensurePresent(pServicemodule, pEntity, pNewEntityName);
211: }
212:
213: // This helper makes sure that the VersionMismatch message exist and uptodate
214: void ensurePresent(Servicemodule pServicemodule, Entity pEntity,
215: String pEntityName) {
216: // Work on the VersionMismatch message
217: {
218: String lMessageName = StylesheetImpl
219: .getEntityVersionIdMismatchMessageName(pEntityName);
220: String lMessageDescription = suggestVersionMismatchMessageDescription(pEntityName);
221: String lMessageText = suggestVersionMismatchMessageText(pEntityName);
222: Message lMessage = pServicemodule.findMessage(lMessageName);
223: if (lMessage == null) {
224: lMessage = mModelAssistantImpl.mMessageClass
225: .createMessage();
226: lMessage.setName(lMessageName);
227: lMessage.setServicemodule(pServicemodule);
228:
229: }
230: lMessage.setType(MessageTypeEnum.ERROR);
231: lMessage.setDescription(lMessageDescription);
232: lMessage.setDefaultText(lMessageText);
233: // This mesage has two fields - expected version id and actual version id
234: Collection lMessageFields = lMessage.getFields();
235: // Unable to use iterator over the live collection, because as we delete fields - they will
236: // be deleted from the list causing problems with the iterator
237: List lUnprocessedMessageFields = new ArrayList();
238: lUnprocessedMessageFields.addAll(lMessageFields);
239: // Expected version id
240: {
241: String lFieldName = "ExpectedVersionId";
242: MessageField lMessageField = lMessage
243: .findField(lFieldName);
244: if (lMessageField == null) {
245: lMessageField = mModelAssistantImpl.mMessageFieldClass
246: .createMessageField();
247: lMessageField.setName(lFieldName);
248: lMessageFields.add(lMessageField);
249: } else {
250: lUnprocessedMessageFields.remove(lMessageField);
251: }
252: lMessageField.setDescription("The " + pEntityName
253: + " VersionId submitted to the service call.");
254: if (pEntity != null)
255: lMessageField.setDataType(pEntity
256: .getVersionIdDataType());
257: }
258: // Stored version id
259: {
260: String lFieldName = "StoredVersionId";
261: MessageField lMessageField = lMessage
262: .findField(lFieldName);
263: if (lMessageField == null) {
264: lMessageField = mModelAssistantImpl.mMessageFieldClass
265: .createMessageField();
266: lMessageField.setName(lFieldName);
267: lMessageFields.add(lMessageField);
268: } else {
269: lUnprocessedMessageFields.remove(lMessageField);
270: }
271: lMessageField.setDescription("The stored "
272: + pEntityName + " VersionId.");
273: if (pEntity != null)
274: lMessageField.setDataType(pEntity
275: .getVersionIdDataType());
276: }
277: for (Iterator lUnprocessedMessageFieldsIterator = lUnprocessedMessageFields
278: .iterator(); lUnprocessedMessageFieldsIterator
279: .hasNext();) {
280: MessageField lMessageField = (MessageField) lUnprocessedMessageFieldsIterator
281: .next();
282: lMessageField.refDelete();
283: }
284: }
285: }
286:
287: // This helper makes sure that the message is absent
288: void ensureAbsent(Servicemodule pServicemodule, String pEntityName) {
289: // Work on the VersionMismatch message
290: Message lMessage = pServicemodule.findMessage(StylesheetImpl
291: .getEntityVersionIdMismatchMessageName(pEntityName));
292: if (lMessage != null)
293: lMessage.refDelete();
294: }
295:
296: // Helper. Returns the message description
297: private static String suggestVersionMismatchMessageDescription(
298: String pEntityName) {
299: // Use name 'as is' here
300: return "This error indicates that operation has failed because value of submitted "
301: + pEntityName
302: + " VersionId was not the same as the one stored.";
303: }
304:
305: // Helper. Returns the message text
306: private static String suggestVersionMismatchMessageText(
307: String pEntityName) {
308: // Use name 'as is' here
309: return pEntityName
310: + " version id mismatch (possibly someone else have updated the entity). Expected VersionId: \"${Fields.ExpectedVersionId}\" Stored VersionId: \"${Fields.StoredVersionId}\"";
311: }
312: }
|