Skip to content

Commit 0186b22

Browse files
committed
Java and C# linting fixes and suppressions
1 parent ccb9a31 commit 0186b22

File tree

87 files changed

+803
-399
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+803
-399
lines changed

checkstyle-suppressions.xml

-10
This file was deleted.

csharp/GlobalSuppressions.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Global Suppression Notes
2+
3+
## Overview
4+
5+
Senzing has chosen to suppress some of the default coding guidance for .NET development in the
6+
provided examples and code snippets via the use of `GlobalSuppressions.cs` files. This is done
7+
to favor of readability and clarity of the examples and, in places, to encourage developers to
8+
implement code that is more robust and easily maintained. The reasoning for each such suppression
9+
is given here along with alternatives if you instead choose to follow the guidance from
10+
the suppressed directives.
11+
12+
### CA1859: Use concrete types when possible for improved performance
13+
14+
Senzing encourages developers to use the `Senzing.Sdk.SzEnvironment` interface in favor of its concrete
15+
implementation type throughout their code with the exception of the construction and initialization of
16+
the `Senzing.Sdk.SzEnvironment` instance. This is encouraged so that your code can easily interchange one
17+
implementation for another without concerns for dependencies on methods that may be specific to a concrete
18+
implementation type. For example, one might swap `SzCoreEnvironment` for an open-source `SzGrpcEnvironment`
19+
on a single line for initialization without concerns for searching out incompatibilities that might be
20+
caused elsewhere in the code due to such a change.
21+
22+
In short, Senzing feels that in the case of `SzEnvironment` the performance concerns referenced by `CA1859`
23+
are insignificant and negligible especially when compared to the cost of sacrificing good Object-Oriented
24+
Programming principles that would otherwise improve the maintainability of your source code.
25+
26+
Therefore, Senzing encourages:
27+
28+
```java
29+
// initialize the Senzing environment
30+
SzEnvironment env = SzCoreEnvironment.NewBuilder()
31+
.Settings(settings)
32+
.InstanceName(instanceName)
33+
.VerboseLogging(false)
34+
.Build();
35+
```
36+
37+
Over:
38+
39+
```java
40+
// initialize the Senzing environment
41+
SzCoreEnvironment env = SzCoreEnvironment.NewBuilder()
42+
.Settings(settings)
43+
.InstanceName(instanceName)
44+
.VerboseLogging(false)
45+
.Build();
46+
```
47+
48+
If, however, you prefer to adhere to the guidance encouraged by `CA1859`, then simply use the
49+
concrete type in your declaration of the environment variable **OR** use the `var` keyword in
50+
place of a specific type name.

csharp/README.md

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ Further, you will need to set environment variables so the Senzing installation
3232
set Path=%SENZING_PATH%\er\lib;%Path%
3333
```
3434

35+
## Using Example Code
36+
37+
Senzing encourages and allows you to freely copy the provided example code and modify it to your own needs as you
38+
see fit. However, please refer to the [Global Suppression Notes] to understand how to best adapt the example code
39+
to your own coding project.
40+
3541
## Building
3642

3743
The C# snippets can built using the `dotnet build [project-name]` command under each directory. They can be run using `dotnet run --project [project-name]` command. Attempting to run a snippet will also trigger building it.
@@ -162,3 +168,5 @@ The `SnippetRunner` project will run one or more snippets for you and create a t
162168
- stewardship.ForceResolve
163169
- stewardship.ForceUnresolve
164170
```
171+
172+
[Global Suppression Notes]: GlobalSuppressions.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// This file is used by Code Analysis to maintain SuppressMessage
2+
// attributes that are applied to this project.
3+
// Project-level suppressions either have no target or are given
4+
// a specific target and scoped to a namespace, type, member, etc.
5+
6+
using System.Diagnostics.CodeAnalysis;
7+
8+
[assembly: SuppressMessage("Performance", "CA1854:Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method", Justification = "Nullable Dictionary making for less readable code.")]
9+
[assembly: SuppressMessage("Usage", "CA2201:Do not raise reserved exception types", Justification = "These are examples and there is no need to use more specific exceptions")]
10+
[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "It is better to OOP principle to use interfaces rather than concrete types")]

csharp/runner/SnippetRunner/InstallLocations.cs

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
namespace Senzing.Snippets.Runner;
2+
13
using System.Text;
24
using System.Text.Json;
35
using System.Text.RegularExpressions;
@@ -315,8 +317,7 @@ private static bool IsDirectory(string path)
315317
supportDir = (supportPath != null) ? new DirectoryInfo(supportPath) : null;
316318

317319
// check if support dir is not defined AND we have a local dev build
318-
if (supportDir == null && installDir != null
319-
&& "dist".Equals(installDir.Name, OrdinalIgnoreCase))
320+
if (supportDir == null && "dist".Equals(installDir.Name, OrdinalIgnoreCase))
320321
{
321322
supportDir = new DirectoryInfo(Path.Combine(installDir.FullName, "data"));
322323
if (!supportDir.Exists)
@@ -386,7 +387,7 @@ private static bool IsDirectory(string path)
386387
resourceDir = (resourcePath != null) ? new DirectoryInfo(resourcePath) : null;
387388

388389
// try the "resources" sub-directory of the installation
389-
if (resourceDir == null && installDir != null)
390+
if (resourceDir == null)
390391
{
391392
resourceDir = new DirectoryInfo(Path.Combine(installDir.FullName, "resources"));
392393
if (!resourceDir.Exists)
@@ -456,7 +457,7 @@ private static bool IsDirectory(string path)
456457
configDir = (configPath != null) ? new DirectoryInfo(configPath) : null;
457458

458459
// check if config dir is not defined AND we have a local dev build
459-
if (configDir == null && installDir != null && templatesDir != null
460+
if (configDir == null && templatesDir != null
460461
&& "dist".Equals(installDir.Name, OrdinalIgnoreCase))
461462
{
462463
configDir = templatesDir;
@@ -473,7 +474,7 @@ private static bool IsDirectory(string path)
473474
}
474475

475476
// if still null, try to use the install's etc directory
476-
if (configDir == null && installDir != null)
477+
if (configDir == null)
477478
{
478479
configDir = new DirectoryInfo(
479480
Path.Combine(installDir.FullName, "etc"));
@@ -572,7 +573,7 @@ private static bool IsDirectory(string path)
572573
result.supportDir = supportDir;
573574
result.resourceDir = resourceDir;
574575
result.templatesDir = templatesDir;
575-
result.devBuild = (installDir != null) && ("dist".Equals(installDir.Name, OrdinalIgnoreCase));
576+
result.devBuild = ("dist".Equals(installDir.Name, OrdinalIgnoreCase));
576577

577578
// return the result
578579
return result;

csharp/runner/SnippetRunner/Program.cs

+37-26
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1-
using System.Collections;
1+
using System.Collections;
22
using System.Diagnostics;
3+
using System.Globalization;
34
using System.Reflection;
45
using System.Text;
56
using System.Text.Json;
67
using System.Text.Json.Nodes;
8+
79
using Microsoft.Data.Sqlite;
10+
811
using Senzing.Sdk;
912
using Senzing.Sdk.Core;
13+
using Senzing.Snippets.Runner;
14+
15+
using static System.StringComparison;
1016
using static Senzing.Sdk.SzFlags;
1117

1218
Assembly assembly = Assembly.GetExecutingAssembly();
@@ -52,7 +58,7 @@
5258
if (snippetDir == null && runnerDir != null)
5359
{
5460
csharpDir = Directory.GetParent(runnerDir.FullName);
55-
if (!"csharp".Equals(csharpDir?.Name))
61+
if (!"csharp".Equals(csharpDir?.Name, Ordinal))
5662
{
5763
HandleWrongDirectory();
5864
}
@@ -86,7 +92,7 @@ SortedDictionary<string, SortedDictionary<string, string>> snippetsMap
8692
{
8793
string group = entry.Key;
8894
IDictionary<string, string> snippetMap = entry.Value;
89-
IList<(string, string, string)> tuples
95+
List<(string, string, string)> tuples
9096
= new List<(string, string, string)>(snippetMap.Count);
9197

9298
foreach (KeyValuePair<string, string> subEntry in snippetMap)
@@ -106,7 +112,7 @@ SortedDictionary<string, SortedDictionary<string, string>> snippetsMap
106112
{
107113
string snippet = subEntry.Key;
108114
string snippetPath = subEntry.Value;
109-
IList<(string, string, string)> tuples = new List<(string, string, string)>(1);
115+
List<(string, string, string)> tuples = new List<(string, string, string)>(1);
110116
tuples.Add((group, snippet, snippetPath));
111117
snippetOptions.Add(snippet, tuples.AsReadOnly());
112118
}
@@ -132,7 +138,7 @@ SortedDictionary<string, SortedDictionary<string, string>> snippetsMap
132138
settingsJson = JsonNode.Parse(settings)?.AsObject();
133139
if (settingsJson == null)
134140
{
135-
throw new Exception("Setting must be a JSON object: " + settings);
141+
throw new ArgumentNullException("Setting must be a JSON object: " + settings);
136142
}
137143
}
138144
catch (Exception e)
@@ -141,6 +147,7 @@ SortedDictionary<string, SortedDictionary<string, string>> snippetsMap
141147
Console.Error.WriteLine("The provided Senzing settings were not valid JSON:");
142148
Console.Error.WriteLine();
143149
Environment.Exit(1);
150+
throw;
144151
}
145152
}
146153

@@ -155,6 +162,7 @@ SortedDictionary<string, SortedDictionary<string, string>> snippetsMap
155162
{
156163
Console.Error.WriteLine(e);
157164
Environment.Exit(1);
165+
throw;
158166
}
159167
if (installLocations == null)
160168
{
@@ -164,11 +172,11 @@ SortedDictionary<string, SortedDictionary<string, string>> snippetsMap
164172
return;
165173
}
166174

167-
IList<(string, string)> snippets = new List<(string, string)>(100);
175+
List<(string, string)> snippets = new List<(string, string)>(100);
168176
for (int index = 0; index < args.Length; index++)
169177
{
170178
string arg = args[index];
171-
if (arg.Equals("all"))
179+
if (arg.Equals("all", Ordinal))
172180
{
173181
foreach (IDictionary<string, string> snippetMap in snippetsMap.Values)
174182
{
@@ -230,7 +238,7 @@ SortedDictionary<string, SortedDictionary<string, string>> snippetsMap
230238
{
231239
Console.WriteLine();
232240
Stopwatch stopwatch = Stopwatch.StartNew();
233-
IDictionary<string, string> properties = new Dictionary<string, string>();
241+
Dictionary<string, string> properties = new Dictionary<string, string>();
234242
string resourceName = $"""{assemblyName}.Resources.{snippet}.properties""";
235243
LoadProperties(properties, resourceName);
236244
Console.WriteLine("Preparing repository for " + snippet + "...");
@@ -285,14 +293,14 @@ SortedDictionary<string, SortedDictionary<string, string>> snippetsMap
285293
"Missing resource (" + fileName + ") for load file ("
286294
+ loadKey + ") for snippet (" + snippet + ")");
287295
}
296+
StreamReader rdr = new StreamReader(stream, Encoding.UTF8);
288297
try
289298
{
290-
StreamReader rdr = new StreamReader(stream, Encoding.UTF8);
291299
for (string? line = rdr.ReadLine(); line != null; line = rdr.ReadLine())
292300
{
293301
line = line.Trim();
294302
if (line.Length == 0) continue;
295-
if (line.StartsWith("#")) continue;
303+
if (line.StartsWith('#')) continue;
296304
JsonObject? record = JsonNode.Parse(line)?.AsObject();
297305
if (record == null)
298306
{
@@ -307,6 +315,7 @@ SortedDictionary<string, SortedDictionary<string, string>> snippetsMap
307315
}
308316
finally
309317
{
318+
rdr.Close();
310319
stream.Close();
311320
}
312321

@@ -337,7 +346,7 @@ SortedDictionary<string, SortedDictionary<string, string>> snippetsMap
337346
{
338347
Console.Error.WriteLine(e);
339348
Environment.Exit(1);
340-
return;
349+
throw;
341350
}
342351

343352
static void LoadProperties(IDictionary<string, string> properties, String resourceName)
@@ -352,9 +361,9 @@ static void LoadProperties(IDictionary<string, string> properties, String resour
352361
for (string? line = rdr.ReadLine(); line != null; line = rdr.ReadLine())
353362
{
354363
if (line.Trim().Length == 0) continue;
355-
if (line.StartsWith("#")) continue;
356-
if (line.StartsWith("!")) continue;
357-
int index = line.IndexOf('=');
364+
if (line.StartsWith('#')) continue;
365+
if (line.StartsWith('!')) continue;
366+
int index = line.IndexOf('=', Ordinal);
358367
if (index < 1) continue;
359368
string key = line.Substring(0, index).Trim();
360369
string value = "";
@@ -363,18 +372,19 @@ static void LoadProperties(IDictionary<string, string> properties, String resour
363372
value = line.Substring(index + 1);
364373
}
365374
value = value.Trim();
366-
while (value.EndsWith("\\"))
375+
while (value.EndsWith('\\'))
367376
{
368377
line = rdr.ReadLine();
369378
if (line == null) break;
370379
line = line.Trim();
371-
value = value.Substring(0, value.Length - 1) + line;
380+
value = string.Concat(value.AsSpan(0, value.Length - 1), line);
372381
}
373382
properties[key] = value;
374383
}
375384
}
376385
finally
377386
{
387+
rdr.Close();
378388
stream.Close();
379389
}
380390
}
@@ -393,11 +403,12 @@ SortedDictionary<string, SortedDictionary<string, string>> snippetsMap
393403
{
394404
continue;
395405
}
396-
if (!snippetsMap.ContainsKey(group))
406+
snippetsMap.TryGetValue(group, out SortedDictionary<string, string>? snippetMap);
407+
if (snippetMap == null)
397408
{
398-
snippetsMap.Add(group, new SortedDictionary<string, string>());
409+
snippetMap = new SortedDictionary<string, string>();
410+
snippetsMap.Add(group, snippetMap);
399411
}
400-
SortedDictionary<string, string> snippetMap = snippetsMap[group];
401412

402413
foreach (string subdir in Directory.GetDirectories(dir))
403414
{
@@ -495,7 +506,7 @@ static void ExecuteSnippet(string snippet,
495506
Process? process = Process.Start(startInfo);
496507
if (process == null)
497508
{
498-
throw new Exception("Failed to execute snippet; " + snippet);
509+
throw new ArgumentNullException("Failed to execute snippet; " + snippet);
499510
}
500511

501512
if (properties != null && properties.ContainsKey(InputKeyPrefix + 0))
@@ -520,7 +531,7 @@ static void ExecuteSnippet(string snippet,
520531
if (properties != null && properties.ContainsKey(DestroyAfterKey))
521532
{
522533
string propValue = properties[DestroyAfterKey];
523-
int delay = Int32.Parse(propValue);
534+
int delay = Int32.Parse(propValue, CultureInfo.InvariantCulture);
524535
bool exited = process.WaitForExit(delay);
525536
if (!exited && !process.HasExited)
526537
{
@@ -622,11 +633,11 @@ static string SetupTempRepository(InstallLocations senzingInstall)
622633
}
623634
}
624635

625-
string supportPath = supportDir.FullName.Replace("\\", "\\\\");
626-
string configPath = configDir.FullName.Replace("\\", "\\\\"); ;
627-
string resourcePath = resourcesDir.FullName.Replace("\\", "\\\\"); ;
628-
string baseConfig = File.ReadAllText(configFile).Replace("\\", "\\\\");
629-
string databasePath = databaseFile.Replace("\\", "\\\\");
636+
string supportPath = supportDir.FullName.Replace("\\", "\\\\", Ordinal);
637+
string configPath = configDir.FullName.Replace("\\", "\\\\", Ordinal);
638+
string resourcePath = resourcesDir.FullName.Replace("\\", "\\\\", Ordinal);
639+
string baseConfig = File.ReadAllText(configFile).Replace("\\", "\\\\", Ordinal);
640+
string databasePath = databaseFile.Replace("\\", "\\\\", Ordinal);
630641
string settings = $$"""
631642
{
632643
"PIPELINE": {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// This file is used by Code Analysis to maintain SuppressMessage
2+
// attributes that are applied to this project.
3+
// Project-level suppressions either have no target or are given
4+
// a specific target and scoped to a namespace, type, member, etc.
5+
6+
using System.Diagnostics.CodeAnalysis;
7+
8+
[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")]

csharp/snippets/configuration/AddDataSources/Program.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242
// get the SzConfig for the config ID
4343
SzConfig config = configMgr.CreateConfig(configID);
44-
44+
4545
// create an array of the data sources to add
4646
string[] dataSources = { "CUSTOMERS", "EMPLOYEES", "WATCHLIST" };
4747

@@ -56,7 +56,7 @@
5656

5757
// add the modified config to the repository with a comment
5858
long newConfigID = configMgr.RegisterConfig(modifiedConfig);
59-
59+
6060
try
6161
{
6262
// replace the default config
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// This file is used by Code Analysis to maintain SuppressMessage
2+
// attributes that are applied to this project.
3+
// Project-level suppressions either have no target or are given
4+
// a specific target and scoped to a namespace, type, member, etc.
5+
6+
using System.Diagnostics.CodeAnalysis;
7+
8+
[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")]

0 commit comments

Comments
 (0)