Exemplo n.º 1
0
def show_unary_op(node, args=None):
    """
    Show the 'unary_op' view of the 'soft' category.
    """
    INFO("soft.show_unary_op(%s)" % node['qname'])

    results = QUERY("""
        SELECT DISTINCT ?operator ?operand
        WHERE {
            %s expr:hasOperator ?operator .
            %s expr:hasOperand ?operand .
        }
        """ % ((node["qname"], ) * 2))

    if len(results) == 0:
        raise Exception(
            "Invalid specification of unary operation %s.\n\nNode=%s" %
            (node["qname"], pprint.pformat(node)))

    for (operatorUri, operandUri) in results:

        operatorNode = generic.getDefaultNode(node.cache,
                                              URI_TO_QNAME(operatorUri))
        operandNode = generic.getDefaultNode(node.cache,
                                             URI_TO_QNAME(operandUri))

        node["operator"] = operatorNode["qname"]
        node["operand"] = operandNode["qname"]

        operatorNode.show("soft")
        operandNode.show("soft")
Exemplo n.º 2
0
def getMemberPath(startUri, endUri):
    """
    Get the path to a member..
    """
    INFO("soft.getMemberPath(%s,%s)" % (startUri, endUri))

    startUri = str(startUri)
    endUri = str(endUri)

    if startUri == endUri:
        return []
    else:
        results = QUERY("""
            SELECT DISTINCT ?member ?label
            WHERE {
                <%s> soft:hasVariable ?member .
                ?member (soft:hasVariable)* <%s> .
                OPTIONAL { <%s> rdfs:label ?label . }
            }
            """ % (startUri, endUri, startUri))
        if len(results) == 0:
            raise Exception("%s has no member that owns %s!" %
                            (startUri, endUri))

        for (memberUri, label) in results:
            if label is None:
                raise Exception("%s has no label!" % (startUri))

            return [label.toPython()] + getMemberPath(str(memberUri), endUri)
Exemplo n.º 3
0
def getDefaultNode(cache, qname):
    """
    Get a Node with default information, or get the node from the cache if available.

    The default information of a node includes:
     - its qname
     - its label
     - its uri
     - its comment
     - its ontoscript counter
     - its RDF classes (a list of qnames)

    All nodes contain the default information
     + optional other slots (filled by the show_... callbacks mentioned in allviews.py)
     + optional expansions (filled by the get... callbacks mentioned in allviews.py)
    """
    try:
        node = cache[qname]
    except:
        INFO("    Get default node for %s" %qname)

        results = QUERY("""
            SELECT DISTINCT ?label ?comment ?counter ?rdfClass
            WHERE {
                OPTIONAL { %s rdfs:label ?label } .
                OPTIONAL { %s rdfs:comment ?comment } .
                OPTIONAL { %s ontoscript:counter ?counter } .
                OPTIONAL { %s a/(rdfs:subClassOf*) ?rdfClass . FILTER (!isBlank(?rdfClass)) } .

            }
            """ %(qname,qname,qname,qname))

        node = Node(
                qname           = qname,
                uri             = QNAME_TO_URI(qname),
                cache           = cache)

        rdfClasses = [] # only for logging

        for label, comment, counter, rdfClass in results:
            if label is not None:
                node["label"] = label.toPython()
            if comment is not None:
                node["comment"] = comment.toPython()
            if counter is not None:
                node["counter"] = int(counter.toPython())
            if rdfClass is not None:
                rdfClassQName = URI_TO_QNAME(rdfClass)
                node.registerClass(rdfClassQName)
                rdfClasses.append(rdfClassQName)

        INFO("     --> label '%s', counter %d, rdfClasses %s" %(node["label"], node["counter"], rdfClasses))

        node.registerClass("rdfs:Resource")

        node.registerKnownViews()

        cache[qname] = node

    return node
