eu.esdihumboldt.hale.ui.function.generic.AbstractGenericFunctionWizard.java Source code

Java tutorial

Introduction

Here is the source code for eu.esdihumboldt.hale.ui.function.generic.AbstractGenericFunctionWizard.java

Source

/*
 * Copyright (c) 2012 Data Harmonisation Panel
 * 
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution. If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *     HUMBOLDT EU Integrated Project #030962
 *     Data Harmonisation Panel <http://www.dhpanel.eu>
 */

package eu.esdihumboldt.hale.ui.function.generic;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.annotation.Nullable;

import org.eclipse.jface.dialogs.IPageChangingListener;
import org.eclipse.jface.dialogs.PageChangingEvent;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.IWizardContainer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimaps;

import de.fhg.igd.eclipse.util.extension.ExtensionObjectFactoryCollection;
import de.fhg.igd.eclipse.util.extension.FactoryFilter;
import de.fhg.igd.slf4jplus.ALogger;
import de.fhg.igd.slf4jplus.ALoggerFactory;
import eu.esdihumboldt.hale.common.align.extension.function.FunctionDefinition;
import eu.esdihumboldt.hale.common.align.extension.function.FunctionParameterDefinition;
import eu.esdihumboldt.hale.common.align.extension.function.ParameterDefinition;
import eu.esdihumboldt.hale.common.align.model.Cell;
import eu.esdihumboldt.hale.common.align.model.MutableCell;
import eu.esdihumboldt.hale.common.align.model.ParameterValue;
import eu.esdihumboldt.hale.common.align.model.impl.DefaultCell;
import eu.esdihumboldt.hale.ui.HaleWizardPage;
import eu.esdihumboldt.hale.ui.function.AbstractFunctionWizard;
import eu.esdihumboldt.hale.ui.function.FunctionWizard;
import eu.esdihumboldt.hale.ui.function.extension.ParameterPageExtension;
import eu.esdihumboldt.hale.ui.function.extension.ParameterPageFactory;
import eu.esdihumboldt.hale.ui.function.generic.pages.EntitiesPage;
import eu.esdihumboldt.hale.ui.function.generic.pages.FunctionWizardPage;
import eu.esdihumboldt.hale.ui.function.generic.pages.GenericParameterPage;
import eu.esdihumboldt.hale.ui.function.generic.pages.ParameterPage;
import eu.esdihumboldt.hale.ui.selection.SchemaSelection;
import eu.esdihumboldt.hale.ui.util.wizard.HaleWizardDialog;
import eu.esdihumboldt.hale.ui.util.wizard.TitleImageWizard;

/**
 * Generic function wizard
 * 
 * @param <T> the function type
 * @param <P> the field definition type
 * @author Simon Templer
 */
