
com.sibvisions.rad.ui.vaadin.ext.data.AbstractDataBookDataProvider Maven / Gradle / Ivy
Show all versions of jvxvaadin-server Show documentation
/*
* Copyright 2017 SIB Visions GmbH
*
* 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.
*
*
* History
*
* 06.10.2017 - [RZ] - Craetion
*/
package com.sibvisions.rad.ui.vaadin.ext.data;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import jvx.rad.model.IDataBook;
import jvx.rad.model.ModelException;
import jvx.rad.model.SortDefinition;
import jvx.rad.model.condition.ICondition;
import com.sibvisions.util.type.CommonUtil;
import com.vaadin.data.provider.AbstractBackEndDataProvider;
import com.vaadin.data.provider.Query;
import com.vaadin.data.provider.QuerySortOrder;
import com.vaadin.shared.data.sort.SortDirection;
/**
* The {@link AbstractDataBookDataProvider} is an
* {@link AbstractBackEndDataProvider} which provides the base for reading from
* an {@link IDataBook}.
*
* @param the type of the returned items.
* @author Robert Zenz
*/
public abstract class AbstractDataBookDataProvider extends AbstractBackEndDataProvider
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class members
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/** The backing {@link IDataBook}. */
protected IDataBook dataBook = null;
/** If this provider is enabled. */
protected boolean enabled = true;
/** force set filter. */
private boolean force = false;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Creates a new instance of {@link AbstractDataBookDataProvider}.
*
* @param pDataBook the {@link IDataBook}.
*/
protected AbstractDataBookDataProvider(IDataBook pDataBook)
{
super();
dataBook = pDataBook;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Abstract methods
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Gets all the items between the given indexes.
*
* Implementing classes can safely assume that the {@link IDataBook} is in
* the correct state regarding the sort order. If this provider is disabled,
* this method will not be called.
*
* @param pQuery the query.
* @param pStartRowIndex the row index at which to start, inclusive.
* @param pEndRowIndex the row index at which to stop, exclusive.
* @return the {@link Stream} of items.
* @throws ModelException if accessing the {@link IDataBook} failed.
*/
protected abstract Stream getItems(Query pQuery, int pStartRowIndex, int pEndRowIndex) throws ModelException;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Abstract methods implementation
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* {@inheritDoc}
*/
@Override
protected Stream fetchFromBackEnd(Query pQuery)
{
if (!enabled)
{
return Stream.empty();
}
try
{
prepareDataBook(pQuery);
int start = pQuery.getOffset();
int end = start + pQuery.getLimit();
Stream items = getItems(pQuery, start, end);
restoreDataBook();
return items;
}
catch (ModelException e)
{
throw new RuntimeException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
protected int sizeInBackEnd(Query pQuery)
{
if (!enabled)
{
return 0;
}
try
{
prepareDataBook(pQuery);
int count = Math.min(pQuery.getLimit(), getItemsCount(pQuery));
restoreDataBook();
return count;
}
catch (ModelException e)
{
throw new RuntimeException(e);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// User-defined methods
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Gets if this provider is enabled.
*
* If the provider is enabled, it delivers data. If it is disabled, an item
* count of zero is returned and an empty {@link Stream} instead of items.
*
* @return {@code true} if this provider is enabled.
* @see #setEnabled(boolean)
*/
public boolean isEnabled()
{
return enabled;
}
/**
* Sets if this provider is enabled.
*
* If the provider is enabled, it delivers data. If it is disabled, an item
* count of zero is returned and an empty {@link Stream} instead of items.
*
* @param pEnabled {@code true} if this provider should be enabled.
* @see #isEnabled()
*/
public void setEnabled(boolean pEnabled)
{
enabled = pEnabled;
}
/**
* Checks if the two given {@link ICondition}s are different, returning
* {@code true} in that case.
*
* This function is used to determine whether the filter on the
* {@link #dataBook} has changed or not. If this function returns
* {@code true}, the new filter will be set on the {@link #dataBook}.
*
* @param pFirstCondition the first {@link ICondition} for the test, can be
* {@code null}.
* @param pSecondCondition the second {@link ICondition} for the test, can
* be {@code null}.
* @return {@code true} if the two given {@link ICondition}s are not equal.
*/
protected boolean isDifferentFilter(ICondition pFirstCondition, ICondition pSecondCondition)
{
String firstFilterString = pFirstCondition == null ? "" : pFirstCondition.toString();
String secondFilterString = pSecondCondition == null ? "" : pSecondCondition.toString();
return !CommonUtil.equals(firstFilterString, secondFilterString);
}
/**
* Creates an {@link ICondition} for the given value.
*
* By default, this method returns the currently set filter of the
* {@link #dataBook} to preserve it.
*
* @param pValue the value to use as filter.
* @return the created {@link ICondition}, can be {@code null}.
* @throws ModelException because Martin said!
*/
protected ICondition createFilter(Object pValue) throws ModelException
{
return dataBook.getFilter();
}
/**
* Gets the item count from the {@link IDataBook} for the current query.
*
* Extending classes can safely assume that {@link #prepareDataBook(Query)}
* has been caled at this point. If this provider is disabled, this method
* will not be called.
*
* @param pQuery the {@link Query} for which to get the count.
* @return the item count.
* @throws ModelException when accessing/using the {@link IDataBook} failed.
*/
protected int getItemsCount(Query pQuery) throws ModelException
{
if (!dataBook.isAllFetched())
{
return dataBook.getRowCount() + 1;
}
else
{
return dataBook.getRowCount();
}
}
/**
* Gets if the given {@link SortDefinition} is {@code null} or empty.
*
* A {@link SortDefinition} is considered empty if the list of columns is
* either {@code null} or has no items.
*
* @param pSort the {@link SortDefinition} to check.
* @return {@code true} if the given {@link SortDefinition} can be
* considered {@code null} or empty.
*/
protected boolean isNullOrEmpty(SortDefinition pSort)
{
return pSort == null
|| pSort.getColumns() == null
|| pSort.getColumns().length == 0;
}
/**
* Prepares the {@link IDataBook} based on the given {@link Query}.
*
* @param pQuery the {@link Query} to use.
* @throws ModelException when preparing the {@link IDataBook} failed.
*/
protected void prepareDataBook(Query pQuery) throws ModelException
{
updateSort(pQuery.getSortOrders());
updateFilter(pQuery.getFilter());
}
/**
* Restores the {@link IDataBook}.
*
* @throws ModelException if restoring the {@link IDataBook} failed.
*/
protected void restoreDataBook() throws ModelException
{
}
/**
* Converts the given sort to a {@link SortDefinition}.
*
* @param pSort the sort to convert.
* @return the created {@link SortDefinition}, {@code null} if there is
* nothing to convert.
*/
protected SortDefinition toSortDefinition(List pSort)
{
if (pSort == null || pSort.isEmpty())
{
return null;
}
String[] columnNames = new String[pSort.size()];
boolean[] directions = new boolean[pSort.size()];
for (int index = 0; index < pSort.size(); index++)
{
QuerySortOrder querySortOrder = pSort.get(index);
columnNames[index] = querySortOrder.getSorted();
directions[index] = (querySortOrder.getDirection() == SortDirection.ASCENDING);
}
return new SortDefinition(columnNames, directions);
}
/**
* Checks and updates the {@link ICondition} of the {@link IDataBook} if
* necessary.
*
* @param pFilter the filter to use.
* @throws ModelException if accessing the old or setting the new
* {@link ICondition} failed.
*/
protected void updateFilter(Optional