/**
* Copyright (C) 2007 - 2014 52°North Initiative for Geospatial Open Source
* Software GmbH
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* If the program is linked with libraries which are licensed under one of
* the following licenses, the combination of the program with the linked
* library is not considered a "derivative work" of the program:
*
* • Apache License, version 2.0
* • Apache Software License, version 1.0
* • GNU Lesser General Public License, version 3
* • Mozilla Public License, versions 1.0, 1.1 and 2.0
* • Common Development and Distribution License (CDDL), version 1.0
*
* Therefore the distribution of the program linked with libraries licensed
* under the aforementioned licenses, is permitted by the copyright holders
* if the distribution is compliant with both the GNU General Public
* License version 2 and the aforementioned licenses.
*
* 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.
*/
package org.n52.wps.transactional.handler;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.xpath.XPathAPI;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.IAlgorithmRepository;
import org.n52.wps.server.ITransactionalAlgorithmRepository;
import org.n52.wps.server.RepositoryManager;
import org.n52.wps.transactional.algorithm.GenericTransactionalAlgorithm;
import org.n52.wps.transactional.request.DeployProcessRequest;
import org.n52.wps.transactional.request.ITransactionalRequest;
import org.n52.wps.transactional.request.UndeployProcessRequest;
import org.n52.wps.transactional.response.TransactionalResponse;
import org.n52.wps.transactional.service.TransactionalHelper;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public class TransactionalRequestHandler {
/**
* Handles the request and returns a transactional response (if succeeded)
* or throws an exception (otherwise)
*
* @param request
* the request to handle
* @return a response if the process has succeeded. <code>null</code> is
* never returned
* @throws Exception
* if an error occurs handling the request
*/
public TransactionalResponse handle(ITransactionalRequest request)
throws ExceptionReport {
if (request instanceof DeployProcessRequest) {
return handleDeploy((DeployProcessRequest) request);
} else if (request instanceof UndeployProcessRequest) {
return handleUnDeploy((UndeployProcessRequest) request);
} else {
throw new ExceptionReport("Error. Could not handle request",
ExceptionReport.OPERATION_NOT_SUPPORTED);
}
}
private TransactionalResponse handleDeploy(
DeployProcessRequest request) throws ExceptionReport {
//storeDescribeProcess
storeDescribeProcess(request);
try {
ITransactionalAlgorithmRepository repository = TransactionalHelper
.getMatchingTransactionalRepository(request.getSchema());
if (repository == null) {
throw new ExceptionReport("Could not find matching repository",
ExceptionReport.NO_APPLICABLE_CODE);
}
if (!repository.addAlgorithm(request)) {
throw new ExceptionReport("Could not deploy process",
ExceptionReport.NO_APPLICABLE_CODE);
} else {
return new TransactionalResponse(
"Process successfully deployed");
}
} catch (RuntimeException e) {
throw new ExceptionReport("Could not deploy process",
ExceptionReport.NO_APPLICABLE_CODE);
}
}
private void storeDescribeProcess(DeployProcessRequest request) {
String processName ="";
try{
processName = XPathAPI.selectSingleNode(request.getProcessDescription(), "/DeployProcess/ProcessDescriptions/ProcessDescription/Identifier/text()").getNodeValue().trim();
}catch(DOMException de){
de.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
Node describeProcess = null;
try {
describeProcess = XPathAPI.selectSingleNode(request.getProcessDescription(), "/DeployProcess/ProcessDescriptions");
} catch (TransformerException e) {
e.printStackTrace();
}
String fullPath = GenericTransactionalAlgorithm.class.getProtectionDomain().getCodeSource().getLocation().toString();
int searchIndex= fullPath.indexOf("WEB-INF");
String subPath = fullPath.substring(0, searchIndex);
subPath = subPath.replaceFirst("file:", "");
if(subPath.startsWith("/")){
subPath = subPath.substring(1);
}
File directory = new File(subPath+"WEB-INF/ProcessDescriptions/");
if(!directory.exists()){
directory.mkdirs();
}
String path = subPath+"WEB-INF/ProcessDescriptions/"+processName+".xml";
try {
writeXmlFile(describeProcess, path);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static TransactionalResponse handleUnDeploy(
UndeployProcessRequest request) throws ExceptionReport {
try {
if (RepositoryManager.getInstance().getAlgorithm(
request.getProcessID()) == null) {
throw new ExceptionReport("The process does not exist",
ExceptionReport.INVALID_PARAMETER_VALUE);
}
IAlgorithmRepository repository = RepositoryManager.getInstance()
.getRepositoryForAlgorithm(request.getProcessID());
if (repository instanceof ITransactionalAlgorithmRepository) {
ITransactionalAlgorithmRepository transactionalRepository = (ITransactionalAlgorithmRepository) repository;
if (!transactionalRepository.removeAlgorithm(request)) {
throw new ExceptionReport("Could not undeploy process",
ExceptionReport.NO_APPLICABLE_CODE);
} else {
return new TransactionalResponse(
"Process successfully undeployed");
}
} else {
throw new ExceptionReport(
"The process is not in a transactional "
+ "repository and cannot be undeployed",
ExceptionReport.INVALID_PARAMETER_VALUE);
}
} catch (RuntimeException e) {
throw new ExceptionReport("Could not undeploy process",
ExceptionReport.NO_APPLICABLE_CODE);
}
}
protected void writeXmlFile(Node node, String filename) throws IOException, TransformerFactoryConfigurationError, TransformerException, ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
Document tempDocument = documentBuilder.newDocument();
Node importedNode = tempDocument.importNode(node, true);
tempDocument.appendChild(importedNode);
// Prepare the DOM document for writing
Source source = new DOMSource(tempDocument);
// Prepare the output file
File file = new File(filename);
String parent = file.getParent();
File directory = new File(parent);
directory.mkdirs();
//file.createNewFile();
OutputStream fileOutput = new FileOutputStream(file);
Result result = new StreamResult(fileOutput);
// Write the DOM document to the file
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.transform(source, result);
}
}