public abstract class AbstractGenericFunctionWizard<P extends ParameterDefinition, T extends FunctionDefinition<P>>
        extends AbstractFunctionWizard implements TitleImageWizard {

    private static final ALogger log = ALoggerFactory.getLogger(AbstractGenericFunctionWizard.class);

    private final String functionId;
    private MutableCell resultCell;

    private EntitiesPage<T, P, ?> entitiesPage;

    private List<ParameterPage> parameterPages;

    private Image functionImage;

    /**
     * Create a generic function wizard for a certain function based on a schema
     * selection
     * 
     * @param selection the schema selection, may be <code>null</code>
     * @param functionId the function identifier
     */
    public AbstractGenericFunctionWizard(SchemaSelection selection, String functionId) {
        super(selection);

        setHelpAvailable(true);
        this.functionId = functionId;
    }

    /**
     * Create a generic function wizard for a certain function based on a schema
     * selection
     * 
     * @param selection the schema selection, may be <code>null</code>
     * @param parameters initial function parameters
     * @param functionId the function identifier
     */
    public AbstractGenericFunctionWizard(SchemaSelection selection, ListMultimap<String, ParameterValue> parameters,
            String functionId) {
        super(selection, parameters);

        setHelpAvailable(true);
        this.functionId = functionId;
    }

    /**
     * @see AbstractFunctionWizard#AbstractFunctionWizard(Cell)
     */
    public AbstractGenericFunctionWizard(Cell cell) {
        super(cell);

        setHelpAvailable(true);
        this.functionId = cell.getTransformationIdentifier();
    }

    /**
     * @see AbstractFunctionWizard#init()
     */
    @Override
    public void init() {
        super.init();

        setWindowTitle(getFunction().getDisplayName());

        // create the entities page
        // it is needed for creating a new cell to allow assigning the entities
        // and when editing a cell to populate its copy with the same
        // configuration
        entitiesPage = createEntitiesPage(getInitSelection(), getInitCell());

        // create parameter pages
        if (!getFunction().getDefinedParameters().isEmpty()) {
            if (getInitCell() != null) {
                parameterPages = createParameterPages(getInitCell());
            } else {
                parameterPages = createParameterPages(getInitParameters());
            }
        }
    }

    /**
     * @see AbstractFunctionWizard#init(SchemaSelection)
     */
    @Override
    protected void init(SchemaSelection selection) {
        // create a new cell
        resultCell = new DefaultCell();
        resultCell.setTransformationIdentifier(getFunctionId());
    }

    @Override
    protected void init(SchemaSelection selection, ListMultimap<String, ParameterValue> parameters) {
        init(selection);

        resultCell.setTransformationParameters(parameters);
    }

    /**
     * @see AbstractFunctionWizard#init(Cell)
     */
    @Override
    protected void init(Cell cell) {
        // create a new cell even if a cell is already present
        resultCell = new DefaultCell(cell);
        // copy ID
        resultCell.setId(cell.getId());
        // XXX necessary to reset those?
        resultCell.setSource(null);
        resultCell.setTarget(null);
        resultCell.setTransformationParameters(null);
        // the cell configuration will be duplicated or changed by the wizard
        // afterwards the old cell is replaced by the new cell in the alignment
    }

    /**
     * Create the entities page
     * 
     * @param initSelection the initial selection, may be <code>null</code>
     * @param initCell the initial cell, may be <code>null</code>
     * @return the entities page
     */
    protected abstract EntitiesPage<T, P, ?> createEntitiesPage(SchemaSelection initSelection, Cell initCell);

    /**
     * Create parameter pages.
     * 
     * @param initialValues the initial parameter values, may be
     *            <code>null</code>
     * @return the list of parameter pages
     */
    protected List<ParameterPage> createParameterPages(
            @Nullable ListMultimap<String, ParameterValue> initialValues) {
        LinkedList<ParameterPage> parameterPages = new LinkedList<ParameterPage>();

        // create copy of function parameter set
        Set<FunctionParameterDefinition> functionParameters = new LinkedHashSet<>();
        for (FunctionParameterDefinition param : getFunction().getDefinedParameters())
            functionParameters.add(param);

        if (initialValues != null)
            initialValues = Multimaps.unmodifiableListMultimap(initialValues);
        // get available parameter pages
        List<ParameterPageFactory> paramPageFactories = ParameterPageExtension.getInstance()
                .getFactories(new FactoryFilter<ParameterPage, ParameterPageFactory>() {

                    @Override
                    public boolean acceptFactory(ParameterPageFactory factory) {
                        return factory.getFunctionId().equals(getFunctionId());
                    }

                    @Override
                    public boolean acceptCollection(
                            ExtensionObjectFactoryCollection<ParameterPage, ParameterPageFactory> collection) {
                        return true;
                    }
                });
        // use available parameter pages (first come first serve)
        for (ParameterPageFactory paramPageFactory : paramPageFactories) {
            Set<FunctionParameterDefinition> pageFunctionParameters = new HashSet<>();
            for (FunctionParameterDefinition fp : paramPageFactory.getAssociatedParameters())
                if (functionParameters.contains(fp))
                    pageFunctionParameters.add(fp);
            if (!pageFunctionParameters.isEmpty()) {
                ParameterPage paramPage;
                try {
                    paramPage = paramPageFactory.createExtensionObject();
                } catch (Exception e) {
                    log.error("Could not creating parameter page " + paramPageFactory.getIdentifier(), e);
                    continue;
                }
                functionParameters.removeAll(pageFunctionParameters);
                parameterPages.add(paramPage);
                paramPage.setParameter(pageFunctionParameters, initialValues);
            }
        }
        // use generic parameter page for remaining parameters
        if (!functionParameters.isEmpty()) {
            ParameterPage generic = new GenericParameterPage();
            generic.setParameter(functionParameters, initialValues);
            parameterPages.add(generic);
        }

        return parameterPages;
    }

    /**
     * Create the page for configuring the function parameters.
     * 
     * @param initialCell the initial cell, may be <code>null</code>
     * @return the parameter configuration page or <code>null</code>
     */
    protected List<ParameterPage> createParameterPages(Cell initialCell) {
        // get initial values
        ListMultimap<String, ParameterValue> initialValues = (initialCell == null) ? null
                : initialCell.getTransformationParameters();

        return createParameterPages(initialValues);
    }

    @Override
    public void createPageControls(Composite pageContainer) {
        super.createPageControls(pageContainer);

        // disable help button, let function wizards do their work afterwards
        // At all other points the buttons aren't created yet.
        if (getContainer() instanceof HaleWizardDialog)
            ((HaleWizardDialog) getContainer()).setHelpButtonEnabled(false);
    }

    /**
     * @see Wizard#setContainer(IWizardContainer)
     */
    @Override
    public void setContainer(IWizardContainer wizardContainer) {
        super.setContainer(wizardContainer);

        if (wizardContainer instanceof HaleWizardDialog) {
            final HaleWizardDialog container = (HaleWizardDialog) wizardContainer;
            // has to be pageChanging, because closing the tray in page changed
            // leads to an exception
            ((HaleWizardDialog) wizardContainer).addPageChangingListener(new IPageChangingListener() {

                @Override
                public void handlePageChanging(PageChangingEvent event) {
                    boolean helpAvailable = false;
                    if (event.getTargetPage() instanceof HaleWizardPage<?>) {
                        HaleWizardPage<?> page = (HaleWizardPage<?>) event.getTargetPage();
                        helpAvailable = page.getHelpContext() != null;
                    }

                    container.setHelpButtonEnabled(helpAvailable);

                    if (container.getTray() != null)
                        container.closeTray();
                }
            });
        }
    }

    /**
     * @see Wizard#addPages()
     */
    @Override
    public void addPages() {
        super.addPages();

        if (entitiesPage != null) {
            addPage(entitiesPage);
        }

        if (parameterPages != null) {
            for (ParameterPage parameterPage : parameterPages)
                addPage(parameterPage);
        }
    }

    /**
     * @see FunctionWizard#getResult()
     */
    @Override
    public MutableCell getResult() {
        return resultCell;
    }

    /**
     * Get the function identifier
     * 
     * @return the function identifier
     */
    public String getFunctionId() {
        return functionId;
    }

    /**
     * Get the function
     * 
     * @return the function
     */
    public abstract T getFunction();

    /**
     * @see Wizard#performFinish()
     */
    @Override
    public boolean performFinish() {
        ListMultimap<String, ParameterValue> parameters = ArrayListMultimap.create();
        resultCell.setTransformationParameters(parameters);
        // configure cell with all pages
        for (IWizardPage page : getPages())
            if (page instanceof FunctionWizardPage)
                ((FunctionWizardPage) page).configureCell(resultCell);
            else if (page instanceof ParameterPage)
                parameters.putAll(((ParameterPage) page).getConfiguration());

        return true;
    }

    /**
     * Returns the cell that would be created if the wizard would be finished
     * now.
     * 
     * @return the cell
     */
    public Cell getUnfinishedCell() {
        MutableCell current = new DefaultCell();
        current.setTransformationIdentifier(getFunctionId());
        ListMultimap<String, ParameterValue> parameters = ArrayListMultimap.create();
        current.setTransformationParameters(parameters);
        for (IWizardPage page : getPages()) {
            // stop at first uncompleted page
            if (!page.isPageComplete())
                break;
            if (page instanceof FunctionWizardPage)
                ((FunctionWizardPage) page).configureCell(current);
            else if (page instanceof ParameterPage)
                parameters.putAll(((ParameterPage) page).getConfiguration());
        }
        return current;
    }

    /**
     * @see TitleImageWizard#getTitleImage()
     */
    @Override
    public Image getTitleImage() {
        if (functionImage == null) {
            try {
                functionImage = ImageDescriptor.createFromURL(getFunction().getIconURL()).createImage();
            } catch (Exception e) {
                // ignore
            }
        }

        return functionImage;
    }

    /**
     * @see Wizard#dispose()
     */
    @Override
    public void dispose() {
        if (functionImage != null) {
            functionImage.dispose();
        }

        super.dispose();
    }

}