using Coscine.Api.Project.Models; using Coscine.ApiCommons; using Coscine.ApiCommons.Exceptions; using Coscine.ApiCommons.Factories; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json.Linq; using System; using System.Linq; using VDS.RDF.Writing; using VDS.RDF.Parsing; using VDS.RDF; using Metadata; using System.Web; using System.IO; namespace Coscine.Api.Project.Controllers { public class MetadataController : Controller { private readonly Authenticator _authenticator; private readonly MetadataModel _metadataModel; private readonly ResourceModel _resourceModel; private readonly Util _util; public MetadataController() { _authenticator = new Authenticator(this, Program.Configuration); _metadataModel = new MetadataModel(); _resourceModel = new ResourceModel(); _util = new Util(); } [Route("[controller]")] public IActionResult Index() { return Ok(_authenticator.ValidateAndExecute((user) => { return NoContent(); })); } [HttpGet("[controller]/resource/{resourceId}/ap/{applicationProfileId}")] public IActionResult GetApplicationProfile(string resourceId, string applicationProfileId) { var user = _authenticator.GetUserFromToken(); var resource = _resourceModel.GetById(Guid.Parse(resourceId)); if (_metadataModel.IsProjectMember(user, resource)) { var graph = _util.GetGraph(HttpUtility.UrlDecode(applicationProfileId)); var fixedValuesGraph = new Graph(); fixedValuesGraph.LoadFromString(resource.FixedValues, new RdfJsonParser()); graph.Merge(fixedValuesGraph); var json = JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter())); return Ok(json); } else { throw new NotAuthorizedException("User is no project member!"); } } [HttpGet("[controller]/resource/{resourceId}/aplist/")] public IActionResult ListAllApplicationProfiles(string resourceId) { return Ok(_authenticator.ValidateAndExecute((user) => { var resource = _resourceModel.GetById(Guid.Parse(resourceId)); if (_metadataModel.IsProjectMember(user, resource)) { var graphUris = _util.ListGraphs(); return new JArray(graphUris.Select(x => x.ToString()).Where(x => x.StartsWith("https://purl.org/coscine/ap/"))); } else { throw new NotAuthorizedException("User is no project member!"); } })); } [HttpGet("[controller]/resource/{resourceId}/filename/{filename}/ver/{version}")] public IActionResult GetMetadataForFile(string resourceId, string filename, string version) { return Ok(_authenticator.ValidateAndExecute((user) => { var resource = _resourceModel.GetById(Guid.Parse(resourceId)); if (_metadataModel.IsProjectMember(user, resource)) { var id = _metadataModel.GenerateId(resourceId, filename, version); var graph = _util.GetGraph(id); return JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter())); } else { throw new NotAuthorizedException("User is no project member!"); } })); } [HttpPut("[controller]/resource/{resourceId}/filename/{filename}/ver/{version}")] public IActionResult StoreMetadataForFile(string resourceId, string filename, string version) { return Ok(_authenticator.ValidateAndExecute((user) => { var innerBlock = ObjectFactory<JToken>.DeserializeFromStream(Request.Body); var graphName = _metadataModel.GenerateId(resourceId, filename, version); var graphNameUri = new Uri(graphName); var json = new JObject { [graphName] = innerBlock }; var resource = _resourceModel.GetById(Guid.Parse(resourceId)); if (_metadataModel.IsProjectMember(user, resource)) { var graph = new Graph(); graph.LoadFromString(json.ToString(), new RdfJsonParser()); var fixedValuesGraph = new Graph(); fixedValuesGraph.LoadFromString(resource.FixedValues, new RdfJsonParser()); foreach(var triple in fixedValuesGraph.Triples.Where(x => x.Predicate.ToString() == "https://purl.org/coscine/fixedValue")) { // Remove any existing triples foreach (var triple2 in graph.GetTriplesWithSubjectPredicate(graph.CreateUriNode(graphNameUri), triple.Subject).ToList()) { graph.Retract(triple2); } graph.Assert(graph.CreateUriNode(graphNameUri), triple.Subject, triple.Object); } // Default values is not checked or added // validate the data if (_util.ValidateShacl(graph, graphNameUri)) { // store the data if (_util.HasGraph(graphNameUri)) { _util.ClearGraph(graphNameUri); } else { _util.CreateNamedGraph(graphNameUri); } // BaseUri must be set for the sparql query graph.BaseUri = graphNameUri; _util.AddGraph(graph); return NoContent(); } else { throw new NotAuthorizedException("Data has the wrong format!"); } } else { throw new NotAuthorizedException("User is no project member!"); } })); } [HttpGet("[controller]/vocabulary/{resourceId}/{path}")] public IActionResult GetVocabulary(string resourceId, string path) { return Ok(_authenticator.ValidateAndExecute((user) => { var resource = _resourceModel.GetById(Guid.Parse(resourceId)); if (_metadataModel.IsProjectMember(user, resource)) { var graph = _util.GetGraph(HttpUtility.UrlDecode(path)); JArray de = new JArray(); foreach (var kv in _util.GetVocabularyLabels(graph, "de")) { JObject obj = new JObject { ["value"] = kv.Key, ["name"] = kv.Value }; de.Add(obj); } JArray en = new JArray(); foreach(var kv in _util.GetVocabularyLabels(graph, "en")) { JObject obj = new JObject { ["value"] = kv.Key, ["name"] = kv.Value }; en.Add(obj); } JObject json = new JObject { ["de"] = de, ["en"] = en }; return json; } else { throw new NotAuthorizedException("User is no project member!"); } })); } } }