/*
*------------------------------------------------------------------------------
* Copyright (C) 2006-2014 University of Dundee. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*------------------------------------------------------------------------------
*/
package org.openmicroscopy.shoola.agents.dataBrowser.view;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.openmicroscopy.shoola.agents.dataBrowser.AnnotatedFilter;
import org.openmicroscopy.shoola.agents.dataBrowser.CommentsFilter;
import org.openmicroscopy.shoola.agents.dataBrowser.DataBrowserAgent;
import org.openmicroscopy.shoola.agents.dataBrowser.DataBrowserLoader;
import org.openmicroscopy.shoola.agents.dataBrowser.DataFilter;
import org.openmicroscopy.shoola.agents.dataBrowser.DataObjectCreator;
import org.openmicroscopy.shoola.agents.dataBrowser.DataObjectSaver;
import org.openmicroscopy.shoola.agents.dataBrowser.DatasetsLoader;
import org.openmicroscopy.shoola.agents.dataBrowser.RateFilter;
import org.openmicroscopy.shoola.agents.dataBrowser.ReportLoader;
import org.openmicroscopy.shoola.agents.dataBrowser.TabularDataLoader;
import org.openmicroscopy.shoola.agents.dataBrowser.TagsFilter;
import org.openmicroscopy.shoola.agents.dataBrowser.TagsLoader;
import org.openmicroscopy.shoola.agents.dataBrowser.ThumbnailLoader;
import org.openmicroscopy.shoola.agents.dataBrowser.ThumbnailsManager;
import org.openmicroscopy.shoola.agents.dataBrowser.browser.Browser;
import org.openmicroscopy.shoola.agents.dataBrowser.browser.ImageDisplay;
import org.openmicroscopy.shoola.agents.dataBrowser.browser.ImageDisplayVisitor;
import org.openmicroscopy.shoola.agents.dataBrowser.browser.ImageNode;
import org.openmicroscopy.shoola.agents.dataBrowser.layout.Layout;
import org.openmicroscopy.shoola.agents.dataBrowser.layout.LayoutFactory;
import org.openmicroscopy.shoola.agents.dataBrowser.visitor.ResetThumbnailVisitor;
import org.openmicroscopy.shoola.agents.util.EditorUtil;
import org.openmicroscopy.shoola.agents.util.ViewerSorter;
import org.openmicroscopy.shoola.env.LookupNames;
import org.openmicroscopy.shoola.env.data.model.ApplicationData;
import org.openmicroscopy.shoola.env.data.util.FilterContext;
import omero.gateway.SecurityContext;
import omero.gateway.model.TableResult;
import omero.gateway.model.DataObject;
import omero.gateway.model.DatasetData;
import omero.gateway.model.ExperimenterData;
import omero.gateway.model.FileAnnotationData;
import omero.gateway.model.GroupData;
import omero.gateway.model.ImageData;
import omero.gateway.model.PlateData;
import omero.gateway.model.ProjectData;
import omero.gateway.model.ScreenData;
import omero.gateway.model.TagAnnotationData;
/**
* The Model component in the <code>DataBrowser</code> MVC triad.
* This class tracks the <code>DataBrowser</code>'s state and knows how to
* initiate data retrievals. It also knows how to store and manipulate
* the results. However, this class doesn't know the actual hierarchy
* the <code>DataBrowser</code> is for. Subclasses fill this gap and provide
* a suitable data loader. The {@link DataBrowserComponent} intercepts the
* results of data loadings, feeds them back to this class and fires state
* transitions as appropriate.
*
* @author Jean-Marie Burel
* <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @author Donald MacDonald
* <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a>
* @version 3.0
* @since OME3.0
*/
abstract class DataBrowserModel
{
/** The number of loaders to use for the thumbnails.*/
static final int MAX_LOADER = 4;
/** Identifies the <code>DatasetsModel</code>. */
static final int DATASETS = DataBrowser.DATASETS;
/** Identifies the <code>ImagesModel</code>. */
static final int IMAGES = DataBrowser.IMAGES;
/** Identifies the <code>ProjectsModel</code>. */
static final int PROJECTS = DataBrowser.PROJECTS;
/** Identifies the <code>SearchModel</code>. */
static final int SEARCH = DataBrowser.SEARCH;
/** Identifies the <code>TagSetsModel</code>. */
static final int TAGSETS = DataBrowser.TAGSETS;
/** Identifies the <code>WellsModel</code>. */
static final int WELLS = DataBrowser.WELLS;
/** Identifies the <code>TagsModel</code>. */
static final int TAGS = DataBrowser.TAGS;
/** Identifies the <code>PlatesModel</code>. */
static final int PLATES = DataBrowser.PLATES;
/** Identifies the <code>GroupModel</code>. */
static final int GROUP = DataBrowser.GROUP;
/** Identifies the <code>FSFolderModel</code>. */
static final int FS_FOLDER = DataBrowser.FS_FOLDER;
/** Holds one of the state flags defined by {@link DataBrowser}. */
protected int state;
/** Maps an image id to the list of thumbnail providers for that image. */
private ThumbnailsManager thumbsManager;
/** Maps an image id to the list of thumbnail providers for that image. */
private ThumbnailsManager fullSizeThumbsManager;
/** Used to sort the nodes by date or alphabetically. */
protected ViewerSorter sorter;
/** The current fields loader. */
private DataBrowserLoader fieldsLoader;
/** The current data loader. */
private DataBrowserLoader loader;
/** The collection of existing tags. */
private Collection existingTags;
/** The collection of existing datasets. */
private Collection existingDatasets;
/** The collection of external applications if any. */
private List<ApplicationData> applications;
/** Sets the experimenter. */
private ExperimenterData experimenter;
/** Flag indicating that the thumbnails are loaded or not. */
protected boolean thumbnailLoaded;
/** Reference to the component that embeds this model. */
protected DataBrowser component;
/** Reference to the browser. */
protected Browser browser;
/** Reference to the browser. */
protected ImageTableView tableView;
/** Reference to the SearchResultView. */
protected SearchResultView searchResultView;
/** The number of images. */
protected int numberOfImages;
/** The number of images loaded. */
protected int imagesLoaded;
/** The parent of the nodes. Used as back pointer. */
protected Object parent;
/** The grandparent of the node. Used as back pointer. */
protected Object grandParent;
/** The security context.*/
protected SecurityContext ctx;
/** The display mode.*/
protected int displayMode;
/**
* Invokes the value is not set.
*/
private void checkDefaultDisplayMode()
{
Integer value = (Integer) DataBrowserAgent.getRegistry().lookup(
LookupNames.DATA_DISPLAY);
if (value == null) setDisplayMode(LookupNames.EXPERIMENTER_DISPLAY);
else setDisplayMode(value.intValue());
}
/**
* Indicates to load all annotations available if the user can annotate
* and is an administrator/group owner or to only load the user's
* annotation.
*
* @param ho The object to handle.
* @return See above
*/
private boolean canRetrieveAll(Object ho)
{
if (!canAnnotate(ho)) return false;
//check the group level
long groupID = -1;
if (ho instanceof DataObject) {
DataObject data = (DataObject) ho;
groupID = data.getGroupId();
}
GroupData group = getGroup(groupID);
if (group == null) return false;
if (GroupData.PERMISSIONS_GROUP_READ ==
group.getPermissions().getPermissionsLevel()) {
if (DataBrowserAgent.isAdministrator()) return true;
Set leaders = group.getLeaders();
Iterator i = leaders.iterator();
long userID = getCurrentUser().getId();
ExperimenterData exp;
while (i.hasNext()) {
exp = (ExperimenterData) i.next();
if (exp.getId() == userID)
return true;
}
return false;
}
return true;
}
/**
* Returns the user currently logged in.
*
* @return See above.
*/
ExperimenterData getCurrentUser()
{
return DataBrowserAgent.getUserDetails();
}
/**
* Creates a new instance.
*
* @param ctx The security context.
*/
DataBrowserModel(SecurityContext ctx)
{
sorter = new ViewerSorter();
state = DataBrowser.NEW;
this.ctx = ctx;
checkDefaultDisplayMode();
}
/**
* Returns <code>true</code> if the specified object can be annotated,
* <code>false</code> otherwise, depending on the permission.
*
* @param ho The data object to check.
* @return See above.
*/
boolean canAnnotate(Object ho)
{
long id = DataBrowserAgent.getUserDetails().getId();
boolean b = EditorUtil.isUserOwner(ho, id);
if (b) return b; //user it the owner.
if (!(ho instanceof DataObject)) return false;
DataObject data = (DataObject) ho;
return data.canAnnotate();
}
/**
* Returns the parent of the nodes if any.
*
* @return See above.
*/
Object getParent() { return parent; }
/**
* Returns the experimenter.
*
* @return See above.
*/
Object getExperimenter() { return experimenter; }
/**
* Returns the number of images.
*
* @return See above.
*/
int getNumberOfImages() { return numberOfImages; }
/**
* Returns the {@link ViewerSorter}.
*
* @return See above.
*/
ViewerSorter getSorter() { return sorter; }
/** Creates a default layout and lays out the nodes. */
void layoutBrowser()
{
layoutBrowser(LayoutFactory.SQUARY_LAYOUT);
}
/**
* Lays out the browser.
*
* @param type The type of layout to create.
*/
void layoutBrowser(int type)
{
if (browser == null) return;
//Do initial layout and set the icons.
if (browser.getSelectedLayout() == null) {
Layout layout = LayoutFactory.createLayout(type, sorter, 0);
browser.setSelectedLayout(layout);
}
//browser.accept(browser.getSelectedLayout(),
// ImageDisplayVisitor.IMAGE_SET_ONLY);
browser.accept(browser.getSelectedLayout());
}
/**
* Creates or recycles the table view.
*
* @return See above.
*/
ImageTableView createImageTableView()
{
if (tableView != null) return tableView;
tableView = new ImageTableView(this, (ImageDisplay) browser.getUI());
return tableView;
}
/**
* Creates or recycles the {@link SearchResultView}
*
* @return See above.
*/
SearchResultView createSearchResultView()
{
if (searchResultView != null)
return searchResultView;
searchResultView = new SearchResultView((ImageDisplay)browser.getUI(), (AdvancedResultSearchModel)this);
return searchResultView;
}
/**
* Returns the current state.
*
* @return See above.
*/
int getState() { return state; }
/**
* Loads the data.
*
* @param refresh Pass <code>false</code> if we retrieve the data for
* the first time, <code>true</code> otherwise.
* @param ids The collection of image's ids or <code>null</code>.
*/
void loadData(boolean refresh, Collection ids)
{
if (refresh)
browser.accept(new ResetThumbnailVisitor(ids),
ImageDisplayVisitor.IMAGE_NODE_ONLY);
List<DataBrowserLoader> loaders = createDataLoader(refresh, ids);
if (loaders == null) {
state = DataBrowser.READY;
return;
}
state = DataBrowser.LOADING;
Iterator<DataBrowserLoader> i = loaders.iterator();
while (i.hasNext()) {
i.next().load();
}
}
/**
* Loads the fields for the specified well. Returns <code>true</code>
* if a loader was created, <code>false</code> otherwise.
*
* @param row The row identifying the well.
* @param column The column identifying the well.
* @return See above.
*/
boolean loadFields(int row, int column)
{
if (!(this instanceof WellsModel)) return false;
fieldsLoader = ((WellsModel) this).createFieldsLoader(row, column);
if (fieldsLoader == null) return false;
fieldsLoader.load();
return true;
}
/** Cancels any-going fields loading. */
void cancelFieldsLoading()
{
if (fieldsLoader != null) fieldsLoader.cancel();
}
/**
* Sets the grand parent of the browsed nodes.
*
* @param grandParent The value to set.
*/
void setGrandParent(Object grandParent) { this.grandParent = grandParent; }
/**
* Returns the grand parent.
*
* @return See above.
*/
Object getGrandParent() { return grandParent; }
/**
* Returns the browser.
*
* @return See above.
*/
Browser getBrowser() { return browser; }
/**
* Returns the browser.
*
* @return See above.
*/
ImageTableView getTableView() { return tableView; }
/**
* Returns the SearchResultView.
*
* @return See above.
*/
SearchResultView getSearchView() {
return searchResultView;
}
/**
* Called by the <code>DataBrowser</code> after creation to allow this
* object to store a back reference to the embedding component.
*
* @param component The embedding component.
*/
void initialize(DataBrowser component)
{
this.component = component;
}
/**
* Sets the specified thumbnail for all image nodes in the display that
* map to the same image hierarchy object.
* When every image object has a thumbnail, this method sets the state
* to {@link HiViewer#READY}.
*
* @param imageID The id of the image or to the object of reference
* which the thumbnail belongs.
* @param thumb The thumbnail pixels.
* @param valid Pass <code>true</code> if it is a valid thumbnail,
* <code>false</code> otherwise.
* @param maxEntries The number of thumbnails to load.
* @return The percentage of processed data.
*/
int setThumbnail(Object ref, BufferedImage thumb, boolean valid,
int maxEntries)
{
if (thumbsManager == null) {
if (getType() == WELLS) {
thumbsManager = new ThumbnailsManager(getNodes(), maxEntries);
} else {
thumbsManager = new ThumbnailsManager(
browser.getVisibleImageNodes(), maxEntries);
}
}
thumbsManager.setThumbnail(ref, thumb, valid);
int perc = thumbsManager.getPercentDone();
if (thumbsManager.isDone()) {
state = DataBrowser.READY;
thumbsManager = null;
}
return perc;
}
/**
* Returns <code>true</code> if the loading is done,
* <code>false</code> otherwise.
*
* @param imageID The id of the image the passed object is for.
* @param thumb The Buffered image.
* @return See above.
*/
boolean setSlideViewImage(long imageID, BufferedImage thumb)
{
if (fullSizeThumbsManager != null) {
fullSizeThumbsManager.setFullSizeImage(imageID, thumb);
if (fullSizeThumbsManager.isDone()) {
state = DataBrowser.READY;
fullSizeThumbsManager = null;
return true;
}
}
return false;
}
/** Discards any on-going data loading. */
void discard()
{
}
void cancelFiltering()
{
}
void cancelSlideShow()
{
}
/**
* Sets the current state.
*
* @param state The value to set.
*/
void setState(int state) { this.state = state; }
/**
* Filters the passed <code>DataObject</code>s by rate.
*
* @param rate The selected rate. One of the constants defined
* by {@link RateFilter}.
* @param nodes The collection of <code>DataObject</code>s to filter.
*/
void fireFilteringByRate(int rate, Set nodes)
{
state = DataBrowser.FILTERING;
RateFilter loader = new RateFilter(component, ctx, rate, nodes);
loader.load();
}
/**
* Filters the passed <code>DataObject</code>s by tags.
*
* @param tags The selected tags.
* @param nodes The collection of <code>DataObject</code>s to filter.
*/
void fireFilteringByTags(List<String> tags, Set<DataObject> nodes)
{
state = DataBrowser.FILTERING;
TagsFilter loader = new TagsFilter(component, ctx, tags, nodes);
loader.load();
}
/**
* Filters the passed <code>DataObject</code>s by comments.
*
* @param comments The selected comments.
* @param nodes The collection of <code>DataObject</code>s to filter.
*/
void fireFilteringByComments(List<String> comments, Set<DataObject> nodes)
{
state = DataBrowser.FILTERING;
CommentsFilter loader = new CommentsFilter(component, ctx, comments,
nodes);
loader.load();
}
/**
* Filters the passed <code>DataObject</code>s by context.
*
* @param context The filtering context.
* @param nodes The collection of <code>DataObject</code>s to filter.
*/
void fireFilteringByContext(FilterContext context, Set<DataObject> nodes)
{
state = DataBrowser.FILTERING;
DataFilter loader = new DataFilter(component, ctx, context, nodes);
loader.load();
}
/**
* Filters the passed <code>DataObject</code>s depending on the
* type of annotations.
*
* @param annotationType The type of annotation to filter by.
* @param annotated Pass <code>true</code> to determine the annotated
* nodes, <code>false</code> to determine the
* not annotated nodes.
* @param nodes The collection of <code>DataObject</code>s to filter.
*/
void fireFilteringByAnnotated(Class annotationType, boolean annotated,
Set<DataObject> nodes)
{
state = DataBrowser.FILTERING;
AnnotatedFilter loader = new AnnotatedFilter(component, ctx,
annotationType, annotated, nodes);
loader.load();
}
/** Starts an asynchronous call to load the existing tags. */
void fireTagsLoading()
{
state = DataBrowser.LOADING;
TagsLoader loader = new TagsLoader(component, ctx,
canRetrieveAll(parent));
loader.load();
}
/** Starts an asynchronous call to load the existing datasets. */
void fireExisitingDatasetsLoading()
{
DatasetsLoader loader = new DatasetsLoader(component, ctx);
loader.load();
}
/**
* Starts an asynchronous retrieval all the full size image.
*
* @param images The value to handle.
*/
void fireFullSizeLoading(Collection<ImageNode> images)
{
Set nodes = new HashSet<ImageData>();
Set<ImageNode> toKeep = new HashSet<ImageNode>();
Iterator i = images.iterator();
ImageNode node;
while (i.hasNext()) {
node = (ImageNode) i.next();
if (node.getThumbnail().getFullSizeImage() == null) {
nodes.add(node.getHierarchyObject());
toKeep.add(node);
}
}
if (nodes.size() > 0) {
fullSizeThumbsManager = new ThumbnailsManager(toKeep,
toKeep.size());
ThumbnailLoader loader = new ThumbnailLoader(component, ctx,
nodes, false, ThumbnailLoader.IMAGE, nodes.size());
loader.load();
state = DataBrowser.LOADING_SLIDE_VIEW;
}
}
/**
* Starts an asynchronous retrieval
*
* @param data The <code>DataObject</code> to create.
* @param images The images to add to the <code>DataObject</code>.
*/
void fireDataSaving(DataObject data, Collection images)
{
DataObject p = null;
if (parent instanceof DataObject) p = (DataObject) parent;
if (grandParent != null && grandParent instanceof DataObject)
p = (DataObject) grandParent;
//Review that code.
if (data instanceof DatasetData) {
if (!(p instanceof ProjectData)) p = null;
} else if (data instanceof TagAnnotationData) {
if (p instanceof TagAnnotationData) {
TagAnnotationData tag = (TagAnnotationData) p;
if (!TagAnnotationData.INSIGHT_TAGSET_NS.equals(
tag.getNameSpace()))
p = null;
}
}
DataObjectCreator loader = new DataObjectCreator(component, ctx,
p, data, images);
loader.load();
}
/**
* Starts an asynchronous retrieval
*
* @param data The <code>DataObject</code> to create.
* @param images The images to add to the <code>DataObject</code>.
*/
void fireDataSaving(Collection datasets, Collection images)
{
DataObjectSaver loader = new DataObjectSaver(component, ctx, datasets,
images);
loader.load();
}
/**
* Starts an asynchronous data retrieval for writing the report.
*
* @param images The images to handle.
* @param types The types of data to report.
* @param name The name of the report.
*/
void fireReportLoading(Collection images, List<Class> types,
String name)
{
ReportLoader loader = new ReportLoader(component, ctx, types,
sorter.sort(images), name);
loader.load();
}
/**
* Sets the collection of existing tags.
*
* @param tags The value to set.
*/
void setTags(Collection tags)
{
if (tags == null) return;
Iterator i = tags.iterator();
List l = new ArrayList();
TagAnnotationData tag;
String ns;
while (i.hasNext()) {
tag = (TagAnnotationData) i.next();
ns = tag.getNameSpace();
if (!TagAnnotationData.INSIGHT_TAGSET_NS.equals(ns))
l.add(tag);
}
existingTags = sorter.sort(l);
}
/**
* Sets the collection of existing datasets.
*
* @param datasets The value to set.
*/
void setExistingDatasets(Collection datasets)
{
existingDatasets = datasets;
}
/**
* Returns the collection of existing tags.
*
* @return See above.
*/
Collection getExistingDatasets() { return existingDatasets; }
/**
* Returns <code>true</code> if the model is of type
* <code>Dataset</code>, <code>Images</code>, <code>false</code> otherwise.
*
* @return See above.
*/
boolean isImagesModel()
{
switch (getType()) {
case DATASETS:
case IMAGES:
case TAGS:
return true;
default:
return false;
}
}
/**
* Returns the collection of existing tags.
*
* @return See above.
*/
Collection getExistingTags() { return existingTags; }
/**
* Returns <code>true</code> is a magnified thumbnail is displayed when
* the user mouses over a node, <code>false</code> otherwise.
*
* @return See above.
*/
boolean isRollOver() { return browser.isRollOver(); }
/**
* Returns <code>true</code> if the parent is writable,
* <code>false</code> otherwise.
*
* @return See above.
*/
boolean canLinkParent()
{
if (DataBrowserAgent.isAdministrator()) return true;
switch (getDisplayMode()) {
case LookupNames.GROUP_DISPLAY:
if (parent == null || !(parent instanceof DataObject))
return false;
return ((DataObject) parent).canLink();
case LookupNames.EXPERIMENTER_DISPLAY:
default:
long userID = DataBrowserAgent.getUserDetails().getId();
if (parent == null) {
if (experimenter == null) return false;
return experimenter.getId() == userID;
}
if (!(parent instanceof DataObject)) {
if (experimenter == null) return false;
return experimenter.getId() == userID;
}
return EditorUtil.isUserOwner(parent, userID);
}
}
/**
* Returns the sorted collection.
*
* @param collection The collection to sort.
* @return See above.
*/
List sortCollection(Collection collection)
{
return sorter.sort(collection);
}
/**
* Sets the collection of external applications.
*
* @param applications The value to set.
*/
void setApplicationData(List<ApplicationData> applications)
{
this.applications = applications;
}
/**
* Sets the experimenter.
*
* @param experimenter The value to set.
*/
void setExperimenter(ExperimenterData experimenter)
{
this.experimenter = experimenter;
}
/**
* Returns the collections of applications.
*
* @return See above.
*/
List<ApplicationData> getApplications() { return applications; }
/**
* Starts an asynchronous call to load the tabular data.
*
* @param data The data to load.
*/
void fireTabularDataLoading(List<FileAnnotationData> data)
{
TabularDataLoader loader = null;
if (data == null) {
if (this instanceof WellsModel) {
if (grandParent instanceof ScreenData) {
loader = new TabularDataLoader(component, ctx,
(DataObject) grandParent,
canRetrieveAll(grandParent));
loader.load();
if (parent instanceof PlateData) {
loader = new TabularDataLoader(component, ctx,
(DataObject) parent, canRetrieveAll(parent));
loader.load();
}
} else if (parent instanceof PlateData) {
loader = new TabularDataLoader(component, ctx,
(DataObject) parent, canRetrieveAll(parent));
loader.load();
}
}
} else if (data.size() > 0) {
List<Long> ids = new ArrayList<Long>();
Iterator<FileAnnotationData> i = data.iterator();
while (i.hasNext()) {
ids.add(i.next().getFileID());
}
loader = new TabularDataLoader(component, ctx, ids,
canRetrieveAll(parent));
loader.load();
}
}
/**
* Sets the tabular data.
*
* @param data The value to set.
*/
void setTabularData(List<TableResult> data)
{
if (this instanceof WellsModel) {
((WellsModel) this).setTabularData(data);
}
}
/**
* Returns the selected layout.
*
* @return See above.
*/
int getLayoutIndex()
{
Browser b = getBrowser();
if (b == null) return LayoutFactory.SQUARY_LAYOUT;
Layout layout = b.getSelectedLayout();
if (layout == null) return LayoutFactory.SQUARY_LAYOUT;
return layout.getIndex();
}
/**
* Returns the security context.
*
* @return See above.
*/
SecurityContext getSecurityContext() { return ctx; }
/**
* Returns <code>true</code> if the user belongs to only one group,
* <code>false</code> otherwise.
*
* @return See above.
*/
boolean isSingleGroup()
{
Collection l = DataBrowserAgent.getAvailableUserGroups();
return l.size() <= 1;
}
/**
* Returns the group corresponding to the specified id or <code>null</code>.
*
* @param groupId The identifier of the group.
* @return See above.
*/
GroupData getGroup(long groupId)
{
Collection groups = DataBrowserAgent.getAvailableUserGroups();
if (groups == null) return null;
Iterator i = groups.iterator();
GroupData group;
while (i.hasNext()) {
group = (GroupData) i.next();
if (group.getId() == groupId) return group;
}
return null;
}
/**
* Returns the display mode. One of the constants defined by
* {@link LookupNames}.
*
* @return See above.
*/
int getDisplayMode() { return displayMode; }
/**
* Returns <code>true</code> if the thumbnails have been loaded
* <code>false</code> otherwise.
*
* @return See above.
*/
boolean hasThumbnailsBeenLoaded() { return loader != null; }
/**
* Sets the display mode.
*
* @param value The value to set.
*/
void setDisplayMode(int value)
{
if (value < 0) {
checkDefaultDisplayMode();
return;
}
switch (value) {
case LookupNames.EXPERIMENTER_DISPLAY:
case LookupNames.GROUP_DISPLAY:
displayMode = value;
break;
default:
displayMode = LookupNames.EXPERIMENTER_DISPLAY;
}
if (existingDatasets != null) {
existingDatasets.clear();
setExistingDatasets(null);
}
if (existingTags != null) {
existingTags.clear();
setTags(null);
}
}
/**
* Creates a collection of loaders for the thumbnails.
*
* @param images The objects to load.
* @return See above.
*/
List<DataBrowserLoader> createThumbnailsLoader(List<DataObject> images)
{
if (images == null) return null;
List<DataBrowserLoader> loaders = new ArrayList<DataBrowserLoader>();
int n = images.size();
int diff = n/MAX_LOADER;
List<DataObject> l;
int j;
int step = 0;
if (n < MAX_LOADER) diff = 1;
for (int k = 0; k < MAX_LOADER; k++) {
l = new ArrayList<DataObject>();
j = step+diff;
if (k == (MAX_LOADER-1)) j += (n-j);
if (j <= n) {
l = images.subList(step, j);
step += l.size();
}
if (l.size() > 0) {
loaders.add(new ThumbnailLoader(component, ctx, l, n));
}
}
return loaders;
}
/**
* Returns <code>true</code> if the user is a system user e.g. root
* <code>false</code> otherwise.
*
* @param id The identifier of the user.
* @return See above.
*/
boolean isSystemUser(long id)
{
return DataBrowserAgent.getRegistry().getAdminService().isSystemUser(id);
}
/**
* Returns <code>true</code> if the user is a system user e.g. root
* <code>false</code> otherwise.
*
* @param id The identifier of the user.
* @param key One of the constants defined by <code>GroupData</code>.
* @return See above.
*/
boolean isSystemUser(long id, String key)
{
return DataBrowserAgent.getRegistry().getAdminService().isSystemUser(
id, key);
}
/**
* Returns <code>true</code> if the group is a system group e.g. System
* <code>false</code> otherwise.
*
* @param id The identifier of the group.
* @param key One of the constants defined by <code>GroupData</code>.
* @return See above.
*/
boolean isSystemGroup(long id, String key)
{
return DataBrowserAgent.getRegistry().getAdminService().isSecuritySystemGroup(id, key);
}
/**
* Creates a data loader that can retrieve the hierarchy objects needed
* by this model.
*
* @param refresh Pass <code>false</code> if we retrieve the data for
* the first time, <code>true</code> otherwise.
* @param ids The collection of images' ids to reload.
* @return A suitable data loader.
*/
protected abstract List<DataBrowserLoader> createDataLoader(boolean refresh,
Collection ids);
/**
* Returns the type of the model.
*
* @return See above.
*/
protected abstract int getType();
/**
* Returns the collection of {@link ImageDisplay}.
*
* @return See above.
*/
protected abstract List<ImageDisplay> getNodes();
}