com.ocs.dynamo.functional.ui.MultiDomainEditLayout.java Source code

Java tutorial

Introduction

Here is the source code for com.ocs.dynamo.functional.ui.MultiDomainEditLayout.java

Source

/*
   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 com.ocs.dynamo.functional.ui;

import java.util.List;

import com.ocs.dynamo.constants.DynamoConstants;
import com.ocs.dynamo.exception.OCSRuntimeException;
import com.ocs.dynamo.functional.domain.Domain;
import com.ocs.dynamo.service.BaseService;
import com.ocs.dynamo.ui.ServiceLocator;
import com.ocs.dynamo.ui.component.DefaultVerticalLayout;
import com.ocs.dynamo.ui.composite.form.FormOptions;
import com.ocs.dynamo.ui.composite.layout.BaseCustomComponent;
import com.ocs.dynamo.ui.composite.layout.ServiceBasedSplitLayout;
import com.vaadin.data.Container.Filter;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.sort.SortOrder;
import com.vaadin.data.util.filter.SimpleStringFilter;
import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.ui.Button;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.Layout;
import com.vaadin.ui.VerticalLayout;

/**
 * A layout that allows the user to easily manage multiple domains. The list of domain classes can
 * be passed to the constructor. Please note that for every domain class, you must define a
 * (default) service
 * 
 * @author bas.rutten
 *
 */
public class MultiDomainEditLayout extends BaseCustomComponent {

    private static final long serialVersionUID = 4410282343830892631L;

    /**
     * The classes of the domains that are managed by this screen
     */
    private final List<Class<? extends Domain>> domainClasses;

    /**
     * The combo box for selecting the domain
     */
    private ComboBox domainCombo;

    /**
     * The form options (these are passed directly to the split layout)
     */
    private FormOptions formOptions;

    /**
     * The main layout
     */
    private VerticalLayout mainLayout;

    private Class<? extends Domain> selectedDomain;

    /**
     * The layout that contains the controls for editing the selected domain
     */
    private VerticalLayout selectedDomainLayout;

    /**
     * The split layout that displays the currently selected domain
     */
    private ServiceBasedSplitLayout<?, ?> splitLayout;

    /**
     * Constructor
     * 
     * @param formOptions
     *            the form options
     * @param domainClasses
     *            the classes of the domains
     */
    public MultiDomainEditLayout(FormOptions formOptions, List<Class<? extends Domain>> domainClasses) {
        this.formOptions = formOptions;
        this.domainClasses = domainClasses;
    }

    @Override
    public void attach() {
        super.attach();
        build();
    }

    public void build() {

        mainLayout = new DefaultVerticalLayout(true, true);

        // form that contains the combo box
        FormLayout form = new FormLayout();
        form.setMargin(true);
        form.setStyleName(DynamoConstants.CSS_CLASS_HALFSCREEN);
        mainLayout.addComponent(form);

        // combo box for selecting domain
        domainCombo = new ComboBox(message("ocs.select.domain"));
        for (Class<? extends Domain> clazz : getDomainClasses()) {
            domainCombo.addItem(clazz);
            domainCombo.setItemCaption(clazz, getEntityModelFactory().getModel(clazz).getDisplayName());
        }
        domainCombo.setNullSelectionAllowed(false);
        domainCombo.setSizeFull();

        // respond to a change by displaying the correct domain
        domainCombo.addValueChangeListener(new ValueChangeListener() {

            private static final long serialVersionUID = 8441066091930807231L;

            @Override
            @SuppressWarnings("unchecked")
            public void valueChange(ValueChangeEvent event) {
                selectDomain((Class<? extends Domain>) event.getProperty().getValue());
            }
        });

        form.addComponent(domainCombo);

        selectedDomainLayout = new DefaultVerticalLayout();
        mainLayout.addComponent(selectedDomainLayout);

        // select the first domain (if there is any)
        if (!getDomainClasses().isEmpty()) {
            domainCombo.setValue(getDomainClasses().get(0));
        }
        setCompositionRoot(mainLayout);
    }

    /**
     * Construct a split layout for a certain domain
     * 
     * @param domainClass
     *            the class of the domain
     * @param formOptions
     *            the form options
     * @return
     */
    @SuppressWarnings("unchecked")
    private <T extends Domain> ServiceBasedSplitLayout<Integer, T> constructSplitLayout(Class<T> domainClass,
            FormOptions formOptions) {

        BaseService<Integer, T> baseService = (BaseService<Integer, T>) ServiceLocator
                .getServiceForEntity(domainClass);
        if (baseService != null) {

            ServiceBasedSplitLayout<Integer, T> splitLayout = new ServiceBasedSplitLayout<Integer, T>(baseService,
                    getEntityModelFactory().getModel(domainClass), formOptions,
                    new SortOrder(Domain.NAME, SortDirection.ASCENDING)) {

                private static final long serialVersionUID = -6504072714662771230L;

                @Override
                protected Filter constructQuickSearchFilter(String value) {
                    return new SimpleStringFilter(Domain.NAME, value, true, false);
                }

                @Override
                protected boolean mustEnableButton(Button button, T selectedItem) {
                    if (getRemoveButton() == button) {
                        return isDeleteAllowed(getSelectedDomain());
                    }
                    return true;
                }

                @Override
                protected void postProcessButtonBar(Layout buttonBar) {
                    MultiDomainEditLayout.this.postProcessButtonBar(buttonBar);
                }

                @Override
                protected boolean isEditAllowed() {
                    return MultiDomainEditLayout.this.isEditAllowed();
                }

            };
            return splitLayout;
        } else {
            throw new OCSRuntimeException(message("ocs.no.service.class.found", domainClass));
        }
    }

    public List<Class<? extends Domain>> getDomainClasses() {
        return domainClasses;
    }

    /**
     * 
     * @return the currently selected domain class
     */
    public Class<? extends Domain> getSelectedDomain() {
        return selectedDomain;
    }

    public Domain getSelectedItem() {
        return (Domain) splitLayout.getSelectedItem();
    }

    /**
     * Check if the deletion of domain values for a certain class is allowed
     * 
     * @param clazz
     *            the class
     * @return
     */
    protected boolean isDeleteAllowed(Class<?> clazz) {
        return true;
    }

    /**
     * Indicates whether editing is allowed
     */
    protected boolean isEditAllowed() {
        return true;
    }

    protected void postProcessButtonBar(Layout buttonBar) {
        // overwrite in subclasses
    }

    /**
     * Registers a button. The button will be disabled or enabled depending on whether an item is
     * selected
     * 
     * @param button
     *            the button to register
     */
    public void registerButton(Button button) {
        if (splitLayout != null) {
            splitLayout.registerButton(button);
        }
    }

    public void reload() {
        if (splitLayout != null) {
            splitLayout.reload();
        }
    }

    /**
     * Constructs a layout for editing a certain domain
     * 
     * @param clazz
     *            the domain class
     */
    private void selectDomain(Class<? extends Domain> clazz) {
        selectedDomain = clazz;
        ServiceBasedSplitLayout<?, ?> layout = constructSplitLayout(clazz, formOptions);
        selectedDomainLayout.replaceComponent(splitLayout, layout);
        splitLayout = layout;
    }
}