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.domains.enterprisemodel.impl;
016:
017: import java.util.ArrayList;
018: import java.util.Arrays;
019:
020: import javax.naming.Context;
021: import javax.naming.InitialContext;
022: import javax.naming.NamingException;
023:
024: import com.metaboss.enterprise.bo.BOException;
025: import com.metaboss.enterprise.bo.BOInvalidOperationForReadOnlyObjectException;
026: import com.metaboss.enterprise.bo.BONamingAndDirectoryServiceInvocationException;
027: import com.metaboss.enterprise.bo.BOPersistenceServiceInvocationException;
028: import com.metaboss.enterprise.bo.BOUnexpectedProgramConditionException;
029: import com.metaboss.enterprise.ps.PSException;
030: import com.metaboss.sdlctools.domains.enterprisemodel.BOAssociation;
031: import com.metaboss.sdlctools.domains.enterprisemodel.BOAssociationRole;
032: import com.metaboss.sdlctools.domains.enterprisemodel.BOEntity;
033: import com.metaboss.sdlctools.domains.enterprisemodel.BOEntityAssociationRoleList;
034: import com.metaboss.sdlctools.domains.enterprisemodel.storage.PSEntity;
035: import com.metaboss.sdlctools.types.enterprisemodel.AssociationRoleStereotype;
036: import com.oldboss.framework.bo.impl.BOObjectImpl;
037:
038: public class BOEntityAssociationRoleListImpl extends BOObjectImpl
039: implements BOEntityAssociationRoleList {
040: private BOMetaBossDomainImpl mMetaBossDomainImpl = null;
041: private BOEntity mEntity = null;
042: private BOAssociationRole[] mDetails = null;
043:
044: /* Instance creator */
045: public static BOEntityAssociationRoleList createInstanceForExisting(
046: BOMetaBossDomainImpl pMetaBossDomainImpl, BOEntity pEntity)
047: throws BOException {
048: BOEntityAssociationRoleListImpl lImpl = (BOEntityAssociationRoleListImpl) pMetaBossDomainImpl
049: .retrieveExistingBOInstance(
050: BOEntityAssociationRoleList.class, pEntity
051: .getRef());
052: if (lImpl != null)
053: return lImpl;
054: lImpl = new BOEntityAssociationRoleListImpl();
055: lImpl.mMetaBossDomainImpl = pMetaBossDomainImpl;
056: lImpl.mEntity = pEntity;
057: lImpl.setupForExisting();
058: pMetaBossDomainImpl.saveNewBOInstance(
059: BOEntityAssociationRoleList.class, pEntity.getRef(),
060: lImpl);
061: return lImpl;
062: }
063:
064: /* Private constructor restricts instance creation from outside */
065: private BOEntityAssociationRoleListImpl() throws BOException {
066: }
067:
068: /** Retrieves an association role by it's reference or null if none exists */
069: public BOAssociationRole getAssociationRole(
070: String pAssociationRoleRef) throws BOException {
071: loadDetailsIfNecessary();
072: for (int i = 0; i < mDetails.length; i++) {
073: if (mDetails[i].getRef().equals(pAssociationRoleRef))
074: return mDetails[i];
075: }
076: return null;
077: }
078:
079: /* return true if this entity has specified association role object
080: * This excludes any roles possibly defined in supertypes (if this entity is
081: * a subtype) */
082: public boolean contains(BOAssociationRole pAssociationRole)
083: throws BOException {
084: loadDetailsIfNecessary();
085: for (int i = 0; i < mDetails.length; i++) {
086: if (mDetails[i].equals(pAssociationRole))
087: return true;
088: }
089: return false;
090: }
091:
092: /** Retrieves all roles tied up to this entity */
093: public BOAssociationRole[] getAllAssociationRoles()
094: throws BOException {
095: loadDetailsIfNecessary();
096: return mDetails;
097: }
098:
099: /* Retrieves all association roles defined in this entity, including any roles
100: * defined in supertypes */
101: public BOAssociationRole[] getCombinedAssociationRoles()
102: throws BOException {
103: loadDetailsIfNecessary();
104: BOEntity lSupertypeEntity = mEntity.getSupertype();
105: if (lSupertypeEntity == null)
106: return getAllAssociationRoles();
107: ArrayList lAssociationRoles = new ArrayList();
108: lAssociationRoles.addAll(Arrays.asList(mDetails));
109: lAssociationRoles.addAll(Arrays.asList(lSupertypeEntity
110: .getAssociationRoles().getCombinedAssociationRoles()));
111: return (BOAssociationRole[]) lAssociationRoles
112: .toArray(new BOAssociationRole[lAssociationRoles.size()]);
113: }
114:
115: /* Retrieves optionsl association role with the owner - entity which has containment association with this entity */
116: public BOAssociationRole getOwnerAssociationRole()
117: throws BOException {
118: BOAssociationRole lOwnerAssociationRole = null;
119: BOAssociationRole[] lCombinedAssociationRoles = getCombinedAssociationRoles();
120: for (int i = 0; i < lCombinedAssociationRoles.length; i++) {
121: BOAssociationRole lAssociationRole = lCombinedAssociationRoles[i];
122: BOAssociation lAssociation = lAssociationRole
123: .getAssociation();
124: BOAssociationRole lOtherRole = lAssociation.getRoleA();
125: if (lOtherRole.getName().equals(lAssociationRole.getName()))
126: lOtherRole = lAssociation.getRoleB();
127: if (lOtherRole.getStereotype().equals(
128: AssociationRoleStereotype.COMPOSITION)) {
129: if (lOwnerAssociationRole != null)
130: throw new BOUnexpectedProgramConditionException(
131: "It appears that entity "
132: + mEntity.getRef()
133: + " is declared as having more than one owner. This is not supported");
134: if (!lAssociationRole
135: .getCardinality()
136: .equals(
137: com.metaboss.sdlctools.types.enterprisemodel.AssociationRoleCardinality.ONE))
138: throw new BOUnexpectedProgramConditionException(
139: "It appears that entity "
140: + mEntity.getRef()
141: + " has owner entity with association role cardinality not 'one and only one'. This is not supported");
142: lOwnerAssociationRole = lAssociationRole;
143: }
144: }
145: return lOwnerAssociationRole;
146: }
147:
148: /* Removes required association role form the list. Returns true if role has been
149: * found and removed, false otherwise. Note that this is
150: * the helper mwthod not visible through interfaces. BOAssociationRole.setEntity()
151: * method should be used to change entities (it calls this method internally) */
152: void removeAssociationRole(BOAssociationRole pRole)
153: throws BOException {
154: if (!isBeingEdited())
155: throw new BOInvalidOperationForReadOnlyObjectException();
156: boolean lFoundMatch = false;
157: ArrayList lNewDetails = new ArrayList();
158: for (int i = 0; i < mDetails.length; i++) {
159: BOAssociationRole lRole = mDetails[i];
160: if (lRole.equals(pRole))
161: lFoundMatch = true;
162: else
163: lNewDetails.add(lRole);
164: }
165: if (!lFoundMatch)
166: throw new BOUnexpectedProgramConditionException(
167: "AssociationRole is not part of the entity associations. AssociationRoleRef: "
168: + pRole.getRef() + " EntityRef: "
169: + mEntity.getRef());
170: mDetails = (BOAssociationRole[]) lNewDetails
171: .toArray(new BOAssociationRole[lNewDetails.size()]);
172: }
173:
174: /* Adds required association role to the the list.
175: * Note that this is the helper mwthod not visible through interfaces.
176: * BOAssociationRole.setEntity() method should be used to change entities
177: * (it calls this method internally) */
178: void addAssociationRole(BOAssociationRole pRole) throws BOException {
179: if (!isBeingEdited())
180: throw new BOInvalidOperationForReadOnlyObjectException();
181: BOAssociationRole[] lCombinedAssociationRoles = getCombinedAssociationRoles();
182: // Check if this role is not present and role with the same name is not present
183: for (int i = 0; i < lCombinedAssociationRoles.length; i++) {
184: if (lCombinedAssociationRoles[i].equals(pRole))
185: throw new BOUnexpectedProgramConditionException(
186: "Attempt to add AssociationRole for the second time.");
187: if (lCombinedAssociationRoles[i].getName().equals(
188: pRole.getName()))
189: throw new BOUnexpectedProgramConditionException(
190: "Attempt to add AssociationRole with duplicate name.");
191: }
192: // Passed all checks, add the role
193: ArrayList lNewDetails = new ArrayList(Arrays.asList(mDetails));
194: lNewDetails.add(pRole);
195: mDetails = (BOAssociationRole[]) lNewDetails
196: .toArray(new BOAssociationRole[lNewDetails.size()]);
197: }
198:
199: private void loadDetailsIfNecessary() throws BOException {
200: if (mDetails == null) {
201: try {
202: // Get the instance of the enterprise ps home via jndi
203: Context ctx = new InitialContext();
204: PSEntity lPs = (PSEntity) ctx
205: .lookup(PSEntity.COMPONENT_URL);
206:
207: String[] lAssociationRoleRefs = lPs
208: .getAssociationRoleRefs(mEntity.getRef());
209: if (lAssociationRoleRefs == null
210: || lAssociationRoleRefs.length == 0) {
211: mDetails = new BOAssociationRole[0];
212: } else {
213: mDetails = new BOAssociationRole[lAssociationRoleRefs.length];
214: for (int i = 0; i < lAssociationRoleRefs.length; i++)
215: mDetails[i] = BOAssociationRoleImpl
216: .createInstanceForExisting(
217: mMetaBossDomainImpl,
218: lAssociationRoleRefs[i]);
219: }
220: } catch (NamingException e) {
221: throw new BONamingAndDirectoryServiceInvocationException(
222: "", e);
223: } catch (PSException e) {
224: throw new BOPersistenceServiceInvocationException("", e);
225: }
226: }
227: }
228:
229: protected void onBeginEdit() throws BOException {
230: // Fully load the object
231: loadDetailsIfNecessary();
232: }
233:
234: /* Encapsulates commit action by this object */
235: protected void onCommitUpdate() throws BOException {
236: try {
237: // Get the instance of the enterprise ps home via jndi
238: Context lCtx = new InitialContext();
239: PSEntity lPs = (PSEntity) lCtx
240: .lookup(PSEntity.COMPONENT_URL);
241: String[] lAssociationRoleRefs = new String[mDetails.length];
242: for (int i = 0; i < mDetails.length; i++)
243: lAssociationRoleRefs[i] = mDetails[i].getRef();
244: lPs.updateAssociationRoleRefs(mEntity.getRef(),
245: lAssociationRoleRefs);
246: } catch (NamingException e) {
247: throw new BONamingAndDirectoryServiceInvocationException(
248: "", e);
249: } catch (PSException e) {
250: throw new BOPersistenceServiceInvocationException("", e);
251: }
252: }
253: }
|