All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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