/** * Retrieve a list of schemaLocation values associated with the specified oaiIdentifier. * * @param oaiIdentifier the OAI identifier * @return a List<String> containing schemaLocation Strings * @throws OAIInternalServerError signals an http status code 500 problem * @throws IdDoesNotExistException the specified oaiIdentifier can't be found * @throws NoMetadataFormatsException the specified oaiIdentifier was found but the item is * flagged as deleted and thus no schemaLocations (i.e. metadataFormats) can be produced. */ public List<String> getSchemaLocations(String oaiIdentifier) throws OAIInternalServerError, IdDoesNotExistException, NoMetadataFormatsException { StatementResultSet stmtRs = null; try { stmtRs = new StatementResultSet(populateIdentifierQuery(oaiIdentifier)); /* * Let your recordFactory decide which schemaLocations * (i.e. metadataFormats) it can produce from the record. * Doing so will preserve the separation of database access * (which happens here) from the record content interpretation * (which is the responsibility of the RecordFactory implementation). */ if (!stmtRs.next()) { throw new IdDoesNotExistException(oaiIdentifier); } else { /* Make sure the identifierQuery returns the columns you need * (if any) to determine the supported schemaLocations for this item */ Map<String, Object> nativeItem = stmtRs.getColumnValues(); return getRecordFactory().getSchemaLocations(nativeItem); } } catch (SQLException e) { LOGGER.error("An Exception occured", e); throw new OAIInternalServerError(e.getMessage()); } finally { try { if (stmtRs != null) { stmtRs.close(); } } catch (SQLException e) { LOGGER.error("An Exception occured", e); throw new OAIInternalServerError(e.getMessage()); } } }
/** * get an Iterator containing the abouts for the nativeItem * * @param nativeItem * @return an Iterator containing the list of about values for this nativeItem */ private Iterator getAbouts(Map<String, Object> nativeItem) throws OAIInternalServerError { StatementResultSet stmtRs = null; try { List<String> abouts = new ArrayList<String>(); if (aboutQuery != null) { RecordFactory rf = getRecordFactory(); String oaiIdentifier = rf.getOAIIdentifier(nativeItem); stmtRs = new StatementResultSet(populateAboutQuery(oaiIdentifier)); while (stmtRs.next()) { Map<String, Object> aboutMap = stmtRs.getColumnValues(); abouts.add((String) aboutMap.get(aboutValueLabel)); } } return abouts.iterator(); } catch (SQLException e) { LOGGER.error("An Exception occured", e); throw new OAIInternalServerError(e.getMessage()); } finally { try { stmtRs.close(); } catch (SQLException e) { LOGGER.error("An Exception occured", e); throw new OAIInternalServerError(e.getMessage()); } } }
/** * Retrieve the specified metadata for the specified oaiIdentifier * * @param oaiIdentifier the OAI identifier * @param metadataPrefix the OAI metadataPrefix * @return the <record/> portion of the XML response. * @throws OAIInternalServerError signals an http status code 500 problem * @throws CannotDisseminateFormatException the metadataPrefix is not supported by the item. * @throws IdDoesNotExistException the oaiIdentifier wasn't found */ public String getRecord(String oaiIdentifier, String metadataPrefix) throws OAIInternalServerError, CannotDisseminateFormatException, IdDoesNotExistException { StatementResultSet stmtRs = null; try { stmtRs = new StatementResultSet(populateIdentifierQuery(oaiIdentifier)); if (!stmtRs.next()) { throw new IdDoesNotExistException(oaiIdentifier); } Map<String, Object> nativeItem = stmtRs.getColumnValues(); return constructRecord(nativeItem, metadataPrefix); } catch (SQLException e) { LOGGER.error("An Exception occured", e); throw new OAIInternalServerError(e.getMessage()); } finally { try { if (stmtRs != null) { stmtRs.close(); } } catch (SQLException e) { LOGGER.error("An Exception occured", e); throw new OAIInternalServerError(e.getMessage()); } } }
/** * Retrieve a list of sets that satisfy the specified criteria * * @return a Map object containing "sets" Iterator object (contains <setSpec/> XML Strings) as * well as an optional resumptionMap Map. * @throws OAIInternalServerError signals an http status code 500 problem */ public Map listSets() throws NoSetHierarchyException, OAIInternalServerError { StatementResultSet stmtRs = null; if (setQuery == null) { if (sets.size() == 0) { throw new NoSetHierarchyException(); } Map<String, Object> listSetsMap = new HashMap<String, Object>(); listSetsMap.put("sets", sets.iterator()); return listSetsMap; } else { purge(); // clean out old resumptionTokens Map<String, Object> listSetsMap = new HashMap<String, Object>(); List<String> sets = new ArrayList<String>(); try { LOGGER.debug(setQuery); /* Get some records from your database */ stmtRs = new StatementResultSet(setQuery); stmtRs.last(); int numRows = stmtRs.getRow(); stmtRs.beforeFirst(); int count; /* load the sets ArrayLists. */ for (count = 0; count < maxListSize && stmtRs.next(); ++count) { /* Use the RecordFactory to extract header/set pairs for each item */ Map<String, Object> nativeItem = stmtRs.getColumnValues(); sets.add(getSetXML(nativeItem)); LOGGER.debug("JDBCOAICatalog.listSets: adding an entry"); } /* decide if you're done */ if (count < numRows) { String resumptionId = getResumptionId(); /** * *************************************************************** Note that storing the * ResultSet in the resumptionResult means the token can't be reused. * *************************************************************** */ resumptionResults.put(resumptionId, stmtRs); /** * *************************************************************** Construct the * resumptionToken String however you see fit. * *************************************************************** */ StringBuilder resumptionTokenSb = new StringBuilder(); resumptionTokenSb.append(resumptionId); resumptionTokenSb.append("!"); resumptionTokenSb.append(Integer.toString(count)); resumptionTokenSb.append("!"); resumptionTokenSb.append(Integer.toString(numRows)); /** * *************************************************************** Use the following line * if you wish to include the optional resumptionToken attributes in the response. * Otherwise, use the line after it that I've commented out. * *************************************************************** */ listSetsMap.put( "resumptionMap", getResumptionMap(resumptionTokenSb.toString(), numRows, 0)); } else { stmtRs.close(); stmtRs = null; } } catch (SQLException e) { if (stmtRs != null) { try { stmtRs.close(); } catch (SQLException e1) { e1.printStackTrace(); } } LOGGER.error("An Exception occured", e); throw new OAIInternalServerError(e.getMessage()); } listSetsMap.put("sets", sets.iterator()); return listSetsMap; } }
/** * Retrieve the next set of records associated with the resumptionToken * * @param resumptionToken implementation-dependent format taken from the previous listRecords() * Map result. * @return a Map object containing entries for "headers" and "identifiers" Iterators (both * containing Strings) as well as an optional "resumptionMap" Map. * @throws OAIInternalServerError signals an http status code 500 problem * @throws BadResumptionTokenException the value of the resumptionToken argument is invalid or * expired. */ public Map<String, Object> listRecords(String resumptionToken) throws BadResumptionTokenException, OAIInternalServerError { Map<String, Object> listRecordsMap = new HashMap<String, Object>(); List<String> records = new ArrayList<String>(); purge(); // clean out old resumptionTokens /** * ******************************************************************** parse your * resumptionToken and look it up in the resumptionResults, if necessary * ******************************************************************** */ StringTokenizer tokenizer = new StringTokenizer(resumptionToken, "!"); String resumptionId; int oldCount; int numRows; String metadataPrefix; StatementResultSet stmtRs = null; try { resumptionId = tokenizer.nextToken(); oldCount = Integer.parseInt(tokenizer.nextToken()); numRows = Integer.parseInt(tokenizer.nextToken()); metadataPrefix = tokenizer.nextToken(); } catch (NoSuchElementException e) { throw new BadResumptionTokenException(); } try { /* Get some more records from your database */ stmtRs = (StatementResultSet) resumptionResults.get(resumptionId); if (stmtRs == null) { throw new BadResumptionTokenException(); } if (stmtRs.getRow() != oldCount) { stmtRs.absolute(oldCount); } int count; /* load the headers and identifiers ArrayLists. */ for (count = 0; count < maxListSize && stmtRs.next(); ++count) { try { Map<String, Object> nativeItem = stmtRs.getColumnValues(); String record = constructRecord(nativeItem, metadataPrefix); records.add(record); } catch (CannotDisseminateFormatException e) { /* the client hacked the resumptionToken beyond repair */ throw new BadResumptionTokenException(); } } /* decide if you're done */ if (oldCount + count < numRows) { /** * *************************************************************** Construct the * resumptionToken String however you see fit. * *************************************************************** */ StringBuilder resumptionTokenSb = new StringBuilder(); resumptionTokenSb.append(resumptionId); resumptionTokenSb.append("!"); resumptionTokenSb.append(Integer.toString(oldCount + count)); resumptionTokenSb.append("!"); resumptionTokenSb.append(Integer.toString(numRows)); resumptionTokenSb.append("!"); resumptionTokenSb.append(metadataPrefix); /** * *************************************************************** Use the following line if * you wish to include the optional resumptionToken attributes in the response. Otherwise, * use the line after it that I've commented out. * *************************************************************** */ listRecordsMap.put( "resumptionMap", getResumptionMap(resumptionTokenSb.toString(), numRows, oldCount)); } else { stmtRs.close(); stmtRs = null; } } catch (SQLException e) { if (stmtRs != null) { try { stmtRs.close(); } catch (SQLException e1) { e1.printStackTrace(); } } LOGGER.error("An Exception occured", e); throw new OAIInternalServerError(e.getMessage()); } listRecordsMap.put("records", records.iterator()); return listRecordsMap; }
/** * Retrieve a list of records that satisfy the specified criteria. Note, though, that unlike the * other OAI verb type methods implemented here, both of the listRecords methods are already * implemented in AbstractCatalog rather than abstracted. This is because it is possible to * implement ListRecords as a combination of ListIdentifiers and GetRecord combinations. * Nevertheless, I suggest that you override both the AbstractCatalog.listRecords methods here * since it will probably improve the performance if you create the response in one fell swoop * rather than construct it one GetRecord at a time. * * @param from beginning date using the proper granularity * @param until ending date using the proper granularity * @param set the set name or null if no such limit is requested * @param metadataPrefix the OAI metadataPrefix or null if no such limit is requested * @return a Map object containing entries for a "records" Iterator object (containing XML * <record/> Strings) and an optional "resumptionMap" Map. * @throws OAIInternalServerError signals an http status code 500 problem * @throws CannotDisseminateFormatException the metadataPrefix isn't supported by the item. */ public Map listRecords(String from, String until, String set, String metadataPrefix) throws CannotDisseminateFormatException, NoItemsMatchException, OAIInternalServerError { purge(); // clean out old resumptionTokens Map<String, Object> listRecordsMap = new HashMap<String, Object>(); List<String> records = new ArrayList<String>(); StatementResultSet stmtRs = null; try { stmtRs = new StatementResultSet(populateRangeQuery(from, until, set)); stmtRs.last(); int numRows = stmtRs.getRow(); if (numRows == 0) { throw new NoItemsMatchException(); } stmtRs.beforeFirst(); int count; /* load the records ArrayList */ for (count = 0; count < maxListSize && stmtRs.next(); ++count) { Map<String, Object> nativeItem = stmtRs.getColumnValues(); String record = constructRecord(nativeItem, metadataPrefix); records.add(record); } /* decide if you're done */ if (count < numRows) { String resumptionId = getResumptionId(); resumptionResults.put(resumptionId, stmtRs); /** * *************************************************************** Construct the * resumptionToken String however you see fit. * *************************************************************** */ StringBuilder resumptionTokenSb = new StringBuilder(); resumptionTokenSb.append(resumptionId); resumptionTokenSb.append("!"); resumptionTokenSb.append(Integer.toString(count)); resumptionTokenSb.append("!"); resumptionTokenSb.append(Integer.toString(numRows)); resumptionTokenSb.append("!"); resumptionTokenSb.append(metadataPrefix); /** * *************************************************************** Use the following line if * you wish to include the optional resumptionToken attributes in the response. Otherwise, * use the line after it that I've commented out. * *************************************************************** */ listRecordsMap.put( "resumptionMap", getResumptionMap(resumptionTokenSb.toString(), numRows, 0)); } else { stmtRs.close(); stmtRs = null; } } catch (SQLException e) { if (stmtRs != null) { try { stmtRs.close(); } catch (SQLException e1) { e1.printStackTrace(); } } LOGGER.error("An Exception occured", e); throw new OAIInternalServerError(e.getMessage()); } listRecordsMap.put("records", records.iterator()); return listRecordsMap; }
/** * Retrieve the next set of sets associated with the resumptionToken * * @param resumptionToken implementation-dependent format taken from the previous listSets() Map * result. * @return a Map object containing "sets" Iterator object (contains <setSpec/> XML Strings) as * well as an optional resumptionMap Map. * @throws BadResumptionTokenException the value of the resumptionToken is invalid or expired. * @throws OAIInternalServerError signals an http status code 500 problem */ public Map<String, Object> listSets(String resumptionToken) throws OAIInternalServerError, BadResumptionTokenException { StatementResultSet stmtRs = null; if (setQuery == null) { throw new BadResumptionTokenException(); } else { purge(); // clean out old resumptionTokens Map<String, Object> listSetsMap = new HashMap<String, Object>(); List<String> sets = new ArrayList<String>(); /** * ******************************************************************** parse your * resumptionToken and look it up in the resumptionResults, if necessary * ******************************************************************** */ StringTokenizer tokenizer = new StringTokenizer(resumptionToken, "!"); String resumptionId; int oldCount; int numRows; try { resumptionId = tokenizer.nextToken(); oldCount = Integer.parseInt(tokenizer.nextToken()); numRows = Integer.parseInt(tokenizer.nextToken()); } catch (NoSuchElementException e) { throw new BadResumptionTokenException(); } try { /* Get some more records from your database */ stmtRs = (StatementResultSet) resumptionResults.get(resumptionId); if (stmtRs == null) { throw new BadResumptionTokenException(); } if (stmtRs.getRow() != oldCount) { stmtRs.absolute(oldCount); } int count; /* load the sets ArrayLists. */ for (count = 0; count < maxListSize && stmtRs.next(); ++count) { Map<String, Object> nativeItem = stmtRs.getColumnValues(); /* Use the RecordFactory to extract set for each item */ sets.add(getSetXML(nativeItem)); } /* decide if you're done. */ if (oldCount + count < numRows) { /** * *************************************************************** Construct the * resumptionToken String however you see fit. * *************************************************************** */ StringBuilder resumptionTokenSb = new StringBuilder(); resumptionTokenSb.append(resumptionId); resumptionTokenSb.append("!"); resumptionTokenSb.append(Integer.toString(oldCount + count)); resumptionTokenSb.append("!"); resumptionTokenSb.append(Integer.toString(numRows)); /** * *************************************************************** Use the following line * if you wish to include the optional resumptionToken attributes in the response. * Otherwise, use the line after it that I've commented out. * *************************************************************** */ listSetsMap.put( "resumptionMap", getResumptionMap(resumptionTokenSb.toString(), numRows, oldCount)); } else { stmtRs.close(); stmtRs = null; } } catch (SQLException e) { if (stmtRs != null) { try { stmtRs.close(); } catch (SQLException e1) { e1.printStackTrace(); } } LOGGER.error("An Exception occured", e); throw new OAIInternalServerError(e.getMessage()); } listSetsMap.put("sets", sets.iterator()); return listSetsMap; } }