📄 .#flowrepositorybuilder.java.1.3
字号:
/*
* Copyright (c) 2003, 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.designer.builder;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.orthanc.flow4j.base.PrettyPrinterUtils;
import net.orthanc.flow4j.designer.Flow4JDesignerException;
import net.orthanc.flow4j.designer.core.Flow4JPlugin;
import net.orthanc.flow4j.designer.core.Flow4JProject;
import net.orthanc.flow4j.model.codegen.javasrc.Consts;
import net.orthanc.flow4j.model.codegen.javasrc.structure.JavaClass;
import net.orthanc.flow4j.model.codegen.javasrc.structure.JavaFile;
import net.orthanc.flow4j.model.codegen.javasrc.structure.Method;
import net.orthanc.flow4j.model.codegen.structure.CodeLine;
import org.acm.seguin.util.FileSettings;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
/**
* Builds the class that implements <code>IFlowRepository</code> and
* contains the code to register all flows in the project.
* @author agreif
*/
public class FlowRepositoryBuilder extends IncrementalProjectBuilder {
/**
* Always returns <code>null</code>
* @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
*/
protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
throws CoreException {
try {
monitor.subTask("Build flow repository");
IProject project = getProject();
if (!isBuildableProject(project))
return null;
Flow4JProject flow4jProject =
Flow4JPlugin.getFlow4JProject(project);
String flowRepositoryClasspath =
flow4jProject.getFlowReposClassPath();
FileDesc packageFolderDesc;
try {
// get the folder where the class file should be stored
packageFolderDesc =
getSourceFolder(project, flowRepositoryClasspath);
if (packageFolderDesc == null)
return null;
} catch (Flow4JDesignerException e) {
throw e;
} catch (Exception e) {
Flow4JPlugin.log(e);
return null;
}
List flowClassPaths = new ArrayList();
// collect the paths of the project's flow files
getFlowClassPaths(project, flowClassPaths);
try {
// generate source file
buildFlowRepository(
//folder.getProjectRelativePath().append(
// getClassName(flowRepositoryClasspath)),
packageFolderDesc,
getPackagePath(flowRepositoryClasspath).replace('/', '.'),
getClassName(flowRepositoryClasspath),
flowClassPaths,
monitor);
} catch (Exception e) {
Flow4JPlugin.log(e);
}
} finally {
monitor.done();
}
return null;
}
/**
* Returns the folder in which the FlowRepsoitory class should
* be stored.
* If the package of the class exists in one of the project's source folders
* then the package folder is returned.
* Otherwise the package folder in the project's <strong>first</strong>
* source folder is returned.
* @param project the project
* @param flowRepositoryClasspath the fully qualified class path of the Flow repository class
* @return the folder in which the FlowRepsoitory class should be stored.
* @throws JavaModelException
* @throws CoreException
* @throws Flow4JDesignerException
*/
private FileDesc getSourceFolder(
IProject project,
String flowRepositoryClasspath)
throws JavaModelException, CoreException, Flow4JDesignerException {
if (flowRepositoryClasspath == null
|| flowRepositoryClasspath.trim().length() == 0)
throw new Flow4JDesignerException("No flow repository class path specified");
IPath[] sourceFolderPaths =
Flow4JPlugin.getClasspathSourceFolders(project);
if (sourceFolderPaths == null || sourceFolderPaths.length == 0)
return null;
int pos = flowRepositoryClasspath.lastIndexOf(".");
if (pos == -1)
return new FileDesc(
Flow4JPlugin.getWorkspaceRoot().getFolder(sourceFolderPaths[0]),
null);
IJavaProject javaProject = Flow4JPlugin.getJavaProject(project);
IPath packagePath = new Path(getPackagePath(flowRepositoryClasspath));
for (int i = 0; i < sourceFolderPaths.length; i++) {
IPath path = sourceFolderPaths[i].append(packagePath);
IFolder folder = Flow4JPlugin.getWorkspaceRoot().getFolder(path);
if (folder.exists())
return new FileDesc(
Flow4JPlugin.getWorkspaceRoot().getFolder(
sourceFolderPaths[i]),
packagePath);
}
return new FileDesc(
Flow4JPlugin.getWorkspaceRoot().getFolder(sourceFolderPaths[0]),
packagePath);
}
private String getPackagePath(String classpath) {
int pos = classpath.lastIndexOf(".");
if (pos == -1)
return "";
return classpath.substring(0, pos).replace('.', '/');
}
private String getClassName(String classpath) {
int pos = classpath.lastIndexOf(".");
if (pos == -1)
return classpath;
return classpath.substring(pos + 1);
}
/**
* Collects the <code>IPath</code> objects of the flow files in the given project.
* @param project the folder in which to look for flow files
* @param flowClassNames the container to collect the paths objects to
*/
private void getFlowClassPaths(IProject project, List flowClassPaths)
throws JavaModelException {
IPath[] sourceFolderPaths =
Flow4JPlugin.getClasspathSourceFolders(project);
List list = new ArrayList();
for (int i = 0; i < sourceFolderPaths.length; i++) {
IPath folderPath = sourceFolderPaths[i];
IFolder folder =
Flow4JPlugin.getWorkspaceRoot().getFolder(folderPath);
if (folder.exists())
getFlowClassPaths(folder, list);
// strip
for (Iterator iter = list.iterator(); iter.hasNext();) {
IPath path = (IPath) iter.next();
path = path.removeFirstSegments(folderPath.segmentCount() - 1);
flowClassPaths.add(path);
}
list.clear();
}
}
/**
* Collects the <code>IPath</code> objects of the flow files in the given folder.
* Recurses into subfolders
* @param folder the folder in which to look for flow files
* @param flowClassNames the container to collect the paths objects to
*/
private void getFlowClassPaths(IFolder folder, List flowClassPaths) {
try {
IResource[] members = folder.members();
for (int i = 0; i < members.length; i++) {
IResource resource = members[i];
if (resource.getType() == IResource.FILE
&& Flow4JPlugin.isFlowFile((IFile) resource)) {
flowClassPaths.add(
((IFile) resource)
.getFullPath()
.removeFirstSegments(1)
.removeTrailingSeparator()
.removeFileExtension());
} else if (resource.getType() == IResource.FOLDER) {
getFlowClassPaths((IFolder) resource, flowClassPaths);
}
}
} catch (CoreException e) {
Flow4JPlugin.log(e);
}
}
/**
* Creates the flow repository java source file in the given output path.
* The file name begins with the project name and ends with "FlowRepository".
* @param outputPath the path where the sources should be written
* @param packageName the name of the package
* @param className the name of the class
* @param flowClassPaths the <code>IPath</code> objects of the flows
* @param monitor the progress monitor
* @throws IOException if the file cannot be written
* @throws CoreException
*/
private void buildFlowRepository(
//IPath outputPath,
FileDesc packageFolderDesc,
String packageName,
String className,
List flowClassPaths,
IProgressMonitor monitor)
throws IOException, CoreException {
JavaFile repositoryFile = new JavaFile();
JavaClass repositoryClass = repositoryFile.getJavaClass();
repositoryClass.setClassName(className);
repositoryFile.setPackageName(packageName);
repositoryClass.addInterface(
"net.orthanc.flow4j.runtime.IFlowRepository");
repositoryClass.addModifier(Consts.MODIFIER_PUBLIC);
Method method = new Method("getFlowClasses");
repositoryClass.addMethod(method);
method.setReturnType("java.util.Collection");
method.addModifier(Consts.MODIFIER_PUBLIC);
method.addToCodeBlock(
new CodeLine("java.util.List classes = new java.util.ArrayList();"));
for (Iterator iter = flowClassPaths.iterator(); iter.hasNext();) {
IPath flowClassPath = (IPath) iter.next();
String classpathStr = flowClassPath.toString().replace('/', '.');
method.addToCodeBlock(
new CodeLine("classes.add(" + classpathStr + ".class);"));
}
method.addToCodeBlock(new CodeLine("return classes;"));
// serialize
StringWriter stringWriter = new StringWriter();
BufferedWriter writer = new BufferedWriter(stringWriter);
repositoryFile.serialize(writer);
writer.close();
String source = stringWriter.toString();
// pretty printer
FileSettings prettySettings = Flow4JPlugin.getPrettySettings();
if (prettySettings != null)
try {
source = PrettyPrinterUtils.prettyPrintSource(source);
} catch (Exception e) {
Flow4JPlugin.log(e);
}
InputStream in = new ByteArrayInputStream(source.getBytes());
// IFile outputFile =
// getProject().getFile(outputPath.addFileExtension("java"));
try {
IFolder packageFolder = packageFolderDesc.getFolder();
if (!packageFolder.exists())
// derived=true, means that resource is recreatable by build process
// and should not go into source control because the resource will change often
Flow4JPlugin.createFolder(
packageFolderDesc.getRoot(),
packageFolderDesc.getPath(),
false);
IFile outputFile =
packageFolder.getFile(
new Path(className).addFileExtension("java"));
if (!outputFile.exists()) {
outputFile.create(in, true, monitor);
outputFile.setDerived(true);
}
else
outputFile.setContents(in, true, true, monitor);
} finally {
try {
if (in != null)
in.close();
} catch (IOException e1) {
Flow4JPlugin.log(e1);
}
}
}
/**
* Returns whether the project is buildable by the FlowBuilder.
* @param project
* @return true if the FlowBuilder can build the given project
*/
static boolean isBuildableProject(IProject project) {
if (Flow4JPlugin.hasFlow4JNature(project))
return true;
return false;
}
private class FileDesc {
IContainer root;
IPath path;
FileDesc(IContainer root, IPath path) {
this.root = root;
this.path = path;
}
/**
* @return
*/
public IPath getPath() {
return path;
}
/**
* @return
*/
public IContainer getRoot() {
return root;
}
public IFolder getFolder() {
return root.getFolder(path);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -