package peal.helper;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import betsy.common.tasks.FileTasks;
import betsy.common.tasks.ZipTasks;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import peal.identifier.ProcessModelId;
import peal.packages.DeploymentPackage;
import peal.packages.LogPackage;
import peal.packages.Package;
import peal.packages.ProcessModelPackage;
public class ZipFileHelper {
public static Package buildFromFolder(Path folder) throws IOException {
Path tempZipFile = Files.createTempDirectory("peal").resolve("zip-file.zip");
ZipTasks.zipFolder(tempZipFile, folder);
return createZipFileFromArchive(tempZipFile);
}
public static Package createZipFileFromArchive(Path tempZipFile) throws IOException {
Package aPackage = new Package();
aPackage.setData(Files.readAllBytes(tempZipFile));
return aPackage;
}
public static ProcessModelPackage zipToProcessModelPackage(Package aPackage) {
ProcessModelPackage result = new ProcessModelPackage();
result.setData(aPackage.getData());
return result;
}
public static DeploymentPackage zipToDeployablePackage(Package aPackage, String fileExtension, ProcessModelId processModelId) {
DeploymentPackage result = new DeploymentPackage();
result.setData(aPackage.getData());
result.fileExtension = fileExtension;
result.processModelId = processModelId;
return result;
}
public static LogPackage zipToLog(Package aPackage) {
LogPackage result = new LogPackage();
result.setData(aPackage.getData());
return result;
}
public static Path extractIntoTemporaryFolder(Package aPackage) throws IOException {
Path tempZipFile = storeDataAsZipFile(aPackage);
// unpack in another temporary folder
Path tempExtractedFolder = Files.createTempDirectory("peal");
ZipTasks.unzip(tempZipFile, tempExtractedFolder);
findOtherFilesInPath(tempExtractedFolder).stream().filter(path -> path.toString().endsWith(".zip")).forEach(path -> {
Path tmpDir = Paths.get(path.toString() + ".EXTRACT/");
FileTasks.mkdirs(tmpDir);
ZipTasks.unzip(path, tmpDir);
});
return tempExtractedFolder;
}
public static Path storeDataAsZipFile(Package aPackage) throws IOException {
Path tempZipFile = Files.createTempDirectory("peal").resolve("zip-file.zip");
// write zip file to temporary folder
Files.write(tempZipFile, aPackage.getData());
return tempZipFile;
}
public static Path findBpelFileInPath(Path path) throws IOException {
return Files.find(path, 10, ZipFileHelper::isBpelFile).findFirst().
orElseThrow(() -> new IllegalStateException("could not find any bpel files in path " + path));
}
public static Path findBpmnFileInPath(Path path) throws IOException {
return Files.find(path, 10, ZipFileHelper::isBpmnFile).findFirst().
orElseThrow(() -> new IllegalStateException("could not find any bpel files in path " + path));
}
public static String findBpmnProcessNameInPath(Path path) throws IOException, SAXException, ParserConfigurationException, XPathExpressionException {
if(Files.isDirectory(path)) {
return findBpmnProcessNameInPath(findBpmnFileInPath(path));
}
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(path.toFile());
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
xpath.setNamespaceContext( new NamespaceContext() {
@Override
public String getNamespaceURI(String prefix) {
if("bpmn2".equals(prefix)) {
return "http://www.omg.org/spec/BPMN/20100524/MODEL";
}
return null;
}
@Override
public String getPrefix(String namespaceURI) {
return null;
}
@Override
public Iterator getPrefixes(String namespaceURI) {
return null;
}
});
XPathExpression expr = xpath.compile("/*[local-name()='definitions']/*[local-name()='process']/@id");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
return nl.item(0).getTextContent();
}
public static String findBpelProcessNameInPath(Path path) throws IOException, SAXException, ParserConfigurationException, XPathExpressionException {
if(Files.isDirectory(path)) {
return findBpelProcessNameInPath(findBpelFileInPath(path));
}
return findBpelProcessName(path);
}
public static String findBpelProcessName(Path path)
throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(path.toFile());
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
xpath.setNamespaceContext( new NamespaceContext() {
@Override
public String getNamespaceURI(String prefix) {
if("bpel".equals(prefix)) {
return "http://docs.oasis-open.org/wsbpel/2.0/process/executable";
}
return null;
}
@Override
public String getPrefix(String namespaceURI) {
return null;
}
@Override
public Iterator getPrefixes(String namespaceURI) {
return null;
}
});
XPathExpression expr = xpath.compile("/*[local-name()='process']/@name");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
if(nl.getLength() <= 0) {
return ""; // not found
}
return nl.item(0).getTextContent();
}
public static String findBpelTargetNameSpaceInPath(Path path) throws IOException, SAXException, ParserConfigurationException, XPathExpressionException {
if(Files.isDirectory(path)) {
return findBpelTargetNameSpaceInPath(findBpelFileInPath(path));
}
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(path.toFile());
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
xpath.setNamespaceContext( new NamespaceContext() {
@Override
public String getNamespaceURI(String prefix) {
if("bpel".equals(prefix)) {
return "http://docs.oasis-open.org/wsbpel/2.0/process/executable";
}
return null;
}
@Override
public String getPrefix(String namespaceURI) {
return null;
}
@Override
public Iterator getPrefixes(String namespaceURI) {
return null;
}
});
XPathExpression expr = xpath.compile("/*[local-name()='process']/@targetNamespace");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
return nl.item(0).getTextContent();
}
public static String findBpmnTargetNameSpaceInPath(Path path) throws IOException, SAXException, ParserConfigurationException, XPathExpressionException {
if(Files.isDirectory(path)) {
return findBpmnTargetNameSpaceInPath(findBpmnFileInPath(path));
}
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(path.toFile());
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
xpath.setNamespaceContext( new NamespaceContext() {
@Override
public String getNamespaceURI(String prefix) {
if("bpmn2".equals(prefix)) {
return "http://www.omg.org/spec/BPMN/20100524/MODEL";
}
return null;
}
@Override
public String getPrefix(String namespaceURI) {
return null;
}
@Override
public Iterator getPrefixes(String namespaceURI) {
return null;
}
});
XPathExpression expr = xpath.compile("/*[local-name()='definitions']/@targetNamespace");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
return nl.item(0).getTextContent();
}
public static void adjustFileNameOfBpelToProcessName(Path folder) throws IOException, XPathExpressionException, SAXException, ParserConfigurationException {
Path bpelFile = findBpelFileInPath(folder);
String processName = findBpelProcessNameInPath(bpelFile);
String correctBpelFileName = processName + ".bpel";
if(!bpelFile.toString().endsWith(correctBpelFileName)){
Files.move(bpelFile, bpelFile.getParent().resolve(correctBpelFileName));
}
}
public static void adjustFileNameOfBpmnToProcessName(Path folder) throws IOException, XPathExpressionException, SAXException, ParserConfigurationException {
Path bpmnFile = findBpmnFileInPath(folder);
String processName = findBpmnProcessNameInPath(bpmnFile);
String correctBpmnFileName = processName + ".bpmn";
if(!bpmnFile.toString().endsWith(correctBpmnFileName)){
Files.move(bpmnFile, bpmnFile.getParent().resolve(correctBpmnFileName));
}
}
public static List<Path> findWsdlFilesInPath(Path path) throws IOException {
return Files.find(path, 10, ZipFileHelper::isWsdlFile).collect(Collectors.toList());
}
public static List<Path> findOtherFilesInPath(Path path) throws IOException {
return Files.find(path, 10, ZipFileHelper::isNeitherWsdlNorDirectoryNorBpelFile).collect(Collectors.toList());
}
private static boolean isWsdlFile(Path path, BasicFileAttributes a) {
return path.getFileName().toString().endsWith(".wsdl");
}
private static boolean isBpelFile(Path path, BasicFileAttributes a) {
return path.getFileName().toString().endsWith(".bpel");
}
private static boolean isBpmnFile(Path path, BasicFileAttributes a) {
return path.getFileName().toString().endsWith(".bpmn");
}
private static boolean isNeitherWsdlNorDirectoryNorBpelFile(Path path, BasicFileAttributes a) {
return !isBpelFile(path, a) && !isWsdlFile(path, a) && !Files.isDirectory(path);
}
public static LogPackage createLogPackage(List<Path> logs) {
Path result;
try {
result = Files.createTempDirectory("peal").resolve("logs");
} catch (IOException e1) {
throw new RuntimeException("could not create log folder", e1);
}
FileTasks.mkdirs(result);
Path logFolder = result;
for(Path file : logs) {
try {
FileTasks.copyFileIntoFolder(file, logFolder);
} catch (Exception e) {
e.printStackTrace();
}
}
try {
return zipToLog(buildFromFolder(logFolder));
} catch (IOException e) {
throw new RuntimeException("could not create zip file", e);
}
}
}