/*
* Copyright (C) 2015 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.workflow;
import cz.cas.lib.proarc.common.config.CatalogConfiguration;
import cz.cas.lib.proarc.common.export.mets.ValidationErrorHandler;
import cz.cas.lib.proarc.common.mods.ModsUtils;
import cz.cas.lib.proarc.common.mods.custom.ModsConstants;
import cz.cas.lib.proarc.common.workflow.model.PhysicalMaterial;
import cz.cas.lib.proarc.common.xml.ProarcXmlUtils;
import cz.cas.lib.proarc.common.xml.SimpleNamespaceContext;
import java.io.IOException;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
*
* @author Jan Pokorsky
*/
class PhysicalMaterialBuilder {
private final PhysicalMaterial m = new PhysicalMaterial();
private XPath xpath;
private DocumentBuilder db;
private ValidationErrorHandler validationErrorHandler;
public PhysicalMaterialBuilder() {
initXml();
}
public PhysicalMaterial build() {
return m;
}
public PhysicalMaterial build(String xml, CatalogConfiguration catalog) {
setCatalog(catalog);
setMetadata(xml);
return m;
}
public PhysicalMaterialBuilder setCatalog(CatalogConfiguration catalog) {
m.setSource(catalog.getUrl());
return this;
}
public PhysicalMaterialBuilder setMetadata(String modsXml) {
try {
return setMetadataImpl(modsXml);
} catch (Exception ex) {
StringBuilder sb = new StringBuilder("Cannot set metadata!");
for (String error : validationErrorHandler.getValidationErrors()) {
sb.append('\n').append(error);
}
throw new IllegalStateException(sb.toString(), ex);
}
}
private PhysicalMaterialBuilder setMetadataImpl(String modsXml) throws IOException, SAXException, XPathExpressionException {
Document modsDom = db.parse(new InputSource(new StringReader(modsXml)));
Element modsElm = (Element) xpath.evaluate(
"m:mods | m:modsCollection/m:mods", modsDom, XPathConstants.NODE);
String barcode = xpath.evaluate(
"m:identifier[@type='barcode' and not(@invalid)]", modsElm);
StringBuilder label = getTitle(new StringBuilder(), modsElm);
m.setMetadata(modsXml);
m.setBarcode(barcode);
m.setField001(null);
m.setLabel(label.length() == 0
? "?"
: label.length() > 2000
? label.substring(0, 2000) : label.toString());
return this;
}
private StringBuilder getTitle(StringBuilder label, Element modsElm) throws XPathExpressionException {
Element titleInfoElm = (Element) xpath.evaluate(
"m:titleInfo[not(@type) and m:title/text()]", modsElm, XPathConstants.NODE);
if (titleInfoElm != null) {
String title = val(xpath.evaluate("m:title/text()", titleInfoElm));
String subTitle = val(xpath.evaluate("m:subTitle/text()", titleInfoElm));
label.append(title);
if (subTitle != null) {
label.append(" : ");
label.append(subTitle);
}
}
return label;
}
private void initXml() {
try {
XPathFactory xPathFactory = ProarcXmlUtils.defaultXPathFactory();
xpath = xPathFactory.newXPath();
xpath.setNamespaceContext(new SimpleNamespaceContext().add("m", ModsConstants.NS));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setSchema(ModsUtils.getSchema());
db = dbf.newDocumentBuilder();
validationErrorHandler = new ValidationErrorHandler();
db.setErrorHandler(validationErrorHandler);
} catch (Exception ex) {
throw new IllegalStateException("Cannot initialize XML support!", ex);
}
}
static String val(String v) {
return v == null || v.isEmpty() ? null : v;
}
}