All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jadex.bpmn.model.io.SBpmnModelWriter Maven / Gradle / Ivy

The newest version!
package jadex.bpmn.model.io;

import jadex.bpmn.model.MActivity;
import jadex.bpmn.model.MBpmnModel;
import jadex.bpmn.model.MContextVariable;
import jadex.bpmn.model.MDataEdge;
import jadex.bpmn.model.MLane;
import jadex.bpmn.model.MMessagingEdge;
import jadex.bpmn.model.MParameter;
import jadex.bpmn.model.MPool;
import jadex.bpmn.model.MProperty;
import jadex.bpmn.model.MSequenceEdge;
import jadex.bpmn.model.MSubProcess;
import jadex.bridge.ClassInfo;
import jadex.bridge.modelinfo.ConfigurationInfo;
import jadex.bridge.modelinfo.IArgument;
import jadex.bridge.modelinfo.UnparsedExpression;
import jadex.bridge.service.ProvidedServiceInfo;
import jadex.bridge.service.RequiredServiceInfo;
import jadex.commons.SUtil;
import jadex.commons.Tuple2;
import jadex.commons.collection.IndexMap;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  Writer for BPMN models.
 *
 */
public class SBpmnModelWriter
{
	/** The build number */
	public static final int BUILD = 31;
	
	/** The indentation string. */
	public static final String INDENT_STRING = "  ";
	
	/** Tag for start events. */
	public static final String START_EVENT_TAG = "startEvent";
	
	/** Tag for intermediate events. */
	public static final String INTERMEDIATE_EVENT_TAG = "intermediate";
	
	/** Tag for end events. */
	public static final String END_EVENT_TAG = "endEvent";
	
