package org.sigmah.offline.presenter;
/*
* #%L
* Sigmah
* %%
* Copyright (C) 2010 - 2016 URD
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.allen_sauer.gwt.log.client.Log;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.widget.grid.GridSelectionModel;
import com.extjs.gxt.ui.client.widget.treegrid.TreeGrid;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import java.util.List;
import org.sigmah.client.dispatch.CommandResultHandler;
import org.sigmah.client.dispatch.monitor.LoadingMask;
import org.sigmah.client.i18n.I18N;
import org.sigmah.client.inject.Injector;
import org.sigmah.client.page.Page;
import org.sigmah.client.page.PageRequest;
import org.sigmah.client.page.RequestParameter;
import org.sigmah.client.ui.presenter.base.AbstractPagePresenter;
import org.sigmah.client.ui.view.base.ViewPopupInterface;
import org.sigmah.client.ui.widget.Loadable;
import org.sigmah.client.ui.widget.button.Button;
import org.sigmah.client.ui.zone.Zone;
import org.sigmah.offline.dao.OrgUnitAsyncDAO;
import org.sigmah.offline.dao.ProjectAsyncDAO;
import org.sigmah.offline.dao.RequestManager;
import org.sigmah.offline.dao.RequestManagerCallback;
import org.sigmah.offline.dao.TransfertAsyncDAO;
import org.sigmah.offline.js.TransfertJS;
import org.sigmah.offline.view.FileSelectionView;
import org.sigmah.shared.command.GetFilesFromFavoriteProjects;
import org.sigmah.shared.command.result.ListResult;
import org.sigmah.shared.command.result.VoidResult;
import org.sigmah.shared.dto.ProjectDTO;
import org.sigmah.shared.dto.base.EntityDTO;
import org.sigmah.shared.dto.orgunit.OrgUnitDTO;
import org.sigmah.shared.dto.value.FileUploadUtils;
import org.sigmah.shared.dto.value.FileVersionDTO;
import org.sigmah.shared.file.HasProgressListeners;
import org.sigmah.shared.file.TransfertManager;
import org.sigmah.shared.file.TransfertType;
/**
* Presenter for the popup that allow the user to select which files he wants
* to cache.
*
* @author Raphaƫl Calabro (rcalabro@ideia.fr)
*/
public class FileSelectionPresenter extends AbstractPagePresenter<FileSelectionPresenter.View> {
/**
* Description of the view managed by this presenter.
*/
@ImplementedBy(FileSelectionView.class)
public static interface View extends ViewPopupInterface {
TreeGrid<TreeGridFileModel> getUploadGrid();
TreeGrid<TreeGridFileModel> getDownloadGrid();
TreeStore<TreeGridFileModel> getUploadStore();
TreeStore<TreeGridFileModel> getDownloadStore();
GridSelectionModel<TreeGridFileModel> getUploadSelectionModel();
GridSelectionModel<TreeGridFileModel> getDownloadSelectionModel();
void addFileVersionToUploadGrid(FileVersionDTO fileVersion, EntityDTO<Integer> parent);
void addFileVersionToDownloadGrid(FileVersionDTO fileVersion, EntityDTO<Integer> parent);
void setUploadSelectedFileSize(long totalSize);
void setDownloadSelectedFileSize(long totalSize);
void selectAndExpandAll();
void clear();
Button getCancelButton();
Button getTransferFilesButton();
}
@Inject
private TransfertAsyncDAO transfertAsyncDAO;
@Inject
private ProjectAsyncDAO projectAsyncDAO;
@Inject
private OrgUnitAsyncDAO orgUnitAsyncDAO;
@Inject
private TransfertManager transfertManager;
/**
* Presenter's initialization.
*
* @param view
* The view managed by the presenter.
* @param injector
* The application injector.
*/
@Inject
protected FileSelectionPresenter(final View view, final Injector injector) {
super(view, injector);
}
@Override
public Page getPage() {
return Page.OFFLINE_SELECT_FILES;
}
@Override
public void onBind() {
setPageTitle(I18N.CONSTANTS.sigmahOfflinePrepareOfflineFileTransferPopup());
view.getCancelButton().addSelectionListener(new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
hideView();
}
});
view.getTransferFilesButton().addSelectionListener(new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
transferSelectedFiles();
hideView();
}
});
view.getUploadSelectionModel().addListener(Events.SelectionChange, new Listener<BaseEvent>() {
@Override
public void handleEvent(BaseEvent be) {
long totalSize = 0L;
for(final TreeGridFileModel model : view.getUploadSelectionModel().getSelectedItems()) {
if(model.getDTO() instanceof FileVersionDTO) {
final FileVersionDTO fileVersion = (FileVersionDTO) model.getDTO();
totalSize += fileVersion.getSize();
}
}
view.setUploadSelectedFileSize(totalSize);
}
});
view.getDownloadSelectionModel().addListener(Events.SelectionChange, new Listener<BaseEvent>() {
@Override
public void handleEvent(BaseEvent be) {
long totalSize = 0L;
for(final TreeGridFileModel model : view.getDownloadSelectionModel().getSelectedItems()) {
if(model.getDTO() instanceof FileVersionDTO) {
final FileVersionDTO fileVersion = (FileVersionDTO) model.getDTO();
totalSize += fileVersion.getSize();
}
}
view.setDownloadSelectedFileSize(totalSize);
}
});
}
@Override
public void onPageRequest(PageRequest request) {
view.clear();
final Loadable[] loadables = new Loadable[] {
new LoadingMask(view.getDownloadGrid()),
new LoadingMask(view.getUploadGrid()),
view.getTransferFilesButton()};
final RequestManager<VoidResult> manager = new RequestManager<VoidResult>(null, new CommandResultHandler<VoidResult>() {
@Override
protected void onCommandSuccess(VoidResult result) {
view.getUploadStore().commitChanges();
view.getDownloadStore().commitChanges();
view.selectAndExpandAll();
for(final Loadable loadable : loadables) {
loadable.setLoading(false);
}
}
});
// Find local files.
final int uploadReady = manager.prepareRequest();
transfertAsyncDAO.getAll(TransfertType.UPLOAD, new RequestManagerCallback<VoidResult, List<TransfertJS>>(manager) {
@Override
public void onRequestSuccess(List<TransfertJS> transfers) {
for(final TransfertJS transfert : transfers) {
addTransfer(transfert, manager);
}
manager.setRequestSuccess(uploadReady);
}
});
// Find distant files.
final int downloadReady = manager.prepareRequest();
dispatch.execute(new GetFilesFromFavoriteProjects(), new RequestManagerCallback<VoidResult, ListResult<TreeGridFileModel>>(manager) {
@Override
public void onRequestSuccess(ListResult<TreeGridFileModel> result) {
for(final TreeGridFileModel model : result.getList()) {
for(final FileVersionDTO fileVersion : model.getChildren()) {
transfertManager.isCached(fileVersion, new RequestManagerCallback<VoidResult, Boolean>(manager) {
@Override
public void onRequestSuccess(Boolean cached) {
if(cached == null || !cached) {
view.addFileVersionToDownloadGrid(fileVersion, model.getDTO());
}
}
});
}
}
manager.setRequestSuccess(downloadReady);
}
});
for(final Loadable loadable : loadables) {
loadable.setLoading(true);
}
manager.ready();
}
private <M> void addTransfer(TransfertJS transfert, RequestManager<M> manager) {
final FileVersionDTO fileVersion = transfert.getFileVersion().toDTO();
final String parentIdProperty = transfert.getProperties().get(FileUploadUtils.DOCUMENT_PROJECT);
if(parentIdProperty == null) {
Log.error("No parent for file version " + fileVersion.getId());
}
final int parentId = Integer.parseInt(parentIdProperty);
projectAsyncDAO.getWithoutDependencies(parentId, new RequestManagerCallback<M, ProjectDTO>(manager) {
@Override
public void onRequestSuccess(ProjectDTO project) {
if(project != null) {
view.addFileVersionToUploadGrid(fileVersion, project);
}
}
});
orgUnitAsyncDAO.getWithoutDependencies(parentId, new RequestManagerCallback<M, OrgUnitDTO>(manager) {
@Override
public void onRequestSuccess(OrgUnitDTO orgUnit) {
if(orgUnit != null) {
view.addFileVersionToUploadGrid(fileVersion, orgUnit);
}
}
});
}
private void transferSelectedFiles() {
// Uploads
final List<TreeGridFileModel> uploads = view.getUploadSelectionModel().getSelectedItems();
for(final TreeGridFileModel model : uploads) {
if(model.getDTO() instanceof FileVersionDTO) {
final FileVersionDTO fileVersion = (FileVersionDTO) model.getDTO();
transfertAsyncDAO.getByFileVersionId(fileVersion.getId(), new AsyncCallback<TransfertJS>() {
@Override
public void onFailure(Throwable caught) {
Log.error("An error occured while fetching the content of file version id " + fileVersion.getId() + '.', caught);
}
@Override
public void onSuccess(TransfertJS result) {
((HasProgressListeners)transfertManager).resumeUpload(result);
}
});
}
}
// Downloads
final List<TreeGridFileModel> downloads = view.getDownloadSelectionModel().getSelectedItems();
for(final TreeGridFileModel model : downloads) {
if(model.getDTO() instanceof FileVersionDTO) {
final FileVersionDTO fileVersion = (FileVersionDTO) model.getDTO();
transfertManager.cache(fileVersion);
}
}
eventBus.updateZoneRequest(Zone.OFFLINE_BANNER.requestWith(RequestParameter.SHOW_BRIEFLY, true));
}
}