/*
* Copyright (C) 2013 Robert Simonovsky
*
* 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.export.desa.structure;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.yourmediashelf.fedora.generated.foxml.DatastreamVersionType;
import com.yourmediashelf.fedora.generated.foxml.DigitalObject;
import cz.cas.lib.proarc.common.export.desa.Const;
import cz.cas.lib.proarc.common.export.desa.DesaContext;
import cz.cas.lib.proarc.common.export.mets.MetsExportException;
import cz.cas.lib.proarc.common.export.mets.MetsUtils;
import cz.cas.lib.proarc.common.fedora.FoxmlUtils;
/**
* Class that represents the element of Desa export
*
* @author Robert Simonovsky
*
*/
public class DesaElement implements IDesaElement {
public final List<Element> descriptor;
public final String model;
private final DesaContext desaContext;
private final String originalPid;
private final Logger LOG = Logger.getLogger(DesaElement.class.getName());
private DesaElement parent;
private final List<DesaElement> children = new ArrayList<DesaElement>();
private final List<Element> relsExt;
private final DigitalObject sourceObject;
private String idSIPVersion;
private final String descriptorType;
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getDescriptorType
* ()
*/
@Override
public String getDescriptorType() {
return descriptorType;
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getIdSIPVersion
* ()
*/
@Override
public String getIdSIPVersion() {
return idSIPVersion;
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#setIdSIPVersion
* (java.lang.String)
*/
@Override
public void setIdSIPVersion(String idSIPVersion) {
this.idSIPVersion = idSIPVersion;
}
private final String elementType;
private final String elementID;
private String zipName;
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getZipName()
*/
@Override
public String getZipName() {
return zipName;
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#setZipName
* (java.lang.String)
*/
@Override
public void setZipName(String zipName) throws MetsExportException {
this.zipName = zipName;
if (!checkZipFileOK()) {
throw new MetsExportException(this.getOriginalPid(), "Identifier is not valid - generated output file name is:" + zipName, false, null);
}
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getDesaContext
* ()
*/
@Override
public DesaContext getDesaContext() {
return desaContext;
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getElementType
* ()
*/
@Override
public String getElementType() {
return elementType;
}
/**
* Constructor
*
* @param digitalObject
* @param parent
* @param desaContext
* @param fillChildren
* @throws MetsExportException
*/
public DesaElement(DigitalObject digitalObject, Object parent, DesaContext desaContext, boolean fillChildren) throws MetsExportException {
this.desaContext = desaContext;
this.sourceObject = digitalObject;
this.relsExt = FoxmlUtils.findDatastream(digitalObject, "RELS-EXT").getDatastreamVersion().get(0).getXmlContent().getAny();
DatastreamVersionType biblioVersion = FoxmlUtils.findDatastream(digitalObject, "BIBLIO_MODS").getDatastreamVersion().get(0);
this.descriptor = biblioVersion.getXmlContent().getAny();
this.descriptorType = biblioVersion.getFORMATURI();
model = MetsUtils.getModel(relsExt);
this.elementType = Const.typeMap.get(model);
this.elementID = this.elementType + desaContext.addElementId(this.elementType);
this.originalPid = digitalObject.getPID();
if (parent instanceof DesaElement) {
this.parent = (DesaElement) parent;
}
if (fillChildren) {
fillChildren();
}
if (parent == null) {
if (Const.FILE.equals(this.getElementType())) {
this.parent = initParent();
}
}
if (this.parent == null) {
desaContext.setRootElement(this);
LOG.log(Level.FINE, "Root element found:" + getOriginalPid() + "(" + getElementType() + ")");
}
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getElementID
* ()
*/
@Override
public String getElementID() {
return elementID;
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getParent()
*/
@Override
public DesaElement getParent() {
return parent;
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getChildren()
*/
@Override
public List<DesaElement> getChildren() {
return children;
}
/**
* Inits the parent element of current element
*
* @return
* @throws MetsExportException
*/
private DesaElement initParent() throws MetsExportException {
String parentId;
if (desaContext.getFedoraClient() != null) {
parentId = MetsUtils.getParent(originalPid, desaContext.getRemoteStorage());
LOG.fine("Parent found from Fedora:" + parentId);
} else {
parentId = MetsUtils.getParent(originalPid, desaContext.getFsParentMap());
LOG.fine("Parent found from Local:" + parentId);
}
if (parentId == null) {
LOG.fine("Parent not found - returning null");
return null;
}
DigitalObject parentObject = null;
if (desaContext.getFedoraClient() != null) {
parentObject = MetsUtils.readRelatedFoXML(parentId, desaContext.getFedoraClient());
} else {
parentObject = MetsUtils.readRelatedFoXML(desaContext.getPath(), parentId);
}
DesaElement parentInit = new DesaElement(parentObject, null, desaContext, false);
parentInit.children.add(this);
return parentInit;
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getDescriptor
* ()
*/
@Override
public List<Element> getDescriptor() {
return descriptor;
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getModel()
*/
@Override
public String getModel() {
return model;
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getOriginalPid
* ()
*/
@Override
public String getOriginalPid() {
return originalPid;
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getRelsExt()
*/
@Override
public List<Element> getRelsExt() {
return relsExt;
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#getSourceObject
* ()
*/
@Override
public DigitalObject getSourceObject() {
return sourceObject;
}
/**
* Static method for instantiating an Element
*
* @param object
* @param parent
* @param desaContext
* @param withChildren
* @return
* @throws MetsExportException
*/
public static DesaElement getElement(DigitalObject object, DesaElement parent, DesaContext desaContext, boolean withChildren) throws MetsExportException {
List<Element> relsExt = FoxmlUtils.findDatastream(object, "RELS-EXT").getDatastreamVersion().get(0).getXmlContent().getAny();
String model = MetsUtils.getModel(relsExt);
String type = Const.typeMap.get(model);
if (type == null) {
throw new MetsExportException(object.getPID(), "Unknown model:" + model, false, null);
}
return new DesaElement(object, parent, desaContext, withChildren);
}
/**
* Generates children of this element
*
*/
@Override
public void fillChildren() throws MetsExportException {
Node node = MetsUtils.xPathEvaluateNode(relsExt, "*[local-name()='RDF']/*[local-name()='Description']");
NodeList hasPageNodes = node.getChildNodes();
for (int a = 0; a < hasPageNodes.getLength(); a++) {
if (MetsUtils.hasReferenceXML(hasPageNodes.item(a).getNodeName())) {
Node rdfResourceNode = hasPageNodes.item(a).getAttributes().getNamedItem("rdf:resource");
String fileName = rdfResourceNode.getNodeValue();
DigitalObject object = null;
if (desaContext.getFedoraClient() != null) {
object = MetsUtils.readRelatedFoXML(fileName, desaContext.getFedoraClient());
} else {
object = MetsUtils.readRelatedFoXML(desaContext.getPath(), fileName);
}
DesaElement child = new DesaElement(object, this, desaContext, true);
this.children.add(child);
LOG.log(Level.FINE, "Child found for:" + getOriginalPid() + "(" + getElementType() + ") - " + child.getOriginalPid() + "(" + child.getElementType() + ")");
}
}
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#accept(cz
* .cas.lib.proarc.common.export.desa.structure.IDesaElementVisitor)
*/
@Override
public void accept(IDesaElementVisitor desaVisitor) throws MetsExportException {
desaVisitor.insertIntoMets(this, null);
}
/*
* (non-Javadoc)
*
* @see
* cz.cas.lib.proarc.common.export.desa.structure.IDesaElement#accept(cz
* .cas.lib.proarc.common.export.desa.structure.IDesaElementVisitor)
*/
@Override
public void accept(IDesaElementVisitor desaVisitor, HashMap<String, String> desaProps) throws MetsExportException {
LOG.info("Export visitor accepted for:" + this.getOriginalPid() + "(" + this.getElementType() + ")");
desaVisitor.insertIntoMets(this, desaProps);
}
/**
* Checks if fileName is correct
*
* @param folder
*/
private boolean checkZipFileOK() {
File file = null;
try {
file = new File(this.getDesaContext().getOutputPath() + File.separator + this.getZipName() + ".zip");
LOG.fine("Checking if fileName is OK:" + file.getAbsolutePath());
if (file.exists()) {
LOG.log(Level.SEVERE, "File:" + file.getAbsolutePath() + " already exists !");
return false;
}
file.createNewFile();
file.delete();
return true;
} catch (IOException e) {
LOG.log(Level.WARNING, "file:" + file.getAbsolutePath() + " is not valid filename", e);
return false;
}
}
}