package edu.ualberta.med.biobank.treeview; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Tree; import org.springframework.remoting.RemoteAccessException; import edu.ualberta.med.biobank.common.wrappers.ModelWrapper; import edu.ualberta.med.biobank.common.wrappers.listener.WrapperEvent; import edu.ualberta.med.biobank.common.wrappers.listener.WrapperListenerAdapter; import edu.ualberta.med.biobank.gui.common.BgcLogger; import edu.ualberta.med.biobank.gui.common.BgcPlugin; import edu.ualberta.med.biobank.treeview.dispatch.DispatchAdapter; public abstract class AbstractSearchedNode extends AdapterBase { private static BgcLogger logger = BgcLogger .getLogger(AbstractSearchedNode.class.getName()); protected Set<Object> searchedObjects = new HashSet<Object>(); protected Set<Integer> searchedObjectIds = new HashSet<Integer>(); private boolean keepDirectLeafChild; public AbstractSearchedNode(AdapterBase parent, int id, boolean keepDirectLeafChild) { super(parent, id, Messages.AbstractSearchedNode_searched, true); this.keepDirectLeafChild = keepDirectLeafChild; } @Override public void popupMenu(TreeViewer tv, Tree tree, Menu menu) { MenuItem mi = new MenuItem(menu, SWT.PUSH); mi.setText(Messages.AbstractSearchedNode_clear); mi.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { clear(); } }); } @Override public void performExpand() { List<ModelWrapper<?>> alreadyHasListener = new ArrayList<ModelWrapper<?>>(); try { for (AbstractAdapterBase child : getChildren()) { if (child instanceof AdapterBase) { ModelWrapper<?> childWrapper = ((AdapterBase) child) .getModelObject(); if (childWrapper != null) { childWrapper.reload(); } } List<AbstractAdapterBase> subChildren = new ArrayList<AbstractAdapterBase>( child.getChildren()); List<AbstractAdapterBase> toRemove = new ArrayList<AbstractAdapterBase>(); for (AbstractAdapterBase subChild : subChildren) { ModelWrapper<?> wrapper = null; if (subChild instanceof AdapterBase) { Object subChildObj = ((AdapterBase) subChild) .getModelObject(); if (subChildObj instanceof ModelWrapper) { wrapper = (ModelWrapper<?>) subChildObj; // wrapper.reload(); // FIXME: using reload here breaks a lot of stuff, // why? } } Integer subChildId = subChild.getId(); if (!searchedObjectIds.contains(subChildId)) { toRemove.add(subChild); } else { // subChild.rebuild(); if (wrapper != null) { alreadyHasListener.add(wrapper); } } } for (AbstractAdapterBase subChild : toRemove) child.removeChild(subChild); } // add searched objects is not yet there for (final Object o : searchedObjects) { if (o instanceof ModelWrapper) { ModelWrapper<?> w = (ModelWrapper<?>) o; if (!alreadyHasListener.contains(w)) { w.addWrapperListener(new WrapperListenerAdapter() { @Override public void deleted(WrapperEvent event) { searchedObjects.remove(o); performExpand(); } }); } } addNode(o); } if (!keepDirectLeafChild) { // remove sub children without any children List<AbstractAdapterBase> children = new ArrayList<AbstractAdapterBase>( getChildren()); for (AbstractAdapterBase child : children) { if (!(child instanceof DispatchAdapter) && child.getChildren().size() == 0) { removeChild(child); } } } } catch (final RemoteAccessException exp) { BgcPlugin.openRemoteAccessErrorMessage(exp); } catch (Exception e) { logger.error("Error while refreshing searched elements", e); //$NON-NLS-1$ } } protected abstract void addNode(Object obj); @Override protected void executeDoubleClick() { performExpand(); } @Override protected List<? extends ModelWrapper<?>> getWrapperChildren() throws Exception { return null; } @Override public String getViewFormId() { return null; } @Override public String getTooltipTextInternal() { return null; } @Override protected String getLabelInternal() { return null; } @Override public String getEntryFormId() { return null; } public void addSearchObject(Object searchedObject, Integer id) { searchedObjects.add(searchedObject); searchedObjectIds.add(id); } protected abstract boolean isParentTo(Object parent, Object child); @Override public List<AbstractAdapterBase> search(Class<?> searchedClass, Integer objectId) { return searchChildren(searchedClass, objectId); } public void clear() { searchedObjects.clear(); searchedObjectIds.clear(); removeAll(); performExpand(); } public void removeObject(Object child, Integer childId) { searchedObjects.remove(child); searchedObjectIds.remove(childId); } }