Package com.digitalpetri.opcua.nodeset

Source Code of com.digitalpetri.opcua.nodeset.UaNodeSet

package com.digitalpetri.opcua.nodeset;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.digitalpetri.opcua.nodeset.attributes.*;
import com.digitalpetri.opcua.nodeset.util.AttributeUtil;
import org.opcfoundation.ua.builtintypes.ExpandedNodeId;
import org.opcfoundation.ua.builtintypes.NodeId;
import org.opcfoundation.ua.core.NodeClass;
import org.opcfoundation.ua.generated.*;

public class UaNodeSet<NodeType, ReferenceType> {

    private final Map<String, NodeId> aliasMap = new HashMap<>();
    private final Map<NodeId, NodeType> nodeMap = new HashMap<>();
    private final Map<NodeId, List<ReferenceType>> referenceMap = new HashMap<>();

    private final UANodeSet nodeSet;
    private final Marshaller marshaller;
    private final NodeBuilder<NodeType, ReferenceType> nodeBuilder;
    private final ReferenceBuilder<ReferenceType> referenceBuilder;

    UaNodeSet(InputStream nodeSetXml,
              NodeBuilder<NodeType, ReferenceType> nodeBuilder,
              ReferenceBuilder<ReferenceType> referenceBuilder) throws JAXBException {

        this.nodeBuilder = nodeBuilder;
        this.referenceBuilder = referenceBuilder;

        JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
        marshaller = jaxbContext.createMarshaller();

        nodeSet = UANodeSet.class.cast(jaxbContext.createUnmarshaller().unmarshal(nodeSetXml));

        nodeSet.getAliases().getAlias().stream().forEach(a -> {
            aliasMap.put(a.getAlias(), NodeId.parseNodeId(a.getValue()));
        });

        nodeSet.getUAObjectOrUAVariableOrUAMethod().stream().forEach(gNode -> {
            NodeId sourceNodeId = NodeId.parseNodeId(gNode.getNodeId());

            gNode.getReferences().getReference().forEach(gReference -> {
                Map<NodeId, ReferenceType> references = referenceAndInverse(sourceNodeId, gReference);

                references.keySet().stream().forEach(nodeId -> {
                    ReferenceType reference = references.get(nodeId);
                    if (referenceMap.containsKey(nodeId)) {
                        referenceMap.get(nodeId).add(reference);
                    } else {
                        List<ReferenceType> l = new ArrayList<>(1);
                        l.add(reference);
                        referenceMap.put(nodeId, l);
                    }
                });
            });
        });

        nodeSet.getUAObjectOrUAVariableOrUAMethod().stream().forEach(this::buildNode);
    }

    public Map<String, NodeId> getAliasMap() {
        return aliasMap;
    }

    public Map<NodeId, NodeType> getNodeMap() {
        return nodeMap;
    }

    public Map<NodeId, List<ReferenceType>> getReferenceMap() {
        return referenceMap;
    }

    private NodeType buildNode(GeneratedUANode gNode) {
        if (gNode instanceof GeneratedUADataType) return dataTypeNode((GeneratedUADataType) gNode);
        if (gNode instanceof GeneratedUAMethod) return methodNode((GeneratedUAMethod) gNode);
        if (gNode instanceof GeneratedUAObject) return objectNode((GeneratedUAObject) gNode);
        if (gNode instanceof GeneratedUAObjectType) return objectTypeNode((GeneratedUAObjectType) gNode);
        if (gNode instanceof GeneratedUAReferenceType) return referenceTypeNode((GeneratedUAReferenceType) gNode);
        if (gNode instanceof GeneratedUAVariable) return variableNode((GeneratedUAVariable) gNode);
        if (gNode instanceof GeneratedUAVariableType) return variableTypeNode((GeneratedUAVariableType) gNode);
        if (gNode instanceof GeneratedUAView) return viewNode((GeneratedUAView) gNode);

        throw new RuntimeException("unexpected node: " + gNode);
    }

    private NodeType dataTypeNode(GeneratedUADataType generated) {
        DataTypeNodeAttributes attributes = DataTypeNodeAttributes.fromGenerated(generated);
        List<ReferenceType> references = referenceMap.get(attributes.getNodeAttributes().getNodeId());

        NodeType node = nodeBuilder.buildDataTypeNode(attributes, references);
        nodeMap.put(attributes.getNodeAttributes().getNodeId(), node);
        return node;
    }

    private NodeType methodNode(GeneratedUAMethod generated) {
        MethodNodeAttributes attributes = MethodNodeAttributes.fromGenerated(generated);
        List<ReferenceType> references = referenceMap.get(attributes.getNodeAttributes().getNodeId());

        NodeType node = nodeBuilder.buildMethodNode(attributes, references);
        nodeMap.put(attributes.getNodeAttributes().getNodeId(), node);
        return node;
    }

    private NodeType objectNode(GeneratedUAObject generated) {
        ObjectNodeAttributes attributes = ObjectNodeAttributes.fromGenerated(generated);
        List<ReferenceType> references = referenceMap.get(attributes.getNodeAttributes().getNodeId());

        NodeType node = nodeBuilder.buildObjectNode(attributes, references);
        nodeMap.put(attributes.getNodeAttributes().getNodeId(), node);
        return node;
    }

