001/* 002 * Copyright 2010 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.workflow; 017 018import java.io.ByteArrayInputStream; 019import java.io.File; 020import java.io.IOException; 021import java.io.InputStream; 022import java.nio.charset.StandardCharsets; 023import java.nio.file.Files; 024import java.nio.file.Paths; 025 026import org.apache.commons.io.FileUtils; 027import org.apache.commons.io.FilenameUtils; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030import org.w3c.dom.Element; 031 032import com.opensymphony.workflow.loader.XMLWorkflowFactory; 033 034/** 035 * A XML factory for finding workflows definitions in 036 * <code>context://WEB-INF/param/workflows.xml</code> 037 * 038 * or if the file does not exits, built from the content of the <code>context://WEB-INF/workflows/*.xml</code> files 039 */ 040public class XmlWorkflowFactory extends XMLWorkflowFactory 041{ 042 // Path to the XML for the configuration of the workflow. 043 private static final String __CONFIG_FILE = "workflows.xml"; 044 // Path to the directory having the XML workflows. 045 private static final String __CONFIG_DIRECTORY = "workflows"; 046 047 /** Logger for traces. */ 048 protected Logger _logger = LoggerFactory.getLogger(getClass()); 049 050 private String _contextPath; 051 052 /** 053 * Constructor. 054 * @param contextPath The webapp context path 055 * @throws Exception if an error occurs. 056 */ 057 public XmlWorkflowFactory(String contextPath) throws Exception 058 { 059 _contextPath = contextPath; 060 } 061 062 @Override 063 protected InputStream getInputStream(String name) 064 { 065 File workflowsFile = new File(_contextPath, __CONFIG_FILE); 066 if (workflowsFile.exists() && workflowsFile.isFile()) 067 { 068 if (_logger.isDebugEnabled()) 069 { 070 _logger.debug("Readinng workflows configuration file at " + workflowsFile.getAbsolutePath()); 071 } 072 try 073 { 074 return Files.newInputStream(Paths.get(workflowsFile.getAbsolutePath())); 075 } 076 catch (IOException e) 077 { 078 _logger.error("An error occurred reading the workflows configuration file at " + workflowsFile.getAbsolutePath(), e); 079 return null; 080 } 081 } 082 else 083 { 084 if (_logger.isDebugEnabled()) 085 { 086 _logger.debug("No workflows configuration file at " + workflowsFile.getAbsolutePath() + ". Creating it."); 087 } 088 089 File workflowsDirectory = new File(_contextPath, __CONFIG_DIRECTORY); 090 if (workflowsDirectory.exists() && workflowsDirectory.isDirectory()) 091 { 092 StringBuilder hotFile = new StringBuilder(); 093 hotFile.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 094 hotFile.append("<workflows>\n"); 095 096 for (File file : FileUtils.listFiles(workflowsDirectory, new String[] {"xml"}, false)) 097 { 098 hotFile.append("\t<workflow name=\""); 099 hotFile.append(FilenameUtils.removeExtension(file.getName())); 100 hotFile.append("\" type=\"file\" location=\""); 101 hotFile.append(__CONFIG_DIRECTORY); 102 hotFile.append(File.separator); 103 hotFile.append(file.getName()); 104 hotFile.append("\"/>\n"); 105 } 106 107 hotFile.append("</workflows>\n"); 108 109 return new ByteArrayInputStream(hotFile.toString().getBytes(StandardCharsets.UTF_8)); 110 } 111 else 112 { 113 _logger.error("Found neither workflows configuration file at " + workflowsFile.getAbsolutePath() + " nor workflows directory at " + workflowsDirectory.getAbsolutePath()); 114 return null; 115 } 116 } 117 } 118 119 @Override 120 protected String getBaseDir(Element root) 121 { 122 return new File(_contextPath).getPath(); 123 } 124}