Source Code Cross Referenced for BaseTranslator.java in  » UML » AndroMDA-3.2 » org » andromda » translation » ocl » 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 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.andromda.translation.ocl;
002:
003:        import org.andromda.core.common.ExceptionUtils;
004:        import org.andromda.core.translation.Expression;
005:        import org.andromda.core.translation.TranslationUtils;
006:        import org.andromda.core.translation.Translator;
007:        import org.andromda.core.translation.TranslatorException;
008:        import org.andromda.core.translation.library.LibraryTranslation;
009:        import org.andromda.core.translation.library.LibraryTranslationFinder;
010:        import org.andromda.translation.ocl.analysis.DepthFirstAdapter;
011:        import org.andromda.translation.ocl.lexer.Lexer;
012:        import org.andromda.translation.ocl.lexer.LexerException;
013:        import org.andromda.translation.ocl.node.AClassifierContextDeclaration;
014:        import org.andromda.translation.ocl.node.ADefClassifierExpressionBody;
015:        import org.andromda.translation.ocl.node.AInvClassifierExpressionBody;
016:        import org.andromda.translation.ocl.node.AOperationContextDeclaration;
017:        import org.andromda.translation.ocl.node.AOperationExpressionBody;
018:        import org.andromda.translation.ocl.node.Start;
019:        import org.andromda.translation.ocl.parser.OclParser;
020:        import org.andromda.translation.ocl.parser.OclParserException;
021:        import org.andromda.translation.ocl.parser.ParserException;
022:        import org.andromda.translation.ocl.syntax.ConcreteSyntaxUtils;
023:        import org.andromda.translation.ocl.syntax.OperationDeclaration;
024:        import org.apache.log4j.Logger;
025:
026:        import java.io.IOException;
027:        import java.io.PushbackReader;
028:        import java.io.StringReader;
029:        import java.util.HashMap;
030:        import java.util.Map;
031:
032:        /**
033:         * The "base" translator which all Translator's should extend, provides some basic functionality, such as the retrieveal
034:         * of translation fragments from the translation template file, pre-processing, post-processing, etc.
035:         * <p/>
036:         * The primary methods (in addition to methods you'll extend to handle expression parsing) to take note of when
037:         * extending this class are: <ul> <li><a href="#handleTranslationFragment(org.andromda.core.translation.node.Node)">handleTranslationFragment(java.lang.String,
038:         * Node node) </a></li> <li><a href="#getTranslationFragment(java.lang.String)">getTranslationFragment(java.lang.String)
039:         * </a></li> <li><a href="#getExpression()">getExpression() </a></li> <li><a href="#preProcess()">preProcess() </a></li>
040:         * <li><a href="#postProcess()">postProcess() </a></li> </ul> </p>
041:         *
042:         * @author Chad Brandon
043:         */
044:        public abstract class BaseTranslator extends DepthFirstAdapter
045:                implements  Translator {
046:
047:            /**
048:             * The logger instance that can be used by all decendant classes.
049:             */
050:            protected Logger logger = Logger.getLogger(this .getClass());
051:
052:            /**
053:             * This is set by the "translate" method in order to provide any Translator classes extending this class access to
054:             * the element that is the context for the expression.
055:             */
056:            private Object contextElement = null;
057:
058:            /**
059:             * Contains the Expression that was/will be populated during execution of the translation method
060:             */
061:            private Expression translatedExpression = null;
062:
063:            /**
064:             * The processed Translation file.
065:             */
066:            private LibraryTranslation libraryTranslation = null;
067:
068:            /**
069:             * Called by the translate method to set the element which provides the context for the traslated expression.
070:             *
071:             * @param contextElement
072:             */
073:            private void setContextElement(Object contextElement) {
074:                this .contextElement = contextElement;
075:            }
076:
077:            /**
078:             * Returns the current value of the Expression. This stores the translation being translated.
079:             *
080:             * @return Expression stores the the translation.
081:             */
082:            public Expression getExpression() {
083:                final String methodName = "BaseTranslator.getExpression";
084:                if (this .translatedExpression == null) {
085:                    throw new TranslatorException(methodName
086:                            + " - translatedExpression can not be null");
087:                }
088:                return translatedExpression;
089:            }
090:
091:            /**
092:             * Returns the context element for the expression being translated.
093:             *
094:             * @return the context element.
095:             */
096:            public Object getContextElement() {
097:                String methodName = "getContextElement";
098:                if (this .contextElement == null) {
099:                    throw new TranslatorException(methodName
100:                            + " - the contextElement can not be null");
101:                }
102:                return this .contextElement;
103:            }
104:
105:            /**
106:             * Calls the handlerMethod defined on the &lt;fragment/&gt; element if <code>fragmentName</code> matches one the
107:             * fragments defined within the current translation file.
108:             * <p/>
109:             * <a name="#handlerMethod"/> A handlerMethod must have two arguments: <ol> <li>The first argument must be a
110:             * <code>java.lang.String</code> which will be the body of the corresponding <code>kind</code> element for the
111:             * matching fragment. (i.e. if <code>'context LegalAgreement inv: allInstances -> isUnique(documentTitle')'</code>
112:             * is being translated, then the body of the element &lt;kind name="inv"/&gt; would be returned)</li> <li>The second
113:             * argument is of type <code>java.lang.Object</code> and is the node that is currently being parsed at the time the
114:             * matching of the <code>fragmentName</code> occurred.</li> </ol>
115:             * <p/>
116:             * <p/>
117:             * For example this handlerMethod might be defined within your translation file to handle the 'allInstances'
118:             * expression:
119:             * <p/>
120:             * <pre>
121:             * <p/>
122:             *                 &lt;fragment name=&quot;(\s*${elementName}\s*\.)?\s*allInstances.*&quot;
123:             *                              handlerMethod=&quot;handleAllInstances&quot;&gt;
124:             *                     &lt;kind name=&quot;body&quot;&gt;
125:             *                         from $completeElementName as $lowerCaseElementName
126:             *                     &lt;/kind&gt;
127:             *                 &lt;/fragment&gt;
128:             * <p/>
129:             * </pre>
130:             * <p/>
131:             * </p>
132:             * <p/>
133:             * And the implementation of the <code>handleAllInstances</code> method would be:
134:             * <p/>
135:             * <pre>
136:             * public void handleAllInstances(String translation, Object node)
137:             * {
138:             * //some handling code
139:             * }
140:             * </pre>
141:             * <p/>
142:             * </p>
143:             *
144:             * @param node the node being parsed, the toString value of this node is what is matched against the translation
145:             *             fragment. We also need to pass the node to our <a href="#handlerMethod">handlerMethod </a> so that it
146:             *             can be used it for additional processing (if we need it).
147:             * @see getTranslationFragment(java.lang.String)
148:             */
149:            protected void handleTranslationFragment(Object node) {
150:                ExceptionUtils.checkNull("node", node);
151:                if (this .libraryTranslation != null) {
152:                    this .libraryTranslation.handleTranslationFragment(
153:                            TranslationUtils.trimToEmpty(node), this 
154:                                    .getExpression().getKind(), node);
155:                }
156:            }
157:
158:            /**
159:             * Finds the "fragment" with the specified <code>fragmentName</code> from the library translation file.
160:             * <p/>
161:             * <strong>IMPORTANT: </strong> as a best practice, it is recommended that you use <a
162:             * href="#handleTranslationFragment(org.andromda.core.translation.parser.node.Node)">handleTranslationFragment(Node
163:             * node) </a> if at all possible (instead of this method), it will help your code be cleaner and the methods smaller
164:             * and more maintainable. </p>
165:             * <p/>
166:             * Will retrieve the contents of the fragment <code>kind</code> that corresponds to the kind of expression currently
167:             * being translated. (i.e. if <code>'context LegalAgreement inv: allInstances -> isUnique(documentTitle')</code>' is
168:             * being translated, then the body of the element &lt;kind name="inv"&gt; would be returned). </p>
169:             * <p/>
170:             * <strong>NOTE: </strong>You would use this method <strong>instead </strong> of <a
171:             * href="#handleTranslationFragment(org.andromda.core.translation.parser.node.Node)">handleTranslationFragment(Node
172:             * node) </a> if you just want to retrieve the value of the fragment and don't want to have a <a
173:             * href="#handlerMethod">handlerMethod </a> which actually handles the processing of the output. For example you may
174:             * want to add a fragment called 'constraintTail' which would always be added to your translation at the end of the
175:             * constraint, the 'tail'. There isn't any part of the expression that matches this, but you still want to store it
176:             * in a translation template since it could be different between translations within your Translation-Library. </p>
177:             *
178:             * @param fragmentName the name of the fragment to retrieve from the translation
179:             * @return String the output String from the translated fragment.
180:             * @see #handleTranslationFragment(Node node)
181:             */
182:            protected String getTranslationFragment(String fragmentName) {
183:                ExceptionUtils.checkEmpty("fragmentName", fragmentName);
184:                String fragmentString = null;
185:                if (this .libraryTranslation != null) {
186:                    fragmentString = this .libraryTranslation
187:                            .getTranslationFragment(fragmentName, this 
188:                                    .getExpression().getKind());
189:                }
190:                return fragmentString;
191:            }
192:
193:            /**
194:             * Performs any initlization. Subclasses should override this method if they want to provide any initilization
195:             * before translation begins.
196:             */
197:            public void preProcess() {
198:                this .contextElement = null;
199:            }
200:
201:            /**
202:             * <p/>
203:             * <strong>NOTE: </strong> null is allowed for contextElement (even though it isn't within
204:             * ExpressionTranslator.translate() since the TraceTranslator doesn't need a <code>contextElement</code> and we
205:             * don't want to slow down the trace by having to read and load a model each time. </p>
206:             *
207:             * @see org.andromda.core.translation.ExpressionTranslator#translate( java.lang.String, java.lang.Object,
208:             *      java.lang.String)
209:             */
210:            public Expression translate(String translationName,
211:                    String expression, Object contextElement) {
212:                ExceptionUtils.checkEmpty("translationName", translationName);
213:                ExceptionUtils.checkEmpty("expression", expression);
214:                try {
215:                    // pre processing
216:                    this .preProcess();
217:                    // set the context element so translators extending this have the
218:                    // context element available
219:                    this .setContextElement(contextElement);
220:                    Map templateObjects = new HashMap();
221:                    this .libraryTranslation = LibraryTranslationFinder
222:                            .findLibraryTranslation(translationName);
223:                    final String variable = this .libraryTranslation
224:                            .getVariable();
225:                    if (variable != null) {
226:                        templateObjects.put(variable, contextElement);
227:                    }
228:                    if (this .libraryTranslation != null) {
229:                        libraryTranslation.getLibrary().initialize();
230:                        libraryTranslation.processTranslation(templateObjects);
231:                        this .process(expression);
232:                        libraryTranslation.getLibrary().shutdown();
233:                    }
234:                    // post processing
235:                    this .postProcess();
236:                } catch (Exception ex) {
237:                    String errMsg = "Error translating with translation '"
238:                            + translationName + "'," + " contextElement '"
239:                            + contextElement + "' and expression --> '"
240:                            + expression + "'" + "\nMESSAGE --> '"
241:                            + ex.getMessage() + "'";
242:                    logger.error(errMsg);
243:                    throw new TranslatorException(errMsg, ex);
244:                }
245:                return translatedExpression;
246:            }
247:
248:            /**
249:             * Parses the expression and applies this Translator to it.
250:             *
251:             * @param expression the expression to process.
252:             * @throws IOException if an IO error occurs during processing.
253:             */
254:            protected void process(final String expression) throws IOException {
255:                ExceptionUtils.checkEmpty("expression", expression);
256:                try {
257:                    Lexer lexer = new Lexer(new PushbackReader(
258:                            new StringReader(expression)));
259:                    OclParser parser = new OclParser(lexer);
260:                    Start startNode = parser.parse();
261:                    this .translatedExpression = new Expression(expression);
262:                    startNode.apply(this );
263:                } catch (ParserException ex) {
264:                    throw new OclParserException(ex.getMessage());
265:                } catch (LexerException ex) {
266:                    throw new OclParserException(ex.getMessage());
267:                }
268:            }
269:
270:            /**
271:             * Performs any post processing. Subclasses should override to perform any final cleanup/processing.
272:             */
273:            public void postProcess() {
274:                // currently does nothing --> sub classes should override to perform
275:                // final processing
276:            }
277:
278:            /* The Following Are Overriden Parser Generated Methods */
279:
280:            /**
281:             * Sets the kind and name of the expression for <code>inv</code> expressions. If subclasses override this method,
282:             * they <strong>MUST </strong> call this method before their own implementation.
283:             *
284:             * @param expressionBody
285:             */
286:            public void inAInvClassifierExpressionBody(
287:                    AInvClassifierExpressionBody expressionBody) {
288:                ExceptionUtils.checkNull("expressionBody", expressionBody);
289:                if (this .translatedExpression != null) {
290:                    this .translatedExpression.setName(TranslationUtils
291:                            .trimToEmpty(expressionBody.getName()));
292:                    this .translatedExpression.setKind(ExpressionKinds.INV);
293:                }
294:            }
295:
296:            /**
297:             * Sets the kind and name of the expression for <code>def</code> expressions. If subclasses override this method,
298:             * they <strong>MUST </strong> call this method before their own implementation.
299:             *
300:             * @param expressionBody
301:             */
302:            public void inADefClassifierExpressionBody(
303:                    ADefClassifierExpressionBody expressionBody) {
304:                ExceptionUtils.checkNull("expressionBody", expressionBody);
305:                if (this .translatedExpression != null) {
306:                    this .translatedExpression.setName(TranslationUtils
307:                            .trimToEmpty(expressionBody.getName()));
308:                    this .translatedExpression.setKind(ExpressionKinds.DEF);
309:                }
310:            }
311:
312:            /**
313:             * Sets the kind and name of the expression for operation contexts. If subclasses override this method, they
314:             * <strong>MUST </strong> call this method before their own implementation.
315:             *
316:             * @param operationExpressionBody
317:             */
318:            public void inAOperationExpressionBody(
319:                    AOperationExpressionBody operationExpressionBody) {
320:                ExceptionUtils.checkNull("operationExpressionBody",
321:                        operationExpressionBody);
322:
323:                if (this .translatedExpression != null) {
324:                    // sets the name of the expression
325:                    this .translatedExpression.setName(TranslationUtils
326:                            .getPropertyAsString(operationExpressionBody,
327:                                    "name"));
328:
329:                    // sets the kind of the expression (body, post, or pre)
330:                    this .translatedExpression.setKind(TranslationUtils
331:                            .getPropertyAsString(operationExpressionBody,
332:                                    "operationStereotype"));
333:                }
334:            }
335:
336:            /**
337:             * Sets the element type which represents the context of the expression for expressions having operations as their
338:             * context. If subclasses override this method, they <strong>MUST </strong> call this method before their own
339:             * implementation.
340:             *
341:             * @param declaration the AOperationContextDeclaration instance from which we retrieve the element type.
342:             */
343:            public void inAOperationContextDeclaration(
344:                    AOperationContextDeclaration declaration) {
345:                final String methodName = "BaseTranslator.inAOperationContextDeclaration";
346:                if (logger.isDebugEnabled()) {
347:                    logger.debug("performing " + methodName
348:                            + " with declaration --> " + declaration);
349:                }
350:                if (this .translatedExpression != null) {
351:                    this .translatedExpression
352:                            .setContextElement(ConcreteSyntaxUtils.getType(
353:                                    declaration.getName(), declaration
354:                                            .getPathNameTail()));
355:                }
356:                this .operation = ConcreteSyntaxUtils
357:                        .getOperationDeclaration(declaration.getOperation());
358:            }
359:
360:            /**
361:             * Stores the operation declartion of constraint (if the context is an operation).
362:             */
363:            private OperationDeclaration operation;
364:
365:            /**
366:             * Gets the operation declaration of the constraint (if the context is an operation), otherwise returns null.
367:             *
368:             * @return the operation declaration or null.
369:             */
370:            protected OperationDeclaration getOperation() {
371:                return this .operation;
372:            }
373:
374:            /**
375:             * Indicates if the given <code>argument</code> is an operation argument (if the context declaration is an
376:             * operation)
377:             *
378:             * @param argument the argument to check.
379:             * @return true/false
380:             */
381:            protected boolean isOperationArgument(final String argument) {
382:                return this .operation != null
383:                        && ConcreteSyntaxUtils.getArgumentNames(
384:                                operation.getArguments()).contains(argument);
385:            }
386:
387:            /**
388:             * Sets the element type which represents the context of the expression for expressions having classifiers as their
389:             * context. If subclasses override this method, they <strong>MUST </strong> call this method before their own
390:             * implementation.
391:             *
392:             * @param declaration the AClassifierContextDeclaration instance from which we retrieve the element type.
393:             */
394:            public void inAClassifierContextDeclaration(
395:                    AClassifierContextDeclaration declaration) {
396:                final String methodName = "BaseTranslator.inAClassifierContextDeclaration";
397:                if (logger.isDebugEnabled()) {
398:                    logger.debug("performing " + methodName
399:                            + " with declaration --> " + declaration);
400:                }
401:                if (this.translatedExpression != null) {
402:                    this.translatedExpression
403:                            .setContextElement(ConcreteSyntaxUtils.getType(
404:                                    declaration.getName(), declaration
405:                                            .getPathNameTail()));
406:                }
407:            }
408:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.