def __init__(self, version=3.0):
        super().__init__(version)
        if self.version >= 4.0:
            self.behavior_parser = BehaviorParser(version)
            self.constant_parser = ConstantParser(version)

        if self.version >= 3.0 and self.version < 4.0:
            self.switcher = {
                'APPLICATION-SOFTWARE-COMPONENT-TYPE':
                self.parseSoftwareComponent,
                'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE':
                self.parseSoftwareComponent,
                'SWC-IMPLEMENTATION': self.parseSwcImplementation,
                'COMPOSITION-TYPE': self.parseCompositionType,
                'CALPRM-COMPONENT-TYPE': self.parseSoftwareComponent,
                'SERVICE-COMPONENT-TYPE': self.parseSoftwareComponent
            }
        elif self.version >= 4.0:
            self.switcher = {
                'APPLICATION-SW-COMPONENT-TYPE': self.parseSoftwareComponent,
                'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE':
                self.parseSoftwareComponent,
                'SERVICE-COMPONENT-TYPE': self.parseSoftwareComponent,
                'PARAMETER-SW-COMPONENT-TYPE': self.parseSoftwareComponent,
                'COMPOSITION-SW-COMPONENT-TYPE': self.parseCompositionType,
                'SENSOR-ACTUATOR-SW-COMPONENT-TYPE':
                self.parseSoftwareComponent,
                'SERVICE-SW-COMPONENT-TYPE': self.parseSoftwareComponent,
                'SWC-IMPLEMENTATION': self.parseSwcImplementation
            }
Example #2
0
 def _registerDefaultElementParsers(self, parser):
     parser.registerElementParser(DataTypeParser(self.version))
     parser.registerElementParser(DataTypeSemanticsParser(self.version))
     parser.registerElementParser(DataTypeUnitsParser(self.version))
     parser.registerElementParser(PortInterfacePackageParser(self.version))
     parser.registerElementParser(SoftwareAddressMethodParser(self.version))
     parser.registerElementParser(ModeDeclarationParser(self.version))
     parser.registerElementParser(ConstantParser(self.version))
     parser.registerElementParser(ComponentTypeParser(self.version))
     parser.registerElementParser(BehaviorParser(self.version))
     parser.registerElementParser(SystemParser(self.version))
     parser.registerElementParser(SignalParser(self.version))
Example #3
0
   def __init__(self,version=3.0):
      super().__init__(version)
      if self.version >=4.0:
         self.behavior_parser = BehaviorParser(version)
         self.constant_parser = ConstantParser(version)

      if self.version >= 3.0 and self.version < 4.0:
         self.switcher = { 'APPLICATION-SOFTWARE-COMPONENT-TYPE': self.parseSoftwareComponent,
                           'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE': self.parseSoftwareComponent,
                           'SWC-IMPLEMENTATION': self.parseSwcImplementation,
                           'COMPOSITION-TYPE': self.parseCompositionType,
                           'CALPRM-COMPONENT-TYPE': self.parseSoftwareComponent,
                           'SERVICE-COMPONENT-TYPE': self.parseSoftwareComponent
                          }
      elif self.version >= 4.0:
         self.switcher = {
            'APPLICATION-SW-COMPONENT-TYPE': self.parseSoftwareComponent,            
            'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE': self.parseSoftwareComponent,
            'SERVICE-COMPONENT-TYPE': self.parseSoftwareComponent,
            'COMPOSITION-SW-COMPONENT-TYPE': self.parseCompositionType,
            'SWC-IMPLEMENTATION': self.parseSwcImplementation
         }
