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.HashSet;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Set;
023:
024: import javax.jmi.reflect.ConstraintViolationException;
025: import javax.jmi.reflect.RefObject;
026:
027: import com.metaboss.sdlctools.models.metabossmodel.ModelElementConstraint;
028: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.Structure;
029: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Message;
030: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Operation;
031: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.OperationInputField;
032: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.OperationOutputField;
033: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.OperationOutputMessage;
034: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Service;
035: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Servicemodule;
036: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.TransactionPolicyEnum;
037: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Domain;
038: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Entity;
039: import com.metaboss.util.StringUtils;
040:
041: /** This class containse helper methods dealing with the Domain Support Servicemodule model element */
042: class TargetGetEntityOperationHelper {
043: private ModelAssistantImpl mModelAssistantImpl;
044:
045: TargetGetEntityOperationHelper(
046: ModelAssistantImpl pModelAssistantImpl) {
047: mModelAssistantImpl = pModelAssistantImpl;
048: // Add entity lifecycle listener
049: mModelAssistantImpl.addLifecycleListener(Entity.class,
050: new ModelAssistantImpl.ModelElementLifecycleListener() {
051: public void onElementJustCreated(
052: RefObject pModelElementJustCreated) {
053: Entity lEntity = (Entity) pModelElementJustCreated;
054: String lEntityName = lEntity.getName();
055: if (lEntityName == null)
056: return; // Domain does not have a name
057: Domain lDomain = lEntity.getDomain();
058: if (lDomain == null)
059: return; // Entity is not associated with domain
060: String lDomainName = lDomain.getName();
061: if (lDomainName == null)
062: return; // Domain does not have a name
063: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
064: .getSystem();
065: if (lSystem == null)
066: return; // Domain is not associated with system
067: Servicemodule lServicemodule = lSystem
068: .findServicemodule(StylesheetImpl
069: .getDomainSupportServicemoduleName(lDomainName));
070: if (lServicemodule == null)
071: return; // There is no support servicemodule yet
072: Service lDomainSupportService = lServicemodule
073: .findService(StylesheetImpl
074: .getDataManagementServiceName(lDomainName));
075: if (lDomainSupportService == null)
076: return; // There is no domain support service yet
077: // Create associated element
078: ensurePresent(lDomainSupportService, lEntity,
079: lEntityName);
080: }
081:
082: public void onElementBeingDeleted(
083: RefObject pModelElementBeingDeleted) {
084: Entity lEntity = (Entity) pModelElementBeingDeleted;
085: String lEntityName = lEntity.getName();
086: if (lEntityName == null)
087: return; // Domain does not have a name
088: Domain lDomain = lEntity.getDomain();
089: if (lDomain == null)
090: return; // Entity is not associated with domain
091: String lDomainName = lDomain.getName();
092: if (lDomainName == null)
093: return; // Domain does not have a name
094: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
095: .getSystem();
096: if (lSystem == null)
097: return; // Domain is not associated with system
098: Servicemodule lServicemodule = lSystem
099: .findServicemodule(StylesheetImpl
100: .getDomainSupportServicemoduleName(lDomainName));
101: if (lServicemodule == null)
102: return; // There is no support servicemodule yet
103: Service lDomainSupportService = lServicemodule
104: .findService(StylesheetImpl
105: .getDataManagementServiceName(lDomainName));
106: if (lDomainSupportService == null)
107: return; // There is no domain support service yet
108: // Remove associated element
109: ensureAbsent(lDomainSupportService, lEntityName);
110: }
111: });
112: // Add entity Name attribute change listener
113: mModelAssistantImpl
114: .addAttributeChangeListener(
115: Entity.class,
116: "Name",
117: new ModelAssistantImpl.ModelElementAttributeChangeListener() {
118: public void onAttributeBeingUpdated(
119: RefObject pModelElementBeingUpdated,
120: String pAttributeName,
121: Object pOldValue, Object pNewValue) {
122: Entity lEntity = (Entity) pModelElementBeingUpdated;
123: Domain lDomain = lEntity.getDomain();
124: if (lDomain == null)
125: return; // Entity is not associated with domain
126: String lDomainName = lDomain.getName();
127: if (lDomainName == null)
128: return; // Domain does not have a name
129: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
130: .getSystem();
131: if (lSystem == null)
132: return; // Domain is not associated with system
133: Servicemodule lServicemodule = lSystem
134: .findServicemodule(StylesheetImpl
135: .getDomainSupportServicemoduleName(lDomainName));
136: if (lServicemodule == null)
137: return; // There is no support servicemodule yet
138: Service lDomainSupportService = lServicemodule
139: .findService(StylesheetImpl
140: .getDataManagementServiceName(lDomainName));
141: if (lDomainSupportService == null)
142: return; // There is no domain support service yet
143: // Work on domain support operation associated with this entity
144: if (pNewValue == null) {
145: // Only old value is known - ensure that the element is deleted
146: ensureAbsent(lDomainSupportService,
147: (String) pOldValue);
148: } else {
149: // The element must be present - rename or create
150: if (pOldValue != null)
151: ensureRenamedPresent(
152: lDomainSupportService,
153: lEntity,
154: (String) pOldValue,
155: (String) pNewValue);
156: else
157: ensurePresent(
158: lDomainSupportService,
159: lEntity,
160: (String) pNewValue);
161: }
162: // Work on output messages in other operations which are associated with this entity
163: Set lInstancesWhichMayNeedToFindEntityWhenLoading = new HashSet();
164: Util
165: .collectInstancesWhichMayNeedToFindEntityWhenLoading(
166: lEntity,
167: lInstancesWhichMayNeedToFindEntityWhenLoading);
168: for (Iterator lInstancesWhichMayNeedToFindEntityWhenLoadingIterator = lInstancesWhichMayNeedToFindEntityWhenLoading
169: .iterator(); lInstancesWhichMayNeedToFindEntityWhenLoadingIterator
170: .hasNext();) {
171: Entity lEntityElement = (Entity) lInstancesWhichMayNeedToFindEntityWhenLoadingIterator
172: .next();
173: String lEntityElementName = lEntityElement
174: .getName();
175: if (lEntityElementName != null)
176: continue;
177: if (pNewValue == null) {
178: // Only old value is known - ensure that the element is deleted
179: entityNotFoundMessage_EnsureAbsent(
180: lDomainSupportService,
181: lEntityElementName,
182: (String) pOldValue);
183: } else {
184: // The element must be present - rename or create
185: if (pOldValue != null)
186: entityNotFoundMessage_EnsureRenamedPresent(
187: lDomainSupportService,
188: lEntityElementName,
189: (String) pOldValue,
190: (String) pNewValue);
191: else
192: entityNotFoundMessage_EnsureAbsent(
193: lDomainSupportService,
194: lEntityElementName,
195: (String) pNewValue);
196: }
197: }
198: }
199: });
200: }
201:
202: private static final String sOperationConstraintTextBase = "A Data Management Service must have Get Entity operation for every Entity in the corresponding Domain.";
203: private static final String sRequiredInstanceKeyInputFieldConstraintTextBase = "A Get Entity Data Management Operation must have well formed Required Instance Key input parameter carrying Entity identification information.";
204: private static final String sRetrievedEntityDetailsOutputFieldConstraintTextBase = "A Get Entity Data Management Operation must have well formed Retrieved Entity Details output parameter carrying the details of all retrieved Entities.";
205: private static final String sEntityNotFoundErrorOutputMessageConstraintTextBase = "A Get Entity Data Management Operation must have well formed Entity Not Found output message, one for each reference, which is a part of the primary key.";
206: private static final String sOperationInputConstraintTextBase = "A Get Entity Data Management Operation must have well formed Input Constraints performing sanity check on the input data.";
207:
208: // This helper verifies constraints which are dealing with entity structures
209: void verifyConstraints(Collection pViolations,
210: Service pDataManagementService, Entity pEntity,
211: Collection pUnclaimedOperations) {
212: String lEntityName = pEntity.getName();
213: if (lEntityName == null)
214: return;
215: String lOperationName = suggestOperationName(lEntityName);
216: Operation lOperation = pDataManagementService
217: .findOperation(lOperationName);
218: if (lOperation == null) {
219: pViolations
220: .add(new ConstraintViolationException(
221: pDataManagementService,
222: pDataManagementService.refMetaObject(),
223: sOperationConstraintTextBase + " The '"
224: + lOperationName
225: + "' Operation not found."));
226: return;
227: }
228: pUnclaimedOperations.remove(lOperation); // Claim the operation
229: // Validate operation details
230: if (!TransactionPolicyEnum.SUPPORTED.equals(lOperation
231: .getTransactionPolicy()))
232: pViolations.add(new ConstraintViolationException(
233: lOperation, lOperation.refMetaObject(),
234: "A Query Data Management Operation must have transaction policy '"
235: + TransactionPolicyEnum.SUPPORTED
236: .toString() + "'. The '"
237: + lOperation.getTransactionPolicy()
238: + "' Transaction policy is unexpected."));
239: if (!lOperation.isQuery())
240: pViolations
241: .add(new ConstraintViolationException(
242: lOperation,
243: lOperation.refMetaObject(),
244: "A Query Data Management Operation must have the isQuery attribute set to true."));
245:
246: // Input Fields - only verify that the ones we need exist. The extra ones are allowed
247: {
248: String lOperationInputFieldName = StylesheetImpl
249: .getEntityKeyOperationInputParameterName(lEntityName);
250: OperationInputField lInputField = lOperation
251: .findInputField(lOperationInputFieldName);
252: if (lInputField != null) {
253: Structure lEntityKeyStructure = pDataManagementService
254: .getServicemodule() != null ? pDataManagementService
255: .getServicemodule()
256: .findStructure(
257: StylesheetImpl
258: .getEntityKeyStructureName(lEntityName))
259: : null;
260: if (lEntityKeyStructure != null
261: && lEntityKeyStructure.equals(lInputField
262: .getStructureType()) == false)
263: pViolations.add(new ConstraintViolationException(
264: lInputField, lInputField.refMetaObject(),
265: sRequiredInstanceKeyInputFieldConstraintTextBase
266: + " The '"
267: + lOperationInputFieldName
268: + "' input field has wrong type."));
269: if (lInputField.isArray())
270: pViolations
271: .add(new ConstraintViolationException(
272: lInputField,
273: lInputField.refMetaObject(),
274: sRequiredInstanceKeyInputFieldConstraintTextBase
275: + " The '"
276: + lOperationInputFieldName
277: + "' input fieldis an array, which is wrong."));
278: } else
279: pViolations.add(new ConstraintViolationException(
280: lOperation, lOperation.refMetaObject(),
281: sRequiredInstanceKeyInputFieldConstraintTextBase
282: + " The '" + lOperationInputFieldName
283: + "' input field is missing."));
284: }
285: // Input constraints - only verify that the ones that we need exist. The extra ones are allowed
286: {
287: // Work on the entity key validation constraint.
288: {
289: String lEntityKeyInputFieldName = StylesheetImpl
290: .getEntityKeyOperationInputParameterName(lEntityName);
291: String lConstraintName = lEntityKeyInputFieldName
292: + "FieldPresenceConstraint";
293: ModelElementConstraint lModelElementConstraint = lOperation
294: .findInputConstraint(lConstraintName);
295: if (lModelElementConstraint == null)
296: pViolations
297: .add(new ConstraintViolationException(
298: lOperation,
299: lOperation.refMetaObject(),
300: sOperationInputConstraintTextBase
301: + " The '"
302: + lConstraintName
303: + "' Input Constraint is missing."));
304: }
305: }
306: // Output Fields - only verify that the ones that we need exist. The extra ones are allowed
307: {
308: String lOperationOutputFieldName = suggestEntityReturnParameterName(lEntityName);
309: OperationOutputField lOutputField = lOperation
310: .findOutputField(lOperationOutputFieldName);
311: if (lOutputField != null) {
312: Structure lEntityDetailsStructure = pDataManagementService
313: .getServicemodule() != null ? pDataManagementService
314: .getServicemodule()
315: .findStructure(
316: StylesheetImpl
317: .getEntityDetailsStructureName(lEntityName))
318: : null;
319: if (lEntityDetailsStructure != null
320: && lEntityDetailsStructure.equals(lOutputField
321: .getStructureType()) == false)
322: pViolations
323: .add(new ConstraintViolationException(
324: lOutputField,
325: lOutputField.refMetaObject(),
326: sRetrievedEntityDetailsOutputFieldConstraintTextBase
327: + " The '"
328: + lOperationOutputFieldName
329: + "' output field has wrong type."));
330: if (lOutputField.isArray())
331: pViolations
332: .add(new ConstraintViolationException(
333: lOutputField,
334: lOutputField.refMetaObject(),
335: sRetrievedEntityDetailsOutputFieldConstraintTextBase
336: + " The '"
337: + lOperationOutputFieldName
338: + "' output field is an array, which is wrong."));
339: } else
340: pViolations.add(new ConstraintViolationException(
341: lOperation, lOperation.refMetaObject(),
342: sRetrievedEntityDetailsOutputFieldConstraintTextBase
343: + " The '" + lOperationOutputFieldName
344: + "' output field is missing."));
345: }
346: // Output Messages
347: {
348: // When instance is being loaded (gets and delete operations) instance not found message can be returned for this entity instance
349: // and all primary key associations entities (definitely will have at least our own)
350: Set lEntitiesWhichMayBeNotFoundWhenLoadingInstance = new HashSet();
351: lEntitiesWhichMayBeNotFoundWhenLoadingInstance.add(pEntity);
352: Util.collectEntitiesWhichMayBeNotFoundWhenLoadingInstance(
353: pEntity,
354: lEntitiesWhichMayBeNotFoundWhenLoadingInstance);
355: for (Iterator lEntitiesWhichMayBeNotFoundWhenLoadingInstanceIterator = lEntitiesWhichMayBeNotFoundWhenLoadingInstance
356: .iterator(); lEntitiesWhichMayBeNotFoundWhenLoadingInstanceIterator
357: .hasNext();) {
358: Entity lEntityElement = (Entity) lEntitiesWhichMayBeNotFoundWhenLoadingInstanceIterator
359: .next();
360: // We need to use entity name parameter for the entity which is passed as a parameter.
361: String lEntityElementName = lEntityElement
362: .equals(pEntity) ? lEntityName : lEntityElement
363: .getName();
364: if (lEntityElementName == null)
365: continue;
366: String lOperationOutputMessageName = StylesheetImpl
367: .getEntityNotFoundOperationOutputMessageName(lEntityElementName);
368: OperationOutputMessage lOutputMessage = lOperation
369: .findOutputMessage(lOperationOutputMessageName);
370: if (lOutputMessage != null) {
371: Message lEntityNotFoundMessage = pDataManagementService
372: .getServicemodule() != null ? pDataManagementService
373: .getServicemodule()
374: .findMessage(
375: StylesheetImpl
376: .getEntityInstanceNotFoundMessageName(lEntityElementName))
377: : null;
378: if (lEntityNotFoundMessage != null
379: && lEntityNotFoundMessage
380: .equals(lOutputMessage
381: .getMessageType()) == false)
382: pViolations
383: .add(new ConstraintViolationException(
384: lOutputMessage,
385: lOutputMessage.refMetaObject(),
386: sEntityNotFoundErrorOutputMessageConstraintTextBase
387: + " The '"
388: + lOperationOutputMessageName
389: + "' output message has wrong type."));
390: if (lOutputMessage.isArray())
391: pViolations
392: .add(new ConstraintViolationException(
393: lOutputMessage,
394: lOutputMessage.refMetaObject(),
395: sEntityNotFoundErrorOutputMessageConstraintTextBase
396: + " The '"
397: + lOperationOutputMessageName
398: + "' output message is an array, which is wrong."));
399: } else
400: pViolations.add(new ConstraintViolationException(
401: lOperation, lOperation.refMetaObject(),
402: sEntityNotFoundErrorOutputMessageConstraintTextBase
403: + " The '"
404: + lOperationOutputMessageName
405: + "' output message is missing."));
406: }
407: }
408: }
409:
410: // This helper is doing everything necessary to rectify errors reported in verifyConstraints()
411: void rectifyModel(Service pDataManagementService, Entity pEntity,
412: Collection pUnclaimedOperations) {
413: // Check if we have an operation and than just call ensurePresent
414: String lEntityName = pEntity.getName();
415: String lOperationName = suggestOperationName(lEntityName);
416: Operation lOperation = pDataManagementService
417: .findOperation(lOperationName);
418: if (lOperation != null)
419: pUnclaimedOperations.remove(lOperation); // Claim the operation
420: // Now just call ensurePresent
421: ensurePresent(pDataManagementService, pEntity, lEntityName);
422: }
423:
424: // This helper renames the key and details structures
425: void ensureRenamedPresent(Service pDataManagementService,
426: Entity pEntity, String pOldEntityName, String pNewEntityName) {
427: // Note that this method only deals with renaming and than calls the ensure present method
428: String lOldOperationName = suggestOperationName(pOldEntityName);
429: Operation lOldOperation = pDataManagementService
430: .findOperation(lOldOperationName);
431: String lNewOperationName = suggestOperationName(pNewEntityName);
432: Operation lNewOperation = pDataManagementService
433: .findOperation(lNewOperationName);
434: // Be relaxed here - allow for all sorts of mishaps
435: if (lOldOperation != null) {
436: if (lNewOperation != null) {
437: // New and old structures are present - just delete the old one
438: lOldOperation.refDelete();
439: } else {
440: // Old structure is present - new one is not - rename
441: lOldOperation.setName(lNewOperationName);
442: }
443: }
444: // Call the ensure present bit
445: ensurePresent(pDataManagementService, pEntity, pNewEntityName);
446: }
447:
448: // This helper makes sure that the version id attribute is present in the details structure
449: void ensurePresent(Service pDataManagementService, Entity pEntity,
450: String pEntityName) {
451: // Work on the servicemodule
452: String lOperationName = suggestOperationName(pEntityName);
453: Operation lOperation = pDataManagementService
454: .findOperation(lOperationName);
455: if (lOperation == null) {
456: lOperation = mModelAssistantImpl.mOperationClass
457: .createOperation();
458: lOperation.setService(pDataManagementService);
459: lOperation.setName(lOperationName);
460: }
461: lOperation
462: .setDescription(suggestOperationDescription(pEntityName));
463: lOperation
464: .setTransactionPolicy(TransactionPolicyEnum.SUPPORTED);
465: lOperation.setQuery(true);
466:
467: // Input Fields
468: {
469: Collection lOperationInputFields = lOperation
470: .getInputFields();
471: List lUnprocessedInputFields = new ArrayList();
472: lUnprocessedInputFields.addAll(lOperationInputFields);
473: {
474: String lOperationInputFieldName = StylesheetImpl
475: .getEntityKeyOperationInputParameterName(pEntityName);
476: OperationInputField lInputField = lOperation
477: .findInputField(lOperationInputFieldName);
478: if (lInputField == null) {
479: lInputField = mModelAssistantImpl.mOperationInputFieldClass
480: .createOperationInputField();
481: lInputField.setName(lOperationInputFieldName);
482: lInputField.setOperation(lOperation);
483: } else {
484: lUnprocessedInputFields.remove(lInputField);
485: }
486: lInputField
487: .setDescription(suggestUniqueKeyInputParameterDescription(pEntityName));
488: lInputField.setArray(false);
489: lInputField.setDataType(null);
490: Structure lEntityKeyStructure = pDataManagementService
491: .getServicemodule() != null ? pDataManagementService
492: .getServicemodule()
493: .findStructure(
494: StylesheetImpl
495: .getEntityKeyStructureName(pEntityName))
496: : null;
497: lInputField.setStructureType(lEntityKeyStructure);
498: }
499: // Delete all input fields left
500: for (Iterator lUnprocessedInputFieldsIterator = lUnprocessedInputFields
501: .iterator(); lUnprocessedInputFieldsIterator
502: .hasNext();) {
503: OperationInputField lInputField = (OperationInputField) lUnprocessedInputFieldsIterator
504: .next();
505: if (!lInputField.isDerived())
506: lInputField.refDelete();
507: }
508: }
509: // Input constraints
510: {
511: // Copy aside the collection of the constraints, so we can delete the unused ones
512: Collection lUnclaimedConstraints = new ArrayList();
513: lUnclaimedConstraints.addAll(lOperation
514: .getInputConstraints());
515: // Work on the entity key validation constraint.
516: {
517: String lEntityKeyInputFieldName = StylesheetImpl
518: .getEntityKeyOperationInputParameterName(pEntityName);
519: String lEntityKeyOCLFieldName = lEntityKeyInputFieldName
520: .substring(0, 1).toLowerCase()
521: + lEntityKeyInputFieldName.substring(1);
522: String lConstraintName = lEntityKeyInputFieldName
523: + "FieldPresenceConstraint";
524: ModelElementConstraint lModelElementConstraint = lOperation
525: .findInputConstraint(lConstraintName);
526: if (lModelElementConstraint == null) {
527: lModelElementConstraint = mModelAssistantImpl.mModelElementConstraintClass
528: .createModelElementConstraint();
529: lModelElementConstraint.setName(lConstraintName);
530: lOperation.getInputConstraints().add(
531: lModelElementConstraint);
532: } else {
533: // Claim the field
534: lUnclaimedConstraints
535: .remove(lModelElementConstraint);
536: }
537: lModelElementConstraint
538: .setDescription("Verifies that the "
539: + lEntityKeyInputFieldName
540: + " input field is not empty in the operation input");
541: lModelElementConstraint.setDefaultErrorText("The '"
542: + lEntityKeyInputFieldName
543: + "' input field must not be empty.");
544: lModelElementConstraint.setOclExpression("not "
545: + lEntityKeyOCLFieldName + ".oclIsUndefined()");
546: }
547: // Remove unclaimed constraints
548: for (Iterator lUnclaimedConstraintsIterator = lUnclaimedConstraints
549: .iterator(); lUnclaimedConstraintsIterator
550: .hasNext();) {
551: ModelElementConstraint lUnclaimedConstraint = (ModelElementConstraint) lUnclaimedConstraintsIterator
552: .next();
553: if (!lUnclaimedConstraint.isDerived())
554: lUnclaimedConstraint.refDelete();
555: }
556: }
557: // Output Fields
558: {
559: Collection lOperationOutputFields = lOperation
560: .getOutputFields();
561: List lUnprocessedOutputFields = new ArrayList();
562: lUnprocessedOutputFields.addAll(lOperationOutputFields);
563: {
564: String lOperationOutputFieldName = suggestEntityReturnParameterName(pEntityName);
565: OperationOutputField lOutputField = lOperation
566: .findOutputField(lOperationOutputFieldName);
567: if (lOutputField == null) {
568: lOutputField = mModelAssistantImpl.mOperationOutputFieldClass
569: .createOperationOutputField();
570: lOutputField.setName(lOperationOutputFieldName);
571: lOperationOutputFields.add(lOutputField);
572: } else {
573: lUnprocessedOutputFields.remove(lOutputField);
574: }
575: lOutputField
576: .setDescription(suggestEntityReturnParameterDescription(pEntityName));
577: lOutputField.setArray(false);
578: lOutputField.setDataType(null);
579: Structure lEntityDetailsStructure = pDataManagementService
580: .getServicemodule() != null ? pDataManagementService
581: .getServicemodule()
582: .findStructure(
583: StylesheetImpl
584: .getEntityDetailsStructureName(pEntityName))
585: : null;
586: lOutputField.setStructureType(lEntityDetailsStructure);
587: }
588: // Delete all output fields left
589: for (Iterator lUnprocessedOutputFieldsIterator = lUnprocessedOutputFields
590: .iterator(); lUnprocessedOutputFieldsIterator
591: .hasNext();) {
592: OperationOutputField lOutputField = (OperationOutputField) lUnprocessedOutputFieldsIterator
593: .next();
594: if (!lOutputField.isDerived())
595: lOutputField.refDelete();
596: }
597: }
598: // Output Messages
599: {
600: Collection lOperationOutputMessages = lOperation
601: .getOutputMessages();
602: List lUnprocessedOutputMessages = new ArrayList();
603: lUnprocessedOutputMessages.addAll(lOperationOutputMessages);
604:
605: // When instance is being loaded (gets and delete operations) instance not found message can be returned for this entity instance
606: // and all primary key associations entities (definitely will have at least our own)
607: Set lEntitiesWhichMayBeNotFoundWhenLoadingInstance = new HashSet();
608: lEntitiesWhichMayBeNotFoundWhenLoadingInstance.add(pEntity);
609: Util.collectEntitiesWhichMayBeNotFoundWhenLoadingInstance(
610: pEntity,
611: lEntitiesWhichMayBeNotFoundWhenLoadingInstance);
612: for (Iterator lEntitiesWhichMayBeNotFoundWhenLoadingInstanceIterator = lEntitiesWhichMayBeNotFoundWhenLoadingInstance
613: .iterator(); lEntitiesWhichMayBeNotFoundWhenLoadingInstanceIterator
614: .hasNext();) {
615: Entity lEntityElement = (Entity) lEntitiesWhichMayBeNotFoundWhenLoadingInstanceIterator
616: .next();
617: // We need to use entity name parameter for the entity which is passed as a parameter.
618: String lEntityElementName = lEntityElement
619: .equals(pEntity) ? pEntityName : lEntityElement
620: .getName();
621: if (lEntityElementName == null)
622: continue;
623: String lOperationOutputMessageName = StylesheetImpl
624: .getEntityNotFoundOperationOutputMessageName(lEntityElementName);
625: OperationOutputMessage lOutputMessage = lOperation
626: .findOutputMessage(lOperationOutputMessageName);
627: if (lOutputMessage == null) {
628: lOutputMessage = mModelAssistantImpl.mOperationOutputMessageClass
629: .createOperationOutputMessage();
630: lOutputMessage.setName(lOperationOutputMessageName);
631: lOutputMessage.setOperation(lOperation);
632: } else {
633: lUnprocessedOutputMessages.remove(lOutputMessage);
634: }
635: lOutputMessage
636: .setDescription(StylesheetImpl
637: .getEntityNotFoundOperationOutputMessageDescription(lEntityElementName));
638: lOutputMessage.setArray(false);
639: Message lEntityNotFoundMessage = pDataManagementService
640: .getServicemodule() != null ? pDataManagementService
641: .getServicemodule()
642: .findMessage(
643: StylesheetImpl
644: .getEntityInstanceNotFoundMessageName(lEntityElementName))
645: : null;
646: lOutputMessage.setMessageType(lEntityNotFoundMessage);
647: }
648:
649: // Delete all output messages left
650: for (Iterator lUnprocessedOutputMessagesIterator = lUnprocessedOutputMessages
651: .iterator(); lUnprocessedOutputMessagesIterator
652: .hasNext();) {
653: OperationOutputMessage lOutputMessage = (OperationOutputMessage) lUnprocessedOutputMessagesIterator
654: .next();
655: if (!lOutputMessage.isDerived())
656: lOutputMessage.refDelete();
657: }
658: }
659: }
660:
661: // This helper makes sure that the version id attribute is absent in the details structure
662: void ensureAbsent(Service pDataManagementService, String pEntityName) {
663: // Work on the details structure
664: Operation lOperation = pDataManagementService
665: .findOperation(suggestOperationName(pEntityName));
666: if (lOperation != null)
667: lOperation.refDelete();
668: }
669:
670: // This helper renames the key and details structures
671: void entityNotFoundMessage_EnsureRenamedPresent(
672: Service pDataManagementService,
673: String pOperationEntityName,
674: String pOldDependentEntityName,
675: String pNewDependentEntityName) {
676: String lOperationName = suggestOperationName(pOperationEntityName);
677: Operation lOperation = pDataManagementService
678: .findOperation(lOperationName);
679: if (lOperation == null)
680: return;
681: // Note that this method only deals with renaming and than calls the ensure present method
682: String lOldOutputMessageName = StylesheetImpl
683: .getEntityNotFoundOperationOutputMessageName(pOldDependentEntityName);
684: OperationOutputMessage lOldOutputMessage = lOperation
685: .findOutputMessage(lOldOutputMessageName);
686: String lNewOutputMessageName = StylesheetImpl
687: .getEntityNotFoundOperationOutputMessageName(pNewDependentEntityName);
688: OperationOutputMessage lNewOutputMessage = lOperation
689: .findOutputMessage(lNewOutputMessageName);
690: // Be relaxed here - allow for all sorts of mishaps
691: if (lOldOutputMessage != null) {
692: if (lNewOutputMessage != null) {
693: // New and old structures are present - just delete the old one
694: lOldOutputMessage.refDelete();
695: } else {
696: // Old structure is present - new one is not - rename
697: lOldOutputMessage.setName(lNewOutputMessageName);
698: }
699: }
700: // Call the ensure present bit
701: entityNotFoundMessage_EnsurePresent(pDataManagementService,
702: pOperationEntityName, pNewDependentEntityName);
703: }
704:
705: // This helper makes sure that the version id attribute is present in the details structure
706: void entityNotFoundMessage_EnsurePresent(
707: Service pDataManagementService,
708: String pOperationEntityName, String pDependentEntityName) {
709: String lOperationName = suggestOperationName(pOperationEntityName);
710: Operation lOperation = pDataManagementService
711: .findOperation(lOperationName);
712: if (lOperation == null)
713: return;
714: String lOperationOutputMessageName = StylesheetImpl
715: .getEntityNotFoundOperationOutputMessageName(pDependentEntityName);
716: OperationOutputMessage lOutputMessage = lOperation
717: .findOutputMessage(lOperationOutputMessageName);
718: if (lOutputMessage == null) {
719: lOutputMessage = mModelAssistantImpl.mOperationOutputMessageClass
720: .createOperationOutputMessage();
721: lOutputMessage.setName(lOperationOutputMessageName);
722: lOutputMessage.setOperation(lOperation);
723: }
724: lOutputMessage
725: .setDescription(StylesheetImpl
726: .getEntityNotFoundOperationOutputMessageDescription(pDependentEntityName));
727: lOutputMessage.setArray(false);
728: Message lEntityNotFoundMessage = pDataManagementService
729: .getServicemodule() != null ? pDataManagementService
730: .getServicemodule()
731: .findMessage(
732: StylesheetImpl
733: .getEntityInstanceNotFoundMessageName(pDependentEntityName))
734: : null;
735: lOutputMessage.setMessageType(lEntityNotFoundMessage);
736: }
737:
738: // This helper makes sure that the version id attribute is absent in the details structure
739: void entityNotFoundMessage_EnsureAbsent(
740: Service pDataManagementService,
741: String pOperationEntityName, String pDependentEntityName) {
742: // Work on the details structure
743: Operation lOperation = pDataManagementService
744: .findOperation(suggestOperationName(pOperationEntityName));
745: if (lOperation == null)
746: return; // Whole operation is not present
747: String lOperationOutputMessageName = StylesheetImpl
748: .getEntityNotFoundOperationOutputMessageName(pDependentEntityName);
749: OperationOutputMessage lOutputMessage = lOperation
750: .findOutputMessage(lOperationOutputMessageName);
751: if (lOutputMessage != null)
752: lOutputMessage.refDelete();
753: }
754:
755: // Helper. Returns the message name
756: private static String suggestOperationName(String pEntityName) {
757: // Use normalised name here
758: return "get"
759: + StringUtils.suggestName(pEntityName, true, false);
760: }
761:
762: // Helper. Returns the message description
763: private static String suggestOperationDescription(String pEntityName) {
764: // Use name 'as is' here
765: return "Retrieves details of a particular "
766: + pEntityName
767: + " instance from the domain. Instance is identified by key structure.";
768: }
769:
770: // Helper. Returns the message description
771: private static String suggestUniqueKeyInputParameterDescription(
772: String pEntityName) {
773: // Use name 'as is' here
774: return "The unique key referring to the instance of "
775: + pEntityName + " to be retrieved.";
776: }
777:
778: // Helper. Returns the message name
779: private static String suggestEntityReturnParameterName(
780: String pEntityName) {
781: // Use normalised name here
782: return StringUtils.suggestName(pEntityName, true, false);
783: }
784:
785: // Helper. Returns the message description
786: private static String suggestEntityReturnParameterDescription(
787: String pEntityName) {
788: // Use name 'as is' here
789: return "Details of a particuar " + pEntityName
790: + " found in the domain.";
791: }
792: }
|