/* ========================================================================
* Copyright (c) 2005-2025 The OPC Foundation, Inc. All rights reserved.
*
* OPC Foundation MIT License 1.00
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* The complete license agreement can be found here:
* http://opcfoundation.org/License/MIT/1.00/
* ======================================================================*/
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Xml;
using Opc.Ua.Export;
using Opc.Ua.Schema.Types;
namespace Opc.Ua.Schema.Model
{
///
/// Model design represents the content of a set of validated design files.
/// This includes access to only nodes that are not excluded per exclusion
/// criteria and to add nodes that are implicit. Also assigns identifiers
/// as per input identifier file or in sequence of the designs.
///
public interface IModelDesign
{
///
/// Use the true type instead of ExtensionObject when subtypes are allowed.
///
bool UseAllowSubtypes { get; }
///
/// Get all node designs in the model including declarations etc.
///
NodeDesign[] Nodes { get; }
///
/// Namespaces used in the model design.
///
Namespace[] Namespaces { get; }
///
/// Target namespace information
///
Namespace TargetNamespace { get; }
///
/// Target publication date if specified
///
DateTime? TargetPublicationDate { get; }
///
/// Target version if specified
///
string TargetVersion { get; }
///
/// Model depdendencies or null if none
///
IEnumerable Dependencies { get; }
///
/// Namespace table
///
NamespaceTable NamespaceUris { get; }
///
/// Default role permissions to apply to nodes.
///
IReadOnlyDictionary RolePermissions { get; }
///
/// Default access restrictions to apply to nodes.
///
IReadOnlyDictionary AccessRestrictions { get; }
///
/// Returns a list of nodes with nodes excluded per exclusion criteria.
///
IEnumerable GetNodeDesigns();
///
/// Returns a list of services filtered by their service category.
///
Service[] GetListOfServices(params ServiceCategory[] serviceCategories);
///
/// Determines if a node is excluded.
///
bool IsExcluded(NodeDesign node);
///
/// Determines if a data type is excluded.
///
bool IsExcluded(DataType dataType);
///
/// Determines if a field/parameter is excluded.
///
bool IsExcluded(Parameter field);
///
/// Try to find node design.
///
bool TryFindNode(
XmlQualifiedName symbolicId,
string sourceName,
string referenceName,
[NotNullWhen(true)] out NodeDesign? target);
}
///
/// Extensions on top of the model design validator
///
internal static class ModelDesignValidatorExtensions
{
///
/// Find nodedesign of type T
///
///
///
public static T FindNode(
this IModelDesign validator,
XmlQualifiedName symbolicId,
string sourceName,
string referenceName) where T : NodeDesign
{
if (!validator.TryFindNode(
symbolicId,
sourceName,
referenceName,
out T? target))
{
throw new InvalidOperationException(CoreUtils.Format(
"The {0} reference for node {1} is not the expected type: {2}.",
referenceName,
sourceName,
typeof(T).Name));
}
return target;
}
///
/// Find node design
///
///
public static NodeDesign FindNode(
this IModelDesign validator,
XmlQualifiedName symbolicId,
string sourceName,
string referenceName)
{
if (!validator.TryFindNode(
symbolicId,
sourceName,
referenceName,
out NodeDesign? target))
{
throw new InvalidOperationException(CoreUtils.Format(
"The {0} reference for node {1} is not valid: {2}.",
referenceName,
sourceName,
symbolicId.Name));
}
return target;
}
///
/// Find nodedesign of type T
///
///
public static bool TryFindNode(
this IModelDesign validator,
XmlQualifiedName symbolicId,
string sourceName,
string referenceName,
[NotNullWhen(true)] out T? target) where T : NodeDesign
{
if (!validator.TryFindNode(
symbolicId,
sourceName,
referenceName,
out NodeDesign? node) ||
node is not T design)
{
target = default;
return false;
}
target = design;
return true;
}
}
}