/// <summary> Lists all of the identifiers within a particular OAI-PMH set </summary> /// <param name="Output"> Stream to which to write the text for this main writer </param> /// <param name="SetCode"> Code for the OAI-PMH set </param> /// <param name="From"> Date from which to return all the identifiers </param> /// <param name="Until"> Date to which to return all the identifiers </param> /// <param name="MetadataPrefix"> Prefix of the metadata fomat to return the identifier information</param> /// <param name="ResumptionToken"> Resumption token from the original query string, if one was provided </param> protected internal void ListIdentifiers(TextWriter Output, string SetCode, string From, string Until, string MetadataPrefix, string ResumptionToken) { // Set the default dates and page first DateTime from_date = new DateTime(1900, 1, 1); DateTime until_date = DateTime.Now.AddDays(1); int current_page = 1; // Start to build the request XML StringBuilder request = new StringBuilder(); // If there is a resumption token, that should be used to pull all information if (ResumptionToken.Length > 0) { // Add to the request request.Append("resumptionToken=\"" + ResumptionToken + "\" "); // Try to get the MetadataPrefix from the token if (ResumptionToken.IndexOf(":") < 0) { Write_Error(Output, "resumptionToken=\"" + ResumptionToken + "\" verb=\"ListRecords\"", "badResumptionToken", "no metadata specified in resumption token:" + ResumptionToken); return; } // Compute the state from the token try { MetadataPrefix = ResumptionToken.Substring(ResumptionToken.IndexOf(":") + 1); string modifiedToken = ResumptionToken.Substring(0, ResumptionToken.IndexOf(":")); string page_string = modifiedToken.Substring(0, 6); SetCode = modifiedToken.Substring(6 + oai_repository_identifier.Length); // Try to parse the page and dates now if (!Int32.TryParse(page_string, out current_page)) { Write_Error(Output, "resumptionToken=\"" + ResumptionToken + "\" verb=\"ListRecords\"", "badResumptionToken", "no resumeAfter in resumptionToken:" + ResumptionToken); return; } // Was there a from and until date included in the token? if (SetCode.IndexOf(".") > 0) { int period_index = SetCode.IndexOf("."); string from_string = SetCode.Substring(period_index + 1, 8); string until_string = SetCode.Substring(period_index + 9, 8); SetCode = SetCode.Substring(0, period_index); // Before we can parse those dates, we need to format a bit for the .NET framework from_string = from_string.Substring(4, 2) + "/" + from_string.Substring(6) + "/" + from_string.Substring(0, 4); until_string = until_string.Substring(4, 2) + "/" + until_string.Substring(6) + "/" + until_string.Substring(0, 4); // Try to parse the dates now if ((!DateTime.TryParse(from_string, out from_date)) || (!DateTime.TryParse(until_string, out until_date))) { Write_Error(Output, "resumptionToken=\"" + ResumptionToken + "\" verb=\"ListRecords\"", "badResumptionToken", "no resumeAfter in resumptionToken:" + ResumptionToken); return; } } } catch { Write_Error(Output, "resumptionToken=\"" + ResumptionToken + "\" verb=\"ListIdentifiers\"", "badResumptionToken", "no resumeAfter in resumptionToken:" + ResumptionToken); return; } } else { // Add to the request if (From.Length > 0) { request.Append("from=\"" + From + "\" "); } request.Append("metadataPrefix=\"" + MetadataPrefix + "\" "); if (SetCode.Length > 0) { request.Append("set=\"" + SetCode + "\" "); } if (Until.Length > 0) { request.Append("until=\"" + Until + "\" "); } // Check the format of FROM and UNTIL, if they are provided const string REGEX_MATCH_STRING = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})))"; if (From.Length > 0) { if ((From.Length != 10) || (!Regex.Match(From, REGEX_MATCH_STRING).Success) || (!DateTime.TryParse(From, out from_date))) { Write_Error(Output, "verb=\"\"", "badArgument", "bad OAI date format:" + From); return; } } if (Until.Length > 0) { if ((Until.Length != 10) || (!Regex.Match(Until, REGEX_MATCH_STRING).Success) || (!DateTime.TryParse(Until, out until_date))) { Write_Error(Output, "verb=\"\"", "badArgument", "bad OAI date format:" + Until); return; } } } // Make sure both the identifier and metadata have data if (MetadataPrefix.Length == 0) { Write_Error(Output, "verb=\"\"", "badArgument", "metadataPrefix required argument is missing."); return; } // Finish the request echo portion request.Append("verb=\"ListIdentifiers\""); // Metadata prefix must be in list of acceptable if (!metadataPrefixes.Contains(MetadataPrefix)) { Write_Error(Output, request.ToString(), "cannotDisseminateFormat", MetadataPrefix + " is not supported by this repository."); return; } // Get the records List <OAI_Record> results = SobekCM_Database.Get_OAI_Data(SetCode, MetadataPrefix, from_date, until_date, IDENTIFIERS_PER_PAGE, current_page, false); if (results.Count == 0) { Write_Error(Output, request.ToString(), "noRecordsMatch", "There are no records matching the criteria indicated by this request's arguments."); } else { // Determine if a resumption token should be submitted after this. This is easily // done since the database will attempt to return one additional record, if more records // exist bool more_records = false; if (results.Count > IDENTIFIERS_PER_PAGE) { more_records = true; results.RemoveAt(results.Count - 1); } // Write the list of records/identifiers Write_OAI_ListRecords(SetCode, from_date, until_date, ResumptionToken, request.ToString(), true, current_page, more_records, MetadataPrefix, results, Output); } }