	/** Activity type mapping. */
	public static final Map ACT_TYPE_MAPPING = new HashMap();
	static
	{
		ACT_TYPE_MAPPING.put(MBpmnModel.TASK, "task");
		ACT_TYPE_MAPPING.put(MBpmnModel.SUBPROCESS, "subProcess");
		ACT_TYPE_MAPPING.put(MBpmnModel.GATEWAY_PARALLEL, "parallelGateway");
		ACT_TYPE_MAPPING.put(MBpmnModel.GATEWAY_DATABASED_EXCLUSIVE, "exclusiveGateway");
		ACT_TYPE_MAPPING.put(MBpmnModel.GATEWAY_DATABASED_INCLUSIVE, "inclusiveGateway");
		
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_START_EMPTY, START_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_START_MESSAGE, START_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_START_TIMER, START_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_START_RULE, START_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_START_SIGNAL, START_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_START_MULTIPLE, START_EVENT_TAG);
		
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_INTERMEDIATE_EMPTY, INTERMEDIATE_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_INTERMEDIATE_ERROR, INTERMEDIATE_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_INTERMEDIATE_RULE, INTERMEDIATE_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_INTERMEDIATE_SIGNAL, INTERMEDIATE_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_INTERMEDIATE_MESSAGE, INTERMEDIATE_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_INTERMEDIATE_TIMER, INTERMEDIATE_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_INTERMEDIATE_MULTIPLE, INTERMEDIATE_EVENT_TAG);
		
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_END_EMPTY, END_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_END_ERROR, END_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_END_MESSAGE, END_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_END_SIGNAL, END_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_END_COMPENSATION, END_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_END_CANCEL, END_EVENT_TAG);
		ACT_TYPE_MAPPING.put(MBpmnModel.EVENT_END_TERMINATE, END_EVENT_TAG);
	}
	
	/**
	 *  Writes a BPMN model.
	 *  
	 *  @param outputfile The output file.
	 *  @param mmodel The BPMN model.
	 *  @param vmodelwriter The visual model writer, can be null.
	 */
	public static final void writeModel(File outputfile, MBpmnModel mmodel, IBpmnVisualModelWriter vmodelwriter) throws IOException
	{
		File file = File.createTempFile(outputfile.getName(), ".bpmn2");
		OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
		writeModel(os, mmodel, vmodelwriter);
		os.close();
		
		SUtil.moveFile(file, outputfile);
	}
	
	/**
	 *  Writes a BPMN model.
	 *  
	 *  @param os The output stream.
	 *  @param mmodel The BPMN model.
	 *  @param vmodelwriter The visual model writer, can be null.
	 */
	public static final void writeModel(OutputStream os, MBpmnModel mmodel, IBpmnVisualModelWriter vmodelwriter) throws IOException
	{
		PrintStream out = new PrintStream(os, false, "UTF-8");
		
		writeInitialBoilerPlate(out);
		
		int ind = 1;
		
		writeJadexModelInfo(out, ind, mmodel);
		
		List pools = mmodel.getPools();
		
		writePoolSemantics(out, ind, pools);
		
		//writePoolCollaborations(out, pools);
		
		if (vmodelwriter != null)
		{
			vmodelwriter.writeVisualModel(out);
		}
		
		out.println("");
		out.println();
		
		out.flush();
	}
	
	/**
	 *  Writes the initial XML boiler plate.
	 *  
	 *  @param out The output.
	 *  @param semid The semantics ID.
	 */
	protected static final void writeInitialBoilerPlate(PrintStream out)
	{
		String indent = "                      ";
		out.println("");
		out.print("");
	}
	
	/**
	 *  Writes the Jadex-specific model information
	 *  
	 *  @param out The output.
	 *  @param ind The indentation level.
	 *  @param mmodel The model.
	 */
	protected static final void writeJadexModelInfo(PrintStream out, int ind, MBpmnModel mmodel)
	{
		out.print(getIndent(ind));
		out.println("");
		++ind;
		
		String name = mmodel.getModelInfo().getName();
		if (name != null && name.length() > 0)
		{
			out.print(getIndent(ind));
			out.print("");
			out.print(escapeString(name));
			out.println("");
		}
		
		String desc = mmodel.getModelInfo().getDescription();
		if (desc != null && desc.length() > 0)
		{
			out.print(getIndent(ind));
			out.print("");
			out.print(escapeString(desc));
			out.println("");
		}
		
		String pkg = mmodel.getModelInfo().getPackage();
		if (pkg != null && pkg.length() > 0)
		{
			out.print(getIndent(ind));
			out.print("");
			out.print(escapeString(pkg));
			out.println("");
		}
		
		boolean suspend = Boolean.TRUE.equals(mmodel.getModelInfo().getSuspend(null));
		boolean master = Boolean.TRUE.equals(mmodel.getModelInfo().getMaster(null));
		boolean daemon = Boolean.TRUE.equals(mmodel.getModelInfo().getDaemon(null));
		boolean autoshutdown = Boolean.TRUE.equals(mmodel.getModelInfo().getAutoShutdown(null));
		String monitoring = mmodel.getModelInfo().getMonitoring(null)!=null ? mmodel.getModelInfo().getMonitoring(null).toString() : null;
		boolean synchronous = Boolean.TRUE.equals(mmodel.getModelInfo().getSynchronous(null));
		boolean keepalive = Boolean.TRUE.equals(mmodel.isKeepAlive());
		
		if (suspend || master || daemon || autoshutdown || monitoring!=null || synchronous || keepalive)
		{
			out.print(getIndent(ind));
			out.print("");
		}
		
		writeImports(out, ind, mmodel.getModelInfo().getImports());
		
		writeArguments(out, ind, false, mmodel.getModelInfo().getArguments());
		
		writeArguments(out, ind, true, mmodel.getModelInfo().getResults());
		
		writeContextVariables(out, ind, mmodel);
		
		writeProvidedServices(out, ind, mmodel);
		
		writeRequiredServices(out, ind, mmodel);
		
		writeConfigurations(out, ind, mmodel, mmodel.getModelInfo().getConfigurations());
		
		--ind;
		out.print(getIndent(ind));
		out.println("");
	}
	
	/**
	 *  Writes the imports.
	 *  
	 *  @param out The output.
	 *  @param ind The indentation level.
	 *  @param imports The imports.
	 */
	protected static final void writeImports(PrintStream out, int ind, String[] imports)
	{
		if (imports.length > 0)
		{
			out.print(getIndent(ind));
			out.println("");
			++ind;
			
			for (int i = 0; i < imports.length; ++i)
			{
				out.print(getIndent(ind));
				out.print("");
				out.print(escapeString(imports[i]));
				out.println("");
			}
			
			--ind;
			out.print(getIndent(ind));
			out.println("");
		}
	}
	
	/**
	 *  Writes the arguments or results.
	 *  
	 *  @param out The output.
	 *  @param ind The indentation level.
	 *  @param results Set true for writing results.
	 *  @param args The arguments or results.
	 */
	protected static final void writeArguments(PrintStream out, int ind, boolean results, IArgument[] args)
	{
		String prefix = results? "result" : "argument";
		
		if (args.length > 0)
		{
			out.print(getIndent(ind));
			out.print("");
			++ind;
			
			for (int i = 0; i < args.length; ++i)
			{
				if(args[i].getName() != null && args[i].getName().length() > 0)
				{
					IArgument arg = args[i];
					
					boolean hasdesc = arg.getDescription() != null && arg.getDescription().length() > 0;
					boolean hasval = arg.getDefaultValue() != null && arg.getDefaultValue().getValue() != null && arg.getDefaultValue().getValue().length() > 0;
					
					out.print(getIndent(ind));
					out.print("");
						++ind;
						
						if (hasdesc)
						{
							out.print(getIndent(ind));
							out.print("");
							out.print(escapeString(arg.getDescription()));
							out.println("");
						}
						
						if (hasval)
						{
							out.print(getIndent(ind));
							out.print("");
							out.print(escapeString(arg.getDefaultValue().getValue()));
							out.println("");
						}
						
						--ind;
						out.print(getIndent(ind));
						out.print("");
					}
					else
					{
						out.println("\"/>");
					}
				}
			}
			
			--ind;
			out.print(getIndent(ind));
			out.print("");
		}
	}
	
	/**
	 *  Writes the context variables.
	 *  
	 *  @param out The output.
	 *  @param ind The indentation level.
	 *  @param mmodel The BPMN model.
	 */
	protected static final void writeContextVariables(PrintStream out, int ind, MBpmnModel mmodel)
	{
		List ctvs = mmodel.getContextVariables();
		if (ctvs.size() > 0)
		{
			out.print(getIndent(ind));
			out.println("");
			++ind;
			
			for (MContextVariable ctv : ctvs)
			{
				ClassInfo ci = ctv.getClazz();
				String cn = ci != null? ci.getTypeName() : "";
				
				out.print(getIndent(ind));
				out.print(" 0)
				if (ctv.getValue() != null && ctv.getValue().length() > 0)
				{
					out.println("\">");
					++ind;
					
					out.print(getIndent(ind));
					out.print("");
					out.print(escapeString(ctv.getValue()));
					out.println("");
					
					--ind;
					out.print(getIndent(ind));
					out.println("");
				}
				else
				{
					out.println("\"/>");
				}
			}
			
			--ind;
			out.print(getIndent(ind));
			out.println("");
		}
	}
	
	/**
	 *  Writes the provided services.
	 *  
	 *  @param out The output.
	 *  @param mmodel The BPMN model.
	 */
	protected static final void writeProvidedServices(PrintStream out, int ind, MBpmnModel mmodel)
	{
		ProvidedServiceInfo[] pss = mmodel.getModelInfo().getProvidedServices();
		if (pss != null && pss.length > 0)
		{
			out.print(getIndent(ind));
			out.println("");
			++ind;
			
			for (ProvidedServiceInfo ps : pss)
			{
				out.print(getIndent(ind));
				out.print(" 0)
					{
						out.print("\" class=\"");
						out.print(escapeString(implclass.getTypeName()));
					}
					
					String proxytype = ps.getImplementation().getProxytype();
					if (proxytype != null && proxytype.length() > 0)
					{
						out.print("\" proxytype=\"");
						out.print(escapeString(proxytype));
					}
					
					String impl = ps.getImplementation().getValue();
					if (impl != null && impl.length() > 0)
					{
						out.print("\" implementation=\"");
						out.print(escapeString(impl));
					}
				}
				
				out.println("\"/>");
			}
			
			--ind;
			out.print(getIndent(ind));
			out.println("");
		}
	}
	
	/**
	 *  Writes the required services.
	 *  
	 *  @param out The output.
	 *  @param mmodel The BPMN model.
	 */
	protected static final void writeRequiredServices(PrintStream out, int ind, MBpmnModel mmodel)
	{
		RequiredServiceInfo[] rss = mmodel.getModelInfo().getRequiredServices();
		if (rss != null && rss.length > 0)
		{
			out.print(getIndent(ind));
			out.println("");
			++ind;
			
			for (RequiredServiceInfo rs : rss)
			{
				out.print(getIndent(ind));
				out.print(" 0)
					{
						out.print("\" scope=\"");
						out.print(escapeString(scope));
					}
					
					boolean dyn = rs.getDefaultBinding().isDynamic();
					out.print("\" dynamic=\"");
					out.print(dyn);
				}
				
				out.println("\"/>");
			}
			
			--ind;
			out.print(getIndent(ind));
			out.println("");
		}
	}
	
	/**
	 *  Writes the configurations.
	 *  
	 *  @param out The output.
	 *  @param ind The indentation level.
	 *  @param configurations The configurations.
	 */
	protected static final void writeConfigurations(PrintStream out, int ind, MBpmnModel mmodel, ConfigurationInfo[] configurations)
	{
		if (configurations.length > 0)
		{
			List ctvs = mmodel.getContextVariables();
			Map> ctvconfexp = new HashMap>();
			for (MContextVariable ctv : ctvs)
			{
				for (int i = 0; i < configurations.length; ++i)
				{
					//UnparsedExpression cexp = mmodel.getContextVariableExpression(ctvname, configurations[i].getName());
					UnparsedExpression cexp = ctv.getConfigValue(configurations[i].getName());
					if (cexp != null && cexp.getValue() != null && cexp.getValue().length() > 0)
					{
						Map confctvs = ctvconfexp.get(configurations[i].getName());
						if (confctvs == null)
						{
							confctvs = new HashMap();
							ctvconfexp.put(configurations[i].getName(), confctvs);
						}
						confctvs.put(ctv.getName(), cexp.getValue());
					}
				}
			}
			
			out.print(getIndent(ind));
			out.println("");
			
			++ind;
			for (int i = 0; i < configurations.length; ++i)
			{
				ConfigurationInfo conf = configurations[i];
				
				out.print(getIndent(ind));
				out.print("");
				++ind;
				
				if (conf.getDescription() != null && conf.getDescription().length() > 0)
				{
					out.print(getIndent(ind));
					out.print("");
					out.print(escapeString(conf.getDescription()));
					out.println("");
				}
				
				String poollane = mmodel.getPoolLane(conf.getName());
				if (poollane != null && poollane.length() > 0)
				{
					out.print(getIndent(ind));
					out.print("");
					out.print(escapeString(poollane));
					out.println("");
				}
				
				if (conf.getArguments().length > 0 || conf.getResults().length > 0 || ctvconfexp.containsKey(conf.getName()))
				{
					UnparsedExpression[] args = conf.getArguments();
					if (args.length > 0)
					{
						out.print(getIndent(ind));
						out.println("");
						++ind;
						
						for (int j = 0; j < args.length; ++j)
						{
							if (args[j].getValue() != null && args[j].getValue().length() > 0)
							{
								out.print(getIndent(ind));
								out.print("");
								out.print(escapeString(args[j].getValue()));
								out.println("");
							}
						}
						
						--ind;
						out.print(getIndent(ind));
						out.println("");
					}
					
					UnparsedExpression[] res = conf.getResults();
					if (res.length > 0)
					{
						out.print(getIndent(ind));
						out.println("");
						++ind;
						
						for (int j = 0; j < res.length; ++j)
						{
							if (res[j].getValue() != null && res[j].getValue().length() > 0)
							{
								out.print(getIndent(ind));
								out.print("");
								out.print(escapeString(res[j].getValue()));
								out.println("");
							}
						}
						
						--ind;
						out.print(getIndent(ind));
						out.println("");
					}
					
					Map confctvmap = ctvconfexp.get(conf.getName());
					if (confctvmap != null && confctvmap.size() > 0)
					{
						out.print(getIndent(ind));
						out.println("");
						++ind;
						
						for (Map.Entry entry : confctvmap.entrySet())
						{
							if (entry.getValue() != null && entry.getValue().length() > 0)
							{
								out.print(getIndent(ind));
								out.print("");
								out.print(escapeString(entry.getValue()));
								out.println("");
							}
						}
						
						--ind;
						out.print(getIndent(ind));
						out.println("");
					}
				}
				
				ProvidedServiceInfo[] pss = conf.getProvidedServices();
				if (pss != null && pss.length > 0)
				{
					out.print(getIndent(ind));
					out.println("");
					++ind;
					
					for (ProvidedServiceInfo ps : pss)
					{
						if (ps.getImplementation() != null)
						{
							out.print(getIndent(ind));
							out.print(" 0)
							{
								out.print("\" class=\"");
								out.print(escapeString(ps.getImplementation().getClazz().getTypeName()));
							}
							
							if (ps.getImplementation().getProxytype() != null && ps.getImplementation().getProxytype().length() > 0)
							{
								out.print("\" proxytype=\"");
								out.print(escapeString(ps.getImplementation().getProxytype()));
							}
							
							if (ps.getImplementation().getValue() != null && ps.getImplementation().getValue().length() > 0)
							{
								out.print("\" implementation=\"");
								out.print(escapeString(ps.getImplementation().getValue()));
							}
							
							out.println("\"/>");
						}
					}
					
					--ind;
					out.print(getIndent(ind));
					out.println("");
				}
				
				RequiredServiceInfo[] rss = conf.getRequiredServices();
				if (rss != null && rss.length > 0)
				{
					out.print(getIndent(ind));
					out.println("");
					++ind;
					
					for (RequiredServiceInfo rs : rss)
					{
						if (rs.getDefaultBinding() != null)
						{
							out.print(getIndent(ind));
							out.print(" 0)
							{
								out.print("\" scope=\"");
								out.print(escapeString(rs.getDefaultBinding().getScope()));
							}
							
							out.println("\"/>");
						}
					}
					
					--ind;
					out.print(getIndent(ind));
					out.println("");
				}
				
				--ind;
				out.print(getIndent(ind));
				out.println("");
			}
			--ind;
			
			out.print(getIndent(ind));
			out.println("");
		}
	}
	
	/**
	 *  Writes the pools of the semantics sections.
	 *  
	 *  @param out The output.
	 *  @param ind The indentation level.
	 *  @param pools The pools.
	 */
	protected static final void writePoolSemantics(PrintStream out, int ind, List pools)
	{
		if (pools != null && pools.size() > 0)
		{
			for (MPool pool : pools)
			{
				out.print(getIndent(ind) + "");
				++ind;
				
				List lanes = pool.getLanes();
				if (lanes != null && lanes.size() > 0)
				{
					writeLaneSemantics(out, ind, lanes);
				}
				
				List activities = getPoolActivities(pool);
				
				List seqedges = new ArrayList();
				List medges = new ArrayList();
				List dataedges = new ArrayList();
				writeActivitySemantics(out, activities, null, ind, seqedges, medges, dataedges);
				
				writeSequenceEdgeSemantics(out, seqedges, ind);
				writeMessagingEdgeSemantics(out, medges, ind);
				writePoolExtensions(out, ind, dataedges);
				
				--ind;
				out.println(getIndent(ind) + "");
			}
		}
	}
	
	/**
	 *  Writes the pools of the collaboration sections.
	 *  
	 *  @param out The output.
	 *  @param pools The pools.
	 */
//	protected static final void writePoolCollaborations(PrintStream out, List pools)
//	{
//		out.println(getIndent(1) + "");
//		for (MPool pool : pools)
//		{
//			out.print(getIndent(2) + "");
//		}
//		out.println(getIndent(1) + "");
//	}
	
	/**
	 *  Writes the pool extension elements (e.g. data edges).
	 *  
	 *  @param out The output.
	 *  @param ind The indentation level.
	 *  @param seqedges The sequence edges.
	 */
	protected static final void writePoolExtensions(PrintStream out, int ind, List dataedges)
	{
		out.println(getIndent(ind) + "");
		++ind;
		for (MDataEdge dedge : dataedges)
		{
			out.print(getIndent(ind));
			out.print(" 0)
			{
				out.print("name=\"");
				out.print(escapeString(dedge.getName()));
				out.print("\" ");
			}
			out.print("id=\"");
			out.print(escapeString(dedge.getId()));
			out.print("\" sourceRef=\"");
			out.print(escapeString(dedge.getSource().getId()));
			out.print("\" sourceParam=\"");
			out.print(escapeString(dedge.getSourceParameter()));
			out.print("\" targetRef=\"");
			out.print(escapeString(dedge.getTarget().getId()));
			out.print("\" targetParam=\"");
			out.print(escapeString(dedge.getTargetParameter()));
			
			if (dedge.getParameterMapping() != null &&
				dedge.getParameterMapping().getValue() != null &&
				dedge.getParameterMapping().getValue().length() > 0)
			{
				out.println("\">");
				++ind;
				out.print(getIndent(ind));
				out.print("");
				out.print(escapeString(dedge.getParameterMapping().getValue()));
				out.println("");
				--ind;
				out.print(getIndent(ind));
				out.println("");
			}
			else
			{
				out.println("\"/>");
			}
		}
		--ind;
		out.println(getIndent(ind) + "");
	}
	
	/**
	 *  Writes the lanes of the semantics sections.
	 *  
	 *  @param out The output.
	 *  @param ind The indentation level.
	 *  @param lanes The lanes.
	 */
	protected static final void writeLaneSemantics(PrintStream out, int ind, List lanes)
	{
		out.println(getIndent(ind) + "");
		++ind;
		
		//TODO: Child lane sets
		
		for (MLane lane : lanes)
		{
			out.print(getIndent(ind) + "");
			++ind;
			
			// Write activity references
			List activities = lane.getActivities();
			for (MActivity activity : activities)
			{
				out.print(getIndent(ind) + "");
				out.print(escapeString(activity.getId()));
				out.println("");
			}
			
			--ind;
			out.println(getIndent(ind) + "");
		}
		
		--ind;
		out.println(getIndent(ind) + "");
	}
	
	/**
	 *  Writes the activities of the semantics sections.
	 *  
	 *  @param out The output.
	 *  @param activities The activities.
	 */
	protected static final void writeActivitySemantics(PrintStream out, List activities, String evthandlerref, int baseind, List seqedges, List medges, List dataedges)
	{
		for(MActivity activity : activities)
		{
			// As activities are also contained in the pool in the old bpmn model
			if(activity.isEventHandler() && evthandlerref==null)
				continue; 
			
			if (activity.getOutgoingDataEdges() != null)
			{
				dataedges.addAll(activity.getOutgoingDataEdges());
			}
			
			if (activity.getOutgoingSequenceEdges() != null)
			{
				seqedges.addAll(activity.getOutgoingSequenceEdges());
			}
			
			if (activity.getOutgoingMessagingEdges() != null)
			{
				medges.addAll(activity.getOutgoingMessagingEdges());
			}
			
			out.print(getIndent(baseind) + " 0)
			{
				out.print(" name=\"");
				out.print(escapeString(activity.getName()));
				out.print("\"");
			}
			out.print(" id=\"");
			out.print(activity.getId());
			
			List edges = activity.getOutgoingSequenceEdges();
			if (edges != null)
			{
				for (MSequenceEdge edge : edges)
				{
					if (edge.isDefault())
					{
						out.print("\" default=\"");
						out.print(escapeString(edge.getId()));
						break;
					}
				}
			}
			
			if(activity.isEventHandler())
			{
				out.print("\" attachedToRef=\"");
				out.print(escapeString(evthandlerref));
			}
			
			out.println("\">");
			
			edges = activity.getIncomingSequenceEdges();
			if (edges != null)
			{
				for (MSequenceEdge edge : edges)
				{
					out.print(getIndent(baseind + 1) + "");
					out.print(escapeString(edge.getId()));
					out.println("");
				}
			}
			
			edges = activity.getOutgoingSequenceEdges();
			if (edges != null)
			{
				for (MSequenceEdge edge : edges)
				{
					out.print(getIndent(baseind + 1) + "");
					out.print(escapeString(edge.getId()));
					out.println("");
				}
			}
			
			if (event)
			{
				if (activity.getActivityType().contains("Message"))
				{
					out.print(getIndent(baseind + 1));
					out.println("");
				}
				else if (activity.getActivityType().contains("Timer"))
				{
					out.print(getIndent(baseind + 1));
					out.print(" 0)
					{
						out.println(">");
						out.print(getIndent(baseind + 2));
						out.print("");
						out.print(escapeString(((UnparsedExpression) activity.getPropertyValue("duration")).getValue()));
						out.println("");
						out.print(getIndent(baseind + 1));
						out.println("");
					}
					else
					{
						out.println("/>");
					}
				}
				else if (activity.getActivityType().contains("Rule"))
				{
					out.print(getIndent(baseind + 1));
					out.println("");
				}
				else if (activity.getActivityType().contains("Signal"))
				{
					out.print(getIndent(baseind + 1));
					out.println("");
				}
				else if (activity.getActivityType().contains("Error"))
				{
					out.print(getIndent(baseind + 1));
					out.println("");
				}
				else if (activity.getActivityType().contains("Compensation"))
				{
					out.println("");
				}
				else if (activity.getActivityType().contains("Cancel"))
				{
					out.print(getIndent(baseind + 1));
					out.println("");
				}
				else if (activity.getActivityType().contains("Terminate"))
				{
					out.print(getIndent(baseind + 1));
					out.println("");
				}
				else if (activity.getActivityType().contains("Multipl"))
				{
					out.print(getIndent(baseind + 1));
					out.println("");
				}
			}
			
			boolean issubproc = MBpmnModel.SUBPROCESS.equals(activity.getActivityType());
			String procref = null;
			boolean isprocrefexp = false;
			if (issubproc)
			{
				MSubProcess subproc = (MSubProcess) activity;
				if (subproc.hasPropertyValue("file"))
				{
					UnparsedExpression fileexp = (UnparsedExpression) subproc.getPropertyValue("file"); 
					procref = fileexp.getValue();
					isprocrefexp = true;
				}
				else if (subproc.hasPropertyValue("filename"))
				{
					procref = subproc.getPropertyValue("filename").getValue();
					if (procref != null && procref.length() >= 2)
					{
						procref = procref.substring(1);
						procref = procref.substring(0, procref.length() - 1);
					}
				}
				else
				{
					List subactivities = subproc.getActivities();
					if (subactivities != null && subactivities.size() > 0)
					{
						writeActivitySemantics(out, subactivities, null, baseind + 1, seqedges, medges, dataedges);
					}
					
//					List subseqedges = subproc.getSequenceEdges();
//					if (subseqedges != null && subseqedges.size() > 0)
//					{
//						writeSequenceEdgeSemantics(out, subseqedges, baseind + 1);
//					}
				}
			}
			
			boolean istask = MBpmnModel.TASK.equals(activity.getActivityType()) || issubproc;
			boolean hasclass = activity.getClazz()!=null && activity.getClazz().getTypeName() != null && activity.getClazz().getTypeName().length() > 0;
			boolean hastaskparams = istask && activity.getParameters()!=null && activity.getParameters().size()>0;
			boolean hasprops = activity.getProperties()!=null && activity.getProperties().size()>0;
			
			if(hasclass || hastaskparams || hasprops || procref != null)
			{
				out.println(getIndent(baseind + 1) + "");
				
				if(hasclass)
				{
					out.print(getIndent(baseind + 2) + "");
					out.print(escapeString(activity.getClazz().getTypeName()));
					out.println("");
				}
				
				if(hastaskparams)
				{
					IndexMap params = activity.getParameters();
					for (String key: params.keySet())
					{
						MParameter param = params.get(key);
						out.print(getIndent(baseind + 2) + " 0)
						{
							out.print(">");
							out.print(escapeString(inival));
							out.println("");
						}
						else
						{
							out.println("/>");
						}
					}
				}
				
				if(hasprops)
				{
					IndexMap props = activity.getProperties();
					for(String key: props.keySet())
					{
						MProperty prop = props.get(key);
						out.print(getIndent(baseind + 2) + " 0)
						{
							out.print(">");
							out.print(escapeString(inival));
							out.println("");
						}
						else
						{
							out.println("/>");
						}
					}
				}
				
				if(procref != null)
				{
					String tagpart = "jadex:subprocessref>";
					if (isprocrefexp)
					{
						tagpart = "jadex:subprocessexpressionref>";
					}
					out.print(getIndent(baseind + 2) + "<" + tagpart);
					out.print(escapeString(procref));
					out.println("");
			}
			
			out.print(getIndent(baseind) + "");
			
			if (activity.getEventHandlers() != null && activity.getEventHandlers().size() > 0)
			{
				writeActivitySemantics(out, activity.getEventHandlers(), activity.getId(), baseind, seqedges, medges, dataedges);
			}
		}
	}
	
	/**
	 *  Writes the sequence edges of the semantics sections.
	 *  
	 *  @param out The output.
	 *  @param seqedges The sequence edges.
	 */
	protected static final void writeSequenceEdgeSemantics(PrintStream out, List seqedges, int baseind)
	{
		for (MSequenceEdge edge : seqedges)
		{
			out.print(getIndent(baseind) + " 0)
			{
				out.print("name=\"");
				out.print(escapeString(edge.getName()));
				out.print("\" ");
			}
			out.print("sourceRef=\"");
			out.print(escapeString(edge.getSource().getId()));
			out.print("\" targetRef=\"");
			out.print(escapeString(edge.getTarget().getId()));
			out.print("\" id=\"");
			out.print(escapeString(edge.getId()));
			out.println("\">");
			
			if (edge.getCondition() != null)
			{
				String cond = edge.getCondition().getValue();
				if (cond != null && cond.length() > 0)
				{
					out.print(getIndent(baseind + 1) + "");
					out.print(escapeString(cond));
					out.println("");
				}
			}
			
//			Map> mappings = edge.getParameterMappings();
			IndexMap> mappings = edge.getParameterMappings();
			if(mappings != null && mappings.size() > 0)
			{
				out.println(getIndent(baseind + 1) + "");
				
				for(Object key: mappings.keySet())
				{
					out.print(getIndent(baseind + 2) + "");
					out.print(escapeString(((Tuple2)mappings.get(key)).getFirstEntity().getValue()));
					out.println("");
				}
				
				out.println(getIndent(baseind + 1) + "");
			}
			
			out.println(getIndent(baseind) + "");
		}
	}
	
	/**
	 *  Writes the messaging edges of the semantics sections.
	 *  
	 *  @param out The output.
	 *  @param seqedges The messaging edges.
	 */
	protected static final void writeMessagingEdgeSemantics(PrintStream out, List medges, int baseind)
	{
		for (MMessagingEdge edge : medges)
		{
			out.print(getIndent(baseind) + " 0)
			{
				out.print("name=\"");
				out.print(escapeString(edge.getName()));
				out.print("\" ");
			}
			out.print("sourceRef=\"");
			out.print(escapeString(edge.getSource().getId()));
			out.print("\" targetRef=\"");
			out.print(escapeString(edge.getTarget().getId()));
			out.print("\" id=\"");
			out.print(escapeString(edge.getId()));
			out.println("\">");
			
			out.println(getIndent(baseind) + "");
		}
	}
	
	/**
	 *  Gets all activities in a pool.
	 *  TODO: Support nested lanes.
	 *  
	 *  @param pool The pool.
	 *  @return The contained activities.
	 */
	public static final List getPoolActivities(MPool pool)
	{
		List ret = new ArrayList();
		if (pool.getActivities() != null && pool.getActivities().size() > 0)
		{
			ret.addAll(pool.getActivities());
		}
		
		List lanes = pool.getLanes();
		if (lanes != null)
		{
			for (MLane lane : lanes)
			{
				if (lane.getActivities() != null && lane.getActivities().size() > 0)
				{
					ret.addAll(lane.getActivities());
				}
			}
		}
		
		return ret;
	}
	
	/**
	 *  Generates indentation.
	 *  
	 *  @param num The indentation number.
	 *  @return Indentation string.
	 */
	public static final String getIndent(int num)
	{
		StringBuilder sb = new StringBuilder();
		while (num-- > 0)
		{
			sb.append(INDENT_STRING);
		}
		return sb.toString();
	}
	
	/** Carriage return. */
	private static final String CR = makeCharStringTrustMeJava(13);
	
	/** Line feed. */
	private static final String LF = makeCharStringTrustMeJava(10);
	
	/**
	 *  Escapes strings for xml.
	 */
	private static final String escapeString(String string)
	{
//		if(string==null)
//			System.out.println("nullnull");
		string = string.replace("&", "&");
		string = string.replace("\"", """);
		string = string.replace("'", "'");
		string = string.replace("<", "<");
		string = string.replace(">", ">");
		string = string.replace("\\", "\\\\");
		string = string.replace(CR + LF, LF);
		string = string.replace(CR + CR, LF);
		string = string.replace(CR, LF);
		string = string.replace(LF, "\\n");
		string = string.replace("\n", "\\n");
		return string;
	}
	
	/**
	 *  Helper method to override stupid Java checks.
	 */
	private static final String makeCharStringTrustMeJava(int num)
	{
		String ret = null;
		try
		{
			ret = new String(new byte[] { (byte) num }, "UTF-8");
		}
		catch(Exception e)
		{
		}
		return ret;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy