org.jbpm.gd.jpdl.properties.TaskFormGenerationDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.jbpm.gd.jpdl.properties.TaskFormGenerationDialog.java

Source

/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jbpm.gd.jpdl.properties;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.part.FileEditorInput;
import org.jbpm.gd.jpdl.Logger;
import org.jbpm.gd.jpdl.Plugin;
import org.jbpm.gd.jpdl.model.Variable;
import org.jbpm.gd.jpdl.model.VariableContainer;
import org.jbpm.gd.jpdl.taskform.Field;
import org.jbpm.gd.jpdl.taskform.FieldType;
import org.jbpm.gd.jpdl.taskform.FormGenerator;

public class TaskFormGenerationDialog extends StatusDialog {

    private static final String pluginId = Plugin.getDefault().getBundle().getSymbolicName();

    private static final IStatus okStatus = new Status(Status.INFO, pluginId, 0,
            "Press OK to generate a form in the specified filename.", null);
    private static final IStatus noFileNameStatus = new Status(Status.ERROR, pluginId, 0,
            "Please specify a correct filename.", null);

    String taskName;
    FormToolkit toolkit;
    VariableContainerConfigurationComposite fieldComposite;
    VariableContainer fieldContainer;
    VariableContainerConfigurationComposite buttonComposite;
    VariableContainer buttonContainer;

    Label fileNameLabel;
    Text fileNameText;
    Composite fieldArea;
    Composite buttonArea;

    public TaskFormGenerationDialog(Shell parentShell, String taskName) {
        super(parentShell);
        toolkit = new FormToolkit(parentShell.getDisplay());
        fieldContainer = new VariableContainerImpl();
        buttonContainer = new VariableContainerImpl();
        this.taskName = taskName;
    }

    public boolean close() {
        toolkit.dispose();
        return super.close();
    }

    protected Point getInitialSize() {
        return new Point(550, 475);
    }

    protected Control createDialogArea(Composite parent) {
        Composite area = (Composite) super.createDialogArea(parent);
        area.setLayout(new FormLayout());
        fieldArea = toolkit.createComposite(area);
        fieldArea.setBackground(ColorConstants.menuBackground);
        fieldArea.setLayout(new FormLayout());
        buttonArea = toolkit.createComposite(area);
        buttonArea.setBackground(ColorConstants.menuBackground);
        buttonArea.setLayout(new FormLayout());
        Composite formFileArea = toolkit.createComposite(area);
        formFileArea.setBackground(ColorConstants.menuBackground);
        formFileArea.setLayout(new FormLayout());
        fieldArea.setLayoutData(createFieldAreaLayoutData());
        buttonArea.setLayoutData(createButtonAreaLayoutData());
        formFileArea.setLayoutData(createFormFileAreaLayoutData());
        createFieldComposite(fieldArea);
        createButtonComposite(buttonArea);
        createFormFileField(formFileArea);
        getShell().setText("Generate Task Form");
        return area;
    }

    protected Button createButton(Composite parent, int id, String label, boolean defaultButton) {
        return super.createButton(parent, id, label, false);
    }

    private FormData createFieldAreaLayoutData() {
        FormData result = new FormData();
        result.top = new FormAttachment(0, 10);
        result.left = new FormAttachment(0, 10);
        result.right = new FormAttachment(100, -10);
        result.height = 175;
        return result;
    }

    private FormData createButtonAreaLayoutData() {
        FormData result = new FormData();
        result.top = new FormAttachment(fieldArea, 0);
        result.left = new FormAttachment(0, 10);
        result.right = new FormAttachment(100, -10);
        result.height = 125;
        return result;
    }

    private FormData createFormFileAreaLayoutData() {
        FormData result = new FormData();
        result.top = new FormAttachment(buttonArea, 0);
        result.left = new FormAttachment(0, 0);
        result.right = new FormAttachment(100, 0);
        result.bottom = new FormAttachment(100, 0);
        return result;
    }

