/* ======================================================================== * 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; } } }