class ComponentTypeParser(ElementParser):
    """
    ComponentType parser
    """
    def __init__(self, version=3.0):
        super().__init__(version)
        if self.version >= 4.0:
            self.behavior_parser = BehaviorParser(version)
            self.constant_parser = ConstantParser(version)

        if self.version >= 3.0 and self.version < 4.0:
            self.switcher = {
                'APPLICATION-SOFTWARE-COMPONENT-TYPE':
                self.parseSoftwareComponent,
                'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE':
                self.parseSoftwareComponent,
                'SWC-IMPLEMENTATION': self.parseSwcImplementation,
                'COMPOSITION-TYPE': self.parseCompositionType,
                'CALPRM-COMPONENT-TYPE': self.parseSoftwareComponent,
                'SERVICE-COMPONENT-TYPE': self.parseSoftwareComponent
            }
        elif self.version >= 4.0:
            self.switcher = {
                'APPLICATION-SW-COMPONENT-TYPE': self.parseSoftwareComponent,
                'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE':
                self.parseSoftwareComponent,
                'SERVICE-COMPONENT-TYPE': self.parseSoftwareComponent,
                'PARAMETER-SW-COMPONENT-TYPE': self.parseSoftwareComponent,
                'COMPOSITION-SW-COMPONENT-TYPE': self.parseCompositionType,
                'SENSOR-ACTUATOR-SW-COMPONENT-TYPE':
                self.parseSoftwareComponent,
                'SERVICE-SW-COMPONENT-TYPE': self.parseSoftwareComponent,
                'SWC-IMPLEMENTATION': self.parseSwcImplementation
            }

    def getSupportedTags(self):
        return self.switcher.keys()

    def parseElement(self, xmlElement, parent=None):
        parseFunc = self.switcher.get(xmlElement.tag)
        if parseFunc is not None:
            return parseFunc(xmlElement, parent)
        else:
            return None

    def parseSoftwareComponent(self, xmlRoot, parent=None):
        componentType = None
        handledTags = ['SHORT-NAME']
        if xmlRoot.tag == 'APPLICATION-SOFTWARE-COMPONENT-TYPE':  #for AUTOSAR 3.x
            componentType = autosar.component.ApplicationSoftwareComponent(
                self.parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        elif xmlRoot.tag == 'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE':  #for AUTOSAR 3.x
            componentType = autosar.component.ComplexDeviceDriverComponent(
                self.parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        elif xmlRoot.tag == 'APPLICATION-SW-COMPONENT-TYPE':  #for AUTOSAR 4.x
            componentType = autosar.component.ApplicationSoftwareComponent(
                self.parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        elif (xmlRoot.tag
              == 'SERVICE-COMPONENT-TYPE') or (xmlRoot.tag
                                               == 'SERVICE-SW-COMPONENT-TYPE'):
            componentType = autosar.component.ServiceComponent(
                self.parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        elif xmlRoot.tag == 'CALPRM-COMPONENT-TYPE':  #for AUTOSAR 3.x
            componentType = autosar.component.ParameterComponent(
                self.parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        elif xmlRoot.tag == 'PARAMETER-SW-COMPONENT-TYPE':  #for AUTOSAR 4.x
            componentType = autosar.component.ParameterComponent(
                self.parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        elif xmlRoot.tag == 'SENSOR-ACTUATOR-SW-COMPONENT-TYPE':  #for AUTOSAR 4.x
            componentType = autosar.component.SensorActuatorComponent(
                self.parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        else:
            raise NotImplementedError(xmlRoot.tag)
        for xmlElem in xmlRoot.findall('./*'):
            if xmlElem.tag not in handledTags:
                if (xmlElem.tag == 'ADMIN-DATA') or (xmlElem.tag == 'DESC'):
                    pass  #Implement later
                elif xmlElem.tag == 'PORTS':
                    self.parseComponentPorts(componentType, xmlRoot)
                elif xmlElem.tag == 'INTERNAL-BEHAVIORS':
                    behaviors = xmlElem.findall('./SWC-INTERNAL-BEHAVIOR')
                    if len(behaviors) > 1:
                        raise ValueError(
                            '%s: an SWC cannot have multiple internal behaviors'
                            % (componentType))
                    elif len(behaviors) == 1:
                        componentType.behavior = self.behavior_parser.parseSWCInternalBehavior(
                            behaviors[0], componentType)
                else:
                    print('Unhandled tag: ' + xmlElem.tag, file=sys.stderr)
        return componentType

    def parseComponentPorts(self, componentType, xmlRoot):
        xmlPorts = xmlRoot.find('PORTS')
        assert (xmlPorts is not None)
        for xmlPort in xmlPorts.findall('*'):
            if (xmlPort.tag == "R-PORT-PROTOTYPE"):
                portName = xmlPort.find('SHORT-NAME').text
                portInterfaceRef = self.parseTextNode(
                    xmlPort.find('REQUIRED-INTERFACE-TREF'))
                port = autosar.port.RequirePort(portName,
                                                portInterfaceRef,
                                                parent=componentType)
                if hasAdminData(xmlPort):
                    port.adminData = parseAdminDataNode(
                        xmlPort.find('ADMIN-DATA'))
                if xmlPort.findall('./REQUIRED-COM-SPECS') is not None:
                    for xmlItem in xmlPort.findall('./REQUIRED-COM-SPECS/*'):
                        if xmlItem.tag == 'CLIENT-COM-SPEC':
                            operationName = _getOperationNameFromComSpec(
                                xmlItem, portInterfaceRef)
                            comspec = autosar.port.OperationComSpec(
                                operationName)
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'UNQUEUED-RECEIVER-COM-SPEC' or xmlItem.tag == 'NONQUEUED-RECEIVER-COM-SPEC':
                            dataElemName = _getDataElemNameFromComSpec(
                                xmlItem, portInterfaceRef)
                            comspec = autosar.port.DataElementComSpec(
                                dataElemName)
                            if xmlItem.find('./ALIVE-TIMEOUT') is not None:
                                comspec.aliveTimeout = self.parseTextNode(
                                    xmlItem.find('./ALIVE-TIMEOUT'))
                            if self.version >= 4.0:
                                xmlElem = xmlItem.find('./INIT-VALUE')
                                if xmlElem != None:
                                    for xmlChild in xmlElem.findall('./*'):
                                        if xmlChild.tag == 'CONSTANT-REFERENCE':
                                            comspec.initValueRef = self.parseTextNode(
                                                xmlChild.find(
                                                    './CONSTANT-REF'))
                                        else:
                                            values = self.constant_parser.parseValueV4(
                                                xmlElem, None)
                                            if len(values) != 1:
                                                raise ValueError(
                                                    'INIT-VALUE cannot cannot contain multiple elements'
                                                )
                                            comspec.initValue = values[0]
                            else:
                                if xmlItem.find('./INIT-VALUE-REF') != None:
                                    comspec.initValueRef = self.parseTextNode(
                                        xmlItem.find('./INIT-VALUE-REF'))
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'QUEUED-RECEIVER-COM-SPEC':
                            dataElemName = _getDataElemNameFromComSpec(
                                xmlItem, portInterfaceRef)
                            comspec = autosar.port.DataElementComSpec(
                                dataElemName)
                            if xmlItem.find('./QUEUE-LENGTH') != None:
                                comspec.queueLength = self.parseTextNode(
                                    xmlItem.find('./QUEUE-LENGTH'))
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'MODE-SWITCH-RECEIVER-COM-SPEC':
                            comspec = self._parseModeSwitchReceiverComSpec(
                                xmlItem)
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'PARAMETER-REQUIRE-COM-SPEC':
                            comspec = self._parseParameterComSpec(
                                xmlItem, portInterfaceRef)
                            port.comspec.append(comspec)
                        else:
                            raise NotImplementedError(xmlItem.tag)
                componentType.requirePorts.append(port)
            elif (xmlPort.tag == 'P-PORT-PROTOTYPE'):
                portName = xmlPort.find('SHORT-NAME').text
                portInterfaceRef = self.parseTextNode(
                    xmlPort.find('PROVIDED-INTERFACE-TREF'))
                port = autosar.port.ProvidePort(portName,
                                                portInterfaceRef,
                                                parent=componentType)
                if hasAdminData(xmlPort):
                    port.adminData = parseAdminDataNode(
                        xmlPort.find('ADMIN-DATA'))
                if xmlPort.findall('./PROVIDED-COM-SPECS') is not None:
                    for xmlItem in xmlPort.findall('./PROVIDED-COM-SPECS/*'):
                        if xmlItem.tag == 'SERVER-COM-SPEC':
                            operationName = _getOperationNameFromComSpec(
                                xmlItem, portInterfaceRef)
                            comspec = autosar.port.OperationComSpec(
                                operationName)
                            comspec.queueLength = self.parseIntNode(
                                xmlItem.find('QUEUE-LENGTH'))
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'UNQUEUED-SENDER-COM-SPEC' or xmlItem.tag == 'NONQUEUED-SENDER-COM-SPEC':
                            dataElemName = _getDataElemNameFromComSpec(
                                xmlItem, portInterfaceRef)
                            comspec = autosar.port.DataElementComSpec(
                                dataElemName)
                            if self.version >= 4.0:
                                xmlElem = xmlItem.find('./INIT-VALUE')
                                if xmlElem != None:
                                    for xmlChild in xmlElem.findall('./*'):
                                        if xmlChild.tag == 'CONSTANT-REFERENCE':
                                            comspec.initValueRef = self.parseTextNode(
                                                xmlChild.find(
                                                    './CONSTANT-REF'))
                                        else:
                                            values = self.constant_parser.parseValueV4(
                                                xmlElem, None)
                                            if len(values) != 1:
                                                raise ValueError(
                                                    'INIT-VALUE cannot cannot contain multiple elements'
                                                )
                                            comspec.initValue = values[0]
                            else:
                                if xmlItem.find(
                                        './INIT-VALUE-REF') is not None:
                                    comspec.initValueRef = self.parseTextNode(
                                        xmlItem.find('./INIT-VALUE-REF'))
                            if xmlItem.find('./CAN-INVALIDATE') != None:
                                comspec.canInvalidate = True if self.parseTextNode(
                                    xmlItem.find('./CAN-INVALIDATE')
                                ) == 'true' else False
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'QUEUED-SENDER-COM-SPEC':
                            dataElemName = _getDataElemNameFromComSpec(
                                xmlItem, portInterfaceRef)
                            comspec = autosar.port.DataElementComSpec(
                                dataElemName)
                            assert (comspec is not None)
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'PARAMETER-PROVIDE-COM-SPEC':
                            comspec = self._parseParameterComSpec(
                                xmlItem, portInterfaceRef)
                            assert (comspec is not None)
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'MODE-SWITCH-SENDER-COM-SPEC':
                            comspec = self._parseModeSwitchSenderComSpec(
                                xmlItem)
                            assert (comspec is not None)
                            port.comspec.append(comspec)
                        else:
                            raise NotImplementedError(xmlItem.tag)
                componentType.providePorts.append(port)

    def parseSwcImplementation(self, xmlRoot, parent=None):
        ws = parent.rootWS()
        assert (ws is not None)
        name = self.parseTextNode(xmlRoot.find('SHORT-NAME'))
        behaviorRef = self.parseTextNode(xmlRoot.find('BEHAVIOR-REF'))
        implementation = autosar.component.SwcImplementation(name,
                                                             behaviorRef,
                                                             parent=parent)
        behavior = ws.find(behaviorRef)
        if behavior is not None:
            swc = ws.find(behavior.componentRef)
            if swc is not None:
                swc.implementation = implementation
        return implementation

    def parseCompositionType(self, xmlRoot, parent=None):
        """
        parses COMPOSITION-TYPE
        """
        assert (xmlRoot.tag
                == 'COMPOSITION-TYPE') or (xmlRoot.tag
                                           == 'COMPOSITION-SW-COMPONENT-TYPE')
        dataTypeMappingRefs = None
        swc = autosar.component.CompositionComponent(
            self.parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        self.push()
        for xmlElem in xmlRoot.findall('./*'):
            if xmlElem.tag == 'SHORT-NAME':
                continue
            elif xmlElem.tag == 'PORTS':
                self.parseComponentPorts(swc, xmlRoot)
            elif xmlElem.tag == 'COMPONENTS':
                self.parseComponents(xmlElem, swc)
            elif xmlElem.tag == 'CONNECTORS':
                if self.version >= 4.0:
                    self.parseConnectorsV4(xmlElem, swc)
                else:
                    self.parseConnectorsV3(xmlElem, swc)
            elif xmlElem.tag == 'DATA-TYPE-MAPPING-REFS':
                dataTypeMappingRefs = []
                for xmlChild in xmlElem.findall('./*'):
                    if xmlChild.tag == 'DATA-TYPE-MAPPING-REF':
                        tmp = self.parseTextNode(xmlChild)
                        assert (tmp is not None)
                        dataTypeMappingRefs.append(tmp)
            else:
                self.defaultHandler(xmlElem)
        if dataTypeMappingRefs is not None:
            swc.dataTypeMappingRefs = dataTypeMappingRefs
        self.pop(swc)
        return swc

    def parseComponents(self, xmlRoot, parent):
        """
        parses <COMPONENTS>
        """
        assert (xmlRoot.tag == 'COMPONENTS')
        for elem in xmlRoot.findall('./*'):
            componentTag = 'SW-COMPONENT-PROTOTYPE' if self.version >= 4.0 else 'COMPONENT-PROTOTYPE'
            if elem.tag == componentTag:
                name = self.parseTextNode(elem.find('SHORT-NAME'))
                typeRef = self.parseTextNode(elem.find('TYPE-TREF'))
                parent.components.append(
                    autosar.component.ComponentPrototype(
                        name, typeRef, parent))
            else:
                raise NotImplementedError(elem.tag)

    def parseConnectorsV3(self, xmlRoot, parent=None):
        """
        parses <CONNECTORS> (AUTOSAR 3)
        """
        assert (xmlRoot.tag == 'CONNECTORS')
        for elem in xmlRoot.findall('./*'):
            if elem.tag == 'ASSEMBLY-CONNECTOR-PROTOTYPE':
                name = self.parseTextNode(elem.find('SHORT-NAME'))
                providerComponentRef = self.parseTextNode(
                    elem.find('./PROVIDER-IREF/COMPONENT-PROTOTYPE-REF'))
                providerPortRef = self.parseTextNode(
                    elem.find('./PROVIDER-IREF/P-PORT-PROTOTYPE-REF'))
                requesterComponentRef = self.parseTextNode(
                    elem.find('./REQUESTER-IREF/COMPONENT-PROTOTYPE-REF'))
                requesterPortRef = self.parseTextNode(
                    elem.find('./REQUESTER-IREF/R-PORT-PROTOTYPE-REF'))
                parent.assemblyConnectors.append(
                    autosar.component.AssemblyConnector(
                        name,
                        autosar.component.ProviderInstanceRef(
                            providerComponentRef, providerPortRef),
                        autosar.component.RequesterInstanceRef(
                            requesterComponentRef, requesterPortRef)))
            elif elem.tag == 'DELEGATION-CONNECTOR-PROTOTYPE':
                name = self.parseTextNode(elem.find('SHORT-NAME'))
                innerComponentRef = self.parseTextNode(
                    elem.find('./INNER-PORT-IREF/COMPONENT-PROTOTYPE-REF'))
                innerPortRef = self.parseTextNode(
                    elem.find('./INNER-PORT-IREF/PORT-PROTOTYPE-REF'))
                outerPortRef = self.parseTextNode(
                    elem.find('./OUTER-PORT-REF'))
                parent.delegationConnectors.append(
                    autosar.component.DelegationConnector(
                        name,
                        autosar.component.InnerPortInstanceRef(
                            innerComponentRef, innerPortRef),
                        autosar.component.OuterPortRef(outerPortRef)))
            else:
                raise NotImplementedError(elem.tag)

    def parseConnectorsV4(self, xmlRoot, parent=None):
        """
        parses <CONNECTORS> (AUTOSAR 4)
        """
        assert (xmlRoot.tag == 'CONNECTORS')
        for xmlElem in xmlRoot.findall('./*'):
            if xmlElem.tag == 'ASSEMBLY-SW-CONNECTOR':
                name = self.parseTextNode(xmlElem.find('SHORT-NAME'))
                for xmlChild in xmlElem.findall('./*'):
                    if xmlChild.tag == 'SHORT-NAME':
                        continue
                    elif xmlChild.tag == 'PROVIDER-IREF':
                        providerComponentRef = self.parseTextNode(
                            xmlChild.find('./CONTEXT-COMPONENT-REF'))
                        providerPortRef = self.parseTextNode(
                            xmlChild.find('./TARGET-P-PORT-REF'))
                    elif xmlChild.tag == 'REQUESTER-IREF':
                        requesterComponentRef = self.parseTextNode(
                            xmlChild.find('./CONTEXT-COMPONENT-REF'))
                        requesterPortRef = self.parseTextNode(
                            xmlChild.find('./TARGET-R-PORT-REF'))
                    else:
                        raise NotImplementedError(xmlChild.tag)
                if providerComponentRef is None:
                    raise RuntimeError(
                        'PROVIDER-IREF/CONTEXT-COMPONENT-REF is missing: item=%s'
                        % name)
                if providerComponentRef is None:
                    raise RuntimeError(
                        'PROVIDER-IREF/TARGET-P-PORT-REF is missing: item=%s' %
                        name)
                if requesterComponentRef is None:
                    raise RuntimeError(
                        'REQUESTER-IREF/CONTEXT-COMPONENT-REF is missing: item=%s'
                        % name)
                if requesterPortRef is None:
                    raise RuntimeError(
                        'REQUESTER-IREF/TARGET-R-PORT-REF is missing: item=%s'
                        % name)

                parent.assemblyConnectors.append(
                    autosar.component.AssemblyConnector(
                        name,
                        autosar.component.ProviderInstanceRef(
                            providerComponentRef, providerPortRef),
                        autosar.component.RequesterInstanceRef(
                            requesterComponentRef, requesterPortRef)))
            elif xmlElem.tag == 'DELEGATION-SW-CONNECTOR':
                name = self.parseTextNode(xmlElem.find('SHORT-NAME'))
                for xmlChild in xmlElem.findall('./INNER-PORT-IREF/*'):
                    if xmlChild.tag == 'R-PORT-IN-COMPOSITION-INSTANCE-REF':
                        innerComponentRef = self.parseTextNode(
                            xmlChild.find('./CONTEXT-COMPONENT-REF'))
                        innerPortRef = self.parseTextNode(
                            xmlChild.find('./TARGET-R-PORT-REF'))
                    elif xmlChild.tag == 'P-PORT-IN-COMPOSITION-INSTANCE-REF':
                        innerComponentRef = self.parseTextNode(
                            xmlChild.find('./CONTEXT-COMPONENT-REF'))
                        innerPortRef = self.parseTextNode(
                            xmlChild.find('./TARGET-P-PORT-REF'))
                    else:
                        raise NotImplementedError(xmlChild.tag)
                outerPortRef = self.parseTextNode(
                    xmlElem.find('./OUTER-PORT-REF'))
                parent.delegationConnectors.append(
                    autosar.component.DelegationConnector(
                        name,
                        autosar.component.InnerPortInstanceRef(
                            innerComponentRef, innerPortRef),
                        autosar.component.OuterPortRef(outerPortRef)))
            else:
                raise NotImplementedError(xmlElem.tag)

    def _parseModeSwitchReceiverComSpec(self, xmlRoot):
        (enhancedMode, supportAsync, modeGroupRef) = (None, None, None)
        assert (xmlRoot.tag == 'MODE-SWITCH-RECEIVER-COM-SPEC')
        for xmlElem in xmlRoot.findall('./*'):
            if xmlElem.tag == 'ENHANCED-MODE-API':
                enhancedMode = self.parseBooleanNode(xmlElem)
            elif xmlElem.tag == 'SUPPORTS-ASYNCHRONOUS-MODE-SWITCH':
                supportAsync = self.parseBooleanNode(xmlElem)
            elif xmlElem.tag == 'MODE-GROUP-REF':
                modeGroupRef = self.parseTextNode(xmlElem)
            else:
                raise NotImplementedError(xmlElem.tag)
        return autosar.port.ModeSwitchComSpec(None,
                                              enhancedMode,
                                              supportAsync,
                                              modeGroupRef=modeGroupRef)

    def _parseModeSwitchSenderComSpec(self, xmlRoot):
        (enhancedMode, queueLength, modeSwitchAckTimeout,
         modeGroupRef) = (None, None, None, None)
        assert (xmlRoot.tag == 'MODE-SWITCH-SENDER-COM-SPEC')
        for xmlElem in xmlRoot.findall('./*'):
            if xmlElem.tag == 'ENHANCED-MODE-API':
                enhancedMode = self.parseBooleanNode(xmlElem)
            elif xmlElem.tag == 'MODE-GROUP-REF':
                modeGroupRef = self.parseTextNode(xmlElem)
            elif xmlElem.tag == 'MODE-SWITCHED-ACK':
                for xmlChild in xmlElem.findall('./*'):
                    if xmlChild.tag == 'TIMEOUT':
                        tmp = self.parseFloatNode(xmlChild)
                        if tmp is not None:
                            modeSwitchAckTimeout = int(
                                tmp * 1000
                            )  #We use milliseconds in our internal model
            elif xmlElem.tag == 'QUEUE-LENGTH':
                queueLength = self.parseIntNode(xmlElem)
            else:
                raise NotImplementedError(xmlElem.tag)
        return autosar.port.ModeSwitchComSpec(None, enhancedMode, None,
                                              queueLength,
                                              modeSwitchAckTimeout,
                                              modeGroupRef)

    def _parseParameterComSpec(self, xmlRoot, portInterfaceRef):
        (initValue, name) = (None, None)
        for xmlElem in xmlRoot.findall('./*'):
            if xmlElem.tag == 'INIT-VALUE':
                values = self.constant_parser.parseValueV4(xmlElem, None)
                if len(values) != 1:
                    raise ValueError(
                        'INIT-VALUE cannot cannot contain multiple elements')
                initValue = values[0]
            elif xmlElem.tag == 'PARAMETER-REF':
                name = _getParameterNameFromComSpec(xmlElem, portInterfaceRef)
            else:
                raise NotImplementedError(xmlElem.tag)
        if (name is not None):
            return autosar.port.ParameterComSpec(name, initValue)
        else:
            raise RuntimeError(
                'PARAMETER-REQUIRE-COM-SPEC must have a PARAMETER-REF')
Example #5
0
    def loadXML(self, package, xmlRoot):
        dataTypeParser = DataTypeParser(self, self.version)
        componentTypeParser = ComponentTypeParser(self, self.version)
        dataTypeSemanticsParser = DataTypeSemanticsParser(self, self.version)
        dataTypeUnitsParser = DataTypeUnitsParser(self, self.version)
        cepParameterGroupPackageParser = CEPParameterGroupPackageParser(
            self, self.version)
        modeDeclarationGroupPackageParser = ModeDeclarationGroupPackageParser(
            self, self.version)
        portInterfacePackageParser = PortInterfacePackageParser(
            self, self.version)
        constantPackageParser = ConstantPackageParser(self, self.version)
        behaviorParser = BehaviorParser(self, self.version)
        signalParser = SignalParser(self, self.version)
        systemParser = SystemParser(self, self.version)

        if self.version == 3:
            self.switcher = {
                'ARRAY-TYPE': dataTypeParser.parseArrayType,
                'BOOLEAN-TYPE': dataTypeParser.parseBooleanType,
                'INTEGER-TYPE': dataTypeParser.parseIntegerType,
                'REAL-TYPE': dataTypeParser.parseRealType,
                'RECORD-TYPE': dataTypeParser.parseRecordType,
                'STRING-TYPE': dataTypeParser.parseStringType,
                'APPLICATION-SOFTWARE-COMPONENT-TYPE':
                componentTypeParser.parseSoftwareComponent,
                'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE':
                componentTypeParser.parseSoftwareComponent,
                'INTERNAL-BEHAVIOR': behaviorParser.parseInternalBehavior,
                'SWC-IMPLEMENTATION':
                componentTypeParser.parseSwcImplementation,
                'COMPU-METHOD': dataTypeSemanticsParser.parseCompuMethod,
                'UNIT': dataTypeUnitsParser.parseUnit,
                'SW-ADDR-METHOD':
                cepParameterGroupPackageParser.parseSWAddrMethod,
                'MODE-DECLARATION-GROUP':
                modeDeclarationGroupPackageParser.parseModeDeclarationGroup,
                'SENDER-RECEIVER-INTERFACE':
                portInterfacePackageParser.parseSenderReceiverInterface,
                'CALPRM-INTERFACE':
                portInterfacePackageParser.parseParameterInterface,
                'CLIENT-SERVER-INTERFACE':
                portInterfacePackageParser.parseClientServerInterface,
                'CONSTANT-SPECIFICATION':
                constantPackageParser.parseConstantSpecification,
                'COMPOSITION-TYPE': componentTypeParser.parseCompositionType,
                'SYSTEM-SIGNAL': signalParser.parseSystemSignal,
                'SYSTEM-SIGNAL-GROUP': signalParser.parseSystemSignalGroup,
                'SYSTEM': systemParser.parseSystem
            }

            if xmlRoot.find('ELEMENTS'):
                elementNames = set([x.name for x in package.elements])
                for xmlElement in xmlRoot.findall('./ELEMENTS/*'):
                    parseFunc = self.switcher.get(xmlElement.tag)
                    if parseFunc is not None:
                        element = parseFunc(xmlElement,
                                            self.rootProject,
                                            parent=package)
                        element.parent = package
                        if isinstance(element,
                                      autosar.element.Element) == True:
                            if element.name not in elementNames:
                                #ignore duplicated items
                                package.append(element)
                                elementNames.add(element.name)
                        else:
                            #raise ValueError("parse error: %s"%type(element))
                            raise ValueError("parse error: %s" %
                                             xmlElement.tag)
                    else:
                        print("unhandled: %s" % xmlElement.tag)
            if xmlRoot.find('SUB-PACKAGES'):
                for xmlPackage in xmlRoot.findall('./SUB-PACKAGES/AR-PACKAGE'):
                    name = xmlPackage.find("./SHORT-NAME").text
                    subPackage = autosar.package.Package(name)
                    self.loadXML(subPackage, xmlPackage)
                    package.subPackages.append(subPackage)
                    subPackage.parent = package
        else:
            raise NotImplementedError('Version of ARXML not supported')
Example #6
0
class ComponentTypeParser(ElementParser):
    """
   ComponentType parser   
   """
    def __init__(self, version=3.0):
        super().__init__(version)
        if self.version >= 4.0:
            self.behavior_parser = BehaviorParser(version)

        if self.version >= 3.0 and self.version < 4.0:
            self.switcher = {
                'APPLICATION-SOFTWARE-COMPONENT-TYPE':
                self.parseSoftwareComponent,
                'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE':
                self.parseSoftwareComponent,
                'SWC-IMPLEMENTATION': self.parseSwcImplementation,
                'COMPOSITION-TYPE': self.parseCompositionType,
                'CALPRM-COMPONENT-TYPE': self.parseSoftwareComponent,
                'SERVICE-COMPONENT-TYPE': self.parseSoftwareComponent
            }
        elif self.version >= 4.0:
            self.switcher = {
                'APPLICATION-SW-COMPONENT-TYPE': self.parseSoftwareComponent,
                'SWC-IMPLEMENTATION': self.parseSwcImplementation
            }

    def getSupportedTags(self):
        return self.switcher.keys()

    def parseElement(self, xmlElement, parent=None):
        parseFunc = self.switcher.get(xmlElement.tag)
        if parseFunc is not None:
            return parseFunc(xmlElement, parent)
        else:
            return None

    def parseSoftwareComponent(self, xmlRoot, parent=None):
        componentType = None
        handledTags = [
            'SHORT-NAME', 'APPLICATION-SOFTWARE-COMPONENT-TYPE',
            'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE',
            'APPLICATION-SW-COMPONENT-TYPE'
        ]
        if xmlRoot.tag == 'APPLICATION-SOFTWARE-COMPONENT-TYPE':  #for AUTOSAR 3.x
            componentType = ApplicationSoftwareComponent(
                parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        elif xmlRoot.tag == 'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE':
            componentType = ComplexDeviceDriverComponent(
                parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        elif xmlRoot.tag == 'APPLICATION-SW-COMPONENT-TYPE':  #for AUTOSAR 4.x
            componentType = ApplicationSoftwareComponent(
                parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        elif xmlRoot.tag == 'SERVICE-COMPONENT-TYPE':
            componentType = ServiceComponent(
                parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        elif xmlRoot.tag == 'CALPRM-COMPONENT-TYPE':
            componentType = ParameterComponent(
                parseTextNode(xmlRoot.find('SHORT-NAME')), parent)
        else:
            raise NotImplementedError(xmlRoot.tag)
        for xmlElem in xmlRoot.findall('./*'):
            if xmlElem.tag not in handledTags:
                if xmlElem.tag == 'PORTS':
                    self.parseComponentPorts(componentType, xmlRoot)
                elif xmlElem.tag == 'INTERNAL-BEHAVIORS':
                    behaviors = xmlElem.findall('./SWC-INTERNAL-BEHAVIOR')
                    if len(behaviors) > 1:
                        raise ValueError(
                            '%s: an SWC cannot have multiple internal behaviors'
                            % (componentType))
                    elif len(behaviors) == 1:
                        componentType.behavior = self.behavior_parser.parseSWCInternalBehavior(
                            behaviors[0], componentType)
                else:
                    print('Unhandled tag: ' + xmlElem.tag, file=sys.stderr)
        return componentType

    def parseComponentPorts(self, componentType, xmlRoot):
        xmlPorts = xmlRoot.find('PORTS')
        assert (xmlPorts is not None)
        for xmlPort in xmlPorts.findall('*'):
            if (xmlPort.tag == "R-PORT-PROTOTYPE"):
                portName = xmlPort.find('SHORT-NAME').text
                portInterfaceRef = parseTextNode(
                    xmlPort.find('REQUIRED-INTERFACE-TREF'))
                port = RequirePort(portName,
                                   portInterfaceRef,
                                   parent=componentType)
                if xmlPort.findall('./REQUIRED-COM-SPECS') is not None:
                    for xmlItem in xmlPort.findall('./REQUIRED-COM-SPECS/*'):
                        if xmlItem.tag == 'CLIENT-COM-SPEC':
                            operationName = _getOperationNameFromComSpec(
                                xmlItem, portInterfaceRef)
                            comspec = OperationComSpec(operationName)
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'UNQUEUED-RECEIVER-COM-SPEC' or xmlItem.tag == 'NONQUEUED-RECEIVER-COM-SPEC':
                            dataElemName = _getDataElemNameFromComSpec(
                                xmlItem, portInterfaceRef)
                            comspec = DataElementComSpec(dataElemName)
                            if xmlItem.find('./ALIVE-TIMEOUT') != None:
                                comspec.aliveTimeout = parseTextNode(
                                    xmlItem.find('./ALIVE-TIMEOUT'))
                            if self.version >= 4.0:
                                if xmlItem.find('./INIT-VALUE') != None:
                                    comspec.initValueRef = parseTextNode(
                                        xmlItem.find(
                                            './INIT-VALUE/CONSTANT-REFERENCE/CONSTANT-REF'
                                        ))
                            else:
                                if xmlItem.find('./INIT-VALUE-REF') != None:
                                    comspec.initValueRef = parseTextNode(
                                        xmlItem.find('./INIT-VALUE-REF'))
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'QUEUED-RECEIVER-COM-SPEC':
                            dataElemName = _getDataElemNameFromComSpec(
                                xmlItem, portInterfaceRef)
                            comspec = DataElementComSpec(dataElemName)
                            if xmlItem.find('./QUEUE-LENGTH') != None:
                                comspec.queueLength = parseTextNode(
                                    xmlItem.find('./QUEUE-LENGTH'))
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'MODE-SWITCH-RECEIVER-COM-SPEC':
                            pass  #TODO: implement later
                        elif xmlItem.tag == 'PARAMETER-REQUIRE-COM-SPEC':
                            pass  #TODO: implement later
                        else:
                            raise NotImplementedError(xmlItem.tag)
                componentType.requirePorts.append(port)
            elif (xmlPort.tag == 'P-PORT-PROTOTYPE'):
                portName = xmlPort.find('SHORT-NAME').text
                portInterfaceRef = parseTextNode(
                    xmlPort.find('PROVIDED-INTERFACE-TREF'))
                port = ProvidePort(portName,
                                   portInterfaceRef,
                                   parent=componentType)
                if xmlPort.findall('./PROVIDED-COM-SPECS') is not None:
                    for xmlItem in xmlPort.findall('./PROVIDED-COM-SPECS/*'):
                        if xmlItem.tag == 'SERVER-COM-SPEC':
                            operationName = _getOperationNameFromComSpec(
                                xmlItem, portInterfaceRef)
                            comspec = OperationComSpec(operationName)
                            comspec.queueLength = parseIntNode(
                                xmlItem.find('QUEUE-LENGTH'))
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'UNQUEUED-SENDER-COM-SPEC' or xmlItem.tag == 'NONQUEUED-SENDER-COM-SPEC':
                            dataElemName = _getDataElemNameFromComSpec(
                                xmlItem, portInterfaceRef)
                            comspec = DataElementComSpec(dataElemName)
                            if self.version >= 4.0:
                                if xmlItem.find('./INIT-VALUE') != None:
                                    comspec.initValueRef = parseTextNode(
                                        xmlItem.find(
                                            './INIT-VALUE/CONSTANT-REFERENCE/CONSTANT-REF'
                                        ))
                            else:
                                if xmlItem.find('./INIT-VALUE-REF') != None:
                                    comspec.initValueRef = parseTextNode(
                                        xmlItem.find('./INIT-VALUE-REF'))
                            if xmlItem.find('./CAN-INVALIDATE') != None:
                                comspec.canInvalidate = True if parseTextNode(
                                    xmlItem.find('./CAN-INVALIDATE')
                                ) == 'true' else False
                            port.comspec.append(comspec)
                        elif xmlItem.tag == 'QUEUED-SENDER-COM-SPEC':
                            dataElemName = _getDataElemNameFromComSpec(
                                xmlItem, portInterfaceRef)
                            comspec = DataElementComSpec(dataElemName)
                            port.comspec.append(comspec)
                        else:
                            raise NotImplementedError(xmlItem.tag)
                componentType.providePorts.append(port)

    def parseSwcImplementation(self, xmlRoot, parent=None):
        ws = parent.rootWS()
        assert (ws is not None)
        name = parseTextNode(xmlRoot.find('SHORT-NAME'))
        behaviorRef = parseTextNode(xmlRoot.find('BEHAVIOR-REF'))
        implementation = SwcImplementation(name, behaviorRef, parent=parent)
        behavior = ws.find(behaviorRef)
        if behavior is not None:
            swc = ws.find(behavior.componentRef)
            if swc is not None:
                swc.implementation = implementation
        return implementation

    def parseCompositionType(self, xmlRoot, parent=None):
        """
      parses COMPOSITION-TYPE
      """
        assert (xmlRoot.tag == 'COMPOSITION-TYPE')
        swc = CompositionComponent(parseTextNode(xmlRoot.find('SHORT-NAME')),
                                   parent)
        for elem in xmlRoot.findall('./*'):
            if elem.tag == 'SHORT-NAME':
                continue
            if elem.tag == 'PORTS':
                self.parseComponentPorts(swc, xmlRoot)
            elif elem.tag == 'COMPONENTS':
                self.parseComponents(elem, swc)
            elif elem.tag == 'CONNECTORS':
                self.parseConnectors(elem, swc)
            else:
                raise NotImplementedError(elem.tag)
        return swc

    def parseComponents(self, xmlRoot, parent):
        """
      parses <COMPONENTS>
      """
        assert (xmlRoot.tag == 'COMPONENTS')
        for elem in xmlRoot.findall('./*'):
            if elem.tag == 'COMPONENT-PROTOTYPE':
                name = parseTextNode(elem.find('SHORT-NAME'))
                typeRef = parseTextNode(elem.find('TYPE-TREF'))
                parent.components.append(
                    ComponentPrototype(name, typeRef, parent))
            else:
                raise NotImplementedError(elem.tag)

    def parseConnectors(self, xmlRoot, parent=None):
        """
      parses <CONNECTORS>
      """
        assert (xmlRoot.tag == 'CONNECTORS')
        for elem in xmlRoot.findall('./*'):
            if elem.tag == 'ASSEMBLY-CONNECTOR-PROTOTYPE':
                name = parseTextNode(elem.find('SHORT-NAME'))
                providerComponentRef = parseTextNode(
                    elem.find('./PROVIDER-IREF/COMPONENT-PROTOTYPE-REF'))
                providerPortRef = parseTextNode(
                    elem.find('./PROVIDER-IREF/P-PORT-PROTOTYPE-REF'))
                requesterComponentRef = parseTextNode(
                    elem.find('./REQUESTER-IREF/COMPONENT-PROTOTYPE-REF'))
                requesterPortRef = parseTextNode(
                    elem.find('./REQUESTER-IREF/R-PORT-PROTOTYPE-REF'))
                parent.assemblyConnectors.append(
                    AssemblyConnector(
                        name,
                        ProviderInstanceRef(providerComponentRef,
                                            providerPortRef),
                        RequesterInstanceRef(requesterComponentRef,
                                             requesterPortRef)))
            elif elem.tag == 'DELEGATION-CONNECTOR-PROTOTYPE':
                name = parseTextNode(elem.find('SHORT-NAME'))
                innerComponentRef = parseTextNode(
                    elem.find('./INNER-PORT-IREF/COMPONENT-PROTOTYPE-REF'))
                innerPortRef = parseTextNode(
                    elem.find('./INNER-PORT-IREF/PORT-PROTOTYPE-REF'))
                outerPortRef = parseTextNode(elem.find('./OUTER-PORT-REF'))
                parent.delegationConnectors.append(
                    DelegationConnector(
                        name,
                        InnerPortInstanceRef(innerComponentRef, innerPortRef),
                        OuterPortRef(outerPortRef)))
            else:
                raise NotImplementedError(elem.tag)
Example #7
0
class ComponentTypeParser(ElementParser):
   """
   ComponentType parser
   """

   def __init__(self,version=3.0):
      super().__init__(version)
      if self.version >=4.0:
         self.behavior_parser = BehaviorParser(version)
         self.constant_parser = ConstantParser(version)

      if self.version >= 3.0 and self.version < 4.0:
         self.switcher = { 'APPLICATION-SOFTWARE-COMPONENT-TYPE': self.parseSoftwareComponent,
                           'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE': self.parseSoftwareComponent,
                           'SWC-IMPLEMENTATION': self.parseSwcImplementation,
                           'COMPOSITION-TYPE': self.parseCompositionType,
                           'CALPRM-COMPONENT-TYPE': self.parseSoftwareComponent,
                           'SERVICE-COMPONENT-TYPE': self.parseSoftwareComponent
                          }
      elif self.version >= 4.0:
         self.switcher = {
            'APPLICATION-SW-COMPONENT-TYPE': self.parseSoftwareComponent,            
            'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE': self.parseSoftwareComponent,
            'SERVICE-COMPONENT-TYPE': self.parseSoftwareComponent,
            'COMPOSITION-SW-COMPONENT-TYPE': self.parseCompositionType,
            'SWC-IMPLEMENTATION': self.parseSwcImplementation
         }

   def getSupportedTags(self):
      return self.switcher.keys()

   def parseElement(self, xmlElement, parent = None):
      parseFunc = self.switcher.get(xmlElement.tag)
      if parseFunc is not None:
         return parseFunc(xmlElement,parent)
      else:
         return None

   def parseSoftwareComponent(self,xmlRoot,parent=None):
      componentType=None
      handledTags = ['SHORT-NAME','APPLICATION-SOFTWARE-COMPONENT-TYPE', 'COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE', 'APPLICATION-SW-COMPONENT-TYPE']
      if xmlRoot.tag=='APPLICATION-SOFTWARE-COMPONENT-TYPE': #for AUTOSAR 3.x
         componentType = autosar.component.ApplicationSoftwareComponent(self.parseTextNode(xmlRoot.find('SHORT-NAME')),parent)
      elif xmlRoot.tag=='COMPLEX-DEVICE-DRIVER-COMPONENT-TYPE':
         componentType = autosar.component.ComplexDeviceDriverComponent(self.parseTextNode(xmlRoot.find('SHORT-NAME')),parent)
      elif xmlRoot.tag == 'APPLICATION-SW-COMPONENT-TYPE': #for AUTOSAR 4.x
         componentType = autosar.component.ApplicationSoftwareComponent(self.parseTextNode(xmlRoot.find('SHORT-NAME')),parent)
      elif xmlRoot.tag == 'SERVICE-COMPONENT-TYPE':
         componentType = autosar.component.ServiceComponent(self.parseTextNode(xmlRoot.find('SHORT-NAME')),parent)
      elif xmlRoot.tag == 'CALPRM-COMPONENT-TYPE':
         componentType = autosar.component.ParameterComponent(self.parseTextNode(xmlRoot.find('SHORT-NAME')),parent)
      else:
         raise NotImplementedError(xmlRoot.tag)
      for xmlElem in xmlRoot.findall('./*'):
         if xmlElem.tag not in handledTags:
            if xmlElem.tag == 'PORTS':
               self.parseComponentPorts(componentType,xmlRoot)
            elif xmlElem.tag == 'INTERNAL-BEHAVIORS':
               behaviors = xmlElem.findall('./SWC-INTERNAL-BEHAVIOR')
               if len(behaviors)>1:
                  raise ValueError('%s: an SWC cannot have multiple internal behaviors'%(componentType))
               elif len(behaviors) == 1:
                  componentType.behavior = self.behavior_parser.parseSWCInternalBehavior(behaviors[0], componentType)
            else:
               print('Unhandled tag: '+xmlElem.tag, file=sys.stderr)
      return componentType

   def parseComponentPorts(self,componentType,xmlRoot):
      xmlPorts=xmlRoot.find('PORTS')
      assert(xmlPorts is not None)
      for xmlPort in xmlPorts.findall('*'):
         if(xmlPort.tag == "R-PORT-PROTOTYPE"):
            portName = xmlPort.find('SHORT-NAME').text
            portInterfaceRef = self.parseTextNode(xmlPort.find('REQUIRED-INTERFACE-TREF'))
            port = autosar.component.RequirePort(portName,portInterfaceRef,parent=componentType)
            if xmlPort.findall('./REQUIRED-COM-SPECS') is not None:
               for xmlItem in xmlPort.findall('./REQUIRED-COM-SPECS/*'):
                  if xmlItem.tag == 'CLIENT-COM-SPEC':
                     operationName=_getOperationNameFromComSpec(xmlItem,portInterfaceRef)
                     comspec=autosar.component.OperationComSpec(operationName)
                     port.comspec.append(comspec)
                  elif xmlItem.tag == 'UNQUEUED-RECEIVER-COM-SPEC' or xmlItem.tag == 'NONQUEUED-RECEIVER-COM-SPEC':
                     dataElemName = _getDataElemNameFromComSpec(xmlItem,portInterfaceRef)
                     comspec = autosar.component.DataElementComSpec(dataElemName)
                     if xmlItem.find('./ALIVE-TIMEOUT') is not None:
                        comspec.aliveTimeout = self.parseTextNode(xmlItem.find('./ALIVE-TIMEOUT'))
                     if self.version >= 4.0:
                        xmlElem = xmlItem.find('./INIT-VALUE')
                        if xmlElem != None:
                           for xmlChild in xmlElem.findall('./*'):
                              if xmlChild.tag == 'CONSTANT-REFERENCE':
                                 comspec.initValueRef = self.parseTextNode(xmlChild.find('./CONSTANT-REF'))
                              else:
                                 values = self.constant_parser.parseValueV4(xmlElem, None)
                                 if len(values) != 1:
                                    raise ValueError('INIT-VALUE cannot cannot contain multiple elements')
                                 comspec.initValue = values[0]
                     else:
                        if xmlItem.find('./INIT-VALUE-REF') != None:
                           comspec.initValueRef = self.parseTextNode(xmlItem.find('./INIT-VALUE-REF'))
                     port.comspec.append(comspec)
                  elif xmlItem.tag == 'QUEUED-RECEIVER-COM-SPEC':
                     dataElemName = _getDataElemNameFromComSpec(xmlItem,portInterfaceRef)
                     comspec = autosar.component.DataElementComSpec(dataElemName)
                     if xmlItem.find('./QUEUE-LENGTH') != None:
                        comspec.queueLength = self.parseTextNode(xmlItem.find('./QUEUE-LENGTH'))
                     port.comspec.append(comspec)
                  elif xmlItem.tag == 'MODE-SWITCH-RECEIVER-COM-SPEC':
                     comspec = self._parseModeSwitchComSpec(xmlItem)
                     port.comspec.append(comspec)
                  elif xmlItem.tag == 'PARAMETER-REQUIRE-COM-SPEC':
                     comspec = self._parseParameterComSpec(xmlItem, portInterfaceRef)
                     port.comspec.append(comspec)
                  else:
                     raise NotImplementedError(xmlItem.tag)
            componentType.requirePorts.append(port)
         elif(xmlPort.tag == 'P-PORT-PROTOTYPE'):
            portName = xmlPort.find('SHORT-NAME').text
            portInterfaceRef = self.parseTextNode(xmlPort.find('PROVIDED-INTERFACE-TREF'))
            port = autosar.component.ProvidePort(portName,portInterfaceRef,parent=componentType)
            if xmlPort.findall('./PROVIDED-COM-SPECS') is not None:
               for xmlItem in xmlPort.findall('./PROVIDED-COM-SPECS/*'):
                  if xmlItem.tag == 'SERVER-COM-SPEC':
                     operationName=_getOperationNameFromComSpec(xmlItem,portInterfaceRef)
                     comspec=autosar.component.OperationComSpec(operationName)
                     comspec.queueLength=self.parseIntNode(xmlItem.find('QUEUE-LENGTH'))
                     port.comspec.append(comspec)
                  elif xmlItem.tag == 'UNQUEUED-SENDER-COM-SPEC' or xmlItem.tag == 'NONQUEUED-SENDER-COM-SPEC':
                     dataElemName = _getDataElemNameFromComSpec(xmlItem,portInterfaceRef)
                     comspec = autosar.component.DataElementComSpec(dataElemName)
                     if self.version >= 4.0:
                        xmlElem = xmlItem.find('./INIT-VALUE')
                        if xmlElem != None:
                           for xmlChild in xmlElem.findall('./*'):
                              if xmlChild.tag == 'CONSTANT-REFERENCE':
                                 comspec.initValueRef = self.parseTextNode(xmlChild.find('./CONSTANT-REF'))
                              else:
                                 values = self.constant_parser.parseValueV4(xmlElem, None)
                                 if len(values) != 1:
                                    raise ValueError('INIT-VALUE cannot cannot contain multiple elements')
                                 comspec.initValue = values[0]
                     else:
                        if xmlItem.find('./INIT-VALUE-REF') is not None:
                           comspec.initValueRef = self.parseTextNode(xmlItem.find('./INIT-VALUE-REF'))
                     if xmlItem.find('./CAN-INVALIDATE') != None:
                        comspec.canInvalidate = True if self.parseTextNode(xmlItem.find('./CAN-INVALIDATE'))=='true' else False
                     port.comspec.append(comspec)
                  elif xmlItem.tag == 'QUEUED-SENDER-COM-SPEC':
                     dataElemName = _getDataElemNameFromComSpec(xmlItem,portInterfaceRef)
                     comspec = autosar.component.DataElementComSpec(dataElemName)
                     port.comspec.append(comspec)
                  else:
                     raise NotImplementedError(xmlItem.tag)
            componentType.providePorts.append(port)

   def parseSwcImplementation(self,xmlRoot,parent=None):
      ws = parent.rootWS()
      assert(ws is not None)
      name = self.parseTextNode(xmlRoot.find('SHORT-NAME'))
      behaviorRef = self.parseTextNode(xmlRoot.find('BEHAVIOR-REF'))
      implementation = autosar.component.SwcImplementation(name,behaviorRef,parent=parent)
      behavior = ws.find(behaviorRef)
      if behavior is not None:
         swc = ws.find(behavior.componentRef)
         if swc is not None:
            swc.implementation=implementation
      return implementation

   def parseCompositionType(self,xmlRoot,parent=None):
      """
      parses COMPOSITION-TYPE
      """
      assert (xmlRoot.tag=='COMPOSITION-TYPE') or (xmlRoot.tag=='COMPOSITION-SW-COMPONENT-TYPE')
      swc=autosar.component.CompositionComponent(self.parseTextNode(xmlRoot.find('SHORT-NAME')),parent)
      for elem in xmlRoot.findall('./*'):
         if elem.tag=='SHORT-NAME':
            continue
         if elem.tag=='PORTS':
            self.parseComponentPorts(swc,xmlRoot)
         elif elem.tag=='COMPONENTS':
            self.parseComponents(elem,swc)
         elif elem.tag=='CONNECTORS':
            if self.version >= 4.0:
               self.parseConnectorsV4(elem,swc)
            else:
               self.parseConnectorsV3(elem,swc)
         else:
            raise NotImplementedError(elem.tag)
      return swc

   def parseComponents(self,xmlRoot,parent):
      """
      parses <COMPONENTS>
      """
      assert(xmlRoot.tag=='COMPONENTS')
      for elem in xmlRoot.findall('./*'):
         componentTag = 'SW-COMPONENT-PROTOTYPE' if self.version >= 4.0 else 'COMPONENT-PROTOTYPE'
         if elem.tag==componentTag:
            name=self.parseTextNode(elem.find('SHORT-NAME'))
            typeRef=self.parseTextNode(elem.find('TYPE-TREF'))
            parent.components.append(autosar.component.ComponentPrototype(name,typeRef,parent))
         else:
            raise NotImplementedError(elem.tag)

   def parseConnectorsV3(self,xmlRoot,parent=None):
      """
      parses <CONNECTORS> (AUTOSAR 3)
      """
      assert(xmlRoot.tag=='CONNECTORS')
      for elem in xmlRoot.findall('./*'):
         if elem.tag=='ASSEMBLY-CONNECTOR-PROTOTYPE':
            name=self.parseTextNode(elem.find('SHORT-NAME'))
            providerComponentRef=self.parseTextNode(elem.find('./PROVIDER-IREF/COMPONENT-PROTOTYPE-REF'))
            providerPortRef=self.parseTextNode(elem.find('./PROVIDER-IREF/P-PORT-PROTOTYPE-REF'))
            requesterComponentRef=self.parseTextNode(elem.find('./REQUESTER-IREF/COMPONENT-PROTOTYPE-REF'))
            requesterPortRef=self.parseTextNode(elem.find('./REQUESTER-IREF/R-PORT-PROTOTYPE-REF'))
            parent.assemblyConnectors.append(autosar.component.AssemblyConnector(name, autosar.component.ProviderInstanceRef(providerComponentRef,providerPortRef), autosar.component.RequesterInstanceRef(requesterComponentRef,requesterPortRef)))
         elif elem.tag=='DELEGATION-CONNECTOR-PROTOTYPE':
            name=self.parseTextNode(elem.find('SHORT-NAME'))
            innerComponentRef=self.parseTextNode(elem.find('./INNER-PORT-IREF/COMPONENT-PROTOTYPE-REF'))
            innerPortRef=self.parseTextNode(elem.find('./INNER-PORT-IREF/PORT-PROTOTYPE-REF'))
            outerPortRef=self.parseTextNode(elem.find('./OUTER-PORT-REF'))
            parent.delegationConnectors.append(autosar.component.DelegationConnector(name, autosar.component.InnerPortInstanceRef(innerComponentRef,innerPortRef), autosar.component.OuterPortRef(outerPortRef)))
         else:
            raise NotImplementedError(elem.tag)

   def parseConnectorsV4(self,xmlRoot,parent=None):
      """
      parses <CONNECTORS> (AUTOSAR 4)
      """
      assert(xmlRoot.tag=='CONNECTORS')
      for xmlElem in xmlRoot.findall('./*'):
         if xmlElem.tag=='ASSEMBLY-SW-CONNECTOR':
            name=self.parseTextNode(xmlElem.find('SHORT-NAME'))
            for xmlChild in xmlElem.findall('./*'):
               if xmlChild.tag == 'SHORT-NAME':
                  continue
               elif xmlChild.tag == 'PROVIDER-IREF':
                  providerComponentRef=self.parseTextNode(xmlChild.find('./CONTEXT-COMPONENT-REF'))
                  providerPortRef=self.parseTextNode(xmlChild.find('./TARGET-P-PORT-REF'))
               elif xmlChild.tag == 'REQUESTER-IREF':
                  requesterComponentRef=self.parseTextNode(xmlChild.find('./CONTEXT-COMPONENT-REF'))
                  requesterPortRef=self.parseTextNode(xmlChild.find('./TARGET-R-PORT-REF'))
               else:
                  raise NotImplementedError(xmlChild.tag)
            if providerComponentRef is None:
               raise RuntimeError('PROVIDER-IREF/CONTEXT-COMPONENT-REF is missing: item=%s'%name)
            if providerComponentRef is None:
               raise RuntimeError('PROVIDER-IREF/TARGET-P-PORT-REF is missing: item=%s'%name)
            if requesterComponentRef is None:
               raise RuntimeError('REQUESTER-IREF/CONTEXT-COMPONENT-REF is missing: item=%s'%name)
            if requesterPortRef is None:
               raise RuntimeError('REQUESTER-IREF/TARGET-R-PORT-REF is missing: item=%s'%name)
            
            parent.assemblyConnectors.append(autosar.component.AssemblyConnector(name, autosar.component.ProviderInstanceRef(providerComponentRef,providerPortRef), autosar.component.RequesterInstanceRef(requesterComponentRef,requesterPortRef)))
         elif xmlElem.tag=='DELEGATION-SW-CONNECTOR':
            name=self.parseTextNode(xmlElem.find('SHORT-NAME'))
            for xmlChild in xmlElem.findall('./INNER-PORT-IREF/*'):
               if xmlChild.tag == 'R-PORT-IN-COMPOSITION-INSTANCE-REF':
                  innerComponentRef=self.parseTextNode(xmlChild.find('./CONTEXT-COMPONENT-REF'))
                  innerPortRef=self.parseTextNode(xmlChild.find('./TARGET-R-PORT-REF'))
               elif xmlChild.tag == 'P-PORT-IN-COMPOSITION-INSTANCE-REF':
                  innerComponentRef=self.parseTextNode(xmlChild.find('./CONTEXT-COMPONENT-REF'))
                  innerPortRef=self.parseTextNode(xmlChild.find('./TARGET-P-PORT-REF'))
               else:
                  raise NotImplementedError(xmlChild.tag)
            outerPortRef=self.parseTextNode(xmlElem.find('./OUTER-PORT-REF'))
            parent.delegationConnectors.append(autosar.component.DelegationConnector(name, autosar.component.InnerPortInstanceRef(innerComponentRef,innerPortRef), autosar.component.OuterPortRef(outerPortRef)))
         else:
            raise NotImplementedError(xmlElem.tag)

   def _parseModeSwitchComSpec(self, xmlRoot):
      (enhancedMode, supportAsync) = (False, False)
      for xmlElem in xmlRoot.findall('./*'):
         if xmlElem.tag == 'ENHANCED-MODE-API':
            enhancedMode = self.parseBooleanNode(xmlElem)
         elif xmlElem.tag == 'SUPPORTS-ASYNCHRONOUS-MODE-SWITCH':
            supportAsync = self.parseBooleanNode(xmlElem)
         else:
            raise NotImplementedError(xmlElem.tag)
      return autosar.component.ModeSwitchComSpec(enhancedMode, supportAsync)

   def _parseParameterComSpec(self, xmlRoot, portInterfaceRef):
      (initValue, name) = (None, None)
      for xmlElem in xmlRoot.findall('./*'):
         if xmlElem.tag == 'INIT-VALUE':
            values = self.constant_parser.parseValueV4(xmlElem, None)
            if len(values) != 1:
               raise ValueError('INIT-VALUE cannot cannot contain multiple elements')
            initValue = values[0]
         elif xmlElem.tag == 'PARAMETER-REF':
            name = _getParameterNameFromComSpec(xmlElem, portInterfaceRef)
         else:
            raise NotImplementedError(xmlElem.tag)
      if (name is not None):
         return autosar.component.ParameterComSpec(name, initValue)
      else:
         raise RuntimeError('PARAMETER-REQUIRE-COM-SPEC must have a PARAMETER-REF')
 def __init__(self,pkg,version=3.0):
    self.version=version
    self.pkg=pkg
    if self.version >=4.0:
       self.behavior_parser = BehaviorParser(pkg,version)