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