public static XDocument ListIdentifiersOrRecords( string verb, string from, string until, string metadataPrefix, string set, string resumptionToken, bool isRoundtrip, List <XElement> errorList, bool?loadAbout) { List <XElement> errors = errorList; DateTime? fromDate = DateTime.MinValue; DateTime? untilDate = DateTime.MaxValue; /* VERB */ bool isRecord = false; if (String.IsNullOrEmpty(verb) || !(verb == "ListIdentifiers" || verb == "ListRecords")) { errors.Add(MlErrors.badVerbArgument); } else { isRecord = verb == "ListRecords"; } /* FROM */ bool isFrom = !String.IsNullOrEmpty(from); fromDate = MlDecode.SafeDateTime(from); if (isFrom && fromDate == null) { errors.Add(MlErrors.badFromArgument); } /* UNTIL */ bool isUntil = !String.IsNullOrEmpty(until); untilDate = MlDecode.SafeDateTime(until); if (isUntil && untilDate == null) { errors.Add(MlErrors.badUntilArgument); } if (isFrom && isUntil && fromDate > untilDate) { errors.Add(MlErrors.badFromAndUntilArgument); } // if both dates exist, they should be in the same format if (!string.IsNullOrEmpty(from) && !string.IsNullOrEmpty(until)) { if (from.Count() != until.Count()) { errors.Add(MlErrors.badFromAndUntilFormatArgument); } } if (fromDate == null) { fromDate = new DateTime(1900, 1, 1); } if (until == null) { untilDate = DateTime.Now; } if (untilDate != null) { untilDate = ((DateTime)untilDate).AddMilliseconds(999); } /* METADATA PREFIX */ bool isPrefixOk = !String.IsNullOrEmpty(metadataPrefix); /* SETS */ bool isSet = !String.IsNullOrEmpty(set); if (isSet && !Properties.supportSets) { errors.Add(MlErrors.noSetHierarchy); } /* RESUMPTION TOKEN */ bool isResumption = !String.IsNullOrEmpty(resumptionToken); if (isResumption && !isRoundtrip) { if (isFrom || isUntil || isPrefixOk || isSet) { errors.Add(MlErrors.badResumptionArgumentOnly); } if (!(Properties.resumptionTokens.ContainsKey(resumptionToken) && Properties.resumptionTokens[resumptionToken].Verb == verb && Properties.resumptionTokens[resumptionToken].ExpirationDate >= DateTime.UtcNow)) { errors.Insert(0, MlErrors.badResumptionArgument); } if (errors.Count == 0) { return(ListIdentifiersOrRecords( verb, Properties.resumptionTokens[resumptionToken].From.HasValue ? Properties.resumptionTokens[resumptionToken].From.Value.ToUniversalTime().ToString(Properties.granularity) : null, Properties.resumptionTokens[resumptionToken].Until.HasValue ? Properties.resumptionTokens[resumptionToken].Until.Value.ToUniversalTime().ToString(Properties.granularity) : null, Properties.resumptionTokens[resumptionToken].MetadataPrefix, Properties.resumptionTokens[resumptionToken].Set, resumptionToken, true, errors, loadAbout)); } } if (!isPrefixOk) /* Check if the only required attribute is included in the request */ { errors.Add(MlErrors.badMetadataArgument); } else if (FormatList.Prefix2Int(metadataPrefix) == 0) { errors.Add(MlErrors.cannotDisseminateFormat); } bool isAbout = loadAbout.HasValue ? loadAbout.Value : Properties.loadAbout; XElement request = new XElement("request", new XAttribute("verb", verb), isFrom ? new XAttribute("from", from) : null, isUntil ? new XAttribute("until", until) : null, isPrefixOk ? new XAttribute("metadataPrefix", metadataPrefix) : null, isSet ? new XAttribute("set", set) : null, isResumption ? new XAttribute("resumptionToken", resumptionToken) : null, Properties.baseURL); if (errors.Count > 0) { errors.Insert(0, request); /* add request on the first position, that it will be diplayed before errors */ return(CreateXml(errors.ToArray())); } var records = new List <RecordQueryResult>(); List <string> sets = Common.Helper.GetAllSets(set); var formatNum = FormatList.Prefix2Int(metadataPrefix); EntityManager entityManager = new EntityManager(); EntityPermissionManager entityPermissionManager = new EntityPermissionManager(); DatasetManager datasetManager = new DatasetManager(); OAIHelper oaiHelper = new OAIHelper(); try { //1. Get list of all datasetids which shoudl be harvested - // ToDo use also the existing parameters like from date long?entityTypeId = entityManager.FindByName(typeof(Dataset).Name)?.Id; entityTypeId = entityTypeId.HasValue ? entityTypeId.Value : -1; // get all datasetids with the last modify date List <long> dsvIds = datasetManager.GetDatasetVersionLatestIds(); // ToDo to get all datasets with the last modfied date, the datasetversionrepo of the dataset manager is used, but its many wrong because of session problem in the past List <long> datasetIds = datasetManager.GetDatasetLatestIds(); datasetIds = datasetManager.DatasetVersionRepo.Query(dsv => dsvIds.Contains(dsv.Id) && dsv.Timestamp >= fromDate && dsv.Timestamp <= untilDate ).Select(dsv => dsv.Dataset.Id).ToList(); //2. Generate a list of headers var recordsQuery = new List <Header>(); foreach (long id in datasetIds) { if (entityPermissionManager.Exists(null, entityTypeId.Value, id)) { recordsQuery.Add(oaiHelper.GetHeader(id)); } } if (isSet) { recordsQuery = recordsQuery.Where(h => h.OAI_Set.Equals(AppConfiguration.ApplicationName)).ToList(); } int recordsCount = recordsQuery.Count(); if (recordsCount == 0) { return(CreateXml(new XElement[] { request, MlErrors.noRecordsMatch })); } else if (isRoundtrip) { Properties.resumptionTokens[resumptionToken].CompleteListSize = recordsCount; recordsQuery = recordsQuery.AsEnumerable().Skip( Properties.resumptionTokens[resumptionToken].Cursor.Value).Take( isRecord ? Properties.maxRecordsInList : Properties.maxIdentifiersInList).ToList(); } else if ((isRecord ? Properties.resumeListRecords : Properties.resumeListIdentifiers) && (isRecord ? recordsCount > Properties.maxRecordsInList : recordsCount > Properties.maxIdentifiersInList)) { resumptionToken = Common.Helper.CreateGuid(); isResumption = true; Properties.resumptionTokens.Add(resumptionToken, new ResumptionToken() { Verb = verb, From = isFrom ? fromDate : null, Until = isUntil ? untilDate : null, MetadataPrefix = metadataPrefix, Set = set, ExpirationDate = DateTime.UtcNow.Add(Properties.expirationTimeSpan), CompleteListSize = recordsCount, Cursor = 0 }); recordsQuery = recordsQuery.AsEnumerable().Take( isRecord ? Properties.maxRecordsInList : Properties.maxIdentifiersInList).ToList(); } /* get data from database */ //var recGroup = (from rec in recordsQuery // join omd in context.ObjectMetadata on rec.HeaderId equals omd.ObjectId // join mdt in context.Metadata on omd.MetadataId equals mdt.MetadataId // group new { OmdMetaType = omd.MetadataType, OaiMetaData = mdt } by rec into grp // select grp).ToList(); /* distribute data into logical units */ foreach (var header in recordsQuery) { long id = oaiHelper.ConvertToId(header.OAI_Identifier); //ToDo add about to the RecordQueryResult object, currently its only null records.Add(new RecordQueryResult(header, oaiHelper.GetMetadata(id, metadataPrefix), null)); } } finally { datasetManager.Dispose(); entityPermissionManager.Dispose(); } bool isCompleted = isResumption ? Properties.resumptionTokens[resumptionToken].Cursor + records.Count >= Properties.resumptionTokens[resumptionToken].CompleteListSize : false; XElement list = new XElement(verb, isRecord ? GetListRecords(records, isAbout) : GetListIdentifiers(records), isResumption ? /* add resumption token or not */ MlEncode.ResumptionToken(Properties.resumptionTokens[resumptionToken], resumptionToken, isCompleted) : null); if (isResumption) { if (isCompleted) { Properties.resumptionTokens.Remove(resumptionToken); } else { Properties.resumptionTokens[resumptionToken].Cursor = Properties.resumptionTokens[resumptionToken].Cursor + records.Count; } } return(CreateXml(new XElement[] { request, list })); }
/// <summary> /// get metadata informations the latest version of a dataset /// </summary> /// <param name="id"></param> /// <returns></returns> public Metadata GetMetadata(long id, string metadataPrefix) { DatasetManager datasetManager = new DatasetManager(); try { DatasetVersion datasetVersion = datasetManager.GetDatasetLatestVersion(id); Metadata metadata = new Metadata(); long mdId = datasetVersion.Dataset.MetadataStructure.Id; XDocument xMetadata = XmlUtility.ToXDocument(datasetVersion.Metadata); metadata.Title = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Title), LinkElementType.Key, mdId, xMetadata)); metadata.Description = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Description), LinkElementType.Key, mdId, xMetadata)); metadata.Creator = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Author), LinkElementType.Key, mdId, xMetadata)); // string to date string date = MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.DataLastModified), LinkElementType.Key, mdId, xMetadata).FirstOrDefault(); DateTime dt; if (DateTime.TryParse(date, out dt)) { metadata.Date = dt; } else // if date is not set in the metadata, lassd motified date of the version is loaded { metadata.Date = datasetVersion.Timestamp; } metadata.Subject = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Subject), LinkElementType.Key, mdId, xMetadata)); // if the publisher is not set in the metadata, its loaded from the tenant. var publishers = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Publisher), LinkElementType.Key, mdId, xMetadata)); if (!publishers.Any()) { metadata.Publisher = AppConfiguration.ApplicationName; } metadata.Contributor = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Contributor), LinkElementType.Key, mdId, xMetadata)); //if type is not in the metadata default it is "dataset" var types = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Type), LinkElementType.Key, mdId, xMetadata)); if (!types.Any()) { types = getEntityName(id); } metadata.Type = types; //if language is not in the metadata default it is "english" var formats = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Format), LinkElementType.Key, mdId, xMetadata)); if (!formats.Any()) { formats = string.Join("][", getFormats(id)); } metadata.Format = formats; metadata.Identifier = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Identifier), LinkElementType.Key, mdId, xMetadata)); metadata.Source = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Source), LinkElementType.Key, mdId, xMetadata)); //if language is not in the metadata default it is "english" var language = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Language), LinkElementType.Key, mdId, xMetadata)); if (language.Any()) { metadata.Language = "English"; } metadata.Relation = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Relation), LinkElementType.Key, mdId, xMetadata)); metadata.Coverage = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Coverage), LinkElementType.Key, mdId, xMetadata)); metadata.Rights = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Rights), LinkElementType.Key, mdId, xMetadata)); //relinks metadata.ParentIdentifier = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Relation), LinkElementType.Key, mdId, xMetadata)); metadata.AdditionalContent = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Description), LinkElementType.Key, mdId, xMetadata)); metadata.PrincipalInvestigator = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Contributor), LinkElementType.Key, mdId, xMetadata)); //set metadata prefix var formatNum = FormatList.Prefix2Int(metadataPrefix); metadata.MdFormat = formatNum; // linkTypes metadata.DataCenter = AppConfiguration.ApplicationName; //ToDo add version to the path string server = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority); string url = server + "/ddm/data/showdata/" + id; metadata.AddtionalData.Add(Metadata.METADATA_URL.ToString(), url); metadata.AddtionalData.Add(Metadata.DATA_URL.ToString(), url); metadata.CoverageComplex = new Coverage(); metadata.CoverageComplex.NorthBoundLatitude = Convert.ToInt32(MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.NorthBoundLatitude), LinkElementType.Key, mdId, xMetadata).FirstOrDefault()); metadata.CoverageComplex.WestBoundLongitude = Convert.ToInt32(MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.WestBoundLongitude), LinkElementType.Key, mdId, xMetadata).FirstOrDefault()); metadata.CoverageComplex.SouthBoundLatitude = Convert.ToInt32(MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.SouthBoundLatitude), LinkElementType.Key, mdId, xMetadata).FirstOrDefault()); metadata.CoverageComplex.EastBoundLongitude = Convert.ToInt32(MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.EastBoundLongitude), LinkElementType.Key, mdId, xMetadata).FirstOrDefault()); metadata.CoverageComplex.Location = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Coverage), LinkElementType.Key, mdId, xMetadata)); metadata.CoverageComplex.MinElevation = MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.MinEvelation), LinkElementType.Key, mdId, xMetadata).FirstOrDefault(); metadata.CoverageComplex.MaxElevation = MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.MaxEvelation), LinkElementType.Key, mdId, xMetadata).FirstOrDefault(); metadata.Keyword = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Keyword), LinkElementType.Key, mdId, xMetadata)); var parameters = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Parameter), LinkElementType.Key, mdId, xMetadata)); if (string.IsNullOrEmpty(parameters)) { parameters = string.Join("][", getVariableNames(id)); } metadata.Parameter = parameters; metadata.Method = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Method), LinkElementType.Key, mdId, xMetadata)); metadata.Sensor = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Sensor), LinkElementType.Key, mdId, xMetadata)); metadata.Feature = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Feature), LinkElementType.Key, mdId, xMetadata)); metadata.Taxonomy = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Taxonomy), LinkElementType.Key, mdId, xMetadata)); metadata.Platform = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Platform), LinkElementType.Key, mdId, xMetadata)); metadata.Project = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.ProjectTitle), LinkElementType.Key, mdId, xMetadata)); metadata.Habitat = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Habitat), LinkElementType.Key, mdId, xMetadata)); metadata.Stratigraphy = string.Join("][", MappingUtils.GetValuesFromMetadata(Convert.ToInt64(Key.Stratigraphy), LinkElementType.Key, mdId, xMetadata)); return(metadata); } finally { datasetManager.Dispose(); } }
public static XDocument GetRecord(string identifier, string metadataPrefix, List <XElement> errorList, bool?loadAbout, Tenant tenant = null) { List <XElement> errors = errorList; bool isIdentifier = !String.IsNullOrEmpty(identifier); if (!isIdentifier) { errors.Add(MlErrors.badIdentifierArgument); } bool isPrefixOk = !String.IsNullOrEmpty(metadataPrefix); if (!isPrefixOk) { errors.Add(MlErrors.badMetadataArgument); } else if (FormatList.Prefix2Int(metadataPrefix) == 0) { errors.Add(MlErrors.cannotDisseminateFormat); isPrefixOk = false; } bool isAbout = loadAbout.HasValue ? loadAbout.Value : Properties.loadAbout; RecordQueryResult record = null; if (isIdentifier && isPrefixOk) { OAIHelper helper = new OAIHelper(); long datasetId = helper.ConvertToId(identifier); Header header = helper.GetHeader(datasetId); if (header == null) { errors.Add(MlErrors.idDoesNotExist); } else { record = new RecordQueryResult(header, helper.GetMetadata(datasetId, metadataPrefix)); // ToDo Check About in the documentaion of oai-pmh record.About = null; if (record == null || record.Metadata == null) { errors.Add(MlErrors.cannotDisseminateRecordFormat); } } } XElement request = new XElement("request", new XAttribute("verb", "GetRecord"), isIdentifier ? new XAttribute("identifier", identifier) : null, isPrefixOk ? new XAttribute("metadataPrefix", metadataPrefix) : null, Properties.baseURL); if (errors.Count > 0) { errors.Insert(0, request); /* add request on the first position, that it will be diplayed before errors */ return(CreateXml(errors.ToArray())); } XElement theRecord = new XElement("GetRecord", new XElement("record", MlEncode.HeaderItem(record.Header, Properties.granularity), MlEncode.Metadata(record.Metadata, Properties.granularity)), isAbout ? MlEncode.About(record.About, Properties.granularity) : null); return(CreateXml(new XElement[] { request, theRecord })); }