0001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
0002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
0003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
0004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
0005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
0006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
0008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
0011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
0012: // POSSIBILITY OF SUCH DAMAGE.
0013: //
0014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
0015: package com.metaboss.sdlctools.models.modelassistant.metabossmodel.domainsupport;
0016:
0017: import java.util.ArrayList;
0018: import java.util.Collection;
0019: import java.util.HashSet;
0020: import java.util.Iterator;
0021: import java.util.List;
0022: import java.util.Set;
0023:
0024: import javax.jmi.reflect.ConstraintViolationException;
0025: import javax.jmi.reflect.RefObject;
0026:
0027: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.DataType;
0028: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Message;
0029: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.MessageField;
0030: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.MessageTypeEnum;
0031: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Servicemodule;
0032: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.AssociationRole;
0033: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Attribute;
0034: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Domain;
0035: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Entity;
0036: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.PrimaryKeyElement;
0037: import com.metaboss.util.StringUtils;
0038:
0039: /** This class containse helper methods dealing with the Duplicate Create Failed error message model element */
0040: class TargetDuplicateCreateFailedMessageHelper {
0041: private ModelAssistantImpl mModelAssistantImpl;
0042:
0043: TargetDuplicateCreateFailedMessageHelper(
0044: ModelAssistantImpl pModelAssistantImpl) {
0045: mModelAssistantImpl = pModelAssistantImpl;
0046:
0047: // Add entity Name attribute change listener
0048: mModelAssistantImpl
0049: .addAttributeChangeListener(
0050: Entity.class,
0051: "Name",
0052: new ModelAssistantImpl.ModelElementAttributeChangeListener() {
0053: public void onAttributeBeingUpdated(
0054: RefObject pModelElementBeingUpdated,
0055: String pAttributeName,
0056: Object pOldValue, Object pNewValue) {
0057: Entity lEntity = (Entity) pModelElementBeingUpdated;
0058: Domain lDomain = lEntity.getDomain();
0059: if (lDomain == null)
0060: return; // Entity is not associated with domain
0061: String lDomainName = lDomain.getName();
0062: if (lDomainName == null)
0063: return; // Domain does not have a name
0064: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
0065: .getSystem();
0066: if (lSystem == null)
0067: return; // Domain is not associated with system
0068: Servicemodule lServicemodule = lSystem
0069: .findServicemodule(StylesheetImpl
0070: .getDomainSupportServicemoduleName(lDomainName));
0071: if (lServicemodule == null)
0072: return; // There is no support servicemodule yet
0073: if (pNewValue == null) {
0074: // Only old value is known - ensure that the element is deleted
0075: ensureAbsent(lServicemodule,
0076: (String) pOldValue);
0077: } else {
0078: // New value is known - analyse the criteria and deal with the element accordingly
0079: if (!lEntity
0080: .getPrimaryKeyElements()
0081: .isEmpty()) {
0082: // The element must be present - rename or create
0083: if (pOldValue != null)
0084: ensureRenamedPresent(
0085: lServicemodule,
0086: lEntity,
0087: (String) pOldValue,
0088: (String) pNewValue);
0089: else
0090: ensurePresent(
0091: lServicemodule,
0092: lEntity,
0093: (String) pNewValue);
0094: } else {
0095: // The element must be absent - delete
0096: ensureAbsent(lServicemodule,
0097: (String) pNewValue);
0098: if (pOldValue != null)
0099: ensureAbsent(
0100: lServicemodule,
0101: (String) pOldValue);
0102: }
0103: }
0104: }
0105: });
0106: // Add entity primaryKeyElements reference change listener
0107: mModelAssistantImpl
0108: .addReferenceChangeListener(
0109: Entity.class,
0110: "primaryKeyElements",
0111: new ModelAssistantImpl.ModelElementReferenceChangeListener() {
0112: public void onReferenceBeingUpdated(
0113: RefObject pModelElementBeingUpdated,
0114: String pReferenceName,
0115: RefObject pReferencedModelElementToRemove,
0116: RefObject pReferencedModelElementToAdd) {
0117: Entity lEntity = (Entity) pModelElementBeingUpdated;
0118: Domain lDomain = lEntity.getDomain();
0119: if (lDomain == null)
0120: return; // Entity is not associated with domain
0121: String lDomainName = lDomain.getName();
0122: if (lDomainName == null)
0123: return; // Domain does not have a name
0124: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
0125: .getSystem();
0126: if (lSystem == null)
0127: return; // Domain is not associated with system
0128: Servicemodule lServicemodule = lSystem
0129: .findServicemodule(StylesheetImpl
0130: .getDomainSupportServicemoduleName(lDomainName));
0131: if (lServicemodule == null)
0132: return; // There is no support servicemodule yet
0133: Set lAllEntitiesToConsider = new HashSet();
0134: lAllEntitiesToConsider.add(lEntity);
0135: lAllEntitiesToConsider.addAll(lEntity
0136: .getCombinedSubtypes());
0137: for (Iterator lEntityElementsIterator = lAllEntitiesToConsider
0138: .iterator(); lEntityElementsIterator
0139: .hasNext();) {
0140: Entity lEntityElement = (Entity) lEntityElementsIterator
0141: .next();
0142: // Analyse the criteria and deal with the element accordingly
0143: if (pReferencedModelElementToAdd != null) {
0144: if (pReferencedModelElementToAdd instanceof Attribute) {
0145: Attribute lAttribute = (Attribute) pReferencedModelElementToAdd;
0146: String lAttributeName = lAttribute
0147: .getName();
0148: if (lAttributeName == null)
0149: return; // Attribute does not have a name
0150: primaryKeyAttribute_EnsurePresent(
0151: lServicemodule,
0152: lEntityElement,
0153: lAttributeName,
0154: lAttribute
0155: .getDataType());
0156: } else if (pReferencedModelElementToAdd instanceof AssociationRole) {
0157: AssociationRole lReference = (AssociationRole) pReferencedModelElementToAdd;
0158: String lReferenceName = lReference
0159: .getName();
0160: if (lReferenceName == null)
0161: return; // Attribute does not have a name
0162: primaryKeyReference_EnsurePresent(
0163: lServicemodule,
0164: lEntityElement,
0165: lReferenceName,
0166: lReference
0167: .getEntity());
0168: }
0169: } else if (pReferencedModelElementToRemove != null) {
0170: if (pReferencedModelElementToRemove instanceof Attribute) {
0171: Attribute lAttribute = (Attribute) pReferencedModelElementToRemove;
0172: String lAttributeName = lAttribute
0173: .getName();
0174: if (lAttributeName == null)
0175: return; // Attribute does not have a name
0176: primaryKeyAttribute_EnsureAbsent(
0177: lServicemodule,
0178: lEntityElement,
0179: lAttributeName);
0180: } else if (pReferencedModelElementToRemove instanceof AssociationRole) {
0181: AssociationRole lReference = (AssociationRole) pReferencedModelElementToRemove;
0182: String lReferenceName = lReference
0183: .getName();
0184: if (lReferenceName == null)
0185: return; // Attribute does not have a name
0186: primaryKeyReference_EnsureAbsent(
0187: lServicemodule,
0188: lEntityElement,
0189: lReferenceName);
0190: }
0191: }
0192: }
0193: }
0194: });
0195:
0196: // Add attribute Name attribute change listener
0197: mModelAssistantImpl
0198: .addAttributeChangeListener(
0199: Attribute.class,
0200: "Name",
0201: new ModelAssistantImpl.ModelElementAttributeChangeListener() {
0202: public void onAttributeBeingUpdated(
0203: RefObject pModelElementBeingUpdated,
0204: String pAttributeName,
0205: Object pOldValue, Object pNewValue) {
0206: Attribute lAttribute = (Attribute) pModelElementBeingUpdated;
0207: Entity lEntity = lAttribute.getEntity();
0208: if (lEntity == null)
0209: return; // Attribute is not associated with entity
0210: Domain lDomain = lEntity.getDomain();
0211: if (lDomain == null)
0212: return; // Entity is not associated with domain
0213: String lDomainName = lDomain.getName();
0214: if (lDomainName == null)
0215: return; // Domain does not have a name
0216: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
0217: .getSystem();
0218: if (lSystem == null)
0219: return; // Domain is not associated with system
0220: Servicemodule lServicemodule = lSystem
0221: .findServicemodule(StylesheetImpl
0222: .getDomainSupportServicemoduleName(lDomainName));
0223: if (lServicemodule == null)
0224: return; // There is no support servicemodule yet
0225: Set lAllEntitiesToConsider = new HashSet();
0226: lAllEntitiesToConsider.add(lEntity);
0227: lAllEntitiesToConsider.addAll(lEntity
0228: .getCombinedSubtypes());
0229: for (Iterator lEntityElementsIterator = lAllEntitiesToConsider
0230: .iterator(); lEntityElementsIterator
0231: .hasNext();) {
0232: Entity lEntityElement = (Entity) lEntityElementsIterator
0233: .next();
0234: String lEntityName = lEntityElement
0235: .getName();
0236: if (lEntityName == null)
0237: continue; // Entity does not have a name
0238: if (pNewValue == null) {
0239: // Only old value is known - ensure that the element is deleted
0240: primaryKeyAttribute_EnsureAbsent(
0241: lServicemodule,
0242: lEntityElement,
0243: (String) pOldValue);
0244: } else {
0245: // New value is known - analyse the criteria and deal with the element accordingly
0246: if (lEntityElement
0247: .getPrimaryKeyElements()
0248: .contains(lAttribute)) {
0249: // The element must be present - rename or create
0250: if (pOldValue != null)
0251: primaryKeyAttribute_EnsureRenamedPresent(
0252: lServicemodule,
0253: lEntityElement,
0254: (String) pOldValue,
0255: (String) pNewValue,
0256: lAttribute
0257: .getDataType());
0258: else
0259: primaryKeyAttribute_EnsurePresent(
0260: lServicemodule,
0261: lEntityElement,
0262: (String) pNewValue,
0263: lAttribute
0264: .getDataType());
0265: } else {
0266: // The element must be absent - delete
0267: primaryKeyAttribute_EnsureAbsent(
0268: lServicemodule,
0269: lEntityElement,
0270: (String) pNewValue);
0271: if (pOldValue != null)
0272: primaryKeyAttribute_EnsureAbsent(
0273: lServicemodule,
0274: lEntityElement,
0275: (String) pOldValue);
0276: }
0277: }
0278: }
0279: }
0280: });
0281: // Add attribute dataType reference change listener
0282: mModelAssistantImpl
0283: .addReferenceChangeListener(
0284: Attribute.class,
0285: "dataType",
0286: new ModelAssistantImpl.ModelElementReferenceChangeListener() {
0287: public void onReferenceBeingUpdated(
0288: RefObject pModelElementBeingUpdated,
0289: String pReferenceName,
0290: RefObject pReferencedModelElementToRemove,
0291: RefObject pReferencedModelElementToAdd) {
0292: Attribute lAttribute = (Attribute) pModelElementBeingUpdated;
0293: String lAttributeName = lAttribute
0294: .getName();
0295: if (lAttributeName == null)
0296: return; // Attribute does not have a name
0297: Entity lEntity = lAttribute.getEntity();
0298: if (lEntity == null)
0299: return; // Attribute is not associated with entity
0300: Domain lDomain = lEntity.getDomain();
0301: if (lDomain == null)
0302: return; // Entity is not associated with domain
0303: String lDomainName = lDomain.getName();
0304: if (lDomainName == null)
0305: return; // Domain does not have a name
0306: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
0307: .getSystem();
0308: if (lSystem == null)
0309: return; // Domain is not associated with system
0310: Servicemodule lServicemodule = lSystem
0311: .findServicemodule(StylesheetImpl
0312: .getDomainSupportServicemoduleName(lDomainName));
0313: if (lServicemodule == null)
0314: return; // There is no support servicemodule yet
0315: Set lAllEntitiesToConsider = new HashSet();
0316: lAllEntitiesToConsider.add(lEntity);
0317: lAllEntitiesToConsider.addAll(lEntity
0318: .getCombinedSubtypes());
0319: for (Iterator lEntityElementsIterator = lAllEntitiesToConsider
0320: .iterator(); lEntityElementsIterator
0321: .hasNext();) {
0322: Entity lEntityElement = (Entity) lEntityElementsIterator
0323: .next();
0324: String lEntityName = lEntityElement
0325: .getName();
0326: if (lEntityName == null)
0327: continue; // Entity does not have a name
0328: // Analyse the criteria and deal with the element accordingly
0329: if (lEntityElement
0330: .getPrimaryKeyElements()
0331: .contains(lAttribute)) {
0332: if (pReferencedModelElementToAdd != null)
0333: primaryKeyAttribute_EnsurePresent(
0334: lServicemodule,
0335: lEntityElement,
0336: lAttributeName,
0337: (DataType) pReferencedModelElementToAdd);
0338: else if (pReferencedModelElementToRemove != null)
0339: primaryKeyAttribute_EnsurePresent(
0340: lServicemodule,
0341: lEntityElement,
0342: lAttributeName,
0343: null);
0344: }
0345: }
0346: }
0347: });
0348:
0349: // Add reference Name attribute change listener
0350: mModelAssistantImpl
0351: .addAttributeChangeListener(
0352: AssociationRole.class,
0353: "Name",
0354: new ModelAssistantImpl.ModelElementAttributeChangeListener() {
0355: public void onAttributeBeingUpdated(
0356: RefObject pModelElementBeingUpdated,
0357: String pAttributeName,
0358: Object pOldValue, Object pNewValue) {
0359: AssociationRole lAssociationRole = (AssociationRole) pModelElementBeingUpdated;
0360: Entity lEntity = lAssociationRole
0361: .getReferencingEntity();
0362: if (lEntity == null)
0363: return; // Attribute is not associated with entity
0364: Domain lDomain = lEntity.getDomain();
0365: if (lDomain == null)
0366: return; // Entity is not associated with domain
0367: String lDomainName = lDomain.getName();
0368: if (lDomainName == null)
0369: return; // Domain does not have a name
0370: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
0371: .getSystem();
0372: if (lSystem == null)
0373: return; // Domain is not associated with system
0374: Servicemodule lServicemodule = lSystem
0375: .findServicemodule(StylesheetImpl
0376: .getDomainSupportServicemoduleName(lDomainName));
0377: if (lServicemodule == null)
0378: return; // There is no support servicemodule yet
0379: Set lAllEntitiesToConsider = new HashSet();
0380: lAllEntitiesToConsider.add(lEntity);
0381: lAllEntitiesToConsider.addAll(lEntity
0382: .getCombinedSubtypes());
0383: for (Iterator lEntityElementsIterator = lAllEntitiesToConsider
0384: .iterator(); lEntityElementsIterator
0385: .hasNext();) {
0386: Entity lEntityElement = (Entity) lEntityElementsIterator
0387: .next();
0388: String lEntityName = lEntityElement
0389: .getName();
0390: if (lEntityName == null)
0391: continue; // Entity does not have a name
0392: if (pNewValue == null) {
0393: // Only old value is known - ensure that the element is deleted
0394: primaryKeyReference_EnsureAbsent(
0395: lServicemodule,
0396: lEntityElement,
0397: (String) pOldValue);
0398: } else {
0399: // New value is known - analyse the criteria and deal with the element accordingly
0400: if (lEntityElement
0401: .getPrimaryKeyElements()
0402: .contains(
0403: lAssociationRole)) {
0404: // The element must be present - rename or create
0405: if (pOldValue != null)
0406: primaryKeyReference_EnsureRenamedPresent(
0407: lServicemodule,
0408: lEntityElement,
0409: (String) pOldValue,
0410: (String) pNewValue,
0411: lAssociationRole
0412: .getEntity());
0413: else
0414: primaryKeyReference_EnsurePresent(
0415: lServicemodule,
0416: lEntityElement,
0417: (String) pNewValue,
0418: lAssociationRole
0419: .getEntity());
0420: } else {
0421: // The element must be absent - delete
0422: primaryKeyReference_EnsureAbsent(
0423: lServicemodule,
0424: lEntityElement,
0425: (String) pNewValue);
0426: if (pOldValue != null)
0427: primaryKeyReference_EnsureAbsent(
0428: lServicemodule,
0429: lEntityElement,
0430: (String) pOldValue);
0431: }
0432: }
0433: }
0434: }
0435: });
0436: }
0437:
0438: // This helper verifies constraints
0439: void verifyConstraints(Collection pViolations,
0440: Servicemodule pServicemodule, Entity pEntity,
0441: Collection pUnclaimedMessages) {
0442: if (pEntity.getPrimaryKeyElements().isEmpty())
0443: return; // If message is present - the generic unclaimed objects constraint processing will take care of it
0444: String lMessageName = StylesheetImpl
0445: .getDuplicateCreateFailedMessageName(pEntity.getName());
0446: Message lMessage = pServicemodule.findMessage(lMessageName);
0447: if (lMessage == null) {
0448: pViolations
0449: .add(new ConstraintViolationException(
0450: pServicemodule,
0451: pServicemodule.refMetaObject(),
0452: "A Domain Support Servicemodule must have 'Duplicate Create Failed' Message for every Entity which has the natural primary key. The '"
0453: + lMessageName
0454: + "' Message not found."));
0455: return;
0456: }
0457: // Claim the message
0458: pUnclaimedMessages.remove(lMessage); // Claim the message
0459:
0460: // Copy aside the collection of the fields, so we can keep track of the unused ones
0461: Collection lUnclaimedFields = new ArrayList();
0462: lUnclaimedFields.addAll(lMessage.getFields());
0463: // Work on primary key fields
0464: for (Iterator lPrimaryKeyElementsIterator = pEntity
0465: .getPrimaryKeyElements().iterator(); lPrimaryKeyElementsIterator
0466: .hasNext();) {
0467: PrimaryKeyElement lPrimaryKeyElement = (PrimaryKeyElement) lPrimaryKeyElementsIterator
0468: .next();
0469: if (lPrimaryKeyElement instanceof Attribute) {
0470: Attribute lAttribute = (Attribute) lPrimaryKeyElement;
0471: // Now create field
0472: String lMessageFieldName = suggestAttributeParameterName(lAttribute
0473: .getName());
0474: MessageField lMessageField = lMessage
0475: .findField(lMessageFieldName);
0476: if (lMessageField != null) {
0477: // Claim the field
0478: lUnclaimedFields.remove(lMessageField);
0479: // Verify data types
0480: DataType lExpectedDataType = lAttribute
0481: .getDataType();
0482: DataType lActualDataType = lMessageField
0483: .getDataType();
0484: if ((lExpectedDataType != null && lActualDataType == null)
0485: || (lExpectedDataType == null && lActualDataType != null)
0486: || (lExpectedDataType != null
0487: && lActualDataType != null && lActualDataType
0488: .equals(lExpectedDataType) == false))
0489: pViolations
0490: .add(new ConstraintViolationException(
0491: lMessageField,
0492: lMessageField.refMetaObject(),
0493: "The '"
0494: + lMessageFieldName
0495: + "' field in the '"
0496: + lMessageName
0497: + "' Message must be of the same type as corresponding Entity Attribute."));
0498: } else
0499: pViolations
0500: .add(new ConstraintViolationException(
0501: lMessage,
0502: lMessage.refMetaObject(),
0503: "A DuplicateCreateFailed Message must contain all Entity Primary Key fields for the asociated Entity. The '"
0504: + lMessageFieldName
0505: + "' Field not found."));
0506: } else if (lPrimaryKeyElement instanceof AssociationRole) {
0507: AssociationRole lRole = (AssociationRole) lPrimaryKeyElement;
0508: // Now create field
0509: String lMessageFieldName = suggestReferenceParameterName(lRole
0510: .getName());
0511: MessageField lMessageField = lMessage
0512: .findField(lMessageFieldName);
0513: if (lMessageField != null) {
0514: // Claim the field
0515: lUnclaimedFields.remove(lMessageField);
0516: // Verify data types
0517: DataType lExpectedDataType = lRole.getEntity() != null ? lRole
0518: .getEntity().getInstanceIdDataType()
0519: : null;
0520: DataType lActualDataType = lMessageField
0521: .getDataType();
0522: if ((lExpectedDataType != null && lActualDataType == null)
0523: || (lExpectedDataType == null && lActualDataType != null)
0524: || (lExpectedDataType != null
0525: && lActualDataType != null && lActualDataType
0526: .equals(lExpectedDataType) == false))
0527: pViolations
0528: .add(new ConstraintViolationException(
0529: lMessageField,
0530: lMessageField.refMetaObject(),
0531: "The '"
0532: + lMessageFieldName
0533: + "' field in the '"
0534: + lMessageName
0535: + "' Message must be of the instance identifier of the entity being referenced."));
0536: } else
0537: pViolations
0538: .add(new ConstraintViolationException(
0539: lMessage,
0540: lMessage.refMetaObject(),
0541: "A DuplicateCreateFailed Message must contain all Entity Primary Key fields for the asociated Entity. The '"
0542: + lMessageFieldName
0543: + "' Field not found."));
0544: }
0545: }
0546: // Create errors for all unclaimed fields
0547: for (Iterator lUnclaimedFieldsIterator = lUnclaimedFields
0548: .iterator(); lUnclaimedFieldsIterator.hasNext();) {
0549: MessageField lUnclaimedField = (MessageField) lUnclaimedFieldsIterator
0550: .next();
0551: pViolations
0552: .add(new ConstraintViolationException(
0553: lUnclaimedField,
0554: lUnclaimedField.refMetaObject(),
0555: "A DuplicateCreateFailed Message must contain only Primary Key fields for the asociated Entity. The '"
0556: + lUnclaimedField.getName()
0557: + "' Field is unexpected."));
0558: }
0559: }
0560:
0561: // This helper is doing everything necessary to rectify errors reported in verifyConstraints()
0562: void rectifyModel(Servicemodule pServicemodule, Entity pEntity,
0563: Collection pUnclaimedMessages) {
0564: // Check if we have a message and than just call ensurePresent
0565: String lMessageName = StylesheetImpl
0566: .getDuplicateCreateFailedMessageName(pEntity.getName());
0567: Message lMessage = pServicemodule.findMessage(lMessageName);
0568: if (lMessage != null)
0569: pUnclaimedMessages.remove(lMessage); // Claim the message
0570: // Now just call ensurePresent or absent depending on condition
0571: if (!pEntity.getPrimaryKeyElements().isEmpty())
0572: ensurePresent(pServicemodule, pEntity, pEntity.getName());
0573: else
0574: ensureAbsent(pServicemodule, pEntity.getName());
0575: }
0576:
0577: // This helper renames the message
0578: void ensureRenamedPresent(Servicemodule pServicemodule,
0579: Entity pEntity, String pOldEntityName, String pNewEntityName) {
0580: // Note that this method only deals with renaming and than calls the ensure present method
0581:
0582: // Work on the VersionMismatch message
0583: {
0584: String lOldMessageName = StylesheetImpl
0585: .getDuplicateCreateFailedMessageName(pOldEntityName);
0586: Message lOldMessage = pServicemodule
0587: .findMessage(lOldMessageName);
0588: String lNewMessageName = StylesheetImpl
0589: .getDuplicateCreateFailedMessageName(pNewEntityName);
0590: Message lNewMessage = pServicemodule
0591: .findMessage(lNewMessageName);
0592: // Be relaxed here - allow for all sorts of mishaps
0593: if (lOldMessage != null) {
0594: if (lNewMessage != null) {
0595: // New and old mesages are present - just delete the old one
0596: lOldMessage.refDelete();
0597: } else {
0598: // Old message is present - new one is not - rename
0599: lOldMessage.setName(lNewMessageName);
0600: }
0601: }
0602: }
0603:
0604: // Call the ensure present bit
0605: ensurePresent(pServicemodule, pEntity, pNewEntityName);
0606: }
0607:
0608: // This helper makes sure that the VersionMismatch message exist and uptodate
0609: void ensurePresent(Servicemodule pServicemodule, Entity pEntity,
0610: String pEntityName) {
0611: // Work on the VersionMismatch message
0612: {
0613: String lMessageName = StylesheetImpl
0614: .getDuplicateCreateFailedMessageName(pEntityName);
0615: String lMessageDescription = suggestDuplicateCreateFailedMessageDescription(pEntityName);
0616: String lMessageText = suggestDuplicateCreateFailedMessageText(
0617: pEntityName, pEntity.getPrimaryKeyElements());
0618: Message lMessage = pServicemodule.findMessage(lMessageName);
0619: if (lMessage == null) {
0620: lMessage = mModelAssistantImpl.mMessageClass
0621: .createMessage();
0622: lMessage.setName(lMessageName);
0623: lMessage.setServicemodule(pServicemodule);
0624: }
0625: lMessage.setType(MessageTypeEnum.ERROR);
0626: lMessage.setDescription(lMessageDescription);
0627: lMessage.setDefaultText(lMessageText);
0628: // This mesage has two fields - expected version id and actual version id
0629: Collection lMessageFields = lMessage.getFields();
0630: // Unable to use iterator over the live collection, because as we delete fields - they will
0631: // be deleted from the list causing problems with the iterator
0632: List lUnprocessedMessageFields = new ArrayList();
0633: lUnprocessedMessageFields.addAll(lMessageFields);
0634: for (Iterator lPrimaryKeyElementsIterator = pEntity
0635: .getPrimaryKeyElements().iterator(); lPrimaryKeyElementsIterator
0636: .hasNext();) {
0637: PrimaryKeyElement lPrimaryKeyElement = (PrimaryKeyElement) lPrimaryKeyElementsIterator
0638: .next();
0639: if (lPrimaryKeyElement instanceof Attribute) {
0640: Attribute lAttribute = (Attribute) lPrimaryKeyElement;
0641: // Now create field
0642: String lFieldName = suggestAttributeParameterName(lAttribute
0643: .getName());
0644: MessageField lMessageField = lMessage
0645: .findField(lFieldName);
0646: if (lMessageField == null) {
0647: lMessageField = mModelAssistantImpl.mMessageFieldClass
0648: .createMessageField();
0649: lMessageField.setName(lFieldName);
0650: lMessageFields.add(lMessageField);
0651: } else {
0652: lUnprocessedMessageFields.remove(lMessageField);
0653: }
0654: lMessageField
0655: .setDescription(suggestAttributeParameterDescription(lAttribute
0656: .getName()));
0657: lMessageField.setDataType(lAttribute.getDataType());
0658: } else if (lPrimaryKeyElement instanceof AssociationRole) {
0659: AssociationRole lRole = (AssociationRole) lPrimaryKeyElement;
0660: // Now create field
0661: String lFieldName = suggestReferenceParameterName(lRole
0662: .getName());
0663: MessageField lMessageField = lMessage
0664: .findField(lFieldName);
0665: if (lMessageField == null) {
0666: lMessageField = mModelAssistantImpl.mMessageFieldClass
0667: .createMessageField();
0668: lMessageField.setName(lFieldName);
0669: lMessageFields.add(lMessageField);
0670: } else {
0671: lUnprocessedMessageFields.remove(lMessageField);
0672: }
0673: lMessageField
0674: .setDescription(suggestReferenceParameterDescription(lRole
0675: .getName()));
0676: lMessageField.setDataType(lRole.getEntity()
0677: .getInstanceIdDataType());
0678: }
0679: }
0680: for (Iterator lUnprocessedMessageFieldsIterator = lUnprocessedMessageFields
0681: .iterator(); lUnprocessedMessageFieldsIterator
0682: .hasNext();) {
0683: MessageField lMessageField = (MessageField) lUnprocessedMessageFieldsIterator
0684: .next();
0685: lMessageField.refDelete();
0686: }
0687: }
0688: }
0689:
0690: // This helper makes sure that the message is absent
0691: void ensureAbsent(Servicemodule pServicemodule, String pEntityName) {
0692: // Work on the VersionMismatch message
0693: {
0694: Message lMessage = pServicemodule
0695: .findMessage(StylesheetImpl
0696: .getDuplicateCreateFailedMessageName(pEntityName));
0697: if (lMessage != null)
0698: lMessage.refDelete();
0699: }
0700: }
0701:
0702: // This helper renames the attribute
0703: void primaryKeyAttribute_EnsureRenamedPresent(
0704: Servicemodule pServicemodule, Entity pEntity,
0705: String pOldAttributeName, String pNewAttributeName,
0706: DataType pAttributeDataType) {
0707: String lMessagename = StylesheetImpl
0708: .getDuplicateCreateFailedMessageName(pEntity.getName());
0709: Message lMessage = pServicemodule
0710: .findMessage(StylesheetImpl
0711: .getDuplicateCreateFailedMessageName(pEntity
0712: .getName()));
0713: if (lMessage == null) {
0714: // No message is present yet we can create one here
0715: ensurePresent(pServicemodule, pEntity, pEntity.getName());
0716: if ((lMessage = pServicemodule.findMessage(StylesheetImpl
0717: .getDuplicateCreateFailedMessageName(pEntity
0718: .getName()))) == null)
0719: return;
0720: }
0721: // Note that this method only deals with renaming and than calls the ensure present method
0722: String lOldFieldName = suggestAttributeParameterName(pOldAttributeName);
0723: MessageField lOldField = lMessage.findField(lOldFieldName);
0724: String lNewFieldName = suggestAttributeParameterName(pNewAttributeName);
0725: MessageField lNewField = lMessage.findField(lNewFieldName);
0726: // Be relaxed here - allow for all sorts of mishaps
0727: if (lOldField != null) {
0728: if (lNewField != null) {
0729: // New and old fields are present - just delete the old one
0730: lOldField.refDelete();
0731: lMessage
0732: .setDefaultText(removeParameterText(
0733: lMessage.getDefaultText(),
0734: suggestAttributeParameterText(pOldAttributeName)));
0735: } else {
0736: // Old field is present - new one is not - rename
0737: lOldField.setName(lNewFieldName);
0738: lMessage
0739: .setDefaultText(replaceParameterText(
0740: lMessage.getDefaultText(),
0741: suggestAttributeParameterText(pOldAttributeName),
0742: suggestAttributeParameterText(pNewAttributeName)));
0743: }
0744: }
0745: // Call the ensure present bit
0746: primaryKeyAttribute_EnsurePresent(pServicemodule, pEntity,
0747: pNewAttributeName, pAttributeDataType);
0748: }
0749:
0750: // This helper makes sure that the field for the given primary key attribute is present is present in the details structure
0751: void primaryKeyAttribute_EnsurePresent(
0752: Servicemodule pServicemodule, Entity pEntity,
0753: String pAttributeName, DataType pAttributeDataType) {
0754: String lMessagename = StylesheetImpl
0755: .getDuplicateCreateFailedMessageName(pEntity.getName());
0756: Message lMessage = pServicemodule
0757: .findMessage(StylesheetImpl
0758: .getDuplicateCreateFailedMessageName(pEntity
0759: .getName()));
0760: if (lMessage == null) {
0761: // No message is present yet we can create one here
0762: ensurePresent(pServicemodule, pEntity, pEntity.getName());
0763: if ((lMessage = pServicemodule.findMessage(StylesheetImpl
0764: .getDuplicateCreateFailedMessageName(pEntity
0765: .getName()))) == null)
0766: return;
0767: }
0768: String lFieldName = suggestAttributeParameterName(pAttributeName);
0769: MessageField lMessageField = lMessage.findField(lFieldName);
0770: if (lMessageField == null) {
0771: // Create new message field
0772: lMessageField = mModelAssistantImpl.mMessageFieldClass
0773: .createMessageField();
0774: lMessageField.setName(lFieldName);
0775: lMessageField.setMessage(lMessage);
0776: // Modify the textof the message to include this field
0777: lMessage.setDefaultText(addParameterText(lMessage
0778: .getDefaultText(),
0779: suggestAttributeParameterText(pAttributeName)));
0780: }
0781: lMessageField
0782: .setDescription(suggestAttributeParameterDescription(pAttributeName));
0783: lMessageField.setDataType(pAttributeDataType);
0784: }
0785:
0786: // This helper makes sure that the version id attribute is absent in the details structure
0787: void primaryKeyAttribute_EnsureAbsent(Servicemodule pServicemodule,
0788: Entity pEntity, String pAttributeName) {
0789: Message lMessage = pServicemodule
0790: .findMessage(StylesheetImpl
0791: .getDuplicateCreateFailedMessageName(pEntity
0792: .getName()));
0793: if (lMessage == null)
0794: return; // No message yet
0795: String lFieldName = suggestAttributeParameterName(pAttributeName);
0796: MessageField lMessageField = lMessage.findField(lFieldName);
0797: if (lMessageField != null) {
0798: // Delete the field as well as the portion of the text related to this field
0799: lMessageField.refDelete();
0800: if (!lMessage.getFields().isEmpty()) {
0801: // Some more fields are left - we only need to edit the text
0802: lMessage.setDefaultText(removeParameterText(lMessage
0803: .getDefaultText(),
0804: suggestAttributeParameterText(pAttributeName)));
0805: } else {
0806: // If message has no more attributes - it can be deleted as a whole
0807: lMessage.refDelete();
0808: }
0809: } else {
0810: // If message has no more attributes - it can be deleted as a whole
0811: if (lMessage.getFields().isEmpty())
0812: lMessage.refDelete();
0813: }
0814: }
0815:
0816: // This helper renames the attribute
0817: void primaryKeyReference_EnsureRenamedPresent(
0818: Servicemodule pServicemodule, Entity pEntity,
0819: String pOldReferenceName, String pNewReferenceName,
0820: Entity pReferencedEntity) {
0821: String lMessagename = StylesheetImpl
0822: .getDuplicateCreateFailedMessageName(pEntity.getName());
0823: Message lMessage = pServicemodule
0824: .findMessage(StylesheetImpl
0825: .getDuplicateCreateFailedMessageName(pEntity
0826: .getName()));
0827: if (lMessage == null) {
0828: // No message is present yet we can create one here
0829: ensurePresent(pServicemodule, pEntity, pEntity.getName());
0830: if ((lMessage = pServicemodule.findMessage(StylesheetImpl
0831: .getDuplicateCreateFailedMessageName(pEntity
0832: .getName()))) == null)
0833: return;
0834: }
0835: // Note that this method only deals with renaming and than calls the ensure present method
0836: String lOldFieldName = suggestReferenceParameterName(pOldReferenceName);
0837: MessageField lOldField = lMessage.findField(lOldFieldName);
0838: String lNewFieldName = suggestReferenceParameterName(pNewReferenceName);
0839: MessageField lNewField = lMessage.findField(lNewFieldName);
0840: // Be relaxed here - allow for all sorts of mishaps
0841: if (lOldField != null) {
0842: if (lNewField != null) {
0843: // New and old fields are present - just delete the old one
0844: lOldField.refDelete();
0845: lMessage
0846: .setDefaultText(removeParameterText(
0847: lMessage.getDefaultText(),
0848: suggestReferenceParameterText(pOldReferenceName)));
0849: } else {
0850: // Old field is present - new one is not - rename
0851: lOldField.setName(lNewFieldName);
0852: lMessage
0853: .setDefaultText(replaceParameterText(
0854: lMessage.getDefaultText(),
0855: suggestReferenceParameterText(pOldReferenceName),
0856: suggestReferenceParameterText(pNewReferenceName)));
0857: }
0858: }
0859: // Call the ensure present bit
0860: primaryKeyReference_EnsurePresent(pServicemodule, pEntity,
0861: pNewReferenceName, pReferencedEntity);
0862: }
0863:
0864: // This helper makes sure that the field for the given primary key attribute is present is present in the details structure
0865: void primaryKeyReference_EnsurePresent(
0866: Servicemodule pServicemodule, Entity pEntity,
0867: String pReferenceName, Entity pReferencedEntity) {
0868: String lMessagename = StylesheetImpl
0869: .getDuplicateCreateFailedMessageName(pEntity.getName());
0870: Message lMessage = pServicemodule
0871: .findMessage(StylesheetImpl
0872: .getDuplicateCreateFailedMessageName(pEntity
0873: .getName()));
0874: if (lMessage == null) {
0875: // No message is present yet we can create one here
0876: ensurePresent(pServicemodule, pEntity, pEntity.getName());
0877: if ((lMessage = pServicemodule.findMessage(StylesheetImpl
0878: .getDuplicateCreateFailedMessageName(pEntity
0879: .getName()))) == null)
0880: return;
0881: }
0882: String lFieldName = suggestReferenceParameterName(pReferenceName);
0883: MessageField lMessageField = lMessage.findField(lFieldName);
0884: if (lMessageField == null) {
0885: // Create new message field
0886: lMessageField = mModelAssistantImpl.mMessageFieldClass
0887: .createMessageField();
0888: lMessageField.setName(lFieldName);
0889: lMessageField.setMessage(lMessage);
0890: // Modify the textof the message to include this field
0891: lMessage.setDefaultText(addParameterText(lMessage
0892: .getDefaultText(),
0893: suggestReferenceParameterText(pReferenceName)));
0894: }
0895: lMessageField
0896: .setDescription(suggestReferenceParameterDescription(pReferenceName));
0897: lMessageField
0898: .setDataType(pReferencedEntity != null ? pReferencedEntity
0899: .getInstanceIdDataType()
0900: : null);
0901: }
0902:
0903: // This helper makes sure that the version id attribute is absent in the details structure
0904: void primaryKeyReference_EnsureAbsent(Servicemodule pServicemodule,
0905: Entity pEntity, String pReferenceName) {
0906: Message lMessage = pServicemodule
0907: .findMessage(StylesheetImpl
0908: .getDuplicateCreateFailedMessageName(pEntity
0909: .getName()));
0910: if (lMessage == null)
0911: return; // No message yet
0912: String lFieldName = suggestReferenceParameterName(pReferenceName);
0913: MessageField lMessageField = lMessage.findField(lFieldName);
0914: if (lMessageField != null) {
0915: // Delete the field as well as the portion of the text related to this field
0916: lMessageField.refDelete();
0917: if (!lMessage.getFields().isEmpty()) {
0918: // Some more fields are left - we only need to edit the text
0919: lMessage.setDefaultText(removeParameterText(lMessage
0920: .getDefaultText(),
0921: suggestReferenceParameterText(pReferenceName)));
0922: } else {
0923: // If message has no more attributes - it can be deleted as a whole
0924: lMessage.refDelete();
0925: }
0926: } else {
0927: // If message has no more attributes - it can be deleted as a whole
0928: if (lMessage.getFields().isEmpty())
0929: lMessage.refDelete();
0930: }
0931: }
0932:
0933: // Helper. Returns the parameter name
0934: private static String suggestAttributeParameterName(
0935: String pAttributeName) {
0936: // Use normalised name here
0937: StringBuffer lParameterName = new StringBuffer();
0938: lParameterName.append("Proposed");
0939: lParameterName.append(StringUtils.suggestName(pAttributeName,
0940: true, false));
0941: return lParameterName.toString();
0942: }
0943:
0944: // Helper. Returns the parameter description
0945: private static String suggestAttributeParameterDescription(
0946: String pAttributeName) {
0947: StringBuffer lDescription = new StringBuffer();
0948: lDescription.append("Contains the proposed value for the '");
0949: lDescription.append(pAttributeName);
0950: lDescription.append("' primary key attribute.");
0951: return lDescription.toString();
0952: }
0953:
0954: // Helper. Returns the portion of the message text which is there because of the parameter
0955: private static String suggestAttributeParameterText(
0956: String pAttributeName) {
0957: StringBuffer lMessageText = new StringBuffer();
0958: lMessageText.append(pAttributeName);
0959: lMessageText.append(" = \"${Fields.");
0960: lMessageText
0961: .append(suggestAttributeParameterName(pAttributeName));
0962: lMessageText.append("}\"");
0963: return lMessageText.toString();
0964: }
0965:
0966: // Helper. Returns the parameter name
0967: private static String suggestReferenceParameterName(
0968: String pAssociationRoleName) {
0969: // Use normalised name here
0970: StringBuffer lParameterName = new StringBuffer();
0971: lParameterName.append("Proposed");
0972: lParameterName.append(StringUtils.suggestName(
0973: pAssociationRoleName, true, false));
0974: lParameterName.append("InstanceId");
0975: return lParameterName.toString();
0976: }
0977:
0978: // Helper. Returns the parameter description
0979: private static String suggestReferenceParameterDescription(
0980: String pAssociationRoleName) {
0981: StringBuffer lDescription = new StringBuffer();
0982: lDescription.append("Contains the proposed value for the '");
0983: lDescription.append(pAssociationRoleName);
0984: lDescription.append("' primary key association.");
0985: return lDescription.toString();
0986: }
0987:
0988: // Helper. Returns the portion of the message text which is there because of the parameter
0989: private static String suggestReferenceParameterText(
0990: String pAssociationRoleName) {
0991: StringBuffer lMessageText = new StringBuffer();
0992: lMessageText.append(pAssociationRoleName);
0993: lMessageText.append("InstanceId");
0994: lMessageText.append(" = \"${Fields.");
0995: lMessageText
0996: .append(suggestReferenceParameterName(pAssociationRoleName));
0997: lMessageText.append("}\"");
0998: return lMessageText.toString();
0999: }
1000:
1001: // Helper. Returns the message description
1002: private static String suggestDuplicateCreateFailedMessageDescription(
1003: String pEntityName) {
1004: // Use name 'as is' here
1005: StringBuffer lMessageDescription = new StringBuffer();
1006: lMessageDescription
1007: .append("This error indicates that create operation has failed because ");
1008: lMessageDescription.append(pEntityName);
1009: lMessageDescription
1010: .append(" entity with the proposed value of the primary key exists already.");
1011: return lMessageDescription.toString();
1012: }
1013:
1014: // Helper. Returns the message text
1015: private static String suggestDuplicateCreateFailedMessageText(
1016: String pEntityName, Collection pPrimaryKeyElements) {
1017: // Iterate through primary key elements and create default message and input fields
1018: StringBuffer lMessageText = new StringBuffer();
1019: lMessageText.append(pEntityName);
1020: lMessageText
1021: .append(" already exists. Primary key can not be duplicated: ");
1022: for (Iterator lPrimaryKeyElementsIterator = pPrimaryKeyElements
1023: .iterator(); lPrimaryKeyElementsIterator.hasNext();) {
1024: PrimaryKeyElement lPrimaryKeyElement = (PrimaryKeyElement) lPrimaryKeyElementsIterator
1025: .next();
1026: if (lPrimaryKeyElement instanceof Attribute) {
1027: Attribute lAttribute = (Attribute) lPrimaryKeyElement;
1028: // Append text to the message
1029: lMessageText
1030: .append(suggestAttributeParameterText(lAttribute
1031: .getName()));
1032: } else if (lPrimaryKeyElement instanceof AssociationRole) {
1033: AssociationRole lRole = (AssociationRole) lPrimaryKeyElement;
1034: // Append text to the message
1035: lMessageText.append(suggestReferenceParameterText(lRole
1036: .getName()));
1037: }
1038: if (lPrimaryKeyElementsIterator.hasNext())
1039: lMessageText.append(" ,");
1040: }
1041: return lMessageText.toString();
1042: }
1043:
1044: // This helper removes the parameter text from the message text and returns the edited text
1045: // WARNING: This code is very dependent on how message is actually constructed
1046: private static String removeParameterText(String pMessageText,
1047: String pParameterText) {
1048: int lParameterTextPos = pMessageText.indexOf(pParameterText);
1049: if (lParameterTextPos <= 0)
1050: return pMessageText; // This text is not present any way
1051: int lParameterTextLength = pParameterText.length();
1052: StringBuffer lEditedText = new StringBuffer();
1053: // We may or may not need to remove preceeding comma
1054: boolean lHasCommaPrior = (pMessageText.indexOf(" ,",
1055: lParameterTextPos - 2) == 0);
1056: if (lHasCommaPrior) {
1057: // We have comma prior to this parameter - it always needs removal
1058: lEditedText.append(pMessageText.substring(0,
1059: lParameterTextPos - 2));
1060: lEditedText.append(pMessageText.substring(lParameterTextPos
1061: + lParameterTextLength));
1062: } else {
1063: // We do not have comma prior to this parameter
1064: lEditedText.append(pMessageText.substring(0,
1065: lParameterTextPos));
1066: // If there was a comma after - it has to be removed - this is because there was no comma prior to this parameter
1067: boolean lHasCommaAfter = (pMessageText.indexOf(" ,",
1068: lParameterTextPos + lParameterTextLength) == 0);
1069: if (lHasCommaAfter)
1070: lEditedText.append(pMessageText
1071: .substring(lParameterTextPos
1072: + lParameterTextLength + 2));
1073: else
1074: lEditedText.append(pMessageText
1075: .substring(lParameterTextPos
1076: + lParameterTextLength));
1077: }
1078: return lEditedText.toString();
1079: }
1080:
1081: // This helper adds the parameter text to the message text and returns the edited text
1082: // WARNING: This code is very dependent on how message is actually constructed
1083: private static String addParameterText(String pMessageText,
1084: String pParameterText) {
1085: int lParameterTextPos = pMessageText.indexOf(pParameterText);
1086: if (lParameterTextPos > 0)
1087: return pMessageText; // This parameter's text is already there
1088: StringBuffer lEditedText = new StringBuffer(pMessageText);
1089: // We may or may not need to append preceeding comma
1090: if (pMessageText.indexOf("${Fields.") > 0)
1091: lEditedText.append(" ,"); // Has other fields - append comma
1092: lEditedText.append(pParameterText);
1093: return lEditedText.toString();
1094: }
1095:
1096: // This helper replaces the parameter text in the message and returns the edited text
1097: // WARNING: This code is very dependent on how message is actually constructed
1098: private static String replaceParameterText(String pMessageText,
1099: String pOldParameterText, String pNewParameterText) {
1100: int lParameterTextPos = pMessageText.indexOf(pOldParameterText);
1101: if (lParameterTextPos <= 0)
1102: return addParameterText(pMessageText, pNewParameterText); // Old text is not present - we could just add the new one
1103: StringBuffer lEditedText = new StringBuffer();
1104: lEditedText
1105: .append(pMessageText.substring(0, lParameterTextPos));
1106: lEditedText.append(pNewParameterText);
1107: lEditedText.append(pMessageText.substring(lParameterTextPos
1108: + pOldParameterText.length()));
1109: return lEditedText.toString();
1110: }
1111: }
|