/** * Copyright 2015 ArcBees Inc. * * 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.arcbees.gaestudio.client.application.entity; import java.util.List; import java.util.Set; import javax.inject.Inject; import com.arcbees.gaestudio.client.application.entity.editor.EntitiesEditorPresenter; import com.arcbees.gaestudio.client.application.entity.editor.EntityEditorFactory; import com.arcbees.gaestudio.client.application.entity.editor.EntityEditorPresenter; import com.arcbees.gaestudio.client.application.entity.editor.InvalidEntityFieldsException; import com.arcbees.gaestudio.client.application.entity.editor.PropertyEditorErrorEvent; import com.arcbees.gaestudio.client.application.event.DisplayMessageEvent; import com.arcbees.gaestudio.client.application.visualizer.ParsedEntity; import com.arcbees.gaestudio.client.application.visualizer.VisualizerPresenter; import com.arcbees.gaestudio.client.application.visualizer.event.EditEntitiesEvent; import com.arcbees.gaestudio.client.application.visualizer.event.EntitiesSavedEvent; import com.arcbees.gaestudio.client.application.visualizer.event.EntitySavedEvent; import com.arcbees.gaestudio.client.application.widget.message.Message; import com.arcbees.gaestudio.client.application.widget.message.MessageStyle; import com.arcbees.gaestudio.client.place.NameTokens; import com.arcbees.gaestudio.client.resources.AppConstants; import com.arcbees.gaestudio.client.rest.EntitiesService; import com.arcbees.gaestudio.client.rest.EntityService; import com.arcbees.gaestudio.client.util.AsyncCallbackImpl; import com.arcbees.gaestudio.shared.dto.entity.EntityDto; import com.arcbees.gaestudio.shared.rest.UrlParameters; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.collect.FluentIterable; import com.google.web.bindery.event.shared.EventBus; import com.gwtplatform.dispatch.rest.client.RestDispatch; import com.gwtplatform.dispatch.rest.shared.RestAction; import com.gwtplatform.mvp.client.HasUiHandlers; import com.gwtplatform.mvp.client.Presenter; import com.gwtplatform.mvp.client.View; import com.gwtplatform.mvp.client.annotations.NameToken; import com.gwtplatform.mvp.client.annotations.ProxyEvent; import com.gwtplatform.mvp.client.annotations.ProxyStandard; import com.gwtplatform.mvp.client.proxy.PlaceManager; import com.gwtplatform.mvp.client.proxy.ProxyPlace; import com.gwtplatform.mvp.shared.proxy.PlaceRequest; public class EditEntityPresenter extends Presenter<EditEntityPresenter.MyView, EditEntityPresenter.MyProxy> implements EditEntityUiHandlers, PropertyEditorErrorEvent.PropertyEditorErrorHandler, EditEntitiesEvent.EntitiesSelectedHandler { interface MyView extends View, HasUiHandlers<EditEntityUiHandlers> { void showError(String message); void clearErrors(); void showErrorsTitle(String title); } @ProxyStandard @NameToken(NameTokens.editEntity) interface MyProxy extends ProxyPlace<EditEntityPresenter> { } public static final Object EDITOR_SLOT = new Object(); private final RestDispatch restDispatch; private final EntitiesService entitiesService; private final EntityService entityService; private final EntityEditorFactory entityEditorFactory; private final AppConstants appConstants; private final PlaceManager placeManager; private ParsedEntity currentEntity; private EntityEditorPresenter entityEditor; private Set<ParsedEntity> currentEntities; private EntitiesEditorPresenter entitiesEditor; @Inject EditEntityPresenter( EventBus eventBus, MyView view, MyProxy proxy, RestDispatch restDispatch, PlaceManager placeManager, EntitiesService entitiesService, EntityService entityService, EntityEditorFactory entityEditorFactory, AppConstants appConstants) { super(eventBus, view, proxy, VisualizerPresenter.SLOT_ENTITY_DETAILS); this.restDispatch = restDispatch; this.entitiesService = entitiesService; this.entityService = entityService; this.placeManager = placeManager; this.entityEditorFactory = entityEditorFactory; this.appConstants = appConstants; getView().setUiHandlers(this); } @Override public void prepareFromRequest(final PlaceRequest request) { super.prepareFromRequest(request); String encodedKeys = request.getParameter(UrlParameters.KEY, ""); List<String> stringKeys = Splitter.on(",").splitToList(encodedKeys); if (stringKeys.size() == 1) { editEntity(stringKeys.get(0)); } else if (!stringKeys.isEmpty()) { editEntities(); } } @Override public boolean useManualReveal() { return true; } @Override public void save() { getView().clearErrors(); if (currentEntities == null) { saveEntity(); } else { saveEntities(); } } @Override public void cancel() { revealEntitiesList(); } @Override public void onPropertyEditorError(PropertyEditorErrorEvent event) { getView().showError(event.getError()); } @ProxyEvent @Override public void onEditEntitiesSelected(EditEntitiesEvent event) { currentEntity = null; currentEntities = event.getParsedEntities(); List<String> keys = FluentIterable.from(currentEntities) .transform(new Function<ParsedEntity, String>() { @Override public String apply(ParsedEntity input) { return input.getKey().getEncodedKey(); } }).toList(); String keysParam = Joiner.on(",").join(keys); placeManager.revealPlace(new PlaceRequest.Builder() .nameToken(NameTokens.editEntity) .with(UrlParameters.KEY, keysParam) .build()); } @Override protected void onBind() { super.onBind(); addRegisteredHandler(PropertyEditorErrorEvent.getType(), this); } private void resetEditedEntities() { currentEntities = null; currentEntity = null; } private void saveEntity() { try { updateEntity(); } catch (InvalidEntityFieldsException e) { getView().showErrorsTitle(appConstants.invalidFields()); } } private void saveEntities() { try { updateEntities(); } catch (InvalidEntityFieldsException e) { getView().showErrorsTitle(appConstants.invalidFields()); } } private void onSaveEntityFailed(Throwable caught) { String message = caught.getMessage(); if (message == null) { message = appConstants.errorSavingChanges(); } getView().showError(message); } private void revealEntitiesList() { resetEditedEntities(); PlaceRequest.Builder builder = new PlaceRequest.Builder(placeManager.getCurrentPlaceRequest()) .nameToken(NameTokens.visualizer) .without(UrlParameters.KEY); placeManager.revealPlace(builder.build()); } private void editEntities() { entitiesEditor = entityEditorFactory.create(currentEntities); setInSlot(EDITOR_SLOT, entitiesEditor); getProxy().manualReveal(this); } private void editEntity(String key) { String failureMessage = appConstants.failedGettingEntity(); AsyncCallbackImpl<EntityDto> callback = new AsyncCallbackImpl<EntityDto>(failureMessage) { @Override public void onSuccess(EntityDto result) { currentEntity = new ParsedEntity(result); currentEntities = null; entityEditor = entityEditorFactory.create(currentEntity); setInSlot(EDITOR_SLOT, entityEditor); getProxy().manualReveal(EditEntityPresenter.this); } @Override public void handleFailure(Throwable caught) { super.handleFailure(caught); getProxy().manualRevealFailed(); } }; RestAction<EntityDto> getEntityAction = entityService.getEntity(key); restDispatch.execute(getEntityAction, callback); } private void onSaveEntitySucceeded(EntityDto newEntityDto) { EntitySavedEvent.fire(this, newEntityDto); DisplayMessageEvent.fire(this, new Message(appConstants.entitySaved(), MessageStyle.SUCCESS)); revealEntitiesList(); } private void onSaveEntitiesSucceeded(List<EntityDto> entities) { DisplayMessageEvent.fire(this, new Message(appConstants.entitiesSaved(), MessageStyle.SUCCESS)); EntitiesSavedEvent.fire(this, entities); resetEditedEntities(); } private void updateEntity() throws InvalidEntityFieldsException { EntityDto entityDto = entityEditor.flush().getEntityDto(); restDispatch.execute(entityService.updateEntity(entityDto), new AsyncCallbackImpl<EntityDto>() { @Override public void handleFailure(Throwable caught) { onSaveEntityFailed(caught); } @Override public void onSuccess(EntityDto result) { onSaveEntitySucceeded(result); } } ); } private void updateEntities() { List<EntityDto> entities = entitiesEditor.flush(); restDispatch.execute(entitiesService.updateEntities(entities), new AsyncCallbackImpl<List<EntityDto>>() { @Override public void handleFailure(Throwable caught) { onSaveEntityFailed(caught); } @Override public void onSuccess(List<EntityDto> entities) { onSaveEntitiesSucceeded(entities); } } ); } }