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 javax.naming.Context;
018: import javax.naming.InitialContext;
019: import javax.naming.NamingException;
020:
021: import com.metaboss.enterprise.bo.BOException;
022: import com.metaboss.enterprise.bo.BOIllegalArgumentException;
023: import com.metaboss.enterprise.bo.BOInvalidOperationForObjectException;
024: import com.metaboss.enterprise.bo.BOInvalidOperationForReadOnlyObjectException;
025: import com.metaboss.enterprise.bo.BONamingAndDirectoryServiceInvocationException;
026: import com.metaboss.enterprise.bo.BOPersistenceServiceInvocationException;
027: import com.metaboss.enterprise.ps.PSException;
028: import com.metaboss.sdlctools.domains.enterprisemodel.BODatatype;
029: import com.metaboss.sdlctools.domains.enterprisemodel.BODomain;
030: import com.metaboss.sdlctools.domains.enterprisemodel.BOEntity;
031: import com.metaboss.sdlctools.domains.enterprisemodel.BOEntityAssociationRoleList;
032: import com.metaboss.sdlctools.domains.enterprisemodel.BOEntityAttributeList;
033: import com.metaboss.sdlctools.domains.enterprisemodel.BOEntityConstraintList;
034: import com.metaboss.sdlctools.domains.enterprisemodel.BOEntityPrimaryKeyElementList;
035: import com.metaboss.sdlctools.domains.enterprisemodel.BOEntitySelectorList;
036: import com.metaboss.sdlctools.domains.enterprisemodel.BOEntityStateList;
037: import com.metaboss.sdlctools.domains.enterprisemodel.BOEntitySubtypeList;
038: import com.metaboss.sdlctools.domains.enterprisemodel.storage.PSEntity;
039: import com.metaboss.sdlctools.domains.enterprisemodel.storage.STEntity;
040: import com.oldboss.framework.bo.BOTransaction;
041: import com.oldboss.framework.bo.impl.BOObjectImpl;
042:
043: public class BOEntityImpl extends BOObjectImpl implements BOEntity {
044: private BOMetaBossDomainImpl mMetaBossDomainImpl = null;
045: private String mEntityRef = null;
046: private STEntity mDetails = null;
047: private BOEntityAttributeList mAttributeList = null;
048: private BOEntitySubtypeList mSubtypeList = null;
049:
050: /* Instance creator */
051: public static BOEntity createInstanceForExisting(
052: BOMetaBossDomainImpl pMetaBossDomainImpl, String pEntityRef)
053: throws BOException {
054: // See if we have this object in cache
055: BOEntityImpl lImpl = (BOEntityImpl) pMetaBossDomainImpl
056: .retrieveExistingBOInstance(BOEntity.class, pEntityRef);
057: if (lImpl != null)
058: return lImpl;
059: // We do not have this object in cache - create a new instance, save it to cache and return it
060: lImpl = new BOEntityImpl();
061: lImpl.mMetaBossDomainImpl = pMetaBossDomainImpl;
062: lImpl.mEntityRef = pEntityRef;
063: lImpl.setupForExisting();
064: pMetaBossDomainImpl.saveNewBOInstance(BOEntity.class,
065: pEntityRef, lImpl);
066: return lImpl;
067: }
068:
069: /* Instance creator */
070: public static BOEntity createInstanceForNew(
071: BOTransaction pTransaction,
072: BOMetaBossDomainImpl pMetaBossDomainImpl, String pEntityRef)
073: throws BOException {
074: // See if we have this object in cache already
075: BOEntityImpl lImpl = (BOEntityImpl) pMetaBossDomainImpl
076: .retrieveExistingBOInstance(BOEntity.class, pEntityRef);
077: if (lImpl != null)
078: throw new BOIllegalArgumentException(
079: "Entity already exists. EntityRef: " + pEntityRef);
080: lImpl = new BOEntityImpl();
081: lImpl.mMetaBossDomainImpl = pMetaBossDomainImpl;
082: lImpl.mEntityRef = pEntityRef;
083: lImpl.mDetails = new STEntity();
084: lImpl.mDetails.EntityRef = pEntityRef;
085: lImpl.mAttributeList = BOEntityAttributeListImpl
086: .createInstanceForNew(pTransaction,
087: pMetaBossDomainImpl, lImpl);
088: lImpl.mSubtypeList = BOEntitySubtypeListImpl
089: .createInstanceForNew(pTransaction,
090: pMetaBossDomainImpl, lImpl);
091: lImpl.setupForNew(pTransaction);
092: pMetaBossDomainImpl.saveNewBOInstance(BOEntity.class,
093: pEntityRef, lImpl);
094: return lImpl;
095: }
096:
097: /* Private constructor restricts instance creation from outside */
098: private BOEntityImpl() throws BOException {
099: }
100:
101: /* Retrieves unique reference */
102: public String getRef() throws BOException {
103: return mEntityRef;
104: }
105:
106: /* Overriden to provide check reference equality */
107: public boolean equals(Object pOther) {
108: if (pOther == null)
109: return false;
110: if (!(pOther instanceof BOEntityImpl))
111: return false;
112: return ((BOEntityImpl) pOther).mEntityRef.equals(mEntityRef);
113: }
114:
115: /* Retrieves entity name */
116: public String getName() throws BOException {
117: String lEntityName = getRef();
118: if (lEntityName.lastIndexOf(".") >= 0)
119: lEntityName = lEntityName.substring(lEntityName
120: .lastIndexOf(".") + 1);
121: return lEntityName;
122: }
123:
124: /* Retrieves the domain which owns this entity.*/
125: public BODomain getDomain() throws BOException {
126: String lEntityRef = getRef();
127: if (lEntityRef.lastIndexOf(".") >= 0) {
128: String lDomainRef = lEntityRef.substring(0, lEntityRef
129: .lastIndexOf("."));
130: return BODomainImpl.createInstanceForExisting(
131: mMetaBossDomainImpl, lDomainRef);
132: }
133: throw new BOException(
134: "Invalid entity reference - missing enterprise and domain components. (EntityRef:"
135: + getRef() + ")");
136: }
137:
138: /* Retrieves description */
139: public String getDescription() throws BOException {
140: loadDetailsIfNecessary();
141: return mDetails.Description;
142: }
143:
144: /* Changes description */
145: public void setDescription(String pDescription) throws BOException {
146: if (!isBeingEdited())
147: throw new BOInvalidOperationForReadOnlyObjectException();
148: mDetails.Description = pDescription;
149: }
150:
151: /* Retrieves plural entity name */
152: public String getPluralName() throws BOException {
153: loadDetailsIfNecessary();
154: return mDetails.PluralName;
155: }
156:
157: /* Changes plural entity name. It is used anywhere there is a need to refer to collection of entities of this type */
158: public void setPluralName(String pPluralName) throws BOException {
159: if (!isBeingEdited())
160: throw new BOInvalidOperationForReadOnlyObjectException();
161: mDetails.PluralName = pPluralName;
162: }
163:
164: /* Retrieves entity stereotype */
165: public com.metaboss.sdlctools.types.enterprisemodel.EntityStereotype getStereotype()
166: throws BOException {
167: loadDetailsIfNecessary();
168: return mDetails.Stereotype;
169: }
170:
171: /* Changes entity stereotype */
172: public void setStereotype(
173: com.metaboss.sdlctools.types.enterprisemodel.EntityStereotype pStereotype)
174: throws BOException {
175: if (!isBeingEdited())
176: throw new BOInvalidOperationForReadOnlyObjectException();
177: mDetails.Stereotype = pStereotype;
178: }
179:
180: /* Returns the value of abstract flag. Abstract means that the entity instance can never be
181: * created. It can only be used for specialisation */
182: public boolean isAbstract() throws BOException {
183: loadDetailsIfNecessary();
184: return mDetails.IsAbstract;
185: }
186:
187: /** Changes the value of abstract flag. */
188: public void setIsAbstract(boolean pIsAbstract) throws BOException {
189: if (!isBeingEdited())
190: throw new BOInvalidOperationForReadOnlyObjectException();
191: mDetails.IsAbstract = pIsAbstract;
192: }
193:
194: /* Returns the value of final flag. Final means that the entity can never be extendded.
195: * It itself, however, can be a subtype of some other entity */
196: public boolean isFinal() throws BOException {
197: loadDetailsIfNecessary();
198: return mDetails.IsFinal;
199: }
200:
201: /** Changes the value of final flag. */
202: public void setIsFinal(boolean pIsFinal) throws BOException {
203: if (!isBeingEdited())
204: throw new BOInvalidOperationForReadOnlyObjectException();
205: // Check constraints
206: if (pIsFinal == true && getSubtypes().size() > 0)
207: throw new BOInvalidOperationForObjectException(
208: "Entuty has subtypes and can not be made final. EntityRef: "
209: + getRef());
210: mDetails.IsFinal = pIsFinal;
211: }
212:
213: /** Returns the entity, which is a supertype to this entity or null if
214: * this entity does not have a supertype (does not extend anything) */
215: public BOEntity getSupertype() throws BOException {
216: loadDetailsIfNecessary();
217: if (mDetails.SupertypeEntityRef == null
218: || mDetails.SupertypeEntityRef.length() == 0)
219: return null;
220: return BOEntityImpl.createInstanceForExisting(
221: mMetaBossDomainImpl, mDetails.SupertypeEntityRef);
222: }
223:
224: /** Changes the value of supertype */
225: public void setSupertype(BOEntity pSupertype) throws BOException {
226: if (!isBeingEdited())
227: throw new BOInvalidOperationForReadOnlyObjectException();
228: if (pSupertype != null) {
229: if (pSupertype.equals(this ))
230: throw new BOIllegalArgumentException(
231: "Attempt to set entity as it's own supertype. EntityRef: "
232: + mEntityRef);
233: // Check if the entity suggested as supertpe is not anywhere on our subtypes list
234: BOEntity[] lCombinedSubtypes = getSubtypes()
235: .getCombinedSubtypes();
236: for (int i = 0; i < lCombinedSubtypes.length; i++) {
237: if (lCombinedSubtypes[i].equals(pSupertype))
238: throw new BOIllegalArgumentException(
239: "Setting the "
240: + pSupertype.getRef()
241: + " entity as a supertype of the "
242: + mEntityRef
243: + " will create a circularity in the hieirarchy tree. Such circularity is not allowed.");
244: }
245: mDetails.SupertypeEntityRef = pSupertype.getRef();
246: } else
247: mDetails.SupertypeEntityRef = null;
248: }
249:
250: /* Returns the list of entities, for which this entity is direct supertype.
251: * This list may be empty if this entity does not have any subtypes */
252: public BOEntitySubtypeList getSubtypes() throws BOException {
253: if (mSubtypeList == null) {
254: loadDetailsIfNecessary();
255: mSubtypeList = BOEntitySubtypeListImpl
256: .createInstanceForExisting(mMetaBossDomainImpl,
257: this );
258: }
259: return mSubtypeList;
260: }
261:
262: /* Retrieves list of elements comprising primary key. */
263: public BOEntityPrimaryKeyElementList getPrimaryKeyElements()
264: throws BOException {
265: loadDetailsIfNecessary();
266: return BOEntityPrimaryKeyElementListImpl
267: .createInstanceForExisting(mMetaBossDomainImpl, this );
268: }
269:
270: /* Retrieves list of attributes within an entity */
271: public BOEntityAttributeList getAttributes() throws BOException {
272: if (mAttributeList == null) {
273: loadDetailsIfNecessary();
274: mAttributeList = BOEntityAttributeListImpl
275: .createInstanceForExisting(mMetaBossDomainImpl,
276: this );
277: }
278: return mAttributeList;
279: }
280:
281: /* Retrieves list of selectors within an entity */
282: public BOEntitySelectorList getSelectors() throws BOException {
283: loadDetailsIfNecessary();
284: return BOEntitySelectorListImpl.createInstanceForExisting(
285: mMetaBossDomainImpl, this );
286: }
287:
288: /* Retrieves list of selectors within an entity */
289: public BOEntityConstraintList getConstraints() throws BOException {
290: loadDetailsIfNecessary();
291: return BOEntityConstraintListImpl.createInstanceForExisting(
292: mMetaBossDomainImpl, this );
293: }
294:
295: /* Retrieves list of relationships within an entity */
296: public BOEntityAssociationRoleList getAssociationRoles()
297: throws BOException {
298: loadDetailsIfNecessary();
299: return BOEntityAssociationRoleListImpl
300: .createInstanceForExisting(mMetaBossDomainImpl, this );
301: }
302:
303: /* Retrieves list of states this entity can be in */
304: public BOEntityStateList getStates() throws BOException {
305: loadDetailsIfNecessary();
306: return BOEntityStateListImpl.createInstanceForExisting(
307: mMetaBossDomainImpl, this );
308: }
309:
310: /* Retrieves datatype used for instance id */
311: public BODatatype getInstanceIdDatatype() throws BOException {
312: loadDetailsIfNecessary();
313: return BODatatypeImpl.createInstanceForExisting(
314: mMetaBossDomainImpl, getDomain()
315: .getImplicitDatatypesPackage()
316: + "." + getName() + "InstanceId");
317: }
318:
319: /* Retrieves datatype used for version id or null if this entity does not keep version id */
320: public BODatatype getVersionIdDatatype() throws BOException {
321: loadDetailsIfNecessary();
322: if (mDetails.Stereotype == com.metaboss.sdlctools.types.enterprisemodel.EntityStereotype.CARD_FILE) {
323: // Card file has version id
324: return BODatatypeImpl.createInstanceForExisting(
325: mMetaBossDomainImpl, getDomain()
326: .getImplicitDatatypesPackage()
327: + "." + getName() + "VersionId");
328: }
329: return null; // All other stereotypes do not
330: }
331:
332: /* Retrieves datatype used for state or null if this entity does not have state */
333: public BODatatype getStateDatatype() throws BOException {
334: loadDetailsIfNecessary();
335: if (getStates().size() > 0) {
336: // Have states - will have state datatype
337: return BODatatypeImpl.createInstanceForExisting(
338: mMetaBossDomainImpl, getDomain()
339: .getImplicitDatatypesPackage()
340: + "." + getName() + "State");
341: }
342: return null; // No states - no state type
343: }
344:
345: /* Retrieves datatype used for ordering instruction or null if this entity does nit have one */
346: public BODatatype getOrderingInstructionDatatype()
347: throws BOException {
348: loadDetailsIfNecessary();
349: if (getStates().size() > 0
350: || getAttributes().getAttributesToUseInOrdering().length > 0) {
351: // Have states or attributes to use in ordering - will have ordering instruction datatype
352: return BODatatypeImpl.createInstanceForExisting(
353: mMetaBossDomainImpl, getDomain()
354: .getImplicitDatatypesPackage()
355: + "." + getName() + "OrderingInstruction");
356: }
357: return null; // No ordering
358: }
359:
360: /* Retrieves datatype used to carry entity collection size */
361: public BODatatype getCollectionSizeDatatype() throws BOException {
362: // Hardcoded to the system type
363: return BODatatypeImpl.createInstanceForExisting(
364: mMetaBossDomainImpl, ".core.CollectionSize");
365: }
366:
367: /* Retrieves datatype used for carry entity collection page offset */
368: public BODatatype getCollectionOffsetDatatype() throws BOException {
369: // Hardcoded to the system type
370: return BODatatypeImpl.createInstanceForExisting(
371: mMetaBossDomainImpl, ".core.CollectionOffset");
372: }
373:
374: /* Retrieves datatype used for carry size of the entities subset */
375: public BODatatype getSubsetSizeDatatype() throws BOException {
376: // Hardcoded to the system type
377: return BODatatypeImpl.createInstanceForExisting(
378: mMetaBossDomainImpl, ".core.SubsetSize");
379: }
380:
381: /* Retrieves datatype used for carry result of contains() operation on collection of entities */
382: public BODatatype getCollectionContainsFlagDatatype()
383: throws BOException {
384: // Hardcoded to the type for now
385: return BODatatypeImpl.createInstanceForExisting(
386: mMetaBossDomainImpl, ".common.BooleanField");
387: }
388:
389: /* Retrieves datatype used for carry result of isEmpty() operation on collection of entities */
390: public BODatatype getCollectionEmptyFlagDatatype()
391: throws BOException {
392: // Hardcoded to the type for now
393: return BODatatypeImpl.createInstanceForExisting(
394: mMetaBossDomainImpl, ".common.BooleanField");
395: }
396:
397: protected void loadDetailsIfNecessary() throws BOException {
398: if (mDetails == null) {
399: try {
400: // Get the instance of the enterprise ps home via jndi
401: Context lCtx = new InitialContext();
402: PSEntity lPs = (PSEntity) lCtx
403: .lookup(PSEntity.COMPONENT_URL);
404: mDetails = lPs.getEntity(mEntityRef);
405: if (mDetails == null)
406: throw new BOException(
407: "Entity not found. EntityRef:" + mEntityRef);
408: } catch (NamingException e) {
409: throw new BONamingAndDirectoryServiceInvocationException(
410: "", e);
411: } catch (PSException e) {
412: throw new BOPersistenceServiceInvocationException("", e);
413: }
414: }
415: }
416:
417: protected void onBeginEdit() throws BOException {
418: // Fully load the object
419: loadDetailsIfNecessary();
420: }
421:
422: /* Encapsulates commit action by this object */
423: protected void onCommitCreation() throws BOException {
424: try {
425: // Get the instance of the enterprise ps home via jndi
426: Context lCtx = new InitialContext();
427: PSEntity lPs = (PSEntity) lCtx
428: .lookup(PSEntity.COMPONENT_URL);
429: lPs.insertEntity(mDetails);
430: } catch (NamingException e) {
431: throw new BONamingAndDirectoryServiceInvocationException(
432: "", e);
433: } catch (PSException e) {
434: throw new BOPersistenceServiceInvocationException("", e);
435: }
436: }
437:
438: /* Encapsulates commit action by this object */
439: protected void onCommitUpdate() throws BOException {
440: try {
441: // Get the instance of the enterprise ps home via jndi
442: Context lCtx = new InitialContext();
443: PSEntity lPs = (PSEntity) lCtx
444: .lookup(PSEntity.COMPONENT_URL);
445: lPs.updateEntity(mDetails);
446: } catch (NamingException e) {
447: throw new BONamingAndDirectoryServiceInvocationException(
448: "", e);
449: } catch (PSException e) {
450: throw new BOPersistenceServiceInvocationException("", e);
451: }
452: }
453:
454: protected void onCommitDeletion() throws BOException {
455: try {
456: // Get the instance of the enterprise ps home via jndi
457: Context lCtx = new InitialContext();
458: PSEntity lPs = (PSEntity) lCtx
459: .lookup(PSEntity.COMPONENT_URL);
460: lPs.deleteEntity(mEntityRef);
461: } catch (NamingException e) {
462: throw new BONamingAndDirectoryServiceInvocationException(
463: "", e);
464: } catch (PSException e) {
465: throw new BOPersistenceServiceInvocationException("", e);
466: }
467: }
468:
469: /* Encapsulates an action after successfull commit */
470: public void onCommitSucceeded() throws BOException {
471: if (isDeleted())
472: mMetaBossDomainImpl.removeExistingBOInstance(
473: BOEntity.class, mEntityRef);
474: }
475: }
|