Exemplo n.º 4
0
def show_binary_op(node, args=None):
    """
    Show the 'binary_op' view of the 'soft' category.
    """
    INFO("soft.show_binary_op(%s)" % node['qname'])

    results = QUERY("""
        SELECT DISTINCT ?operator ?left ?right
        WHERE {
            %s expr:hasOperator ?operator .
            %s expr:hasLeftOperand ?left .
            %s expr:hasRightOperand ?right .
        }
        """ % ((node["qname"], ) * 3))

    if len(results) == 0:
        raise Exception(
            "Invalid specification of binary operation %s.\n\nNode=%s" %
            (node["qname"], pprint.pformat(node)))

    for (operatorUri, leftUri, rightUri) in results:

        oNode = generic.getDefaultNode(node.cache, URI_TO_QNAME(operatorUri))
        lNode = generic.getDefaultNode(node.cache, URI_TO_QNAME(leftUri))
        rNode = generic.getDefaultNode(node.cache, URI_TO_QNAME(rightUri))

        node["operator"] = oNode["qname"]
        node["left"] = lNode["qname"]
        node["right"] = rNode["qname"]

        oNode.show("soft")
        lNode.show("soft")
        rNode.show("soft")
Exemplo n.º 5
0
def isPlcEnum(type):
    """
    Ask if the given type is an IEC 61131-3 enum
    """
    result = QUERY("""
        ASK WHERE {
            %s rdf:type/rdfs:subClassOf* iec61131:Enum .
        }
        """ % type)
    return bool(result)
Exemplo n.º 6
0
def isPlcStruct(type):
    """
    Ask if the given type is an IEC 61131-3 struct
    """
    result = QUERY("""
        ASK WHERE {
            %s rdf:type/rdfs:subClassOf* iec61131:Struct .
        }
        """ % type)
    return bool(result)
Exemplo n.º 7
0
def isPlcFb(type):
    """
    Ask if the given type is an IEC 61131-3 function block
    """
    result = QUERY("""
        ASK WHERE {
            %s rdf:type/rdfs:subClassOf* iec61131:FunctionBlock .
        }
        """ % type)
    return bool(result)
Exemplo n.º 8
0
def show_variable(node, args=None):
    """
    Show the 'variable' view of the 'soft' category.
    """
    INFO("soft.show_variable(%s)" % node['qname'])

    node["type"] = None
    node["points_to_type"] = None
    node["initial_value"] = None
    node["address"] = None
    node["value"] = None

    results = QUERY("""
        SELECT DISTINCT ?type ?pointsToType ?initialValue ?address ?link ?value
        WHERE {
            OPTIONAL { %s soft:hasType | (^soft:isTypeOf) ?type . } .
            OPTIONAL { %s soft:pointsToType ?pointsToType .} .
            OPTIONAL { %s soft:hasInitialValue ?initialValue . } .
            OPTIONAL { %s soft:hasAddress ?address . } .
            OPTIONAL { %s expr:hasValue | expr:hasNumericValue ?value . } .
        }
        """ % ((node["qname"], ) * 5))

    for type, pointsToType, initialValue, address, link, value in results:

        if type is not None:
            typeQName = URI_TO_QNAME(type.toPython())
            node["type"] = typeQName
            generic.getDefaultNode(node.cache, typeQName).show("soft", "type")

        if pointsToType is not None:
            pointsToTypeQName = URI_TO_QNAME(pointsToType.toPython())
            node["points_to_type"] = pointsToTypeQName
            generic.getDefaultNode(node.cache,
                                   pointsToTypeQName).show("soft", "type")

        if initialValue is not None:
            node["initial_value"] = initialValue.toPython()

        if address is not None:
            node["address"] = address.toPython()

        if value is not None:
            node["value"] = getExpressionString(value)

    node.expand("soft", "variable")

    for memberOf in node["member_of"]:
        node.cache[memberOf].show("soft")

    for l in node["links"]:
        node.cache[l].show("soft")

    for qualifier in node["qualifiers"]:
        node.cache[qualifier].show("soft")
