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.metabossmodel.enterprisemodel;
016:
017: import java.util.Iterator;
018:
019: import tudresden.ocl.check.OclTypeException;
020: import tudresden.ocl.check.types.Any;
021: import tudresden.ocl.check.types.Basic;
022: import tudresden.ocl.check.types.Collection;
023: import tudresden.ocl.check.types.ModelFacade;
024: import tudresden.ocl.check.types.Type;
025:
026: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.DataType;
027: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.Structure;
028: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.StructureField;
029: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Attribute;
030: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Entity;
031: import com.metaboss.sdlctools.models.metabossmodel.statemachinemodel.State;
032: import com.metaboss.sdlctools.models.metabossmodel.statemachinemodel.StateMachine;
033:
034: /** Represents the customised facade of the MetaBoss domain model used by OCL compiler to navigate the model. */
035: public class ModelFacadeForOCLCompiler implements ModelFacade {
036: // Type wrapper around the DataType model element
037: private static class PrimitiveType implements Any {
038: private DataType mDataType;
039:
040: public PrimitiveType(DataType pDataType) {
041: mDataType = pDataType;
042: }
043:
044: public Type navigateQualified(String name, Type[] qualifiers)
045: throws OclTypeException {
046: throw new OclTypeException(
047: "DataType model element does not have '"
048: + name
049: + "' attribute exposed to OCL. DataTypeRef: "
050: + mDataType.getRef());
051: }
052:
053: public boolean conformsTo(Type t) {
054: if ((t instanceof PrimitiveType)
055: && mDataType.equals(((PrimitiveType) t).mDataType))
056: return true;
057: return false;
058: }
059:
060: public Type navigateParameterized(String name, Type[] params)
061: throws OclTypeException {
062: // Supports isPresent() operation which returns true if value is present
063: if (name.equals("oclIsUndefined")
064: && (params == null || params.length == 0))
065: return Basic.BOOLEAN;
066: if (name.equals("isEmpty")
067: && (params == null || params.length == 0))
068: return Basic.BOOLEAN;
069: throw new OclTypeException(
070: "DataType model element does not have '"
071: + name
072: + "' function exposed to OCL. DataTypeRef: "
073: + mDataType.getRef());
074: }
075:
076: public boolean hasState(String stateName) {
077: return false;
078: }
079:
080: public String toString() {
081: return mDataType.getName();
082: }
083: }
084:
085: // Type wrapper around the Structure model element
086: private static class StructureType implements Any {
087: private Structure mStructure;
088:
089: public StructureType(Structure pStructure) {
090: mStructure = pStructure;
091: }
092:
093: public Type navigateQualified(String name, Type[] qualifiers)
094: throws OclTypeException {
095: for (Iterator lFieldsIterator = mStructure.getFields()
096: .iterator(); lFieldsIterator.hasNext();) {
097: StructureField lStructureField = (StructureField) lFieldsIterator
098: .next();
099: if (name.equalsIgnoreCase(lStructureField.getName())) {
100: if (lStructureField.getStructureType() != null) {
101: if (lStructureField.isArray())
102: return new Collection(Collection.SEQUENCE,
103: new StructureType(lStructureField
104: .getStructureType()));
105: else
106: return new StructureType(lStructureField
107: .getStructureType());
108: } else {
109: if (lStructureField.isArray())
110: return new Collection(Collection.SEQUENCE,
111: new PrimitiveType(lStructureField
112: .getDataType()));
113: else
114: return new PrimitiveType(lStructureField
115: .getDataType());
116: }
117: }
118: }
119: throw new OclTypeException("StructureField \'" + name
120: + "\' is not found in Structure. StructureRef: "
121: + mStructure.getRef());
122: }
123:
124: public boolean conformsTo(Type t) {
125: if ((t instanceof StructureType)
126: && mStructure
127: .equals(((StructureType) t).mStructure))
128: return true;
129: return false;
130: }
131:
132: public Type navigateParameterized(String name, Type[] params)
133: throws OclTypeException {
134: // Supports isPresent() operation which returns true if value is present
135: if (name.equals("oclIsUndefined")
136: && (params == null || params.length == 0))
137: return Basic.BOOLEAN;
138: if (name.equals("isEmpty")
139: && (params == null || params.length == 0))
140: return Basic.BOOLEAN;
141: throw new OclTypeException(
142: "Structure model element does not have '"
143: + name
144: + "' function exposed to OCL. StructureRef: "
145: + mStructure.getRef());
146: }
147:
148: public boolean hasState(String stateName) {
149: return false; // Structures do not have state
150: }
151:
152: public String toString() {
153: return mStructure.getName();
154: }
155: }
156:
157: // Type wrapper around the Entity model element
158: private static class EntityType implements Any {
159: private Entity mEntity;
160:
161: public EntityType(Entity pEntity) {
162: mEntity = pEntity;
163: }
164:
165: public Type navigateQualified(String name, Type[] qualifiers)
166: throws OclTypeException {
167: for (Iterator lAttributesIterator = mEntity
168: .getCombinedAttributes().iterator(); lAttributesIterator
169: .hasNext();) {
170: Attribute lAttribute = (Attribute) lAttributesIterator
171: .next();
172: if (name.equalsIgnoreCase(lAttribute.getName())) {
173: return new PrimitiveType(lAttribute.getDataType());
174: }
175: }
176: throw new OclTypeException("Attribute \'" + name
177: + "\' is not found in Entity. EntityRef: "
178: + mEntity.getRef());
179: }
180:
181: public boolean conformsTo(Type t) {
182: if ((t instanceof EntityType)
183: && mEntity.equals(((EntityType) t).mEntity))
184: return true;
185: return false;
186: }
187:
188: public Type navigateParameterized(String name, Type[] params)
189: throws OclTypeException {
190: // Supports isPresent() operation which returns true if value is present
191: if (name.equals("oclIsUndefined")
192: && (params == null || params.length == 0))
193: return Basic.BOOLEAN;
194: throw new OclTypeException(
195: "Entity model element does not have '" + name
196: + "' function exposed to OCL. EntityRef: "
197: + mEntity.getRef());
198: }
199:
200: public boolean hasState(String stateName) {
201: StateMachine lStateMachine = mEntity.getStateMachine();
202: if (lStateMachine != null) {
203: for (Iterator lStatesIterator = lStateMachine
204: .getStates().iterator(); lStatesIterator
205: .hasNext();) {
206: State lState = (State) lStatesIterator.next();
207: if (stateName.equalsIgnoreCase(lState.getName()))
208: return true;
209: }
210: return false; // State with the required name is not found
211: }
212: return false; // State machine does not exists
213: }
214:
215: public String toString() {
216: return mEntity.getName();
217: }
218: }
219:
220: // Type wrapper around the OperationInput model element
221: private static class OperationInputType implements Any {
222: private AbstractOperation mOperation;
223:
224: public OperationInputType(AbstractOperation pOperation) {
225: mOperation = pOperation;
226: }
227:
228: public Type navigateQualified(String name, Type[] qualifiers)
229: throws OclTypeException {
230: for (Iterator lInputFieldsIterator = mOperation
231: .getInputFields().iterator(); lInputFieldsIterator
232: .hasNext();) {
233: OperationInputField lOperationInputField = (OperationInputField) lInputFieldsIterator
234: .next();
235: if (name.equalsIgnoreCase(lOperationInputField
236: .getName())) {
237: if (lOperationInputField.getStructureType() != null) {
238: if (lOperationInputField.isArray())
239: return new Collection(
240: Collection.SEQUENCE,
241: new StructureType(
242: lOperationInputField
243: .getStructureType()));
244: else
245: return new StructureType(
246: lOperationInputField
247: .getStructureType());
248: } else {
249: if (lOperationInputField.isArray())
250: return new Collection(Collection.SEQUENCE,
251: new PrimitiveType(
252: lOperationInputField
253: .getDataType()));
254: else
255: return new PrimitiveType(
256: lOperationInputField.getDataType());
257: }
258: }
259: }
260: throw new OclTypeException("InputField \'" + name
261: + "\' is not found in Operation. OperationRef: "
262: + mOperation.getRef());
263: }
264:
265: public boolean conformsTo(Type t) {
266: if ((t instanceof OperationInputType)
267: && mOperation
268: .equals(((OperationInputType) t).mOperation))
269: return true;
270: return false;
271: }
272:
273: public Type navigateParameterized(String name, Type[] params)
274: throws OclTypeException {
275: throw new OclTypeException(
276: "Operation input element does not have '"
277: + name
278: + "' function exposed to OCL. OperationRef: "
279: + mOperation.getRef());
280: }
281:
282: public boolean hasState(String stateName) {
283: return false; // Structures do not have state
284: }
285:
286: public String toString() {
287: return mOperation.getName();
288: }
289: }
290:
291: private Structure mStructure;
292: private AbstractOperation mOperation;
293: private Entity mEntity;
294: private boolean mIsStructureContext = false;
295: private boolean mIsOperationInputContext = false;
296: private boolean mIsEntityContext = false;
297: private Any mClassifier;
298:
299: /** Creates the facade ready for the structure context resolution */
300: public static ModelFacade createForStructureContext(
301: Structure pStructure) {
302: ModelFacadeForOCLCompiler lModelFacade = new ModelFacadeForOCLCompiler();
303: lModelFacade.mStructure = pStructure;
304: lModelFacade.mIsStructureContext = true;
305: lModelFacade.mClassifier = new StructureType(pStructure);
306: return lModelFacade;
307: }
308:
309: /** Creates the facade ready for the entity context resolution */
310: public static ModelFacade createForEntityContext(Entity pEntity) {
311: ModelFacadeForOCLCompiler lModelFacade = new ModelFacadeForOCLCompiler();
312: lModelFacade.mEntity = pEntity;
313: lModelFacade.mIsEntityContext = true;
314: lModelFacade.mClassifier = new EntityType(pEntity);
315: return lModelFacade;
316: }
317:
318: /** Creates the facade ready for the operation input context resolution */
319: public static ModelFacade createForOperationInputContext(
320: AbstractOperation pOperation) {
321: ModelFacadeForOCLCompiler lModelFacade = new ModelFacadeForOCLCompiler();
322: lModelFacade.mOperation = pOperation;
323: lModelFacade.mIsOperationInputContext = true;
324: lModelFacade.mClassifier = new OperationInputType(pOperation);
325: return lModelFacade;
326: }
327:
328: private ModelFacadeForOCLCompiler() {
329: }
330:
331: public Any getClassifier(String name) throws OclTypeException {
332: if (mIsStructureContext) {
333: if (name.equalsIgnoreCase(mStructure.getName()))
334: return mClassifier;
335: // Structure not found. Create exception with the meaningful message
336: if (mStructure.getNamespace() != null)
337: throw new OclTypeException(
338: "Structure \'"
339: + name
340: + "\' is not found in Namespace. NamespaceRef: "
341: + mStructure.getNamespace());
342: else if (mStructure.getServicemodule() != null)
343: throw new OclTypeException(
344: "Structure \'"
345: + name
346: + "\' is not found in Servicemodule. ServicemoduleRef: "
347: + mStructure.getServicemodule()
348: .getRef());
349: else
350: throw new OclTypeException("Structure \'" + name
351: + "\' is not found.");
352: } else if (mIsOperationInputContext) {
353: if (name.equalsIgnoreCase(mOperation.getName()))
354: return mClassifier;
355: if (mOperation instanceof Operation
356: && ((Operation) mOperation).getService() != null)
357: throw new OclTypeException("Operation \'"
358: + name
359: + "\' is not found in Service. ServiceRef: "
360: + ((Operation) mOperation).getService()
361: .getRef());
362: else if (mOperation instanceof EventSubscriptionOperation
363: && ((EventSubscriptionOperation) mOperation)
364: .getSubscription() != null)
365: throw new OclTypeException(
366: "Operation \'"
367: + name
368: + "\' is not found in EventSubscription. EventSubscriptionRef: "
369: + ((EventSubscriptionOperation) mOperation)
370: .getSubscription().getRef());
371: else
372: throw new OclTypeException("Operation \'" + name
373: + "\' is not found.");
374: } else
375: //if (mIsEntityContext)
376: {
377: if (name.equalsIgnoreCase(mEntity.getName()))
378: return mClassifier;
379: if (mEntity.getDomain() != null)
380: throw new OclTypeException("Entity \'" + name
381: + "\' is not found in Domain. DomainRef: "
382: + mEntity.getDomain());
383: else
384: throw new OclTypeException("Entity \'" + name
385: + "\' is not found.");
386: }
387: }
388: }
|