98 lines
4.0 KiB
Java
98 lines
4.0 KiB
Java
package de.opcua.app.model;
|
|
|
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Ein Knoten im OPC UA JSON-Export.
|
|
* Felder entsprechen dem opcua-export.json Format.
|
|
* referenceTypeId ist optional (z.B. "i=35", "i=46", "i=47").
|
|
*/
|
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
public class ExportNode {
|
|
|
|
public String name;
|
|
public String id;
|
|
public String browseName;
|
|
public String nodeClass;
|
|
public String dataType;
|
|
public String accessLevel;
|
|
public String value;
|
|
public String nodeId; // Feld im opcua-export Format
|
|
public String displayName; // Feld im opcua-export Format
|
|
public String referenceType; // z.B. "Organizes", "HasProperty", "HasComponent"
|
|
public String referenceTypeId; // z.B. "i=35" (Organizes), "i=46" (HasProperty), "i=47" (HasComponent)
|
|
public Boolean containsNoLoops; // OPC UA View-Attribut (null = unbekannt)
|
|
public Long viewVersion; // OPC UA View-Attribut UInt32 (null = unbekannt)
|
|
public List<ExportNode> children;
|
|
|
|
/** Effektiver Anzeigename: displayName > name > browseName. */
|
|
public String effectiveName() {
|
|
if (displayName != null && !displayName.isBlank()) return displayName;
|
|
if (name != null && !name.isBlank()) return name;
|
|
if (browseName != null && !browseName.isBlank()) return browseName;
|
|
return "Node";
|
|
}
|
|
|
|
/** Effektive NodeId: nodeId > id. */
|
|
public String effectiveNodeId() {
|
|
if (nodeId != null && !nodeId.isBlank()) return nodeId;
|
|
return id;
|
|
}
|
|
|
|
public String effectiveDataType() { return dataType; }
|
|
|
|
public boolean isVariable() {
|
|
if (nodeClass != null)
|
|
return "Variable".equals(nodeClass) || "VariableType".equals(nodeClass);
|
|
return value != null || dataType != null;
|
|
}
|
|
|
|
private static String referenceTypeToId(String ref) {
|
|
if (ref == null || ref.isBlank()) return null;
|
|
return switch (ref) {
|
|
case "Organizes" -> "i=35";
|
|
case "HasTypeDefinition" -> "i=40";
|
|
case "HasSubtype" -> "i=45";
|
|
case "HasProperty" -> "i=46";
|
|
case "HasComponent" -> "i=47";
|
|
case "HasNotifier" -> "i=48";
|
|
default -> ref;
|
|
};
|
|
}
|
|
|
|
/** Konvertiert zu TreeNodeRef für GUI. */
|
|
public TreeNodeRef toTreeNodeRef() {
|
|
// 9-Arg-Konstruktor: alle Felder inkl. View-Attribute
|
|
return new TreeNodeRef(
|
|
effectiveName(),
|
|
effectiveNodeId(),
|
|
browseName != null ? browseName : effectiveName(),
|
|
nodeClass != null ? nodeClass : (isVariable() ? "Variable" : "Object"),
|
|
dataType,
|
|
accessLevel != null ? accessLevel : "ReadWrite",
|
|
referenceTypeId != null ? referenceTypeId : referenceTypeToId(referenceType),
|
|
containsNoLoops != null ? containsNoLoops : true, // Default: true (sicher)
|
|
viewVersion != null ? viewVersion : 0L // Default: 0 (unversioniert)
|
|
);
|
|
}
|
|
|
|
/** Konvertiert TreeNodeRef-Daten zurück in ExportNode. */
|
|
public static ExportNode fromTreeNodeRef(TreeNodeRef ref) {
|
|
ExportNode en = new ExportNode();
|
|
en.name = ref.displayName();
|
|
en.id = ref.nodeId();
|
|
en.nodeId = ref.nodeId();
|
|
en.displayName = ref.displayName();
|
|
en.browseName = ref.browseName();
|
|
en.nodeClass = ref.nodeClass();
|
|
en.dataType = ref.dataType();
|
|
en.accessLevel = ref.accessLevel();
|
|
en.referenceTypeId = ref.referenceTypeId();
|
|
en.referenceType = ref.referenceTypeId() != null ? TreeNodeRef.resolveRefTypeId(ref.referenceTypeId()) : null;
|
|
en.containsNoLoops = ref.containsNoLoops();
|
|
en.viewVersion = ref.viewVersion();
|
|
return en;
|
|
}
|
|
}
|