package com.casamind.adware.client.presenter;
import java.util.ArrayList;
import java.util.List;
import com.casamind.adware.client.Adware;
import com.casamind.adware.client.event.EntityDeletedEvent;
import com.casamind.adware.client.event.EntityEditCancelledEvent;
import com.casamind.adware.client.event.EntityUpdatedEvent;
import com.casamind.adware.client.event.RPCInEvent;
import com.casamind.adware.client.event.UserMessageEvent;
import com.casamind.adware.client.helper.RPCCall;
import com.casamind.adware.client.resources.ErrorMessages;
import com.casamind.adware.client.service.DataServiceAsync;
import com.casamind.adware.shared.AccessLevels;
import com.casamind.adware.shared.InfoTypes;
import com.casamind.adware.shared.Pages;
import com.casamind.adware.shared.model.CompanySummaryDTO;
import com.casamind.adware.shared.model.EntitySummary;
import com.casamind.adware.shared.model.ProductSummaryDTO;
import com.casamind.adware.shared.model.PublisherSummaryDTO;
import com.casamind.adware.shared.model.ResourceDTO;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
public class ResourceEditPresenter implements Presenter {
private boolean isNoResourcesWarning = false;
private ResourceDTO resource;
private List<EntitySummary> compList;
private List<EntitySummary> pubList;
private List<EntitySummary> prdList;
private final DataServiceAsync rpcService;
private final SimpleEventBus eventBus;
private final Display display;
private final ErrorMessages errorMessages = GWT.create(ErrorMessages.class);
public interface Display {
HasWidgets getPreviewPanel();
HasValue<String> getName();
HasClickHandlers getSaveButton();
HasClickHandlers getDeleteButton();
HasClickHandlers getCancelButton();
HasClickHandlers getAddResourceButton();
FormPanel getFormPanel();
FileUpload getFileUpload();
Widget asWidget();
ListBox getPublisherList();
ListBox getCompanyList();
ListBox getProductList();
void setEnableUploadButton(boolean isEnabled);
void handleEntityChanged();
}
public ResourceEditPresenter(DataServiceAsync rpcService, SimpleEventBus eventBus, Display display) {
this.rpcService = rpcService;
this.eventBus = eventBus;
this.display = display;
this.resource = new ResourceDTO();
this.compList = new ArrayList<EntitySummary>();
this.pubList = new ArrayList<EntitySummary>();
this.prdList = new ArrayList<EntitySummary>();
bind();
}
public ResourceEditPresenter(final DataServiceAsync rpcService, SimpleEventBus eventBus, Display display, final Long id) {
this(rpcService, eventBus, display);
if (id == null) {
if (Adware.get().getCurrentUser().getAccessLevel() == AccessLevels.Publisher) {
this.pubList.add(Adware.get().getCurrentPublisher());
this.display.getCompanyList().addItem(Adware.get().getCurrentCompany().getDisplayName());
this.display.getPublisherList().addItem(Adware.get().getCurrentPublisher().getDisplayName());
populateProductList(Adware.get().getCurrentPublisher().getId(), null);
} else if (Adware.get().getCurrentUser().getAccessLevel() == AccessLevels.Company) {
this.display.getCompanyList().addItem(Adware.get().getCurrentCompany().getDisplayName());
this.compList.add(Adware.get().getCurrentCompany());
populatePublisherList(Adware.get().getCurrentCompany().getId(), null, null);
} else {
// the user is Admin
populateCompanyList(null, null, null);
}
} else {
new RPCCall<ResourceDTO>() {
@Override
protected void callService(AsyncCallback<ResourceDTO> cb) {
rpcService.getResource(id, cb);
}
@Override
public void onSuccess(ResourceDTO result) {
if (result != null) {
resource = result;
ResourceEditPresenter.this.display.getName().setValue(resource.getFilename());
showImage(resource.getImageURL());
selectItemsInLists(resource.getCompany().getId(), resource.getPublisher().getId(), resource.getProduct().getId());
} else {
Window.alert(errorMessages.unknownError());
}
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
startNewBlobstoreSession();
}
private void selectItemsInLists(Long companyId, Long publisherId, Long productId) {
if (Adware.get().getCurrentUser().getAccessLevel() == AccessLevels.Publisher) {
this.pubList.add(Adware.get().getCurrentPublisher());
this.display.getCompanyList().addItem(Adware.get().getCurrentCompany().getDisplayName());
this.display.getPublisherList().addItem(Adware.get().getCurrentPublisher().getDisplayName());
populateProductList(publisherId, productId);
} else if (Adware.get().getCurrentUser().getAccessLevel() == AccessLevels.Company) {
this.display.getCompanyList().addItem(Adware.get().getCurrentCompany().getDisplayName());
this.compList.add(Adware.get().getCurrentCompany());
populatePublisherList(companyId, publisherId, productId);
} else {
populateCompanyList(companyId, publisherId, productId);
}
}
private void populateCompanyList(final Long companyId, final Long publisherId, final Long productId) {
new RPCCall<List<EntitySummary>>() {
@Override
protected void callService(AsyncCallback<List<EntitySummary>> cb) {
rpcService.getCompanies(cb);
}
@Override
public void onSuccess(List<EntitySummary> result) {
for (EntitySummary entity : result) {
ResourceEditPresenter.this.display.getCompanyList().addItem(entity.getDisplayName());
ResourceEditPresenter.this.compList.add((CompanySummaryDTO) entity);
}
if (ResourceEditPresenter.this.display.getCompanyList().getItemCount() > 0) {
if (companyId == null) {
ResourceEditPresenter.this.display.getCompanyList().setSelectedIndex(0);
populatePublisherList(ResourceEditPresenter.this.compList.get(0).getId(), null, null);
} else {
int index = indexOf(ResourceEditPresenter.this.compList, companyId);
if (index != -1) {
ResourceEditPresenter.this.display.getCompanyList().setSelectedIndex(index);
populatePublisherList(companyId, publisherId, productId);
}
}
}
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
this.display.getCompanyList().addChangeHandler(new ChangeHandler() {
public void onChange(ChangeEvent event) {
int index = ResourceEditPresenter.this.display.getCompanyList().getSelectedIndex();
Long id = ResourceEditPresenter.this.compList.get(index).getId();
populatePublisherList(id, null, null);
}
});
}
private void populatePublisherList(final Long companyId, final Long publisherId, final Long productId) {
this.display.getPublisherList().clear();
this.pubList.clear();
this.display.getProductList().clear();
this.prdList.clear();
new RPCCall<List<PublisherSummaryDTO>>() {
@Override
protected void callService(AsyncCallback<List<PublisherSummaryDTO>> cb) {
rpcService.getPublisherSummariesByCompanyId(companyId, cb);
}
@Override
public void onSuccess(List<PublisherSummaryDTO> result) {
for (PublisherSummaryDTO entity : result) {
ResourceEditPresenter.this.display.getPublisherList().addItem(entity.getDisplayName());
ResourceEditPresenter.this.pubList.add(entity);
}
if (ResourceEditPresenter.this.display.getPublisherList().getItemCount() > 0) {
if (publisherId == null) {
ResourceEditPresenter.this.display.getPublisherList().setSelectedIndex(0);
populateProductList(ResourceEditPresenter.this.pubList.get(0).getId(), null);
} else {
int index = indexOf(ResourceEditPresenter.this.pubList, publisherId);
if (index != -1) {
ResourceEditPresenter.this.display.getPublisherList().setSelectedIndex(index);
populateProductList(publisherId, productId);
}
}
}
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
this.display.getPublisherList().addChangeHandler(new ChangeHandler() {
public void onChange(ChangeEvent event) {
int index = ResourceEditPresenter.this.display.getPublisherList().getSelectedIndex();
Long id = ResourceEditPresenter.this.pubList.get(index).getId();
populateProductList(id, null);
}
});
}
private void populateProductList(final Long publisherId, final Long productId) {
this.display.getProductList().clear();
this.prdList.clear();
new RPCCall<List<ProductSummaryDTO>>() {
@Override
protected void callService(AsyncCallback<List<ProductSummaryDTO>> cb) {
rpcService.getProductSummariesByPublisherId(publisherId, cb);
}
@Override
public void onSuccess(List<ProductSummaryDTO> result) {
for (ProductSummaryDTO entity : result) {
ResourceEditPresenter.this.display.getProductList().addItem(entity.getDisplayName());
ResourceEditPresenter.this.prdList.add(entity);
}
if (ResourceEditPresenter.this.display.getProductList().getItemCount() > 0) {
if (productId == null) {
ResourceEditPresenter.this.display.getProductList().setSelectedIndex(0);
} else {
int index = indexOf(ResourceEditPresenter.this.prdList, productId);
if (index != -1) {
ResourceEditPresenter.this.display.getProductList().setSelectedIndex(index);
}
}
}
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
private String formatFileName(String osPath) {
String filename = "";
if (osPath.contains("\\")) {
filename = osPath.replace("\\", "/").split("/")[osPath.replace("\\", "/").split("/").length - 1];
} else if (osPath.contains("/")) {
filename = osPath.split("/")[osPath.split("/").length - 1];
} else if (osPath.contains("::")) {
filename = osPath.split("::")[osPath.split("::").length - 1];
}
return filename;
}
public void bind() {
this.display.getAddResourceButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
ResourceEditPresenter.this.resource.setFilename(formatFileName(ResourceEditPresenter.this.display.getFileUpload().getFilename()));
ResourceEditPresenter.this.display.getName().setValue(ResourceEditPresenter.this.resource.getFilename().split("\\.")[0]);
ResourceEditPresenter.this.display.handleEntityChanged();
}
});
this.display.getSaveButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
doSave();
}
});
this.display.getDeleteButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
doDelete();
}
});
this.display.getCancelButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
eventBus.fireEvent(new EntityEditCancelledEvent());
}
});
this.display.getFormPanel().addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
@Override
public void onSubmitComplete(final SubmitCompleteEvent event) {
Adware.get().getEventBus().fireEvent(new RPCInEvent());
final String blobKey = ResourceEditPresenter.this.resource.getBlobKey();
if (blobKey != null && !"".equals(blobKey)) {
// remove old image blob
new RPCCall<Boolean>() {
@Override
protected void callService(AsyncCallback<Boolean> cb) {
rpcService.deleteBlob(blobKey, cb);
}
@Override
public void onSuccess(Boolean result) {
if (result == true) {
// if old blob remeved successfully
processImagePreview(event.getResults());
} else {
// remove newly added blob image
new RPCCall<Boolean>() {
@Override
protected void callService(AsyncCallback<Boolean> cb) {
processImagePreview(event.getResults());
rpcService.deleteBlob(event.getResults().split("\t")[0], cb);
}
@Override
public void onSuccess(Boolean result) {
// say that something went wrong
eventBus.fireEvent(new UserMessageEvent(null, InfoTypes.Error, 0));
}
@Override
public void onFailure(Throwable caught) {
if (caught instanceof com.casamind.adware.shared.exception.NotLoggedInException) {
Window.alert(errorMessages.youNeedToLogin());
} else {
Window.alert(errorMessages.rpcError(caught.toString()));
}
}
}.retry(3);
}
}
@Override
public void onFailure(Throwable caught) {
// in case of failure to remove old blob
if (caught instanceof com.casamind.adware.shared.exception.NotLoggedInException) {
Window.alert(errorMessages.youNeedToLogin());
} else {
Window.alert(errorMessages.rpcError(caught.toString()));
}
}
}.retry(3);
} else {
processImagePreview(event.getResults());
}
}
});
}
private void processImagePreview(String imageURLandKEY){
if (imageURLandKEY != null && !"".equals(imageURLandKEY)) {
ResourceEditPresenter.this.resource.setBlobKey(imageURLandKEY.split("\t")[0]);
ResourceEditPresenter.this.resource.setImageURL(imageURLandKEY.split("\t")[1]);
showImage(ResourceEditPresenter.this.resource.getImageURL());
startNewBlobstoreSession();
ResourceEditPresenter.this.display.getFormPanel().reset();
ResourceEditPresenter.this.display.handleEntityChanged();
}
}
private void showImage(String url){
Image image = new Image(url + "=s680");
ResourceEditPresenter.this.display.getPreviewPanel().clear();
ResourceEditPresenter.this.display.getPreviewPanel().add(image);
}
private void doDelete() {
if (resource == null || resource.getId() == null)
return;
if (Window.confirm(errorMessages.warningDeleteEntity(resource.getDisplayName()))) {
deleteEntity(resource);
}
}
private void deleteEntity(final ResourceDTO dto) {
new RPCCall<Boolean>() {
@Override
protected void callService(AsyncCallback<Boolean> cb) {
rpcService.deleteResource(dto, cb);
}
@Override
public void onSuccess(Boolean result) {
if (result == true) {
eventBus.fireEvent(new EntityDeletedEvent());
eventBus.fireEvent(new UserMessageEvent(null, InfoTypes.Info, 0));
} else {
eventBus.fireEvent(new UserMessageEvent(null, InfoTypes.Error, 0));
}
}
@Override
public void onFailure(Throwable caught) {
if (caught instanceof com.casamind.adware.shared.exception.NotLoggedInException) {
Window.alert(errorMessages.youNeedToLogin());
} else {
Window.alert(errorMessages.rpcError(caught.toString()));
}
}
}.retry(3);
}
private void doSave() {
if (this.isNoResourcesWarning == true) {
if (Window.confirm(errorMessages.noResourcesWarning(resource.getDisplayName())) == false) {
return;
}
}
SaveEntity(resource);
}
private void SaveEntity(final ResourceDTO dto) {
dto.setPublisher((PublisherSummaryDTO) pubList.get(display.getPublisherList().getSelectedIndex()));
dto.setProduct((ProductSummaryDTO) prdList.get(display.getProductList().getSelectedIndex()));
dto.setCompany((CompanySummaryDTO) compList.get(display.getCompanyList().getSelectedIndex()));
dto.setFilename(display.getName().getValue().trim());
// Do not retry on CREATE
int retries = 3;
if (dto.getId() == null) {
retries = 0;
}
new RPCCall<ResourceDTO>() {
@Override
protected void callService(AsyncCallback<ResourceDTO> cb) {
if (dto.getId() != null)
rpcService.updateResource(dto, cb);
else
rpcService.createResource(dto, cb);
}
@Override
public void onSuccess(ResourceDTO result) {
if (result != null) {
eventBus.fireEvent(new EntityUpdatedEvent(result));
eventBus.fireEvent(new UserMessageEvent(null, InfoTypes.Info, 0));
} else {
eventBus.fireEvent(new UserMessageEvent(null, InfoTypes.Error, 0));
}
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(retries);
}
private void startNewBlobstoreSession() {
this.display.setEnableUploadButton(false);
this.rpcService.getBlobstoreUploadUrl(Window.Location.getHref(), new AsyncCallback<String>() {
@Override
public void onSuccess(String result) {
display.getFormPanel().setAction(result);
display.getFormPanel().setEncoding(FormPanel.ENCODING_MULTIPART);
display.getFormPanel().setMethod(FormPanel.METHOD_POST);
display.setEnableUploadButton(true);
}
@Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
});
}
private int indexOf(List<EntitySummary> list, Long id) {
for (EntitySummary entity : list) {
if (entity.getId().longValue() == id.longValue()) {
return list.indexOf(entity);
}
}
return -1;
}
@Override
public void go(DeckPanel container) {
for (int i = 0; i < container.getWidgetCount(); i++) {
if (!Pages.isHomePage(container.getWidget(i).getClass()))
container.remove(i);
}
container.add(display.asWidget());
container.showWidget(container.getWidgetIndex(display.asWidget()));
}
}