Source Code Cross Referenced for ValidationJavaTranslator.java in  » UML » AndroMDA-3.2 » org » andromda » translation » ocl » validation » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » UML » AndroMDA 3.2 » org.andromda.translation.ocl.validation 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package org.andromda.translation.ocl.validation;
0002:
0003:        import org.andromda.core.engine.ModelProcessorException;
0004:        import org.andromda.core.translation.TranslationUtils;
0005:        import org.andromda.metafacades.uml.ModelElementFacade;
0006:        import org.andromda.translation.ocl.BaseTranslator;
0007:        import org.andromda.translation.ocl.node.AActualParameterList;
0008:        import org.andromda.translation.ocl.node.AArrowPropertyCallExpressionTail;
0009:        import org.andromda.translation.ocl.node.AAttributeOrAssociationContextDeclaration;
0010:        import org.andromda.translation.ocl.node.ABodyOperationStereotype;
0011:        import org.andromda.translation.ocl.node.AClassifierContextDeclaration;
0012:        import org.andromda.translation.ocl.node.AContextDeclaration;
0013:        import org.andromda.translation.ocl.node.ADefClassifierExpressionBody;
0014:        import org.andromda.translation.ocl.node.ADotPropertyCallExpressionTail;
0015:        import org.andromda.translation.ocl.node.AEqualExpression;
0016:        import org.andromda.translation.ocl.node.AFeatureCall;
0017:        import org.andromda.translation.ocl.node.AFeatureCallParameters;
0018:        import org.andromda.translation.ocl.node.AFeaturePrimaryExpression;
0019:        import org.andromda.translation.ocl.node.AIfExpression;
0020:        import org.andromda.translation.ocl.node.AImpliesLogicalOperator;
0021:        import org.andromda.translation.ocl.node.AInvClassifierExpressionBody;
0022:        import org.andromda.translation.ocl.node.ALetExp;
0023:        import org.andromda.translation.ocl.node.ALetVariableDeclaration;
0024:        import org.andromda.translation.ocl.node.ALogicalExp;
0025:        import org.andromda.translation.ocl.node.ALogicalExpressionTail;
0026:        import org.andromda.translation.ocl.node.AMessageExpression;
0027:        import org.andromda.translation.ocl.node.ANotUnaryOperator;
0028:        import org.andromda.translation.ocl.node.AOperationContextDeclaration;
0029:        import org.andromda.translation.ocl.node.APathName;
0030:        import org.andromda.translation.ocl.node.APostOperationStereotype;
0031:        import org.andromda.translation.ocl.node.APreOperationStereotype;
0032:        import org.andromda.translation.ocl.node.APropertyCallExpression;
0033:        import org.andromda.translation.ocl.node.ARelationalExpression;
0034:        import org.andromda.translation.ocl.node.ARelationalExpressionTail;
0035:        import org.andromda.translation.ocl.node.ATypeDeclaration;
0036:        import org.andromda.translation.ocl.node.AUnaryExpression;
0037:        import org.andromda.translation.ocl.node.AVariableDeclaration;
0038:        import org.andromda.translation.ocl.node.AVariableDeclarationLetExpSub;
0039:        import org.andromda.translation.ocl.node.AVariableDeclarationList;
0040:        import org.andromda.translation.ocl.node.AVariableDeclarationListTail;
0041:        import org.andromda.translation.ocl.node.Node;
0042:        import org.andromda.translation.ocl.node.PAttributeOrAssociationExpressionBody;
0043:        import org.andromda.translation.ocl.node.PClassifierExpressionBody;
0044:        import org.andromda.translation.ocl.node.PContextDeclaration;
0045:        import org.andromda.translation.ocl.node.POperationExpressionBody;
0046:        import org.andromda.translation.ocl.node.PPropertyCallExpressionTail;
0047:        import org.andromda.translation.ocl.node.PVariableDeclarationListTail;
0048:        import org.andromda.translation.ocl.node.TAnd;
0049:        import org.andromda.translation.ocl.node.TApostrophe;
0050:        import org.andromda.translation.ocl.node.TArrow;
0051:        import org.andromda.translation.ocl.node.TAttr;
0052:        import org.andromda.translation.ocl.node.TBag;
0053:        import org.andromda.translation.ocl.node.TBar;
0054:        import org.andromda.translation.ocl.node.TBlank;
0055:        import org.andromda.translation.ocl.node.TBody;
0056:        import org.andromda.translation.ocl.node.TBoolean;
0057:        import org.andromda.translation.ocl.node.TCollection;
0058:        import org.andromda.translation.ocl.node.TColon;
0059:        import org.andromda.translation.ocl.node.TComma;
0060:        import org.andromda.translation.ocl.node.TCommercialAt;
0061:        import org.andromda.translation.ocl.node.TContext;
0062:        import org.andromda.translation.ocl.node.TDef;
0063:        import org.andromda.translation.ocl.node.TDerive;
0064:        import org.andromda.translation.ocl.node.TDiv;
0065:        import org.andromda.translation.ocl.node.TDot;
0066:        import org.andromda.translation.ocl.node.TElse;
0067:        import org.andromda.translation.ocl.node.TEndif;
0068:        import org.andromda.translation.ocl.node.TEndpackage;
0069:        import org.andromda.translation.ocl.node.TEnum;
0070:        import org.andromda.translation.ocl.node.TEqual;
0071:        import org.andromda.translation.ocl.node.TGt;
0072:        import org.andromda.translation.ocl.node.TGteq;
0073:        import org.andromda.translation.ocl.node.TIf;
0074:        import org.andromda.translation.ocl.node.TImplies;
0075:        import org.andromda.translation.ocl.node.TIn;
0076:        import org.andromda.translation.ocl.node.TInit;
0077:        import org.andromda.translation.ocl.node.TInt;
0078:        import org.andromda.translation.ocl.node.TInv;
0079:        import org.andromda.translation.ocl.node.TIsSentOperator;
0080:        import org.andromda.translation.ocl.node.TLBrace;
0081:        import org.andromda.translation.ocl.node.TLBracket;
0082:        import org.andromda.translation.ocl.node.TLParen;
0083:        import org.andromda.translation.ocl.node.TLet;
0084:        import org.andromda.translation.ocl.node.TLt;
0085:        import org.andromda.translation.ocl.node.TLteq;
0086:        import org.andromda.translation.ocl.node.TMessageOperator;
0087:        import org.andromda.translation.ocl.node.TMinus;
0088:        import org.andromda.translation.ocl.node.TMult;
0089:        import org.andromda.translation.ocl.node.TName;
0090:        import org.andromda.translation.ocl.node.TNewLine;
0091:        import org.andromda.translation.ocl.node.TNot;
0092:        import org.andromda.translation.ocl.node.TNotEqual;
0093:        import org.andromda.translation.ocl.node.TOper;
0094:        import org.andromda.translation.ocl.node.TOr;
0095:        import org.andromda.translation.ocl.node.TOrderedset;
0096:        import org.andromda.translation.ocl.node.TPackage;
0097:        import org.andromda.translation.ocl.node.TPlus;
0098:        import org.andromda.translation.ocl.node.TPost;
0099:        import org.andromda.translation.ocl.node.TPre;
0100:        import org.andromda.translation.ocl.node.TRBrace;
0101:        import org.andromda.translation.ocl.node.TRBracket;
0102:        import org.andromda.translation.ocl.node.TRParen;
0103:        import org.andromda.translation.ocl.node.TRange;
0104:        import org.andromda.translation.ocl.node.TReal;
0105:        import org.andromda.translation.ocl.node.TScopeOperator;
0106:        import org.andromda.translation.ocl.node.TSemicolon;
0107:        import org.andromda.translation.ocl.node.TSequence;
0108:        import org.andromda.translation.ocl.node.TSet;
0109:        import org.andromda.translation.ocl.node.TSingleLineComment;
0110:        import org.andromda.translation.ocl.node.TStringLit;
0111:        import org.andromda.translation.ocl.node.TTab;
0112:        import org.andromda.translation.ocl.node.TThen;
0113:        import org.andromda.translation.ocl.node.TTuple;
0114:        import org.andromda.translation.ocl.node.TTupletype;
0115:        import org.andromda.translation.ocl.node.TUnknown;
0116:        import org.andromda.translation.ocl.node.TXor;
0117:        import org.andromda.translation.ocl.syntax.ConcreteSyntaxUtils;
0118:        import org.andromda.translation.ocl.syntax.OCLFeatures;
0119:        import org.andromda.translation.ocl.syntax.OCLPatterns;
0120:        import org.apache.commons.lang.StringUtils;
0121:
0122:        import java.io.InputStream;
0123:        import java.net.URL;
0124:        import java.util.HashMap;
0125:        import java.util.Iterator;
0126:        import java.util.List;
0127:        import java.util.Map;
0128:        import java.util.Properties;
0129:        import java.util.Stack;
0130:
0131:        /**
0132:         * <p/>
0133:         * Provides translation of OCL validation constraints to the Java language. </p>
0134:         *
0135:         * @author Wouter Zoons
0136:         * @author Chad Brandon
0137:         */
0138:        public class ValidationJavaTranslator extends BaseTranslator {
0139:            private static Properties features = null;
0140:
0141:            static {
0142:                try {
0143:                    URL featuresUri = ValidationJavaTranslator.class
0144:                            .getResource("features.properties");
0145:                    if (featuresUri == null) {
0146:                        throw new ModelProcessorException(
0147:                                "Could not load file --> '" + featuresUri + "'");
0148:                    }
0149:                    features = new Properties();
0150:                    InputStream stream = featuresUri.openStream();
0151:                    features.load(stream);
0152:                    stream.close();
0153:                    stream = null;
0154:
0155:                } catch (final Throwable throwable) {
0156:                    throw new ValidationTranslatorException(throwable);
0157:                }
0158:
0159:            }
0160:
0161:            /**
0162:             * The package to which the OCL translator classes belong.
0163:             */
0164:            private static final String OCL_TRANSLATOR_PACKAGE = "org.andromda.translation.ocl.validation";
0165:
0166:            /**
0167:             * This is the start of a new constraint. We prepare everything by resetting and initializing the required objects.
0168:             */
0169:            public void caseAContextDeclaration(AContextDeclaration node) {
0170:                newTranslationLayer();
0171:                {
0172:                    Object temp[] = node.getContextDeclaration().toArray();
0173:                    for (int ctr = 0; ctr < temp.length; ctr++) {
0174:                        ((PContextDeclaration) temp[ctr]).apply(this );
0175:                    }
0176:                }
0177:                mergeTranslationLayers();
0178:                this .getExpression().appendToTranslatedExpression(
0179:                        translationLayers.peek());
0180:                translationLayers.clear();
0181:            }
0182:
0183:            public void caseAClassifierContextDeclaration(
0184:                    AClassifierContextDeclaration node) {
0185:                // explicity call super method so
0186:                // that we can set the type of the expression
0187:                super .inAClassifierContextDeclaration(node);
0188:                Object temp[] = node.getClassifierExpressionBody().toArray();
0189:                for (int ctr = 0; ctr < temp.length; ctr++)
0190:                    ((PClassifierExpressionBody) temp[ctr]).apply(this );
0191:            }
0192:
0193:            public void caseAOperationContextDeclaration(
0194:                    AOperationContextDeclaration node) {
0195:                // explicity call super method so
0196:                // that we can set the type of the expression
0197:                super .inAOperationContextDeclaration(node);
0198:                Object temp[] = node.getOperationExpressionBody().toArray();
0199:                for (int ctr = 0; ctr < temp.length; ctr++)
0200:                    ((POperationExpressionBody) temp[ctr]).apply(this );
0201:            }
0202:
0203:            public void caseAAttributeOrAssociationContextDeclaration(
0204:                    AAttributeOrAssociationContextDeclaration node) {
0205:                super .inAAttributeOrAssociationContextDeclaration(node);
0206:                Object temp[] = node.getAttributeOrAssociationExpressionBody()
0207:                        .toArray();
0208:                for (int ctr = 0; ctr < temp.length; ctr++)
0209:                    ((PAttributeOrAssociationExpressionBody) temp[ctr])
0210:                            .apply(this );
0211:            }
0212:
0213:            public void caseAInvClassifierExpressionBody(
0214:                    AInvClassifierExpressionBody node) {
0215:                // explicity call super method so
0216:                // that we can set the type of the expression
0217:                super .inAInvClassifierExpressionBody(node);
0218:                node.getExpression().apply(this );
0219:            }
0220:
0221:            public void caseADefClassifierExpressionBody(
0222:                    ADefClassifierExpressionBody node) {
0223:                // explicity call super method so
0224:                // that we can set the type of the expression
0225:                super .inADefClassifierExpressionBody(node);
0226:                node.getDefinitionExpression().apply(this );
0227:            }
0228:
0229:            /**
0230:             * We need to keep track that what follows is in the scope of an arrow feature call, this is important because it
0231:             * means it is a feature that is implied by the OCL language, rather than the model on which the constraint
0232:             * applies.
0233:             */
0234:            public void inAArrowPropertyCallExpressionTail(
0235:                    AArrowPropertyCallExpressionTail node) {
0236:                this .arrowPropertyCallStack.push(Boolean.TRUE);
0237:            }
0238:
0239:            /**
0240:             * Undo the arrow feature call trace.
0241:             */
0242:            public void outAArrowPropertyCallExpressionTail(
0243:                    AArrowPropertyCallExpressionTail node) {
0244:                this .arrowPropertyCallStack.pop();
0245:            }
0246:
0247:            /**
0248:             * This indicates we have entered a feature call, we need to mark this to counterpart any previous arrow feature
0249:             * call flags.
0250:             */
0251:            public void inADotPropertyCallExpressionTail(
0252:                    ADotPropertyCallExpressionTail node) {
0253:                this .arrowPropertyCallStack.push(Boolean.FALSE);
0254:            }
0255:
0256:            /**
0257:             * Undo the dot feature call trace.
0258:             */
0259:            public void outADotPropertyCallExpressionTail(
0260:                    ADotPropertyCallExpressionTail node) {
0261:                this .arrowPropertyCallStack.pop();
0262:            }
0263:
0264:            /**
0265:             * Here we need to make sure the equals sign '=' is not translated into the 'equal' keyword. OCL uses '=' for
0266:             * comparison as well as for assignment, Java uses '==', '=' and .equals() so we override the default OCL value here
0267:             * to use '=' instead of 'equal'
0268:             */
0269:            public void caseALetVariableDeclaration(ALetVariableDeclaration node) {
0270:                inALetVariableDeclaration(node);
0271:                if (node.getVariableDeclaration() != null) {
0272:                    node.getVariableDeclaration().apply(this );
0273:                }
0274:                if (node.getEqual() != null) {
0275:                    write("=");
0276:                }
0277:                if (node.getExpression() != null) {
0278:                    node.getExpression().apply(this );
0279:                }
0280:                outALetVariableDeclaration(node);
0281:            }
0282:
0283:            /**
0284:             * Add a variable to the context.
0285:             */
0286:            public void inALetVariableDeclaration(ALetVariableDeclaration node) {
0287:                newTranslationLayer(); // this layer will be disposed later on, we do
0288:                // not write variable declarations
0289:
0290:                AVariableDeclaration variableDeclaration = (AVariableDeclaration) node
0291:                        .getVariableDeclaration();
0292:                String variableName = variableDeclaration.getName().getText();
0293:
0294:                newTranslationLayer();
0295:                node.getExpression().apply(this );
0296:
0297:                String variableValue = translationLayers.pop().toString();
0298:
0299:                addLetVariableToContext(variableName, variableValue);
0300:            }
0301:
0302:            /**
0303:             * In Java we need to end the declaration statement with a semicolon, this is handled here.
0304:             */
0305:            public void outALetVariableDeclaration(ALetVariableDeclaration node) {
0306:                write(";");
0307:                translationLayers.pop();
0308:            }
0309:
0310:            /**
0311:             * Renders a variable declaration. Missing types will imply the java.lang.Object type.
0312:             */
0313:            public void caseAVariableDeclaration(AVariableDeclaration node) {
0314:                if (node.getTypeDeclaration() == null)
0315:                    write("java.lang.Object");
0316:                else
0317:                    node.getTypeDeclaration().apply(this );
0318:
0319:                write(" "); // we need to add a space between the type and the name
0320:
0321:                node.getName().apply(this );
0322:            }
0323:
0324:            public void caseATypeDeclaration(ATypeDeclaration node) {
0325:                node.getType().apply(this );
0326:            }
0327:
0328:            public void caseAVariableDeclarationList(
0329:                    AVariableDeclarationList node) {
0330:                node.getVariableDeclaration().apply(this );
0331:
0332:                if (node.getVariableDeclarationValue() != null)
0333:                    node.getVariableDeclarationValue().apply(this );
0334:
0335:                Object temp[] = node.getVariableDeclarationListTail().toArray();
0336:                for (int ctr = 0; ctr < temp.length; ctr++)
0337:                    ((PVariableDeclarationListTail) temp[ctr]).apply(this );
0338:            }
0339:
0340:            public void caseAVariableDeclarationListTail(
0341:                    AVariableDeclarationListTail node) {
0342:                node.getComma().apply(this );
0343:                node.getVariableDeclaration().apply(this );
0344:
0345:                if (node.getVariableDeclarationValue() != null)
0346:                    node.getVariableDeclarationValue().apply(this );
0347:            }
0348:
0349:            public void caseAEqualExpression(AEqualExpression node) {
0350:                node.getEqual().apply(this );
0351:                node.getExpression().apply(this );
0352:            }
0353:
0354:            public void caseABodyOperationStereotype(
0355:                    ABodyOperationStereotype node) {
0356:            }
0357:
0358:            public void caseAPreOperationStereotype(APreOperationStereotype node) {
0359:            }
0360:
0361:            public void caseAPostOperationStereotype(
0362:                    APostOperationStereotype node) {
0363:            }
0364:
0365:            public void caseAMessageExpression(AMessageExpression node) {
0366:            }
0367:
0368:            public void caseAIfExpression(AIfExpression node) {
0369:                node.getIf().apply(this );
0370:
0371:                write("(");
0372:                node.getIfBranch().apply(this );
0373:                write(")");
0374:
0375:                node.getThen().apply(this );
0376:
0377:                write("{");
0378:                node.getThenBranch().apply(this );
0379:                write(";");
0380:                write("}");
0381:
0382:                node.getElse().apply(this );
0383:
0384:                write("{");
0385:                node.getElseBranch().apply(this );
0386:                write(";");
0387:                write("}");
0388:            }
0389:
0390:            public void caseAPropertyCallExpression(APropertyCallExpression node) {
0391:                newTranslationLayer();
0392:                node.getPrimaryExpression().apply(this );
0393:                Object temp[] = node.getPropertyCallExpressionTail().toArray();
0394:                for (int ctr = 0; ctr < temp.length; ctr++)
0395:                    ((PPropertyCallExpressionTail) temp[ctr]).apply(this );
0396:                mergeTranslationLayerAfter();
0397:            }
0398:
0399:            public void caseADotPropertyCallExpressionTail(
0400:                    ADotPropertyCallExpressionTail node) {
0401:                inADotPropertyCallExpressionTail(node);
0402:                String expression = TranslationUtils.trimToEmpty(node);
0403:                // we prepend an introspection call if the expression is
0404:                // an operation call
0405:                if (OCLPatterns.isOperation(expression)) {
0406:                    AFeatureCall featureCall = (AFeatureCall) node
0407:                            .getFeatureCall();
0408:                    String featureCallExpression = TranslationUtils
0409:                            .trimToEmpty(node.getFeatureCall());
0410:                    if (OCLFeatures.isOclIsKindOf(featureCallExpression)) {
0411:                        this .handleOclIsKindOf(featureCall);
0412:                    } else if (OCLFeatures.isOclIsTypeOf(featureCallExpression)) {
0413:                        this .handleOclIsTypeOf(featureCall);
0414:                    } else if (OCLFeatures.isConcat(featureCallExpression)) {
0415:                        this .handleConcat(featureCall);
0416:                    } else {
0417:                        this .handleDotFeatureCall(featureCall);
0418:                    }
0419:                }
0420:                outADotPropertyCallExpressionTail(node);
0421:            }
0422:
0423:            /**
0424:             * oclIsKindOf(type) is a special feature defined by OCL on all objects.
0425:             */
0426:            private void handleOclIsKindOf(Object node) {
0427:                String type = this .getParametersAsType(node);
0428:                if (type != null) {
0429:                    write(" instanceof ");
0430:                    write(type);
0431:                }
0432:            }
0433:
0434:            /**
0435:             * oclIsTypeOf(type) is a special feature defined by OCL on all objects.
0436:             */
0437:            private void handleOclIsTypeOf(Object node) {
0438:                String type = this .getParametersAsType(node);
0439:                if (type != null) {
0440:                    write(".getClass().getName().equals(");
0441:                    write(type);
0442:                    write(".class.getName())");
0443:                }
0444:            }
0445:
0446:            /**
0447:             * Extracts the parameters from the given <code>node</code> and returns the parameters as a type (or null if none
0448:             * can be extracted).
0449:             *
0450:             * @param node the node from which to extrac the parameters
0451:             * @return the fully qualified type name.
0452:             */
0453:            private String getParametersAsType(Object node) {
0454:                String type = null;
0455:                if (node instanceof  AFeatureCall) {
0456:                    type = ConcreteSyntaxUtils
0457:                            .getParametersAsString((AFeatureCall) node);
0458:                } else if (node instanceof  AFeatureCallParameters) {
0459:                    type = ConcreteSyntaxUtils
0460:                            .getParametersAsString((AFeatureCallParameters) node);
0461:                }
0462:                if (type != null) {
0463:                    type = type.replaceAll("\\s*::\\s*", ".");
0464:                    // if we don't have a package define, attempt to find the model
0465:                    // element
0466:                    // in the same package as the context element.
0467:                    if (type.indexOf(".") == -1) {
0468:                        if (this .getModelElement() != null) {
0469:                            type = this .getModelElement().getPackageName()
0470:                                    + "." + type;
0471:                        }
0472:                    }
0473:                }
0474:                return type;
0475:            }
0476:
0477:            /**
0478:             * contact(string) is a special feature defined by OCL on strings.
0479:             */
0480:            private void handleConcat(AFeatureCall featureCall) {
0481:                write(" + \"\" + ");
0482:                write(OCL_INTROSPECTOR_INVOKE_PREFIX);
0483:                write(CONTEXT_ELEMENT_NAME);
0484:                write(",\"");
0485:                write(ConcreteSyntaxUtils.getParametersAsString(featureCall)
0486:                        .replaceAll("\\s*", ""));
0487:                write("\")");
0488:            }
0489:
0490:            /**
0491:             * Handles a <strong>dot </strong> feature call. Its expected that this <code>featureCall</code>'s parent is a
0492:             * ADotPropertyCallExpressionTail. This is here because dot feature calls must be handled differently than
0493:             * <code>arrow<code> feature calls.
0494:             *
0495:             * @param featureCall the <strong>dot</strong> <code>featureCall</code> to handle.
0496:             */
0497:            public void handleDotFeatureCall(AFeatureCall featureCall) {
0498:                this .prependToTranslationLayer(OCL_INTROSPECTOR_INVOKE_PREFIX);
0499:                this .appendToTranslationLayer(",\"");
0500:                this .appendToTranslationLayer(TranslationUtils
0501:                        .deleteWhitespace(featureCall));
0502:                this .appendToTranslationLayer("\"");
0503:                if (featureCall.getFeatureCallParameters() != null) {
0504:                    List parameters = ConcreteSyntaxUtils
0505:                            .getParameters(featureCall);
0506:                    if (parameters != null && !parameters.isEmpty()) {
0507:                        write(",new Object[]{");
0508:                        this 
0509:                                .appendToTranslationLayer(OCL_INTROSPECTOR_INVOKE_PREFIX);
0510:                        this .appendToTranslationLayer(CONTEXT_ELEMENT_NAME);
0511:                        this .appendToTranslationLayer(",\"");
0512:                        this .appendToTranslationLayer(ConcreteSyntaxUtils
0513:                                .getParameters(featureCall).get(0));
0514:                        this .appendToTranslationLayer("\")}");
0515:                    }
0516:                }
0517:                this .appendToTranslationLayer(")");
0518:            }
0519:
0520:            public void caseAArrowPropertyCallExpressionTail(
0521:                    AArrowPropertyCallExpressionTail node) {
0522:                inAArrowPropertyCallExpressionTail(node);
0523:                node.getArrow().apply(this );
0524:                this .handleArrowFeatureCall((AFeatureCall) node
0525:                        .getFeatureCall());
0526:                outAArrowPropertyCallExpressionTail(node);
0527:            }
0528:
0529:            /**
0530:             * @see org.andromda.translation.ocl.BaseTranslator#isOperationArgument(java.lang.String)
0531:             */
0532:            protected boolean isOperationArgument(String argument) {
0533:                return super .isOperationArgument(this .getRootName(argument));
0534:            }
0535:
0536:            /**
0537:             * Gets the root path name from the given <code>navigationalPath</code> (by trimming off any additional navigational
0538:             * path).
0539:             *
0540:             * @param navigationalPath the navigational property path (i.e. car.door)
0541:             * @return the root of the path name.
0542:             */
0543:            private String getRootName(String navigationalPath) {
0544:                return StringUtils.trimToEmpty(navigationalPath).replaceAll(
0545:                        "\\..*", "");
0546:            }
0547:
0548:            /**
0549:             * Gets the tail of the navigational path (that is it removes the root from the path and returns the tail).
0550:             *
0551:             * @param navigationalPath the navigational property path (i.e. car.door)
0552:             * @return the tail of the path name.
0553:             */
0554:            private String getPathTail(String navigationalPath) {
0555:                final int dotIndex = navigationalPath.indexOf(".");
0556:                return dotIndex != -1 ? navigationalPath.substring(
0557:                        dotIndex + 1, navigationalPath.length())
0558:                        : navigationalPath;
0559:            }
0560:
0561:            /**
0562:             * @todo: improve implementation to reduce the code duplication (avoid having two write statements)
0563:             */
0564:            public void caseAFeaturePrimaryExpression(
0565:                    AFeaturePrimaryExpression node) {
0566:                inAFeaturePrimaryExpression(node);
0567:                if (node.getPathName() != null) {
0568:                    final String variableName = ((APathName) node.getPathName())
0569:                            .getName().getText();
0570:                    final String variableValue = getDeclaredLetVariableValue(variableName);
0571:                    final boolean isDeclaredAsLetVariable = (variableValue != null);
0572:                    String featureExpression = TranslationUtils
0573:                            .deleteWhitespace(node);
0574:                    if (isDeclaredAsLetVariable) {
0575:                        write(variableValue);
0576:                    } else if (node.getFeatureCallParameters() == null
0577:                            || OCLPatterns.isOperation(featureExpression)) {
0578:                        APropertyCallExpression expression = (APropertyCallExpression) node
0579:                                .parent();
0580:                        String expressionAsString = ConcreteSyntaxUtils
0581:                                .getPrimaryExpression(expression);
0582:                        // remove any references to 'self.' as we write
0583:                        expressionAsString = expressionAsString.replaceAll(
0584:                                "self\\.", "");
0585:                        if (OCLFeatures.isSelf(expressionAsString)) {
0586:                            write(CONTEXT_ELEMENT_NAME);
0587:                        } else if (StringUtils.isNotBlank(expressionAsString)) {
0588:                            boolean convertToBoolean = false;
0589:                            if (node.parent().parent() instanceof  AUnaryExpression) {
0590:                                AUnaryExpression unaryExpression = (AUnaryExpression) node
0591:                                        .parent().parent();
0592:                                // we convert each unary not expression to boolean
0593:                                convertToBoolean = unaryExpression
0594:                                        .getUnaryOperator() instanceof  ANotUnaryOperator;
0595:                                if (convertToBoolean) {
0596:                                    this .write(BOOLEAN_WRAP_PREFIX);
0597:                                }
0598:                            }
0599:                            if (OCLFeatures.isOclIsKindOf(expressionAsString)) {
0600:                                this .write("object");
0601:                                this .handleOclIsKindOf(node
0602:                                        .getFeatureCallParameters());
0603:                            } else if (OCLFeatures
0604:                                    .isOclIsTypeOf(expressionAsString)) {
0605:                                this .write("object");
0606:                                this .handleOclIsTypeOf(node
0607:                                        .getFeatureCallParameters());
0608:                            } else {
0609:                                // whether or not an introspector call is required
0610:                                boolean introspectorCall = true;
0611:                                String invokedObject = CONTEXT_ELEMENT_NAME;
0612:                                // if we're in an arrow call we assume the invoked
0613:                                // object is the object for which the arrow call applies
0614:                                if (this .arrowPropertyCallStack.peek().equals(
0615:                                        Boolean.TRUE)) {
0616:                                    invokedObject = "object";
0617:                                }
0618:                                if (this 
0619:                                        .isOperationArgument(expressionAsString)) {
0620:                                    // - if the expression is an argument, then 
0621:                                    //   that becomes the invoked object
0622:                                    invokedObject = this 
0623:                                            .getRootName(expressionAsString);
0624:                                    expressionAsString = this 
0625:                                            .getPathTail(expressionAsString);
0626:                                    introspectorCall = !invokedObject
0627:                                            .equals(expressionAsString);
0628:                                }
0629:                                if (introspectorCall) {
0630:                                    write(OCL_INTROSPECTOR_INVOKE_PREFIX);
0631:                                }
0632:                                write(invokedObject);
0633:                                if (introspectorCall) {
0634:                                    write(",\"");
0635:                                    write(expressionAsString);
0636:                                }
0637:                                if (introspectorCall) {
0638:                                    write("\")");
0639:                                }
0640:                                if (convertToBoolean) {
0641:                                    this .write(BOOLEAN_WRAP_SUFFIX);
0642:                                }
0643:                            }
0644:                            if (this .requiresBooleanConversion) {
0645:                                this .write(BOOLEAN_WRAP_SUFFIX);
0646:                                this .requiresBooleanConversion = false;
0647:                            }
0648:                        }
0649:                    } else {
0650:                        node.getPathName().apply(this );
0651:                    }
0652:                }
0653:                if (node.getIsMarkedPre() != null) {
0654:                    node.getIsMarkedPre().apply(this );
0655:                }
0656:                if (node.getQualifiers() != null) {
0657:                    // we use introspection when in an arrow, so passing
0658:                    // feature name as a String without parentheses
0659:                    if (this .arrowPropertyCallStack.peek()
0660:                            .equals(Boolean.FALSE)) {
0661:                        node.getQualifiers().apply(this );
0662:                    }
0663:                }
0664:                outAFeaturePrimaryExpression(node);
0665:            }
0666:
0667:            /**
0668:             * Handles an <strong>arrow </strong> feature call. Its expected that this <code>featureCall</code>'s parent is a
0669:             * AArrowPropertyCallExpressionTail. This is here because arrow feature calls must be handled differently than
0670:             * <code>dot<code> feature calls.
0671:             *
0672:             * @param featureCall the <strong>arrow</strong> <code>featureCall</code> to handle.
0673:             */
0674:            public void handleArrowFeatureCall(AFeatureCall featureCall) {
0675:                AFeatureCallParameters params = (AFeatureCallParameters) featureCall
0676:                        .getFeatureCallParameters();
0677:                AActualParameterList list = null;
0678:                if (params != null) {
0679:                    list = (AActualParameterList) params
0680:                            .getActualParameterList();
0681:                }
0682:                boolean arrow = this .arrowPropertyCallStack.peek().equals(
0683:                        Boolean.TRUE)
0684:                        && !String.valueOf(list).trim().equals("");
0685:                {
0686:                    newTranslationLayer();
0687:                    final String navigationalPath = ConcreteSyntaxUtils
0688:                            .getArrowFeatureCallResultNavigationalPath((APropertyCallExpression) featureCall
0689:                                    .parent().parent());
0690:                    // if the result of an arrow feature (collection operation) has a
0691:                    // navigational
0692:                    // path, retrieve it and wrap the current expression with an OCL
0693:                    // introspector call
0694:                    boolean resultNavigationalPath = StringUtils
0695:                            .isNotBlank(navigationalPath);
0696:                    if (resultNavigationalPath) {
0697:                        write(OCL_INTROSPECTOR_INVOKE_PREFIX);
0698:                    }
0699:                    write(OCL_TRANSLATOR_PACKAGE);
0700:                    write(".OCLCollections.");
0701:                    inAFeatureCall(featureCall);
0702:                    if (featureCall.getPathName() != null) {
0703:                        featureCall.getPathName().apply(this );
0704:                    }
0705:                    String featureCallName = TranslationUtils
0706:                            .trimToEmpty(featureCall.getPathName());
0707:                    AFeatureCallParameters parameters = (AFeatureCallParameters) featureCall
0708:                            .getFeatureCallParameters();
0709:                    if (parameters != null) {
0710:                        if (parameters.getLParen() != null) {
0711:                            parameters.getLParen().apply(this );
0712:                        }
0713:                        mergeTranslationLayerBefore();
0714:                        AActualParameterList parameterList = (AActualParameterList) parameters
0715:                                .getActualParameterList();
0716:                        if (parameterList != null) {
0717:                            List expressions = parameterList
0718:                                    .getCommaExpression();
0719:
0720:                            if (parameterList.getExpression() != null) {
0721:                                if (arrow) {
0722:                                    write(",");
0723:                                    write(features.getProperty(featureCallName));
0724:                                    write(" ");
0725:                                    if (OCLPredicateFeatures
0726:                                            .isPredicateFeature(featureCallName)) {
0727:                                        write(BOOLEAN_WRAP_PREFIX);
0728:                                    }
0729:                                }
0730:                                parameterList.getExpression().apply(this );
0731:                            }
0732:                            for (int ctr = 0; ctr < expressions.size(); ctr++) {
0733:                                Node expression = (Node) expressions.get(ctr);
0734:                                if (expression != null) {
0735:                                    write(",");
0736:                                    expression.apply(this );
0737:                                }
0738:                            }
0739:                            if (parameterList.getExpression() != null) {
0740:                                if (OCLPredicateFeatures
0741:                                        .isPredicateFeature(featureCallName)) {
0742:                                    write(BOOLEAN_WRAP_SUFFIX);
0743:                                }
0744:                                if (arrow)
0745:                                    write(";}}");
0746:                            }
0747:                        }
0748:                        if (parameters.getRParen() != null) {
0749:                            parameters.getRParen().apply(this );
0750:                        }
0751:                    }
0752:                    // now since we have a navigational path off of the
0753:                    // result we need to write the path and close off
0754:                    // the call to the OCL introspector.
0755:                    if (resultNavigationalPath) {
0756:                        write(",\"");
0757:                        write(navigationalPath);
0758:                        write("\"");
0759:                        write(")");
0760:                    }
0761:                    this .outAFeatureCall(featureCall);
0762:                }
0763:            }
0764:
0765:            public void caseALetExp(ALetExp node) {
0766:                inALetExp(node);
0767:                if (node.getLet() != null) {
0768:                    node.getLet().apply(this );
0769:                }
0770:                if (node.getLetVariableDeclaration() != null) {
0771:                    node.getLetVariableDeclaration().apply(this );
0772:                }
0773:                if (node.getLetExpSub() != null) {
0774:                    node.getLetExpSub().apply(this );
0775:                }
0776:                outALetExp(node);
0777:            }
0778:
0779:            /**
0780:             * We are ready to store a new context of variables
0781:             */
0782:            public void inALetExp(ALetExp node) {
0783:                newLetVariableContext();
0784:            }
0785:
0786:            /**
0787:             * The variables are out of scope, we need to purge their context.
0788:             */
0789:            public void outALetExp(ALetExp node) {
0790:                dropLetVariableContext();
0791:            }
0792:
0793:            public void caseAVariableDeclarationLetExpSub(
0794:                    AVariableDeclarationLetExpSub node) {
0795:                node.getComma().apply(this );
0796:                node.getLetVariableDeclaration().apply(this );
0797:                node.getLetExpSub().apply(this );
0798:            }
0799:
0800:            public void caseALogicalExp(ALogicalExp node) {
0801:                newTranslationLayer();
0802:                if (node.getRelationalExpression() != null) {
0803:                    node.getRelationalExpression().apply(this );
0804:                }
0805:                Object tails[] = node.getLogicalExpressionTail().toArray();
0806:                for (int ctr = 0; ctr < tails.length; ctr++) {
0807:                    ((ALogicalExpressionTail) tails[ctr]).apply(this );
0808:                }
0809:                mergeTranslationLayerAfter();
0810:            }
0811:
0812:            public void caseALogicalExpressionTail(ALogicalExpressionTail node) {
0813:                node.getLogicalOperator().apply(this );
0814:                if (node.getLogicalOperator() instanceof  AImpliesLogicalOperator) {
0815:                    prependToTranslationLayer("(");
0816:                }
0817:                if (node.getRelationalExpression() != null) {
0818:                    node.getRelationalExpression().apply(this );
0819:                }
0820:                if (node.getLogicalOperator() instanceof  AImpliesLogicalOperator) {
0821:                    write(":true)");
0822:                }
0823:            }
0824:
0825:            public void caseARelationalExpressionTail(
0826:                    ARelationalExpressionTail node) {
0827:                inARelationalExpressionTail(node);
0828:
0829:                newTranslationLayer();
0830:                write(OCL_TRANSLATOR_PACKAGE);
0831:                write(".OCLExpressions.");
0832:                node.getRelationalOperator().apply(this );
0833:                write("(");
0834:                mergeTranslationLayerBefore();
0835:                if (node.getAdditiveExpression() != null) {
0836:                    write(",");
0837:                    node.getAdditiveExpression().apply(this );
0838:                }
0839:                write(")");
0840:                outARelationalExpressionTail(node);
0841:            }
0842:
0843:            /**
0844:             * A flag indicating if the expression needs to be converted/wrapped in a Java Boolean instance.
0845:             */
0846:            private boolean requiresBooleanConversion = false;
0847:
0848:            public void inARelationalExpression(ARelationalExpression node) {
0849:                // in this block of code, we determine whether or not
0850:                // the next appended expression needs to be
0851:                // converted/wrapped by a Java Boolean
0852:                if (node.getRelationalExpressionTail() == null) {
0853:                    Object parent = node.parent();
0854:                    Object expression = null;
0855:                    if (parent instanceof  ALogicalExp) {
0856:                        List tails = ((ALogicalExp) parent)
0857:                                .getLogicalExpressionTail();
0858:                        if (tails != null && !tails.isEmpty()) {
0859:                            expression = tails.get(0);
0860:                            // if it's an AND or OR expression set the expression
0861:                            // to the node
0862:                            if (OCLPatterns.isAndOrOrExpression(expression)) {
0863:                                expression = node;
0864:                            }
0865:                        }
0866:                    } else if (parent instanceof  ALogicalExpressionTail) {
0867:                        expression = node;
0868:                    }
0869:                    requiresBooleanConversion = expression != null
0870:                            && OCLPatterns.isNavigationalPath(expression)
0871:                            && !OCLPatterns.isOperation(node);
0872:                    if (this .requiresBooleanConversion) {
0873:                        this .write(BOOLEAN_WRAP_PREFIX);
0874:                    }
0875:                }
0876:                newTranslationLayer();
0877:            }
0878:
0879:            public void outARelationalExpression(ARelationalExpression node) {
0880:                mergeTranslationLayerAfter();
0881:            }
0882:
0883:            public void caseTName(TName node) {
0884:                write(node.getText());
0885:            }
0886:
0887:            public void caseTAnd(TAnd tAnd) {
0888:                write("&&");
0889:            }
0890:
0891:            public void caseTOr(TOr tOr) {
0892:                write("||");
0893:            }
0894:
0895:            public void caseTXor(TXor tXor) {
0896:                write("^");
0897:            }
0898:
0899:            public void caseTImplies(TImplies tImplies) {
0900:                // convert any non boolean's to boolean
0901:                this .prependToTranslationLayer(BOOLEAN_WRAP_PREFIX);
0902:                this .appendToTranslationLayer(BOOLEAN_WRAP_SUFFIX);
0903:                write("?");
0904:            }
0905:
0906:            public void caseTNot(TNot tNot) {
0907:                write("!");
0908:            }
0909:
0910:            public void caseTPlus(TPlus tPlus) {
0911:                write("+");
0912:            }
0913:
0914:            public void caseTMinus(TMinus tMinus) {
0915:                write("-");
0916:            }
0917:
0918:            public void caseTMult(TMult tMult) {
0919:                write("*");
0920:            }
0921:
0922:            public void caseTDiv(TDiv tDiv) {
0923:                write("/");
0924:            }
0925:
0926:            public void caseTEqual(TEqual tEqual) {
0927:                write("equal");
0928:            }
0929:
0930:            public void caseTNotEqual(TNotEqual tNotEqual) {
0931:                write("notEqual");
0932:            }
0933:
0934:            public void caseTLt(TLt tLt) {
0935:                write("less");
0936:            }
0937:
0938:            public void caseTLteq(TLteq tLteq) {
0939:                write("lessOrEqual");
0940:            }
0941:
0942:            public void caseTGt(TGt tGt) {
0943:                write("greater");
0944:            }
0945:
0946:            public void caseTGteq(TGteq tGteq) {
0947:                write("greaterOrEqual");
0948:            }
0949:
0950:            public void caseTInv(TInv tInv) {
0951:            }
0952:
0953:            public void caseTDef(TDef tDef) {
0954:            }
0955:
0956:            public void caseTLet(TLet tLet) {
0957:            }
0958:
0959:            public void caseTColon(TColon tColon) {
0960:            }
0961:
0962:            public void caseTLBrace(TLBrace tlBrace) {
0963:                write("{");
0964:            }
0965:
0966:            public void caseTLBracket(TLBracket tlBracket) {
0967:                write("[");
0968:            }
0969:
0970:            public void caseTLParen(TLParen tlParen) {
0971:                write("(");
0972:            }
0973:
0974:            public void caseTRBrace(TRBrace trBrace) {
0975:                write("}");
0976:            }
0977:
0978:            public void caseTRBracket(TRBracket trBracket) {
0979:                write("]");
0980:            }
0981:
0982:            public void caseTRParen(TRParen trParen) {
0983:                write(")");
0984:            }
0985:
0986:            public void caseTContext(TContext tContext) {
0987:            }
0988:
0989:            public void caseTBoolean(TBoolean tBoolean) {
0990:                write(tBoolean.getText());
0991:            }
0992:
0993:            public void caseTApostrophe(TApostrophe tApostrophe) {
0994:                write("\'");
0995:            }
0996:
0997:            public void caseTBlank(TBlank tBlank) {
0998:                write(" ");
0999:            }
1000:
1001:            public void caseTCollection(TCollection tCollection) {
1002:                write("java.util.Collection ");
1003:            }
1004:
1005:            public void caseTComment(TSingleLineComment tSingleLineComment) {
1006:                write("// ");
1007:            }
1008:
1009:            public void caseTEndif(TEndif tEndif) {
1010:            }
1011:
1012:            public void caseTAttr(TAttr tAttr) {
1013:            }
1014:
1015:            public void caseTBag(TBag tBag) {
1016:            }
1017:
1018:            public void caseTBar(TBar tBar) {
1019:            }
1020:
1021:            public void caseTBody(TBody tBody) {
1022:            }
1023:
1024:            public void caseTCommercialAt(TCommercialAt tCommercialAt) {
1025:            }
1026:
1027:            public void caseTDerive(TDerive tDerive) {
1028:            }
1029:
1030:            public void caseTEndpackage(TEndpackage tEndpackage) {
1031:            }
1032:
1033:            public void caseTEnum(TEnum tEnum) {
1034:            }
1035:
1036:            public void caseTIn(TIn tIn) {
1037:            }
1038:
1039:            public void caseTInit(TInit tInit) {
1040:            }
1041:
1042:            public void caseTInt(TInt tInt) {
1043:                write(tInt.getText());
1044:            }
1045:
1046:            public void caseTIsSentOperator(TIsSentOperator tIsSentOperator) {
1047:            }
1048:
1049:            public void caseTMessageOperator(TMessageOperator tMessageOperator) {
1050:            }
1051:
1052:            public void caseTNewLine(TNewLine tNewLine) {
1053:            }
1054:
1055:            public void caseTOper(TOper tOper) {
1056:            }
1057:
1058:            public void caseTOrderedset(TOrderedset tOrderedset) {
1059:            }
1060:
1061:            public void caseTPackage(TPackage tPackage) {
1062:            }
1063:
1064:            public void caseTPost(TPost tPost) {
1065:            }
1066:
1067:            public void caseTPre(TPre tPre) {
1068:            }
1069:
1070:            public void caseTArrow(TArrow tArrow) {
1071:            }
1072:
1073:            public void caseTIf(TIf tIf) {
1074:                write("if");
1075:            }
1076:
1077:            public void caseTElse(TElse tElse) {
1078:                write("else");
1079:            }
1080:
1081:            public void caseTThen(TThen tThen) {
1082:            }
1083:
1084:            public void caseTRange(TRange tRange) {
1085:            }
1086:
1087:            public void caseTReal(TReal tReal) {
1088:                write(tReal.getText());
1089:            }
1090:
1091:            public void caseTComma(TComma tComma) {
1092:                write(", ");
1093:            }
1094:
1095:            public void caseTDot(TDot tDot) {
1096:                write(".");
1097:            }
1098:
1099:            public void caseTSemicolon(TSemicolon tSemicolon) {
1100:            }
1101:
1102:            public void caseTUnknown(TUnknown tUnknown) {
1103:            }
1104:
1105:            public void caseTScopeOperator(TScopeOperator tScopeOperator) {
1106:                write(".");
1107:            }
1108:
1109:            public void caseTSequence(TSequence tSequence) {
1110:            }
1111:
1112:            public void caseTSet(TSet tSet) {
1113:            }
1114:
1115:            /**
1116:             * @todo: this method very naively replaces every single quote by a double quote, this should be updated
1117:             */
1118:            public void caseTStringLit(TStringLit tStringLit) {
1119:                final StringBuffer buffer = new StringBuffer(tStringLit
1120:                        .getText().replace('\'', '\"'));
1121:                write(buffer);
1122:            }
1123:
1124:            public void caseTTab(TTab tTab) {
1125:            }
1126:
1127:            public void caseTTuple(TTuple tTuple) {
1128:            }
1129:
1130:            public void caseTTupletype(TTupletype tTupletype) {
1131:            }
1132:
1133:            private final Stack translationLayers = new Stack();
1134:
1135:            /**
1136:             * Contains Boolean.TRUE on the top when the most recent property call was an arrow property call, contains
1137:             * Boolean.FALSE otherwise.
1138:             */
1139:            private final Stack arrowPropertyCallStack = new Stack();
1140:
1141:            /**
1142:             * This stack contains elements implementing the Map interface. For each definition of variables a new Map element
1143:             * will be pushed onto the stack. This element contains the variables defined in the definition.
1144:             * <p/>
1145:             * The keys and values contained in the Map are the names of the variables only (String instances).
1146:             */
1147:            private final Stack letVariableStack = new Stack();
1148:
1149:            private void write(Object object) {
1150:                appendToTranslationLayer(String.valueOf(object));
1151:            }
1152:
1153:            private StringBuffer newTranslationLayer() {
1154:                return (StringBuffer) translationLayers
1155:                        .push(new StringBuffer());
1156:            }
1157:
1158:            private StringBuffer appendToTranslationLayer(Object appendix) {
1159:                return ((StringBuffer) translationLayers.peek())
1160:                        .append(appendix);
1161:            }
1162:
1163:            private StringBuffer prependToTranslationLayer(Object appendix) {
1164:                return ((StringBuffer) translationLayers.peek()).insert(0,
1165:                        appendix);
1166:            }
1167:
1168:            private StringBuffer mergeTranslationLayerAfter() {
1169:                StringBuffer newTop = null;
1170:
1171:                if (translationLayers.size() > 1) {
1172:                    newTop = appendToTranslationLayer(translationLayers.pop());
1173:                }
1174:
1175:                return newTop;
1176:            }
1177:
1178:            private StringBuffer mergeTranslationLayerBefore() {
1179:                StringBuffer newTop = null;
1180:
1181:                if (translationLayers.size() > 1) {
1182:                    newTop = prependToTranslationLayer(translationLayers.pop());
1183:                }
1184:
1185:                return newTop;
1186:            }
1187:
1188:            private StringBuffer mergeTranslationLayers() {
1189:                while (mergeTranslationLayerAfter() != null)
1190:                    ;
1191:                return (StringBuffer) translationLayers.peek();
1192:            }
1193:
1194:            private String getDeclaredLetVariableValue(String variableName) {
1195:                for (final Iterator iterator = letVariableStack.iterator(); iterator
1196:                        .hasNext();) {
1197:                    Map variableMap = (Map) iterator.next();
1198:                    if (variableMap.containsKey(variableName)) {
1199:                        return (String) variableMap.get(variableName);
1200:                    }
1201:                }
1202:                return null;
1203:            }
1204:
1205:            private void newLetVariableContext() {
1206:                letVariableStack.push(new HashMap(4));
1207:            }
1208:
1209:            private void dropLetVariableContext() {
1210:                if (!letVariableStack.isEmpty())
1211:                    letVariableStack.pop();
1212:            }
1213:
1214:            private void addLetVariableToContext(String variableName,
1215:                    String variableValue) {
1216:                ((Map) letVariableStack.peek())
1217:                        .put(variableName, variableValue);
1218:            }
1219:
1220:            /**
1221:             * Gets the current context element as a {@link org.andromda.uml.metafacades.ModelElementFacade}.
1222:             *
1223:             * @return the context element as a model element facade
1224:             */
1225:            private ModelElementFacade getModelElement() {
1226:                return (ModelElementFacade) this .getContextElement();
1227:            }
1228:
1229:            public ValidationJavaTranslator() {
1230:                arrowPropertyCallStack.push(Boolean.FALSE);
1231:            }
1232:
1233:            /**
1234:             * The name of the context element within the translated expression.
1235:             */
1236:            private static final String CONTEXT_ELEMENT_NAME = "contextElement";
1237:
1238:            /**
1239:             * The prefix for calling the OCLIntrospector to invoke a property or method on an element.
1240:             */
1241:            private static final String OCL_INTROSPECTOR_INVOKE_PREFIX = OCL_TRANSLATOR_PACKAGE
1242:                    + ".OCLIntrospector.invoke(";
1243:
1244:            /**
1245:             * The prefix for converting expressions to boolean expressions
1246:             */
1247:            private static final String BOOLEAN_WRAP_PREFIX = "Boolean.valueOf(String.valueOf(";
1248:
1249:            /**
1250:             * The suffix for converting expressions to boolean expressions;
1251:             */
1252:            private static final String BOOLEAN_WRAP_SUFFIX = ")).booleanValue()";
1253:
1254:            /**
1255:             * We need to wrap every expression with a converter so that any expressions that return just objects are converted
1256:             * to boolean values.
1257:             *
1258:             * @see org.andromda.translation.ocl.BaseTranslator#postProcess()
1259:             */
1260:            public void postProcess() {
1261:                this .getExpression().insertInTranslatedExpression(0,
1262:                        OCL_TRANSLATOR_PACKAGE + ".OCLResultEnsurer.ensure(");
1263:                this .getExpression().insertInTranslatedExpression(0,
1264:                        "boolean constraintValid = ");
1265:                this .getExpression().insertInTranslatedExpression(
1266:                        0,
1267:                        "final java.lang.Object " + CONTEXT_ELEMENT_NAME
1268:                                + " = this; ");
1269:                this .getExpression().appendToTranslatedExpression(");");
1270:            }
1271:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.