nz.co.senanque.vaadinsupport.tableeditor.TableEditorLayout.java Source code

Java tutorial

Introduction

Here is the source code for nz.co.senanque.vaadinsupport.tableeditor.TableEditorLayout.java

Source

/*******************************************************************************
 * Copyright (c)2014 Prometheus Consulting
 *
 * 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 nz.co.senanque.vaadinsupport.tableeditor;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import nz.co.senanque.vaadinsupport.formatting.FormattingTable;
import nz.co.senanque.vaadinsupport.permissionmanager.PermissionManager;
import nz.co.senanque.vaadinsupport.viewmanager.ViewManaged;
import nz.co.senanque.vaadinsupport.viewmanager.ViewManager;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;

import com.vaadin.addon.jpacontainer.Editor;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Container;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

/**
 * 
 * Layout with a table that handles popup editors. It can be used quite generically with just Spring wiring:
 * 
 *   <bean id="personTableLayout" class="nz.co.senanque.vaadinsupport.tableeditor.TableEditorLayout">
 *       <property name="container" ref="personContainer"/>
 *       <property name="columns">
 *           <list>
 *               <value>name</value>
 *               <value>address</value>
 *               <value>email</value>
 *           </list>
 *       </property>
 *       <property name="editorWindow" ref="editorWindow"/>
 *   </bean>
 *   
 *   <bean id="editorWindow" class="nz.co.senanque.vaadinsupport.tableeditor.EditorWindowImpl" >
 *       <constructor-arg ref="maduraSessionManager"/>
 *       <constructor-arg ref="viewManager"/>
 *       <constructor-arg value="person"/>
 *       <constructor-arg ref="messageSource"/>
 *   </bean>
 *
 * So you can inject your container, a list of fields and an editor implementation and you have a table that displays and edits
 * the contents of the container. Extend the EditorWindow to add special fields if necessary. You can also inject a list of headings
 * which will override the field names when displaying the table heading. Regardless these are translated to the current user's locale.
 * 
 *  The container needs to implement com.vaadin.addon.jpacontainer.Editor<T> if you want to use
 *  the editor functions (and if you don't you might wonder why you need this). The obvious container to use is com.vaadin.addon.jpacontainer.JPAContainerEditor<T>
 *  and you normally use a factory wired like this (using a locally defined Person type):
 *  
 *   &lt;bean id="personContainer" class="com.vaadin.addon.jpacontainer.JPAContainerEditorFactory"&gt;
 *      &lt;property name="type" value="nz.co.senanque.addressbook.instances.Person"/&gt;
 *   &lt;/bean&gt;
 * 
 * @author Roger Parkinson
 * @version $Revision:$
 */
