/* * Copyright (c) 2004-2011 Marco Maccaferri and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Marco Maccaferri - initial API and implementation */ package org.eclipsetrader.ui.internal.navigator; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Status; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipsetrader.core.internal.CoreActivator; import org.eclipsetrader.core.views.IView; import org.eclipsetrader.core.views.IViewChangeListener; import org.eclipsetrader.core.views.IViewItem; import org.eclipsetrader.core.views.IViewVisitor; import org.eclipsetrader.core.views.ViewEvent; import org.eclipsetrader.core.views.ViewItemDelta; import org.eclipsetrader.ui.navigator.INavigatorContentGroup; public class NavigatorView implements IView { private IStructuredContentProvider[] contentProviders; private INavigatorContentGroup[] groups; private ListenerList listeners = new ListenerList(ListenerList.IDENTITY); private NavigatorViewItem root = new NavigatorViewItem(); public NavigatorView() { } /* (non-Javadoc) * @see org.eclipsetrader.core.views.IView#dispose() */ @Override public void dispose() { listeners.clear(); for (int i = 0; i < contentProviders.length; i++) { contentProviders[i].dispose(); } } /* (non-Javadoc) * @see org.eclipsetrader.core.views.IView#getItems() */ @Override public IViewItem[] getItems() { return root.getItems(); } /* (non-Javadoc) * @see org.eclipsetrader.core.views.IView#addViewChangeListener(org.eclipsetrader.core.views.IViewChangeListener) */ @Override public void addViewChangeListener(IViewChangeListener listener) { listeners.add(listener); } /* (non-Javadoc) * @see org.eclipsetrader.core.views.IView#removeViewChangeListener(org.eclipsetrader.core.views.IViewChangeListener) */ @Override public void removeViewChangeListener(IViewChangeListener listener) { listeners.remove(listener); } protected void notifyListeners(ViewEvent event) { Object[] l = listeners.getListeners(); for (int i = 0; i < l.length; i++) { try { ((IViewChangeListener) l[i]).viewChanged(event); } catch (Exception e) { Status status = new Status(IStatus.ERROR, CoreActivator.PLUGIN_ID, 0, "Error running view listener", e); CoreActivator.log(status); } catch (LinkageError e) { Status status = new Status(IStatus.ERROR, CoreActivator.PLUGIN_ID, 0, "Error running view listener", e); CoreActivator.log(status); } } } public IStructuredContentProvider[] getContentProviders() { return contentProviders; } public void setContentProviders(IStructuredContentProvider[] contentProviders) { this.contentProviders = contentProviders; } public void setGroups(INavigatorContentGroup[] groups) { this.groups = groups; } public INavigatorContentGroup[] getGroups() { return groups; } public void update() { List<Object> instruments = new ArrayList<Object>(); if (contentProviders != null) { for (int i = 0; i < contentProviders.length; i++) { instruments.addAll(Arrays.asList(contentProviders[i].getElements(this))); } } NavigatorViewItem newRoot = new NavigatorViewItem(); if (groups != null && groups.length != 0) { groupElements(newRoot, instruments.toArray(new IAdaptable[instruments.size()]), groups); } else { for (Object element : instruments) { newRoot.createChild(element); } } ViewItemDelta delta = new ViewItemDelta(ViewItemDelta.NO_CHANGE, root); updateTree(delta, root, newRoot); if (delta.getChildCount() != 0) { notifyListeners(new ViewEvent(this, delta.getChilds())); } } /* (non-Javadoc) * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) */ @Override @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { if (adapter.isAssignableFrom(getClass())) { return this; } return null; } /* (non-Javadoc) * @see org.eclipsetrader.core.views.IView#accept(org.eclipsetrader.core.views.IViewVisitor) */ @Override public void accept(IViewVisitor visitor) { if (visitor.visit(this)) { for (IViewItem viewItem : getItems()) { viewItem.accept(visitor); } } } protected void updateTree(ViewItemDelta parentDelta, NavigatorViewItem oldItem, NavigatorViewItem newItem) { for (IViewItem viewItem : oldItem.getItems()) { Object reference = ((NavigatorViewItem) viewItem).getReference(); if (!newItem.hasChild(reference)) { oldItem.removeChild(reference); parentDelta.createChild(viewItem, ViewItemDelta.REMOVED); } } for (IViewItem viewItem : newItem.getItems()) { Object reference = ((NavigatorViewItem) viewItem).getReference(); if (!oldItem.hasChild(reference)) { NavigatorViewItem addedItem = oldItem.createChild(reference); ViewItemDelta delta = parentDelta.createChild(addedItem, ViewItemDelta.ADDED); updateTree(delta, addedItem, (NavigatorViewItem) viewItem); } else { NavigatorViewItem existingViewItem = oldItem.getChild(reference); ViewItemDelta delta = parentDelta.createChild(existingViewItem, ViewItemDelta.NO_CHANGE); updateTree(delta, existingViewItem, (NavigatorViewItem) viewItem); } } } protected void groupElements(NavigatorViewItem parent, IAdaptable[] elements, INavigatorContentGroup[] groups) { List<IAdaptable> set = new ArrayList<IAdaptable>(); set.addAll(Arrays.asList(elements)); if (groups != null && groups.length != 0) { INavigatorContentGroup group = groups[0]; INavigatorContentGroup[] downGroups = null; if (groups.length > 1) { downGroups = new INavigatorContentGroup[groups.length - 1]; System.arraycopy(groups, 1, downGroups, 0, downGroups.length); } IViewItem[] groupedElements = group.getGroupedContent(elements); if (groupedElements.length != 0) { for (IViewItem viewItem : groupedElements) { for (IViewItem childItem : viewItem.getItems()) { Object reference = childItem.getAdapter(Object.class); for (Iterator<IAdaptable> iter = set.iterator(); iter.hasNext();) { Object obj = iter.next().getAdapter(reference.getClass()); if (obj == reference) { iter.remove(); } } } Object reference = viewItem.getAdapter(Object.class); NavigatorViewItem instrumentViewItem = parent.createChild(reference); groupElements(instrumentViewItem, viewItem.getItems(), downGroups); } } if (set.size() != 0) { groupElements(parent, set.toArray(new IAdaptable[set.size()]), downGroups); } } else { for (int i = 0; i < elements.length; i++) { Object reference = elements[i].getAdapter(Object.class); parent.createChild(reference); } } } }