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.ModelElementConstraint;
026: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.DataType;
027: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Operation;
028: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.OperationInputField;
029: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.OperationOutputField;
030: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.OperationOutputMessage;
031: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Service;
032: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Servicemodule;
033: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.TransactionPolicyEnum;
034: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Domain;
035: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Entity;
036: import com.metaboss.util.StringUtils;
037:
038: /** This class containse helper methods dealing with the Domain Support Servicemodule model element */
039: class TargetGetAllEntitiesCountOperationHelper {
040: private ModelAssistantImpl mModelAssistantImpl;
041:
042: TargetGetAllEntitiesCountOperationHelper(
043: ModelAssistantImpl pModelAssistantImpl) {
044: mModelAssistantImpl = pModelAssistantImpl;
045: // Add domain lifecycle listener
046: mModelAssistantImpl.addLifecycleListener(Entity.class,
047: new ModelAssistantImpl.ModelElementLifecycleListener() {
048: public void onElementJustCreated(
049: RefObject pModelElementJustCreated) {
050: Entity lEntity = (Entity) pModelElementJustCreated;
051: String lEntityPluralName = lEntity
052: .getPluralName();
053: if (lEntityPluralName == null)
054: return; // Entity does not have a plural name
055: Domain lDomain = lEntity.getDomain();
056: if (lDomain == null)
057: return; // Entity is not associated with domain
058: String lDomainName = lDomain.getName();
059: if (lDomainName == null)
060: return; // Domain does not have a name
061: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
062: .getSystem();
063: if (lSystem == null)
064: return; // Domain is not associated with system
065: Servicemodule lServicemodule = lSystem
066: .findServicemodule(StylesheetImpl
067: .getDomainSupportServicemoduleName(lDomainName));
068: if (lServicemodule == null)
069: return; // There is no support servicemodule yet
070: Service lDomainSupportService = lServicemodule
071: .findService(StylesheetImpl
072: .getDataManagementServiceName(lDomainName));
073: if (lDomainSupportService == null)
074: return; // There is no domain support service yet
075: // Create associated element
076: ensurePresent(lDomainSupportService, lEntity,
077: lEntityPluralName);
078: }
079:
080: public void onElementBeingDeleted(
081: RefObject pModelElementBeingDeleted) {
082: Entity lEntity = (Entity) pModelElementBeingDeleted;
083: String lEntityPluralName = lEntity
084: .getPluralName();
085: if (lEntityPluralName == null)
086: return; // Entity does not have a plural name
087: Domain lDomain = lEntity.getDomain();
088: if (lDomain == null)
089: return; // Entity is not associated with domain
090: String lDomainName = lDomain.getName();
091: if (lDomainName == null)
092: return; // Domain does not have a name
093: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
094: .getSystem();
095: if (lSystem == null)
096: return; // Domain is not associated with system
097: Servicemodule lServicemodule = lSystem
098: .findServicemodule(StylesheetImpl
099: .getDomainSupportServicemoduleName(lDomainName));
100: if (lServicemodule == null)
101: return; // There is no support servicemodule yet
102: Service lDomainSupportService = lServicemodule
103: .findService(StylesheetImpl
104: .getDataManagementServiceName(lDomainName));
105: if (lDomainSupportService == null)
106: return; // There is no domain support service yet
107: // Remove associated element
108: ensureAbsent(lDomainSupportService,
109: lEntityPluralName);
110: }
111: });
112: // Add entity pluralName attribute change listener
113: mModelAssistantImpl
114: .addAttributeChangeListener(
115: Entity.class,
116: "pluralName",
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: if (pNewValue == null) {
144: // Only old value is known - ensure that the element is deleted
145: ensureAbsent(lDomainSupportService,
146: (String) pOldValue);
147: } else {
148: // New value is known - rename or create
149: if (pOldValue != null)
150: ensureRenamedPresent(
151: lDomainSupportService,
152: lEntity,
153: (String) pOldValue,
154: (String) pNewValue);
155: else
156: ensurePresent(
157: lDomainSupportService,
158: lEntity,
159: (String) pNewValue);
160: }
161: }
162: });
163: }
164:
165: private static String sOperationConstraintTextBase = "A Data Management Service must have Get All Entities Count operation for every Entity in the corresponding Domain.";
166: private static String sRetrievedEntityCountOutputFieldConstraintTextBase = "A Get All Entities Count Data Management Operation must have well formed Count output parameter carrying the number of Entities.";
167:
168: // This helper verifies constraints which are dealing with entity structures
169: void verifyConstraints(Collection pViolations,
170: Service pDataManagementService, Entity pEntity,
171: Collection pUnclaimedOperations) {
172: String lEntityPluralName = pEntity.getPluralName();
173: if (lEntityPluralName == null)
174: return;
175: // Work on the Key structure
176: String lOperationName = suggestOperationName(lEntityPluralName);
177: Operation lOperation = pDataManagementService
178: .findOperation(lOperationName);
179: if (lOperation == null) {
180: pViolations
181: .add(new ConstraintViolationException(
182: pDataManagementService,
183: pDataManagementService.refMetaObject(),
184: sOperationConstraintTextBase + " The '"
185: + lOperationName
186: + "' Operation not found."));
187: return;
188: }
189: pUnclaimedOperations.remove(lOperation); // Claim the operation
190: // Validate operation details
191: if (!TransactionPolicyEnum.SUPPORTED.equals(lOperation
192: .getTransactionPolicy()))
193: pViolations.add(new ConstraintViolationException(
194: lOperation, lOperation.refMetaObject(),
195: "A Query Data Management Operation must have transaction policy '"
196: + TransactionPolicyEnum.SUPPORTED
197: .toString() + "'. The '"
198: + lOperation.getTransactionPolicy()
199: + "' Transaction policy is unexpected."));
200: if (!lOperation.isQuery())
201: pViolations
202: .add(new ConstraintViolationException(
203: lOperation,
204: lOperation.refMetaObject(),
205: "A Query Data Management Operation must have the isQuery attribute set to true."));
206: // Input Fields - only verify that the ones that we need exist. The extra ones are allowed
207: {
208: // No input fields
209: }
210: // Output Fields - only verify that the ones that we need exist. The extra ones are allowed
211: {
212: String lOperationOutputFieldName = suggestCountReturnParameterName(lEntityPluralName);
213: OperationOutputField lOutputField = lOperation
214: .findOutputField(lOperationOutputFieldName);
215: if (lOutputField != null) {
216: DataType lCollectionSizeDataType = pEntity
217: .getCollectionSizeDataType();
218: if (lCollectionSizeDataType != null
219: && lCollectionSizeDataType.equals(lOutputField
220: .getDataType()) == false)
221: pViolations
222: .add(new ConstraintViolationException(
223: lOutputField,
224: lOutputField.refMetaObject(),
225: sRetrievedEntityCountOutputFieldConstraintTextBase
226: + " The '"
227: + lOperationOutputFieldName
228: + "' output field has wrong type."));
229: if (lOutputField.isArray())
230: pViolations
231: .add(new ConstraintViolationException(
232: lOutputField,
233: lOutputField.refMetaObject(),
234: sRetrievedEntityCountOutputFieldConstraintTextBase
235: + " The '"
236: + lOperationOutputFieldName
237: + "' output field is an array, which is wrong."));
238: } else
239: pViolations.add(new ConstraintViolationException(
240: lOperation, lOperation.refMetaObject(),
241: sRetrievedEntityCountOutputFieldConstraintTextBase
242: + " The '" + lOperationOutputFieldName
243: + "' output field is missing."));
244: }
245: }
246:
247: // This helper is doing everything necessary to rectify errors reported in verifyConstraints()
248: void rectifyModel(Service pDataManagementService, Entity pEntity,
249: Collection pUnclaimedOperations) {
250: // Check if we have an operation and than just call ensurePresent
251: String lEntityPluralName = pEntity.getPluralName();
252: String lOperationName = suggestOperationName(lEntityPluralName);
253: Operation lOperation = pDataManagementService
254: .findOperation(lOperationName);
255: if (lOperation != null)
256: pUnclaimedOperations.remove(lOperation); // Claim the structure
257: // Now just call ensurePresent
258: ensurePresent(pDataManagementService, pEntity,
259: lEntityPluralName);
260: }
261:
262: // This helper renames the key and details structures
263: void ensureRenamedPresent(Service pDataManagementService,
264: Entity pEntity, String pOldEntityPluralName,
265: String pNewEntityPluralName) {
266: // Note that this method only deals with renaming and than calls the ensure present method
267: String lOldOperationName = suggestOperationName(pOldEntityPluralName);
268: Operation lOldOperation = pDataManagementService
269: .findOperation(lOldOperationName);
270: String lNewOperationName = suggestOperationName(pNewEntityPluralName);
271: Operation lNewOperation = pDataManagementService
272: .findOperation(lNewOperationName);
273: // Be relaxed here - allow for all sorts of mishaps
274: if (lOldOperation != null) {
275: if (lNewOperation != null) {
276: // New and old structures are present - just delete the old one
277: lOldOperation.refDelete();
278: } else {
279: // Old structure is present - new one is not - rename
280: lOldOperation.setName(lNewOperationName);
281: }
282: }
283: // Call the ensure present bit
284: ensurePresent(pDataManagementService, pEntity,
285: pNewEntityPluralName);
286: }
287:
288: // This helper makes sure that the version id attribute is present in the details structure
289: void ensurePresent(Service pDataManagementService, Entity pEntity,
290: String pEntityPluralName) {
291: // Work on the servicemodule
292: String lOperationName = suggestOperationName(pEntityPluralName);
293: Operation lOperation = pDataManagementService
294: .findOperation(lOperationName);
295: if (lOperation == null) {
296: lOperation = mModelAssistantImpl.mOperationClass
297: .createOperation();
298: lOperation.setService(pDataManagementService);
299: lOperation.setName(lOperationName);
300: }
301: lOperation
302: .setDescription(suggestOperationDescription(pEntityPluralName));
303: lOperation
304: .setTransactionPolicy(TransactionPolicyEnum.SUPPORTED);
305: lOperation.setQuery(true);
306:
307: // Input Fields
308: {
309: Collection lOperationInputFields = lOperation
310: .getInputFields();
311: List lUnprocessedInputFields = new ArrayList();
312: lUnprocessedInputFields.addAll(lOperationInputFields);
313:
314: // No input fields
315:
316: // Delete all input fields left
317: for (Iterator lUnprocessedInputFieldsIterator = lUnprocessedInputFields
318: .iterator(); lUnprocessedInputFieldsIterator
319: .hasNext();) {
320: OperationInputField lInputField = (OperationInputField) lUnprocessedInputFieldsIterator
321: .next();
322: if (!lInputField.isDerived())
323: lInputField.refDelete();
324: }
325: }
326: // Input constraints
327: {
328: // Copy aside the collection of the constraints, so we can delete the unused ones
329: Collection lUnclaimedConstraints = new ArrayList();
330: lUnclaimedConstraints.addAll(lOperation
331: .getInputConstraints());
332: // Remove unclaimed constraints
333: for (Iterator lUnclaimedConstraintsIterator = lUnclaimedConstraints
334: .iterator(); lUnclaimedConstraintsIterator
335: .hasNext();) {
336: ModelElementConstraint lUnclaimedConstraint = (ModelElementConstraint) lUnclaimedConstraintsIterator
337: .next();
338: if (!lUnclaimedConstraint.isDerived())
339: lUnclaimedConstraint.refDelete();
340: }
341: }
342: // Output Fields
343: {
344: Collection lOperationOutputFields = lOperation
345: .getOutputFields();
346: List lUnprocessedOutputFields = new ArrayList();
347: lUnprocessedOutputFields.addAll(lOperationOutputFields);
348: {
349: String lOperationOutputFieldName = suggestCountReturnParameterName(pEntityPluralName);
350: OperationOutputField lOutputField = lOperation
351: .findOutputField(lOperationOutputFieldName);
352: if (lOutputField == null) {
353: lOutputField = mModelAssistantImpl.mOperationOutputFieldClass
354: .createOperationOutputField();
355: lOutputField.setName(lOperationOutputFieldName);
356: lOperationOutputFields.add(lOutputField);
357: } else {
358: lUnprocessedOutputFields.remove(lOutputField);
359: }
360: lOutputField
361: .setDescription(suggestCountReturnParameterDescription(pEntityPluralName));
362: lOutputField.setArray(false);
363: lOutputField.setDataType(pEntity
364: .getCollectionSizeDataType());
365: }
366: // Delete all output fields left
367: for (Iterator lUnprocessedOutputFieldsIterator = lUnprocessedOutputFields
368: .iterator(); lUnprocessedOutputFieldsIterator
369: .hasNext();) {
370: OperationOutputField lOutputField = (OperationOutputField) lUnprocessedOutputFieldsIterator
371: .next();
372: if (!lOutputField.isDerived())
373: lOutputField.refDelete();
374: }
375: }
376: // Output Messages
377: {
378: Collection lOperationOutputMessages = lOperation
379: .getOutputMessages();
380: List lUnprocessedOutputMessages = new ArrayList();
381: lUnprocessedOutputMessages.addAll(lOperationOutputMessages);
382:
383: // No output messsages
384:
385: // Delete all output messages left
386: for (Iterator lUnprocessedOutputMessagesIterator = lUnprocessedOutputMessages
387: .iterator(); lUnprocessedOutputMessagesIterator
388: .hasNext();) {
389: OperationOutputMessage lOutputMessage = (OperationOutputMessage) lUnprocessedOutputMessagesIterator
390: .next();
391: if (!lOutputMessage.isDerived())
392: lOutputMessage.refDelete();
393: }
394: }
395: }
396:
397: // This helper makes sure that the version id attribute is absent in the details structure
398: void ensureAbsent(Service pDataManagementService,
399: String pEntityPluralName) {
400: // Work on the details structure
401: Operation lOperation = pDataManagementService
402: .findOperation(suggestOperationName(pEntityPluralName));
403: if (lOperation != null)
404: lOperation.refDelete();
405: }
406:
407: // Helper. Returns the message name
408: private static String suggestOperationName(String pEntityPluralName) {
409: // Use normalised name here
410: return "getAll"
411: + StringUtils.suggestName(pEntityPluralName, true,
412: false) + "Count";
413: }
414:
415: // Helper. Returns the message description
416: private static String suggestOperationDescription(
417: String pEntityPluralName) {
418: // Use name 'as is' here
419: return "Retrieves count of all " + pEntityPluralName
420: + " present in the domain.";
421: }
422:
423: // Helper. Returns the message name
424: private static String suggestCountReturnParameterName(
425: String pEntityPluralName) {
426: // Use normalised name here
427: return StringUtils.suggestName(pEntityPluralName, true, false)
428: + "Count";
429: }
430:
431: // Helper. Returns the message description
432: private static String suggestCountReturnParameterDescription(
433: String pEntityPluralName) {
434: // Use name 'as is' here
435: return "Number of " + pEntityPluralName
436: + " found in the domain.";
437: }
438: }
|