/* * Copyright (c) 2005-2016 Vincent Vandenschrick. All rights reserved. * * This file is part of the Jspresso framework. * * Jspresso is free software: you can redistribute it and/or modify * it 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. * * Jspresso is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Jspresso. If not, see <http://www.gnu.org/licenses/>. */ package org.jspresso.framework.application.frontend.action.lov; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import org.jspresso.framework.action.ActionException; import org.jspresso.framework.action.IActionHandler; import org.jspresso.framework.application.frontend.action.FrontendAction; import org.jspresso.framework.application.frontend.action.ModalDialogAction; import org.jspresso.framework.binding.IValueConnector; import org.jspresso.framework.model.descriptor.ICollectionDescriptorProvider; import org.jspresso.framework.model.descriptor.IComponentDescriptor; import org.jspresso.framework.model.descriptor.basic.BasicCollectionDescriptor; import org.jspresso.framework.model.descriptor.basic.BasicListDescriptor; import org.jspresso.framework.model.descriptor.basic.BasicSetDescriptor; import org.jspresso.framework.util.descriptor.DefaultDescriptor; import org.jspresso.framework.view.IView; import org.jspresso.framework.view.action.IDisplayableAction; import org.jspresso.framework.view.descriptor.ESelectionMode; import org.jspresso.framework.view.descriptor.ICollectionViewDescriptor; import org.jspresso.framework.view.descriptor.basic.BasicCollectionViewDescriptor; import org.jspresso.framework.view.descriptor.basic.BasicTableViewDescriptor; /** * This action takes an arbitrary model collection connector from the action * context parameter and binds it to a newly created table view. This action is * meant to be chained to the generic {@code ModalDialogAction} so that the * table is actually popped-up in a dialog. Two actions ({@code okAction} * and {@code cancelAction}) can be configured to react to the user * decision. * * @author Vincent Vandenschrick * @param <E> * the actual gui component type used. * @param <F> * the actual icon type used. * @param <G> * the actual action type used. */ public class ChooseComponentAction<E, F, G> extends FrontendAction<E, F, G> { private IDisplayableAction cancelAction; private IDisplayableAction okAction; private ICollectionViewDescriptor collectionViewDescriptor; private IComponentDescriptor<?> componentDescriptor; /** * {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public boolean execute(IActionHandler actionHandler, Map<String, Object> context) { List<IDisplayableAction> actions = new ArrayList<>(); if (okAction != null) { actions.add(okAction); } if (cancelAction != null) { actions.add(cancelAction); } context.put(ModalDialogAction.DIALOG_ACTIONS, actions); Object actionParam = getActionParameter(context); ICollectionViewDescriptor viewDescriptor = getCollectionViewDescriptor(context); IValueConnector componentsModelConnector; if (actionParam instanceof IValueConnector) { componentsModelConnector = (IValueConnector) actionParam; if (viewDescriptor == null) { viewDescriptor = new BasicTableViewDescriptor(); ((BasicTableViewDescriptor) viewDescriptor).setReadOnly(true); ((BasicTableViewDescriptor) viewDescriptor) .setSelectionMode(ESelectionMode.SINGLE_SELECTION); ((BasicTableViewDescriptor) viewDescriptor) .setModelDescriptor(componentsModelConnector.getModelDescriptor()); viewDescriptor.setPermId("Choose." + componentsModelConnector.getModelDescriptor().getName()); } } else if (actionParam instanceof Collection<?>) { ICollectionDescriptorProvider<?> collectionDescriptorProvider; IComponentDescriptor<?> elementDescriptor = getComponentDescriptor(context); if (viewDescriptor != null && viewDescriptor.getModelDescriptor() instanceof ICollectionDescriptorProvider<?>) { collectionDescriptorProvider = (ICollectionDescriptorProvider<?>) viewDescriptor .getModelDescriptor(); } else { if (viewDescriptor == null) { viewDescriptor = new BasicTableViewDescriptor(); ((BasicTableViewDescriptor) viewDescriptor).setReadOnly(true); ((BasicTableViewDescriptor) viewDescriptor) .setSelectionMode(ESelectionMode.SINGLE_SELECTION); } if (elementDescriptor != null) { if (actionParam instanceof List<?>) { collectionDescriptorProvider = new BasicListDescriptor<Object>(); } else if (actionParam instanceof Set<?>) { collectionDescriptorProvider = new BasicSetDescriptor<Object>(); } else { throw new ActionException("Unsupported collection type : " + actionParam.getClass().getName()); } ((BasicCollectionDescriptor<Object>) collectionDescriptorProvider) .setElementDescriptor(elementDescriptor); ((BasicCollectionViewDescriptor) viewDescriptor) .setModelDescriptor(collectionDescriptorProvider .getCollectionDescriptor()); } else { throw new ActionException( "Could not determine component descriptor of the collection element."); } } componentsModelConnector = getBackendController(context) .createModelConnector(ACTION_MODEL_NAME, collectionDescriptorProvider.getCollectionDescriptor()); componentsModelConnector.setConnectorValue(actionParam); } else { throw new ActionException( "Could not determine component collection to use for choosing among."); } ((DefaultDescriptor) viewDescriptor.getModelDescriptor()) .setName(ACTION_MODEL_NAME); IView<E> collectionView = getViewFactory(context).createView( viewDescriptor, actionHandler, getLocale(context)); String dialogTitle = getI18nName(getTranslationProvider(context), getLocale(context)); if (dialogTitle != null && dialogTitle.length() > 0) { context.put(ModalDialogAction.DIALOG_TITLE, dialogTitle); } context.put(ModalDialogAction.DIALOG_VIEW, collectionView); getMvcBinder(context).bind(collectionView.getConnector(), componentsModelConnector); return super.execute(actionHandler, context); } /** * Configures the action that will be triggered when the user cancels the * component choice. * * @param cancelAction * the cancelAction to set. */ public void setCancelAction(IDisplayableAction cancelAction) { this.cancelAction = cancelAction; } /** * Configures the action that will be triggered when the user confirms the * component choice. the chosen component will then be retrieved from the * selected view item. * * @param okAction * the okAction to set. */ public void setOkAction(IDisplayableAction okAction) { this.okAction = okAction; } /** * Gets the collectionViewDescriptor. * * @param context * the action context. * @return the collectionViewDescriptor. */ @SuppressWarnings("UnusedParameters") protected ICollectionViewDescriptor getCollectionViewDescriptor( Map<String, Object> context) { return collectionViewDescriptor; } /** * Sets the collectionViewDescriptor. * * @param collectionViewDescriptor * the collectionViewDescriptor to set. */ public void setCollectionViewDescriptor( ICollectionViewDescriptor collectionViewDescriptor) { this.collectionViewDescriptor = collectionViewDescriptor; } /** * Gets the componentDescriptor. * * @param context * the action context. * @return the componentDescriptor. */ @SuppressWarnings("UnusedParameters") protected IComponentDescriptor<?> getComponentDescriptor( Map<String, Object> context) { return componentDescriptor; } /** * Sets the componentDescriptor. * * @param componentDescriptor * the componentDescriptor to set. */ public void setComponentDescriptor(IComponentDescriptor<?> componentDescriptor) { this.componentDescriptor = componentDescriptor; } }