package edu.ualberta.med.biobank.treeview; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.springframework.remoting.RemoteAccessException; import edu.ualberta.med.biobank.SessionManager; import edu.ualberta.med.biobank.common.wrappers.ContainerWrapper; import edu.ualberta.med.biobank.common.wrappers.ModelWrapper; import edu.ualberta.med.biobank.forms.input.FormInput; import edu.ualberta.med.biobank.gui.common.BgcLogger; import edu.ualberta.med.biobank.gui.common.BgcPlugin; import edu.ualberta.med.biobank.treeview.admin.ContainerAdapter; import gov.nih.nci.system.applicationservice.WritableApplicationService; /** * Base class for all "Session" tree view nodes. Generally, most of the nodes in * the tree are adapters for classes in the ORM model. */ public abstract class AdapterBase extends AbstractAdapterBase { private static BgcLogger logger = BgcLogger.getLogger(AdapterBase.class .getName()); protected static final String BGR_LOADING_LABEL = Messages.AdapterBase_loading; private Object modelObject; public AdapterBase(AdapterBase parent, ModelWrapper<?> object) { super(parent, object == null ? null : object.getId(), null, null, false); setModelObject(object); } public AdapterBase(AdapterBase parent, Integer id, String label, boolean hasChildren) { super(parent, id, label, null, hasChildren); } public ModelWrapper<?> getModelObject() { return (ModelWrapper<?>) modelObject; } public ModelWrapper<?> getModelObjectClone() throws Exception { return getModelObject().getDatabaseClone(); } public void setParent(AdapterBase parent) { this.parent = parent; } public void setModelObject(ModelWrapper<?> object) { this.modelObject = object; if (getId() != null) init(); } @Override public Integer getId() { if (getModelObject() != null) { return getModelObject().getId(); } return super.getId(); } /** * Derived classes should not override this method. Instead they should * implement getNameInternal(). * * @return the name for the node. */ @Override public final String getLabel() { if (getModelObject() != null) { return getLabelInternal(); } return super.getLabel(); } /** * Derived classses should implement this method instead of overriding * getName(). * * @return the name of the node. The name is the label displayed in the * treeview. */ protected abstract String getLabelInternal(); @Override public AdapterBase getParent() { return (AdapterBase) parent; } /* * Used when updating tree nodes from a background thread. */ protected void setModelObject(Object modelObject) { this.modelObject = modelObject; } @Override public void addChild(AbstractAdapterBase child) { super.addChild(child); fireAdd(child); } @Override public void insertAfter(AbstractAdapterBase existingNode, AbstractAdapterBase newNode) { super.insertAfter(existingNode, newNode); fireAdd(newNode); } @Override public void removeChild(AbstractAdapterBase item, boolean closeForm) { if (children.size() == 0) return; AbstractAdapterBase itemToRemove = null; for (AbstractAdapterBase child : children) { if ((child.getId() == null && item.getId() == null) || (child.getId().equals(item.getId()) && child.getLabel() .equals(item.getLabel()))) itemToRemove = child; } if (itemToRemove != null) { if (closeForm) { closeEditor(new FormInput(itemToRemove)); } children.remove(itemToRemove); // override because of fireRemove fireRemove(itemToRemove); } } @Override public void removeAll() { super.removeAll(); notifyListeners(); } @Deprecated public WritableApplicationService getAppService() { if (getModelObject() != null) { return getModelObject().getAppService(); } if (parent != null) return ((AdapterBase) parent).getAppService(); return null; } /** * Called to load it's children; * * @param updateNode If not null, the node in the treeview to update. */ @Override public void loadChildren(final boolean updateNode) { BusyIndicator.showWhile(Display.getDefault(), new Runnable() { @Override public void run() { try { Collection<? extends ModelWrapper<?>> children = getWrapperChildren(); if (children != null) { for (ModelWrapper<?> child : children) { AbstractAdapterBase node = getChild(child.getId()); if (node == null) { node = createChildNode(child); addChild(node); } if (updateNode) { SessionManager.updateAdapterTreeNode(node); } } SessionManager.refreshTreeNode(AdapterBase.this); } } catch (final RemoteAccessException exp) { BgcPlugin.openRemoteAccessErrorMessage(exp); } catch (Exception e) { String text = getClass().getName(); if (getModelObject() != null) { text = getModelObject().toString(); } logger.error( "Error while loading children of node " + text, e); //$NON-NLS-1$ } } }); } /** * get the list of this model object children that this node should have as * children nodes. * * @throws Exception */ protected abstract List<? extends ModelWrapper<?>> getWrapperChildren() throws Exception; @Override protected Map<Integer, ?> getChildrenObjects() throws Exception { Map<Integer, Object> map = new HashMap<Integer, Object>(); for (ModelWrapper<?> model : getWrapperChildren()) { map.put(model.getId(), model); } return map; } public static boolean closeEditor(FormInput input) { IWorkbenchPage page = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage(); if (page != null) { IEditorPart part = page.findEditor(input); if (part != null) { return page.closeEditor(part, true); } } return false; } public static IEditorPart openForm(FormInput input, String id) { return openForm(input, id, true); } public static IEditorPart openForm(FormInput input, String id, boolean focusOnEditor) { closeEditor(input); try { IEditorPart part = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage() .openEditor(input, id, focusOnEditor); return part; } catch (PartInitException e) { logger.error("Can't open form with id " + id, e); //$NON-NLS-1$ return null; } } @Override public void openViewForm() { if (getViewFormId() != null && getModelObject() != null && getModelObject().getWrappedObject() != null) { openForm(new FormInput(this), getViewFormId()); } } public Class<?> getObjectClazz() { if (modelObject != null) return modelObject.getClass(); return null; } @Override public List<AbstractAdapterBase> search(Class<?> searchedClass, Integer objectId) { if (getObjectClazz() != null && getObjectClazz().equals(searchedClass)) return Arrays.asList(new AbstractAdapterBase[] { this }); return new ArrayList<AbstractAdapterBase>(); } public void resetObject() throws Exception { if (getModelObject() != null) { getModelObject().reset(); } } protected List<AbstractAdapterBase> searchChildContainers( Class<?> searchedClass, Integer objectId, ContainerAdapter container, final List<ContainerWrapper> parents) { List<AbstractAdapterBase> res = new ArrayList<AbstractAdapterBase>(); if (parents.contains(container.getModelObject())) { AbstractAdapterBase child = container.getChild(objectId, true); if (child == null) { for (AbstractAdapterBase childContainer : container .getChildren()) { if (childContainer instanceof ContainerAdapter) { res = searchChildContainers(searchedClass, objectId, (ContainerAdapter) childContainer, parents); } else { res = childContainer.search(searchedClass, objectId); } if (res.size() > 0) break; } } else { res.add(child); } } return res; } public RootNode getRootNode() { return getParentFromClass(RootNode.class); } @Override public void performExpand() { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { loadChildren(true); RootNode root = getRootNode(); if (root != null) { root.expandChild(AdapterBase.this); } } }); } @SuppressWarnings({ "unchecked", "rawtypes" }) protected int internalCompareTo(AbstractAdapterBase o) { if (getModelObject() != null) return getModelObject().compareTo( (ModelWrapper) ((AdapterBase) o).getModelObject()); return 0; } @Override public void setValue(Object value) { } }