[jboss-svn-commits] JBL Code SVN: r25076 - in labs/jbossrules/trunk: drools-compiler/src/main/java/org/drools/xml/processes and 8 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Feb 3 12:34:20 EST 2009


Author: KrisVerlaenen
Date: 2009-02-03 12:34:20 -0500 (Tue, 03 Feb 2009)
New Revision: 25076

Added:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/RuleFlowMigrator.java
   labs/jbossrules/trunk/drools-compiler/src/main/resources/org/drools/xml/processes/RuleFlowGraphicalFrom4To5.xsl
   labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/repository/MigrateRepository.java
Modified:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/ProcessBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/main/resources/org/drools/xml/processes/RuleFlowFrom4To5.xsl
   labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/flow/ruleflow/editor/RuleFlowModelEditor.java
   labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/builder/RuleFlowContentModelBuilder.java
   labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/contenthandler/RuleFlowHandler.java
   labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/files/FileManagerUtils.java
   labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/repository/BRMSRepositoryConfiguration.java
   labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/JpdlNodeInstance.java
   labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/StartStateInstance.java
   labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/TaskNodeInstance.java
   labs/jbossrules/trunk/drools-process/drools-osworkflow/.classpath
   labs/jbossrules/trunk/drools-process/drools-osworkflow/.project
Log:
JBRULES-1945: Migrating version 4 graphical ruleflows to version 5 in Eclipse plugin and the Guvnor
 - applied patch

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/ProcessBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/ProcessBuilder.java	2009-02-03 17:07:10 UTC (rev 25075)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/ProcessBuilder.java	2009-02-03 17:34:20 UTC (rev 25076)
@@ -65,6 +65,7 @@
 import org.drools.workflow.core.node.StartNode;
 import org.drools.workflow.core.node.Trigger;
 import org.drools.xml.XmlProcessReader;
