/* * 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.std; import java.util.Collection; import java.util.Locale; import java.util.Map; import org.jspresso.framework.action.IActionHandler; import org.jspresso.framework.application.backend.session.EMergeMode; import org.jspresso.framework.application.frontend.action.CloseDialogAction; import org.jspresso.framework.application.frontend.action.FrontendAction; import org.jspresso.framework.model.entity.IEntity; import org.jspresso.framework.util.gate.IGate; import org.jspresso.framework.util.gui.Icon; import org.jspresso.framework.util.i18n.ITranslationProvider; import org.jspresso.framework.view.action.IDisplayableAction; /** * This action should be installed on collection views. It takes the selected * component and edit it in a modal dialog. Editing happens in a "Unit of * Work" meaning that it can be rolled-back when canceling. * * @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 EditSelectedComponentAction<E, F, G> extends AbstractEditComponentAction<E, F, G> { private FrontendAction<E, F, G> cancelAction; private FrontendAction<E, F, G> okAction; /** * Gets the cancelAction. * * @return the cancelAction. */ @Override protected IDisplayableAction getCancelAction() { return cancelAction; } /** * Gets the okAction. * * @return the okAction. */ @Override protected IDisplayableAction getOkAction() { return okAction; } /** * {@inheritDoc} */ @Override public boolean execute(IActionHandler actionHandler, Map<String, Object> context) { if (!getBackendController(context).isUnitOfWorkActive()) { getBackendController(context).beginUnitOfWork(); } try { return super.execute(actionHandler, context); } catch (RuntimeException ex) { getBackendController(context).rollbackUnitOfWork(); throw ex; } } /** * Gets the selected model. * * @param context * the action context. * @return the model. */ @Override protected Object getComponentToEdit(Map<String, Object> context) { IEntity uowEntity = getBackendController(context).cloneInUnitOfWork( (IEntity) getSelectedModel(context)); return uowEntity; } /** * Sets the cancelAction. * * @param cancelAction * the cancelAction to set. */ public void setCancelAction(FrontendAction<E, F, G> cancelAction) { this.cancelAction = new UowRollbackerAction<>(cancelAction); } /** * Sets the okAction. * * @param okAction * the okAction to set. */ public void setOkAction(FrontendAction<E, F, G> okAction) { this.okAction = new UowRollbackerAction<>(okAction); } /** * Default OK action. * * @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 static class DefaultOkAction<E, F, G> extends CloseDialogAction<E, F, G> { /** * Merges eagerly the edited entity. * <p> * {@inheritDoc} */ @Override public boolean execute(IActionHandler actionHandler, Map<String, Object> context) { IEntity entityClone = getModel(context); getBackendController(context).merge(entityClone, EMergeMode.MERGE_EAGER); return super.execute(actionHandler, context); } } /** * A wrapper action that roll backs the current UOW before delegating to its * delegate. * * @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 static class UowRollbackerAction<E, F, G> extends FrontendAction<E, F, G> { private final FrontendAction<E, F, G> delegate; /** * Constructs a new {@code UowRollbackerAction} instance. * * @param delegate * the action to finally delegate to. */ public UowRollbackerAction(FrontendAction<E, F, G> delegate) { this.delegate = delegate; } /** * {@inheritDoc} */ @Override public boolean execute(IActionHandler actionHandler, Map<String, Object> context) { if (getBackendController(context).isUnitOfWorkActive()) { getBackendController(context).rollbackUnitOfWork(); } return actionHandler.execute(delegate, context); } /** * Forwards to the delegate. * <p> * {@inheritDoc} */ @Override public String getAcceleratorAsString() { return delegate.getAcceleratorAsString(); } /** * Forwards to the delegate. * <p> * {@inheritDoc} */ @Override public Collection<IGate> getActionabilityGates() { return delegate.getActionabilityGates(); } /** * Forwards to the delegate. * <p> * {@inheritDoc} */ @Override public String getDescription() { return delegate.getDescription(); } /** * Forwards to the delegate. * <p> * {@inheritDoc} */ @Override public String getI18nDescription(ITranslationProvider translationProvider, Locale locale) { return delegate.getI18nDescription(translationProvider, locale); } /** * Forwards to the delegate. * <p> * {@inheritDoc} */ @Override public String getI18nName(ITranslationProvider translationProvider, Locale locale) { return delegate.getI18nName(translationProvider, locale); } /** * Forwards to the delegate. * <p> * {@inheritDoc} */ @Override public Icon getIcon() { return delegate.getIcon(); } /** * Forwards to the delegate. * <p> * {@inheritDoc} */ @Override public String getMnemonicAsString() { return delegate.getMnemonicAsString(); } /** * Forwards to the delegate. * <p> * {@inheritDoc} */ @Override public String getName() { return delegate.getName(); } /** * Forwards to the delegate. * <p> * {@inheritDoc} */ @Override public String getPermId() { return delegate.getPermId(); } /** * Forwards to the delegate. * <p> * {@inheritDoc} */ @Override public Collection<String> getGrantedRoles() { return delegate.getGrantedRoles(); } /** * Forwards to the delegate. * <p> * {@inheritDoc} */ @Override public String getStyleName() { return delegate.getStyleName(); } } }