Exemplo n.º 9
0
def getAllConstraintViolations():
    """
    Get a list of all constraint violations.

    @return: a list of dictionaries.
    """
    results = QUERY("""
        SELECT DISTINCT ?root ?rootLabel ?rootCounter ?value ?level ?label
        WHERE {
            ?violation rdf:type/rdfs:subClassOf* spin:ConstraintViolation .
            ?violation spin:violationRoot ?root .
            ?root rdfs:label ?rootLabel .
            OPTIONAL { ?root ontoscript:counter ?rootCounter } .
            OPTIONAL { ?violation spin:violationValue ?value } .
            OPTIONAL { ?violation spin:violationLevel ?level } .
            ?violation rdfs:label ?label .
        }
        """)
    d = {}
    for rootUri, rootLabel, rootCounter, value, level, label in results:
        root = URI_TO_QNAME(rootUri)
        hash = "%s-%s" % (root, label)

        if hash not in d.keys():

            d[hash] = {
                "root": {
                    "uri": rootUri.toPython(),
                    "qname": root,
                    "counter": -1,
                    "label": rootLabel.toPython()
                },
                "label": label.toPython(),
                "value": value,
                "level": level
            }

            if rootCounter is not None:
                d[hash]["root"]["counter"] = int(rootCounter.toPython())

            if value is not None:
                try:
                    d[hash]["value"] = value.toPython()
                except:
                    pass

            if level is not None:
                try:
                    d[hash]["level"] = level.toPython()
                except:
                    pass

    return sorted(d.values(), key=lambda x: x["root"]["counter"])
Exemplo n.º 10
0
def getCommonVariablesOfContext(variableUri, contextUri):
    """
    Get the common variables of a given variable and a given context.
    """
    INFO("soft.getCommonVariablesOfContext(%s,%s)" % (variableUri, contextUri))

    ret = []
    results = QUERY("""
        SELECT DISTINCT ?member
        WHERE {
            <%s> soft:hasVariable ?member .
            ?member (soft:hasVariable)* <%s> .
        }
        """ % (contextUri, variableUri))
    for (member, ) in results:
        ret.append(member.toPython())
    return ret
Exemplo n.º 11
0
def show_browse(node, args=None):
    """
    Show the 'browse' view of the 'browse' category.
    """
    INFO("browse.show_browse(%s)" % node['qname'])

    results = QUERY("""
        SELECT DISTINCT ?predicate ?object
        WHERE {
            %s ?predicate ?object .
        }
        """ % node["qname"])

    d = {}

    for predicateUri, ob in results:
        predicate = URI_TO_QNAME(predicateUri)

        if type(ob) == rdflib.term.URIRef:
            object = {
                "type": "uri",
                "content": {
                    "uri": ob.toPython(),
                    "qname": URI_TO_QNAME(ob)
                }
            }

        elif type(ob) == rdflib.term.BNode:
            object = {"type": "bnode", "content": {"id": ob}}
        elif type(ob) == rdflib.term.Literal:
            object = {"type": "literal", "content": ob.toPython()}
        else:
            object = {"type": "unknown", "content": ob}

        if predicate not in d.keys():
            d[predicate] = {
                "uri": predicateUri,
                "qname": predicate,
                "objects": [object]
            }

        else:
            d[predicate]["objects"].append(object)

    node["results"] = sorted(d.values(), key=lambda x: x["qname"])
Exemplo n.º 12
0
def show_primitive(node, args=None):
    """
    Show the 'primitive' view of the 'soft' category.
    """
    INFO("soft.show_InterfaceInstance(%s)" % node['qname'])

    # extra query to get the string value or numeric value
    results = QUERY("""
        SELECT DISTINCT ?value
        WHERE {
            %s expr:hasValue|expr:hasNumericValue ?value .
        }
        """ % node["qname"])

    node["value"] = None

    for (value, ) in results:
        if value is not None:
            node["value"] = getExpressionString(value)
Exemplo n.º 13
0
def show_operator(node, args=None):
    """
    Show the 'operator' view of the 'soft' category.
    """
    INFO("soft.show_operator(%s)" % node['qname'])

    results = QUERY("""
        SELECT DISTINCT ?symbol
        WHERE {
            OPTIONAL { %s iec61131:hasSymbol ?symbol . } .
        }
        """ % ((node["qname"], ) * 1))

    node["plc_symbol"] = None

    for (symbol, ) in results:

        if symbol is not None:
            node["plc_symbol"] = symbol.toPython()
