/* * 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 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; } /** * @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()) parameterPages = createParameterPages(getInitCell()); } /** * @see AbstractFunctionWizard#init(SchemaSelection) */ @Override protected void init(SchemaSelection selection) { // create a new cell resultCell = new DefaultCell(); resultCell.setTransformationIdentifier(getFunctionId()); } /** * @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 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) { 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); // get initial values ListMultimap<String, ParameterValue> initialValues = initialCell == null ? null : initialCell.getTransformationParameters(); 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; } @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(); } }