org.eclipse.wb.internal.swing.databinding.ui.contentproviders.ColumnBindingUiContentProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.wb.internal.swing.databinding.ui.contentproviders.ColumnBindingUiContentProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2011 Google, Inc.
 * All rights reserved. This program and the accompanying materials
 * are 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:
 *    Google, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.wb.internal.swing.databinding.ui.contentproviders;

import com.google.common.collect.Lists;

import org.eclipse.wb.internal.core.DesignerPlugin;
import org.eclipse.wb.internal.core.databinding.model.IObserveInfo.ChildrenContext;
import org.eclipse.wb.internal.core.databinding.model.IObservePresentation;
import org.eclipse.wb.internal.core.databinding.model.reference.IReferenceProvider;
import org.eclipse.wb.internal.core.databinding.model.reference.StringReferenceProvider;
import org.eclipse.wb.internal.core.databinding.ui.editor.ICompleteListener;
import org.eclipse.wb.internal.core.databinding.ui.editor.IUiContentProvider;
import org.eclipse.wb.internal.core.databinding.ui.editor.contentproviders.PropertyAdapter;
import org.eclipse.wb.internal.core.databinding.ui.providers.ObserveDecoratingLabelProvider;
import org.eclipse.wb.internal.core.databinding.utils.CoreUtils;
import org.eclipse.wb.internal.core.utils.check.Assert;
import org.eclipse.wb.internal.core.utils.ui.GridDataFactory;
import org.eclipse.wb.internal.swing.databinding.Messages;
import org.eclipse.wb.internal.swing.databinding.model.ObserveInfo;
import org.eclipse.wb.internal.swing.databinding.model.beans.BeanObserveInfo;
import org.eclipse.wb.internal.swing.databinding.model.beans.BeanSupport;
import org.eclipse.wb.internal.swing.databinding.model.beans.ElPropertyObserveInfo;
import org.eclipse.wb.internal.swing.databinding.model.bindings.ColumnBindingInfo;
import org.eclipse.wb.internal.swing.databinding.model.generic.IGenericType;
import org.eclipse.wb.internal.swing.databinding.model.properties.ElPropertyInfo;
import org.eclipse.wb.internal.swing.databinding.model.properties.PropertyInfo;
import org.eclipse.wb.internal.swing.databinding.ui.contentproviders.el.ElPropertyUiConfiguration;

import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;

import java.util.Collections;
import java.util.List;

/**
 * Editor for {@link ColumnBindingInfo}.
 * 
 * @author lobas_av
 * @coverage bindings.swing.ui
 */
public final class ColumnBindingUiContentProvider implements IUiContentProvider {
    private Label propertiesLabel;
    private CheckboxTreeViewer treeViewer;
    private ElPropertyUiContentProvider elPropertyUIContentProvider;
    private boolean elProperty;
    private String errorMessage;
    private List<PropertyAdapter> properties = Collections.emptyList();
    private ICompleteListener listener;
    private final ColumnBindingInfo binding;

