package org.sigmah.offline.dao;
/*
* #%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 java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.sigmah.offline.indexeddb.*;
import org.sigmah.offline.js.UserJS;
import org.sigmah.shared.command.result.ListResult;
import org.sigmah.shared.dto.UserDTO;
import org.sigmah.shared.dto.orgunit.OrgUnitDTO;
import com.allen_sauer.gwt.log.client.Log;
/**
* Asynchronous DAO for saving and loading <code>UserDTO</code> objects.
*
* @author Raphaƫl Calabro (rcalabro@ideia.fr)
*/
@Singleton
public class UserAsyncDAO extends AbstractUserDatabaseAsyncDAO<UserDTO, UserJS> {
private final OrgUnitAsyncDAO orgUnitDAO;
@Inject
public UserAsyncDAO(OrgUnitAsyncDAO orgUnitDAO) {
this.orgUnitDAO = orgUnitDAO;
}
/**
* {@inheritDoc}
*/
@Override
public void saveOrUpdate(UserDTO userDTO, AsyncCallback<UserDTO> callback, Transaction<Store> transaction) {
super.saveOrUpdate(userDTO, callback, transaction);
// Saving its org unit
if (userDTO.getMainOrgUnit() != null) {
orgUnitDAO.saveOrUpdate(userDTO.getMainOrgUnit(), null, transaction);
}
if (userDTO.getSecondaryOrgUnits() != null) {
for (OrgUnitDTO orgUnit : userDTO.getSecondaryOrgUnits()) {
orgUnitDAO.saveOrUpdate(orgUnit, null, transaction);
}
}
}
/**
* Open a new transaction and save or replace the given objects.
*
* @param userListResult
* <code>ListResult</code> of the <code>UserDTO</code> objects to save or update.
* @param organizationId
* Identifier of the parent organization.
*/
public void saveAll(final ListResult<UserDTO> userListResult, final Integer organizationId) {
if(userListResult != null && userListResult.getList() != null) {
openTransaction(Transaction.Mode.READ_WRITE, new OpenTransactionHandler<Store>() {
@Override
public void onTransaction(Transaction<Store> transaction) {
for(final UserDTO userDTO : userListResult.getList()) {
userDTO.set("organization", organizationId);
saveOrUpdate(userDTO, null, transaction);
}
}
});
}
}
/**
* {@inheritDoc}
*/
@Override
public void get(final int id, final AsyncCallback<UserDTO> callback, final Transaction<Store> transaction) {
if(transaction.useObjectFromCache(UserDTO.class, id, callback)) {
return;
}
final ObjectStore userObjectStore = transaction.getObjectStore(Store.USER);
userObjectStore.get(id).addCallback(new AsyncCallback<Request>() {
@Override
public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
@Override
public void onSuccess(Request request) {
final UserJS userJS = request.getResult();
if(userJS != null) {
final UserDTO userDTO = userJS.toDTO();
transaction.getObjectCache().put(id, userDTO);
orgUnitDAO.get(userJS.getMainOrgUnit(), new AsyncCallback<OrgUnitDTO>() {
@Override
public void onFailure(Throwable caught) {
Log.error("Error while retrieving org unit " + userJS.getMainOrgUnit() + " for user " + userJS.getId());
}
@Override
public void onSuccess(OrgUnitDTO result) {
userDTO.setMainOrgUnit(result);
callback.onSuccess(userDTO);
}
}, transaction);
} else {
callback.onSuccess(null);
}
}
});
}
public void getByOrganization(final int organizationId, final AsyncCallback<ListResult<UserDTO>> callback) {
openTransaction(Transaction.Mode.READ_ONLY, new OpenTransactionHandler<Store>() {
@Override
public void onTransaction(final Transaction<Store> transaction) {
final ObjectStore userObjectStore = transaction.getObjectStore(Store.USER);
final Index organizationIndex = userObjectStore.index("organization");
final OpenCursorRequest openCursorRequest = organizationIndex.openCursor(IDBKeyRange.only(organizationId));
final ArrayList<UserDTO> users = new ArrayList<UserDTO>();
openCursorRequest.addCallback(new AsyncCallback<Request>() {
@Override
public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
@Override
public void onSuccess(Request request) {
final Cursor cursor = openCursorRequest.getResult();
if(cursor != null) {
final UserJS userJS = (UserJS) cursor.getValue();
final UserDTO userDTO = userJS.toDTO();
if (userJS.hasMainOrgUnit()) {
orgUnitDAO.get(userJS.getMainOrgUnit(), new AsyncCallback<OrgUnitDTO>() {
@Override
public void onFailure(Throwable caught) {
Log.error("Error while retrieving org unit " + userJS.getMainOrgUnit() + " for user " + userJS.getId());
}
@Override
public void onSuccess(OrgUnitDTO result) {
userDTO.setMainOrgUnit(result);
}
}, transaction);
}
users.add(userDTO);
cursor.next();
} else {
callback.onSuccess(new ListResult<UserDTO>(users));
}
}
});
}
});
}
public void getByOrgUnit(final int orgUnitId, final AsyncCallback<ListResult<UserDTO>> callback) {
openTransaction(Transaction.Mode.READ_ONLY, new OpenTransactionHandler<Store>() {
@Override
public void onTransaction(final Transaction<Store> transaction) {
final ObjectStore userObjectStore = transaction.getObjectStore(Store.USER);
final Index orgUnitIndex = userObjectStore.index("orgUnit");
final OpenCursorRequest openCursorRequest = orgUnitIndex.openCursor(IDBKeyRange.only(orgUnitId));
final ArrayList<UserDTO> users = new ArrayList<UserDTO>();
openCursorRequest.addCallback(new AsyncCallback<Request>() {
@Override
public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
@Override
public void onSuccess(Request request) {
final Cursor cursor = openCursorRequest.getResult();
if (cursor != null) {
final UserJS userJS = (UserJS) cursor.getValue();
users.add(userJS.toDTO());
cursor.next();
} else {
callback.onSuccess(new ListResult<UserDTO>(users));
}
}
});
}
});
}
public void getByOrgUnits(final Set<Integer> orgUnitIds, final AsyncCallback<ListResult<UserDTO>> callback) {
final List<UserDTO> users = new ArrayList<UserDTO>();
// `i` needs to be final as it is accessed asynchronously
final int[] i = {0};
for (final Integer orgUnitId : orgUnitIds) {
getByOrgUnit(orgUnitId, new AsyncCallback<ListResult<UserDTO>>() {
@Override
public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
@Override
public void onSuccess(ListResult<UserDTO> userDTOListResult) {
users.addAll(userDTOListResult.getData());
i[0]++;
if (i[0] == orgUnitIds.size()) {
callback.onSuccess(new ListResult<UserDTO>(users));
}
}
});
}
}
/**
* {@inheritDoc}
*/
@Override
public Store getRequiredStore() {
return Store.USER;
}
/**
* {@inheritDoc}
*/
@Override
public Collection<BaseAsyncDAO<Store>> getDependencies() {
final ArrayList<BaseAsyncDAO<Store>> list = new ArrayList<BaseAsyncDAO<Store>>();
list.add(orgUnitDAO);
return list;
}
/**
* {@inheritDoc}
*/
@Override
public UserJS toJavaScriptObject(UserDTO t) {
return UserJS.toJavaScript(t);
}
/**
* {@inheritDoc}
*/
@Override
public UserDTO toJavaObject(UserJS js) {
return js.toDTO();
}
}