
fr.lteconsulting.hexa.client.tableobserver.TableServiceBase Maven / Gradle / Ivy
The newest version!
package fr.lteconsulting.hexa.client.tableobserver;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import fr.lteconsulting.hexa.client.interfaces.IAsyncCallback;
import fr.lteconsulting.hexa.client.interfaces.IHasIntegerId;
public abstract class TableServiceBase
{
protected abstract void doDeleteRecord( int recordId, IAsyncCallback callback );
protected abstract void doUpdateField( int recordId, String fieldName, String wantedValue, IAsyncCallback callback );
protected abstract void doGetRecords( IAsyncCallback> callback );
protected abstract void doGetRecord( int recordId, IAsyncCallback callback );
// to be overriden if needed
protected boolean isClientInterestedByRecord( T record, Object clientParam )
{
return true;
}
protected TableServiceBase( String logName )
{
this.logName = logName;
}
String logName;
HashMap records = new HashMap();
boolean fWholeTableLoaded = false;
boolean fFullLoadRequested = false;
HashSet> waitingLoaded = null;
HashSet waitingWholeTableLoaded = null;
class ClientInfo
{
Object param;
XTableListen callback;
ITableCommand command;
public ClientInfo( Object param, XTableListen callback )
{
this.param = param;
this.callback = callback;
command = new ITableCommand()
{
@Override
public boolean isLoaded()
{
return fWholeTableLoaded;
}
@Override
public void waitLoaded( IAsyncCallback callback )
{
if( fWholeTableLoaded )
{
callback.onSuccess( 1 );
return;
}
if( waitingLoaded == null )
waitingLoaded = new HashSet>();
waitingLoaded.add( callback );
}
@Override
public void quit()
{
// GWT.log( "TableServiceBase "+logName+" client leaving..."
// );
clients.remove( ClientInfo.this );
}
@Override
public void askRefreshTable()
{
if( fWholeTableLoaded )
{
ClientInfo.this.onWholeTable( records.values() );
}
else
{
if( fFullLoadRequested )
{
if( waitingWholeTableLoaded == null )
waitingWholeTableLoaded = new HashSet();
waitingWholeTableLoaded.add( ClientInfo.this );
}
else
{
fFullLoadRequested = true;
doGetRecords( new IAsyncCallback>()
{
@Override
public void onSuccess( Iterable result )
{
records.clear();
for( T e : result )
records.put( e.getId(), e );
// GWT.log(
// "TableServiceBase "+logName+" WHOLE TABLE RECEIVED / "
// + TableServiceBase.this.toString() );
fWholeTableLoaded = true;
fFullLoadRequested = false;
ClientInfo.this.onWholeTable( records.values() );
if( waitingWholeTableLoaded != null )
{
for( ClientInfo waitingClient : waitingWholeTableLoaded )
waitingClient.onWholeTable( records.values() );
waitingWholeTableLoaded.clear();
waitingWholeTableLoaded = null;
}
if( waitingLoaded != null )
{
for( IAsyncCallback cb : waitingLoaded )
cb.onSuccess( 1 );
waitingLoaded.clear();
waitingLoaded = null;
}
}
} );
}
}
}
@Override
public T getRecord( int recordId )
{
assert (fWholeTableLoaded);
return records.get( recordId );
}
@Override
public Iterable getRecords()
{
assert (fWholeTableLoaded);
return records.values();
}
@Override
public Iterable getRecordsSorted( Comparator comparator )
{
assert (fWholeTableLoaded);
List sortedList = new ArrayList( records.values() );
Collections.sort( sortedList, comparator );
return sortedList;
}
@Override
public boolean isEmpty()
{
assert (fWholeTableLoaded);
if( ClientInfo.this.param != null )
{
Iterable it = new FilteredIterable( records.values() );
return !it.iterator().hasNext();
}
return records.isEmpty();
}
};
}
void onWholeTable( Iterable records )
{
if( callback == null )
return;
if( param != null )
callback.wholeTable( new FilteredIterable( records ) );
else
callback.wholeTable( records );
}
void onUpdatedRecord( T record )
{
if( callback == null )
return;
if( param != null && !isClientInterestedByRecord( record, param ) )
return;
callback.updated( record );
}
void onUpdatedRecordField( T record, String fieldName )
{
if( callback == null )
return;
if( param != null && !isClientInterestedByRecord( record, param ) )
return;
callback.updatedField( fieldName, record );
}
void onDeletedRecord( int recordId, T oldRecord )
{
if( callback == null )
return;
if( param != null && !isClientInterestedByRecord( oldRecord, param ) )
return;
callback.deleted( recordId, oldRecord );
}
class FilteredIterable implements Iterable
{
Iterable raw;
public FilteredIterable( Iterable raw )
{
this.raw = raw;
}
@Override
public Iterator iterator()
{
class FilteredIterator implements Iterator
{
Iterator rawIt = raw.iterator();
T nextElem = null;
FilteredIterator()
{
prepareNextElem();
}
@Override
public boolean hasNext()
{
return nextElem != null;
}
@Override
public T next()
{
T curElem = nextElem;
prepareNextElem();
return curElem;
}
void prepareNextElem()
{
nextElem = null;
while( rawIt.hasNext() )
{
T test = rawIt.next();
if( isClientInterestedByRecord( test, param ) )
{
nextElem = test;
return;
}
}
}
@Override
public void remove()
{
assert (false) : "remove is not allowed ...";
}
}
return new FilteredIterator();
}
}
}
HashSet clients = new HashSet();
public ITableCommand listen( XTableListen callback )
{
return listenInternal( null, callback );
}
protected ITableCommand listenInternal( Object clientParam, XTableListen callback )
{
ClientInfo client = new ClientInfo( clientParam, callback );
clients.add( client );
return client.command;
}
protected IAsyncCallback getAddInternalCallback( final IAsyncCallback callback )
{
return new IAsyncCallback()
{
@Override
public void onSuccess( T result )
{
if( result == null )
{
callback.onSuccess( null );
return;
}
records.put( result.getId(), result );
for( ClientInfo client : clients )
client.onUpdatedRecord( result );
if( callback != null )
callback.onSuccess( result );
}
};
}
public void delete( final int recordId )
{
doDeleteRecord( recordId, new IAsyncCallback()
{
@Override
public void onSuccess( Integer result )
{
if( result < 0 )
return;
T oldRecord = records.remove( recordId );
for( ClientInfo client : clients )
client.onDeletedRecord( recordId, oldRecord );
}
} );
}
public void updateField( int recordId, final String fieldName, String newValue )
{
doUpdateField( recordId, fieldName, newValue, new IAsyncCallback()
{
@Override
public void onSuccess( String result )
{
}
} );
doGetRecord( recordId, new IAsyncCallback()
{
@Override
public void onSuccess( T result )
{
records.put( result.getId(), result );
for( ClientInfo client : clients )
client.onUpdatedRecordField( result, fieldName );
}
} );
}
public void getRecord( int recordId, IAsyncCallback callback )
{
if( fWholeTableLoaded )
callback.onSuccess( records.get( recordId ) );
else
doGetRecord( recordId, callback );
}
public void getRecords( IAsyncCallback> callback )
{
if( fWholeTableLoaded )
callback.onSuccess( records.values() );
else
doGetRecords( callback );
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy