/* * Copyright (C) 2014 Jan Pokorsky * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package cz.cas.lib.proarc.common.mods.ndk; import cz.cas.lib.proarc.common.fedora.FoxmlUtils; import cz.cas.lib.proarc.mods.CodeOrText; import cz.cas.lib.proarc.mods.DateDefinition; import cz.cas.lib.proarc.mods.GenreDefinition; import cz.cas.lib.proarc.mods.IdentifierDefinition; import cz.cas.lib.proarc.mods.LanguageDefinition; import cz.cas.lib.proarc.mods.LanguageTermDefinition; import cz.cas.lib.proarc.mods.ModsDefinition; import cz.cas.lib.proarc.mods.NameDefinition; import cz.cas.lib.proarc.mods.NamePartDefinition; import cz.cas.lib.proarc.mods.OriginInfoDefinition; import cz.cas.lib.proarc.mods.PlaceDefinition; import cz.cas.lib.proarc.mods.PlaceTermDefinition; import cz.cas.lib.proarc.mods.RecordInfoDefinition; import cz.cas.lib.proarc.mods.StringPlusLanguage; import cz.cas.lib.proarc.mods.StringPlusLanguagePlusAuthority; import cz.cas.lib.proarc.mods.TitleInfoDefinition; import cz.cas.lib.proarc.oaidublincore.ElementType; import cz.cas.lib.proarc.oaidublincore.OaiDcType; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; /** * The mapping helper. * * @author Jan Pokorsky */ final class MapperUtils { static ModsDefinition addPid(ModsDefinition mods, String pid) { String uuid = FoxmlUtils.pidAsUuid(pid); for (IdentifierDefinition id : mods.getIdentifier()) { if (uuid.equals(id.getValue()) && "uuid".equals(id.getType())) { return mods; } } IdentifierDefinition id = new IdentifierDefinition(); id.setValue(uuid); id.setType("uuid"); mods.getIdentifier().add(0, id); return mods; } static GenreDefinition addGenre(ModsDefinition mods, String value) { List<GenreDefinition> genres = mods.getGenre(); GenreDefinition reqGenre = null; for (GenreDefinition genre : genres) { if (value.equals(genre.getValue())) { reqGenre = genre; break; } } if (reqGenre == null) { reqGenre = new GenreDefinition(); reqGenre.setValue(value); genres.add(0, reqGenre); } return reqGenre; } /** * Creates title according to LoC {@code MODS->DC} mapping. * @param ti MODS titleInfo * @return string for DC title */ static String createTitleString(TitleInfoDefinition ti) { StringBuilder title = new StringBuilder(); addNonSort(title, ti); addTitle(title, ti); addSubTitle(title, ti); addPartNumber(title, ti); addPartName(title, ti); return title.toString(); } /** * Builds title from {@code titleInfo} subelements. * @param title the result title * @param titleParts parts to add * @param prefix an optional parts prefix. Added in case the passed title is not empty. * @return the result title */ static StringBuilder addTitlePart(StringBuilder title, List<StringPlusLanguage> titleParts, String prefix) { if (!titleParts.isEmpty()) { String value = toValue(titleParts.get(0).getValue()); if (value != null) { if (prefix != null && title.length() > 0) { title.append(prefix); } title.append(value); } } return title; } static StringBuilder addNonSort(StringBuilder title, TitleInfoDefinition ti) { return addTitlePart(title, ti.getNonSort(), null); } static StringBuilder addTitle(StringBuilder title, TitleInfoDefinition ti) { return addTitlePart(title, ti.getTitle(), " "); } static StringBuilder addSubTitle(StringBuilder title, TitleInfoDefinition ti) { return addTitlePart(title, ti.getSubTitle(), ": "); } static StringBuilder addPartName(StringBuilder title, TitleInfoDefinition ti) { return addTitlePart(title, ti.getPartName(), ". "); } static StringBuilder addPartNumber(StringBuilder title, TitleInfoDefinition ti) { return addTitlePart(title, ti.getPartNumber(), ". "); } // mods/language/languageTerm @type=code, @authority="iso639‐2b" // XXX should it be really checked? static void fillLanguage(ModsDefinition mods) { // fillLanguage(mods.getLanguage()); } static void fillLanguage(List<LanguageDefinition> languages) { // for (LanguageDefinition language : languages) { // for (LanguageTermDefinition languageTerm : language.getLanguageTerm()) { // CodeOrText type = languageTerm.getType(); // if (type == null) { // languageTerm.setType(CodeOrText.CODE); // } // String authority = toValue(languageTerm.getAuthority()); // if (authority == null) { // languageTerm.setAuthority("iso639‐2b"); // } // } // } } static void fillRecordInfo(ModsDefinition mods) { Date now = new Date(); List<RecordInfoDefinition> recordInfos = mods.getRecordInfo(); if (recordInfos.isEmpty()) { recordInfos.add(new RecordInfoDefinition()); } RecordInfoDefinition recordInfo = recordInfos.get(0); // mods/recordInfo/recordCreationDate@encoding="iso8601" List<DateDefinition> recordCreationDates = recordInfo.getRecordCreationDate(); DateDefinition creationDate = null; for (DateDefinition date : recordCreationDates) { if ("iso8601".equals(date.getEncoding())) { creationDate = date; } } // mods/recordInfo/recordCreationDate=now if missing SimpleDateFormat DATETIME_ISO8601 = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); if (creationDate == null) { // remove dates with other encodings recordCreationDates.clear(); creationDate = new DateDefinition(); creationDate.setEncoding("iso8601"); creationDate.setValue(DATETIME_ISO8601.format(now)); recordCreationDates.add(creationDate); } // mods/recordInfo/recordChangeDate@encoding="iso8601" // mods/recordInfo/recordChangeDate=now List<DateDefinition> recordChangeDates = recordInfo.getRecordChangeDate(); recordChangeDates.clear(); DateDefinition changeDate = new DateDefinition(); changeDate.setEncoding("iso8601"); changeDate.setValue(DATETIME_ISO8601.format(now)); recordChangeDates.add(changeDate); // mods/recordInfo/recordContentSource@authority="marcorg" for (StringPlusLanguagePlusAuthority contentSource : recordInfo.getRecordContentSource()) { if (contentSource.getAuthority() == null) { contentSource.setAuthority("marcorg"); } } fillLanguage(recordInfo.getLanguageOfCataloging()); } static void addStringPlusLanguage(List<ElementType> dcElms, List<? extends StringPlusLanguage> modsValues) { for (StringPlusLanguage modsValue : modsValues) { // XXX lang? addElementType(dcElms, modsValue.getValue(), null); } } static void addName(List<NameDefinition> modsNames, List<ElementType> dcElms) { for (NameDefinition name : modsNames) { StringBuilder sbName = new StringBuilder(); StringBuilder sbFamily = new StringBuilder(); StringBuilder sbGiven = new StringBuilder(); StringBuilder sbDate = new StringBuilder(); for (NamePartDefinition namePart : name.getNamePart()) { String type = namePart.getType(); if (type == null) { sbName.append(namePart.getValue()).append(' '); } else if ("family".equals(type)) { sbFamily.append(namePart.getValue()).append(' '); } else if ("given".equals(type)) { sbGiven.append(namePart.getValue()).append(' '); } else if ("date".equals(type)) { sbDate.append(namePart.getValue()).append(", "); } } if (sbFamily.length() > 0) { sbName.append(sbFamily.substring(0, sbFamily.length() - 1)); } if (sbGiven.length() > 0) { if (sbName.length() > 0) { sbName.append(", "); } sbName.append(sbGiven.substring(0, sbGiven.length() - 1)); } if (sbDate.length() > 0) { if (sbName.length() > 0) { sbName.append(", "); } sbName.append(sbDate.substring(0, sbDate.length() - 2)); } if (sbName.length() > 0) { addElementType(dcElms, sbName.toString()); } } } static void addOriginInfo(List<OriginInfoDefinition> originInfos, OaiDcType dc) { for (OriginInfoDefinition originInfo : originInfos) { for (PlaceDefinition place : originInfo.getPlace()) { for (PlaceTermDefinition placeTerm : place.getPlaceTerm()) { CodeOrText type = placeTerm.getType(); if (type == CodeOrText.TEXT || type == null) { addElementType(dc.getCoverages(), placeTerm.getValue()); } } } addStringPlusLanguage(dc.getPublishers(), originInfo.getPublisher()); for (DateDefinition date : originInfo.getDateIssued()) { String point = toValue(date.getPoint()); if (point == null) { addElementType(dc.getDates(), date.getValue()); } } } } static void addLanguage(List<LanguageDefinition> modsLanguages, OaiDcType dc) { for (LanguageDefinition language : modsLanguages) { for (LanguageTermDefinition languageTerm : language.getLanguageTerm()) { CodeOrText type = languageTerm.getType(); if (type != CodeOrText.TEXT) { addElementType(dc.getLanguages(), languageTerm.getValue()); } } } } static List<ElementType> addElementType(List<ElementType> dcElms, String value) { return addElementType(dcElms, value, null); } static List<ElementType> addElementType(List<ElementType> dcElms, String value, String lang) { value = toValue(value); lang = toValue(lang); if (value != null) { dcElms.add(new ElementType(value, lang)); } return dcElms; } static String findPartNumber(ModsDefinition mods) { List<TitleInfoDefinition> titleInfos = mods.getTitleInfo(); if (!titleInfos.isEmpty()) { TitleInfoDefinition titleInfo = titleInfos.get(0); List<StringPlusLanguage> partNumbers = titleInfo.getPartNumber(); if (!partNumbers.isEmpty()) { return toValue(partNumbers.get(0).getValue()); } } return null; } static String findPartName(ModsDefinition mods) { List<TitleInfoDefinition> titleInfos = mods.getTitleInfo(); if (!titleInfos.isEmpty()) { TitleInfoDefinition titleInfo = titleInfos.get(0); List<StringPlusLanguage> partNames = titleInfo.getPartName(); if (!partNames.isEmpty()) { return toValue(partNames.get(0).getValue()); } } return null; } static String toValue(String s) { if (s != null) { s = s.trim(); } return s == null || s.isEmpty() ? null : s; } }