org.bonitasoft.studio.properties.sections.document.DocumentPropertySection.java Source code

Java tutorial

Introduction

Here is the source code for org.bonitasoft.studio.properties.sections.document.DocumentPropertySection.java

Source

/**
 * Copyright (C) 2012 BonitaSoft S.A.
 * BonitaSoft, 32 rue Gustave Eiffel - 38000 Grenoble
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2.0 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.bonitasoft.studio.properties.sections.document;

import static org.bonitasoft.studio.common.Messages.bosProductName;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.bonitasoft.studio.common.ExpressionConstants;
import org.bonitasoft.studio.common.NamingUtils;
import org.bonitasoft.studio.common.emf.tools.ModelHelper;
import org.bonitasoft.studio.common.jface.ElementForIdLabelProvider;
import org.bonitasoft.studio.common.jface.databinding.observables.DocumentObservable;
import org.bonitasoft.studio.common.jface.databinding.validator.GroovyReferenceValidator;
import org.bonitasoft.studio.common.jface.databinding.validator.InputLengthValidator;
import org.bonitasoft.studio.common.properties.AbstractBonitaDescriptionSection;
import org.bonitasoft.studio.expression.editor.filter.AvailableExpressionTypeFilter;
import org.bonitasoft.studio.expression.editor.viewer.ExpressionViewer;
import org.bonitasoft.studio.expression.editor.viewer.ObservableExpressionContentProvider;
import org.bonitasoft.studio.model.expression.Expression;
import org.bonitasoft.studio.model.expression.ExpressionFactory;
import org.bonitasoft.studio.model.process.Document;
import org.bonitasoft.studio.model.process.Element;
import org.bonitasoft.studio.model.process.Pool;
import org.bonitasoft.studio.model.process.ProcessFactory;
import org.bonitasoft.studio.model.process.ProcessPackage;
import org.bonitasoft.studio.pics.Pics;
import org.bonitasoft.studio.pics.PicsConstants;
import org.bonitasoft.studio.properties.i18n.Messages;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.ValidationStatusProvider;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.edit.EMFEditProperties;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.jface.databinding.fieldassist.ControlDecorationSupport;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ViewerProperties;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;

/**
 * @author Aurelien Pupier
 * 
 */
public class DocumentPropertySection extends AbstractBonitaDescriptionSection {

    private ListViewer documentListViewer;
    private EMFDataBindingContext emfDataBindingContext;

    private Text documentNameText;
    private Text documentDescriptionText;
    private Button internalCheckbox;
    private ExpressionViewer documentUrlViewer;
    private ExpressionViewer documentMimeTypeViewer;
    private Button removeButton;
    private Text documentTextId;
    private Button browseButton;
    private Button externalCheckbox;
    private Composite detailsComposite;
    private ControlDecorationSupport decorationSupport;
    private Binding nameBinding;

    public DocumentPropertySection() {
        // keep it for reflective instanciation by Eclipse
    }

