| /******************************************************************************* |
| * Copyright (c) 2014-2015 Zeligsoft (2009) Limited and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| *******************************************************************************/ |
| package org.eclipse.papyrusrt.codegen.utils |
| |
| import org.eclipse.emf.ecore.util.EcoreUtil |
| import org.eclipse.emf.common.util.URI |
| import org.eclipse.emf.ecore.resource.Resource |
| import org.eclipse.emf.ecore.resource.ResourceSet |
| import org.eclipse.uml2.uml.UMLPackage |
| import org.eclipse.papyrusrt.codegen.CodeGenPlugin |
| import org.eclipse.papyrusrt.xtumlrt.common.CommonElement |
| import org.eclipse.papyrusrt.xtumlrt.common.NamedElement |
| import org.eclipse.papyrusrt.xtumlrt.common.Signal |
| import org.eclipse.papyrusrt.xtumlrt.common.Protocol |
| import org.eclipse.papyrusrt.xtumlrt.common.Model |
| import org.eclipse.papyrusrt.xtumlrt.common.Type |
| import static extension org.eclipse.papyrusrt.codegen.utils.UMLRealTimeProfileUtil.* |
| import static extension org.eclipse.papyrusrt.codegen.utils.XTUMLRTUtil.* |
| import org.eclipse.papyrusrt.xtumlrt.common.CommonFactory |
| |
| class RTSModelLibraryUtils |
| { |
| private static var ResourceSet resourceSet |
| private static var reload = true |
| private static var org.eclipse.uml2.uml.Model RTSModelLibrary |
| |
| public static val RTS_LIB_ANNOTATION_NAME = "RTSLibraryElement"; |
| |
| /** UML RTS Model Library */ |
| public static val RTS_MODLIB_PATHMAP = "pathmap://UMLRTRTSLIB/UMLRT-RTS.uml"; |
| public static val RTS_MODLIB_ROOT_ID = "_mPjAgGXmEeS_4daqvwyFrg"; |
| |
| /** Registered name and URI of the RTS Model Library */ |
| public static val RTS_LIBRARY_NAME = "UMLRT-RTS" |
| public static val RTS_LIBRARY_URI = URI.createURI(RTS_MODLIB_PATHMAP).appendFragment(RTS_MODLIB_ROOT_ID) |
| public static val RTS_LIBRARY_URI_STR = RTS_LIBRARY_URI.toPlatformString( false ) |
| |
| /** Textual (xtumlrt) RTS Model Library */ |
| public static val T_RTS_MODLIB_PATHMAP = "pathmap://UMLRTRTSLIB/TUMLRT-RTS.umlrt"; |
| |
| /** Registered name and URI of the RTS Model Library */ |
| public static val T_RTS_LIBRARY_NAME = "RTSLibrary" |
| public static val T_RTS_LIBRARY_URI = URI.createURI(T_RTS_MODLIB_PATHMAP) |
| public static val T_RTS_LIBRARY_URI_STR = T_RTS_LIBRARY_URI.toPlatformString( false ) |
| |
| /** Protocol names */ |
| public static val FRAME_PROTOCOL_NAME = "Frame" |
| public static val TIMING_PROTOCOL_NAME = "Timing" |
| public static val LOG_PROTOCOL_NAME = "Log" |
| public static val BASECOMM_PROTOCOL_NAME = "UMLRTBaseCommProtocol" |
| |
| /** Protocol message names: Timing */ |
| public static val TIMEOUT_MESSAGE_NAME = "timeout" |
| |
| /** Protocol message names: BaseComm */ |
| public static val RTBOUND_MESSAGE_NAME = "rtBound" |
| public static val RTUNBOUND_MESSAGE_NAME = "rtUnbound" |
| |
| /** Type names */ |
| public static val CAPSULE_ID_TYPE_NAME = "UMLRTCapsuleId" |
| public static val TIMER_ID_TYPE_NAME = "UMLRTTimerId" |
| public static val TIME_SPEC_TYPE_NAME = "UMLRTTimespec" |
| public static val TIME_SPEC_2_TYPE_NAME = "UMLRTTimeSpec" |
| |
| /** Packages */ |
| public static val INTERNAL_PACKAGE_NAME = "Internal" |
| |
| /** Protocol elements */ |
| private static var org.eclipse.uml2.uml.Collaboration FRAME_PROTOCOL = null |
| private static var org.eclipse.uml2.uml.Collaboration TIMING_PROTOCOL = null |
| private static var org.eclipse.uml2.uml.Collaboration LOG_PROTOCOL = null |
| private static var org.eclipse.uml2.uml.Collaboration BASECOMM_PROTOCOL = null |
| |
| /** Protocol message elements: Timing */ |
| private static var TIMEOUT_MESSAGE = null |
| |
| /** Protocol message names: BaseComm */ |
| private static var RTBOUND_MESSAGE = null |
| private static var RTUNBOUND_MESSAGE = null |
| |
| static def addSysAnnotation( NamedElement element ) |
| { |
| val sysAnnotation = CommonFactory.eINSTANCE.createAnnotation |
| sysAnnotation.name = RTS_LIB_ANNOTATION_NAME |
| element.annotations.add( sysAnnotation ) |
| } |
| |
| static def loadPackage( URI fullURI ) |
| { |
| if (resourceSet === null) |
| { |
| CodeGenPlugin.warning( "Unable to load package " + fullURI.toPlatformString(true) + "; Resource set is null" ) |
| return null |
| } |
| val Resource resource = resourceSet.getResource( fullURI, true ) |
| if (resource === null) |
| { |
| CodeGenPlugin.warning( "Unable to load package " + fullURI.toPlatformString(true) + "; resource is null" ) |
| return null |
| } |
| val contents = resource.getContents() |
| if (contents === null) |
| { |
| CodeGenPlugin.warning( "Unable to load package " + fullURI.toPlatformString(true) + "; contents is null" ) |
| return null |
| } |
| val eobj = EcoreUtil.getObjectByType( contents, UMLPackage.Literals.PACKAGE ) |
| if (eobj === null || !(eobj instanceof org.eclipse.uml2.uml.Package)) |
| { |
| CodeGenPlugin.warning( "Unable to load package " + fullURI.toPlatformString(true) + "; first element is null or not a UML Package" ) |
| return null |
| } |
| val pkg = eobj as org.eclipse.uml2.uml.Package |
| return pkg |
| } |
| |
| static def loadRTSModelLibrary() |
| { |
| if (!reload) return |
| if (resourceSet === null) |
| { |
| CodeGenPlugin.warning( "Unable to load RTS Model Library; Resource set is null" ) |
| return null |
| } |
| val uriConverter = resourceSet.URIConverter |
| if (uriConverter === null) |
| { |
| CodeGenPlugin.warning( "Unable to load RTS Model Library; Resource set's URI converter is null" ) |
| return null |
| } |
| val normalizedRTSLibURI = uriConverter.normalize( RTS_LIBRARY_URI ) |
| val pkg = loadPackage( normalizedRTSLibURI ) |
| if (pkg === null || !(pkg instanceof org.eclipse.uml2.uml.Model)) |
| { |
| CodeGenPlugin.warning( "Unable to load RTS Model Library; contained UML Package is not a UML Model" ) |
| return null |
| } |
| if (!pkg.isModelLibrary) |
| { |
| CodeGenPlugin.warning( "Loaded model is not a model library" ) |
| } |
| if (pkg.qualifiedName != RTS_LIBRARY_NAME) |
| { |
| CodeGenPlugin.warning( "Loaded model library's name is not RTS" ) |
| } |
| RTSModelLibrary = pkg as org.eclipse.uml2.uml.Model |
| } |
| |
| static def reloadRTSModelLibrary() |
| { |
| reload = true |
| loadRTSModelLibrary |
| } |
| |
| static def setReload( boolean flag ) |
| { |
| reload = flag |
| } |
| |
| static def setResourceSet( ResourceSet resSet ) |
| { |
| if (resSet !== resourceSet || resourceSet === null) |
| { |
| resourceSet = resSet |
| reload = true |
| } |
| else |
| { |
| reload = false |
| } |
| } |
| |
| static def getRTSModelLibrary() |
| { |
| RTSModelLibrary |
| } |
| |
| static def getProtocol( org.eclipse.uml2.uml.Package packge, String name ) |
| { |
| val protocolContainer = packge.getPackagedElement( name ) |
| if (protocolContainer !== null && protocolContainer instanceof org.eclipse.uml2.uml.Package) |
| { |
| val protocol = (protocolContainer as org.eclipse.uml2.uml.Package).getPackagedElement( name ) |
| if (protocol !== null && protocol instanceof org.eclipse.uml2.uml.Collaboration) |
| protocol as org.eclipse.uml2.uml.Collaboration |
| |
| } |
| } |
| |
| static def getFrameProtocol() |
| { |
| if (FRAME_PROTOCOL === null || reload) |
| { |
| FRAME_PROTOCOL = getProtocol( RTSModelLibrary, FRAME_PROTOCOL_NAME ) |
| } |
| FRAME_PROTOCOL |
| } |
| |
| static def getTimingProtocol() |
| { |
| if (TIMING_PROTOCOL === null || reload) |
| { |
| TIMING_PROTOCOL = getProtocol( RTSModelLibrary, TIMING_PROTOCOL_NAME ) |
| } |
| TIMING_PROTOCOL |
| } |
| |
| static def getLogProtocol() |
| { |
| if (LOG_PROTOCOL === null || reload) |
| { |
| LOG_PROTOCOL = getProtocol( RTSModelLibrary, LOG_PROTOCOL_NAME ) |
| } |
| LOG_PROTOCOL |
| } |
| |
| static def getBaseCommProtocol() |
| { |
| if (BASECOMM_PROTOCOL === null || reload) |
| { |
| val internalPackage = RTSModelLibrary.getPackagedElement( INTERNAL_PACKAGE_NAME ) |
| if (internalPackage instanceof org.eclipse.uml2.uml.Package) |
| BASECOMM_PROTOCOL = getProtocol( internalPackage, BASECOMM_PROTOCOL_NAME ) |
| } |
| BASECOMM_PROTOCOL |
| } |
| |
| static def getTimeout() |
| { |
| if (TIMEOUT_MESSAGE === null || reload) |
| { |
| TIMEOUT_MESSAGE = timingProtocol.getInProtocolMessages( false ).findFirst[ it.name == TIMEOUT_MESSAGE_NAME ] |
| } |
| TIMEOUT_MESSAGE |
| } |
| |
| static def getRtBound() |
| { |
| if (RTBOUND_MESSAGE === null || reload) |
| { |
| RTBOUND_MESSAGE = baseCommProtocol.getInOutProtocolMessages.findFirst[ it.name == RTBOUND_MESSAGE_NAME ] |
| } |
| RTBOUND_MESSAGE |
| } |
| |
| static def getRtUnbound() |
| { |
| if (RTUNBOUND_MESSAGE === null || reload) |
| { |
| RTUNBOUND_MESSAGE = baseCommProtocol.getInOutProtocolMessages.findFirst[ it.name == RTUNBOUND_MESSAGE_NAME ] |
| } |
| RTUNBOUND_MESSAGE |
| } |
| |
| static def hasSysAnnotation( NamedElement element ) |
| { |
| element !== null |
| && element.annotations !== null |
| && element.annotations.exists[ (it.name == RTS_LIB_ANNOTATION_NAME) ] |
| } |
| |
| /** |
| * Returns true iff the given UML model is the model library. |
| */ |
| static def boolean isRTSModelLibrary( org.eclipse.uml2.uml.Package packge ) |
| { |
| if (packge == RTSModelLibrary) return true |
| val uriConverter = packge.eResource.resourceSet.URIConverter |
| val packageURI = EcoreUtil.getURI( packge ) |
| val normalizedPackageURI = uriConverter.normalize( packageURI ) |
| val normalizedRTSLibURI = uriConverter.normalize( RTS_LIBRARY_URI ) |
| |
| packge instanceof org.eclipse.uml2.uml.Model |
| && packge.getQualifiedName().equals( RTS_LIBRARY_NAME ) |
| // && packge.isModelLibrary() |
| && normalizedPackageURI == normalizedRTSLibURI |
| } |
| |
| /** |
| * Returns true iff the given xtUMLrt model is the model library. |
| * The translator attaches to such model element, an annotation named with |
| * RTS_LIBRARY_ID. This method searches for such annotation. |
| */ |
| static def boolean isRTSModelLibrary( Model model ) |
| { |
| model !== null |
| && model.name == RTS_LIBRARY_NAME |
| && model.isSystemElement |
| } |
| |
| /** |
| * Return true iff the element belongs to the RTS Model Library |
| */ |
| static def boolean isSystemElement( CommonElement element ) |
| { |
| element !== null |
| && element instanceof NamedElement |
| && (element as NamedElement).hasSysAnnotation |
| } |
| |
| static def boolean isSystemElement( org.eclipse.uml2.uml.Element element ) |
| { |
| element.model !== null |
| && element.model.isRTSModelLibrary |
| } |
| |
| static def isCapsuleId( Type type ) |
| { |
| type !== null && type.name !== null |
| && type.name == CAPSULE_ID_TYPE_NAME |
| && isSystemElement( type ) |
| } |
| |
| static def isTextualRTSModelLibrary( Model model ) |
| { |
| if (model === null) return false |
| val uriConverter = model.eResource.resourceSet.URIConverter |
| val packageURI = EcoreUtil.getURI( model ) |
| val normalizedPackageURI = uriConverter.normalize( packageURI ) |
| val normalizedRTSLibURI = uriConverter.normalize( T_RTS_LIBRARY_URI ) |
| |
| model.name == T_RTS_LIBRARY_NAME |
| && normalizedPackageURI.toPlatformString(true) == normalizedRTSLibURI.toPlatformString(true) |
| } |
| |
| static def isTextualSystemElement( CommonElement element ) |
| { |
| element !== null |
| && element.root instanceof Model |
| && isTextualRTSModelLibrary( element.root as Model ) |
| } |
| |
| static def isTimerId( Type type ) |
| { |
| type !== null && type.name !== null |
| && type.name == TIMER_ID_TYPE_NAME |
| && isSystemElement( type ) |
| } |
| |
| static def isTimerSpec( Type type ) |
| { |
| type !== null && type.name !== null |
| && (type.name == TIME_SPEC_2_TYPE_NAME || type.name == TIME_SPEC_TYPE_NAME) // TODO Until Bug 469218 is resolved |
| && isSystemElement( type ) |
| } |
| |
| static def isBaseCommProtocol( Protocol protocol ) |
| { |
| protocol !== null && protocol.name !== null |
| && protocol.name == BASECOMM_PROTOCOL_NAME |
| && isSystemElement( protocol ) |
| } |
| |
| static def isFrameProtocol( Protocol protocol ) |
| { |
| protocol !== null && protocol.name !== null |
| && protocol.name == FRAME_PROTOCOL_NAME |
| && isSystemElement( protocol ) |
| } |
| |
| static def isTimingProtocol( Protocol protocol ) |
| { |
| protocol !== null && protocol.name !== null |
| && protocol.name == TIMING_PROTOCOL_NAME |
| && isSystemElement( protocol ) |
| } |
| |
| static def isLogProtocol( Protocol protocol ) |
| { |
| protocol !== null && protocol.name !== null |
| && protocol.name == LOG_PROTOCOL_NAME |
| && isSystemElement( protocol ) |
| } |
| |
| static def Iterable<Signal> getAllUserSignals( Protocol protocol ) |
| { |
| protocol.allSignals.filter[ !(it.isSystemElement) ] |
| } |
| |
| static def Iterable<Signal> getUserSignals( Protocol protocol ) |
| { |
| protocol.signals.filter[ !(it.isSystemElement) ] |
| } |
| |
| |
| } |