package org.openflexo.wkf.controller.action;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.util.logging.Logger;
import org.openflexo.fib.FIBLibrary;
import org.openflexo.fib.controller.FIBController.Status;
import org.openflexo.fib.controller.FIBDialog;
import org.openflexo.foundation.rm.FlexoProject;
import org.openflexo.foundation.wkf.FlexoProcess;
import org.openflexo.foundation.wkf.FlexoProcessNode;
import org.openflexo.foundation.wkf.action.AddSubProcess;
import org.openflexo.foundation.wkf.node.SubProcessNode;
import org.openflexo.localization.FlexoLocalization;
import org.openflexo.logging.FlexoLogger;
import org.openflexo.toolbox.FileResource;
import org.openflexo.toolbox.HasPropertyChangeSupport;
public class SubProcessSelectorDialog extends FIBDialog<SubProcessSelectorDialog.SubProcessSelectorData> {
private static final Logger logger = FlexoLogger.getLogger(SubProcessSelectorDialog.class.getPackage().getName());
private static final File FIB_FILE = new FileResource("Fib/FIBSubProcessSelector.fib");
public static enum BoundProcessChoice {
BIND_NEW, BIND_EXISTING, BIND_LATER;
}
public static class SubProcessSelectorData implements HasPropertyChangeSupport {
private FlexoProject project;
private WKFControllerActionInitializer controllerActionInitializer;
private BoundProcessChoice choice = BoundProcessChoice.BIND_NEW;
private FlexoProcessNode existingProcess;
private String newProcessName;
private String subProcessNodeName;
private FlexoProcessNode parentProcess;
private PropertyChangeSupport propertyChangeSupport;
private final SubProcessNode subProcessNode;
private String errorMessage;
private boolean showErrorMessage;
private boolean noParentProcess;
public SubProcessSelectorData(FlexoProject project, WKFControllerActionInitializer controllerActionInitializer,
SubProcessNode subProcessNode, FlexoProcessNode process) {
this.project = project;
this.controllerActionInitializer = controllerActionInitializer;
this.subProcessNode = subProcessNode;
subProcessNodeName = subProcessNode.getName();
this.parentProcess = process;
this.propertyChangeSupport = new PropertyChangeSupport(this);
noParentProcess = true;
validate();
}
@Override
public PropertyChangeSupport getPropertyChangeSupport() {
return propertyChangeSupport;
}
@Override
public String getDeletedProperty() {
return null;
}
public FlexoProject getProject() {
return project;
}
public WKFControllerActionInitializer getControllerActionInitializer() {
return controllerActionInitializer;
}
public SubProcessNode getSubProcessNode() {
return subProcessNode;
}
public BoundProcessChoice getChoice() {
return choice;
}
public void setChoice(BoundProcessChoice choice) {
if (choice == null) {
return;
}
this.choice = choice;
switch (choice) {
case BIND_NEW:
if (subProcessNodeName == null || subProcessNodeName.trim().length() == 0 || subProcessNodeName != null
&& existingProcess != null && subProcessNodeName.equals(existingProcess.getName())) {
setSubProcessNodeName(newProcessName);
}
break;
case BIND_EXISTING:
if (subProcessNodeName == null || subProcessNodeName.trim().length() == 0 || subProcessNodeName != null
&& subProcessNodeName.equals(newProcessName)) {
if (existingProcess != null) {
setSubProcessNodeName(existingProcess.getName());
} else {
setSubProcessNodeName(null);
}
}
break;
}
propertyChangeSupport.firePropertyChange("choice", null, choice);
validate();
}
public FlexoProcessNode getExistingProcess() {
return existingProcess;
}
public void setExistingProcess(FlexoProcessNode existingProcess) {
FlexoProcessNode old = this.existingProcess;
this.existingProcess = existingProcess;
if (existingProcess != null
&& (subProcessNodeName == null || subProcessNodeName.trim().length() == 0 || old != null
&& old.getName().equals(subProcessNodeName))) {
setSubProcessNodeName(existingProcess.getName());
}
propertyChangeSupport.firePropertyChange("existingProcess", old, existingProcess);
validate();
}
public String getNewProcessName() {
return newProcessName;
}
public void setNewProcessName(String newProcessName) {
String old = this.newProcessName;
this.newProcessName = newProcessName;
propertyChangeSupport.firePropertyChange("newProcessName", old, newProcessName);
if (subProcessNodeName == null || subProcessNodeName.trim().length() == 0 || subProcessNodeName.equals(old)) {
setSubProcessNodeName(newProcessName);
}
validate();
}
public FlexoProcessNode getParentProcess() {
return parentProcess;
}
public void setParentProcess(FlexoProcessNode parentProcess) {
this.parentProcess = parentProcess;
propertyChangeSupport.firePropertyChange("parentProcess", null, parentProcess);
}
public boolean getNoParentProcess() {
return noParentProcess;
}
public void setNoParentProcess(boolean value) {
noParentProcess = value;
}
public String getSubProcessNodeName() {
return subProcessNodeName;
}
public void setSubProcessNodeName(String subProcessNodeName) {
this.subProcessNodeName = subProcessNodeName;
propertyChangeSupport.firePropertyChange("subProcessNodeName", null, subProcessNodeName);
}
public String getErrorMessage() {
return errorMessage;
}
private void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
propertyChangeSupport.firePropertyChange("errorMessage", null, this.errorMessage);
}
public boolean isAcceptableParentProcessNode(FlexoProcessNode parentProcessNode) {
return parentProcessNode == null || parentProcessNode.isAncestorOf(subProcessNode.getProcess().getProcessNode());
}
public boolean isAcceptableExistingProcessNode(FlexoProcessNode existingProcessNode) {
return subProcessNode.isAcceptableAsSubProcess(existingProcessNode);
}
private void validate() {
switch (choice) {
case BIND_EXISTING:
if (existingProcess == null) {
setErrorMessage(FlexoLocalization.localizedForKey("please_select_a_valid_process"));
return;
}
break;
case BIND_NEW:
if (newProcessName == null || newProcessName.trim().length() == 0) {
setErrorMessage(FlexoLocalization.localizedForKey("please_submit_a_valid_process_name"));
return;
} else {
if (getProject().getWorkflow().getLocalFlexoProcessWithName(newProcessName) != null) {
setErrorMessage(FlexoLocalization.localizedForKeyWithParams("process_named_($0)_already_exists", newProcessName));
return;
}
}
break;
}
setErrorMessage(null);
}
public boolean isShowErrorMessage() {
return showErrorMessage;
}
public void setShowErrorMessage(boolean showErrorMessage) {
this.showErrorMessage = showErrorMessage;
}
}
public SubProcessSelectorDialog(FlexoProject project, WKFControllerActionInitializer controllerActionInitializer,
SubProcessNode subProcessNode, FlexoProcessNode process) {
super(FIBLibrary.instance().retrieveFIBComponent(FIB_FILE), new SubProcessSelectorData(project, controllerActionInitializer,
subProcessNode, process), controllerActionInitializer.getController().getFlexoFrame(), true, FlexoLocalization
.getMainLocalizer());
}
public boolean askAndSetSubProcess() {
setSize(560, 270);
setLocationRelativeTo(getOwner());
while (true) {
setVisible(true);
if (getStatus() == Status.VALIDATED) {
getData().setShowErrorMessage(true);
getData().validate();
if (getData().getErrorMessage() != null) {
continue;
}
getData().getSubProcessNode().setName(getData().getSubProcessNodeName());
switch (getData().getChoice()) {
case BIND_EXISTING:
FlexoProcessNode existingProcess = getData().getExistingProcess();
if (existingProcess != null) {
FlexoProcess process;
if (existingProcess.getWorkflow().isCache()) {
process = existingProcess.getProcess(true);
if (process == null) {
return false;
}
} else {
process = existingProcess.getProcess();
}
if (process != null) {
getData().getSubProcessNode().setSubProcess(process);
return true;
}
}
break;
case BIND_LATER:
return true;
case BIND_NEW:
AddSubProcess addSubProcess = AddSubProcess.actionType.makeNewAction(getData().subProcessNode.getProcess(), null,
getData().getControllerActionInitializer().getEditor());
addSubProcess.setNewProcessName(getData().getNewProcessName());
if (!getData().getNoParentProcess()) {
addSubProcess.setParentProcess(getData().parentProcess != null ? getData().parentProcess.getProcess() : null);
}
addSubProcess.setShowNewProcess(false);
addSubProcess.doAction();
if (addSubProcess.hasActionExecutionSucceeded()) {
getData().getSubProcessNode().setSubProcess(addSubProcess.getNewProcess());
return true;
}
break;
}
} else {
return false;
}
}
}
}