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 org.sigmah.offline.indexeddb.ObjectStore; import org.sigmah.offline.indexeddb.Request; import org.sigmah.offline.indexeddb.Store; import org.sigmah.offline.indexeddb.Transaction; import org.sigmah.offline.js.ValueJS; import org.sigmah.offline.js.ValueJSIdentifierFactory; import org.sigmah.shared.command.GetValue; import org.sigmah.shared.command.UpdateProject; import org.sigmah.shared.command.result.ValueResult; import org.sigmah.shared.command.result.VoidResult; import org.sigmah.shared.dto.element.event.ValueEventWrapper; import com.allen_sauer.gwt.log.client.Log; import com.google.gwt.core.client.JsArray; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.inject.Inject; import com.google.inject.Singleton; import org.sigmah.offline.indexeddb.IndexedDB; import org.sigmah.offline.indexeddb.OpenDatabaseRequest; import org.sigmah.offline.js.FileDataJS; import org.sigmah.offline.js.FileJS; import org.sigmah.offline.js.FileVersionJS; import org.sigmah.offline.js.ListableValueJS; import org.sigmah.offline.sync.AsyncAdapter; import org.sigmah.offline.sync.SuccessCallback; import org.sigmah.shared.dto.element.FlexibleElementDTO; /** * Asynchronous DAO for saving and loading the values of the flexible elements. * * @author Raphaƫl Calabro (rcalabro@ideia.fr) */ @Singleton public class ValueAsyncDAO extends BaseAsyncDAO<Store> { @Inject private FileDataAsyncDAO fileDataAsyncDAO; /** * {@inheritDoc} */ @Override public OpenDatabaseRequest<Store> openDatabase() { return IndexedDB.openUserDatabase(getAuthentication()); } /** * {@inheritDoc} */ @Override public Class<Store> getSchema() { return Store.class; } public void saveOrUpdate(final GetValue getValue, final ValueResult valueResult) { saveOrUpdate(getValue, valueResult, null); } public void saveOrUpdate(final GetValue getValue, final ValueResult valueResult, final AsyncCallback<VoidResult> callback) { openTransaction(Transaction.Mode.READ_WRITE, new OpenTransactionHandler<Store>() { @Override public void onTransaction(final Transaction<Store> transaction) { saveOrUpdate(getValue, valueResult, callback, transaction); } }); } public void saveOrUpdate(final GetValue getValue, final ValueResult valueResult, final AsyncCallback<VoidResult> callback, final Transaction<Store> transaction) { final ObjectStore valueObjectStore = transaction.getObjectStore(getRequiredStore()); final ValueJS valueJS = ValueJS.toJavaScript(getValue, valueResult); valueObjectStore.put(valueJS).addCallback(new AsyncAdapter<Request, VoidResult>(callback)); } public void saveOrUpdate(final UpdateProject updateProject, final ValueEventWrapper valueEventWrapper, final ValueResult originalValue, final AsyncCallback<VoidResult> callback) { openTransaction(Transaction.Mode.READ_WRITE, new OpenTransactionHandler<Store>() { @Override public void onTransaction(final Transaction<Store> transaction) { saveOrUpdate(updateProject, valueEventWrapper, originalValue, callback, transaction); } }); } public void saveOrUpdate(final UpdateProject updateProject, final ValueEventWrapper valueEventWrapper, final ValueResult originalValue, final AsyncCallback<VoidResult> callback, final Transaction<Store> transaction) { final ObjectStore valueObjectStore = transaction.getObjectStore(getRequiredStore()); final ValueJS valueJS = ValueJS.toJavaScript(updateProject, valueEventWrapper, originalValue); valueObjectStore.put(valueJS).addCallback(new AsyncAdapter<Request, VoidResult>(callback)); } public void saveOrUpdate(final String value, final FlexibleElementDTO flexibleElement, final int projectId, final AsyncCallback<VoidResult> callback) { openTransaction(Transaction.Mode.READ_WRITE, new OpenTransactionHandler<Store>() { @Override public void onTransaction(final Transaction<Store> transaction) { saveOrUpdate(value, flexibleElement, projectId, callback, transaction); } }); } public void saveOrUpdate(final String value, final FlexibleElementDTO flexibleElement, final int projectId, final AsyncCallback<VoidResult> callback, final Transaction<Store> transaction) { final ObjectStore valueObjectStore = transaction.getObjectStore(getRequiredStore()); final ValueJS valueJS = ValueJS.toJavaScript(value, flexibleElement, projectId); valueObjectStore.put(valueJS).addCallback(new AsyncAdapter<Request, VoidResult>(callback)); } public void get(final GetValue getValue, final AsyncCallback<ValueResult> callback) { get(ValueJSIdentifierFactory.toIdentifier(getValue), callback); } public void get(final String id, final AsyncCallback<ValueResult> callback) { openTransaction(Transaction.Mode.READ_ONLY, new OpenTransactionHandler<Store>() { @Override public void onTransaction(Transaction<Store> transaction) { get(id, callback, transaction); } }); } public void get(final String id, final AsyncCallback<ValueResult> callback, Transaction<Store> transaction) { final ObjectStore valueObjectStore = transaction.getObjectStore(getRequiredStore()); valueObjectStore.get(id).addCallback(new SuccessCallback<Request>(callback) { @Override public void onSuccess(Request request) { final ValueJS valueJS = (ValueJS) request.getResult(); if (valueJS != null) { verifyIfFileVersionsAreAvailable(valueJS); callback.onSuccess(valueJS.toValueResult()); } else { // No value has been saved for the requested element Log.warn("No value saved locally for id " + id); callback.onSuccess(new ValueResult()); } } }); } /** * Sets the <code>available</code> flag on {@link FileVersionJS} instances * by searching in the FileData table. * * @param valueJS Value to verifiy. */ private void verifyIfFileVersionsAreAvailable(ValueJS valueJS) { final JsArray<ListableValueJS> values = valueJS.getValues(); if (values != null) { for (int parent = 0; parent < values.length(); parent++) { final ListableValueJS listableValue = values.get(parent); if (listableValue.getListableValueTypeEnum() == ListableValueJS.Type.FILE) { final FileJS file = (FileJS)listableValue; final JsArray<FileVersionJS> versions = file.getVersions(); for (int child = 0; child < versions.length(); child++) { final FileVersionJS version = versions.get(child); fileDataAsyncDAO.getByFileVersionId(version.getId(), new SuccessCallback<FileDataJS>() { @Override public void onSuccess(FileDataJS result) { version.setAvailable(result != null); } }); } } } } } /** * {@inheritDoc} */ @Override public Store getRequiredStore() { return Store.VALUE; } }