Skip to content

Commit

Permalink
fix loading of Noset2.xlml file without Aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
erossignon committed Sep 27, 2022
1 parent 5e49112 commit 714718a
Show file tree
Hide file tree
Showing 13 changed files with 251 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ import {
} from "node-opcua-address-space-base";
import { DataValue } from "node-opcua-data-value";


let counter = 0;

function make_key() {
// return crypto.randomBytes(32);
counter += 1;
return Buffer.from(counter.toString(), "utf-8");
}

interface Data {
maxElements: number;
values: ReferenceDescription[] | DataValue[];
}
/**
* from https://reference.opcfoundation.org/v104/Core/docs/Part4/7.6/
*
Expand Down Expand Up @@ -70,18 +83,6 @@ import { DataValue } from "node-opcua-data-value";
* release all ContinuationPoints passed in the request. If the ContinuationPoint for an operation is missing or
* invalid then the StatusCode for the operation shall be Bad_ContinuationPointInvalid.
*/
let counter = 0;

function make_key() {
// return crypto.randomBytes(32);
counter += 1;
return Buffer.from(counter.toString(), "utf-8");
}

interface Data {
maxElements: number;
values: ReferenceDescription[] | DataValue[];
}
export class ContinuationPointManager implements IContinuationPointManager {
private _map: Map<string, Data>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CallbackT } from "node-opcua-status-code";
import { IAddressSpace } from "node-opcua-address-space-base";

import { adjustNamespaceArray } from "../../src/nodeset_tools/adjust_namespace_array";
import { NodeSetLoader } from "./load_nodeset2";
import { NodeSetLoader, NodeSetLoaderOptions } from "./load_nodeset2";