    private void createFieldComposite(Composite area) {
        String[] columnTitles = new String[] { "Variable Name", "Label", "Read", "Write", "Required" };
        fieldComposite = VariableContainerConfigurationComposite.create(toolkit, area, false, columnTitles);
        fieldComposite.setVariableContainer(fieldContainer);
        fieldComposite.setBackground(ColorConstants.menuBackground);
        fieldComposite.setMessage("Define the form fields:");
        fieldComposite.setVariableDefaultName("field");
    }

    private void createButtonComposite(Composite area) {
        String[] columnTitles = new String[] { "Transition Name", "Label" };
        buttonComposite = VariableContainerConfigurationComposite.create(toolkit, area, true, columnTitles);
        buttonComposite.setVariableContainer(buttonContainer);
        buttonComposite.setBackground(ColorConstants.menuBackground);
        buttonComposite.setMessage("Define the form buttons:");
        buttonComposite.setVariableDefaultName("button");
    }

    private void createFormFileField(Composite area) {
        fileNameLabel = toolkit.createLabel(area, "File name:");
        fileNameLabel.setBackground(ColorConstants.menuBackground);
        createFileText(area);
        fileNameLabel.setLayoutData(createFileNameLabelLayoutData());
        fileNameText.setLayoutData(createFileNameTextLayoutData());

    }

    private FormData createFileNameLabelLayoutData() {
        FormData result = new FormData();
        result.left = new FormAttachment(0, 15);
        result.top = new FormAttachment(0, 12);
        return result;
    }

    private FormData createFileNameTextLayoutData() {
        FormData result = new FormData();
        result.top = new FormAttachment(0, 10);
        result.left = new FormAttachment(fileNameLabel, 5);
        result.right = new FormAttachment(100, -77);
        return result;
    }

    private void createFileText(Composite area) {
        fileNameText = toolkit.createText(area, "");
        if (taskName == null || "".equals(taskName)) {
            taskName = "default";
        }
        int i = taskName.length();
        fileNameText.setText(taskName + ".xhtml");
        fileNameText.setSelection(0, i);
        fileNameText.addKeyListener(new KeyAdapter() {
            public void keyReleased(KeyEvent e) {
                checkFileName();
            }
        });
        checkFileName();
    }

    private void checkFileName() {
        String fileName = fileNameText.getText();
        if (fileName == null || "".equals(fileName)) {
            updateStatus(noFileNameStatus);
        } else {
            updateStatus(okStatus);
        }
    }

    protected void okPressed() {
        generateForm();
        super.okPressed();
    }

    private void generateForm() {
        createTaskFormFile();
        updateFormsXmlFile();
        refreshProcessFolder();
    }

    private void refreshProcessFolder() {
        try {
            getInputFile().getParent().refreshLocal(1, null);
        } catch (CoreException e) {
            Logger.logError("Problem while refreshing process folder.", e);
        }
    }

    private boolean isEmpty(String str) {
        return str == null || "".equals(str);
    }

    private void createTaskFormFile() {
        Variable[] fieldVars = fieldContainer.getVariables();
        List fields = new ArrayList();
        for (int i = 0; i < fieldVars.length; i++) {
            Field field = new Field();
            field.setVariableName(fieldVars[i].getName());
            field.setLabel(
                    isEmpty(fieldVars[i].getMappedName()) ? fieldVars[i].getName() : fieldVars[i].getMappedName());
            field.setReadOnly(!fieldVars[i].isWritable() && fieldVars[i].isReadable());
            field.setFieldType(FieldType.getFieldTypes()[0]);
            fields.add(field);
        }
        Variable[] buttonVariables = buttonContainer.getVariables();
        List buttons = new ArrayList();
        buttons.add(org.jbpm.gd.jpdl.taskform.Button.BUTTON_SAVE);
        buttons.add(org.jbpm.gd.jpdl.taskform.Button.BUTTON_CANCEL);
        for (int i = 0; i < buttonVariables.length; i++) {
            String name = "name";
            String label;
            if (!isEmpty(buttonVariables[i].getName())) {
                name = buttonVariables[i].getName();
            }
            if (!isEmpty(buttonVariables[i].getMappedName())) {
                label = buttonVariables[i].getMappedName();
            } else {
                label = name;
            }
            buttons.add(org.jbpm.gd.jpdl.taskform.Button.createTransitionButton(name, label));
        }
        getFile(fileNameText.getText(), FormGenerator.getForm(fields, buttons));
    }

