/*
* 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.
*/
package org.drools.eclipse.flow.ruleflow.editor.editpart;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import org.drools.eclipse.DroolsEclipsePlugin;
import org.drools.eclipse.DroolsPluginImages;
import org.drools.eclipse.flow.common.editor.editpart.ElementEditPart;
import org.drools.eclipse.flow.common.editor.editpart.figure.AbstractElementFigure;
import org.drools.eclipse.flow.ruleflow.core.WorkItemWrapper;
import org.drools.eclipse.flow.ruleflow.skin.SkinManager;
import org.drools.eclipse.flow.ruleflow.skin.SkinProvider;
import org.drools.eclipse.preferences.IDroolsConstants;
import org.drools.eclipse.util.ProjectClassLoader;
import org.drools.process.core.Work;
import org.drools.process.core.WorkDefinition;
import org.drools.process.core.WorkDefinitionExtension;
import org.drools.process.core.WorkEditor;
import org.eclipse.draw2d.ChopboxAnchor;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.RoundedRectangle;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.views.properties.IPropertySource;
import org.jbpm.workflow.core.node.WorkItemNode;
/**
* EditPart for a Task node.
*/
public class WorkItemEditPart extends ElementEditPart {
private String SKIN =
DroolsEclipsePlugin.getDefault().getPreferenceStore().getString(IDroolsConstants.SKIN);
private static final Color color = new Color(Display.getCurrent(), 255, 250, 205);
protected IFigure createFigure() {
SkinProvider skinProvider = SkinManager.getInstance().getSkinProvider(SKIN);
WorkItemFigureInterface figure = skinProvider.createWorkItemFigure();
Rectangle constraint = getElementWrapper().getConstraint();
if (constraint.width == -1) {
constraint.width = figure.getSize().width;
}
if (constraint.height == -1) {
constraint.height = figure.getSize().height;
}
getElementWrapper().setConstraint(constraint);
String icon = null;
WorkDefinition workDefinition = getWorkDefinition();
if (workDefinition instanceof WorkDefinitionExtension) {
icon = ((WorkDefinitionExtension) workDefinition).getIcon();
}
if (icon == null) {
icon = "icons/action.gif";
}
Image image = DroolsPluginImages.getImage(icon);
if (image == null) {
IJavaProject javaProject = getProject();
if (javaProject != null) {
try {
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
ClassLoader newLoader = ProjectClassLoader.getProjectClassLoader(javaProject);
try {
Thread.currentThread().setContextClassLoader(newLoader);
image = ImageDescriptor.createFromURL(
newLoader.getResource(icon)).createImage();
DroolsPluginImages.putImage(icon, image);
} finally {
Thread.currentThread().setContextClassLoader(oldLoader);
}
} catch (Exception e) {
DroolsEclipsePlugin.log(e);
}
}
}
figure.setIcon(image);
return figure;
}
protected WorkItemWrapper getWorkItemWrapper() {
return (WorkItemWrapper) getElementWrapper();
}
private WorkDefinition getWorkDefinition() {
return getWorkItemWrapper().getWorkDefinition();
}
// public ConnectionAnchor getSourceConnectionAnchor(Request request) {
// Point p = ((DropRequest) request).getLocation();
// return ((WorkItemFigure) getFigure()).getOutgoingConnectionAnchorAt(p);
// }
protected void doubleClicked() {
super.doubleClicked();
// open custom editor pane if one exists
WorkDefinition workDefinition = getWorkDefinition();
if (workDefinition instanceof WorkDefinitionExtension) {
String editor = ((WorkDefinitionExtension) workDefinition).getCustomEditor();
if (editor != null) {
Work work = openEditor(editor, workDefinition);
if (work != null) {
SetWorkCommand setCommand = new SetWorkCommand();
setCommand.setPropertyValue(work);
CommandStack stack = getViewer().getEditDomain().getCommandStack();
stack.execute(setCommand);
}
}
}
}
@SuppressWarnings("unchecked")
private Work openEditor(String editorClassName, WorkDefinition workDefinition) {
IJavaProject javaProject = getProject();
if (javaProject != null) {
try {
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
ClassLoader newLoader = ProjectClassLoader.getProjectClassLoader(javaProject);
try {
Thread.currentThread().setContextClassLoader(newLoader);
Class<WorkEditor> editorClass = (Class<WorkEditor>) newLoader.loadClass(editorClassName);
Constructor<WorkEditor> constructor = editorClass.getConstructor(Shell.class);
WorkEditor editor = constructor.newInstance(getViewer().getControl().getShell());
editor.setWorkDefinition(workDefinition);
WorkItemNode workItemNode = getWorkItemWrapper().getWorkItemNode();
editor.setWork(workItemNode.getWork());
boolean result = editor.show();
return result ? editor.getWork() : null;
} finally {
Thread.currentThread().setContextClassLoader(oldLoader);
}
} catch (Exception e) {
DroolsEclipsePlugin.log(e);
}
}
return null;
}
public static interface WorkItemFigureInterface extends IFigure {
void setIcon(Image icon);
}
public static class WorkItemFigure extends AbstractElementFigure implements WorkItemFigureInterface {
private RoundedRectangle rectangle;
private ConnectionAnchor defaultConnectionAnchor;
private List<ConnectionAnchor> outgoingConnectionAnchors = new ArrayList<ConnectionAnchor>();
public WorkItemFigure() {
defaultConnectionAnchor = new ChopboxAnchor(this);
// FixedConnectionAnchor c = new FixedConnectionAnchor(this);
// outgoingConnectionAnchors.add(c);
// c = new FixedConnectionAnchor(this);
// outgoingConnectionAnchors.add(c);
}
public void layoutConnectionAnchors() {
// FixedConnectionAnchor c = (FixedConnectionAnchor) outgoingConnectionAnchors.get(0);
// c.setOffsetV(getBounds().height);
// c.setOffsetH(0);
// c = (FixedConnectionAnchor) outgoingConnectionAnchors.get(1);
// c.setOffsetV(getBounds().height);
// c.setOffsetH(getBounds().width);
}
public ConnectionAnchor getOutgoingConnectionAnchorAt(Point p) {
ConnectionAnchor closest = null;
long min = Long.MAX_VALUE;
for (ConnectionAnchor c: outgoingConnectionAnchors) {
Point p2 = c.getLocation(null);
long d = p.getDistance2(p2);
if (d < min) {
min = d;
closest = c;
}
}
if (min > 100) {
return defaultConnectionAnchor;
}
return closest;
}
protected void customizeFigure() {
rectangle = new RoundedRectangle();
rectangle.setCornerDimensions(new Dimension(25, 25));
add(rectangle, 0);
rectangle.setBackgroundColor(color);
rectangle.setBounds(getBounds());
setSelected(false);
}
public void setBounds(Rectangle rectangle) {
super.setBounds(rectangle);
this.rectangle.setBounds(rectangle);
}
public void setSelected(boolean b) {
super.setSelected(b);
rectangle.setLineWidth(b ? 3 : 1);
repaint();
}
public void validate() {
if(isValid()) return;
layoutConnectionAnchors();
super.validate();
}
}
private class SetWorkCommand extends Command {
protected Work propertyValue;
protected Work undoValue;
protected IPropertySource target;
public SetWorkCommand() {
super("Set Work Value");
}
public boolean canExecute() {
return true;
}
public void execute() {
undoValue = getWorkItemWrapper().getWorkItemNode().getWork();
getWorkItemWrapper().getWorkItemNode().setWork(propertyValue);
}
public void redo() {
execute();
}
public void setPropertyValue(Work val) {
propertyValue = val;
}
public void undo() {
getWorkItemWrapper().getWorkItemNode().setWork(undoValue);
}
}
}