    ////////////////////////////////////////////////////////////////////////////
    //
    // Constructor
    //
    ////////////////////////////////////////////////////////////////////////////
    public ColumnBindingUiContentProvider(ColumnBindingInfo binding) {
        this.binding = binding;
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Complete
    //
    ////////////////////////////////////////////////////////////////////////////
    public void setCompleteListener(ICompleteListener listener) {
        this.listener = listener;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    /**
     * Sets or clears the error message for this provider.
     */
    private final void setErrorMessage(String message) {
        errorMessage = message;
        if (listener != null) {
            listener.calculateFinish();
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // GUI
    //
    ////////////////////////////////////////////////////////////////////////////
    public int getNumberOfControls() {
        return 2;
    }

    public void createContent(Composite parent, int columns) {
        // create properties title
        propertiesLabel = new Label(parent, SWT.NONE);
        propertiesLabel.setText(Messages.ColumnBindingUiContentProvider_properties);
        // create properties viewer
        treeViewer = new CheckboxTreeViewer(parent, SWT.BORDER | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);
        treeViewer.setContentProvider(new PropertyAdapterContentProvider());
        treeViewer.setLabelProvider(new PropertyAdapterLabelProvider(treeViewer));
        treeViewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                if (event.getChecked()) {
                    treeViewer.setCheckedElements(new Object[] { event.getElement() });
                }
                calculateFinish();
            }
        });
        GridDataFactory.create(treeViewer.getTree()).fill().grab().spanH(columns - 1).minVC(5);
        // create EL property
        ElPropertyUiConfiguration configuration = new ElPropertyUiConfiguration();
        configuration.setTitle(Messages.ColumnBindingUiContentProvider_elExpression);
        elPropertyUIContentProvider = new ElPropertyUiContentProvider(configuration, null);
        elPropertyUIContentProvider.setCompleteListener(new ICompleteListener() {
            public void calculateFinish() {
                ColumnBindingUiContentProvider.this.calculateFinish();
            }
        });
        elPropertyUIContentProvider.createContent(parent, columns);
        //
        treeViewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                handleELProperty();
            }
        });
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Handling
    //
    ////////////////////////////////////////////////////////////////////////////
    private void calculateFinish() {
        // prepare checked elements
        Object[] checkedElements = treeViewer.getCheckedElements();
        // check properties state
        if (checkedElements.length == 0) {
            setErrorMessage(Messages.ColumnBindingUiContentProvider_erorrMessage);
        } else {
            if (elProperty) {
                setErrorMessage(elPropertyUIContentProvider.getErrorMessage());
            } else {
                setErrorMessage(null);
            }
        }
    }

    private void handleELProperty() {
        IGenericType objectType = binding.getJTableBinding().getInputElementType();
        try {
            Object[] elements = treeViewer.getCheckedElements();
            if (elProperty) {
                if (elements.length == 1) {
                    ObservePropertyAdapter adapter = (ObservePropertyAdapter) elements[0];
                    if (adapter.getProperty() instanceof ElPropertyObserveInfo) {
                        elPropertyUIContentProvider.setProperty(
                                (ElPropertyInfo) convertAdapterToProperty(new BeanSupport(), objectType, adapter));
                        return;
                    }
                }
                elProperty = false;
                elPropertyUIContentProvider.setProperty(null);
            } else if (elements.length == 1) {
                ObservePropertyAdapter adapter = (ObservePropertyAdapter) elements[0];
                if (adapter.getProperty() instanceof ElPropertyObserveInfo) {
                    elProperty = true;
                    elPropertyUIContentProvider.setProperty(
                            (ElPropertyInfo) convertAdapterToProperty(new BeanSupport(), objectType, adapter));
                }
            }
        } catch (Throwable e) {
            DesignerPlugin.log(e);
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Update
    //
    ////////////////////////////////////////////////////////////////////////////
    public void updateFromObject() throws Exception {
        IGenericType objectType = binding.getJTableBinding().getInputElementType();
        setObjectType(objectType);
        PropertyInfo property = binding.getDetailProperty();
        elProperty = property instanceof ElPropertyInfo;
        elPropertyUIContentProvider.setProperty(elProperty ? (ElPropertyInfo) property : null);
        ObservePropertyAdapter adapter = convertPropertyToAdapter(new BeanSupport(), objectType, property);
        setCheckedAdExpand(adapter);
        calculateFinish();
    }

    public void saveToObject() throws Exception {
        if (elProperty) {
            elPropertyUIContentProvider.saveToObject();
            binding.setDetailProperty(elPropertyUIContentProvider.getProperty());
        } else {
            IGenericType objectType = binding.getJTableBinding().getInputElementType();
            List<PropertyAdapter> choosenProperties = getChoosenProperties();
            PropertyAdapter propertyAdapter = choosenProperties.get(0);
            PropertyInfo property = convertAdapterToProperty(new BeanSupport(), objectType,
                    (ObservePropertyAdapter) propertyAdapter);
            binding.setDetailProperty(property);
        }
    }

    protected void setObjectType(IGenericType objectType) {
        // check properties
        if (getErrorMessage() == null) {
            try {
                // load properties
                properties = getProperties(objectType);
                treeViewer.setInput(properties);
                // checked properties
                if (!properties.isEmpty()) {
                    treeViewer.setCheckedElements(ArrayUtils.EMPTY_OBJECT_ARRAY);
                }
            } catch (Throwable e) {
                setEmptyProperties();
            }
        } else {
            setEmptyProperties();
        }
    }

    private void setEmptyProperties() {
        properties = Collections.emptyList();
        treeViewer.setInput(properties);
        treeViewer.setCheckedElements(ArrayUtils.EMPTY_OBJECT_ARRAY);
    }

    private void setCheckedAdExpand(Object... adapters) {
        for (int i = 0; i < adapters.length; i++) {
            treeViewer.expandToLevel(adapters[i], 0);
        }
        treeViewer.setCheckedElements(adapters);
        if (adapters.length > 0) {
            treeViewer.setSelection(new StructuredSelection(adapters[0]), true);
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Properties
    //
    ////////////////////////////////////////////////////////////////////////////
    private List<PropertyAdapter> getChoosenProperties() {
        List<PropertyAdapter> properties = Lists.newArrayList();
        CollectionUtils.addAll(properties, treeViewer.getCheckedElements());
        return properties;
    }

    private List<PropertyAdapter> getProperties(IGenericType objectType) throws Exception {
        List<PropertyAdapter> adapters = Lists.newArrayList();
        BeanSupport beanSupport = new BeanSupport();
        beanSupport.doAddELProperty(true);
        for (ObserveInfo property : beanSupport.createProperties(null, objectType)) {
            adapters.add(new ObservePropertyAdapter(null, property));
        }
        return adapters;
    }

    private PropertyInfo convertAdapterToProperty(BeanSupport beanSupport, IGenericType objectType,
            ObservePropertyAdapter adapter) throws Exception {
        ObserveInfo observe = new SubBeanObserveInfo(beanSupport, null, objectType, StringReferenceProvider.EMPTY);
        return adapter.getProperty().createProperty(observe);
    }

    private ObservePropertyAdapter convertPropertyToAdapter(BeanSupport beanSupport, IGenericType objectType,
            PropertyInfo property) throws Exception {
        ObserveInfo observe = property.getObserveProperty(
                new SubBeanObserveInfo(beanSupport, null, objectType, StringReferenceProvider.EMPTY));
        Assert.isNotNull(observe);
        return convertObserveToAdapter(observe);
    }

    private ObservePropertyAdapter convertObserveToAdapter(ObserveInfo observe) throws Exception {
        if (observe != null) {
            ObservePropertyAdapter adapter = new ObservePropertyAdapter(
                    convertObserveToAdapter((ObserveInfo) observe.getParent()), observe);
            adapter.addToParent();
            return adapter;
        }
        return null;
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Classes
    //
    ////////////////////////////////////////////////////////////////////////////
    private static class ObservePropertyAdapter extends PropertyAdapter {
        private final ObservePropertyAdapter m_parent;
        private final ObserveInfo m_property;
        private List<ObservePropertyAdapter> m_children;

        ////////////////////////////////////////////////////////////////////////////
        //
        // Constructor
        //
        ////////////////////////////////////////////////////////////////////////////
        public ObservePropertyAdapter(ObservePropertyAdapter parent, ObserveInfo property) throws Exception {
            super(property.getPresentation().getText(), property.getObjectClass());
            m_parent = parent;
            m_property = property;
        }

        ////////////////////////////////////////////////////////////////////////////
        //
        // Access
        //
        ////////////////////////////////////////////////////////////////////////////
        public ObservePropertyAdapter getParent() {
            return m_parent;
        }

        public ObserveInfo getProperty() {
            return m_property;
        }

        public List<ObservePropertyAdapter> getChildren() {
            if (m_children == null) {
                m_children = Lists.newArrayList();
                List<ObserveInfo> properties = CoreUtils
                        .cast(m_property.getChildren(ChildrenContext.ChildrenForPropertiesTable));
                for (ObserveInfo property : properties) {
                    try {
                        m_children.add(new ObservePropertyAdapter(this, property));
                    } catch (Throwable e) {
                        DesignerPlugin.log(e);
                    }
                }
            }
            return m_children;
        }

        public void addToParent() {
            if (m_parent != null) {
                m_parent.m_children = Lists.newArrayList();
                m_parent.m_children.add(this);
            }
        }

        ////////////////////////////////////////////////////////////////////////////
        //
        // Object
        //
        ////////////////////////////////////////////////////////////////////////////
        @Override
        public int hashCode() {
            int parentHash = m_parent == null ? 1 : m_parent.hashCode();
            return parentHash * super.hashCode();
        }

        @Override
        public boolean equals(Object object) {
            // self check
            if (object == this) {
                return true;
            }
            // compare with other adapter
            if (object instanceof ObservePropertyAdapter) {
                ObservePropertyAdapter adapter = (ObservePropertyAdapter) object;
                if (m_parent == null && adapter.m_parent == null) {
                } else if (m_parent != null && adapter.m_parent == null
                        || m_parent == null && adapter.m_parent != null) {
                    return false;
                } else if (m_parent != null && adapter.m_parent != null) {
                    if (!m_parent.equals(adapter.m_parent)) {
                        return false;
                    }
                }
                return m_name.equals(adapter.m_name) && m_type == adapter.m_type;
            }
            // default
            return false;
        }
    }

    private static class PropertyAdapterContentProvider implements ITreeContentProvider {
        public Object[] getElements(Object input) {
            return ((List<?>) input).toArray();
        }

        public Object getParent(Object element) {
            return getAdapter(element).getParent();
        }

        public boolean hasChildren(Object element) {
            return !getAdapter(element).getChildren().isEmpty();
        }

        public Object[] getChildren(Object element) {
            return getAdapter(element).getChildren().toArray();
        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }

        public void dispose() {
        }
    }

    private static class PropertyAdapterLabelProvider extends LabelProvider
            implements IColorProvider, IFontProvider {
        private final ObserveDecoratingLabelProvider m_labelProvider;

        ////////////////////////////////////////////////////////////////////////////
        //
        // Constructor
        //
        ////////////////////////////////////////////////////////////////////////////
        public PropertyAdapterLabelProvider(TreeViewer viewer) {
            m_labelProvider = new ObserveDecoratingLabelProvider(viewer);
        }

        ////////////////////////////////////////////////////////////////////////////
        //
        // LabelProvider
        //
        ////////////////////////////////////////////////////////////////////////////
        @Override
        public void dispose() {
            super.dispose();
            m_labelProvider.dispose();
        }

        @Override
        public String getText(Object element) {
            return getAdapter(element).getName();
        }

        @Override
        public Image getImage(Object element) {
            try {
                return getAdapterProperty(element).getPresentation().getImage();
            } catch (Throwable e) {
            }
            return super.getImage(element);
        }

        ////////////////////////////////////////////////////////////////////////////
        //
        // Decoration
        //
        ////////////////////////////////////////////////////////////////////////////
        public Color getForeground(Object element) {
            return m_labelProvider.getForeground(getAdapterProperty(element));
        }

        public Color getBackground(Object element) {
            return m_labelProvider.getBackground(getAdapterProperty(element));
        }

        public Font getFont(Object element) {
            return m_labelProvider.getFont(getAdapterProperty(element));
        }
    }

    private static ObservePropertyAdapter getAdapter(Object element) {
        return (ObservePropertyAdapter) element;
    }

    private static ObserveInfo getAdapterProperty(Object element) {
        return getAdapter(element).getProperty();
    }

    private static class SubBeanObserveInfo extends BeanObserveInfo {
        public SubBeanObserveInfo(BeanSupport beanSupport, ObserveInfo parent, IGenericType objectType,
                IReferenceProvider referenceProvider) {
            super(beanSupport, parent, objectType, referenceProvider);
        }

        public IObservePresentation getPresentation() {
            return null;
        }
    }
}