    private void updateFormsXmlFile() {
        IFile file = getInputFile();
        IPath path = file.getProjectRelativePath();
        file = file.getProject().getFile(path.removeLastSegments(1).append("forms.xml"));
        try {
            if (!file.exists()) {
                file.create(new ByteArrayInputStream("<forms/>".getBytes()), true, null);
            }
        } catch (CoreException e) {
            Logger.logError("Could not create forms.xml", e);
        }
        Document document = getDocument(file);
        addForm(document);
        saveDocument(file, document);
    }

    private void saveDocument(IFile formFile, Document document) {
        try {
            StringWriter stringWriter = new StringWriter();
            XMLWriter xmlWriter = new XMLWriter(stringWriter, OutputFormat.createPrettyPrint());
            xmlWriter.write(document);
            formFile.setContents(new ByteArrayInputStream(stringWriter.getBuffer().toString().getBytes()), true,
                    true, null);
        } catch (IOException e) {
            Logger.logError("Problem writing xml document to file", e);
        } catch (CoreException e) {
            Logger.logError("Problem writing xml document to file", e);
        }
    }

    private Element getElementFor(String taskName, Document document) {
        List list = document.getRootElement().elements("form");
        for (int i = 0; i < list.size(); i++) {
            Element element = (Element) list.get(i);
            String candidate = element.attributeValue("task");
            if (candidate != null && candidate.equals(taskName)) {
                return element;
            }
        }
        return null;
    }

    private void addForm(Document document) {
        Element element = getElementFor(taskName, document);
        if (element == null) {
            element = document.getRootElement().addElement("form");
            element.addAttribute("task", taskName);
        }
        Attribute form = element.attribute("form");
        if (form == null) {
            element.addAttribute("form", fileNameText.getText());
        } else {
            form.setValue(fileNameText.getText());
        }
    }

    private Document getDocument(IFile file) {
        try {
            return new SAXReader().read(new InputStreamReader(file.getContents()));
        } catch (DocumentException e) {
            Logger.logError("Problem creating DOM document from forms.xml", e);
        } catch (CoreException e) {
            Logger.logError("Problem getting the contents from forms.xml", e);
        }
        return null;

    }

    private IFile getInputFile() {
        IEditorPart editorPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
                .getActiveEditor();
        return ((FileEditorInput) editorPart.getEditorInput()).getFile();
    }

    private IFile getFile(String name, String initialContents) {
        IFile file = getInputFile();
        IPath path = file.getProjectRelativePath();
        file = file.getProject().getFile(path.removeLastSegments(1).append(name));
        try {
            if (!file.exists()) {
                file.create(new ByteArrayInputStream(initialContents.getBytes()), true, null);
            } else {
                file.setContents(new ByteArrayInputStream(initialContents.getBytes()), true, true, null);
            }
        } catch (CoreException e) {
            Logger.logError("Could not create " + name, e);
        }
        return file;
    }

    private class VariableContainerImpl implements VariableContainer {
        ArrayList variables = new ArrayList();

        public void addVariable(Variable variable) {
            variables.add(variable);
        }

        public Variable[] getVariables() {
            return (Variable[]) variables.toArray(new Variable[variables.size()]);
        }

        public void removeVariable(Variable variable) {
            variables.remove(variable);
        }

    }

}