⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 javasrcmodeldigester.java

📁 一个java写的business process management系统
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright (c) 2003-2004, Alexander Greif
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Flow4J-Eclipse project nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

package net.orthanc.flow4j.model.codegen.javasrc;

import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import net.orthanc.flow4j.Flow4JException;
import net.orthanc.flow4j.base.IOUtils;
import net.orthanc.flow4j.base.PrettyPrinterUtils;
import net.orthanc.flow4j.base.Util;
import net.orthanc.flow4j.bsf.BSFEngineDescriptor;
import net.orthanc.flow4j.bsf.Flow4JBSFManager;
import net.orthanc.flow4j.model.FlowStructureModelDigester;
import net.orthanc.flow4j.model.IFlowVisitor;
import net.orthanc.flow4j.model.bind.BindingHandler;
import net.orthanc.flow4j.model.bind.CallFlowletBind;
import net.orthanc.flow4j.model.bind.DecisionFlowletBind;
import net.orthanc.flow4j.model.bind.EndFlowletBind;
import net.orthanc.flow4j.model.bind.FlowModelBind;
import net.orthanc.flow4j.model.bind.IFlowletBind;
import net.orthanc.flow4j.model.bind.IPropertyHolderBind;
import net.orthanc.flow4j.model.bind.JavaTaskFlowletBind;
import net.orthanc.flow4j.model.bind.JoinFlowletBind;
import net.orthanc.flow4j.model.bind.JumpFlowletBind;
import net.orthanc.flow4j.model.bind.PropertyBind;
import net.orthanc.flow4j.model.bind.ScriptTaskFlowletBind;
import net.orthanc.flow4j.model.bind.StartFlowletBind;
import net.orthanc.flow4j.model.bind.TemplateFlowletBind;
import net.orthanc.flow4j.model.codegen.javasrc.structure.CatchBlock;
import net.orthanc.flow4j.model.codegen.javasrc.structure.CodeBlock;
import net.orthanc.flow4j.model.codegen.javasrc.structure.Field;
import net.orthanc.flow4j.model.codegen.javasrc.structure.IfThenElse;
import net.orthanc.flow4j.model.codegen.javasrc.structure.JavaFile;
import net.orthanc.flow4j.model.codegen.javasrc.structure.JavadocBlock;
import net.orthanc.flow4j.model.codegen.javasrc.structure.Method;
import net.orthanc.flow4j.model.codegen.javasrc.structure.MethodParameter;
import net.orthanc.flow4j.model.codegen.javasrc.structure.TryCatch;
import net.orthanc.flow4j.model.codegen.structure.CodeLine;
import net.orthanc.flow4j.runtime.Flow4JRuntimeConsts;
import net.orthanc.flow4j.runtime.ITaskFlowlet;
import net.orthanc.flow4j.runtime.descriptors.TaskParameterDescriptor;
import net.orthanc.flow4j.runtime.descriptors.TaskParameterDescriptors;
import net.orthanc.flow4j.runtime.descriptors.TaskPropertyDescriptor;
import net.orthanc.flow4j.runtime.descriptors.TaskPropertyDescriptors;

import org.acm.seguin.util.FileSettings;

/**
 * @author greifa
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class JavaSrcModelDigester extends FlowStructureModelDigester {

	public static final String PRETTY_SETTINGS_FILENAME = "pretty.settings";
	private static final String FLOW4J_XDOCLET_PREFIX = "flow4j.";


	private static FileSettings prettySettings;
	private File scriptRootFolder;
	private JavaFile javaFile;
	private FlowModelBind flowModelBind;
	private ClassLoader taskClassLoader;
	//private String flowName;
	private boolean bsfNeeded;
	//private Set scriptLanguageNames;
	private static DecisionStatementCompletion decisionStmntCompl
					= new DecisionStatementCompletion();


	/**
	 * Crates this Digester and also a JavaClass instance
	 * @param className the name of the class
	 * @param packageName the package name or null if the default package
	 */
	private JavaSrcModelDigester(String className, String packageName, File scriptRootFolder) {
		super();
		javaFile = new JavaFile();
		javaFile.getJavaClass().setClassName(className);
		javaFile.setPackageName(packageName);
		javaFile.addImport("net.orthanc.flow4j.runtime.*");
		javaFile.getJavaClass().setJavadoc(new JavadocBlock());
		this.scriptRootFolder = scriptRootFolder;
	}


	/**
	 * Loads the pretty printer settings.
	 * If the specified file is <code>null</code> then nothing happens.
	 * @param settingsFile
	 */
	static public void setPrettySettings(FileSettings prettySettings) {
		JavaSrcModelDigester.prettySettings = prettySettings;
	}

	/**
	 * 	Used by the FlowRepository builder
	 * @return
	 */
	public static FileSettings getPrettySettings() {
		return prettySettings;
	}




	/**
	 * Generates the flow's java source code and stores it in the output file
	 * @param flowFile
	 * @param packagePath
	 * @param destDir
	 * @param scriptRootFolder
	 * @throws IOException
	 * @throws MappingException
	 * @throws MarshalException
	 * @throws ValidationException
	 */
	public static void generateCode(File flowFile, String packagePath, File destDir, File scriptRootFolder)
		throws IOException {
			
		//	generate java surce code
		InputStream javaSrcIn = generateCode(flowFile, packagePath, scriptRootFolder);
		File outputFolder = new File(destDir, packagePath.replace('.', File.separatorChar));
		String fileName = flowFile.getName();
		fileName = fileName.substring(0, fileName.lastIndexOf(".")+1) + Consts.FILE_EXTENSION_JAVA;
		File outputFile = new File(outputFolder, fileName);
		OutputStream javaSrcOut = new FileOutputStream(outputFile);
		IOUtils.copyBufferedStream(javaSrcIn, javaSrcOut);
		javaSrcIn.close();
		javaSrcOut.close();
	}



	/**
	 * Returns a stream on the generated java source code.
	 * Creates an instancce of this class that builds the JavaClass object.
	 * Then the JavaClass object is serialized and a stream to the source
	 * code is returned
	 * @param flowFile
	 * @param packagePath
	 * @param scriptRootFolder
	 * @return a stream on the generated java source code.
	 * @throws IOException
	 * @throws MappingException
	 * @throws MarshalException
	 * @throws ValidationException
	 */
	private static InputStream generateCode(File flowFile, String packagePath, File scriptRootFolder)
		throws IOException {
		return generateCode(
			flowFile,
			packagePath,
			scriptRootFolder,
			new String().getClass().getClassLoader());
	}











	/**
	 * Returns a stream on the generated java source code.
	 * Creates an instancce of this class that builds the JavaClass object.
	 * Then the JavaClass object is serialized and a stream to the source
	 * code is returned
	 * @param flowFile
	 * @param packagePath
	 * @param taskClassLoader
	 * @return a stream on the generated java source code.
	 * @throws IOException
	 * @throws MappingException
	 * @throws MarshalException
	 * @throws ValidationException
	 */
	public static InputStream generateCode(
		File flowFile,
		String packagePath,
		File scriptRootFolder,
		ClassLoader taskClassLoader)
		throws IOException {
			
		String fileName = flowFile.getName();
		String className = fileName.substring(0, fileName.lastIndexOf("."));
		FlowModelBind flowModelBind = BindingHandler.getInstance().loadFlowModel(flowFile, taskClassLoader);
		JavaSrcModelDigester digester =
			new JavaSrcModelDigester(className, packagePath, scriptRootFolder);
		digester.taskClassLoader = taskClassLoader;
		//	digest all parts of the flow model
		digester.digest(flowModelBind);
		//	generate the java class
		digester.generateClassSrc(flowModelBind);
		//	serialize sources
		StringWriter stringWriter = new StringWriter();
		BufferedWriter writer = new BufferedWriter(stringWriter);
		digester.serialize(writer);
		writer.close();
		String source = stringWriter.toString();
		//	pretty print sources
		try {
			if (prettySettings != null)
			source = PrettyPrinterUtils.prettyPrintSource(source);
		} catch(Throwable e) {
			e.printStackTrace();
		}
		return new ByteArrayInputStream(source.getBytes());
	}






	/**
	 * Generates the class's source, all fields and methods.
	 */
	public void generateClassSrc(FlowModelBind flowModelBind) {
		javaFile.getJavaClass().addModifier(Consts.MODIFIER_PUBLIC);
		javaFile.getJavaClass().addModifier(Consts.MODIFIER_FINAL);
		javaFile.getJavaClass().addInterface("IFlow");
		
		//	generate getStartFlowlets() method and the corresponding code
		generateGetStartFlowletsBlock(flowModelBind);
		//	generate execute() method
		generateExecuteMethodSrc(flowModelBind);
		//	generate the class's javadoc
		generateClassJavadoc();
		//	generate BSF Manager
		//generateBSFComponents();
	}


	private void generateGetStartFlowletsBlock(FlowModelBind flowModelBind) {
		String startFlowletsVarName = "startFlowlets";
		Field startFlowletsField = new Field(startFlowletsVarName);
		startFlowletsField.addModifier(Consts.MODIFIER_PRIVATE);
		startFlowletsField.addModifier(Consts.MODIFIER_STATIC);
		startFlowletsField.setType("StartFlowlet[]");
		startFlowletsField.setValue("new StartFlowlet[" + getStartFlowletNodes().size() + "]");
		javaFile.getJavaClass().addField(startFlowletsField);
		
		CodeBlock staticInitializer = javaFile.getJavaClass().getStaticInitializer();

		//	visit all start flowlets
		int counter = 0;
		for (Iterator iter = getStartFlowletNodes().iterator(); iter.hasNext(); counter++) {
			IFlowNode startFlowletNode = (IFlowNode)iter.next();
			StartFlowletBind flowletBind = (StartFlowletBind)((AbstractFlowletNode)startFlowletNode).getFlowletBind();
			String labelText = flowletBind.getLabel().getText();
			
			String variableName = flowletBind.getId(flowModelBind) + "_" + labelText;
			staticInitializer.addFragment(new CodeLine("StartFlowlet " + variableName + " = new StartFlowlet(\"" + labelText + "\");"));
			staticInitializer.addFragment(new CodeLine(startFlowletsVarName + "[" + counter + "] = " + variableName + ";"));
			//	here comes the code that adds properties
			generatePropertySetterCalls(flowletBind, staticInitializer, variableName);
		}
		
		//	the interfaces getter method
		Method getStartFlowletsMethod = new Method("getStartFlowlets");
		javaFile.getJavaClass().addMethod(getStartFlowletsMethod);
		getStartFlowletsMethod.addModifier(Consts.MODIFIER_PUBLIC);
		getStartFlowletsMethod.addModifier(Consts.MODIFIER_FINAL);
		getStartFlowletsMethod.setReturnType("StartFlowlet[]");
		getStartFlowletsMethod.addToCodeBlock(new CodeLine("return " + startFlowletsVarName + ";"));
	}





	/**
	 * Generates the source code of the flow's <code>execute()</code> method
	 */
	private void generateExecuteMethodSrc(FlowModelBind flowModelBind) {
		Method executeMethod = new Method("execute");
		executeMethod.addModifier(Consts.MODIFIER_PUBLIC);
		executeMethod.addModifier(Consts.MODIFIER_FINAL);
		executeMethod.addMethodParameter(new MethodParameter("String", "startFlowletName"));
		executeMethod.addMethodParameter(new MethodParameter("FlowDictionary", "dictionary"));
		javaFile.getJavaClass().addMethod(executeMethod);
		
		IFlowVisitor visitor = new JavaSrcVisitor(executeMethod.getCodeBlock());
		//	visit all start flowlets
		for (Iterator iter = getStartFlowletNodes().iterator(); iter.hasNext();) {
			IFlowNode startFlowletNode = (IFlowNode)iter.next();

			IfThenElse ifThenElse = new IfThenElse();
			((JavaSrcVisitor)visitor).getCodeBlock().addFragment(ifThenElse);
			StartFlowletBind flowletBind = (StartFlowletBind)((AbstractFlowletNode)startFlowletNode).getFlowletBind();
			String labelText = flowletBind.getLabel().getText();
			String methodName = flowletBind.getId(flowModelBind) + "_" + labelText;
		
			ifThenElse.setBooleanStatement("\"" + labelText + "\".equals(startFlowletName)");
			ifThenElse.addTrueFragment(new CodeLine("\t" + methodName + "(dictionary);"));
			((JavaSrcVisitor)visitor).setCodeBlock(ifThenElse.getTrueBlock());
			//	visit others
			startFlowletNode.visit(visitor);
			((JavaSrcVisitor)visitor).setCodeBlock(ifThenElse.getFalseBlock());
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -