Index: plugin.xml =================================================================== --- plugin.xml (revision 19929) +++ plugin.xml (working copy) @@ -334,6 +334,19 @@ class="org.eclipse.core.resources.IResource"> + + + A wizard that creates a jBPM action + + + + rawInterfaces = new HashSet(); + + // adapted data +// private IType superClassType; + private String superClassName; +// private IType interfaceType; +// private String interfaceName; + private String className; +// private String classArgs; + private String packageName; + private IPackageFragmentRoot packageFragmentRoot; + private IPackageFragment packageFragment; + private ArrayList interfaces = new ArrayList(); + + + private NewTypeWizardAdapter() {} + + // Interface for us + + public NewTypeWizardAdapter(IProject project) { + if(project != null) try { + this.javaProject = (IJavaProject)project.getNature(JavaCore.NATURE_ID); + } catch (CoreException e) { + Logger.logError(e); + } + this.project = project; + } + + public void setRawClassName(String rawClassName) { + this.rawData = Boolean.TRUE.booleanValue(); + this.className = rawClassName; + } + + public void setRawSuperClassName(String rawSuperClassName) { + this.rawData = Boolean.TRUE.booleanValue(); + this.superClassName = rawSuperClassName; + } + + public void setRawPackageName(String rawPackageName) { + this.rawData = Boolean.TRUE.booleanValue(); + this.packageName = rawPackageName; + } + + public void addRawInterfaceName(String rawInterfaceName) { + this.rawData = Boolean.TRUE.booleanValue(); + this.rawInterfaces.add(rawInterfaceName); + } + + public void setCanBeModified(boolean canBeModified) { + this.canBeModified = canBeModified; + } + + public void setCreateConstructors(boolean createConstructors) { + this.createConstructors = createConstructors; + } + + public void setCreateInherited(boolean createInherited) { + this.createInherited = createInherited; + } + + public void setCreateMain(boolean createMain) { + this.createMain = createMain; + } + + // doAdapted + + private void doAdapted() { + // source folder name, package name, class name + int loc = className.indexOf(":"); //$NON-NLS-1$ + if (loc != -1) { + if (loc < className.length()) { +// classArgs = className.substring(loc + 1, className.length()); + className = className.substring(0, loc); + } + if (loc > 0) + className = className.substring(0, loc); + else if (loc == 0) + className = ""; //$NON-NLS-1$ + } + classNameStatus = JavaConventions.validateJavaTypeName(className); + + loc = className.lastIndexOf('.'); + if (loc != -1) { + packageName = className.substring(0, loc); + className = className.substring(loc + 1); + packageNameStatus = JavaConventions.validatePackageName(packageName); + classNameStatus = JavaConventions.validateJavaTypeName(className); + } + if (javaProject == null) + return; + try { + if (packageFragmentRoot == null) { + IPackageFragmentRoot srcEntryDft = null; + IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots(); + for (int i = 0; i < roots.length; i++) { + if (roots[i].getKind() == IPackageFragmentRoot.K_SOURCE) { + srcEntryDft = roots[i]; + break; + } + } + if (srcEntryDft != null) + packageFragmentRoot = srcEntryDft; + else { + packageFragmentRoot = javaProject.getPackageFragmentRoot(javaProject.getResource()); + } + if (packageFragment == null + && packageFragmentRoot != null + && packageName != null + && packageName.length() > 0) { + IFolder packageFolder = project.getFolder(packageName); + packageFragment = packageFragmentRoot + .getPackageFragment(packageFolder + .getProjectRelativePath().toOSString()); + } + } + // superclass and interface + if (this.rawInterfaces != null && this.rawInterfaces.size()>0) { + Iterator i = this.rawInterfaces.iterator(); + this.interfaces.clear(); + while (i.hasNext()) { + String _interface = (String)i.next(); + // check interface name + this.interfaces.add(_interface); + } + } + if (this.superClassName !=null && this.superClassName.length()>0) { + // check super class + } + + rawData = Boolean.FALSE.booleanValue(); + } catch (JavaModelException e) { + Logger.logError(e); + } + } + +/* + private IType findTypeForName(String typeName) throws JavaModelException { + if (typeName == null || typeName.length() == 0) + return null; + IType type = null; + String fileName = typeName.replace('.', '/') + ".java"; //$NON-NLS-1$ + IJavaElement element = javaProject.findElement(new Path(fileName)); + if (element == null) + return null; + if (element instanceof IClassFile) { + type = ((IClassFile) element).getType(); + } else if (element instanceof ICompilationUnit) { + IType[] types = ((ICompilationUnit) element).getTypes(); + type = types[0]; + } + return type; + } +*/ + + // Interface for NewClassWizardPage + + public IPackageFragmentRoot getPackageFragmentRoot() { + if (rawData) doAdapted(); + return this.packageFragmentRoot; + } + + public IPackageFragment getPackageFragment() { + if (rawData) doAdapted(); + return this.packageFragment; + } + + public IType getEnclosingType() { + if (rawData) doAdapted(); + return null; + } + + public boolean getEnclosingTypeSelection() { + if (rawData) doAdapted(); + return Boolean.FALSE.booleanValue(); + } + + public String getTypeName() { + if (rawData) doAdapted(); + return this.className; + } + + public String getSuperClass() { + if (rawData) doAdapted(); + return this.superClassName; + } + + public List getSuperInterfaces() { + if (rawData) doAdapted(); + return this.interfaces; + } + + public boolean isCreateMain() { + if (rawData) doAdapted(); + return this.createMain; + } + + public boolean isCreateConstructors() { + if (rawData) doAdapted(); + return this.createConstructors; + } + + public boolean isCreateInherited() { + if (rawData) doAdapted(); + return this.createInherited; + } + + public boolean isCanBeModified() { + if (rawData) doAdapted(); + return this.canBeModified; + } + + public IStatus getClassNameStatus() { + return classNameStatus; + } + + public IStatus getPackageNameStatus() { + return packageNameStatus; + } +} Index: src/org/jbpm/gd/jpdl/wizard/NewClassWizardPageEx.java =================================================================== --- src/org/jbpm/gd/jpdl/wizard/NewClassWizardPageEx.java (revision 0) +++ src/org/jbpm/gd/jpdl/wizard/NewClassWizardPageEx.java (revision 0) @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Exadel, Inc. and Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package org.jbpm.gd.jpdl.wizard; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jdt.ui.wizards.NewClassWizardPage; + +/** + * @author au + */ +public class NewClassWizardPageEx extends NewClassWizardPage { + + private NewTypeWizardAdapter adapter = null; + + public NewClassWizardPageEx() { + super(); + } + + public void init(NewTypeWizardAdapter adapter) { + this.adapter = adapter; + setPackageFragmentRoot(adapter.getPackageFragmentRoot(), adapter.isCanBeModified()); + setPackageFragment(adapter.getPackageFragment(), adapter.isCanBeModified()); + setEnclosingType(adapter.getEnclosingType(), adapter.isCanBeModified()); + setEnclosingTypeSelection(adapter.getEnclosingTypeSelection(), adapter.isCanBeModified()); + setTypeName(adapter.getTypeName(), adapter.isCanBeModified()); + if (adapter.getSuperClass()!=null && adapter.getSuperClass().length()>0) { + setSuperClass(adapter.getSuperClass(), adapter.isCanBeModified()); + } + if (adapter.getSuperInterfaces()!=null) { + setSuperInterfaces(adapter.getSuperInterfaces(), adapter.isCanBeModified()); + } + setMethodStubSelection(false, adapter.isCreateConstructors(), + adapter.isCreateInherited(), adapter.isCanBeModified()); + } + + public void setVisible(boolean visible) { + super.setVisible(visible); + // policy: wizards are not allowed to come up with an error message; + // in this wizard, some fields may need initial validation and thus, + // potentially start with an error message. + IStatus classNameStatus = adapter.getClassNameStatus(); + if (classNameStatus !=null && !classNameStatus.isOK()) updateStatus(classNameStatus); + IStatus packageNameStatus = adapter.getPackageNameStatus(); + if (packageNameStatus != null && !packageNameStatus.isOK()) updateStatus(packageNameStatus); + } +} Index: src/org/jbpm/gd/jpdl/wizard/NewClassWizard.java =================================================================== --- src/org/jbpm/gd/jpdl/wizard/NewClassWizard.java (revision 0) +++ src/org/jbpm/gd/jpdl/wizard/NewClassWizard.java (revision 0) @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Exadel, Inc. and Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package org.jbpm.gd.jpdl.wizard; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.internal.ui.*; +import org.eclipse.jdt.internal.ui.actions.*; +import org.eclipse.jdt.internal.ui.wizards.*; +import org.eclipse.jface.wizard.Wizard; +import org.jbpm.gd.jpdl.Logger; + +/** + * @author au + */ + +public class NewClassWizard extends Wizard { + + protected NewTypeWizardAdapter adapter = null; + protected NewClassWizardPageEx mainPage; + + public NewClassWizard() { + setDialogSettings(JavaPlugin.getDefault().getDialogSettings()); + setWindowTitle(NewWizardMessages.NewClassCreationWizard_title); + setDefaultPageImageDescriptor(JavaPluginImages.DESC_WIZBAN_NEWCLASS); + } + + public void setAdapter(NewTypeWizardAdapter adapter) { + this.adapter = adapter; + } + + public NewClassWizard(NewTypeWizardAdapter adapter) { + this(); + setAdapter(adapter); + } + + public void addPages() { + mainPage = new NewClassWizardPageEx(); + addPage(mainPage); + if (adapter!=null) mainPage.init(adapter); + } + + /** + * @return + */ + public String getClassName() { + return this.mainPage.getTypeName(); + } + + public String getQualifiedClassName() { + String c = mainPage.getTypeName(); + String p = mainPage.getPackageText(); + if(p != null && p.length() > 0) c = p + "." + c; //$NON-NLS-1$ + return c; + } + + protected void finishPage(IProgressMonitor monitor) throws InterruptedException, CoreException { + mainPage.createType(monitor); // use the full progress monitor + } + + protected boolean canRunForked() { + return true; + } + + protected ISchedulingRule getSchedulingRule() { + return ResourcesPlugin.getWorkspace().getRoot(); // look all by default + } + + public boolean performFinish() { + IWorkspaceRunnable op= new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException, OperationCanceledException { + try { + finishPage(monitor); + } catch (InterruptedException e) { + throw new OperationCanceledException(e.getMessage()); + } + } + }; + try { + getContainer().run(canRunForked(), true, new WorkbenchRunnableAdapter(op, getSchedulingRule())); + } catch (InvocationTargetException e) { + Logger.logError(e); + return false; + } catch (InterruptedException e) { + return false; + } + return true; + } +} Index: src/org/jbpm/gd/jpdl/wizard/NewActionWizard.java =================================================================== --- src/org/jbpm/gd/jpdl/wizard/NewActionWizard.java (revision 0) +++ src/org/jbpm/gd/jpdl/wizard/NewActionWizard.java (revision 0) @@ -0,0 +1,192 @@ +package org.jbpm.gd.jpdl.wizard; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.core.IBuffer; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.internal.core.JavaProject; +import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.JavaPluginImages; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.INewWizard; +import org.eclipse.ui.IWorkbench; +import org.jbpm.gd.jpdl.Logger; + +public class NewActionWizard extends NewClassWizard implements INewWizard { + static String ACTION_HANDLER_CLASS = "org.jbpm.graph.def.ActionHandler"; + boolean openCreatedType = false; + + public NewActionWizard() { + setDialogSettings(JavaPlugin.getDefault().getDialogSettings()); + setWindowTitle("New jBPM Action"); + setDefaultPageImageDescriptor(JavaPluginImages.DESC_WIZBAN_NEWCLASS); + } + + public void addPages() { + super.addPages(); + mainPage.setTitle("jBPM Action"); + } + + protected void finishPage(IProgressMonitor monitor) throws InterruptedException, CoreException { + mainPage.createType(monitor); + if(mainPage.getCreatedType() != null) { + modifyJavaSource(); + } + } + + @Override + public boolean performFinish() { + boolean b = super.performFinish(); + if(b) { + if(openCreatedType) { + Display.getDefault().asyncExec(new Runnable(){ + public void run() { + try { + JavaUI.openInEditor(mainPage.getCreatedType()); + } catch (CoreException e) { + Logger.logError(e); + } + } + }); + } + } + return b; + } + + public void init(IWorkbench workbench, IStructuredSelection selection) { + IProject p = getProject(selection); + adapter = new NewTypeWizardAdapter(p); + adapter.setRawSuperClassName(ACTION_HANDLER_CLASS); + IPackageFragment f = getPackageFragment(selection); + if(f != null) { + String name = ""; + IPackageFragment cf = f; + while(cf != null) { + if(name.length() == 0) { + name = cf.getElementName(); + } else { + name = cf.getElementName() + "." + name; + } + cf = (cf.getParent() instanceof IPackageFragment) ? (IPackageFragment)cf.getParent() : null; + } + adapter.setRawPackageName(name); + } + adapter.setRawClassName(""); + openCreatedType = true; + } + + IProject getProject(IStructuredSelection selection) { + if(selection.isEmpty() || !(selection instanceof IStructuredSelection)) { + return null; + } + Object o = ((IStructuredSelection)selection).getFirstElement(); + if(o instanceof IProject) { + return (IProject)o; + } else if(o instanceof IJavaElement) { + IJavaElement e = (IJavaElement)o; + return e.getJavaProject().getProject(); + } else if(o instanceof IAdaptable) { + IResource r = (IResource)((IAdaptable)o).getAdapter(IResource.class); + return r != null ? r.getProject() : null; + } + return null; + } + + IPackageFragment getPackageFragment(IStructuredSelection selection) { + if(selection.isEmpty() || !(selection instanceof IStructuredSelection)) { + return null; + } + Object o = ((IStructuredSelection)selection).getFirstElement(); + if(o instanceof IPackageFragment) { + return (IPackageFragment)o; + } else if(o instanceof IFolder) { + IFolder f = (IFolder)o; + IJavaElement jp = JavaCore.create(f); + if(jp instanceof IPackageFragment) { + return (IPackageFragment)jp; + } + } + return null; + } + + void modifyJavaSource() { +// String newValue = getQualifiedClassName(); + try { + IType type = mainPage.getCreatedType(); + if(type == null) { + return; + } + String name = type.getElementName(); + String sc = type.getSuperclassTypeSignature(); + + ICompilationUnit w = type.getCompilationUnit().getWorkingCopy(new NullProgressMonitor()); + IBuffer b = w.getBuffer(); + String s = b.getContents(); + String lineDelimiter = "\r\n"; + + String IMPORT = "import " + ACTION_HANDLER_CLASS + ";"; + int i1 = s.indexOf(IMPORT); + if(i1 >= 0) { + if(i1 >= 0) { + String content = ""; + String[] imports = { + "import org.jbpm.graph.exe.ExecutionContext;", + }; + for (String is: imports) { + if(s.indexOf(is) < 0) { + content += lineDelimiter + is; + } + } + if(content.length() > 0) { + b.replace(i1 + IMPORT.length(), 0, content); + } + } + + s = b.getContents(); + + int i = s.indexOf('{'); + int j = s.lastIndexOf('}'); + + if(i > 0 && j > i) { + String tab = "\t"; + String content = lineDelimiter + + lineDelimiter + + tab + "private static final long serialVersionUID = 1L;" + lineDelimiter + + lineDelimiter + + tab + "/**" + lineDelimiter + + tab + "* The message member gets its value from the configuration in the" + lineDelimiter + + tab + "* processdefinition. The value is injected directly by the engine." + lineDelimiter + + tab + "*/" + lineDelimiter + + tab + "String message;" + lineDelimiter + + lineDelimiter + + tab + "/**" + lineDelimiter + + tab + "* A message process variable is assigned the value of the message" + lineDelimiter + + tab + "* member. The process variable is created if it doesn't exist yet." + lineDelimiter + + tab + "*/" + lineDelimiter + + tab + "public void execute(ExecutionContext context) throws Exception {" + lineDelimiter + + tab + tab + "//ADD CUSTOM ACTION CODE HERE" + lineDelimiter + + tab + tab + "//context.getContextInstance().setVariable(\"message\", message);" + lineDelimiter + + tab + "}" + lineDelimiter + + lineDelimiter; + b.replace(i + 1, j - i - 1, content); + w.commitWorkingCopy(true, new NullProgressMonitor()); + } + } + } catch (CoreException e) { + Logger.logError(e); + } + } + +}