/* * SPDX-License-Identifier: AGPL-3.0-or-later * Copyright (C) 2025 Sergej Görzen * This file is part of xAPI4Unity. */ #if UNITY_EDITOR using System.Collections.Generic; using Newtonsoft.Json; namespace xAPI4Unity.Editor.Parser.IO { /// /// Represents different types of extensions in the xAPI definition files (e.g., Activity, Context, or Result). /// internal enum ExtensionType { Unknown, Activity, Context, Result } /// /// Represents different types of definitions in the xAPI definition files (e.g., Extension, Verb, or Activity). /// internal enum DefinitionType { Unknown, Extension, Verb, Activity } /// /// Represents the content of an xAPI definition file, including translated names, descriptions, and matching information. /// internal struct DefinitionFileContent { /// /// Dictionary of localized names for the definition. /// [JsonProperty("name")] public Dictionary Names { get; set; } /// /// Dictionary of localized descriptions for the definition. /// [JsonProperty("description")] public Dictionary Descriptions { get; set; } /// /// Related match URIs. May be null if not provided. /// [JsonProperty("relatedMatch", NullValueHandling = NullValueHandling.Ignore)] public string[] RelatedMatch { get; set; } /// /// Exact match URIs. May be null if not provided. /// [JsonProperty("exactMatch", NullValueHandling = NullValueHandling.Ignore)] public string[] ExactMatch { get; set; } } /// /// Represents a single xAPI definition file, including its content and metadata. /// internal class DefinitionFile { /// /// The file path (slashed for cross-platform support). /// public readonly string Path; /// /// The raw JSON content of the file. /// public readonly string JsonContent; /// /// The parsed content of the JSON in the file. /// public readonly DefinitionFileContent Content; /// /// The name of the definition (derived from the file name, without extension). /// public readonly string Name; /// /// The context this definition belongs to (e.g., a namespace or custom scope). /// public readonly string Context; /// /// The associated category of this definition, if applicable. /// public readonly string Category; /// /// Indicates whether this definition belongs to a specific category. /// public bool HasCategory => !string.IsNullOrEmpty(Category); /// /// The type of the xAPI definition (e.g., Extension, Verb, or Activity). /// public readonly DefinitionType DefinitionType; /// /// The type of extension for xAPI definitions categorized as extensions (e.g., Activity, Context, or Result). /// public readonly ExtensionType ExtensionType; /// /// Creates an instance of a DefinitionFile based on its path and content. /// /// The file path in the definition structure. /// The raw JSON content of the file. public DefinitionFile(string path, string content) { // Normalize the path to use slashes for compatibility across environments. Path = path.Replace('\\', '/'); JsonContent = content; // Derive the definition name from the file name (without extension). Name = System.IO.Path.GetFileNameWithoutExtension(path).ClearName(); // Split path segments to extract context, definition type, and other metadata. var s = Path.Split('/'); Context = s[0]; DefinitionType = DetectDefinitionType(s[1]); // Determine the specific extension type, if applicable. if (DefinitionType == DefinitionType.Extension) { ExtensionType = DetectExtensionType(s[2]); } // Parse the JSON content into structured definition file content. if (!string.IsNullOrEmpty(JsonContent)) { Content = JsonConvert.DeserializeObject(JsonContent); } // Extract category information based on path depth and definition type. if (s.Length >= 4 && (DefinitionType == DefinitionType.Verb || DefinitionType == DefinitionType.Activity)) Category = s[2]; else if (s.Length >= 5 && DefinitionType == DefinitionType.Extension) Category = s[3]; } /// /// Detects the definition type based on the path segment. /// /// The path segment representing the type. /// The detected DefinitionType. private DefinitionType DetectDefinitionType(string type) { switch (type) { case "extensions": return DefinitionType.Extension; case "verbs": return DefinitionType.Verb; case "activities": return DefinitionType.Activity; default: return DefinitionType.Unknown; } } /// /// Detects the extension type based on the path segment. /// /// The path segment representing the extension type. /// The detected ExtensionType. private ExtensionType DetectExtensionType(string type) { switch (type) { case "result": return ExtensionType.Result; case "context": return ExtensionType.Context; case "activity": return ExtensionType.Activity; default: return ExtensionType.Unknown; } } /// /// Provides a string representation of the DefinitionFile, including key metadata. /// /// A formatted string containing the file's details. public override string ToString() => $"[File: Name=\"{Name}\", Context=\"{Context}\", DefinitionType=\"{DefinitionType}\", ExtensionType=\"{ExtensionType}\", Path=\"{Path}\", Content=\"{Content}\"]"; } } #endif