Exemplo n.º 14
0
def fillNumber(node, optional=False):
    """
    Fill out the number of a container item (according to the containers ontology).
    """
    INFO("    Fill number of %s")

    node["number"] = None

    results = QUERY("""
        SELECT DISTINCT ?number
        WHERE {
            %s (cont:isItemOf|(^cont:hasItem))/cont:hasNumber ?number .
        }
        """ %node["qname"])


    for (number,) in results:
        node["number"] = int(number.toPython())

    INFO("     --> %s" %node["number"])
Exemplo n.º 15
0
def show_type(node, args=None):
    """
    Show the 'type' view of the 'soft' category.
    """
    INFO("soft.show_type(%s)" % node['qname'])

    results = QUERY("""
        SELECT DISTINCT ?implementation ?symbol ?extends ?returnType
        WHERE {
            OPTIONAL { %s soft:hasImplementation ?implementation . } .
            OPTIONAL { ?implementation soft:isImplementationOf %s . } .
            OPTIONAL { %s (^owl:sameAs)/iec61131:hasSymbol | iec61131:hasSymbol ?symbol . } .
            OPTIONAL { %s soft:extends ?extends } .
            OPTIONAL { %s soft:hasReturnType ?returnType . } .
        }
        """ % ((node["qname"], ) * 5))

    node["implementation"] = None
    node["plc_symbol"] = None
    node["extends"] = None
    node["returnType"] = None

    for implementation, symbol, extends, returnType in results:

        if implementation is not None:
            implementationQName = URI_TO_QNAME(implementation.toPython())
            node["implementation"] = implementationQName
            generic.getDefaultNode(node.cache, implementationQName)
            # don't show it here

        if symbol is not None:
            node["plc_symbol"] = symbol.toPython()
        if extends is not None:
            extendsQName = URI_TO_QNAME(extends.toPython())
            node["extends"] = extendsQName
            generic.getDefaultNode(node.cache, extendsQName).show("soft")
        if returnType is not None:
            returnTypeQName = URI_TO_QNAME(returnType.toPython())
            node["returnType"] = returnTypeQName
            generic.getDefaultNode(node.cache, returnTypeQName).show("soft")
Exemplo n.º 16
0
def getEnumPath(variableUri):
    """
    Get the path to an enumeration.
    """
    INFO("soft.getEnumPath(%s)" % (variableUri))

    results = QUERY("""
        SELECT DISTINCT ?enum ?label
        WHERE {
            ?enum soft:hasEnumerationItem <%s> .
            ?enum rdfs:label ?label .
        }
        """ % (variableUri))

    if len(results) == 0:
        return None
    elif len(results) > 1:
        raise Exception("Multiple enum definitions were found for item %s!" %
                        variableUri)
    else:
        for (enumUri, enumLabel) in results:
            return {"path": [enumLabel.toPython()]}
Exemplo n.º 17
0
def show_if_then(node, args=None):
    """
    Show the 'if_then' view of the 'soft' category.
    """
    INFO("soft.show_if_then(%s)" % node['qname'])

    results = QUERY("""
        SELECT DISTINCT ?if ?then ?else
        WHERE {
            %s soft:if ?if .
            %s soft:then ?then .
            OPTIONAL { %s soft:else ?else . }
        }
        """ % ((node["qname"], ) * 3))

    if len(results) != 1:
        raise Exception("Invalid specification of IfThen operation %s" %
                        node["qname"])

    node["if"] = None
    node["then"] = None
    node["else"] = None

    for (i, t, e) in results:
        iNode = generic.getDefaultNode(node.cache, URI_TO_QNAME(i))
        tNode = generic.getDefaultNode(node.cache, URI_TO_QNAME(t))

        node["if"] = iNode["qname"]
        node["then"] = tNode["qname"]

        iNode.show("soft")
        tNode.show("soft")

        if e is not None:
            eNode = generic.getDefaultNode(node.cache, URI_TO_QNAME(e))
            node["else"] = eNode["qname"]
            eNode.show("soft")
