< Summary

Information
Class: Ice.NativePropertiesAdmin
Assembly: Ice
File(s): /home/runner/work/ice/ice/csharp/src/Ice/NativePropertiesAdmin.cs
Tag: 71_18251537082
Line coverage
59%
Covered lines: 46
Uncovered lines: 31
Coverable lines: 77
Total lines: 196
Line coverage: 59.7%
Branch coverage
52%
Covered branches: 26
Total branches: 50
Branch coverage: 52%
Method coverage
83%
Covered methods: 5
Total methods: 6
Method coverage: 83.3%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
getProperty(...)100%11100%
getPropertiesForPrefix(...)100%11100%
setProperties(...)52%266.765055.74%
addUpdateCallback(...)100%11100%
removeUpdateCallback(...)100%210%

File(s)

/home/runner/work/ice/ice/csharp/src/Ice/NativePropertiesAdmin.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3#nullable enable
 4
 5namespace Ice;
 6
 7/// <summary>The default implementation of the "Properties" admin facet.</summary>
 8public sealed class NativePropertiesAdmin : PropertiesAdminDisp_
 9{
 10    private readonly Properties _properties;
 11    private readonly Logger _logger;
 112    private readonly List<Action<Dictionary<string, string>>> _updateCallbacks = new();
 113    private readonly object _mutex = new();
 14    private const string _traceCategory = "Admin.Properties";
 15
 116    public override string getProperty(string key, Current current) => _properties.getProperty(key);
 17
 18    public override Dictionary<string, string> getPropertiesForPrefix(string prefix, Current current) =>
 119        _properties.getPropertiesForPrefix(prefix);
 20
 21    public override void setProperties(Dictionary<string, string> newProperties, Current current)
 22    {
 123        lock (_mutex)
 24        {
 125            Dictionary<string, string> old = _properties.getPropertiesForPrefix("");
 126            int traceLevel = _properties.getIcePropertyAsInt("Ice.Trace.Admin.Properties");
 27
 28            // Compute the difference between the new property set and the existing property set:
 29            //
 30            // 1) Any properties in the new set that were not defined in the existing set.
 31            //
 32            // 2) Any properties that appear in both sets but with different values.
 33            //
 34            // 3) Any properties not present in the new set but present in the existing set.
 35            //    In other words, the property has been removed.
 36
 137            var added = new Dictionary<string, string>();
 138            var changed = new Dictionary<string, string>();
 139            var removed = new Dictionary<string, string>();
 140            foreach (KeyValuePair<string, string> e in newProperties)
 41            {
 142                string key = e.Key;
 143                string value = e.Value;
 144                if (!old.ContainsKey(key))
 45                {
 146                    if (value.Length > 0)
 47                    {
 48                        //
 49                        // This property is new.
 50                        //
 151                        added.Add(key, value);
 52                    }
 53                }
 54                else
 55                {
 156                    if (!old.TryGetValue(key, out string? v) || !value.Equals(v, StringComparison.Ordinal))
 57                    {
 158                        if (value.Length == 0)
 59                        {
 60                            //
 61                            // This property was removed.
 62                            //
 163                            removed.Add(key, value);
 64                        }
 65                        else
 66                        {
 67                            //
 68                            // This property has changed.
 69                            //
 170                            changed.Add(key, value);
 71                        }
 72                    }
 73
 174                    old.Remove(key);
 75                }
 76            }
 77
 178            if (traceLevel > 0 && (added.Count > 0 || changed.Count > 0 || removed.Count > 0))
 79            {
 080                var message = new System.Text.StringBuilder("Summary of property changes");
 81
 082                if (added.Count > 0)
 83                {
 084                    message.Append("\nNew properties:");
 085                    foreach (KeyValuePair<string, string> e in added)
 86                    {
 087                        message.Append("\n  ");
 088                        message.Append(e.Key);
 089                        if (traceLevel > 1)
 90                        {
 091                            message.Append(" = ");
 092                            message.Append(e.Value);
 93                        }
 94                    }
 95                }
 96
 097                if (changed.Count > 0)
 98                {
 099                    message.Append("\nChanged properties:");
 0100                    foreach (KeyValuePair<string, string> e in changed)
 101                    {
 0102                        message.Append("\n  ");
 0103                        message.Append(e.Key);
 0104                        if (traceLevel > 1)
 105                        {
 0106                            message.Append(" = ");
 0107                            message.Append(e.Value);
 0108                            message.Append(" (old value = ");
 0109                            message.Append(_properties.getProperty(e.Key));
 0110                            message.Append(')');
 111                        }
 112                    }
 113                }
 114
 0115                if (removed.Count > 0)
 116                {
 0117                    message.Append("\nRemoved properties:");
 0118                    foreach (KeyValuePair<string, string> e in removed)
 119                    {
 0120                        message.Append("\n  ");
 0121                        message.Append(e.Key);
 122                    }
 123                }
 124
 0125                _logger.trace(_traceCategory, message.ToString());
 126            }
 127
 128            //
 129            // Update the property set.
 130            //
 131
 1132            foreach (KeyValuePair<string, string> e in added)
 133            {
 1134                _properties.setProperty(e.Key, e.Value);
 135            }
 136
 1137            foreach (KeyValuePair<string, string> e in changed)
 138            {
 1139                _properties.setProperty(e.Key, e.Value);
 140            }
 141
 1142            foreach (KeyValuePair<string, string> e in removed)
 143            {
 1144                _properties.setProperty(e.Key, "");
 145            }
 146
 1147            if (_updateCallbacks.Count > 0)
 148            {
 1149                var changes = new Dictionary<string, string>(added);
 1150                foreach (KeyValuePair<string, string> e in changed)
 151                {
 1152                    changes.Add(e.Key, e.Value);
 153                }
 1154                foreach (KeyValuePair<string, string> e in removed)
 155                {
 1156                    changes.Add(e.Key, e.Value);
 157                }
 158
 159                // Copy callbacks to allow callbacks to update callbacks
 160                foreach (
 1161                    Action<Dictionary<string, string>> callback in
 1162                    new List<System.Action<Dictionary<string, string>>>(_updateCallbacks))
 163                {
 164                    // The callback should not throw any exception.
 1165                    callback(changes);
 166                }
 167            }
 0168        }
 1169    }
 170
 171    /// <summary>Registers an update callback that will be invoked when a property update occurs.</summary>
 172    /// <param name="cb">The callback.</param>
 173    public void addUpdateCallback(System.Action<Dictionary<string, string>> cb)
 174    {
 1175        lock (_mutex)
 176        {
 1177            _updateCallbacks.Add(cb);
 1178        }
 1179    }
 180
 181    /// <summary>Unregisters an update callback previously registered with <see cref="addUpdateCallback" /> .</summary>
 182    /// <param name="cb">The callback.</param>
 183    public void removeUpdateCallback(System.Action<Dictionary<string, string>> cb)
 184    {
 0185        lock (_mutex)
 186        {
 0187            _updateCallbacks.Remove(cb);
 0188        }
 0189    }
 190
 1191    internal NativePropertiesAdmin(Internal.Instance instance)
 192    {
 1193        _properties = instance.initializationData().properties!;
 1194        _logger = instance.initializationData().logger!;
 1195    }
 196}