/*******************************************************************************
* Copyright 2013 Geoscience Australia
*
* 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 au.gov.ga.earthsci.discovery.ui;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.Viewer;
import au.gov.ga.earthsci.discovery.DiscoveryIndexOutOfBoundsException;
import au.gov.ga.earthsci.discovery.DiscoveryResultNotFoundException;
import au.gov.ga.earthsci.discovery.IDiscovery;
import au.gov.ga.earthsci.discovery.IDiscoveryListener;
import au.gov.ga.earthsci.discovery.IDiscoveryResult;
/**
* {@link IStructuredContentProvider} implementation that provides
* {@link IDiscoveryResult}s to a JFace viewer.
*
* @author Michael de Hoog (michael.dehoog@ga.gov.au)
*/
public class DiscoveryResultContentProvider implements IStructuredContentProvider, IDiscoveryListener
{
private Viewer viewer;
private IDiscovery discovery;
private int page = 0;
/**
* @return The page of results of the {@link IDiscovery} that this content
* provider is providing.
*/
public int getPage()
{
return page;
}
/**
* Set the page of results of the {@link IDiscovery} that this content
* provider should provide.
*
* @param page
* Page number of results to provide
*/
public void setPage(int page)
{
this.page = page;
refreshViewer(viewer);
}
@Override
public void dispose()
{
if (discovery != null)
{
discovery.removeListener(this);
}
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
{
this.viewer = viewer;
if (discovery == newInput)
{
//input hasn't changed
return;
}
if (discovery != null)
{
discovery.removeListener(this);
}
if (newInput instanceof IDiscovery)
{
discovery = (IDiscovery) newInput;
discovery.addListener(this);
}
}
@Override
public Object[] getElements(Object inputElement)
{
if (!(inputElement instanceof IDiscovery))
{
return null;
}
List<IDiscoveryResult> results = new ArrayList<IDiscoveryResult>();
IDiscovery discovery = (IDiscovery) inputElement;
int pageSize = discovery.getPageSize();
int resultCount = discovery.getResultCount();
if (resultCount == IDiscovery.UNKNOWN)
{
resultCount = Integer.MAX_VALUE;
}
if (pageSize == 0)
{
for (int i = 0; i < resultCount; i++)
{
try
{
IDiscoveryResult result = discovery.getResult(i);
if (result == null)
{
//assume, if we hit a loading result in unpaged results, there will be no records after this one yet
break;
}
results.add(result);
}
catch (DiscoveryResultNotFoundException e)
{
//ignore for unpaged results
}
catch (DiscoveryIndexOutOfBoundsException e)
{
break;
}
}
}
else
{
int firstIndex = page * pageSize;
for (int i = 0; i < pageSize; i++)
{
int index = firstIndex + i;
if (index >= resultCount)
{
break;
}
try
{
//add null results, and display them as loading
IDiscoveryResult result = discovery.getResult(index);
if (result != null)
{
results.add(result);
}
else
{
//TODO add loading node
}
}
catch (DiscoveryResultNotFoundException e)
{
//TODO for now ignore, is this correct?
}
catch (DiscoveryIndexOutOfBoundsException e)
{
break;
}
}
}
return results.toArray();
}
@Override
public void resultCountChanged(IDiscovery discovery)
{
}
@Override
public void resultAdded(IDiscovery discovery, IDiscoveryResult result)
{
int pageSize = discovery.getPageSize();
boolean refresh = pageSize == 0;
if (pageSize != 0)
{
int startIndex = pageSize * page;
int endIndex = startIndex + pageSize - 1;
int index = result.getIndex();
refresh = startIndex <= index && index <= endIndex;
}
if (refresh)
{
refreshViewer(viewer);
}
}
private static void refreshViewer(final Viewer viewer)
{
if (viewer != null && !viewer.getControl().isDisposed())
{
viewer.getControl().getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
if (!viewer.getControl().isDisposed())
{
viewer.refresh();
}
}
});
}
}
}