Exemplo n.º 18
0
def show_qualifier(node, args=None):
    """
    Show the 'qualifier' view of the 'soft' category.
    """
    INFO("soft.show_qualifier(%s)" % node['qname'])

    results = QUERY("""
        SELECT DISTINCT ?symbol ?value
        WHERE {
            OPTIONAL { %s iec61131:hasSymbol ?symbol . } .
            OPTIONAL { %s expr:hasValue ?value . } .
        }
        """ % ((node["qname"], ) * 2))

    node["plc_symbol"] = None
    node["value"] = None

    for symbol, value in results:

        if symbol is not None:
            node["plc_symbol"] = symbol.toPython()

        if value is not None:
            node["value"] = value.toPython()
Exemplo n.º 19
0
def getInstances(cache, className, filterNotExists=None):
    """
    Get the instances of a class.
    """
    INFO("    Get instances of %s" %className)

    if filterNotExists is None:
        filterNotExistsLine = ""
    else:
        filterNotExistsLine = "FILTER NOT EXISTS { %s }" %filterNotExists

    results = QUERY("""
        SELECT DISTINCT ?instance ?label ?comment ?counter ?rdfClass
        WHERE {
            ?instance rdf:type/rdfs:subClassOf* %s .
            OPTIONAL { ?instance rdfs:label ?label } .
            OPTIONAL { ?instance rdfs:comment ?comment } .
            OPTIONAL { ?instance ontoscript:counter ?counter } .
            OPTIONAL { ?instance a/(rdfs:subClassOf*) ?rdfClass . FILTER (!isBlank(?rdfClass)) } .
            %s
        }
        """ %(className, filterNotExistsLine))

    d = {}
    for uri, label, comment, counter, rdfClass in results:
        qname = URI_TO_QNAME(uri)

        if not d.has_key(qname):
            d[qname] = Node(
                        qname           = qname,
                        uri             = uri.toPython(),
                        cache           = cache)

        if label is not None:
            d[qname]["label"] = label.toPython()
        if comment is not None:
            d[qname]["comment"] = comment.toPython()
        if counter is not None:
            d[qname]["counter"] = int(counter.toPython())
        if rdfClass is not None:
            d[qname].registerClass(URI_TO_QNAME(rdfClass.toPython()))

    keysStr = ""
    for key in d.keys():
        keysStr += (key + " ")

    INFO("     --> " + keysStr)

    for qname, node in d.items():

        node.registerKnownViews()

        if not cache.has_key(qname):
            DEBUG("Caching %s" %qname)
            cache[qname] = node

    # return a list of QNames
    ret = [] # list of qnames
    resultNodes =  sorted(d.values(), key=lambda x: x["counter"])
    for resultNode in resultNodes:
        ret.append(resultNode['qname'])
    return ret
Exemplo n.º 20
0
def fillFields(node, mandatories={}, optionals={}):
    """
    Fill some mandatory and/or optional fields of a node.
    """
    subject = node['qname']

    INFO("    Fill these fields of %s: mandatories=%s, optionals=%s" %(subject, mandatories.keys(), optionals.keys()))

    selectLine = ""
    wherePart = ""

    for key,value in mandatories.items():
        selectLine += " ?%s" %key
        wherePart += "%s %s ?%s .\n" %(subject, value, key)

    for key,value in optionals.items():
        selectLine += " ?%s" %key
        wherePart += "OPTIONAL { %s %s ?%s } .\n" %(subject, value, key)

    query = """
        SELECT DISTINCT %s
        WHERE {
            %s
        }
        """ %(selectLine, wherePart)

    results = QUERY(query)

    if len(results) == 0:
        raise Exception("No results for query:\n%s" %query)


    infoStr = "     --> mandatories ["

    for result in results:
        # the mandatories
        for i in xrange(len(mandatories)):
            key = mandatories.keys()[i]
            try:
                if IS_URI(result[i]):
                    node.cache[subject][key] = URI_TO_QNAME(result[i].toPython())
                else:
                    node.cache[subject][key] = result[i].toPython()
            except:
                node.cache[subject][key] = None

            if i > 0: infoStr += ","
            infoStr += str(node.cache[subject][key])

        infoStr += "], optionals ["

        for i in xrange(len(optionals)):
            key = optionals.keys()[i]
            try:
                j = len(mandatories) + i
                if IS_URI(result[j]):
                    node.cache[subject][key] = URI_TO_QNAME(result[j].toPython())
                else:
                    node.cache[subject][key] = result[j].toPython()
            except:
                node.cache[subject][key] = None

            if i > 0: infoStr += ","
            infoStr += str(node.cache[subject][key])

        infoStr += "]"

    INFO(infoStr)
