/*
*------------------------------------------------------------------------------
* 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.treeviewer.view;
import java.awt.Component;
import java.awt.Point;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.activation.FileDataSource;
import org.apache.commons.collections.CollectionUtils;
import org.openmicroscopy.shoola.agents.dataBrowser.view.DataBrowser;
import org.openmicroscopy.shoola.agents.metadata.rnd.Renderer;
import org.openmicroscopy.shoola.agents.metadata.view.MetadataViewer;
import org.openmicroscopy.shoola.agents.metadata.view.MetadataViewerFactory;
import org.openmicroscopy.shoola.agents.treeviewer.AdminCreator;
import org.openmicroscopy.shoola.agents.treeviewer.DataObjectCreator;
import org.openmicroscopy.shoola.agents.treeviewer.DataObjectRemover;
import org.openmicroscopy.shoola.agents.treeviewer.DataObjectUpdater;
import org.openmicroscopy.shoola.agents.treeviewer.DataTreeViewerLoader;
import org.openmicroscopy.shoola.agents.treeviewer.ExistingObjectsLoader;
import org.openmicroscopy.shoola.agents.treeviewer.ExistingObjectsSaver;
import org.openmicroscopy.shoola.agents.treeviewer.ImageChecker;
import org.openmicroscopy.shoola.agents.treeviewer.MoveDataLoader;
import org.openmicroscopy.shoola.agents.treeviewer.OriginalFileLoader;
import org.openmicroscopy.shoola.agents.treeviewer.ParentLoader;
import org.openmicroscopy.shoola.agents.treeviewer.PlateWellsLoader;
import org.openmicroscopy.shoola.agents.treeviewer.ProjectsLoader;
import org.openmicroscopy.shoola.agents.treeviewer.RndSettingsSaver;
import org.openmicroscopy.shoola.agents.treeviewer.ScriptLoader;
import org.openmicroscopy.shoola.agents.treeviewer.ScriptsLoader;
import org.openmicroscopy.shoola.agents.treeviewer.TagHierarchyLoader;
import org.openmicroscopy.shoola.agents.treeviewer.TimeIntervalsLoader;
import org.openmicroscopy.shoola.agents.treeviewer.TreeViewerAgent;
import org.openmicroscopy.shoola.agents.treeviewer.ImageChecker.ImageCheckerType;
import org.openmicroscopy.shoola.agents.treeviewer.browser.Browser;
import org.openmicroscopy.shoola.agents.treeviewer.browser.BrowserFactory;
import org.openmicroscopy.shoola.agents.treeviewer.finder.Finder;
import org.openmicroscopy.shoola.agents.treeviewer.util.MoveGroupSelectionDialog;
import org.openmicroscopy.shoola.agents.util.browser.TreeImageDisplay;
import org.openmicroscopy.shoola.agents.util.browser.TreeImageSet;
import org.openmicroscopy.shoola.agents.util.browser.TreeImageTimeSet;
import org.openmicroscopy.shoola.agents.util.EditorUtil;
import org.openmicroscopy.shoola.agents.util.ViewerSorter;
import org.openmicroscopy.shoola.agents.util.finder.AdvancedFinder;
import org.openmicroscopy.shoola.agents.util.finder.FinderFactory;
import org.openmicroscopy.shoola.env.LookupNames;
import org.openmicroscopy.shoola.env.data.OmeroImageService;
import org.openmicroscopy.shoola.env.data.model.AdminObject;
import org.openmicroscopy.shoola.env.data.model.ApplicationData;
import org.openmicroscopy.shoola.env.data.model.ScriptObject;
import org.openmicroscopy.shoola.env.data.model.TimeRefObject;
import omero.gateway.SecurityContext;
import omero.log.LogMessage;
import org.openmicroscopy.shoola.env.rnd.RndProxyDef;
import org.openmicroscopy.shoola.util.file.ImportErrorObject;
import org.openmicroscopy.shoola.util.ui.UIUtilities;
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.PixelsData;
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>TreeViewer</code> MVC triad.
* This class tracks the <code>TreeViewer</code>'s state and knows how to
* initiate data retrievals. It also knows how to store and manipulate
* the results. This class provide a suitable data loader.
* The {@link TreeViewerComponent} 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>
* @version 2.2
* @since OME2.2
*/
class TreeViewerModel
{
/** Holds one of the state flags defined by {@link TreeViewer}. */
private int state;
/**
* Will either be a data loader or
* <code>null</code> depending on the current state.
*/
private DataTreeViewerLoader currentLoader;
/** The browsers controlled by the model. */
private Map<Integer, Browser> browsers;
/** The currently selected {@link Browser}. */
private Browser selectedBrowser;
/** The currently selected experimenter. */
private ExperimenterData experimenter;
/**
* The component to find a given phrase in the currently selected
* {@link Browser}.
*/
private Finder finder;
/** The collection of nodes to copy. */
private TreeImageDisplay[] nodesToCopy;
/**
* Either {@link TreeViewer#COPY_AND_PASTE} or
* {@link TreeViewer#CUT_AND_PASTE}.
*/
private int copyIndex;
/** Flag indicating if the {@link TreeViewer} is recycled or not. */
private boolean recycled;
/** Flag indicating to retrieve the node data when rolling over. */
private boolean rollOver;
/** The image to copy the rendering settings from. */
private ImageData refImage;
/** 'Pending' rendering settings */
private RndProxyDef refRndSettings;
/** The viewer displaying the metadata. */
private MetadataViewer metadataViewer;
/** The viewer displaying the thumbnails. */
private DataBrowser dataViewer;
/** Reference to the advanced finder. */
private AdvancedFinder advancedFinder;
/** Reference to the component that embeds this model. */
protected TreeViewer component;
/** Flag indicating if there is an on-going import. */
private boolean importing;
/** Collection of uploaded scripts. */
private Map<Long, ScriptObject> scripts;
/** Used to sort the various collections. */
private ViewerSorter sorter;
/** Scripts with a UI. */
private List<ScriptObject> scriptsWithUI;
/** The security context for the administrator.*/
private SecurityContext adminContext;
/** The id of the group the currently selected node is in.*/
private long selectedGroupId;
/** The display mode.*/
private int displayMode;
/** The number of import failures.*/
private int importFailureCount;
/** The number of successful import.*/
private int importSuccessCount;
/**
* Returns the collection of scripts with a UI, mainly the figure scripts.
*
* @return See above.
*/
private List<ScriptObject> getScriptsWithUI()
{
if (scriptsWithUI != null) return scriptsWithUI;
try {
OmeroImageService svc =
TreeViewerAgent.getRegistry().getImageService();
scriptsWithUI = svc.loadAvailableScriptsWithUI(
getSecurityContext(null));
return scriptsWithUI;
} catch (Exception e) {
LogMessage msg = new LogMessage();
msg.print("Scripts with UI");
msg.print(e);
TreeViewerAgent.getRegistry().getLogger().error(this, msg);
}
return new ArrayList<ScriptObject>();
}
/**
* Builds the map linking the nodes to copy and the parents.
*
* @param parents The parents of the node to copy.
* @return See above.
*/
private Map buildCopyMap(TreeImageDisplay[] parents)
{
Object uo = nodesToCopy[0].getUserObject();
Object uoParent = parents[0].getUserObject();
if (!(uo instanceof DataObject)) return null;
if (!(uoParent instanceof DataObject)) return null;
DataObject obj = (DataObject) uo;
DataObject objParent = (DataObject) uoParent;
if ((objParent instanceof ProjectData &&
obj instanceof DatasetData) ||
(objParent instanceof DatasetData
&& obj instanceof ImageData) ||
(objParent instanceof ScreenData &&
obj instanceof PlateData) ||
(objParent instanceof GroupData &&
obj instanceof ExperimenterData))
{
Map map;
Set children;
map = new HashMap(parents.length);
for (int i = 0; i < parents.length; i++) {
children = new HashSet(nodesToCopy.length);
for (int j = 0; j < nodesToCopy.length; j++)
children.add(nodesToCopy[j].getUserObject());
map.put(parents[i].getUserObject(), children);
}
return map;
} else if ((obj instanceof TagAnnotationData) &&
(objParent instanceof TagAnnotationData)) {
TagAnnotationData tag = (TagAnnotationData) obj;
TagAnnotationData tagSet = (TagAnnotationData) objParent;
String nsSet = tagSet.getNameSpace();
String ns = tag.getNameSpace();
if (TagAnnotationData.INSIGHT_TAGSET_NS.equals(nsSet) &&
ns == null) {
Map map;
Set children;
map = new HashMap(parents.length);
for (int i = 0; i < parents.length; i++) {
children = new HashSet(nodesToCopy.length);
for (int j = 0; j < nodesToCopy.length; j++)
children.add(nodesToCopy[j].getUserObject());
map.put(parents[i].getUserObject(), children);
}
return map;
}
}
return null;
}
/**
* Builds the map linking the nodes to cut and the parents.
*
* @param nodes The nodes to cut.
* @return See above.
*/
private Map buildCutMap(TreeImageDisplay[] nodes)
{
TreeImageDisplay parent, child;
Map<Object, Set> map = new HashMap<Object, Set>();
Object po;
Set<Object> children;
for (int i = 0; i < nodes.length; i++) {
child = nodes[i];
parent = child.getParentDisplay();
if (parent != null) {
po = parent.getUserObject();
children = (Set) map.get(po);
if (children == null) {
children = new HashSet<Object>();
map.put(po, children);
}
children.add(nodes[i].getUserObject());
}
}
return map;
}
/** Creates the browsers controlled by this model. */
private void createBrowsers()
{
Browser browser =
BrowserFactory.createBrowser(Browser.PROJECTS_EXPLORER,
component, experimenter, true);
selectedBrowser = browser;
browser.setSelected(true);
browsers.put(Browser.PROJECTS_EXPLORER, browser);
browser = BrowserFactory.createBrowser(Browser.SCREENS_EXPLORER,
component, experimenter, true);
browsers.put(Browser.SCREENS_EXPLORER, browser);
browser = BrowserFactory.createBrowser(Browser.TAGS_EXPLORER,
component, experimenter, true);
browsers.put(Browser.TAGS_EXPLORER, browser);
browser = BrowserFactory.createBrowser(Browser.IMAGES_EXPLORER,
component, experimenter, true);
browsers.put(Browser.IMAGES_EXPLORER, browser);
browser = BrowserFactory.createBrowser(Browser.FILES_EXPLORER,
component, experimenter, true);
browsers.put(Browser.FILES_EXPLORER, browser);
browser = BrowserFactory.createBrowser(Browser.FILE_SYSTEM_EXPLORER,
component, experimenter, true);
browsers.put(Browser.FILE_SYSTEM_EXPLORER, browser);
browser = BrowserFactory.createBrowser(Browser.ADMIN_EXPLORER,
component, experimenter, true);
browsers.put(Browser.ADMIN_EXPLORER, browser);
}
/** Initializes. */
private void initialize()
{
importFailureCount = 0;
importSuccessCount = 0;
state = TreeViewer.NEW;
browsers = new HashMap<Integer, Browser>();
recycled = false;
refImage = null;
refRndSettings = null;
importing = false;
sorter = new ViewerSorter();
Integer value = (Integer) TreeViewerAgent.getRegistry().lookup(
LookupNames.DATA_DISPLAY);
if (value == null) value = LookupNames.EXPERIMENTER_DISPLAY;
setDisplayMode(value);
}
/**
* Creates a new instance and sets the state to {@link TreeViewer#NEW}.
*
* @param exp The experimenter this manager is for.
*/
protected TreeViewerModel(ExperimenterData exp)
{
initialize();
this.experimenter = exp;
selectedGroupId = exp.getDefaultGroup().getId();
}
/**
* Called by the <code>TreeViewer</code> after creation to allow this
* object to store a back reference to the embedding component.
*
* @param component The embedding component.
*/
void initialize(TreeViewer component)
{
this.component = component;
createBrowsers();
}
/**
* Returns <code>true</code> if the {@link TreeViewer} is recycled,
* <code>false</code> otherwise.
*
* @return See above.
*/
boolean isRecycled() { return recycled; }
/**
* Sets to <code>true</code> if the {@link TreeViewer} is recycled,
* <code>false</code> otherwise.
*
* @param b The value to set.
*/
void setRecycled(boolean b) { recycled = b; }
/**
* Sets the currently selected {@link Browser}.
*
* @param browser The currently selected {@link Browser}.
*/
void setSelectedBrowser(Browser browser) { selectedBrowser = browser; }
/**
* Returns the selected {@link Browser}.
*
* @return See above.
*/
Browser getSelectedBrowser() { return selectedBrowser; }
/**
* Returns the browsers.
*
* @return See above.
*/
Map<Integer, Browser> getBrowsers() { return browsers; }
/**
* Returns the current state.
*
* @return One of the flags defined by the {@link TreeViewer} interface.
*/
int getState() { return state; }
/**
* Sets the object in the {@link TreeViewer#DISCARDED} state.
* Any ongoing data loading will be cancelled.
*/
void discard()
{
cancel();
state = TreeViewer.DISCARDED;
}
/**
* Sets the object in the {@link TreeViewer#READY} state.
* Any ongoing data loading will be cancelled.
*/
void cancel()
{
if (currentLoader != null) {
currentLoader.cancel();
currentLoader = null;
}
state = TreeViewer.READY;
}
/**
* Starts the asynchronous removal of the data and sets the state to
* {@link TreeViewer#SAVE}.
* This method should be invoked to remove a collection of groups or
* experimenters.
*
* @param values The groups or experimenters to delete.
*/
void fireObjectsDeletion(List<DataObject> values)
{
state = TreeViewer.SAVE;
SecurityContext ctx = getSecurityContext();
currentLoader = new DataObjectRemover(component, ctx, values);
currentLoader.load();
}
/**
* Returns the {@link Finder} component.
*
* @return See above.
*/
Finder getFinder() { return finder; }
/**
* Sets the finder component.
*
* @param finder The component to set.
*/
void setFinder(Finder finder) { this.finder = finder; }
/**
* Returns the current user's details.
*
* @return See above.
*/
ExperimenterData getUserDetails()
{
return (ExperimenterData) TreeViewerAgent.getRegistry().lookup(
LookupNames.CURRENT_USER_DETAILS);
}
/**
* Sets the current state.
*
* @param state The state to set.
*/
void setState(int state) { this.state = state; }
/**
* Loads existing objects that can be added to the specified
* <code>DataObject</code>.
*
* @param ho The node to add the objects to.
*/
void fireDataExistingObjectsLoader(DataObject ho)
{
state = TreeViewer.LOADING_DATA;
SecurityContext ctx = getSecurityContext();
if (TreeViewerAgent.isAdministrator())
ctx = getAdminContext();
//if (TreeViewerAgent.isAdministrator()) ctx = adminC
currentLoader = new ExistingObjectsLoader(component, ctx, ho);
currentLoader.load();
}
/**
* Fires an asynchronous call to add the specified children to the
* the currently selected parent.
*
* @param children The children to add.
*/
void fireAddExistingObjects(Set children)
{
TreeImageDisplay parent = selectedBrowser.getLastSelectedDisplay();
if (parent == null) return;
Object po = parent.getUserObject();
SecurityContext ctx = getSecurityContext();
if ((po instanceof ProjectData) || ((po instanceof DatasetData))) {
currentLoader = new ExistingObjectsSaver(component, ctx,
(DataObject) po, children);
currentLoader.load();
}
state = TreeViewer.READY;
}
/**
* Sets the collection of nodes to copy.
*
* @param nodes The nodes to copy.
* @param index The action index.
*/
void setNodesToCopy(TreeImageDisplay[] nodes, int index)
{
copyIndex = index;
nodesToCopy = nodes;
}
/**
* Returns the nodes to copy.
*
* @return See above.
*/
TreeImageDisplay[] getNodesToCopy() { return nodesToCopy; }
/**
* Copies and pastes the nodes. Returns <code>true</code> if we can perform
* the operation according to the selected nodes, <code>false</code>
* otherwise.
*
* @param parents The parents of the nodes to copy.
* @return See above
*/
boolean paste(TreeImageDisplay[] parents)
{
//Check if array contains Experimenter data
if (parents[0].getUserObject() instanceof ExperimenterData) {
copyIndex = TreeViewer.CUT_AND_PASTE;
return cut();
}
Map map = buildCopyMap(parents);
SecurityContext ctx = getSecurityContext();
if (map == null) return false;
if (copyIndex == TreeViewer.COPY_AND_PASTE)
currentLoader = new DataObjectUpdater(component,ctx, map,
DataObjectUpdater.COPY_AND_PASTE);
else if (copyIndex == TreeViewer.CUT_AND_PASTE) {
Map toRemove = buildCutMap(nodesToCopy);
currentLoader = new DataObjectUpdater(component, ctx, map, toRemove,
DataObjectUpdater.CUT_AND_PASTE);
}
currentLoader.load();
state = TreeViewer.SAVE;
nodesToCopy = null;
return true;
}
/**
* Returns <code>true</code> if the nodes have to be cut, <code>false</code>
* otherwise.
*
* @return See above.
*/
boolean cut()
{
if (copyIndex != TreeViewer.CUT_AND_PASTE) return false;
if (nodesToCopy == null || nodesToCopy.length == 0) return false;
Map toRemove = buildCutMap(nodesToCopy);
SecurityContext ctx = getSecurityContext();
currentLoader = new DataObjectUpdater(component, ctx,
new HashMap(), toRemove, DataObjectUpdater.CUT);
currentLoader.load();
state = TreeViewer.SAVE;
return true;
}
/**
* Returns the first name and the last name of the currently
* selected experimenter as a String.
*
* @return See above.
*/
String getExperimenterNames()
{
return EditorUtil.formatExperimenter(getExperimenter());
}
/**
* Returns the selected experimenter.
*
* @return See above.
*/
ExperimenterData getExperimenter()
{
return getUserDetails();
}
/**
* Returns <code>true</code> if the rollOver option is turned on,
* <code>false</code> otherwise.
*
* @return See above.
*/
boolean isRollOver() { return rollOver; }
/**
* Sets the value of the rollOver flag.
*
* @param rollOver Pass <code>true</code> to turn the flag on,
* <code>false</code> to turn off.
*/
void setRollOver(boolean rollOver) { this.rollOver = rollOver; }
/**
* Sets the parameters used to copy and paste rendering settings across
* a collection of pixels set.
*
* @param refImage The image to copy the rendering settings from.
* @param rndProxyDef Copied 'pending' rendering settings (can be null)
*/
void setRndSettings(ImageData refImage, RndProxyDef rndProxyDef)
{
this.refImage = refImage;
this.refRndSettings = rndProxyDef;
}
/**
* Returns <code>true</code> if there are rendering settings to paste,
* <code>false</code> otherwise.
*
* @return See above.
*/
boolean hasRndSettingsToPaste() { return refRndSettings!=null || refImage != null; }
/**
* Fires an asynchronous call to paste the rendering settings.
*
* @param ids Collection of nodes identifiers.
* @param klass The type of nodes to handle.
*/
void firePasteRenderingSettings(List<Long> ids, Class klass) {
state = TreeViewer.SETTINGS_RND;
SecurityContext ctx = getSecurityContext();
if (ctx == null) {
ctx = new SecurityContext(refImage.getGroupId());
}
currentLoader = new RndSettingsSaver(component, ctx, klass, ids, refRndSettings, refImage);
currentLoader.load();
}
/**
* Fires an asynchronous call to paste the rendering settings.
*
* @param ref The time reference object.
*/
void firePasteRenderingSettings(TimeRefObject ref)
{
state = TreeViewer.SETTINGS_RND;
SecurityContext ctx = getSecurityContext();
currentLoader = new RndSettingsSaver(component, ctx, ref,
refImage);
currentLoader.load();
}
/**
* Fires an asynchronous call to paste the rendering settings.
*
* @param ids Collection of nodes identifiers.
* @param klass The type of nodes to handle.
*/
void fireResetRenderingSettings(List<Long> ids, Class klass)
{
state = TreeViewer.SETTINGS_RND;
SecurityContext ctx = getSecurityContext();
currentLoader = new RndSettingsSaver(component, ctx, klass, ids,
RndSettingsSaver.RESET);
currentLoader.load();
}
/**
* Fires an asynchronous call to paste the rendering settings.
*
* @param ref The time reference object.
*/
void fireResetRenderingSettings(TimeRefObject ref)
{
state = TreeViewer.SETTINGS_RND;
SecurityContext ctx = getSecurityContext();
currentLoader = new RndSettingsSaver(component, ctx, ref,
RndSettingsSaver.RESET);
currentLoader.load();
}
/**
* Fires an asynchronous call to paste the rendering settings.
*
* @param ids Collection of nodes identifiers.
* @param klass The type of nodes to handle.
*/
void fireSetMinMax(List<Long> ids, Class klass)
{
state = TreeViewer.SETTINGS_RND;
SecurityContext ctx = getSecurityContext();
currentLoader = new RndSettingsSaver(component, ctx, klass, ids,
RndSettingsSaver.SET_MIN_MAX);
currentLoader.load();
}
/**
* Fires an asynchronous call to paste the rendering settings.
*
* @param ids Collection of nodes identifiers.
* @param klass The type of nodes to handle.
*/
void fireSetOwnerRenderingSettings(List<Long> ids, Class klass)
{
state = TreeViewer.SETTINGS_RND;
SecurityContext ctx = getSecurityContext();
currentLoader = new RndSettingsSaver(component, ctx, klass, ids,
RndSettingsSaver.SET_OWNER);
currentLoader.load();
}
/**
* Fires an asynchronous call to set the original rendering settings.
*
* @param ref The time reference object.
*/
void fireSetOriginalRenderingSettings(TimeRefObject ref)
{
state = TreeViewer.SETTINGS_RND;
SecurityContext ctx = getSecurityContext();
currentLoader = new RndSettingsSaver(component, ctx, ref,
RndSettingsSaver.SET_MIN_MAX);
currentLoader.load();
}
/**
* Fires an asynchronous call to set the rendering settings used by the
* owner of the images.
*
* @param ref The time reference object.
*/
void fireSetOwnerRenderingSettings(TimeRefObject ref)
{
state = TreeViewer.SETTINGS_RND;
SecurityContext ctx = getSecurityContext();
currentLoader = new RndSettingsSaver(component, ctx, ref,
RndSettingsSaver.SET_MIN_MAX);
currentLoader.load();
}
/**
* Starts an asynchronous call to save a data object.
*
* @param object The object to create.
* @param withParent Sets to <code>true</code> if the object will
* have a parent, <code>false</code> otherwise.
*/
void fireDataObjectCreation(DataObject object, boolean withParent)
{
DataObject data = null;
if (withParent) {
Browser browser = getSelectedBrowser();
TreeImageDisplay node = browser.getLastSelectedDisplay();
if (node != null) {
Object p = node.getUserObject();
if (object instanceof DatasetData) {
if (p instanceof ProjectData)
data = ((DataObject) p);
} else if (object instanceof PlateData) {
if (p instanceof ScreenData)
data = ((DataObject) p);
} else if (object instanceof TagAnnotationData) {
if (p instanceof TagAnnotationData) {
TagAnnotationData tag = (TagAnnotationData) p;
String ns = tag.getNameSpace();
if (ns != null &&
TagAnnotationData.INSIGHT_TAGSET_NS.equals(ns))
data = tag;
}
}
}
}
SecurityContext ctx = getSecurityContext();
currentLoader = new DataObjectCreator(component, ctx, object, data);
currentLoader.load();
}
/**
* Returns the metadata viewer.
*
* @return See above.
*/
MetadataViewer getMetadataViewer()
{
if (metadataViewer == null)
metadataViewer = MetadataViewerFactory.getViewer("");
return metadataViewer;
}
/**
* Creates the advanced finder.
*
* @return See above.
*/
AdvancedFinder getAdvancedFinder()
{
if (advancedFinder == null) {
advancedFinder = FinderFactory.getAdvancedFinder(
TreeViewerAgent.getRegistry(),
TreeViewerAgent.getAvailableUserGroups());
advancedFinder.setDisplayMode(getDisplayMode());
}
return advancedFinder;
}
/**
* Browses the node hosting the project to browse.
*
* @param node The node to browse.
*/
void browseProject(TreeImageDisplay node)
{
state = TreeViewer.LOADING_DATA;
ExperimenterData exp = getSelectedBrowser().getNodeOwner(node);
SecurityContext ctx = getSecurityContext();
currentLoader = new ProjectsLoader(component, ctx, node, exp.getId());
currentLoader.load();
}
/**
* Browses the node hosting the plates to browse.
*
* @param nodes The nodes to browse.
* @param withThumbnails Pass <code>true</code> to load the thumbnails,
* <code>false</code> otherwise.
*/
void browsePlates(Collection<TreeImageDisplay> nodes, boolean withThumbnails)
{
state = TreeViewer.LOADING_DATA;
List<TreeImageSet> plates = new ArrayList<TreeImageSet>();
Iterator<TreeImageDisplay> i = nodes.iterator();
while (i.hasNext())
plates.add((TreeImageSet) i.next());
SecurityContext ctx = getSecurityContext();
currentLoader = new PlateWellsLoader(component, ctx, plates,
withThumbnails);
currentLoader.load();
}
/**
* Browses the node hosting the time interval to browse.
*
* @param node The node to browse.
*/
void browseTimeInterval(TreeImageTimeSet node)
{
state = TreeViewer.LOADING_DATA;
SecurityContext ctx = getSecurityContext();
currentLoader = new TimeIntervalsLoader(component, ctx, node);
currentLoader.load();
}
/**
* Browses the node hosting the tag linked to tags to browse.
*
* @param node The node to browse.
*/
void browseTag(TreeImageDisplay node)
{
state = TreeViewer.LOADING_DATA;
ExperimenterData exp = getSelectedBrowser().getNodeOwner(node);
if (exp == null) exp = TreeViewerAgent.getUserDetails();
SecurityContext ctx = getSecurityContext();
currentLoader = new TagHierarchyLoader(component, ctx,
node, exp.getId());
currentLoader.load();
}
/**
* Returns the {@link Browser} corresponding to the passed index
* or <code>null</code> if the index is not supported.
*
* @param index The index of the {@link Browser}.
* @return See above
*/
Browser getBrowser(int index) { return browsers.get(index); }
/**
* Returns the name of the image to copy and paste.
*
* @return See above.
*/
String getRefImagePartialName()
{
if (refImage == null) return null;
return EditorUtil.getPartialName(refImage.getName());
}
/**
* Returns the name of the image to copy and paste.
*
* @return See above.
*/
String getRefImageName()
{
if (refImage == null) return null;
return UIUtilities.removeFileExtension(refImage.getName());
}
/**
* Returns <code>true</code> if the image to copy the rendering settings
* from is in the specified group, <code>false</code> otherwise.
*
* @param groupID The group to handle.
* @return See above.
*/
boolean areSettingsCompatible(long groupID)
{
if (refImage == null) return false;
return refRndSettings!=null || refImage.getGroupId() == groupID;
}
/**
* Returns the type of nodes to copy or <code>null</code> if no nodes
* to copy or cut.
*
* @return See above.
*/
Class getDataToCopyType()
{
TreeImageDisplay[] nodes = getNodesToCopy();
if (nodes == null || nodes.length == 0) return null;
Object ho = nodes[0].getUserObject();
return ho.getClass();
}
/**
* Returns the objects to copy.
*
* @return See above.
*/
List<DataObject> getDataToCopy()
{
TreeImageDisplay[] nodes = getNodesToCopy();
if (nodes == null || nodes.length == 0) return null;
List<DataObject> l = new ArrayList<DataObject>();
for (int i = 0; i < nodes.length; i++) {
if (nodes[i].getUserObject() instanceof DataObject)
l.add((DataObject) nodes[i].getUserObject());
}
return l;
}
/**
* Sets the {@link DataBrowser}.
*
* @param dataViewer The data viewer.
*/
void setDataViewer(DataBrowser dataViewer)
{
this.dataViewer = dataViewer;
}
/**
* Returns the {@link DataBrowser}.
*
* @return See above.
*/
DataBrowser getDataViewer() { return dataViewer; }
/**
* Starts an asynchronous call to download the images.
*
* @param images The image to download.
* @param folder The folder where to download the image.
* @param application The third party application or <code>null</code>.
*/
void downloadImages(List<ImageData> images, File folder,
ApplicationData application)
{
if (images == null || images.isEmpty()) return;
Set<Long> ids = new HashSet<Long>();
ImageData img;
PixelsData data;
Iterator i = images.iterator();
Object o;
while (i.hasNext()) {
o = (Object) i.next();
if (o instanceof ImageData) {
img = (ImageData) o;
if (img.isArchived()) {
data = img.getDefaultPixels();
ids.add(data.getId());
}
}
}
SecurityContext ctx = getSecurityContext();
OriginalFileLoader loader = new OriginalFileLoader(component, ctx, ids,
folder, application);
loader.load();
}
/** Refreshes the renderer. */
void refreshRenderer()
{
if (metadataViewer == null) return;
Renderer rnd = metadataViewer.getRenderer();
if (rnd != null) {
rnd.refresh();
metadataViewer.renderPlane();
}
}
/** Resets the metadata view.
*
* @return The newly created metadata viewer.
*/
MetadataViewer resetMetadataViewer()
{
metadataViewer = null;
return getMetadataViewer();
}
/**
* Reloads the specified thumbnails.
*
* @param ids The collection of images' ids to reload.
*/
void reloadThumbnails(List<Long> ids)
{
if (dataViewer != null)
dataViewer.reloadThumbnails(ids);
}
/**
* Returns the MIME type to the passed object.
*
* @param object The object to handle.
* @return See above.
*/
String getObjectMimeType(Object object)
{
if (object instanceof ImageData) {
ImageData img = (ImageData) object;
if (img.isArchived()) return TreeViewerFactory.IMAGE_ARCHIVED;
return TreeViewerFactory.IMAGE_NOT_ARCHIVED;
} else if (object instanceof FileAnnotationData) {
FileAnnotationData fa = (FileAnnotationData) object;
FileDataSource fds = new FileDataSource(fa.getFileName());
String type = fds.getContentType();
return type;
}
return null;
}
/**
* Returns the MIME type of the currently selected object.
*
* @return See above.
*/
String getObjectMimeType()
{
Browser browser = getSelectedBrowser();
if (browser == null) return null;
TreeImageDisplay d = browser.getLastSelectedDisplay();
if (d == null) return null;
return getObjectMimeType(d.getUserObject());
}
/**
* Returns <code>true</code> if the currently logged in user is
* a leader of a group, <code>false</code> otherwise.
*
* @return See above.
*/
boolean isLeader()
{
return TreeViewerAgent.getGroupsLeaderOf().size() > 0;
}
/**
* Returns <code>true</code> if the user currently logged in is an owner
* of the group, <code>false</code> otherwise.
*
* @param g The group to handle.
* @return See above.
*/
boolean isGroupOwner(GroupData g)
{
if (g == null) return false;
Set leaders = g.getLeaders();
if (CollectionUtils.isEmpty(leaders)) return false;
Iterator i = leaders.iterator();
ExperimenterData leader;
ExperimenterData user = getExperimenter();
while (i.hasNext()) {
leader = (ExperimenterData) i.next();
if (user.getId() == leader.getId()) return true;
}
return false;
}
/**
* Returns <code>true</code> if the currently logged in user
* is an administrator, <code>false</code> otherwise.
*
* @return See above.
*/
boolean isAdministrator()
{
return TreeViewerAgent.isAdministrator();
}
/**
* Fires an asynchronous call to create groups or experimenters.
*
* @param object The object hosting information about object to create.
*/
void fireAdmin(AdminObject object)
{
SecurityContext ctx = getSecurityContext();
if (TreeViewerAgent.isAdministrator())
ctx = getAdminContext();
currentLoader = new AdminCreator(component, ctx, object);
currentLoader.load();
}
/**
* Returns the security context for the administrator
*
* @return See above
*/
SecurityContext getAdminContext()
{
if (adminContext == null)
adminContext = TreeViewerAgent.getAdminContext();
return adminContext;
}
/**
* Returns <code>true</code> if on-going imports, <code>false</code>
* otherwise.
*
* @return See above.
*/
boolean isImporting() { return importing; }
/**
* Sets the flag indicating if there are on-going imports.
*
* @param importing Pass <code>true</code> if there are on-going imports,
* <code>false</code> otherwise.
* @param importResult The result of the import.
*/
void setImporting(boolean importing, Object importResult)
{
this.importing = importing;
if (importResult == null) return;
if (importResult instanceof ImportErrorObject) {
importFailureCount++;
} else {
importSuccessCount++;
}
}
/** Clears the result.*/
void clearImportResult()
{
importFailureCount = 0;
importSuccessCount = 0;
}
/**
* Returns the number of import failures.
*
* @return See above.
*/
int getImportFailureCount() { return importFailureCount; }
/**
* Returns the number of successful imports.
*
* @return See above.
*/
int getImportSuccessCount() { return importSuccessCount; }
/**
* Returns
*/
boolean isFullScreen() { return true; }
/**
* Loads the parents of the specified annotation.
*
* @param data The annotation to handle.
*/
void loadParentOf(FileAnnotationData data)
{
SecurityContext ctx = new SecurityContext(data.getGroupId());
ParentLoader loader = new ParentLoader(component, ctx, data);
loader.load();
}
/**
* Starts an asynchronous retrieval
*
* @param data The <code>DataObject</code> to create.
* @param children The children to add to the <code>DataObject</code>.
*/
void fireDataSaving(DataObject data, Collection children)
{
if (data instanceof DatasetData) {
SecurityContext ctx = getSecurityContext();
DataObjectCreator loader = new DataObjectCreator(component, ctx,
data, null, children);
loader.load();
}
}
/**
* Returns the script corresponding to the passed identifier.
*
* @param scriptID The identifier of the script.
* @return See above.
*/
ScriptObject getScript(long scriptID)
{
return scripts.get(scriptID);
}
/**
* Loads the scripts.
*
* @param location The location of the mouse.
* @param invoker The invoker.
*/
void loadScripts(Point location, Component invoker)
{
ScriptsLoader loader = new ScriptsLoader(component,
getSecurityContext(null), false, location, invoker);
loader.load();
}
/**
* Returns the collection of available scripts.
*
* @return See above.
*/
Collection<ScriptObject> getAvailableScripts()
{
if (scripts == null) return null;
return scripts.values();
}
/**
* Sets the collection of scripts.
*
* @param scripts The value to set.
*/
void setAvailableScripts(List scripts)
{
if (scripts == null) {
this.scripts = null;
return;
}
//sort the scripts.
Map<Long, ScriptObject> map = new LinkedHashMap<Long, ScriptObject>();
List l = sorter.sort(scripts);
Iterator i = l.iterator();
ScriptObject s;
while (i.hasNext()) {
s = (ScriptObject) i.next();
map.put(s.getScriptID(), s);
}
this.scripts = map;
}
/**
* Loads the specified script.
*
* @param scriptID The identifier of the script to load.
*/
void loadScript(long scriptID)
{
ScriptLoader loader = new ScriptLoader(component,
getSecurityContext(null), scriptID);
loader.load();
}
/**
* Sets the specified script.
*
* @param script The loaded script.
*/
void setScript(ScriptObject script)
{
if (scripts == null || scripts.size() == 0) return;
ScriptObject sc = scripts.get(script.getScriptID());
if (sc != null) sc.setJobParams(script.getParameters());
}
/**
* Returns the script corresponding to the specified name.
*
* @return See above.
*/
ScriptObject getScriptFromName(String name)
{
List<ScriptObject> scripts = getScriptsWithUI();
Iterator<ScriptObject> i = scripts.iterator();
ScriptObject script;
while (i.hasNext()) {
script = i.next();
if (name.contains(script.getName()))
return script;
}
return null;
}
/** Transfers the nodes.
*
* @param target The target.
* @param nodes The nodes to transfer.
*/
void transfer(TreeImageDisplay target, List<TreeImageDisplay> nodes)
{
nodesToCopy = (TreeImageDisplay[]) nodes.toArray(
new TreeImageDisplay[0]);
copyIndex = TreeViewer.CUT_AND_PASTE;
Map toRemove = buildCutMap(nodesToCopy);
Map map = new HashMap();
if (target != null) {
TreeImageDisplay[] parents = new TreeImageDisplay[1];
parents[0] = target;
map = buildCopyMap(parents);
}
SecurityContext ctx = getSecurityContext();
currentLoader = new DataObjectUpdater(component, ctx, map, toRemove,
DataObjectUpdater.CUT_AND_PASTE);
currentLoader.load();
state = TreeViewer.SAVE;
}
/**
* Returns the security context.
*
* @return See above
*/
SecurityContext getSecurityContext() { return getSecurityContext(null); }
/**
* Returns the security context.
*
* @return See above
*/
SecurityContext getSecurityContext(TreeImageDisplay node)
{
Browser browser = getSelectedBrowser();
if (browser == null) return new SecurityContext(selectedGroupId);
if (node == null) node = browser.getLastSelectedDisplay();
if (node == null) return new SecurityContext(selectedGroupId);
return browser.getSecurityContext(node);
}
/**
* Returns the group the currently selected node belongs to or the default
* group if no node selected.
*
* @return See above.
*/
GroupData getSelectedGroup()
{
Collection set = TreeViewerAgent.getAvailableUserGroups();
Iterator i = set.iterator();
GroupData g;
while (i.hasNext()) {
g = (GroupData) i.next();
if (g.getId() == selectedGroupId)
return g;
}
g = TreeViewerAgent.getUserDetails().getDefaultGroup();
selectedGroupId = g.getGroupId();
return g;
}
/**
* Returns the groups the user is a member of.
*
* @return See above.
*/
Collection<GroupData> getAvailableGroups()
{
return TreeViewerAgent.getAvailableUserGroups();
}
/**
* Returns the id of the group.
*
* @return See above.
*/
long getSelectedGroupId() { return selectedGroupId; }
/**
* Sets the selected group.
*
* @param selectedGroupId The identifier of the group.
*/
void setSelectedGroupId(long selectedGroupId)
{
this.selectedGroupId = selectedGroupId;
}
/**
* Loads the data.
*
* @param ctx The security context.
* @param dialog The dialog where to display the result.
* @param type The node type.
* @param userID The id of the user to move the data to.
*/
void fireMoveDataLoading(SecurityContext ctx,
MoveGroupSelectionDialog dialog, Class type, long userID)
{
MoveDataLoader loader = new MoveDataLoader(component, ctx, type, dialog,
userID);
loader.load();
}
/**
* 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 = TreeViewerAgent.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 groups the user is a member of.
*
* @return See above.
*/
Collection getGroups()
{
return TreeViewerAgent.getAvailableUserGroups();
}
/**
* Returns the display mode. One of the constants defined by
* {@link TreeViewer}.
*
* @return See above.
*/
int getDisplayMode() { return displayMode; }
/**
* Sets the display mode.
*
* @param value The value to set.
*/
void setDisplayMode(int value)
{
switch (value) {
case LookupNames.EXPERIMENTER_DISPLAY:
case LookupNames.GROUP_DISPLAY:
displayMode = value;
break;
default:
displayMode = LookupNames.EXPERIMENTER_DISPLAY;
}
}
/**
* Starts an asynchronous call checking if the images are split between
* various containers preventing the action to happen.
*
* @param objects The object to handle.
* @param action The object to handle after the check.
* @param index The type of action.
*/
void fireImageChecking(Map<SecurityContext, List<DataObject>> objects,
Object action, ImageCheckerType index)
{
ImageChecker loader = new ImageChecker(component, getSecurityContext(),
objects, action, index);
loader.load();
}
/**
* Returns the name of the server the user is currently connected to.
*
* @return See above.
*/
String getHostname()
{
return TreeViewerAgent.getRegistry().getAdminService().getServerName();
}
/**
* 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 TreeViewerAgent.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.
* @return See above.
*/
boolean isSystemUser(long id, String key)
{
return TreeViewerAgent.getRegistry().getAdminService().isSystemUser(id,
key);
}
/**
* Returns <code>isSystemUsertrue</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 TreeViewerAgent.getRegistry().getAdminService().isSecuritySystemGroup(id, key);
}
}