    private NodeType objectTypeNode(GeneratedUAObjectType generated) {
        ObjectTypeNodeAttributes attributes = ObjectTypeNodeAttributes.fromGenerated(generated);
        List<ReferenceType> references = referenceMap.get(attributes.getNodeAttributes().getNodeId());

        NodeType node = nodeBuilder.buildObjectTypeNode(attributes, references);
        nodeMap.put(attributes.getNodeAttributes().getNodeId(), node);
        return node;
    }

    private NodeType referenceTypeNode(GeneratedUAReferenceType generated) {
        ReferenceTypeNodeAttributes attributes = ReferenceTypeNodeAttributes.fromGenerated(generated);
        List<ReferenceType> references = referenceMap.get(attributes.getNodeAttributes().getNodeId());

        NodeType node = nodeBuilder.buildReferenceTypeNode(attributes, references);
        nodeMap.put(attributes.getNodeAttributes().getNodeId(), node);
        return node;
    }

    private NodeType variableNode(GeneratedUAVariable generated) {
        VariableNodeAttributes attributes = VariableNodeAttributes.fromGenerated(generated, marshaller, aliasMap);
        List<ReferenceType> references = referenceMap.get(attributes.getNodeAttributes().getNodeId());

        NodeType node = nodeBuilder.buildVariableNode(attributes, references);
        nodeMap.put(attributes.getNodeAttributes().getNodeId(), node);
        return node;
    }

    private NodeType variableTypeNode(GeneratedUAVariableType generated) {
        VariableTypeNodeAttributes attributes = VariableTypeNodeAttributes.fromGenerated(generated, marshaller, aliasMap);
        List<ReferenceType> references = referenceMap.get(attributes.getNodeAttributes().getNodeId());

        NodeType node = nodeBuilder.buildVariableTypeNode(attributes, references);
        nodeMap.put(attributes.getNodeAttributes().getNodeId(), node);
        return node;
    }

    private NodeType viewNode(GeneratedUAView generated) {
        ViewNodeAttributes attributes = ViewNodeAttributes.fromGenerated(generated);
        List<ReferenceType> references = referenceMap.get(attributes.getNodeAttributes().getNodeId());

        NodeType node = nodeBuilder.buildViewNode(attributes, references);
        nodeMap.put(attributes.getNodeAttributes().getNodeId(), node);
        return node;
    }

    private Map<NodeId, ReferenceType> referenceAndInverse(NodeId sourceNodeId, GeneratedReference gReference) {
        NodeId referenceTypeId = AttributeUtil.parseReferenceTypeId(gReference, aliasMap);

        /*
         * Create the reference...
         */
        NodeId targetNodeId = NodeId.parseNodeId(gReference.getValue());

        NodeClass targetNodeClass = nodeSet.getUAObjectOrUAVariableOrUAMethod().stream()
                .filter(gNode -> gNode.getNodeId().equals(gReference.getValue()))
                .findFirst()
                .map(this::nodeClass)
                .orElse(NodeClass.Unspecified);

        boolean forward = gReference.isIsForward();

        ReferenceType reference = referenceBuilder.buildReference(
                sourceNodeId, referenceTypeId, new ExpandedNodeId(targetNodeId), targetNodeClass, forward);

        /*
         * Create the inverse of the reference...
         */
        NodeClass sourceNodeClass = nodeSet.getUAObjectOrUAVariableOrUAMethod().stream()
                .filter(gNode -> gNode.getNodeId().equals(sourceNodeId.toString()))
                .findFirst()
                .map(this::nodeClass)
                .orElse(NodeClass.Unspecified);

        ReferenceType inverseReference = referenceBuilder.buildReference(
                targetNodeId, referenceTypeId, new ExpandedNodeId(sourceNodeId), sourceNodeClass, !forward);

        Map<NodeId, ReferenceType> references = new HashMap<>(2);
        references.put(sourceNodeId, reference);
        references.put(NodeId.parseNodeId(gReference.getValue()), inverseReference);
        return references;
    }

    private NodeClass nodeClass(GeneratedUANode gNode) {
        if (gNode instanceof GeneratedUADataType) return NodeClass.DataType;
        if (gNode instanceof GeneratedUAMethod) return NodeClass.Method;
        if (gNode instanceof GeneratedUAObject) return NodeClass.Object;
        if (gNode instanceof GeneratedUAObjectType) return NodeClass.ObjectType;
        if (gNode instanceof GeneratedUAReferenceType) return NodeClass.ReferenceType;
        if (gNode instanceof GeneratedUAVariable) return NodeClass.Variable;
        if (gNode instanceof GeneratedUAVariableType) return NodeClass.VariableType;
        if (gNode instanceof GeneratedUAView) return NodeClass.View;

        return NodeClass.Unspecified;
    }

}
TOP

Related Classes of com.digitalpetri.opcua.nodeset.UaNodeSet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.