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