/*
*------------------------------------------------------------------------------
* 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;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import org.openmicroscopy.shoola.agents.treeviewer.browser.Browser;
import org.openmicroscopy.shoola.agents.util.browser.TreeFileSet;
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.env.data.model.TimeRefObject;
import omero.gateway.SecurityContext;
import org.openmicroscopy.shoola.env.data.views.CallHandle;
import org.openmicroscopy.shoola.env.data.views.MetadataHandlerView;
import omero.gateway.model.DataObject;
import omero.gateway.model.DatasetData;
import omero.gateway.model.FileAnnotationData;
import omero.gateway.model.GroupData;
import omero.gateway.model.ImageData;
import omero.gateway.model.ProjectData;
import omero.gateway.model.ScreenData;
import omero.gateway.model.TagAnnotationData;
/**
* Reloads the data for the specified experimenters.
* This class calls the <code>refreshHierarchy</code> in the
* <code>DataManagerView</code>.
*
* @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
*/
public class RefreshExperimenterDataLoader
extends DataBrowserLoader
{
/** The type of the nodes to select when done. */
private Class<?> type;
/** The identifier of the object to select when done. */
private long id;
/** The type of the root node. */
private Class<?> rootNodeType;
/** Collection of {@link RefreshExperimenterDef} objects. */
private Map<SecurityContext, RefreshExperimenterDef> expNodes;
/** Handle to the asynchronous call so that we can cancel it. */
private CallHandle handle;
/** The node of reference hosting the node to browse. */
private Object refNode;
/** The data object to browse. */
private DataObject toBrowse;
/** The smart folder for tags.*/
private Map<SecurityContext, TreeImageSet> smartFolders;
/**
* Controls if the passed class is supported.
*
* @param klass The class to check.
*/
private void checkClass(Class<?> klass)
{
if (ProjectData.class.equals(klass) || ImageData.class.equals(klass) ||
TagAnnotationData.class.equals(klass) ||
DatasetData.class.equals(klass) ||
FileAnnotationData.class.equals(klass) ||
ScreenData.class.equals(klass) || GroupData.class.equals(klass))
return;
throw new IllegalArgumentException("Root node not supported.");
}
/**
* Formats the results.
*
* @param expId The user's id.
* @param result The result of the call for the passed user.
*/
private void setExperimenterResult(SecurityContext ctx, Object result)
{
RefreshExperimenterDef node = getNode(ctx);
Map<Object, Object> map;
if (result instanceof Map)
map = (Map) result;
else {
Collection set = (Collection) result;
Iterator j = set.iterator();
map = new HashMap<Object, Object>();
Object parent;
Set children = null;
Object ob;
TreeImageSet display;
while (j.hasNext()) {
parent = j.next();
if (parent instanceof TimeRefObject) { //for tag support.
if (smartFolders != null) {
display = smartFolders.get(ctx);
if (display != null) {
display.removeAllChildren();
display.removeAllChildrenDisplay();
map.put(display,
((TimeRefObject) parent).getResults());
}
}
} else {
if (parent instanceof ProjectData) {
children = ((ProjectData) parent).getDatasets();
} else if (parent instanceof DatasetData) {
children = new HashSet(1);
children.add(parent);
} else if (parent instanceof TagAnnotationData) {
children = new HashSet(1);
children.add(parent);
} else if (parent instanceof ScreenData) {
children = ((ScreenData) parent).getPlates();
} else if (parent instanceof GroupData) {
children = ((GroupData) parent).getExperimenters();
}
map.put(parent, children);
}
}
}
node.setResults(map);
}
/**
* Returns the node corresponding to the security context.
*
* @param ctx The context to handle.
* @return
*/
private RefreshExperimenterDef getNode(SecurityContext ctx)
{
Iterator<Entry<SecurityContext, RefreshExperimenterDef>>
kk = expNodes.entrySet().iterator();
Entry<SecurityContext, RefreshExperimenterDef> e;
while (kk.hasNext()) {
e = kk.next();
if (e.getKey().equals(ctx)) {
return e.getValue();
}
}
return null;
}
/**
* Formats the results.
*
* @param ctx The security context.
* @param result The result of the call for the passed user.
*/
private void formatSmartFolderResult(SecurityContext ctx, List result)
{
RefreshExperimenterDef node = expNodes.get(ctx);
List nodes = node.getExpandedNodes();
int n = nodes.size();
TreeImageSet display;
TimeRefObject ref;
Map m = new HashMap();
for (int i = 0; i < n; i++) {
display = (TreeImageSet) nodes.get(i);
ref = (TimeRefObject) result.get(i);
m.put(display, ref.getResults());
}
node.setResults(m);
}
/**
* Creates a new instance.
*
* @param viewer The viewer this data loader is for.
* Mustn't be <code>null</code>.
* @param ctx The security context.
* @param rootNodeType The root node either <code>Project</code> or
* <code>Screen</code>.
* @param expNodes Collection of nodes hosting information about the nodes
* to refresh. Mustn't be <code>null</code>.
* @param refNode The node of reference.
* @param toBrowse The node to browse.
*/
public RefreshExperimenterDataLoader(Browser viewer, SecurityContext ctx,
Class<?> rootNodeType,
Map<SecurityContext, RefreshExperimenterDef> expNodes,
Class<?> type, long id, Object refNode, DataObject toBrowse)
{
super(viewer, ctx);
if (expNodes == null || expNodes.size() == 0)
throw new IllegalArgumentException("Nodes not valid.");
checkClass(rootNodeType);
this.rootNodeType = rootNodeType;
this.expNodes = expNodes;
this.type = type;
this.id = id;
this.refNode = refNode;
this.toBrowse = toBrowse;
}
/**
* Retrieves the data.
* @see DataBrowserLoader#load()
*/
public void load()
{
Entry<SecurityContext, RefreshExperimenterDef> entry;
Iterator<Entry<SecurityContext, RefreshExperimenterDef>>
i = expNodes.entrySet().iterator();
RefreshExperimenterDef def;
long userID;
TimeRefObject ref = null;
List nodes;
List<TimeRefObject> times;
Iterator j;
TreeImageSet node;
Map<SecurityContext, List>
m = new HashMap<SecurityContext, List>(expNodes.size());
SecurityContext ctx;
if (ImageData.class.equals(rootNodeType) ||
FileAnnotationData.class.equals(rootNodeType)) {
TreeImageTimeSet time;
TreeFileSet file;
while (i.hasNext()) {
entry = i.next();
ctx = entry.getKey();
userID = ctx.getExperimenter();
def = (RefreshExperimenterDef) entry.getValue();
nodes = def.getExpandedNodes();
j = nodes.iterator();
times = new ArrayList<TimeRefObject>(nodes.size());
while (j.hasNext()) {
node = (TreeImageSet) j.next();
if (node instanceof TreeImageTimeSet) {
time = (TreeImageTimeSet) node;
ref = new TimeRefObject(userID, TimeRefObject.TIME);
ref.setTimeInterval(time.getStartTime(),
time.getEndTime());
} else if (node instanceof TreeFileSet) {
file = (TreeFileSet) node;
ref = new TimeRefObject(userID, TimeRefObject.FILE);
ref.setFileType(file.getType());
}
if (ref != null) times.add(ref);
}
m.put(ctx, times);
}
} else {
List l;
List<Object> nl;
Iterator k;
Object ob;
while (i.hasNext()) {
entry = i.next();
ctx = entry.getKey();
userID = ctx.getExperimenter();
def = (RefreshExperimenterDef) entry.getValue();
if (GroupData.class.equals(rootNodeType)) {
l = (List) def.getExpandedTopNodes().get(GroupData.class);
if (l == null) l = new ArrayList();
m.put(ctx, l);
} else {
if (TagAnnotationData.class.equals(rootNodeType)) {
l = def.getExpandedNodes();
nl = new ArrayList<Object>();
j = l.iterator();
while (j.hasNext()) {
ob = (Object) j.next();
if (ob instanceof TreeFileSet) {
ref = new TimeRefObject(userID,
TimeRefObject.FILE);
ref.setFileType(
MetadataHandlerView.TAG_NOT_OWNED);
nl.add(ref);
if (smartFolders == null)
smartFolders = new
HashMap<SecurityContext, TreeImageSet>();
smartFolders.put(ctx, (TreeImageSet) ob);
} else nl.add(ob);
}
m.put(ctx, nl);
} else {
l = def.getExpandedNodes();
nl = new ArrayList<Object>();
j = l.iterator();
while (j.hasNext()) {
ob = (Object) j.next();
if (ob instanceof TreeFileSet) {
ref = new TimeRefObject(userID,
TimeRefObject.FILE);
ref.setFileType(TimeRefObject.FILE_IMAGE_TYPE);
nl.add(ref);
if (smartFolders == null)
smartFolders = new
HashMap<SecurityContext, TreeImageSet>();
smartFolders.put(ctx, (TreeImageSet) ob);
} else nl.add(ob);
}
m.put(ctx, nl);
}
}
}
}
handle = dmView.refreshHierarchy(rootNodeType, m, this);
}
/**
* Cancels the data loading.
* @see DataBrowserLoader#cancel()
*/
public void cancel() { handle.cancel(); }
/**
* Feeds the result back to the viewer.
* @see DataBrowserLoader#handleResult(Object)
*/
public void handleResult(Object result)
{
if (viewer.getState() == Browser.DISCARDED) return; //Async cancel.
if (GroupData.class.equals(rootNodeType)) {
Entry<SecurityContext, RefreshExperimenterDef> entry;
RefreshExperimenterDef def;
Iterator<Entry<SecurityContext, RefreshExperimenterDef>>
i = expNodes.entrySet().iterator();
Map nodes;
List l;
Iterator j;
while (i.hasNext()) {
entry = i.next();
def = entry.getValue();
nodes = def.getExpandedTopNodes();
viewer.setGroups((Collection) result,
(List) nodes.get(GroupData.class));
}
return;
}
Map m = (Map) result;
Entry entry;
Iterator i = m.entrySet().iterator();
SecurityContext ctx;
long expId;
if (ImageData.class.equals(rootNodeType) ||
FileAnnotationData.class.equals(rootNodeType)) {
while (i.hasNext()) {
entry = (Entry) i.next();
ctx = (SecurityContext) entry.getKey();
formatSmartFolderResult(ctx, (List) entry.getValue());
}
} else {
while (i.hasNext()) {
entry = (Entry) i.next();
ctx = (SecurityContext) entry.getKey();
Object o = entry.getValue();
if (smartFolders != null && o instanceof Map) {
//need to extract.
Map map = (Map) o;
Iterator k = map.entrySet().iterator();
Entry e;
TreeImageSet display;
Map newMap = new HashMap();
Object key;
while (k.hasNext()) {
e = (Entry) k.next();
key = e.getKey();
if (key instanceof TimeRefObject) {
if (smartFolders != null) {
display = smartFolders.get(ctx);
if (display != null) {
display.removeAllChildren();
display.removeAllChildrenDisplay();
newMap.put(display,
((TimeRefObject) key).getResults());
}
}
} else newMap.put(key, e.getValue());
}
setExperimenterResult(ctx, newMap);
} else {
setExperimenterResult(ctx, o);
}
}
}
viewer.setRefreshExperimenterData(expNodes, type, id);
if (refNode instanceof TreeImageDisplay || refNode == null)
viewer.browse((TreeImageDisplay) refNode, toBrowse, true);
}
}