blob: 3995314256b565056434a4877cd44112ea288841 [file] [log] [blame]
Ernesto Posse8a4f2962015-05-12 13:28:46 -04001/*******************************************************************************
2* Copyright (c) 2015 Zeligsoft (2009) Limited and others.
3* All rights reserved. This program and the accompanying materials
4* are made available under the terms of the Eclipse Public License v1.0
5* which accompanies this distribution, and is available at
6* http://www.eclipse.org/legal/epl-v10.html
7*******************************************************************************/
8
9package org.eclipse.papyrusrt.codegen.xtumlrt.trans
10
11import java.io.IOException
12import java.nio.file.Path
13import java.nio.file.Paths
14import java.util.Collection
15import java.util.Collections
16import java.util.List
17import java.util.Set
18
19import com.google.common.collect.BiMap
20import com.google.common.collect.HashBiMap
21import org.eclipse.core.runtime.IStatus
22import org.eclipse.core.runtime.MultiStatus
23import org.eclipse.emf.common.util.URI
24import org.eclipse.emf.ecore.EObject
25import org.eclipse.emf.ecore.resource.Resource
26import org.eclipse.emf.ecore.resource.ResourceSet
27import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
28import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl
29import org.eclipse.papyrus.umlrt.UMLRealTime.RTMessageKind
30import org.eclipse.papyrusrt.codegen.CodeGenPlugin
31import org.eclipse.papyrusrt.codegen.utils.UML2CppUtil
32import org.eclipse.papyrusrt.xtumlrt.common.Attribute
33import org.eclipse.papyrusrt.xtumlrt.common.Capsule
34import org.eclipse.papyrusrt.xtumlrt.common.CapsuleKind
35import org.eclipse.papyrusrt.xtumlrt.common.CapsulePart
36import org.eclipse.papyrusrt.xtumlrt.common.CommonFactory
37import org.eclipse.papyrusrt.xtumlrt.common.Connector
38import org.eclipse.papyrusrt.xtumlrt.common.ConnectorEnd
39import org.eclipse.papyrusrt.xtumlrt.common.DirectionKind
40import org.eclipse.papyrusrt.xtumlrt.common.Entity
41import org.eclipse.papyrusrt.xtumlrt.common.Model
42import org.eclipse.papyrusrt.xtumlrt.common.MultiplicityElement
43import org.eclipse.papyrusrt.xtumlrt.common.NamedElement
44import org.eclipse.papyrusrt.xtumlrt.common.Operation
45import org.eclipse.papyrusrt.xtumlrt.common.Package
46import org.eclipse.papyrusrt.xtumlrt.common.Parameter
47import org.eclipse.papyrusrt.xtumlrt.common.Port
48import org.eclipse.papyrusrt.xtumlrt.common.PrimitiveType
49import org.eclipse.papyrusrt.xtumlrt.common.Protocol
50import org.eclipse.papyrusrt.xtumlrt.common.ProtocolBehaviourFeatureKind
51import org.eclipse.papyrusrt.xtumlrt.common.RedefinableElement
52import org.eclipse.papyrusrt.xtumlrt.common.Signal
53import org.eclipse.papyrusrt.xtumlrt.common.StateMachine
54import org.eclipse.papyrusrt.xtumlrt.common.StructMember
55import org.eclipse.papyrusrt.xtumlrt.common.StructType
56import org.eclipse.papyrusrt.xtumlrt.common.Type
57import org.eclipse.papyrusrt.xtumlrt.common.VisibilityKind
58import org.eclipse.papyrusrt.xtumlrt.umlrt.PortRegistration
59import org.eclipse.papyrusrt.xtumlrt.umlrt.RTPassiveClass
60import org.eclipse.papyrusrt.xtumlrt.umlrt.RTPort
61import org.eclipse.papyrusrt.xtumlrt.umlrt.UmlrtFactory
62import static extension org.eclipse.papyrusrt.codegen.utils.UMLRealTimeProfileUtil.*
63import static extension org.eclipse.papyrusrt.codegen.utils.GeneralUtil.*
64import org.eclipse.emf.common.util.Enumerator
65
66/**
67 * This class translates models from the UML2 meta-model (org.eclipse.uml2) into the xtUMLrt
68 * meta-model (org.eclipse.papyrusrt.xtumlrt).
69 *
70 * <p>Each element is mapped to the corresponding element by a method. There are a few cases where
71 * the same input element may be mapped into more than one kind of output element. For example
72 * a UML2 Package may be mapped to an xtUMLrt Package, but a UML2 Package which is a protocol
73 * container, as defined in the UML-RT profile, is mapped to an xtUMLrt protocol. Similarly,
74 * a UML2 Class may be mapped to a Capsule, an rtPassiveClass or a xtClass. In these cases, the
75 * output type of the corresponding method is the least-common ancestor in the (meta-class)
76 * type hierarchy.
77 *
78 * <p>The translation is recursive on the structure of elements, this is, the translation of
79 * composite elements (elements which may contain other elements), also translates its
80 * contained elements. This rule applies not only for "Composition" references: for example,
81 * when translating a capsule, we need to translate its ports, which have a protocol as type,
82 * so we need to get the translation of the protocol as well, even though it is not owned by
83 * neither the port nor the capsule. In order to avoid translating the same elements twice, and
84 * to avoid generation cycles, many of these methods are 'create' methods, which only create
85 * the relevant element the first time and cache the result so that future invocations of the
86 * translate method return the same translated element.
87 *
88 * @author Ernesto Posse
89 */
90 @SuppressWarnings( "deprecated" )
91class UML2xtumlrtModelTranslator extends UML2xtumlrtTranslator
92{
93
94 static val XTUMLRT_EXTENSION = "xtumlrt"
95 List<EObject> targets
96 Path outputPath
97 BiMap<EObject, NamedElement> generated
98 Set<EObject> changed
99 UML2xtumlrtSMTranslator stateMachineTranslator
100 static val RTS_MODEL_LIB_CLASSES =
101 #[
102 "UMLRTSignal",
103 "UMLRTMessage",
104 "UMLRTCommsPort",
105 "UMLRTCapsulePart",
106 "UMLRTCapsuleId",
107 "UMLRTTimerId",
108 "UMLRTTimeSpec"
109 ]
110 static val RTS_MODEL_LIB_PROTOCOLS =
111 #[
112 "UMLRTBaseCommProtocol",
113 "UMLRTFrameProtocol",
114 "UMLRTLogProtocol",
115 "UMLRTTimerProtocol"
116 ]
117 static val RTS_MODEL_LIB_DATATYPES =
118 #[
119 "UMLRTCommsPort",
120 "UMLRTCapsulePart"
121 ]
122 static val RTS_MODEL_LIB_ENUMS =
123 #[
124 "Priorities"
125 ]
126
127 new ()
128 {
129 this.generated = HashBiMap.create
130 this.changed = newHashSet
131 this.stateMachineTranslator = new UML2xtumlrtSMTranslator( this )
132 init
133 }
134
135 new ( List<EObject> targets, Path outputPath )
136 {
137 this()
138 this.targets = targets
139 this.outputPath = outputPath
140 }
141
142 private static def init()
143 {
144 val registry = Resource.Factory.Registry.INSTANCE
145 registry.extensionToFactoryMap.put( XTUMLRT_EXTENSION, new XMIResourceFactoryImpl )
146 }
147
148 def setChangeSet( Collection<EObject> changedElements )
149 {
150 changed.addAll( changedElements )
151 }
152
153 def setTargets( List<EObject> targets )
154 {
155 this.targets = targets
156 }
157
158 def setOutputPath( Path outputPath )
159 {
160 this.outputPath = outputPath
161 }
162
163 def IStatus generate()
164 {
165 var MultiStatus result = new MultiStatus( CodeGenPlugin.ID, IStatus.INFO, "UML-RT to xtUMLrt translator invoked", null );
166 try
167 {
168 for (element : changed)
169 {
170 resetTranslateCache( element )
171 }
172 var start = System.currentTimeMillis();
173 for (target : targets)
174 {
175 if ( !(target instanceof org.eclipse.uml2.uml.Element) )
176 {
177 result.add( CodeGenPlugin.info( "Ignoring element " + target.toString() + ": it is not a UML2 element." ) )
178 }
179 else
180 {
181 generated.put( target, translate( target as org.eclipse.uml2.uml.Element ) as NamedElement )
182 }
183 }
184 changed = newHashSet
185 result.add( CodeGenPlugin.info("Translated model to xtUMLrt sucessfully " + (System.currentTimeMillis() - start) + "ms") )
186 }
187 catch (Exception e)
188 {
189 result.add( CodeGenPlugin.error("Error while translating model to xtUMLrt", e) )
190 }
191 result
192 }
193
194 def List<EObject> getAllGenerated()
195 {
196 generated.values.map[ it as EObject ].toList
197 }
198
199 def NamedElement getGenerated( EObject eObject )
200 {
201 generated.get( eObject )
202 }
203
204 def EObject getSource( NamedElement element )
205 {
206 generated.inverse.get( element )
207 }
208
209 def boolean write()
210 {
211 var boolean success = true
212 val ResourceSet resourceSet = new ResourceSetImpl
213 for (target : targets)
214 {
215 val uri = target.eResource().getURI();
216 val elementPath = Paths.get( uri.path() );
217 val fileName = elementPath.fileName.toString
218 val fileNameWithoutExt = fileName.substring(0, fileName.lastIndexOf('.'))
219 val newFileName = fileNameWithoutExt + "." + XTUMLRT_EXTENSION
220 val fullPath = outputPath.resolve( newFileName ).toString
221 val resource = resourceSet.createResource( URI.createFileURI( fullPath ))
222 resource.contents.add( generated.get( target ) )
223 try
224 {
225 resource.save( Collections.EMPTY_MAP )
226 }
227 catch (IOException e)
228 {
229 success = false
230 }
231 }
232 success
233 }
234
235 override EObject translateElement( org.eclipse.uml2.uml.Element umlElement )
236 {
237 val translated = translate( umlElement )
238 if (!(translated instanceof EObject))
239 throw new TranslationException( umlElement, "-", org.eclipse.uml2.uml.Element, EObject, umlElement.class, translated.class, "The result of translating this element did not yield an EMF object")
240 translated as EObject
241 }
242
243 override def Enumerator translateKind( Enum<?> kind )
244 {
245 val translated = translateEnum( kind )
246 if (!(translated instanceof Enumerator))
247 throw new TranslationException( kind, "-", Enum , Enumerator, kind.class, translated?.class, "The result of translating this element did not yield an EMF Enumerator")
248 translated as Enumerator
249 }
250
251
252 /**
253 * Sets the 'redefines' reference of a RedefinableElement in the target meta-model to the
254 * translation of the element it redefines (assuming it's only one at most).
255 *
256 * <p>This method does not create the RedefinableElement in the target meta-model. That
257 * instance is created by any of the other {@code translate} methods, and this one just
258 * updates the {@code refines} reference to the (translated) element being refined.
259 */
260 protected def translateRedefinableElement
261 (
262 org.eclipse.uml2.uml.RedefinableElement element,
263 RedefinableElement newElement
264 )
265 {
266 if (element.redefinedElements !== null && !element.redefinedElements.empty)
267 {
268 val redefinedElement = element.redefinedElements.get(0)
269 newElement.redefines = translate( redefinedElement ) as RedefinableElement
270 }
271 }
272
273 protected def translateMultiplicityElement
274 (
275 org.eclipse.uml2.uml.MultiplicityElement element,
276 MultiplicityElement newElement
277 )
278 {
279 newElement.unique = element.unique
280 newElement.ordered = element.ordered
281 newElement.lowerBound = element.lowerBound
282 newElement.upperBound = element.upperBound
283 }
284
285 /**
286 * Translates a package.
287 *
288 * <p>In UML-RT, protocols are represented as a collection of elements (a collaboration,
289 * some interfaces, etc.) grouped together in a package container. This method decides
290 * whether it is dealing with a "normal" package, or a "protocol container" package, and
291 * invokes the relevant translation.
292 *
293 * @param packge - A {@link org.eclipse.uml2.uml.Package}
294 * @return Either an xtUMLrt {@link Package} or a {@link Protocol} if the input is a
295 * protocol container.
296 */
297 dispatch def NamedElement
298 create
299 if (packge.isRTSModelLibraryProtocolContainer)
300 translateRTSLibraryProtocolContainer( packge )
301 else if (packge instanceof org.eclipse.uml2.uml.Model)
302 translateModel( packge )
303 else if (packge.isProtocolContainer)
304 translateProtocolContainer( packge )
305 else
306 translatePackage( packge )
307 translate( org.eclipse.uml2.uml.Package packge )
308 {
309 name = packge.name
310 UML2xtumlrtCppProfileTranslator.translateStereotypedElement( packge, it )
311 }
312
313 def boolean isRTSModelLibraryProtocolContainer( org.eclipse.uml2.uml.Package packge )
314 {
315 RTS_MODEL_LIB_PROTOCOLS.contains( packge.name )
316 }
317
318 protected def Protocol translateRTSLibraryProtocolContainer( org.eclipse.uml2.uml.Package packge )
319 {
320 val it = CommonFactory.eINSTANCE.createProtocol
321 name = packge.name
322 it
323 }
324
325 protected def Model translateModel( org.eclipse.uml2.uml.Model model )
326 {
327 val it = CommonFactory.eINSTANCE.createModel
328 for (element : model.packagedElements)
329 {
330 if (element instanceof org.eclipse.uml2.uml.Class)
331 topEntities.addIfNotPresent( translate(element) as Entity )
332 else if (element.isProtocolContainer)
333 topProtocols.addIfNotPresent( translate(element) as Protocol )
334 else if (element instanceof org.eclipse.uml2.uml.Package)
335 rootPackages.addIfNotPresent( translate(element) as Package )
336 }
337 it
338 }
339
340 protected def Protocol translateProtocolContainer( org.eclipse.uml2.uml.Package packge )
341 {
342 translate( packge.protocolCollaboration ) as Protocol
343 }
344
345 protected def Package translatePackage( org.eclipse.uml2.uml.Package packge )
346 {
347 val it = CommonFactory.eINSTANCE.createPackage
348 for (element : packge.packagedElements)
349 {
350 if (element instanceof org.eclipse.uml2.uml.Class)
351 entities.addIfNotPresent( translate(element) as Entity )
352 else if (element.isProtocolContainer)
353 protocols.addIfNotPresent( translate(element) as Protocol )
354 else if (element instanceof org.eclipse.uml2.uml.Package)
355 packages.addIfNotPresent( translate(element) as Package )
356 }
357 it
358 }
359
360 /**
361 * @param collaboration - A {@link org.eclipse.uml2.uml.Collaboration}
362 * @return A {@link Protocol} if the collaboration is a protocol, {@code null} otherwise
363 */
364 dispatch def Protocol
365 create
366 if (collaboration.isRTSModelLibraryProtocol)
367 translateRTSModelLibraryProtocol( collaboration )
368 else if (collaboration.isProtocol)
369 translateProtocol( collaboration )
370 translate( org.eclipse.uml2.uml.Collaboration collaboration )
371 {
372 name = collaboration.name
373 translateRedefinableElement( collaboration, it )
374 }
375
376 def boolean isRTSModelLibraryProtocol( org.eclipse.uml2.uml.Collaboration collaboration )
377 {
378 RTS_MODEL_LIB_PROTOCOLS.contains( collaboration.name )
379 }
380
381 protected def translateRTSModelLibraryProtocol( org.eclipse.uml2.uml.Collaboration collaboration )
382 {
383 translateProtocol( collaboration )
384 }
385
386 protected def Protocol translateProtocol( org.eclipse.uml2.uml.Collaboration collaboration )
387 {
388 val it = CommonFactory.eINSTANCE.createProtocol
389 name = collaboration.name
390 for (iface : collaboration.allRealizedInterfaces) // Q: what's the difference between this and allImplementedInterfaces?
391 {
392 if (iface.isRTMessageSet)
393 {
394 val rtMsgKind = iface.getRTMessageSet.rtMsgKind
395 if (rtMsgKind == RTMessageKind.IN || rtMsgKind == RTMessageKind.IN_OUT)
396 {
397 for (operation : iface.ownedOperations)
398 {
399 protocolBehaviourFeatures.add( translate(operation) as Signal )
400 }
401 }
402 }
403 }
404 for (iface : collaboration.allUsedInterfaces())
405 {
406 if (iface.isRTMessageSet)
407 {
408 val rtMsgKind = iface.getRTMessageSet.rtMsgKind
409 if (rtMsgKind == RTMessageKind.OUT || rtMsgKind == RTMessageKind.IN_OUT)
410 {
411 for (operation : iface.ownedOperations)
412 {
413 protocolBehaviourFeatures.add( translate(operation) as Signal )
414 }
415 }
416 }
417 }
418 it
419 }
420
421 /**
422 * @param operation - A {@link org.eclipse.uml2.uml.Operation}
423 * @return A {@link Operation}
424 */
425 dispatch def NamedElement
426 create
427 if (operation.interface.isRTMessageSet)
428 translateSignal( operation )
429 else
430 translateOperation( operation )
431 translate( org.eclipse.uml2.uml.Operation operation )
432 {
433 name = operation.name
434 UML2xtumlrtCppProfileTranslator.translateStereotypedElement( operation, it )
435 }
436
437 protected def Operation translateOperation( org.eclipse.uml2.uml.Operation operation )
438 {
439 val it = CommonFactory.eINSTANCE.createOperation
440 for (parameter : operation.ownedParameters)
441 {
442 parameters.add( translate(parameter) as Parameter )
443 }
444 returnType = translateFeature( operation, "type", org.eclipse.uml2.uml.Type, Type ) as Type
445 val actionCode = CommonFactory.eINSTANCE.createActionCode
446 actionCode.source = UML2CppUtil.getCppCode( operation )
447 body = actionCode
448 it
449 }
450
451 protected def translateSignal( org.eclipse.uml2.uml.Operation operation )
452 {
453 val it = CommonFactory.eINSTANCE.createSignal
454 for (parameter : operation.ownedParameters)
455 {
456 parameters.add( translate(parameter) as Parameter )
457 }
458 if (operation.interface.isRTMessageSet)
459 {
460 val rtMsgKind = operation.interface.getRTMessageSet.rtMsgKind
461 switch (rtMsgKind)
462 {
463 case RTMessageKind.IN: kind = ProtocolBehaviourFeatureKind.IN
464 case RTMessageKind.OUT: kind = ProtocolBehaviourFeatureKind.OUT
465 case RTMessageKind.IN_OUT: kind = ProtocolBehaviourFeatureKind.INOUT
466 }
467 }
468 it
469 }
470
471 /**
472 * @param klass - A {@link org.eclipse.uml2.uml.Class}
473 * @return An {@link Entity}: either a {@link Capsule}, {@link RTPassiveClass} or
474 * {@link xtClass}.
475 */
476 dispatch def Type
477 create
478 if (klass.isRTSModelLibraryClass)
479 translateRTSModelLibraryClass( klass ) as PrimitiveType
480 else if (klass.isCapsule)
481 translateCapsule( klass ) as Entity
482 else
483 translateRTPassiveClass( klass ) as Entity
484 translate( org.eclipse.uml2.uml.Class klass )
485 {
486 name = klass.name
487 UML2xtumlrtCppProfileTranslator.translateStereotypedElement( klass, it )
488 }
489
490 protected def boolean isRTSModelLibraryClass( org.eclipse.uml2.uml.Class klass )
491 {
492 RTS_MODEL_LIB_CLASSES.contains( klass.name )
493 }
494
495 protected def translateRTSModelLibraryClass( org.eclipse.uml2.uml.Class klass )
496 {
497 val it = CommonFactory.eINSTANCE.createPrimitiveType
498 name = klass.name
499 it
500 }
501
502 protected def translateBasicClass( org.eclipse.uml2.uml.Class klass, Entity newClass )
503 {
504 for (attribute : klass.ownedAttributes)
505 {
506 if (!attribute.isRTPort && !attribute.isCapsulePart)
507 newClass.attributes.add( translate(attribute) as Attribute )
508 }
509 for (operation : klass.ownedOperations)
510 {
511 newClass.operations.add( translate(operation) as Operation )
512 }
513 if (klass.ownedBehaviors !== null
514 && !klass.ownedBehaviors.empty
515 && klass.ownedBehaviors.get(0) instanceof org.eclipse.uml2.uml.StateMachine)
516 {
517 var org.eclipse.uml2.uml.StateMachine stateMachine =
518 klass.ownedBehaviors.get(0) as org.eclipse.uml2.uml.StateMachine
519 newClass.behaviour = translate( stateMachine ) as StateMachine
520 }
521 }
522
523 protected def Capsule translateCapsule( org.eclipse.uml2.uml.Class klass )
524 {
525 val it = CommonFactory.eINSTANCE.createCapsule
526 translateBasicClass( klass, it )
527 translateRedefinableElement( klass, it )
528 for (part : klass.capsuleParts)
529 {
530 parts.add( translate(part) as CapsulePart )
531 }
532 for (port : klass.RTPorts)
533 {
534 ports.add( translate(port) as Port )
535 }
536 for (connector : klass.RTConnectors)
537 {
538 connectors.add( translate(connector) as Connector )
539 }
540 it
541 }
542
543 protected def RTPassiveClass translateRTPassiveClass( org.eclipse.uml2.uml.Class klass )
544 {
545 val it = UmlrtFactory.eINSTANCE.createRTPassiveClass
546 translateBasicClass( klass, it )
547 translateRedefinableElement( klass, it )
548 it
549 }
550
551 /**
552 * @param property - A {@link org.eclipse.uml2.uml.Property}
553 * @return An {@link Attribute} or {@link CapsulePart}
554 */
555 dispatch def NamedElement
556 create
557 {
558 val newProperty =
559 if (property.isCapsulePart)
560 translateCapsulePart( property )
561 else if (property.isRTPort)
562 translateRTPort( property )
563 else
564 translateAttribute( property )
565 newProperty as NamedElement
566 }
567 translate( org.eclipse.uml2.uml.Property property )
568 {
569 name = property.name
570 translateMultiplicityElement( property, it as MultiplicityElement )
571 UML2xtumlrtCppProfileTranslator.translateStereotypedElement( property, it )
572 }
573
574 protected def Attribute translateAttribute( org.eclipse.uml2.uml.Property property )
575 {
576 val it = CommonFactory.eINSTANCE.createAttribute
577 type = translateFeature( property, "type", org.eclipse.uml2.uml.Type, Type ) as Type
578 visibility = translateEnumFeature( property, "visibility", org.eclipse.uml2.uml.VisibilityKind, VisibilityKind ) as VisibilityKind
579 it
580 }
581
582 protected def CapsulePart translateCapsulePart( org.eclipse.uml2.uml.Property property )
583 {
584 val it = CommonFactory.eINSTANCE.createCapsulePart
585 type = translateFeature( property, "type", org.eclipse.uml2.uml.Class, Capsule ) as Capsule
586 if (property.lower == 0)
587 {
588 if (property.aggregation == org.eclipse.uml2.uml.AggregationKind.SHARED_LITERAL)
589 {
590 kind = CapsuleKind.PLUGIN
591 }
592 else
593 {
594 kind = CapsuleKind.OPTIONAL
595 }
596 }
597 else
598 {
599 kind = CapsuleKind.FIXED
600 }
601 it
602 }
603
604 protected def Port translatePort( org.eclipse.uml2.uml.Property property )
605 {
606 val it = CommonFactory.eINSTANCE.createPort
607 type = translateFeature( property, "type", org.eclipse.uml2.uml.Collaboration, Protocol ) as Protocol
608 conjugate = (property as org.eclipse.uml2.uml.Port).conjugated
609 it
610 }
611
612 protected def RTPort translateRTPort( org.eclipse.uml2.uml.Property property )
613 {
614 val it = UmlrtFactory.eINSTANCE.createRTPort
615 type = translateFeature( property, "type", org.eclipse.uml2.uml.Collaboration, Protocol ) as Protocol
616 conjugate = (property as org.eclipse.uml2.uml.Port).conjugated
617 val rtPort = property.getRTPort
618 if (rtPort !== null)
619 {
620 notification = rtPort.notification
621 publish = rtPort.publish
622 wired = rtPort.wired
623 switch ( rtPort.registration )
624 {
625 case AUTOMATIC: registration = PortRegistration.AUTOMATIC
626 case APPLICATION: registration = PortRegistration.APPLICATION
627 case APPLICATION_LOCKED: registration = PortRegistration.APPLICATIONLOCKED
628 }
629 }
630 it
631 }
632
633 /**
634 * @param connector - A {@link org.eclipse.uml2.uml.Connector}
635 * @return A {@link Connector}
636 */
637 dispatch def Connector translate( org.eclipse.uml2.uml.Connector connector )
638 {
639 val it = CommonFactory.eINSTANCE.createConnector
640 name = connector.name
641 for (end : connector.ends)
642 {
643 ends.add( translate(end) as ConnectorEnd )
644 }
645 it
646 }
647
648 /**
649 * @param connectorEnd - A {@link org.eclipse.uml2.uml.ConnectorEnd}
650 * @return A {@link ConnectorEnd}
651 */
652 dispatch def ConnectorEnd translate( org.eclipse.uml2.uml.ConnectorEnd connectorEnd )
653 {
654 val it = CommonFactory.eINSTANCE.createConnectorEnd
655 role = translateFeature( connectorEnd, "role", org.eclipse.uml2.uml.Port, Port ) as Port
656 partWithPort =
657 if (connectorEnd.partWithPort === null)
658 null
659 else
660 translateFeature( connectorEnd, "partWithPort", org.eclipse.uml2.uml.Property, CapsulePart ) as CapsulePart
661 it
662 }
663
664 /**
665 * @param parameter - A {@link org.eclipse.uml2.uml.Parameter}
666 * @return A {@link Parameter}
667 */
668 dispatch def Parameter
669 create CommonFactory.eINSTANCE.createParameter
670 translate( org.eclipse.uml2.uml.Parameter parameter )
671 {
672 name = parameter.name
673 type = translateFeature( parameter, "type", org.eclipse.uml2.uml.Type, Type ) as Type
674 direction = translateEnumFeature( parameter, "direction", org.eclipse.uml2.uml.ParameterDirectionKind, DirectionKind ) as DirectionKind
675 UML2xtumlrtCppProfileTranslator.translateStereotypedElement( parameter, it )
676 }
677
678 /**
679 * @param type - A {@link org.eclipse.uml2.uml.DataType}
680 * @return A {@link StructType} or {@link PrimitiveType}
681 */
682 dispatch def Type
683 create
684 if (dataType.isRTSModelLibraryDataType)
685 translateRTSModelLibraryDataType( dataType )
686 else if (dataType instanceof org.eclipse.uml2.uml.PrimitiveType)
687 translatePrimitiveType( dataType )
688 else
689 translateStructType( dataType )
690 translate( org.eclipse.uml2.uml.DataType dataType )
691 {
692 name = dataType.name
693 // Do not translate unknown types
694 }
695
696 def boolean isRTSModelLibraryDataType( org.eclipse.uml2.uml.DataType dataType )
697 {
698 RTS_MODEL_LIB_DATATYPES.contains( dataType )
699 }
700
701 protected def translateRTSModelLibraryDataType( org.eclipse.uml2.uml.DataType dataType )
702 {
703 val it = CommonFactory.eINSTANCE.createPrimitiveType
704 name = dataType.name
705 it
706 }
707
708 protected def PrimitiveType translatePrimitiveType
709 (
710 org.eclipse.uml2.uml.PrimitiveType primitiveType
711 )
712 {
713 val newType = CommonFactory.eINSTANCE.createPrimitiveType
714 switch (primitiveType)
715 {
716 case org.eclipse.uml2.types.TypesPackage.eINSTANCE.boolean: newType.name = "Boolean"
717 case org.eclipse.uml2.types.TypesPackage.eINSTANCE.integer: newType.name = "Integer"
718 case org.eclipse.uml2.types.TypesPackage.eINSTANCE.string: newType.name = "String"
719 case org.eclipse.uml2.types.TypesPackage.eINSTANCE.real: newType.name = "Real"
720 case org.eclipse.uml2.types.TypesPackage.eINSTANCE.unlimitedNatural: newType.name = "UnlimitedNatural"
721 default: newType.name = primitiveType.name
722 }
723 newType
724 }
725
726 protected def StructType translateStructType
727 (
728 org.eclipse.uml2.uml.DataType dataType
729 )
730 {
731 val newType = CommonFactory.eINSTANCE.createStructType
732 for ( attr : dataType.getAllAttributes )
733 {
734 newType.structMembers.add( translateStructMember( attr ) )
735 }
736 newType
737 }
738
739 protected def StructMember translateStructMember
740 (
741 org.eclipse.uml2.uml.Property attribute
742 )
743 {
744 val member = CommonFactory.eINSTANCE.createStructMember
745 member.name = attribute.name
746 member.type = translateFeature( attribute ,"type", org.eclipse.uml2.uml.Type, Type ) as Type
747 member
748 }
749
750 /**
751 * @param type - A {@link org.eclipse.uml2.uml.Type}
752 * @return A {@link Type}
753 */
754 dispatch def Type translate( org.eclipse.uml2.uml.Type type )
755 {
756 // Do not translate unknown types
757 }
758
759 /**
760 * @param stateMachine - A {@link org.eclipse.uml2.uml.StateMachine}
761 * @return A {@link StateMachine}
762 */
763 dispatch def StateMachine translate( org.eclipse.uml2.uml.StateMachine stateMachine )
764 {
765 stateMachineTranslator.translateStateMachine( stateMachine )
766 }
767
768 /**
769 * @param visibilityKind - A {@link org.eclipse.uml2.uml.VisibilityKind}
770 * @return The corresponding {@link VisibilityKind}
771 */
772 dispatch def translateEnum( org.eclipse.uml2.uml.VisibilityKind visibilityKind )
773 {
774 switch (visibilityKind)
775 {
776 case org.eclipse.uml2.uml.VisibilityKind.PUBLIC_LITERAL: VisibilityKind.PUBLIC
777 case org.eclipse.uml2.uml.VisibilityKind.PRIVATE_LITERAL: VisibilityKind.PRIVATE
778 case org.eclipse.uml2.uml.VisibilityKind.PROTECTED_LITERAL: VisibilityKind.PROTECTED
779 default: VisibilityKind.PUBLIC
780 }
781 }
782
783 /**
784 * @param directionKind - A {@link org.eclipse.uml2.uml.ParameterDirectionKind}
785 * @return The corresponding {@link DirectionKind}
786 */
787 dispatch def translateEnum
788 (
789 org.eclipse.uml2.uml.ParameterDirectionKind directionKind
790 )
791 {
792 switch (directionKind)
793 {
794 case org.eclipse.uml2.uml.ParameterDirectionKind.IN_LITERAL: DirectionKind.IN
795 case org.eclipse.uml2.uml.ParameterDirectionKind.OUT_LITERAL: DirectionKind.OUT
796 }
797 }
798
799 /**
800 * @param behavior - A {@link org.eclipse.uml2.uml.Behavior}
801 * @return An {@link ActionCode} instance.
802 */
803 protected def translateActionCode( org.eclipse.uml2.uml.Behavior behavior )
804 {
805 val it = CommonFactory.eINSTANCE.createActionCode
806 source = UML2CppUtil.getCppCode( behavior )
807 it
808 }
809
810
811 def resetTranslateCache( EObject element )
812 {
813 val key = newArrayList( element )
814 _createCache_translate.remove( key )
815 }
816
817}