package org.sakaiproject.citation.impl.openurl; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import org.apache.commons.collections.BidiMap; import org.apache.commons.collections.bidimap.TreeBidiMap; import org.sakaiproject.citation.api.Citation; import org.sakaiproject.citation.api.CitationService; /** * This just attempts to convert as much of the data as possible without worrying about * what it should be attempting to convert. * @author buckett * */ public class GenericConverter extends AbstractConverter { private CitationService citationService; public void setCitationService(CitationService citationService) { this.citationService = citationService; } private static BidiMap conversion = new TreeBidiMap(); static { // From Citation to OpenURL. // conversion.put(citationProp, openUrlProp) conversion.put("creator", "au"); //conversion.put("year", "date"); // TODO Should validate date (also "date", date"). conversion.put("publisher", "pub"); conversion.put("publicationLocation", "place"); conversion.put("edition", "edition"); // conversion.put("sourceTitle", "series"); // Only for books, sourceTitle is used for other things. // From Journals conversion.put("sourceTitle", "jtitle"); // conversion.put("date", "date"); conversion.put("volume", "volume"); conversion.put("issue", "issue"); conversion.put("startPage", "spage"); conversion.put("endPage", "epage"); conversion.put("pages", "pages"); conversion.put("date", "date"); // DOI and ISBN should become IDs on the context object. // For books citation(date) -> openurl(date) // For journals citation(year) -> openurl(date) } private static class Genre { String openUrlId; String openUrlGenre; String citationScheme; private Genre(String openUrlId, String openUrlGenre, String citationScheme) { this.openUrlId = openUrlId; this.openUrlGenre = openUrlGenre; this.citationScheme = citationScheme; } } private static Collection<Genre> genreConversion = new ArrayList<Genre>(); static { genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:journal", "journal", "article")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:journal", "issue", "article")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:journal", "article", "article")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:journal", "proceeding", "proceeding")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:journal", "conference", "proceeding")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:journal", "report", "report")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:journal", "document", "report")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:book", "book", "book")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:book", "bookitem", "chapter")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:book", "book", "book")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:book", "proceeding", "proceeding")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:book", "conference", "proceeding")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:book", "report", "report")); genreConversion.add(new Genre("info:ofi/fmt:kev:mtx:book", "document", "report")); } @Override protected String getOpenUrlKey(String citationKey) { return (String) conversion.get(citationKey); } @Override protected String getCitationsKey(String openUrlKey) { return (String) conversion.getKey(openUrlKey); } public boolean canConvertOpenUrl(String format) { return true; } public boolean canConvertCitation(String type) { return true; } public ContextObjectEntity convert(Citation citation) { Map<String, Object> props = citation.getCitationProperties(); ContextObjectEntity entity = new ContextObjectEntity(); convertSimple(props, entity); String schema = citation.getSchema().getIdentifier(); for (Genre genre: genreConversion) { if (genre.citationScheme.equals(schema)) { entity.setFormat(genre.openUrlId); entity.addValue("genre", genre.openUrlGenre); break; } } if(citation.hasCitationProperty("isbn")) { Object value = citation.getCitationProperty("isbn", false); addId(entity, value, ISBN_URN_PREFIX); } // Do other mapping. if (citation.hasCitationProperty("doi")) { Object value = citation.getCitationProperty("doi", false); addId(entity, value, DOI_PREFIX); } // TODO Guess the genre return entity; } public Citation convert(ContextObjectEntity entity) { Map<String, List<String>> values = entity.getValues(); // Deal with genre. Genre destGenre = null; if(values.containsKey("genre")) { List<String> genres = values.get("genre"); // Should only have 1 if (!genres.isEmpty()) { String openUrlGenre = genres.get(0); for (Genre genre : genreConversion) { if (genre.openUrlGenre.equals(openUrlGenre)) { destGenre = genre; break; } } } } Citation citation = citationService.addCitation(destGenre != null? destGenre.citationScheme: "unknown"); // Map the IDs from CO the citation. for (String id: entity.getIds()) { if (id.startsWith(ISBN_URN_PREFIX)) { String isbn = id.substring(ISBN_URN_PREFIX.length()); if (isbn.length() > 0 ) { citation.setCitationProperty("isnIdentifier", isbn); } } else if (id.startsWith(DOI_PREFIX)) { String doi = id.substring(DOI_PREFIX.length()); if (doi.length() > 0) { citation.setCitationProperty("doi", doi); } } else if (id.startsWith(ISSN_PREFIX)) { String issn = id.substring(ISSN_PREFIX.length()); if (issn.length() > 0) { citation.setCitationProperty("isnIdentifier", issn); } } else { citation.setCitationProperty("otherIds", id); } } convertSimple(values, citation); convertSingle(values, citation, "atitle", "title"); convertSingle(values, citation, "btitle", "title"); convertSingle(values, citation, "issn", "isnIdentifier"); convertSingle(values, citation, "isbn", "isnIdentifier"); if (destGenre != null) { if ("info:ofi/fmt:kev:mtx:journal".equals(destGenre.openUrlId)) { convertSingle(values, citation, "title", "sourceTitle"); if ("journal".equals(destGenre.openUrlGenre)) { // If it says it's a journal and doesn't have a title already use the jtitle convertSingle(values, citation, "jtitle", "title"); // Clear out the sourceTitle. citation.setCitationProperty("sourceTitle", null); } } if ("info:ofi/fmt:kev:mtx:book".equals(destGenre.openUrlId)) { convertSingle(values, citation, "title", "title"); } } String author = Utils.lookForAuthor(values); if (author != null) { citation.setCitationProperty("creator", author); } return citation; } /** * Converts a single value only if a value doesn't exist for the field already. * @param values * @param citation * @param srcProp * @param destProp * @return */ private boolean convertSingle(Map<String, List<String>> values, Citation citation, String srcProp, String destProp) { List<String> valueList = values.get(srcProp); if (valueList != null && !valueList.isEmpty() && !citation.hasCitationProperty(destProp)) { String value = valueList.get(0); if (value != null && value.length() > 0) { citation.setCitationProperty(destProp, value); return true; } } return false; } }