const doDebug = checkDebugFlag(__filename);
const debugLog = make_debugLog(__filename);
Expand All @@ -17,9 +17,10 @@ const errorLog = make_errorLog(__filename);
export async function generateAddressSpaceRaw(
addressSpace: IAddressSpace,
xmlFiles: string | string[],
xmlLoader: (nodeset2xmlUri: string) => Promise<string>
xmlLoader: (nodeset2xmlUri: string) => Promise<string>,
options: NodeSetLoaderOptions
): Promise<void> {
const nodesetLoader = new NodeSetLoader(addressSpace);
const nodesetLoader = new NodeSetLoader(addressSpace, options);

if (!Array.isArray(xmlFiles)) {
xmlFiles = [xmlFiles];
Expand Down
55 changes: 40 additions & 15 deletions packages/node-opcua-address-space/source/loader/load_nodeset2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function makeDefaultVariant(addressSpace: IAddressSpace, dataTypeNode: NodeId, v
}
const dv = builtInType.defaultValue;
const value = typeof dv === "function" ? dv() : dv;

let arrayType: VariantArrayType;
/*
* * n > 1 : the Value is an array with the specified number of dimensions.
Expand Down Expand Up @@ -171,6 +171,7 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
let namespaceCounter = 0;
let found_namespace_in_uri: { [key: string]: NamespacePrivate } = {};
let models: Model[] = [];
let performedCalled = false;

function _reset_namespace_translation() {
debugLog("_reset_namespace_translation");
Expand All @@ -179,16 +180,17 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
namespaceCounter = 0;
alias_map = {};
models = [];
performedCalled = false;
}

function _translateNamespaceIndex(innerIndex: number) {
const namespaceIndex = namespace_uri_translation[innerIndex];

// istanbul ignore next
if (namespaceIndex === undefined) {
// tslint:disable-next-line: no-console
debugLog("Warning: namespace_uri_translation = ", namespace_uri_translation);
throw new Error("_translateNamespaceIndex! Cannot find namespace definition for index " + innerIndex);
errorLog("namespace_uri_translation", namespace_uri_translation);
throw new Error("_translateNamespaceIndex() ! Cannot find namespace definition for index " + innerIndex);
}
return namespaceIndex;
}
Expand All @@ -213,9 +215,9 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
return namespace.internalCreateNode(params) as BaseNode;
}

function _register_namespace_uri_in_translation_table(namespaceUri: string): NamespacePrivate {
function _register_namespace_uri_in_translation_table(namespaceUri: string): void {
if (found_namespace_in_uri[namespaceUri]) {
return found_namespace_in_uri[namespaceUri];
return;
}
const namespace = addressSpace1.getNamespace(namespaceUri);
if (!namespace) {
Expand All @@ -240,7 +242,6 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
" index in addressSpace",
namespace.index
);
return namespace;
}

function _add_namespace(model: Model) {
Expand Down Expand Up @@ -384,6 +385,8 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa

const state_UAObject = {
init(this: any, name: string, attrs: XmlAttributes) {
_perform();

this.obj = {};
this.obj.nodeClass = NodeClass.Object;
this.obj.isAbstract = ec.coerceBoolean(attrs.IsAbstract);
Expand Down Expand Up @@ -422,6 +425,8 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa

const state_UAObjectType = {
init(this: any, name: string, attrs: XmlAttributes) {
_perform();

this.obj = {};
this.obj.nodeClass = NodeClass.ObjectType;
this.obj.isAbstract = ec.coerceBoolean(attrs.IsAbstract);
Expand Down Expand Up @@ -451,6 +456,8 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa

const state_UAReferenceType = {
init(this: any, name: string, attrs: XmlAttributes) {
_perform();

this.obj = {};
this.obj.nodeClass = NodeClass.ReferenceType;
this.obj.isAbstract = ec.coerceBoolean(attrs.IsAbstract);
Expand Down Expand Up @@ -486,6 +493,8 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa

const state_UADataType = {
init(this: any, name: string, attrs: XmlAttributes) {
_perform();

this.obj = {};
this.obj.nodeClass = NodeClass.DataType;
this.obj.isAbstract = ec.coerceBoolean(attrs.IsAbstract) || false;
Expand Down Expand Up @@ -1331,6 +1340,8 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
}
const state_UAVariable = {
init(this: any, name: string, attrs: XmlAttributes) {
_perform();

this.obj = {};

this.obj.nodeClass = NodeClass.Variable;
Expand Down Expand Up @@ -1421,6 +1432,8 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa

const state_UAVariableType = {
init(this: any, name: string, attrs: XmlAttributes) {
_perform();

this.obj = {};
this.obj.isAbstract = ec.coerceBoolean(attrs.IsAbstract);

Expand Down Expand Up @@ -1473,6 +1486,8 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa

const state_UAMethod = {
init(this: any, name: string, attrs: XmlAttributes) {
_perform();

this.obj = {};
this.obj.nodeClass = NodeClass.Method;
// MethodDeclarationId
Expand Down Expand Up @@ -1557,7 +1572,17 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
}
});

function _updateTranslationTable() {
_register_namespace_uri_in_translation_table("http://opcfoundation.org/UA/");
for (const namespaceUri of _namespaceUris) {
_register_namespace_uri_in_translation_table(namespaceUri);
}
}

function _perform() {
if (performedCalled) return;
performedCalled = true;

/**special case for old nodeset file version 1.02 where no models exists */
if (models.length === 0) {
for (const namespaceuri of _namespaceUris) {
Expand All @@ -1573,13 +1598,7 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
});
}
}

doDebug && debugLog("xxx models =", JSON.stringify(models, null, " "));
doDebug && debugLog("xxx _namespaceUris =", _namespaceUris);
_register_namespace_uri_in_translation_table("http://opcfoundation.org/UA/");
for (const namespaceUri of _namespaceUris) {
_register_namespace_uri_in_translation_table(namespaceUri);
}
_updateTranslationTable();
}
// state_ModelTableEntry.parser["RequiredModel"] = state_ModelTableEntry;
let _namespaceUris: string[] = [];
Expand Down Expand Up @@ -1726,9 +1745,15 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
terminate
};
}

export interface NodeSetLoaderOptions {
loadDraftNodes?: boolean;
loadDeprecatedNodes?: boolean;
}