public class TableEditorLayout<T> extends CustomComponent
        implements InitializingBean, ViewManaged, MessageSourceAware, Serializable {

    @AutoGenerated
    private VerticalLayout mainLayout;
    @AutoGenerated
    private FormattingTable table_1;
    /*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
    private static final long serialVersionUID = 1565287876888837051L;
    /*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
    private Container.Filterable m_container;

    private List<String> m_headings;
    private List<String> m_columns;
    private List<String> m_fields;

    private String m_permission;
    @Autowired
    transient private PermissionManager m_permissionManager;

    public List<String> getHeadings() {
        if (m_headings == null) {
            return getColumns();
        }
        return m_headings;
    }

    public void setHeadings(List<String> headings) {
        m_headings = headings;
    }

    public List<String> getColumns() {
        return m_columns;
    }

    public void setColumns(List<String> columns) {
        m_columns = columns;
    }

    public List<String> getFields() {
        if (m_fields == null) {
            return getColumns();
        }
        return m_fields;
    }

    public void setFields(List<String> fields) {
        m_fields = fields;
    }

    private EditorWindow<T> m_editorWindow;
    private transient MessageSource m_messageSource;

    /**
     * The constructor should first build the main layout, set the
     * composition root and then do any custom initialization.
     *
     * The constructor will not be automatically regenerated by the
     * visual editor.
     */
    public TableEditorLayout() {
        buildMainLayout();
        setCompositionRoot(mainLayout);

        table_1.setWidth("100%");
        table_1.setHeight("100%");
        table_1.setPageLength(10);
        table_1.setSelectable(true);
        table_1.setImmediate(true);
        table_1.setColumnCollapsingAllowed(true);
    }

    /**
     * Delete given object from Table. Table will delegate deletion to
     * its container.
     * 
     * @param object
     */
    public void deleteObject(T object) {
        Object id;
        try {
            id = getEditor().getIdForPojo(object);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        table_1.removeItem(id);
    }

    /**
     * Cancel given object from Table. Table will delegate deletion to
     * its container.
     * 
     * @param object
     */
    public void cancelObject(T object) {
        Long id;
        try {
            id = (Long) getEditor().getIdForPojo(object);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        table_1.removeItem(id);
    }

    /**
     * Adds new row to Table and selects new row. Table will delegate Item
     * creation to its container.
     */
    private void newRow() {
        Object newItemId = table_1.addItem();
        // open in editor window unless table is in content editable mode
        if (!table_1.isEditable()) {
            editObject((Long) newItemId, true);
        }
    }

    /**
     * Loads given object to Editor.
     * 
     * @param pojo
     */
    public void edit(T pojo, boolean newRow) {
        getEditorWindow().loadObject(pojo, newRow);
    }

    /**
     * Loads the object into the editor window with a boolean indicating if it is a new row or not.
     * @param id
     * @param newRow
     */
    public void editObject(Long id, boolean newRow) {
        if (id == null) {
            if (getEditorWindow().getParent() != null) {
                ((Window) getEditorWindow().getParent()).removeWindow((Window) m_editorWindow);
            }
        } else {
            T pojo = (T) getEditor().get(id);
            edit(pojo, newRow);
        }
    }

    public void persistObject(T object) {
        getEditor().merge(object);
        table_1.setValue(null);
    }

    public void afterPropertiesSet() throws Exception {
        if (getEditorWindow() != null) {
            // Only set up the editor window if it is there
            getEditorWindow().initialize(getFields());
            getEditorWindow().addListener(new Listener() {

                private static final long serialVersionUID = -6498337136650101469L;

                public void componentEvent(Event event) {
                    if (event instanceof DeleteEvent) {
                        deleteObject((T) ((DeleteEvent) event).getObject());
                        return;
                    }
                    if (event instanceof SaveEvent) {
                        persistObject((T) ((SaveEvent) event).getObject());
                        return;
                    }
                    if (event instanceof CancelEvent) {
                        cancelObject((T) ((CancelEvent) event).getObject());
                        return;
                    }
                }
            });
            table_1.addActionHandler(new Handler() {
                MessageSourceAccessor messageSourceAccessor = new MessageSourceAccessor(m_messageSource);
                private static final long serialVersionUID = -5923269974651895441L;
                Action add = new Action(
                        messageSourceAccessor.getMessage("add.new.row.to.table", null, "add.new.row.to.table"));
                Action remove = new Action(
                        messageSourceAccessor.getMessage("delete.this.row", null, "delete.this.row"));
                Action edit = new Action(messageSourceAccessor.getMessage("edit.this.row", null, "edit.this.row"));

                public Action[] getActions(Object target, Object sender) {
                    List<Action> actions = new ArrayList<Action>();
                    if (getPermissionManager().hasPermission(getPermission())) {
                        actions.add(add);
                        actions.add(remove);
                        actions.add(edit);
                    }
                    return actions.toArray(new Action[actions.size()]);
                }

                public void handleAction(Action action, Object sender, Object target) {
                    if (action == add) {
                        newRow();
                    } else if (action == remove) {
                        T w = (T) getEditor().get((Serializable) target);
                        deleteObject(w);
                    } else if (action == edit) {
                        editObject((Long) target, false);
                    }
                }
            });
        }
        table_1.setContainerDataSource(getContainer(), getColumns().toArray(new String[getColumns().size()]),
                getHeadings().toArray(new String[getHeadings().size()]), m_messageSource);

    }

    public void setContainer(Container.Filterable container) {
        m_container = container;
    }

    public Container.Filterable getContainer() {
        return m_container;
    }

    @SuppressWarnings("unchecked")
    private Editor<T> getEditor() {
        return (Editor<T>) m_container;
    }

    @AutoGenerated
    private VerticalLayout buildMainLayout() {
        // common part: create layout
        mainLayout = new VerticalLayout();
        mainLayout.setImmediate(false);
        mainLayout.setWidth("100%");
        mainLayout.setHeight("100%");
        mainLayout.setMargin(false);

        // top-level component properties
        setWidth("100.0%");
        setHeight("100.0%");

        // table_1
        table_1 = new FormattingTable();
        table_1.setImmediate(false);
        table_1.setWidth("-1px");
        table_1.setHeight("-1px");
        mainLayout.addComponent(table_1);

        return mainLayout;
    }

    public EditorWindow<T> getEditorWindow() {
        return m_editorWindow;
    }

    public void setEditorWindow(EditorWindow<T> editorWindow) {
        m_editorWindow = editorWindow;
    }

    public String getPermission() {
        return m_permission;
    }

    public void setPermission(String permission) {
        m_permission = permission;
    }

    public void setMessageSource(MessageSource messageSource) {
        m_messageSource = messageSource;
    }

    public void setViewManager(ViewManager viewManager) {
        //      m_viewManager = viewManager;
    }

    protected PermissionManager getPermissionManager() {
        return m_permissionManager;
    }

    protected void setPermissionManager(PermissionManager permissionManager) {
        m_permissionManager = permissionManager;
    }
}