/*******************************************************************************
* Copyright 2006 - 2014 Vienna University of Technology,
* Department of Software Technology and Interactive Systems, IFS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
******************************************************************************/
package eu.scape_project.planning.xml;
import java.io.ByteArrayInputStream;
import java.io.Serializable;
import java.util.List;
import javax.inject.Inject;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import eu.scape_project.planning.exception.PlanningException;
import eu.scape_project.planning.manager.DigitalObjectManager;
import eu.scape_project.planning.manager.StorageException;
import eu.scape_project.planning.model.CollectionProfile;
import eu.scape_project.planning.model.DigitalObject;
import eu.scape_project.planning.model.ExecutablePlanDefinition;
import eu.scape_project.planning.model.Plan;
import eu.scape_project.planning.services.taverna.parser.T2FlowParser;
import eu.scape_project.planning.services.taverna.parser.TavernaParserException;
import eu.scape_project.planning.sla.QLDGenerator;
import eu.scape_project.planning.utils.ParserException;
/**
* Generator for preservation action plans.
*/
public class PreservationActionPlanGenerator implements Serializable {
private static final long serialVersionUID = 1201408409334201384L;
public static final String FULL_NAME = "PreservationActionPlan.xml";
private static Namespace xsi = new Namespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
private static Namespace platoNS = new Namespace("", PlanXMLConstants.PLATO_NS);
@Inject
private DigitalObjectManager digitalObjectManager;
private boolean addDigitalObjectData = true;
/**
* Generates a preservation action plan as dom4j document.
*
* @return the preservation action plan
* @throws PlanningException
* if an error occurred during generation
*/
public Document generatePreservationActionPlanDocument(CollectionProfile collectionProfile, ExecutablePlanDefinition executablePlanDefinition, Plan plan) throws PlanningException {
Document doc = createPapDoc();
Element preservationActionPlan = doc.getRootElement();
// Preservation action plan
try {
addPreservationActionPlanData(collectionProfile, preservationActionPlan);
addPreservationActionPlanT2flow(executablePlanDefinition.getT2flowExecutablePlan(), preservationActionPlan);
QLDGenerator qldGen = new QLDGenerator();
qldGen.generateQLD(plan);
Element qualityLevelDescription = preservationActionPlan.addElement("qualityLevelDescription");
Element root = qldGen.getQldNode().getRootElement();
Element schema = qualityLevelDescription.addElement("schema", "http://purl.oclc.org/dsdl/schematron");
schema.addAttribute("xmlns", "http://purl.oclc.org/dsdl/schematron");
schema.add(root.element("pattern").detach());
} catch (ParserException e) {
throw new PlanningException("Error parsing collection profile", e);
} catch (TavernaParserException e) {
throw new PlanningException("Error parsing executable plan", e);
}
return doc;
}
/**
* Creates a document for the preservation action plan.
*
* @return the document
*/
private Document createPapDoc() {
Document doc = DocumentHelper.createDocument();
Element root = doc.addElement(new QName("preservationActionPlan", platoNS));
root.add(xsi);
root.add(platoNS);
root.addAttribute(xsi.getPrefix() + ":schemaLocation", PlanXMLConstants.PLATO_NS + " "
+ PlanXMLConstants.PAP_SCHEMA);
// Set version of corresponding schema
root.addAttribute("version", "1.0");
return doc;
}
/**
* Adds data for the preservation action plan to the parent element.
*
* @param collectionProfile
* source of the data
* @param parent
* the parent element of the element to create
* @return the newly created element or null if none was created
* @throws ParserException
* if the collection profile could not be parsed
* @throws StorageException
* if the data could not be loaded
*/
private Element addPreservationActionPlanData(CollectionProfile collectionProfile, Element parent)
throws ParserException, StorageException {
Element collection = null;
if (collectionProfile != null) {
collection = parent.addElement("collection");
collection.addAttribute("uid", collectionProfile.getCollectionID());
// TODO: Collection has no name
// collection.addAttribute("name",
// p.getSampleRecordsDefinition().getCollectionProfile().getCollectionID());
// Objects
Element objects = parent.addElement("objects");
DigitalObject profileObject = collectionProfile.getProfile();
try {
if (profileObject != null && profileObject.isDataExistent()) {
if (!addDigitalObjectData) {
objects.setText(String.valueOf(profileObject.getId()));
} else {
if (profileObject.getData().getData() == null || profileObject.getData().getData().length == 0) {
profileObject = digitalObjectManager.getCopyOfDataFilledDigitalObject(profileObject);
}
C3POProfileParser parser = new C3POProfileParser();
parser.read(new ByteArrayInputStream(profileObject.getData().getData()), false);
List<String> objectIdentifiers = parser.getObjectIdentifiers();
for (String objectIdentifier : objectIdentifiers) {
objects.addElement("object").addAttribute("uid", objectIdentifier);
}
}
}
} finally {
profileObject = null;
}
}
return collection;
}
/**
* Adds an executable plan t2flow to the parent.
*
* @param t2flow
* the t2flow to add
* @param parent
* the parent element of the element to create
* @return the newly created element or null if none was created
* @throws TavernaParserException
* if the workflow could not be parsed
* @throws StorageException
* if the data could not be loaded
*/
private Element addPreservationActionPlanT2flow(DigitalObject t2flow, Element parent)
throws TavernaParserException, StorageException {
Element executablePlan = null;
if (t2flow != null && t2flow.isDataExistent()) {
executablePlan = parent.addElement("executablePlan").addAttribute("type", "t2flow");
if (!addDigitalObjectData) {
// Add only DigitalObject ID, it can be replaced later
executablePlan.setText(String.valueOf(t2flow.getId()));
} else {
DigitalObject t2flowObject = t2flow;
try {
if (t2flowObject.getData().getData() == null || t2flowObject.getData().getData().length == 0) {
t2flowObject = digitalObjectManager.getCopyOfDataFilledDigitalObject(t2flowObject);
}
T2FlowParser parser = T2FlowParser.createParser(new ByteArrayInputStream(t2flowObject.getData()
.getData()));
Document doc = parser.getDoc();
executablePlan.add(doc.getRootElement());
} finally {
t2flowObject = null;
}
}
}
return executablePlan;
}
}