public void Add(string term, TermDefinition definition) => TermDefinitions[term] = definition;
private async Task _createTermDefinition(Context activeContext, JObject localContext, string term, Dictionary <string, bool> defined) { if (defined.ContainsKey(term)) { if (defined[term]) { return; } else { throw new JsonLDException("cyclic IRI mapping"); } } defined[term] = false; if (term.StartsWith("@")) { throw new JsonLDException("keyword redefinition"); } activeContext.Remove(term); var value = localContext[term]; if (value == null || value.Type == JTokenType.Null || value.Type == JTokenType.Object && ((JObject)value)["@id"]?.Type == JTokenType.Null) { defined[term] = true; activeContext.Add(term, null); return; } if (value.Type == JTokenType.String) { var data = value.ToObject <string>(); value = new JObject { ["@id"] = data }; } else if (value.Type != JTokenType.Object) { throw new JsonLDException("invalid term definition"); } var definition = new TermDefinition(); if (value["@type"] != null) { var type = value["@type"]; if (type.Type != JTokenType.String) { throw new JsonLDException("invalid type mapping"); } var typeString = await _expandIri(activeContext, type.ToObject <string>(), false, true, localContext, defined); if (typeString != "@id" && typeString != "@vocab" && !Uri.IsWellFormedUriString(typeString, UriKind.Absolute)) { throw new JsonLDException("invalid type mapping"); } definition.TypeMapping = typeString; } if (value["@reverse"] != null) { if (value["@id"] != null) { throw new JsonLDException("invalid reverse property"); } if (value["@reverse"].Type != JTokenType.String) { throw new JsonLDException("invalid IRI mapping"); } definition.IriMapping = await _expandIri(activeContext, value["@reverse"].ToObject <string>(), false, true, localContext, defined); if (!definition.IriMapping.Contains(":")) { throw new JsonLDException("invalid IRI mapping"); } definition.ReverseProperty = true; activeContext.Add(term, definition); defined[term] = true; return; } definition.ReverseProperty = false; // not needed, but to be sure(TM) if (value["@id"] != null && value["@id"].ToObject <string>() != term) { if (value["@id"].Type != JTokenType.String) { throw new JsonLDException("invalid IRI mapping"); } definition.IriMapping = await _expandIri(activeContext, value["@id"].ToObject <string>(), false, true, localContext, defined); // todo: 13.2 } else if (term.Contains(":")) { var spl = term.Split(new [] { ':' }, 2); var prefix = spl[0]; var suffix = spl[1]; if (!suffix.StartsWith("//") && localContext[prefix] != null) { await _createTermDefinition(activeContext, localContext, prefix, defined); } if (activeContext.Has(prefix)) { definition.IriMapping = activeContext[prefix].IriMapping + suffix; } else { definition.IriMapping = term; } } else if (activeContext.VocabularyMapping != null) { definition.IriMapping = activeContext.VocabularyMapping + term; } else { throw new JsonLDException("invalid IRI mapping"); } if (value["@container"] != null) { var container = value["@container"].ToObject <string>(); if (!_containerValues.Contains(container)) { throw new JsonLDException("invalid container mapping"); } definition.ContainerMapping = container; } if (value["@language"] != null && value["@type"] == null) { var language = value["@language"].ToObject <string>(); if (value["@language"].Type != JTokenType.Null && value["@language"].Type != JTokenType.String) { throw new JsonLDException("invalid language mapping"); } definition.LanguageMapping = language.ToLower(); } activeContext.Add(term, definition); defined[term] = true; }