/* * Copyright 2014 cruxframework.org. * * 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 org.cruxframework.crux.core.client.dataprovider; import org.cruxframework.crux.core.client.collection.Array; import org.cruxframework.crux.core.client.collection.CollectionFactory; import com.google.gwt.event.shared.HandlerRegistration; /** * @author Thiago da Rosa de Bustamante * */ public abstract class AbstractDataProvider<T> implements DataProvider<T> { protected int currentRecord = -1; protected Array<DataProviderRecord<T>> data = CollectionFactory.createArray(); protected Array<DataChangedHandler> dataChangedHandlers; protected DataProvider.EditionDataHandler<T> dataHandler; protected Array<DataLoadedHandler> dataLoadedHandlers; protected Array<DataSelectionHandler<T>> dataSelectionHandlers; protected Array<DataSortedHandler> dataSortedHandlers; protected Array<DataLoadStoppedHandler> dataStopLoadHandlers; protected boolean loaded = false; protected Array<ResetHandler> resetHandlers; protected SelectionMode selectionMode = SelectionMode.multiple; protected Array<TransactionEndHandler> transactionEndHandlers; protected Array<TransactionStartHandler> transactionStartHandlers; public AbstractDataProvider() { } public AbstractDataProvider(EditionDataHandler<T> dataHandler) { this(); setEditionDataHandler(dataHandler); } @Override public HandlerRegistration addDataChangedHandler(final DataChangedHandler handler) { if (dataChangedHandlers == null) { dataChangedHandlers = CollectionFactory.createArray(); } dataChangedHandlers.add(handler); return new HandlerRegistration() { @Override public void removeHandler() { int index = dataChangedHandlers.indexOf(handler); if (index >= 0) { dataChangedHandlers.remove(index); } } }; } @Override public HandlerRegistration addDataLoadedHandler(final DataLoadedHandler handler) { if (dataLoadedHandlers == null) { dataLoadedHandlers = CollectionFactory.createArray(); } dataLoadedHandlers.add(handler); return new HandlerRegistration() { @Override public void removeHandler() { int index = dataLoadedHandlers.indexOf(handler); if (index >= 0) { dataLoadedHandlers.remove(index); } } }; } @Override public HandlerRegistration addDataSelectionHandler(final DataSelectionHandler<T> handler) { if (dataSelectionHandlers == null) { dataSelectionHandlers = CollectionFactory.createArray(); } dataSelectionHandlers.add(handler); return new HandlerRegistration() { @Override public void removeHandler() { int index = dataSelectionHandlers.indexOf(handler); if (index >= 0) { dataSelectionHandlers.remove(index); } } }; } @Override public HandlerRegistration addDataSortedHandler(final DataSortedHandler handler) { if (dataSortedHandlers == null) { dataSortedHandlers = CollectionFactory.createArray(); } dataSortedHandlers.add(handler); return new HandlerRegistration() { @Override public void removeHandler() { int index = dataSortedHandlers.indexOf(handler); if (index >= 0) { dataSortedHandlers.remove(index); } } }; } @Override public HandlerRegistration addLoadStoppedHandler(final DataLoadStoppedHandler handler) { if (dataStopLoadHandlers == null) { dataStopLoadHandlers = CollectionFactory.createArray(); } dataStopLoadHandlers.add(handler); return new HandlerRegistration() { @Override public void removeHandler() { int index = dataStopLoadHandlers.indexOf(handler); if (index >= 0) { dataStopLoadHandlers.remove(index); } } }; } @Override public HandlerRegistration addResetHandler(final ResetHandler handler) { if (resetHandlers == null) { resetHandlers = CollectionFactory.createArray(); } resetHandlers.add(handler); return new HandlerRegistration() { @Override public void removeHandler() { int index = resetHandlers.indexOf(handler); if (index >= 0) { resetHandlers.remove(index); } } }; } @Override public HandlerRegistration addTransactionEndHandler(final TransactionEndHandler handler) { if (transactionEndHandlers == null) { transactionEndHandlers = CollectionFactory.createArray(); } transactionEndHandlers.add(handler); return new HandlerRegistration() { @Override public void removeHandler() { int index = transactionEndHandlers.indexOf(handler); if (index >= 0) { transactionEndHandlers.remove(index); } } }; } @Override public HandlerRegistration addTransactionStartHandler(final TransactionStartHandler handler) { if (transactionStartHandlers == null) { transactionStartHandlers = CollectionFactory.createArray(); } transactionStartHandlers.add(handler); return new HandlerRegistration() { @Override public void removeHandler() { int index = transactionStartHandlers.indexOf(handler); if (index >= 0) { transactionStartHandlers.remove(index); } } }; } @Override public T get() { DataProviderRecord<T> record = getRecord(); if (isEditable()) { T clonedRecord = null; if(record != null) { clonedRecord = dataHandler.clone(record.getRecordObject()); } return clonedRecord; } return record != null ? record.getRecordObject() : null; } @Override public T get(int index) { DataProviderRecord<T> record = data.get(index); if (isEditable()) { T clonedRecord = null; if(record != null) { clonedRecord = dataHandler.clone(record.getRecordObject()); } return clonedRecord; } if(record == null) { return null; } return record.getRecordObject(); } @Override public SelectionMode getSelectionMode() { return selectionMode; } @Override public boolean isEditable() { return this.dataHandler != null; } @Override public boolean isLoaded() { return loaded; } @Override public boolean isSelected(int index) { if (index >= 0 && index < data.size()) { DataProviderRecord<T> record = data.get(index); return record != null && record.isSelected(); } return false; } @Override public void next() { if (hasNext()) { currentRecord++; } } @Override public void previous() { if (hasPrevious()) { currentRecord--; } } @Override public void read(DataReader<T> reader) { if (reader != null) { DataProviderRecord<T> record = getRecord(); if(record != null) { reader.read(record.getRecordObject(), currentRecord); } else { reader.read(null, currentRecord); } } } @Override public void read(int index, DataReader<T> reader) { if (reader != null) { DataProviderRecord<T> record = data.get(index); if (record != null) { reader.read(record.getRecordObject(), currentRecord); } else { reader.read(null, currentRecord); } } } @Override public void reset() { if(data != null) { data = CollectionFactory.createArray(); } currentRecord = -1; loaded = false; fireResetEvent(); } @Override public void setEditionDataHandler(EditionDataHandler<T> dataHandler) { ensureNotDirty(); this.dataHandler = dataHandler; } @Override public void setSelectionMode(SelectionMode selectionMode) { DataProviderRecord<T>[] records = getSelectedRecords(); if ((selectionMode.equals(SelectionMode.multiple) && records != null && records.length > 1) || (selectionMode.equals(SelectionMode.unselectable) && records != null && records.length > 0)) { throw new DataProviderException("Can not change the seletion mode. The provided mode is " + "incompatible with the dataProvider actual state. It has already selected records."); } this.selectionMode = selectionMode; } @Override public void stopLoading() { fireStopLoadEvent(); } protected void concludeEdition(boolean commited) { fireTransactionEndEvent(commited); } protected void ensureNotDirty() { if (isDirty()) { throw new DataProviderException("There are uncommited changes on this DataProvider. Commit or rollback it first."); } } protected void fireDataChangedEvent(DataProviderRecord<?> currentRecord, int recordPosition) { if (dataChangedHandlers != null) { DataChangedEvent event = new DataChangedEvent(this, currentRecord, recordPosition); for (int i = 0; i< dataChangedHandlers.size(); i++) { dataChangedHandlers.get(i).onDataChanged(event); } } } protected void fireDataSelectionEvent(Array<DataProviderRecord<T>> changedRecords) { if (dataSelectionHandlers != null) { DataSelectionEvent<T> event = new DataSelectionEvent<T>(this, changedRecords); for (int i = 0; i< dataSelectionHandlers.size(); i++) { dataSelectionHandlers.get(i).onDataSelection(event); } } } protected void fireLoadedEvent() { if (dataLoadedHandlers != null) { DataLoadedEvent event = new DataLoadedEvent(this); for (int i = 0; i< dataLoadedHandlers.size(); i++) { dataLoadedHandlers.get(i).onLoaded(event); } } } protected void fireResetEvent() { if (resetHandlers != null) { ResetEvent event = new ResetEvent(this); for (int i = 0; i< resetHandlers.size(); i++) { resetHandlers.get(i).onReset(event); } } } protected void fireSortedEvent(boolean pageChanged) { if (dataSortedHandlers != null) { DataSortedEvent event = new DataSortedEvent(this, pageChanged); for (int i = 0; i< dataSortedHandlers.size(); i++) { dataSortedHandlers.get(i).onSorted(event); } } } protected void fireStopLoadEvent() { if (dataStopLoadHandlers != null) { DataLoadStoppedEvent event = new DataLoadStoppedEvent(this); for (int i = 0; i< dataStopLoadHandlers.size(); i++) { dataStopLoadHandlers.get(i).onLoadStopped(event); } } } protected void fireTransactionEndEvent(boolean commited) { if (transactionEndHandlers != null) { TransactionEndEvent event = new TransactionEndEvent(this, commited); for (int i = 0; i< transactionEndHandlers.size(); i++) { transactionEndHandlers.get(i).onTransactionEnd(event); } } } protected void fireTransactionStartEvent(int firstRecordToLock) { if (transactionStartHandlers != null) { TransactionStartEvent event = new TransactionStartEvent(this, firstRecordToLock); for (int i = 0; i< transactionStartHandlers.size(); i++) { transactionStartHandlers.get(i).onTransactionStart(event); } } } protected void setLoaded() { loaded = true; fireLoadedEvent(); } protected abstract void updateState(DataProviderRecord<T> record, DataProviderRecord.DataProviderRecordState previousState); }