Exemplo n.º 21
0
def getRelated(cache, subject, property, restriction=None, remove=None,  sortedByNumber=False, filterNotExists=None):
    """
    Get the related individuals of an individual.
    """
    INFO("    Get related %s of %s" %(property, subject))

    extraVariables = ""

    if restriction is None:
        restrictionLine = ""
    else:
        restrictionLine = "\n            ?result rdf:type/rdfs:subClassOf* %s ." %restriction

    if remove is None:
        removeLine = ""
    else:
        removeLine = "\n            FILTER NOT EXISTS { %s %s ?result }" %(subject, remove)

    if sortedByNumber:
        numberLine = "\n            OPTIONAL { ?result (cont:isItemOf|(^sys:hasItem))/cont:hasNumber ?number }"
        extraVariables += "?number"
    else:
        numberLine = ""

    if filterNotExists is None:
        filterNotExistsLine = ""
    else:
        filterNotExistsLine = "FILTER NOT EXISTS { %s }" %filterNotExists

    results = QUERY("""
        SELECT DISTINCT ?result ?label ?comment ?counter ?rdfClass %s
        WHERE {
            %s %s ?result . %s%s%s
            OPTIONAL { ?result rdfs:label ?label } .
            OPTIONAL { ?result rdfs:comment ?comment } .
            OPTIONAL { ?result ontoscript:counter ?counter } .
            OPTIONAL { ?result a/(rdfs:subClassOf*) ?rdfClass . FILTER (!isBlank(?rdfClass)) } .
            %s
        }
        """ %(extraVariables, subject,  property, restrictionLine, removeLine, numberLine, filterNotExistsLine))

    d = {}
    for result in results:
        resultQName = URI_TO_QNAME(result[0])

        if resultQName not in d.keys():
            d[resultQName] = Node(uri             = result[0].toPython(),
                                  qname           = resultQName,
                                  cache           = cache)

        if result[1] is not None:
            d[resultQName]["label"] = result[1].toPython()
        if result[2] is not None:
            d[resultQName]["comment"] = result[2].toPython()
        if result[3] is not None:
            d[resultQName]["counter"] = int(result[3].toPython())
        if result[4] is not None:
            d[resultQName].registerClass(URI_TO_QNAME(result[4].toPython()))

        if sortedByNumber:
            if result[5] is not None:
                d[resultQName]["number"] = int(result[5].toPython())
            else:
                d[resultQName]["number"] = None

    keysStr = ""
    for key in d.keys():
        keysStr += (key + " ")

    INFO("     --> " + keysStr)

    for resultQName, resultNode in d.items():
        resultNode.registerKnownViews()
        if not cache.has_key(resultQName):
            cache[resultQName] = d[resultQName]

    # return a list of QNames
    ret = [] # list of qnames

    # first sort by 'counter' key:
    resultNodes =  sorted(d.values(), key=lambda x: x['counter'])  # entries with None will be put first in the sorted list

    # then, if necessary, sort by number:
    if sortedByNumber:
        resultNodes =  sorted(resultNodes, key=lambda x: x['number'])

    for resultNode in resultNodes:
        ret.append(resultNode['qname'])

    return ret