    @Override
    public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
        super.createControls(parent, aTabbedPropertySheetPage);
        Composite mainComposite = getWidgetFactory().createComposite(parent);
        mainComposite.setLayout(GridLayoutFactory.fillDefaults().numColumns(2).margins(10, 10).create());
        mainComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        createMasterPanel(mainComposite);
        createDetailsPanel(mainComposite);
        documentListViewer.getList().setFocus();
    }

    protected void createMasterPanel(Composite mainComposite) {
        Composite masterComposite = getWidgetFactory().createComposite(mainComposite);
        masterComposite.setLayout(GridLayoutFactory.fillDefaults().numColumns(2).create());
        masterComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        // Label explanationLabel =
        // getWidgetFactory().createLabel(masterComposite,
        // Messages.explainDocumentPropertySection);
        // explanationLabel.setLayoutData(GridDataFactory.fillDefaults().span(2,1).create());
        getWidgetFactory().createLabel(masterComposite, "");// filler
        final Text documentListFilter = getWidgetFactory().createText(masterComposite, "",
                SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
        documentListFilter.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
        documentListFilter.setMessage(WorkbenchMessages.FilteredTree_FilterMessage);
        documentListFilter.addModifyListener(new ModifyListener() {

            private ViewerFilter filter;

            @Override
            public void modifyText(ModifyEvent e) {
                final String textForFiltering = documentListFilter.getText();
                if (filter != null) {
                    documentListViewer.removeFilter(filter);
                }
                if (textForFiltering != null && !textForFiltering.isEmpty()) {
                    filter = new ViewerFilter() {

                        @Override
                        public boolean select(Viewer viewer, Object parentElement, Object element) {
                            return ((Element) element).getName().contains(textForFiltering);
                        }
                    };
                    documentListViewer.addFilter(filter);
                }

            }
        });

        createButtons(masterComposite);
        documentListViewer = createList(masterComposite);
    }

    private ListViewer createList(Composite mainComposite) {
        List list = getWidgetFactory().createList(mainComposite,
                SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
        list.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        ListViewer documentListViewer = new ListViewer(list);
        documentListViewer.setLabelProvider(new ElementForIdLabelProvider());
        documentListViewer.setContentProvider(new ObservableListContentProvider());
        documentListViewer.addSelectionChangedListener(new ISelectionChangedListener() {

            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                final ISelection listSelection = event.getSelection();
                if (listSelection.isEmpty()) {
                    removeButton.setEnabled(false);
                    detailsComposite.setVisible(false);
                } else {
                    detailsComposite.setVisible(true);
                    removeButton.setEnabled(true);
                    final Document document = (Document) ((IStructuredSelection) listSelection).getFirstElement();
                    documentUrlViewer.getTextControl().setEnabled(!document.isIsInternal());
                    documentUrlViewer.getButtonControl().setEnabled(!document.isIsInternal());
                    documentTextId.setEnabled(document.isIsInternal());
                    browseButton.setEnabled(document.isIsInternal());
                }
            }
        });
        return documentListViewer;
    }

    private void createButtons(Composite mainComposite) {
        Composite buttonComposite = getWidgetFactory().createComposite(mainComposite);
        buttonComposite.setLayout(GridLayoutFactory.fillDefaults().numColumns(1).spacing(0, 3).create());
        buttonComposite.setLayoutData(GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).create());
        createAddButton(buttonComposite);
        createRemoveButton(buttonComposite);
    }

    private void createAddButton(Composite buttonComposite) {
        Button addButton = getWidgetFactory().createButton(buttonComposite, Messages.AddSimple, SWT.FLAT);
        addButton.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).hint(85, SWT.DEFAULT).create());
        addButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                super.widgetSelected(e);
                Document newDocument = ProcessFactory.eINSTANCE.createDocument();
                Set<String> existingNames = new HashSet<String>();
                for (Document existingDocument : getPool().getDocuments()) {
                    existingNames.add(existingDocument.getName());
                }
                newDocument.setName(NamingUtils
                        .generateNewName(existingNames, Messages.documentDefaultName.toLowerCase()).toLowerCase());
                newDocument.setUrl(ExpressionFactory.eINSTANCE.createExpression());
                final Expression mimetypeExpression = ExpressionFactory.eINSTANCE.createExpression();
                mimetypeExpression.setName("application/octet-stream");
                mimetypeExpression.setContent("application/octet-stream");
                mimetypeExpression.setReturnType(String.class.getName());
                mimetypeExpression.setType(ExpressionConstants.CONSTANT_TYPE);
                newDocument.setMimeType(mimetypeExpression);
                getEditingDomain().getCommandStack()
                        .execute(new AddCommand(getEditingDomain(), getPool().getDocuments(), newDocument));
                documentListViewer.setSelection(new StructuredSelection(newDocument));

                newDocument.eAdapters().add(new AdapterImpl() {
                    @Override
                    public void notifyChanged(Notification msg) {
                        super.notifyChanged(msg);
                    }
                });
            }
        });
    }

    private void createRemoveButton(Composite buttonComposite) {
        removeButton = getWidgetFactory().createButton(buttonComposite, Messages.Remove, SWT.FLAT);
        removeButton.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).hint(85, SWT.DEFAULT).create());
        removeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                super.widgetSelected(e);
                final Document documentToRemove = (Document) ((IStructuredSelection) documentListViewer
                        .getSelection()).getFirstElement();
                documentListViewer.remove(documentToRemove);
                getEditingDomain().getCommandStack()
                        .execute(DeleteCommand.create(getEditingDomain(), documentToRemove));
                documentListViewer.refresh();
                documentListViewer.setSelection(new StructuredSelection());
            }
        });
    }

    private void createDetailsPanel(Composite mainComposite) {
        detailsComposite = getWidgetFactory().createComposite(mainComposite);
        detailsComposite.setLayout(GridLayoutFactory.fillDefaults().numColumns(2).spacing(10, 5).create());
        detailsComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        createDocumentNameField(detailsComposite);
        createDocumentDescriptionField(detailsComposite);
        createDocumentMimeTypeField(detailsComposite);
        createDocumentTypeCheckbox(detailsComposite);
    }

    private void createDocumentNameField(Composite detailsComposite) {
        getWidgetFactory().createLabel(detailsComposite, Messages.name);
        documentNameText = getWidgetFactory().createText(detailsComposite, "", SWT.BORDER);
        documentNameText.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
    }

    private void createDocumentDescriptionField(Composite detailsComposite) {
        getWidgetFactory().createLabel(detailsComposite, Messages.description);
        documentDescriptionText = getWidgetFactory().createText(detailsComposite, "", SWT.BORDER);
        documentDescriptionText.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
    }

    private void createDocumentMimeTypeField(Composite detailsComposite) {
        Label mimeTypeLabel = getWidgetFactory().createLabel(detailsComposite, Messages.mimeType);
        documentMimeTypeViewer = new ExpressionViewer(detailsComposite, SWT.BORDER, getWidgetFactory(),
                getEditingDomain(), ProcessPackage.Literals.DOCUMENT__MIME_TYPE);
        documentMimeTypeViewer
                .addFilter(new AvailableExpressionTypeFilter(new String[] { ExpressionConstants.CONSTANT_TYPE }));
        documentMimeTypeViewer.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        documentMimeTypeViewer.getTextControl()
                .setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        documentMimeTypeViewer.setExample(Messages.hintMimeTypeDocument);
        ControlDecoration cd = new ControlDecoration(mimeTypeLabel, SWT.RIGHT);
        cd.setImage(Pics.getImage(PicsConstants.hint));
        cd.setDescriptionText(Messages.explanationMimeTypeDocument);
    }

    private void createDocumentTypeCheckbox(Composite detailsComposite) {
        Composite documentTypeComposite = getWidgetFactory().createComposite(detailsComposite);
        documentTypeComposite.setLayout(GridLayoutFactory.fillDefaults().numColumns(2).spacing(10, 5).create());
        documentTypeComposite.setLayoutData(GridDataFactory.fillDefaults().span(2, 2).grab(true, true).create());
        externalCheckbox = getWidgetFactory().createButton(documentTypeComposite, Messages.External, SWT.RADIO);
        ControlDecoration controlDecorationForExternal = new ControlDecoration(externalCheckbox, SWT.RIGHT);
        controlDecorationForExternal.setImage(Pics.getImage(PicsConstants.hint));
        controlDecorationForExternal.setDescriptionText(Messages.explanationExternalDocument);
        createDocumentURL(documentTypeComposite);
        internalCheckbox = getWidgetFactory().createButton(documentTypeComposite, Messages.Internal, SWT.RADIO);
        ControlDecoration controlDecorationForInternal = new ControlDecoration(internalCheckbox, SWT.RIGHT);
        controlDecorationForInternal.setImage(Pics.getImage(PicsConstants.hint));
        controlDecorationForInternal.setDescriptionText(
                Messages.bind(Messages.explanationInternalDocument, new Object[] { bosProductName }));
        createDocumentBrowse(documentTypeComposite);
    }

    private void createDocumentURL(Composite slaveComposite) {
        documentUrlViewer = new ExpressionViewer(slaveComposite, SWT.BORDER, getWidgetFactory(), getEditingDomain(),
                ProcessPackage.Literals.DOCUMENT__URL);
        documentUrlViewer
                .addFilter(new AvailableExpressionTypeFilter(new String[] { ExpressionConstants.CONSTANT_TYPE }));
        documentUrlViewer.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        documentUrlViewer.getTextControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        documentUrlViewer.setExample(Messages.hintExternalUrl);
        documentUrlViewer.setContentProvider(new ObservableExpressionContentProvider());
    }

    private void createDocumentBrowse(Composite slaveComposite) {
        Composite browseWithTextComposite = getWidgetFactory().createComposite(slaveComposite);
        browseWithTextComposite.setLayout(GridLayoutFactory.fillDefaults().numColumns(2).create());
        browseWithTextComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        documentTextId = getWidgetFactory().createText(browseWithTextComposite, "");
        documentTextId.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        ;
        browseButton = getWidgetFactory().createButton(browseWithTextComposite, Messages.Browse, SWT.FLAT);
        browseButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                super.widgetSelected(e);
                final SelectDocumentInBonitaStudioRepository selectDocumentInBonitaStudioRepository = new SelectDocumentInBonitaStudioRepository(
                        PlatformUI.getWorkbench().getActiveWorkbenchWindow());
                if (IDialogConstants.OK_ID == selectDocumentInBonitaStudioRepository.open()) {
                    documentTextId.setText(selectDocumentInBonitaStudioRepository.getSelectedDocument().getName());
                }
            }
        });
    }

    @Override
    public void setInput(IWorkbenchPart part, ISelection selection) {
        super.setInput(part, selection);
        resetDatabindingContext();
        bindList();

        final IObservableValue documentSelected = ViewersObservables.observeSingleSelection(documentListViewer);
        bindDetails(documentSelected);
        documentListViewer.setSelection(new StructuredSelection());
        documentListViewer.addSelectionChangedListener(new ISelectionChangedListener() {

            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                nameBinding.updateTargetToModel();
            }
        });
    }

    protected void bindList() {
        final IObservableList documentsListObserved = EMFEditProperties
                .list(getEditingDomain(), ProcessPackage.Literals.POOL__DOCUMENTS).observe(getPool());
        emfDataBindingContext.bindList(WidgetProperties.items().observe(documentListViewer.getList()),
                documentsListObserved);
        documentListViewer.setInput(documentsListObserved);
    }

    protected void bindDetails(final IObservableValue documentSelected) {
        if (nameBinding != null) {
            nameBinding.dispose();
        }
        if (decorationSupport != null) {
            decorationSupport.dispose();
        }
        IObservableValue externalUrlObserved = EMFEditProperties
                .value(getEditingDomain(), ProcessPackage.Literals.DOCUMENT__URL).observeDetail(documentSelected);
        emfDataBindingContext.bindValue(ViewerProperties.singleSelection().observe(documentUrlViewer),
                externalUrlObserved);
        documentUrlViewer.setInput(documentSelected);

        IObservableValue mimeTypeObserved = EMFEditProperties
                .value(getEditingDomain(), ProcessPackage.Literals.DOCUMENT__MIME_TYPE)
                .observeDetail(documentSelected);
        emfDataBindingContext.bindValue(ViewerProperties.singleSelection().observe(documentMimeTypeViewer),
                mimeTypeObserved);
        documentMimeTypeViewer.setInput(documentSelected);

        final UpdateValueStrategy targetToModel = new UpdateValueStrategy();

        targetToModel.setAfterGetValidator(new InputLengthValidator(Messages.name, 50));
        targetToModel.setBeforeSetValidator(new DocumentNameValidator(documentListViewer));

        final IObservableValue nameObserved = EMFEditProperties
                .value(getEditingDomain(), ProcessPackage.Literals.ELEMENT__NAME).observeDetail(documentSelected);

        nameBinding = emfDataBindingContext.bindValue(
                SWTObservables.observeDelayedValue(500, SWTObservables.observeText(documentNameText, SWT.Modify)),
                nameObserved, targetToModel, null);

        decorationSupport = ControlDecorationSupport.create(nameBinding, SWT.LEFT);

        nameObserved.addValueChangeListener(new IValueChangeListener() {
            @Override
            public void handleValueChange(ValueChangeEvent event) {
                if (documentListViewer != null && !documentListViewer.getList().isDisposed()) {
                    documentListViewer.refresh();
                }
            }
        });

        IObservableValue descriptionObserved = EMFEditProperties
                .value(getEditingDomain(), ProcessPackage.Literals.ELEMENT__DOCUMENTATION)
                .observeDetail(documentSelected);
        emfDataBindingContext.bindValue(SWTObservables.observeDelayedValue(500,
                SWTObservables.observeText(documentDescriptionText, SWT.Modify)), descriptionObserved);

        IObservableValue internalTypeObserved = EMFEditProperties
                .value(getEditingDomain(), ProcessPackage.Literals.DOCUMENT__IS_INTERNAL)
                .observeDetail(documentSelected);
        emfDataBindingContext.bindValue(SWTObservables.observeSelection(internalCheckbox), internalTypeObserved);

        IObservableValue documentInternalIDObserved = EMFEditProperties
                .value(getEditingDomain(), ProcessPackage.Literals.DOCUMENT__DEFAULT_VALUE_ID_OF_DOCUMENT_STORE)
                .observeDetail(documentSelected);
        emfDataBindingContext.bindValue(
                SWTObservables.observeDelayedValue(500, SWTObservables.observeText(documentTextId, SWT.Modify)),
                documentInternalIDObserved);

        IObservableValue externalTypeObserved = EMFEditProperties
                .value(getEditingDomain(), ProcessPackage.Literals.DOCUMENT__IS_INTERNAL)
                .observeDetail(documentSelected);
        emfDataBindingContext.bindValue(SWTObservables.observeSelection(externalCheckbox), externalTypeObserved,
                new UpdateValueStrategy() {
                    @Override
                    public Object convert(Object value) {
                        return super.convert(!(Boolean) value);
                    }
                }, new UpdateValueStrategy() {
                    @Override
                    public Object convert(Object value) {
                        return super.convert(!(Boolean) value);
                    }
                });

        emfDataBindingContext.bindValue(SWTObservables.observeEnabled(documentUrlViewer.getTextControl()),
                externalTypeObserved, new UpdateValueStrategy() {
                    @Override
                    public Object convert(Object value) {
                        return super.convert(!(Boolean) value);
                    }
                }, new UpdateValueStrategy() {
                    @Override
                    public Object convert(Object value) {
                        return super.convert(!(Boolean) value);
                    }
                });
        emfDataBindingContext.bindValue(SWTObservables.observeEnabled(documentUrlViewer.getButtonControl()),
                externalTypeObserved, new UpdateValueStrategy() {
                    @Override
                    public Object convert(Object value) {
                        return super.convert(!(Boolean) value);
                    }
                }, new UpdateValueStrategy() {
                    @Override
                    public Object convert(Object value) {
                        return super.convert(!(Boolean) value);
                    }
                });

        emfDataBindingContext.bindValue(SWTObservables.observeEnabled(documentTextId), internalTypeObserved);
        emfDataBindingContext.bindValue(SWTObservables.observeEnabled(browseButton), internalTypeObserved);
    }

    protected void resetDatabindingContext() {
        if (emfDataBindingContext != null) {
            emfDataBindingContext.dispose();
        }
        emfDataBindingContext = new EMFDataBindingContext();
    }

    protected Pool getPool() {
        return (Pool) ModelHelper.getParentProcess(getEObject());
    }

    @Override
    public void dispose() {
        if (decorationSupport != null) {
            decorationSupport.dispose();
        }
        if (emfDataBindingContext != null) {
            emfDataBindingContext.dispose();
        }
        super.dispose();
    }

    @Override
    public String getSectionDescription() {
        return Messages.documentPropertySectionDescription;
    }
}