+import org.drools.xml.processes.RuleFlowMigrator;
 
 /**
  * A ProcessBuilder can be used to build processes based on XML files
@@ -232,35 +233,39 @@
         reader.close();
     }
 
+    
+  
+    /*************************************************************************
+     * Converts a drools version 4 .rf or .rfm ruleflow to a version 5 .rf.
+     * Version 5 .rf ruleflows are allowed, but are not migrated.
+     * @param reader containing any drools 4 .rf or .rfm ruleflow, or a 
+     * version 5 .rf
+     * @return reader containing the input reader in the latest (5) .rf format
+     * @throws Exception
+     ************************************************************************/
     private Reader portToCurrentVersion(final Reader reader) throws Exception {
-        String xml = convertReaderToString( reader );
-        if ( xml.indexOf( "<org.drools.ruleflow.core.impl.RuleFlowProcessImpl " ) >= 0 ) {
-            // Not a current version convert it.
-            String version5XML = XSLTransformation.transform( XSL_FROM_4_TO_5,
-                                                              xml,
-                                                              null );
-            // Add the namespace attribute to the process element as it is not added by the XSL transformation.
-            version5XML = version5XML.replaceAll( "<process ",
-                                                  PROCESS_ELEMENT_WITH_NAMESPACE );
-            return new StringReader( version5XML );
+        //Migrate v4 ruleflows to v5
+        String xml = RuleFlowMigrator.convertReaderToString( reader );
+        
+        if ( RuleFlowMigrator.needToMigrateRFM(xml) ) {
+            // Not a current version RFM convert it.
+            xml = RuleFlowMigrator.portRFMToCurrentVersion(xml);
         }
-        return reader;
+        else if ( RuleFlowMigrator.needToMigrateRF(xml) ) {
+            // Not a current version RF convert it.
+            xml = RuleFlowMigrator.portRFMToCurrentVersion(xml);}
+        //
+        // Note that we have also return any input v5 ruleflow as 
+        // a StringReader since the act of checking it using 
+        // convertReaderToString will have read the reader making it
+        // appear empty if read later. As reset is not guaranteed on
+        // all Reader implementation, it is safest to convert the v5 
+        // ruleflow string representation to a StringReader as well.
+        //
+        return new StringReader( xml );
     }
 
-    private String convertReaderToString(Reader reader) throws IOException {
-        final StringBuffer text = new StringBuffer();
 
-        final char[] buf = new char[1024];
-        int len = 0;
-
-        while ( (len = reader.read( buf )) >= 0 ) {
-            text.append( buf,
-                         0,
-                         len );
-        }
-        return text.toString();
-    }
-
     private String generateRules(final Process process) {
         StringBuilder builder = new StringBuilder();
 
@@ -349,59 +354,4 @@
         return result;
     }
 
-    private static class XSLTransformation {
-        public static String transform(String stylesheet,
-                                       String srcXMLString,
-                                       HashMap<String, String> 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<String, String> params) throws Exception {
-
-            Transformer transformer = getTransformer( stylesheet );
-
-            transformer.clearParameters();
-
-            if ( params != null && params.size() > 0 ) {
-                Iterator<String> 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;
-        }
-    }
 }

Added: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/RuleFlowMigrator.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/RuleFlowMigrator.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/RuleFlowMigrator.java	2009-02-03 17:34:20 UTC (rev 25076)
@@ -0,0 +1,287 @@
+package org.drools.xml.processes;
+
+/*
+ * Copyright 2005 JBoss Inc
+ * 
+ * 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.
+ */
+
+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;
+
+
+/*******************************************************************************
+ * Class the migrates drools version 4 .rfm and .rf ruleflow files to version
+ * 5 .rf and .rfm ruleflows.
+ * 
+ * @author <a href="mailto:author at acme.com">A.N Author</a>
+ ******************************************************************************/
+public class RuleFlowMigrator 
+{
+    /**
+     * XSL file that transforms drools 4 .rfm ruleflow files to version 5
+     */
+    private static final String  XSL_RFM_FROM_4_TO_5 = "/org/drools/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/xml/processes/RuleFlowGraphicalFrom4To5.xsl";
+    
+    /**
+     * String containing namespace header for migrtated ruleflow files
+     */
+    private static final String  PROCESS_ELEMENT_WITH_NAMESPACE = "<process xmlns=\"http://drools.org/drools-5.0/process\"\n" + "    xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+                                                                           + "    xs:schemaLocation=\"http://drools.org/drools-5.0/process drools-processes-5.0.xsd\"\n";
+    
+    /*************************************************************************
+     * Returns a drools 5 version of a given drools 4 .rf (Graphical) ruleflow
+     * in string format. Note that this method assumes the given ruleflow 
+     * is a valid version 4 .rf ruleflow - this can be checked using the
+     * needToMigrateRF method.
+     * 
+     * @param xml Drools 4 ruleflow (.rf) in xml format
+     * @return drools 5 version of a given drools 4 .rf (Graphical) ruleflow
+     * in string format.
+     * @throws Exception
+     ************************************************************************/
+    public static String portRFToCurrentVersion(String xml) throws Exception 
+    {
+    	return portToCurrentVersion(xml, XSL_RF_FROM_4_TO_5);
+    }
+    
+    /*************************************************************************
+     * Returns a drools 5 version of a given drools 4 .rfm ruleflow
+     * in string format. Note that this method assumes the given ruleflow 
+     * is a valid version 4 .rfm ruleflow - this can be checked using the
+     * needToMigrateRFM method. The return version 5 xml can be used as
+     * a .rf (graphical) ruleflow, but its nodes do not contains
+     * positional data.
+     * 
+     * @param xml Drools 4 ruleflow (.rfm) in xml format
+     * @return drools 5 version of a given drools 4 .rfm ruleflow
+     * in string format.
+     * @throws Exception
+     ************************************************************************/
+    public static String portRFMToCurrentVersion(String xml) throws Exception 
+    {
+    	return portToCurrentVersion(xml, XSL_RFM_FROM_4_TO_5);
+    }
+
+    
+    /*************************************************************************
+     * Returns true if the given .rf (graphical) ruleflow xml is a version
+     * 4 ruleflow that needs to be migrated to version 5, and returns 
+     * false otherwise.
+     * @param xml a .rf ruleflow in xml format
+     * @return true if the given .rf (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 needToMigrateRF(String xml) throws Exception {
+    	return ( xml != null) && 
+    	(xml.indexOf( "org.drools.eclipse.flow.ruleflow.core.RuleFlowProcessWrapper" ) >= 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( "<process ", PROCESS_ELEMENT_WITH_NAMESPACE );
+    	return version5XML;
+    }
+
+
+    /*************************************************************************
+     * Converts the contents of the given Reader into a string.
+     * WARNING: the given string is not reset (as not all 
+     * readers support reset). Consequently, anny further
+     * attempt to read from the given reader will return nothing,
+     * unless you reset the reader.
+     * @param reader
+     * @return he contents of the given Reader into a string.
+     * @throws IOException
+     ************************************************************************/
+    public static String convertReaderToString(Reader reader) throws IOException {
+        final StringBuffer text = new StringBuffer();
+
+        final char[] buf = new char[1024];
+        int len = 0;
+
+        while ( (len = reader.read( buf )) >= 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)
+            {
+                System.out.println("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)
+        	{
+        		System.out.println("Ruleflow migrated from version 4.0 to 5.0");
+        		FileWriter fw = new FileWriter(outFile);
+        		fw.write(result);
+        		fw.flush();
+        		fw.close();
+        	}
+        	else
+        	{
+        		System.out.println("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.
+     * 
+     * @author 
+     ******************************************************************************/
+    private static class XSLTransformation {
+        public static String transform(String stylesheet,
+                                       String srcXMLString,
+                                       HashMap<String, String> 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<String, String> params) throws Exception {
+
+            Transformer transformer = getTransformer( stylesheet );
+
+            transformer.clearParameters();
+
+            if ( params != null && params.size() > 0 ) {
+                Iterator<String> 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;
+        }
+    }
+}

Modified: labs/jbossrules/trunk/drools-compiler/src/main/resources/org/drools/xml/processes/RuleFlowFrom4To5.xsl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/resources/org/drools/xml/processes/RuleFlowFrom4To5.xsl	2009-02-03 17:07:10 UTC (rev 25075)
+++ labs/jbossrules/trunk/drools-compiler/src/main/resources/org/drools/xml/processes/RuleFlowFrom4To5.xsl	2009-02-03 17:34:20 UTC (rev 25076)
@@ -2,11 +2,13 @@
 <xsl:stylesheet version="2.0"
 	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 	<xsl:output method="xml" indent="yes" />
+	<!-- Converts a drools version 4 non-graphical ruleflow file (i.e. .rfm file) to version5 .rf file-->
 	<!-- How to get the first node so the the implementing class need not be mentioned here.-->
 	<xsl:variable name="type">RuleFlow</xsl:variable>
 	<xsl:variable name="name"><xsl:value-of select="./org.drools.ruleflow.core.impl.RuleFlowProcessImpl/name"/></xsl:variable>
 	<xsl:variable name="id"><xsl:value-of select="./org.drools.ruleflow.core.impl.RuleFlowProcessImpl/id"/></xsl:variable>
 	<xsl:variable name="packageName"><xsl:value-of select="./org.drools.ruleflow.core.impl.RuleFlowProcessImpl/packageName"/></xsl:variable>
+	<xsl:variable name="version"><xsl:value-of select="./org.drools.ruleflow.core.impl.RuleFlowProcessImpl/version"/></xsl:variable>
 	<xsl:param name="generateTypes">false</xsl:param>
 	<xsl:param name="generateImports">false</xsl:param>
 	<xsl:param name="generateIncludes">false</xsl:param>
@@ -20,7 +22,12 @@
 			<xsl:attribute name="name"><xsl:value-of select="$name"/></xsl:attribute>
 			<xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute>
 			<xsl:attribute name="package-name"><xsl:value-of select="$packageName"/></xsl:attribute>
+			<xsl:attribute name="version"><xsl:value-of select="$version"/></xsl:attribute>
 			<!-- TODO Could not add other namespace related attributes on the element node especially for schema location. -->
+			<xsl:element name="header">
+				<xsl:call-template name="processImports"/>
+				<xsl:call-template name="processGlobals"/>
+			</xsl:element>
 			<xsl:element name="nodes">
 				<xsl:call-template name="processNodes"/>
 			</xsl:element>
@@ -28,6 +35,31 @@
 				<xsl:call-template name="formConnections" />
 			</xsl:element>
 		</xsl:element>
+	</xsl:template>
+	
+	<xsl:template name="processImports">
+		<xsl:if test="//imports">
+			<xsl:element name="imports">
+			<xsl:for-each select="//imports/string">
+				<xsl:element name="import">
+					<xsl:attribute name="name"><xsl:value-of select="."/></xsl:attribute>
+				</xsl:element>
+			</xsl:for-each>
+			</xsl:element>
+		</xsl:if>
+	</xsl:template>
+	
+	<xsl:template name="processGlobals">
+		<xsl:if test="//globals">
+			<xsl:element name="globals">
+			<xsl:for-each select="//globals/entry">
+				<xsl:element name="global">
+					<xsl:attribute name="identifier"><xsl:value-of select="./string[1]/."/></xsl:attribute>
+					<xsl:attribute name="type"><xsl:value-of select="./string[2]/."/></xsl:attribute>
+				</xsl:element>
+			</xsl:for-each>
+			</xsl:element>
+		</xsl:if>
 	</xsl:template>
 
 	<xsl:template name="processNodes">

Added: labs/jbossrules/trunk/drools-compiler/src/main/resources/org/drools/xml/processes/RuleFlowGraphicalFrom4To5.xsl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/resources/org/drools/xml/processes/RuleFlowGraphicalFrom4To5.xsl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/main/resources/org/drools/xml/processes/RuleFlowGraphicalFrom4To5.xsl	2009-02-03 17:34:20 UTC (rev 25076)
@@ -0,0 +1,295 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="2.0"
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+	<xsl:output method="xml" indent="yes" />
+	<!-- Converts a drools version 4 graphical ruleflow file (i.e. .rf file) to version 5-->
+	<!-- How to get the first node so the the implementing class need not be mentioned here.-->
+	<xsl:variable name="type">RuleFlow</xsl:variable>
+	<xsl:variable name="name"><xsl:value-of select="//process/name/."/></xsl:variable>
+	<xsl:variable name="id"><xsl:value-of select="//process/id/."/></xsl:variable>
+	<xsl:variable name="packageName"><xsl:value-of select="//process/packageName/."/></xsl:variable>
+	<xsl:variable name="version"><xsl:value-of select="//process/version/."/></xsl:variable>
+	<xsl:variable name="routerLayout"><xsl:value-of select="//routerLayout/."/></xsl:variable>
+	<xsl:param name="generateTypes">false</xsl:param>
+	<xsl:param name="generateImports">false</xsl:param>
+	<xsl:param name="generateIncludes">false</xsl:param>
+	<xsl:param name="defaultIncludeFile">false</xsl:param>
+	<xsl:template match="/">
+		<!-- If we do not add the namespace then 5.0 Eclipse editor does not recognize the process 
+		node if there are more than 2 sub processes defined in the ruleflow! 
+		If we put the namespace then it gets reflected in child elements like ruleSet, join etc.-->
+		<xsl:element name="process">
+			<xsl:attribute name="type"><xsl:value-of select="$type"/></xsl:attribute>
+			<xsl:attribute name="name"><xsl:value-of select="$name"/></xsl:attribute>
+			<xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute>
+			<xsl:attribute name="package-name"><xsl:value-of select="$packageName"/></xsl:attribute>
+			<xsl:attribute name="version"><xsl:value-of select="$version"/></xsl:attribute>
+			<xsl:attribute name="routerLayout"><xsl:value-of select="$routerLayout"/></xsl:attribute>
+			<!-- TODO Could not add other namespace related attributes on the element node especially for schema location. -->
+			<xsl:element name="header">
+				<xsl:call-template name="processImports"/>
+				<xsl:call-template name="processGlobals"/>
+			</xsl:element>
+			<xsl:element name="nodes">
+				<xsl:call-template name="processNodes"/>
+			</xsl:element>
+			<xsl:element name="connections">
+				<xsl:call-template name="formConnections" />
+			</xsl:element>
+		</xsl:element>
+	</xsl:template>
+	
+	<xsl:template name="processImports">
+		<xsl:if test="//imports">
+			<xsl:element name="imports">
+			<xsl:for-each select="//imports/string">
+				<xsl:element name="import">
+					<xsl:attribute name="name"><xsl:value-of select="."/></xsl:attribute>
+				</xsl:element>
+			</xsl:for-each>
+			</xsl:element>
+		</xsl:if>
+	</xsl:template>
+	
+	<xsl:template name="processGlobals">
+		<xsl:if test="//globals">
+			<xsl:element name="globals">
+			<xsl:for-each select="//globals/entry">
+				<xsl:element name="global">
+					<xsl:attribute name="identifier"><xsl:value-of select="./string[1]/."/></xsl:attribute>
+					<xsl:attribute name="type"><xsl:value-of select="./string[2]/."/></xsl:attribute>
+				</xsl:element>
+			</xsl:for-each>
+			</xsl:element>
+		</xsl:if>
+	</xsl:template>
+
+	<xsl:template name="processNodes">
+		<xsl:for-each select="//element[@id != '']">
+			<xsl:call-template name="printNodes"><xsl:with-param name="className"><xsl:value-of select = "@class"/></xsl:with-param></xsl:call-template>
+		</xsl:for-each>
+		
+		<!-- Only those from or to nodes that have id. When there is reference it means that the node was already declared as id earlier or would come later.-->
+		<xsl:for-each select="//from[@id != '']|//to[@id != '']">
+			<xsl:call-template name="printNodes"><xsl:with-param name="className"><xsl:value-of select = "@class"/></xsl:with-param></xsl:call-template>
+		</xsl:for-each>
+	</xsl:template>
+
+	<xsl:template name="printNodes">
+		<xsl:param name="className"/>
+		<xsl:choose>
+			<xsl:when test="$className = 'org.drools.ruleflow.core.impl.RuleSetNodeImpl'">
+				<xsl:call-template name="RenderRuleSetNode"/>
+			</xsl:when>
+			<xsl:when test="$className = 'org.drools.ruleflow.core.impl.ActionNodeImpl'">
+				<xsl:call-template name="RenderActionNode"/>
+			</xsl:when>
+			<xsl:when test="$className = 'org.drools.ruleflow.core.impl.SplitImpl'">
+				<xsl:call-template name="RenderSplitNode"/>
+			</xsl:when>
+			<xsl:when test="$className = 'org.drools.ruleflow.core.impl.JoinImpl'">
+				<xsl:call-template name="RenderJoinNode"/>
+			</xsl:when>
+			<xsl:when test="$className = 'org.drools.ruleflow.core.impl.SubFlowNodeImpl'">
+				<xsl:call-template name="RenderSubflowNode"/>
+			</xsl:when>
+			<xsl:when test="$className = 'org.drools.ruleflow.core.impl.StartNodeImpl'">
+				<xsl:call-template name="RenderStartNode"/>
+			</xsl:when>
+			<xsl:when test="$className = 'org.drools.ruleflow.core.impl.EndNodeImpl'">
+				<xsl:call-template name="RenderEndNode"/>
+			</xsl:when>
+			<xsl:when test="$className = 'org.drools.ruleflow.core.impl.MilestoneNodeImpl'">
+				<xsl:call-template name="RenderMilestoneNode"/>
+			</xsl:when>
+		</xsl:choose>
+	</xsl:template>
+
+	<xsl:template name="RenderSplitNode">
+		<xsl:element name="split">
+			<xsl:attribute name="type"><xsl:value-of select = "./type"/></xsl:attribute>
+			<xsl:call-template name="renderIdAndNameAttribute"/>
+			<!-- Add constraints element if XOR or OR type of Split Node i.e. it is not AND node-->
+			<xsl:choose>
+				<xsl:when test="./type != '1'">
+					<xsl:element name="constraints">
+						<xsl:for-each select="constraints/entry/org.drools.ruleflow.core.impl.ConstraintImpl">
+							<xsl:call-template name="RenderConstraintNode"></xsl:call-template>
+						</xsl:for-each>
+					</xsl:element>
+				</xsl:when>
+			</xsl:choose>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template name="RenderConstraintNode">
+		<xsl:element name="constraint">
+			<xsl:attribute name="toNodeId">
+				<xsl:choose>
+					<xsl:when test="../org.drools.ruleflow.core.impl.ConnectionImpl[@id != '']">
+						<xsl:for-each select = "../org.drools.ruleflow.core.impl.ConnectionImpl/to">
+							<xsl:call-template name="printReferenceOrId"/>
+						</xsl:for-each>
+					</xsl:when>
+					<xsl:otherwise>
+						<xsl:variable name="constraintReference"><xsl:value-of select="../org.drools.ruleflow.core.impl.ConnectionImpl/@reference"/></xsl:variable>
+						<xsl:for-each select = "//org.drools.ruleflow.core.impl.ConnectionImpl[@id = $constraintReference]/to">
+							<xsl:call-template name="printReferenceOrId"/>
+						</xsl:for-each>
+					</xsl:otherwise>
+				</xsl:choose>
+			</xsl:attribute>
+			<xsl:attribute name="toType"><xsl:value-of select = "'DROOLS_DEFAULT'"/></xsl:attribute>
+			<xsl:attribute name="priority"><xsl:value-of select = "./priority"/></xsl:attribute>
+			<xsl:attribute name="type"><xsl:value-of select = "'rule'"/></xsl:attribute>
+			<xsl:attribute name="dialect"><xsl:value-of select = "'mvel'"/></xsl:attribute>
+			<xsl:attribute name="name"><xsl:value-of select = "./name"/></xsl:attribute>
+			<xsl:value-of select = "./constraint"/>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template name="RenderSubflowNode">
+		<xsl:element name="subProcess">
+			<xsl:attribute name="processId"><xsl:value-of select = "./processId"/></xsl:attribute>
+			<xsl:call-template name="renderIdAndNameAttribute"/>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template name="RenderJoinNode">
+		<xsl:element name="join">
+			<xsl:attribute name="type"><xsl:value-of select = "./type"/></xsl:attribute>
+			<xsl:call-template name="renderIdAndNameAttribute"/>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template name="RenderRuleSetNode">
+		<xsl:element name="ruleSet">
+			<xsl:attribute name="ruleFlowGroup"><xsl:value-of select = "./ruleFlowGroup"/></xsl:attribute>
+			<xsl:call-template name="renderIdAndNameAttribute"/>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template name="RenderActionNode">
+		<xsl:element name="actionNode">
+			<xsl:call-template name="renderIdAndNameAttribute"/>
+			<xsl:element name="action">
+			<!-- Hard coding type as expression and dialect as mvel. Not sure how this can be understood in the 4.0 format.
++-->
+				<xsl:attribute name="type"><xsl:value-of select = "'expression'"/></xsl:attribute>
+				<xsl:attribute name="dialect"><xsl:value-of select = "'mvel'"/></xsl:attribute>
+				<xsl:value-of select = "./action/consequence"/>
+			</xsl:element>
+		</xsl:element>
+	</xsl:template>
+	
+	<xsl:template name="RenderStartNode">
+		<xsl:element name="start">
+			<xsl:call-template name="renderIdAndNameAttribute"/>
+		</xsl:element>
+	</xsl:template>
+	
+	<xsl:template name="RenderEndNode">
+		<xsl:element name="end">
+			<xsl:call-template name="renderIdAndNameAttribute"/>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template name="RenderMilestoneNode">
+		<xsl:element name="milestone">
+			<xsl:call-template name="renderIdAndNameAttribute"/>
+			<xsl:element name="constraint">
+				<!-- Hard coded the type and dialect as in 4.0 it was assumed to be mvel. -->
+				<xsl:attribute name="type"><xsl:value-of select="'rule'"/></xsl:attribute>
+				<xsl:attribute name="dialect"><xsl:value-of select="'mvel'"/></xsl:attribute>
+				<xsl:value-of select="./constraint"/>
+			</xsl:element>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template name="renderIdAndNameAttribute">
+		<xsl:attribute name="id"><xsl:value-of select = "./@id"/></xsl:attribute>
+		<xsl:attribute name="name"><xsl:value-of select = "./name"/></xsl:attribute>
+		<xsl:call-template name="renderPosition"><xsl:with-param name="theId"><xsl:value-of select = "./@id"/></xsl:with-param></xsl:call-template>
+	</xsl:template>
+	
+	<xsl:template name="renderPosition2">
+		<xsl:param name="theId"/>
+		<xsl:attribute name="shahad"><xsl:value-of select = "$theId"/></xsl:attribute>
+	</xsl:template>
+	
+	<xsl:template name="renderPosition">
+		<xsl:param name="theId"/>
+		<xsl:for-each select="//element[./@id=$theId or ./@reference=$theId]">
+				<xsl:apply-templates select="../constraint"/>
+		</xsl:for-each>
+	</xsl:template>
+	
+	
+	<xsl:template match="constraint">
+		<xsl:attribute name="x"><xsl:value-of select = "./x"/></xsl:attribute>
+		<xsl:attribute name="y"><xsl:value-of select = "./y"/></xsl:attribute>
+		<xsl:attribute name="width"><xsl:value-of select = "./width"/></xsl:attribute>
+		<xsl:attribute name="height"><xsl:value-of select = "./height"/></xsl:attribute>
+	</xsl:template>
+	
+	
+	<xsl:template name="formConnections">
+		<xsl:for-each select="//from">
+			<xsl:element name="connection">
+				<xsl:attribute name="from"><xsl:apply-templates select="current()"/></xsl:attribute>
+				<xsl:attribute name="to"><xsl:apply-templates select="../to"/></xsl:attribute>
+				<xsl:call-template name="renderSourceBendpoints"><xsl:with-param name="theId"><xsl:apply-templates select="current()"/></xsl:with-param></xsl:call-template>
+				<xsl:call-template name="renderTargetBendpoints"><xsl:with-param name="theId"><xsl:apply-templates select="../to"/></xsl:with-param></xsl:call-template>
+			</xsl:element>
+		</xsl:for-each>
+	</xsl:template>
+	<xsl:template match="to">
+		<xsl:call-template name="printReferenceOrId"/>
+	</xsl:template>
+	<xsl:template match="from">
+		<xsl:call-template name="printReferenceOrId"/>
+	</xsl:template>
+	<xsl:template name="printReferenceOrId">
+		<xsl:for-each select="@*">
+			<xsl:choose>
+				<xsl:when test="(name() = 'reference') or (name() = 'id')">
+					<xsl:value-of select="."/>
+				</xsl:when>
+			</xsl:choose>
+		</xsl:for-each>
+	</xsl:template>
+	
+	<xsl:template name="renderSourceBendpoints">
+		<xsl:param name="theId"/>
+		<xsl:for-each select="//source/org.drools.eclipse.flow.common.editor.core.DefaultElementWrapper/default/element[./@id=$theId or ./@reference=$theId]">
+			<xsl:if test="../../../../bendpoints/child::*">
+				<xsl:attribute name="bendpoints">
+					<xsl:text>[</xsl:text>
+					<xsl:for-each select="../../../../bendpoints/child::*">
+						<xsl:value-of select="concat(./x/.,',',./y/.)"/>
+						<xsl:if test="position() != last()">;</xsl:if>
+					</xsl:for-each>
+					<xsl:text>]</xsl:text>
+				</xsl:attribute>
+			</xsl:if>
+		</xsl:for-each>
+	</xsl:template>
+	
+	<xsl:template name="renderTargetBendpoints">
+		<xsl:param name="theId"/>
+		<xsl:for-each select="//target/org.drools.eclipse.flow.common.editor.core.DefaultElementWrapper/default/element[./@id=$theId or ./@reference=$theId]">
+			<xsl:if test="../../../../bendpoints/child::*">
+				<xsl:attribute name="bendpoints">
+					<xsl:text>[</xsl:text>
+					<xsl:for-each select="../../../../bendpoints/child::*">
+						<xsl:value-of select="concat(./x/.,',',./y/.)"/>
+						<xsl:if test="position() != last()">;</xsl:if>
+					</xsl:for-each>
+					<xsl:text>]</xsl:text>
+				</xsl:attribute>
+			</xsl:if>
+		</xsl:for-each>
+	</xsl:template>
+	
+	
+</xsl:stylesheet>
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/flow/ruleflow/editor/RuleFlowModelEditor.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/flow/ruleflow/editor/RuleFlowModelEditor.java	2009-02-03 17:07:10 UTC (rev 25075)
+++ labs/jbossrules/trunk/drools-eclipse/org.drools.eclipse/src/main/java/org/drools/eclipse/flow/ruleflow/editor/RuleFlowModelEditor.java	2009-02-03 17:34:20 UTC (rev 25076)
@@ -20,6 +20,8 @@
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.StringReader;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
@@ -39,6 +41,7 @@
 import org.drools.ruleflow.core.RuleFlowProcess;
 import org.drools.xml.XmlProcessReader;
 import org.drools.xml.XmlRuleFlowProcessDumper;
+import org.drools.xml.processes.RuleFlowMigrator;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.draw2d.geometry.Rectangle;
 import org.eclipse.gef.EditPartFactory;
@@ -169,25 +172,49 @@
         writer.close();
     }
     
+    
     protected void createModel(InputStream is) {
-        try {
-            InputStreamReader reader = new InputStreamReader(is);
-            PackageBuilderConfiguration configuration = new PackageBuilderConfiguration();
-            XmlProcessReader xmlReader = new XmlProcessReader( configuration.getSemanticModules() );
-            try {
-                RuleFlowProcess process = (RuleFlowProcess) xmlReader.read(reader);
-                if (process == null) {
-                    setModel(createModel());
-                } else {
-                    setModel(new RuleFlowWrapperBuilder().getProcessWrapper(process, getJavaProject()));
-                }
-            } catch (Throwable t) {
-                DroolsEclipsePlugin.log(t);
-                setModel(createModel());
-            }
-            reader.close();
-        } catch (Throwable t) {
-            DroolsEclipsePlugin.log(t);
-        }
+    	try 
+    	{
+    		InputStreamReader isr = new InputStreamReader(is);
+    		PackageBuilderConfiguration configuration = new PackageBuilderConfiguration();
+    		XmlProcessReader xmlReader = new XmlProcessReader( configuration.getSemanticModules() );
+    		
+    		//Migrate v4 ruleflows to v5
+    		Reader reader = null;
+    		try 
+    		{
+    			String xml = RuleFlowMigrator.convertReaderToString(isr);
+    			if (RuleFlowMigrator.needToMigrateRFM(xml))
+    			{
+    				xml = RuleFlowMigrator.portRFToCurrentVersion(xml);
+    				MessageDialog.openInformation(this.getSite().getShell(),
+    			            "Incompatible RuleFlow Version", 
+    			            "WARNING! The selected RuleFlow is Drools version 4 format.\n\n" +
+    			            "Any changes made to this RuleFlow will be saved in Drools 5 format, which is " +
+    			            "not compatible with Drools 4. To convert this RuleFlow " +
+    			            "to Drools 5 format, select Save As from the File menu and overwrite this " +
+    			            "file - the new RuleFlow file will be saved in Drools 5 format.");
+    			}
+    			
+    			reader =  new StringReader(xml);
+
+    			RuleFlowProcess process = (RuleFlowProcess) xmlReader.read(reader);
+    			if (process == null) {
+    				setModel(createModel());
+    			} else {
+    				setModel(new RuleFlowWrapperBuilder().getProcessWrapper(process, getJavaProject()));
+    			}
+    		} catch (Throwable t) {
+    			DroolsEclipsePlugin.log(t);
+    			setModel(createModel());
+    		}
+
+    		if (reader != null){
+    			reader.close();
+    		}
+    	} catch (Throwable t) {
+    		DroolsEclipsePlugin.log(t);
+    	}
     }
 }

Modified: labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/builder/RuleFlowContentModelBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/builder/RuleFlowContentModelBuilder.java	2009-02-03 17:07:10 UTC (rev 25075)
+++ labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/builder/RuleFlowContentModelBuilder.java	2009-02-03 17:34:20 UTC (rev 25076)
@@ -97,8 +97,19 @@
 
             tn.setId( node.getId() );
 
-            tn.setX( (Integer) node.getMetaData( "x" ) );
-            tn.setY( (Integer) node.getMetaData( "y" ) );
+            //Guard needed to Migrate v4 ruleflows to v5
+            Integer x = (Integer) node.getMetaData( "x" );
+            if (x != null)
+            {
+            	tn.setX(x);
+            }
+            
+            // Guard needed to Migrate v4 ruleflows to v5
+            Integer y = (Integer) node.getMetaData( "y" );
+            if (y != null)
+            {
+            	tn.setY(y);
+            }
 
             Integer height = (Integer) node.getMetaData( "height" );
             if ( height != null ) {

Modified: labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/contenthandler/RuleFlowHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/contenthandler/RuleFlowHandler.java	2009-02-03 17:07:10 UTC (rev 25075)
+++ labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/contenthandler/RuleFlowHandler.java	2009-02-03 17:34:20 UTC (rev 25076)
@@ -52,6 +52,14 @@
 			asset.content = content;
 		} else if (process == null && !"".equals(item.getContent())) {
 			asset.content = new RuleFlowContentModel();
+			//
+			// 
+			// Migrate v4 ruleflows to v5
+			// All we can do is put the old drools 4 rfm back as the xml so 
+			// that we can at least rebuild the package with it if the
+			// migrate ruleflow system property is set true.
+			//
+			((RuleFlowContentModel)asset.content).setXml(item.getContent());
 		}
 
 	}
@@ -82,19 +90,41 @@
 	}
 
 	public void storeAssetContent(RuleAsset asset, AssetItem repoAsset)
-			throws SerializableException {
+	throws SerializableException {
 
 		RuleFlowContentModel content = (RuleFlowContentModel) asset.content;
 
-		RuleFlowProcess process = createModel(new ByteArrayInputStream(content
-				.getXml().getBytes()));
+		// 
+		// Migrate v4 ruleflows to v5
+		// Added guards to check for nulls in the case where the ruleflows
+		// have not been migrated from drools 4 to 5.
+		//
+		if (content != null)
+		{
+			if (content.getXml() != null)
+			{
+				RuleFlowProcess process = createModel(new ByteArrayInputStream(content
+						.getXml().getBytes()));
 
-		RuleFlowProcessBuilder.updateProcess(process, content.getNodes());
+				if (process != null)
+				{
+					RuleFlowProcessBuilder.updateProcess(process, content.getNodes());
 
-		XmlRuleFlowProcessDumper dumper = XmlRuleFlowProcessDumper.INSTANCE;
-		String out = dumper.dump(process);
+					XmlRuleFlowProcessDumper dumper = XmlRuleFlowProcessDumper.INSTANCE;
+					String out = dumper.dump(process);
 
-		repoAsset.updateContent(out);
+					repoAsset.updateContent(out);
+				}
+				else
+				{
+					//
+					// Migrate v4 ruleflows to v5
+					// Put the old contents back as there is no updating possible
+				    //
+					repoAsset.updateContent(content.getXml());
+				}
+			}
+		}
 	}
 
 	public void assembleDRL(BRMSPackageBuilder builder, AssetItem asset,

Modified: labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/files/FileManagerUtils.java
===================================================================
--- labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/files/FileManagerUtils.java	2009-02-03 17:07:10 UTC (rev 25075)
+++ labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/files/FileManagerUtils.java	2009-02-03 17:34:20 UTC (rev 25076)
@@ -33,7 +33,6 @@
 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
 import org.apache.commons.fileupload.servlet.ServletFileUpload;
 import org.drools.compiler.DroolsParserException;
-import org.drools.compiler.PackageBuilderConfiguration;
 import org.drools.guvnor.client.common.HTMLFileManagerFields;
 import org.drools.guvnor.server.ServiceImplementation;
 import org.drools.guvnor.server.builder.BRMSPackageBuilder;
@@ -42,6 +41,7 @@
 import org.drools.guvnor.server.contenthandler.ContentManager;
 import org.drools.guvnor.server.contenthandler.IRuleAsset;
 import org.drools.guvnor.server.contenthandler.ModelContentHandler;
+import org.drools.guvnor.server.repository.MigrateRepository;
 import org.drools.guvnor.server.security.AdminType;
 import org.drools.guvnor.server.security.RoleTypes;
 import org.drools.guvnor.server.util.ClassicDRLImporter;
@@ -250,6 +250,24 @@
 					RoleTypes.ADMIN);
 		}
         repository.importRulesRepository( data );
+        
+        //
+        //Migrate v4 ruleflows to v5
+        //This section checks if the repository contains drools v4
+        //ruleflows that need to be migrated to drools v5
+        //
+        try
+        {
+        	if ( MigrateRepository.needsRuleflowMigration(repository) ) 
+        	{
+        		MigrateRepository.migrateRuleflows( repository );
+        	}
+        }
+        catch ( RepositoryException e ) 
+        {
+        	e.printStackTrace();
+        	throw new RulesRepositoryException(e);
+        }
     }
 
     @Restrict("#{identity.loggedIn}")
@@ -258,6 +276,24 @@
 
         repository.importPackageToRepository( data,
                                               importAsNew );
+        
+        //
+        //Migrate v4 ruleflows to v5
+        //This section checks if the repository contains drools v4
+        //ruleflows that need to be migrated to drools v5
+        //
+        try
+        {
+        	if ( MigrateRepository.needsRuleflowMigration(repository) ) 
+        	{
+        		MigrateRepository.migrateRuleflows( repository );
+        	}
+        }
+        catch ( RepositoryException e ) 
+        {
+        	e.printStackTrace();
+        	throw new RulesRepositoryException(e);
+        }
     }
 
     /**

Modified: labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/repository/BRMSRepositoryConfiguration.java
===================================================================
--- labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/repository/BRMSRepositoryConfiguration.java	2009-02-03 17:07:10 UTC (rev 25075)
+++ labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/repository/BRMSRepositoryConfiguration.java	2009-02-03 17:34:20 UTC (rev 25076)
@@ -25,6 +25,7 @@
 
 import org.drools.repository.JCRRepositoryConfigurator;
 import org.drools.repository.JackrabbitRepositoryConfigurator;
+import org.drools.repository.RulesRepository;
 import org.drools.repository.RulesRepositoryAdministrator;
 import org.drools.repository.RulesRepositoryException;
 import org.jboss.seam.ScopeType;
@@ -58,11 +59,30 @@
 
 
     void create(Session sessionForSetup) {
-
-        RulesRepositoryAdministrator admin = new RulesRepositoryAdministrator(sessionForSetup);
+    	
+    	RulesRepositoryAdministrator admin = new RulesRepositoryAdministrator(sessionForSetup);
         if (!admin.isRepositoryInitialized()) {
             configurator.setupRulesRepository( sessionForSetup );
         }
+        
+        //
+        //Migrate v4 ruleflows to v5
+        //This section checks if the repository contains drools v4
+        //ruleflows that need to be migrated to drools v5
+        //
+        RulesRepository repo = new RulesRepository(sessionForSetup);
+        try
+        {
+        	if ( MigrateRepository.needsRuleflowMigration(repo) ) 
+        	{
+        		MigrateRepository.migrateRuleflows( repo );
+        	}
+        }
+        catch ( RepositoryException e ) 
+        {
+        	e.printStackTrace();
+        	throw new RulesRepositoryException(e);
+        }
         //sessionForSetup.logout();
     }
 

Added: labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/repository/MigrateRepository.java
===================================================================
--- labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/repository/MigrateRepository.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-guvnor/src/main/java/org/drools/guvnor/server/repository/MigrateRepository.java	2009-02-03 17:34:20 UTC (rev 25076)
@@ -0,0 +1,165 @@
+package org.drools.guvnor.server.repository;
+
+import javax.jcr.RepositoryException;
+
+import org.drools.guvnor.client.common.AssetFormats;
+import org.drools.repository.AssetItem;
+import org.drools.repository.AssetItemIterator;
+import org.drools.repository.PackageItem;
+import org.drools.repository.PackageIterator;
+import org.drools.repository.RulesRepository;
+import org.drools.xml.processes.RuleFlowMigrator;
+
+import org.apache.log4j.Logger;
+
+/**
+ * This class is used to migrate version 4 ruleflow assets in a version 4
+ * or 5 drools repository into version 5 ruleflow assets.
+ * IMPORTANT: the current code only performs the transformations if the
+ * Drools system property drools.ruleflow.port is true, just as the 
+ * drools compiler only transforms version 4 ruleflows to 5 if this
+ * property is set.
+ * 
+ * If a ruleflow is migrated, it is checked in as new version so that
+ * the previous version is preserved. The current code checks-in
+ * the new version as the admin user with an appropriate comment indicating
+ * that the flow has been migrated. Hover, the code could also be changed
+ * to check-in each migrated ruleflow using the credentials of the last
+ * person to check-in the ruleflow, however, in future there may be a 
+ * danger that the person who last checked in the file may have lost
+ * privileges to check-in the file, so we use the admin user
+ * for now.
+ * 
+ * @author Shahad Ahmed
+ */
+public class MigrateRepository {
+	
+	private static final Logger log  = Logger.getLogger( MigrateRepository.class );
+
+	
+	/*************************************************************************
+	 * Returns true if the drools system property drools.ruleflow.port is true
+	 * indicating that ruleflow migration should be performed.
+	 * @param repo
+	 * @return true if the drools system property drools.ruleflow.port is true
+     * indicating that ruleflow migration should be performed.
+	 * @throws RepositoryException
+	 ************************************************************************/
+	public static boolean needsRuleflowMigration(RulesRepository repo) throws RepositoryException {
+		String portRuleFlow = System.getProperty( "drools.ruleflow.port", "false" );
+		return portRuleFlow.equalsIgnoreCase("true");
+	}
+
+	
+	/*************************************************************************
+	 * Iterates through all the packages in the given repository  
+	 * migrating all drools 4 .rfm and .rf ruleflow assets that need to be 
+	 * migrated to 5.
+	 * Note that archived assets, and assets in snapshots are also migrated.
+	 * @param repo
+	 * @throws RepositoryException
+	 ************************************************************************/
+	public static void migrateRuleflows(RulesRepository repo) throws RepositoryException 
+	{
+		log.debug("AUTO MIGRATION: Performing drools ruleflow migration...");
+
+		PackageIterator pkgs = repo.listPackages();
+		boolean performed = false;
+		while(pkgs.hasNext()) {
+			performed = true;
+			PackageItem pkg = (PackageItem) pkgs.next();
+			migrateRuleflows(pkg);
+
+			String[] snaps = repo.listPackageSnapshots(pkg.getName());
+			if (snaps != null) {
+				for (int i = 0; i < snaps.length; i++) {
+					PackageItem snap = repo.loadPackageSnapshot(pkg.getName(), snaps[i]);
+					migrateRuleflows(snap);
+				}
+			}
+		}
+
+		if (performed) {
+			log.debug("AUTO MIGRATION: Drools rulesflow migration completed.");
+		}
+	}
+
+	
+	/*************************************************************************
+	 * migrate all ruleflows in the package, including archived ones.
+	 * The migrated ruleflow is checked in as a new version and previous 
+	 * versions are not migrated.
+	 * NOTE that we always try to migrate if the drools.ruleflow.port
+	 * property is true, even if the repository has been migrated before.
+	 * This is needed as the drools.ruleflow.port property may have been
+	 * false when the repository was first migrated (i.e. the 
+	 * HEADER_PROPERTY_NAME above may have been migrated, but not the 
+	 * ruleflows).
+	 * Also, all snapshot packages are updated as well.
+	 * @param pkg
+	 ************************************************************************/
+	private static void migrateRuleflows(PackageItem pkg) 
+	{
+		String portRuleFlow = System.getProperty( "drools.ruleflow.port", "false" );
+		if ( portRuleFlow.equalsIgnoreCase( "true" ) ) 
+		{
+			AssetItemIterator it = listAssetsByFormatIncludingArchived(pkg, 
+						new String[]{AssetFormats.RULE_FLOW_RF});
+
+			while(it.hasNext())
+			{
+				AssetItem item = it.next();
+				String rf = item.getContent();
+				try
+				{
+					if(RuleFlowMigrator.needToMigrateRFM(rf))
+					{
+						log.debug("Migrating v4 RFM to v5: " + item.getName());
+						rf = RuleFlowMigrator.portRFMToCurrentVersion(rf);
+						item.updateContent(rf);
+						item.checkin("Auto migration from ruleflow RFM version 4 to 5");
+					}
+					else if(RuleFlowMigrator.needToMigrateRF(rf))
+                    {
+                        log.debug("Migrating v4 RF to v5: " + item.getName());
+                        rf = RuleFlowMigrator.portRFToCurrentVersion(rf);
+                        item.updateContent(rf);
+                        item.checkin("Auto migration from ruleflow RF version 4 to 5");
+                    }
+				}
+				catch (Exception ex)
+				{
+					log.error("Ruleflow migration failed for item: " 
+							+ item.getName() + " due to " + ex);
+					ex.printStackTrace(System.out);
+				}
+
+			}
+		}
+	}
+	
+	
+    /*************************************************************************
+     * This will load an iterator for assets in the given package of the 
+     * given format type, including archived assets.
+     * @param pkg The package to check
+     * @param formats an array of the format types to find.
+     * @return an iterator for assets of the given format type, including
+     * archived assets.
+     ************************************************************************/
+    private static AssetItemIterator listAssetsByFormatIncludingArchived(PackageItem pkg,
+    		String[] formats) {
+        if (formats.length == 1) {
+            return pkg.queryAssets( "drools:format='" + formats[0] + "'" , true);
+        } else {
+            String predicate = " ( ";
+            for ( int i = 0; i < formats.length; i++ ) {
+                predicate = predicate + "drools:format='" + formats[i] + "'";
+                if (!(i == formats.length -1 )) { predicate =  predicate + " OR "; }
+            }
+            predicate = predicate + " ) ";
+            return pkg.queryAssets( predicate , true);
+        }
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/JpdlNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/JpdlNodeInstance.java	2009-02-03 17:07:10 UTC (rev 25075)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/JpdlNodeInstance.java	2009-02-03 17:34:20 UTC (rev 25076)
@@ -297,7 +297,7 @@
     }
 
 	public void addTimerListener() {
-    	((ProcessInstance) getProcessInstance()).addEventListener("timerTriggered", this, false);
+    	getProcessInstance().addEventListener("timerTriggered", this, false);
 	}
 	
     public void removeEventListeners() {
@@ -307,7 +307,7 @@
     }
     
     public void removeTimerListener() {
-    	((ProcessInstance) getProcessInstance()).removeEventListener("timerTriggered", this, false);
+    	getProcessInstance().removeEventListener("timerTriggered", this, false);
     }
 
 }

Modified: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/StartStateInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/StartStateInstance.java	2009-02-03 17:07:10 UTC (rev 25075)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/StartStateInstance.java	2009-02-03 17:34:20 UTC (rev 25076)
@@ -62,14 +62,14 @@
     }
     
     private void addWorkItemListener() {
-    	((ProcessInstance) getProcessInstance()).addEventListener("workItemCompleted", this, false);
-    	((ProcessInstance) getProcessInstance()).addEventListener("workItemAborted", this, false);
+    	getProcessInstance().addEventListener("workItemCompleted", this, false);
+    	getProcessInstance().addEventListener("workItemAborted", this, false);
     }
     
     public void removeEventListeners() {
         super.removeEventListeners();
-        ((ProcessInstance) getProcessInstance()).removeEventListener("workItemCompleted", this, false);
-        ((ProcessInstance) getProcessInstance()).removeEventListener("workItemAborted", this, false);
+        getProcessInstance().removeEventListener("workItemCompleted", this, false);
+        getProcessInstance().removeEventListener("workItemAborted", this, false);
     }
 
     public void signalEvent(String type, Object event) {

Modified: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/TaskNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/TaskNodeInstance.java	2009-02-03 17:07:10 UTC (rev 25075)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/TaskNodeInstance.java	2009-02-03 17:34:20 UTC (rev 25076)
@@ -6,7 +6,6 @@
 
 import org.drools.jpdl.core.node.TaskNode;
 import org.drools.process.core.context.swimlane.SwimlaneContext;
-import org.drools.process.instance.ProcessInstance;
 import org.drools.process.instance.context.swimlane.SwimlaneContextInstance;
 import org.drools.process.instance.impl.WorkItemImpl;
 import org.drools.runtime.process.NodeInstance;
@@ -88,13 +87,13 @@
     }
 
     public void addEventListeners() {
-    	((ProcessInstance) getProcessInstance()).addEventListener("workItemCompleted", this, false);
-    	((ProcessInstance) getProcessInstance()).addEventListener("workItemAborted", this, false);
+    	getProcessInstance().addEventListener("workItemCompleted", this, false);
+    	getProcessInstance().addEventListener("workItemAborted", this, false);
     }
     
     public void removeEventListeners() {
-        ((ProcessInstance) getProcessInstance()).removeEventListener("workItemCompleted", this, false);
-        ((ProcessInstance) getProcessInstance()).removeEventListener("workItemAborted", this, false);
+        getProcessInstance().removeEventListener("workItemCompleted", this, false);
+        getProcessInstance().removeEventListener("workItemAborted", this, false);
     }
 
     public void signalEvent(String type, Object event) {

Modified: labs/jbossrules/trunk/drools-process/drools-osworkflow/.classpath
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-osworkflow/.classpath	2009-02-03 17:07:10 UTC (rev 25075)
+++ labs/jbossrules/trunk/drools-process/drools-osworkflow/.classpath	2009-02-03 17:34:20 UTC (rev 25076)
@@ -5,24 +5,43 @@
   <classpathentry kind="src" path="src/test/resources" output="target/test-classes" including="**" excluding="**/*.java"/>
   <classpathentry kind="output" path="target/classes"/>
   <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+  <classpathentry kind="var" path="M2_REPO/antlr/antlr/2.7.6/antlr-2.7.6.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/antlr/antlr-runtime/3.1.1/antlr-runtime-3.1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/avalon-framework/avalon-framework/4.1.3/avalon-framework-4.1.3.jar"/>
   <classpathentry kind="var" path="M2_REPO/bsh/bsh/1.2b7/bsh-1.2b7.jar"/>
+  <classpathentry kind="var" path="M2_REPO/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar"/>
+  <classpathentry kind="var" path="M2_REPO/commons-collections/commons-collections/3.2/commons-collections-3.2.jar"/>
   <classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1/commons-logging-1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/eclipse/jdt/core/3.4.2.v_883_R34x/core-3.4.2.v_883_R34x.jar"/>
+  <classpathentry kind="var" path="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/drools/drools-api/5.0.0.SNAPSHOT/drools-api-5.0.0.SNAPSHOT.jar" sourcepath="M2_REPO/org/drools/drools-api/5.0.0.SNAPSHOT/drools-api-5.0.0.SNAPSHOT-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/drools/drools-compiler/5.0.0.SNAPSHOT/drools-compiler-5.0.0.SNAPSHOT.jar" sourcepath="M2_REPO/org/drools/drools-compiler/5.0.0.SNAPSHOT/drools-compiler-5.0.0.SNAPSHOT-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/drools/drools-core/5.0.0.SNAPSHOT/drools-core-5.0.0.SNAPSHOT.jar" sourcepath="M2_REPO/org/drools/drools-core/5.0.0.SNAPSHOT/drools-core-5.0.0.SNAPSHOT-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/drools/drools-process-enterprise/5.0.0.SNAPSHOT/drools-process-enterprise-5.0.0.SNAPSHOT.jar" sourcepath="M2_REPO/org/drools/drools-process-enterprise/5.0.0.SNAPSHOT/drools-process-enterprise-5.0.0.SNAPSHOT-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hibernate/ejb3-persistence/1.0.2.GA/ejb3-persistence-1.0.2.GA.jar"/>
+  <classpathentry kind="var" path="M2_REPO/com/h2database/h2/1.0.77/h2-1.0.77.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-annotations/3.4.0.GA/hibernate-annotations-3.4.0.GA.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-commons-annotations/3.1.0.GA/hibernate-commons-annotations-3.1.0.GA.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-core/3.3.0.SP1/hibernate-core-3.3.0.SP1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-entitymanager/3.4.0.GA/hibernate-entitymanager-3.4.0.GA.jar"/>
+  <classpathentry kind="var" path="M2_REPO/janino/janino/2.5.15/janino-2.5.15.jar"/>
+  <classpathentry kind="var" path="M2_REPO/javassist/javassist/3.4.GA/javassist-3.4.GA.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/jmock/jmock/2.5.1/jmock-2.5.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/jmock/jmock-legacy/2.5.1/jmock-legacy-2.5.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/joda-time/joda-time/1.5.2/joda-time-1.5.2.jar"/>
+  <classpathentry kind="var" path="M2_REPO/javax/transaction/jta/1.0.1B/jta-1.0.1B.jar"/>
+  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
   <classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.13/log4j-1.2.13.jar"/>
   <classpathentry kind="var" path="M2_REPO/logkit/logkit/1.0.1/logkit-1.0.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/avalon-framework/avalon-framework/4.1.3/avalon-framework-4.1.3.jar"/>
-  <classpathentry kind="var" path="M2_REPO/javax/servlet/servlet-api/2.3/servlet-api-2.3.jar"/>
-  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/mvel/mvel2/2.0.6/mvel2-2.0.6.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/objenesis/objenesis/1.0/objenesis-1.0.jar"/>
   <classpathentry kind="var" path="M2_REPO/opensymphony/oscore/2.2.5/oscore-2.2.5.jar"/>
   <classpathentry kind="var" path="M2_REPO/opensymphony/osworkflow/2.8.0/osworkflow-2.8.0.jar"/>
+  <classpathentry kind="var" path="M2_REPO/javax/persistence/persistence-api/1.0/persistence-api-1.0.jar"/>
   <classpathentry kind="var" path="M2_REPO/opensymphony/propertyset/1.4/propertyset-1.4.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/antlr/antlr-runtime/3.0.1/antlr-runtime-3.0.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/drools/drools-api/5.0.0.SNAPSHOT/drools-api-5.0.0.SNAPSHOT.jar" sourcepath="M2_REPO/org/drools/drools-api/5.0.0.SNAPSHOT/drools-api-5.0.0.SNAPSHOT-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/drools/drools-compiler/5.0.0.SNAPSHOT/drools-compiler-5.0.0.SNAPSHOT.jar" sourcepath="M2_REPO/org/drools/drools-compiler/5.0.0.SNAPSHOT/drools-compiler-5.0.0.SNAPSHOT-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/drools/drools-core/5.0.0.SNAPSHOT/drools-core-5.0.0.SNAPSHOT.jar" sourcepath="M2_REPO/org/drools/drools-core/5.0.0.SNAPSHOT/drools-core-5.0.0.SNAPSHOT-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/mvel/mvel2/2.0.1-SNAPSHOT/mvel2-2.0.1-SNAPSHOT.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/eclipse/jdt/core/3.4.2.v_883_R34x/core-3.4.2.v_883_R34x.jar"/>
-  <classpathentry kind="var" path="M2_REPO/janino/janino/2.5.15/janino-2.5.15.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/jmock/jmock/2.5.0.1/jmock-2.5.0.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/javax/servlet/servlet-api/2.3/servlet-api-2.3.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.4.3/slf4j-api-1.4.3.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-jdk14/1.5.2/slf4j-jdk14-1.5.2.jar"/>
 </classpath>
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-process/drools-osworkflow/.project
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-osworkflow/.project	2009-02-03 17:07:10 UTC (rev 25075)
+++ labs/jbossrules/trunk/drools-process/drools-osworkflow/.project	2009-02-03 17:34:20 UTC (rev 25076)
@@ -1,13 +1,13 @@
-<projectDescription>
-  <name>drools-osworkflow</name>
-  <comment>A rule production system</comment>
-  <projects/>
-  <buildSpec>
-    <buildCommand>
-      <name>org.eclipse.jdt.core.javabuilder</name>
-    </buildCommand>
-  </buildSpec>
-  <natures>
-    <nature>org.eclipse.jdt.core.javanature</nature>
-  </natures>
+<projectDescription>
+  <name>drools-osworkflow</name>
+  <comment>A rule production system</comment>
+  <projects/>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+  </natures>
 </projectDescription>
\ No newline at end of file




More information about the jboss-svn-commits mailing list