export class NodeSetLoader {
_s: any;
constructor(addressSpace: IAddressSpace) {
_s: NodeSet2ParserEngine;
constructor(addressSpace: IAddressSpace, private options?: NodeSetLoaderOptions) {
this._s = makeNodeSetParserEngine(addressSpace);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as fs from "fs";
import { callbackify, promisify } from "util";
import { callbackify } from "util";

import { checkDebugFlag, make_debugLog, make_errorLog } from "node-opcua-debug";
import { ErrorCallback } from "node-opcua-status-code";
import { IAddressSpace } from "node-opcua-address-space-base";

import { generateAddressSpaceRaw } from "..";
import { NodeSetLoaderOptions } from "../source/loader/load_nodeset2";
const doDebug = checkDebugFlag(__filename);
const debugLog = make_debugLog(__filename);
const errorLog = make_errorLog(__filename);
Expand All @@ -26,9 +26,31 @@ export function generateAddressSpace(
xmlFiles: string | string[],
callback: (err?: Error) => void
): void;
export function generateAddressSpace(addressSpace: IAddressSpace, xmlFiles: string | string[]): Promise<void>;
export function generateAddressSpace(addressSpace: IAddressSpace, xmlFiles: string | string[], callback?: ErrorCallback): any {
callbackify(generateAddressSpaceRaw)(addressSpace, xmlFiles, readNodeSet2XmlFile, callback!);
export function generateAddressSpace(
addressSpace: IAddressSpace,
xmlFiles: string | string[],
options: NodeSetLoaderOptions | undefined,
callback: (err?: Error) => void
): void;
export function generateAddressSpace(
addressSpace: IAddressSpace,
xmlFiles: string | string[],
options?: NodeSetLoaderOptions
): Promise<void>;
export function generateAddressSpace(
... args: any[]
): any {
const addressSpace = args[0] as IAddressSpace;
const xmlFiles = args[1] as string | string[];
if (args.length === 4) {
const options = args[2] as NodeSetLoaderOptions | undefined;
const callback = args[3] as (err?: Error) => void;
callbackify(generateAddressSpaceRaw)(addressSpace, xmlFiles, readNodeSet2XmlFile, options ||{}, callback!);
} else {
const options = {};
const callback = args[2] as (err?: Error) => void;
callbackify(generateAddressSpaceRaw)(addressSpace, xmlFiles, readNodeSet2XmlFile, options, callback!);
}
}

// tslint:disable:no-var-requires
Expand Down
6 changes: 6 additions & 0 deletions packages/node-opcua-address-space/src/base_node_private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,12 @@ function _extractInterfaces2(typeDefinitionNode: UAObjectType | UAVariableType,
}

const addressSpace = typeDefinitionNode.addressSpace;

const hasInterfaceReference = addressSpace.findReferenceType("HasInterface");
if (!hasInterfaceReference) {
// this version of the standard UA namespace doesn't support Interface yet
return [];
}
// example:
// FolderType
// FunctionalGroupType
Expand Down
10 changes: 10 additions & 0 deletions packages/node-opcua-address-space/src/namespace_impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ export class NamespaceImpl implements NamespacePrivate {
public addressSpace: AddressSpacePrivate;
public readonly index: number;

public emulateVersion103 = false;

public version = "0.0.0";
public publicationDate: Date = new Date(Date.UTC(1900, 0, 1));

Expand Down Expand Up @@ -289,27 +291,35 @@ export class NamespaceImpl implements NamespacePrivate {
public _objectTypeIterator(): IterableIterator<UAObjectType> {
return this._objectTypeMap.values();
}

public _objectTypeCount(): number {
return this._objectTypeMap.size;
}

public _variableTypeIterator(): IterableIterator<UAVariableType> {
return this._variableTypeMap.values();
}

public _variableTypeCount(): number {
return this._variableTypeMap.size;
}

public _dataTypeIterator(): IterableIterator<UADataType> {
return this._dataTypeMap.values();
}

public _dataTypeCount(): number {
return this._dataTypeMap.size;
}

public _referenceTypeIterator(): IterableIterator<UAReferenceType> {
return this._referenceTypeMap.values();
}

public _referenceTypeCount(): number {
return this._referenceTypeMap.size;
}

public _aliasCount(): number {
return this._aliases.size;
}
Expand Down

0 comments on commit 714718a

Please sign in to comment.