org.jbpm.compiler.xml.processes.RuleFlowMigrator Maven / Gradle / Ivy
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates.
*
* 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 org.jbpm.compiler.xml.processes;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*******************************************************************************
* Class the migrates drools version 4 .rfm and .rf ruleflow files to version
* 5 .rf and .rfm ruleflows.
*
******************************************************************************/
public class RuleFlowMigrator
{
private static final Logger logger = LoggerFactory.getLogger(RuleFlowMigrator.class);
/**
* XSL file that transforms drools 4 .rfm ruleflow files to version 5
*/
private static final String XSL_RFM_FROM_4_TO_5 = "/org/drools/compiler/compiler/xml/processes/RuleFlowFrom4To5.xsl";
/**
* XSL file that transforms drools 4 .rf (graphical) ruleflow files to
* version 5
*/
private static final String XSL_RF_FROM_4_TO_5 = "/org/drools/compiler/compiler/xml/processes/RuleFlowGraphicalFrom4To5.xsl";
/**
* String containing namespace header for migrtated ruleflow files
*/
private static final String PROCESS_ELEMENT_WITH_NAMESPACE = "= 0 );
}
/*************************************************************************
* Returns true if the given .rfm ruleflow xml is a version
* 4 ruleflow that needs to be migrated to version 5, and returns
* false otherwise.
* @param xml a .rfm ruleflow in xml format
* @return true if the given .rfm graphical ruleflow xml is a version
* 4 ruleflow that needs to be migrated to version 5, and returns
* false otherwise.
* @throws Exception
************************************************************************/
public static boolean needToMigrateRFM(String xml) throws Exception {
return ( xml != null) &&
(xml.indexOf( "org.drools.ruleflow.core.impl.RuleFlowProcessImpl" ) >= 0 );
}
/*************************************************************************
* Utility method that applies a given xsl transform to the given xml to
* transform a drools 4 ruleflow to version 5.
* @param xml the ruleflow to be transformed
* @param xsl the xsl transform to apply to the ruleflow xml
* @return the ruleflow xml transformed from version 4 to 5 using the
* given xsl transformation
* @throws Exception
************************************************************************/
private static String portToCurrentVersion(String xml, String xsl) throws Exception
{
// convert it.
String version5XML = XSLTransformation.transform(xsl, xml, null);
// Add the namespace attribute to the process element as it is not added by the XSL transformation.
version5XML = version5XML.replaceAll( "= 0 ) {
text.append( buf,
0,
len );
}
return text.toString();
}
/*************************************************************************
* Test application that reads a given source
* file containing a drools 4 .rf and writes it to another given file
* location as a drools 5 .rf file.
*
* @param args an array whose first element is the source filename and
* the second element is the the destination filename to which the
* transformed ruleflow is written
************************************************************************/
public static final void main(String[] args)
{
try
{
if (args.length != 2)
{
logger.info("usage: RuleFileMigrator source_file dest_file");
System.exit(1);
}
File inFile = new File(args[0]);
File outFile = new File(args[1]);
FileReader fr = new FileReader(inFile);
String xml = convertReaderToString(fr);
String result = null;
if (needToMigrateRF(xml))
{
result = portRFToCurrentVersion(xml);
}
if (result != null)
{
logger.info("Ruleflow migrated from version 4.0 to 5.0");
FileWriter fw = new FileWriter(outFile);
fw.write(result);
fw.flush();
fw.close();
}
else
{
logger.info("No Ruleflow Migration Reguired - Ruleflow is version 5.0");
}
}
catch (Throwable t)
{
t.printStackTrace();
}
}
/*******************************************************************************
* This class transform a string using an XSL transform - moved verbatim
* from the ProcessBuilder class.
*
******************************************************************************/
private static class XSLTransformation {
public static String transform(String stylesheet,
String srcXMLString,
HashMap params) throws Exception {
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult( writer );
Source src = new StreamSource( new StringReader( srcXMLString ) );
transform( stylesheet,
src,
result,
params );
return writer.toString();
}
public static void transform(String stylesheet,
Source src,
Result res,
HashMap params) throws Exception {
Transformer transformer = getTransformer( stylesheet );
transformer.clearParameters();
if ( params != null && params.size() > 0 ) {
Iterator itKeys = params.keySet().iterator();
while ( itKeys.hasNext() ) {
String key = itKeys.next();
String value = params.get( key );
transformer.setParameter( key,
value );
}
}
transformer.transform( src,
res );
}
private static Transformer getTransformer(String stylesheet) throws Exception {
Transformer transformer = null;
InputStream xslStream = null;
try {
InputStream in = XSLTransformation.class.getResourceAsStream( stylesheet );
xslStream = new BufferedInputStream( in );
StreamSource src = new StreamSource( xslStream );
src.setSystemId( stylesheet );
transformer = TransformerFactory.newInstance().newTransformer( src );
} finally {
if ( xslStream != null ) xslStream.close();
}
return transformer;
}
}
}