| /* |
| * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany) 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: |
| * Victor Roldan Betancort - initial API and implementation |
| */ |
| package org.eclipse.emf.cdo.internal.ui.views; |
| |
| import org.eclipse.emf.cdo.CDODeltaNotification; |
| import org.eclipse.emf.cdo.CDOObject; |
| import org.eclipse.emf.cdo.internal.ui.actions.RemoveAllContainerItemAction; |
| import org.eclipse.emf.cdo.internal.ui.actions.RemoveContainerItemAction; |
| import org.eclipse.emf.cdo.internal.ui.dnd.CDOObjectDropAdapter; |
| import org.eclipse.emf.cdo.internal.ui.editor.CDOEditor; |
| import org.eclipse.emf.cdo.internal.ui.messages.Messages; |
| import org.eclipse.emf.cdo.transaction.CDOCommitContext; |
| import org.eclipse.emf.cdo.transaction.CDODefaultTransactionHandler2; |
| import org.eclipse.emf.cdo.transaction.CDOTransaction; |
| import org.eclipse.emf.cdo.util.CDOUtil; |
| import org.eclipse.emf.cdo.view.CDOAdapterPolicy; |
| import org.eclipse.emf.cdo.view.CDOView; |
| |
| import org.eclipse.net4j.util.container.Container; |
| import org.eclipse.net4j.util.container.ContainerEvent; |
| import org.eclipse.net4j.util.container.IContainer; |
| import org.eclipse.net4j.util.container.IContainerDelta; |
| import org.eclipse.net4j.util.event.IEvent; |
| import org.eclipse.net4j.util.event.IListener; |
| import org.eclipse.net4j.util.event.INotifier; |
| import org.eclipse.net4j.util.lifecycle.ILifecycleEvent; |
| import org.eclipse.net4j.util.ui.UIUtil; |
| import org.eclipse.net4j.util.ui.actions.LongRunningAction; |
| |
| import org.eclipse.emf.common.notify.Adapter; |
| import org.eclipse.emf.common.notify.AdapterFactory; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.edit.provider.ComposedAdapterFactory; |
| import org.eclipse.emf.edit.provider.IItemLabelProvider; |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; |
| import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry; |
| import org.eclipse.emf.spi.cdo.FSMUtil; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IMenuListener; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.action.Separator; |
| import org.eclipse.jface.viewers.IColorProvider; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.ISelectionProvider; |
| import org.eclipse.jface.viewers.IStructuredContentProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.ITableLabelProvider; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TableViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.KeyAdapter; |
| import org.eclipse.swt.events.KeyEvent; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableColumn; |
| import org.eclipse.ui.ISharedImages; |
| import org.eclipse.ui.IWorkbenchActionConstants; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.part.ViewPart; |
| import org.eclipse.ui.views.properties.IPropertySheetPage; |
| import org.eclipse.ui.views.properties.PropertySheetPage; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.atomic.AtomicLong; |
| |
| /** |
| * @author Victor Roldan Betancort |
| */ |
| public class CDOWatchListView extends ViewPart implements ISelectionProvider |
| { |
| private static final String[] columnNames = { Messages.getString("CDOWatchListView.0"), //$NON-NLS-1$ |
| Messages.getString("CDOWatchListView.1"), Messages.getString("CDOWatchListView.2"), //$NON-NLS-1$ //$NON-NLS-2$ |
| Messages.getString("CDOWatchListView.3") }; //$NON-NLS-1$ |
| |
| private static final int[] columnWidths = { 110, 280, 170, 230 }; |
| |
| public static final String ID = "org.eclipse.emf.cdo.ui.CDOWatchListView"; //$NON-NLS-1$ |
| |
| private final ComposedAdapterFactory adapterFactory; |
| |
| private final CDOObjectContainer container = new CDOObjectContainer(); |
| |
| private final WatchedObjectsDataRegistry dataRegistry = new WatchedObjectsDataRegistry(); |
| |
| private TableViewer viewer; |
| |
| private IPropertySheetPage propertySheetPage; |
| |
| private IAction removeAction; |
| |
| private IAction removeAllAction; |
| |
| private IAction resetNotificationAction; |
| |
| private IAction resetAllNotificationAction; |
| |
| public CDOWatchListView() |
| { |
| adapterFactory = CDOEditor.createAdapterFactory(true); |
| container.addListener(getDataRegistry()); |
| } |
| |
| @Override |
| public void dispose() |
| { |
| adapterFactory.dispose(); |
| super.dispose(); |
| } |
| |
| public WatchedObjectsDataRegistry getDataRegistry() |
| { |
| return dataRegistry; |
| } |
| |
| @Override |
| public void createPartControl(Composite parent) |
| { |
| // Create Viewer |
| viewer = createViewer(parent); |
| |
| // This listener always refreshes viewer upon notification |
| IListener refreshListener = new IListener() |
| { |
| public void notifyEvent(IEvent event) |
| { |
| UIUtil.refreshViewer(viewer); |
| } |
| }; |
| |
| container.addListener(refreshListener); |
| getDataRegistry().addListener(refreshListener); |
| |
| // Configure ViewPart |
| createActions(); |
| createToolbarButtons(); |
| createContextMenu(); |
| hookKeyboardActions(); |
| createViewPulldownMenu(); |
| getSite().setSelectionProvider(this); |
| } |
| |
| private void createActions() |
| { |
| ISharedImages platformImages = PlatformUI.getWorkbench().getSharedImages(); |
| removeAction = new RemoveContainerItemAction<CDOObject>(container, viewer); |
| removeAction.setText(Messages.getString("CDOWatchListView.4")); //$NON-NLS-1$ |
| removeAction.setImageDescriptor(platformImages.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE)); |
| removeAction.setDisabledImageDescriptor(platformImages.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE_DISABLED)); |
| removeAction.setToolTipText(Messages.getString("CDOWatchListView.5")); //$NON-NLS-1$ |
| |
| removeAllAction = new RemoveAllContainerItemAction<CDOObject>(container); |
| removeAllAction.setText(Messages.getString("CDOWatchListView.6")); //$NON-NLS-1$ |
| removeAllAction.setImageDescriptor(platformImages.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE)); |
| removeAllAction.setToolTipText(Messages.getString("CDOWatchListView.7")); //$NON-NLS-1$ |
| |
| resetNotificationAction = new ResetNotificationAction(); |
| resetNotificationAction.setText(Messages.getString("CDOWatchListView.8")); //$NON-NLS-1$ |
| resetNotificationAction.setImageDescriptor(platformImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO)); |
| resetNotificationAction |
| .setDisabledImageDescriptor(platformImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO_DISABLED)); |
| resetNotificationAction.setToolTipText(Messages.getString("CDOWatchListView.9")); //$NON-NLS-1$ |
| |
| resetAllNotificationAction = new ResetAllNotificationAction(); |
| resetAllNotificationAction.setText(Messages.getString("CDOWatchListView.10")); //$NON-NLS-1$ |
| resetAllNotificationAction.setImageDescriptor(platformImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO)); |
| resetAllNotificationAction |
| .setDisabledImageDescriptor(platformImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO_DISABLED)); |
| resetAllNotificationAction.setToolTipText(Messages.getString("CDOWatchListView.11")); //$NON-NLS-1$ |
| } |
| |
| private void createToolbarButtons() |
| { |
| getViewSite().getActionBars().getToolBarManager().add(resetAllNotificationAction); |
| } |
| |
| private void createViewPulldownMenu() |
| { |
| IMenuManager menu = getViewSite().getActionBars().getMenuManager(); |
| menu.add(removeAllAction); |
| } |
| |
| private void createContextMenu() |
| { |
| MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ |
| menuMgr.setRemoveAllWhenShown(true); |
| menuMgr.addMenuListener(new IMenuListener() |
| { |
| public void menuAboutToShow(IMenuManager m) |
| { |
| CDOWatchListView.this.fillContextMenu(m); |
| } |
| }); |
| |
| Menu menu = menuMgr.createContextMenu(viewer.getControl()); |
| viewer.getControl().setMenu(menu); |
| getSite().registerContextMenu(menuMgr, viewer); |
| } |
| |
| private void fillContextMenu(IMenuManager menuMgr) |
| { |
| boolean isEmpty = viewer.getSelection().isEmpty(); |
| removeAction.setEnabled(!isEmpty); |
| menuMgr.add(removeAction); |
| resetNotificationAction.setEnabled(!isEmpty); |
| menuMgr.add(resetNotificationAction); |
| menuMgr.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); |
| } |
| |
| private void hookKeyboardActions() |
| { |
| viewer.getControl().addKeyListener(new KeyAdapter() |
| { |
| @Override |
| public void keyReleased(KeyEvent event) |
| { |
| handleKeyReleased(event); |
| } |
| }); |
| } |
| |
| protected void handleKeyReleased(KeyEvent event) |
| { |
| if (event.character == SWT.DEL && event.stateMask == 0) |
| { |
| removeAction.run(); |
| } |
| } |
| |
| @Override |
| public void setFocus() |
| { |
| viewer.getControl().setFocus(); |
| } |
| |
| public ISelection getSelection() |
| { |
| if (viewer != null) |
| { |
| return viewer.getSelection(); |
| } |
| |
| return StructuredSelection.EMPTY; |
| } |
| |
| public void setSelection(ISelection selection) |
| { |
| // Doesn't need to set viewer.setSelection(). Already done with user event. |
| } |
| |
| public void addSelectionChangedListener(ISelectionChangedListener listener) |
| { |
| if (viewer != null) |
| { |
| viewer.addSelectionChangedListener(listener); |
| } |
| } |
| |
| public void removeSelectionChangedListener(ISelectionChangedListener listener) |
| { |
| if (viewer != null) |
| { |
| viewer.removeSelectionChangedListener(listener); |
| } |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public <T> T getAdapter(Class<T> adapter) |
| { |
| if (adapter.equals(IPropertySheetPage.class)) |
| { |
| return (T)getPropertySheetPage(); |
| } |
| |
| return super.getAdapter(adapter); |
| } |
| |
| public IPropertySheetPage getPropertySheetPage() |
| { |
| if (propertySheetPage == null) |
| { |
| PropertySheetPage page = new PropertySheetPage(); |
| page.setPropertySourceProvider(new AdapterFactoryContentProvider(adapterFactory)); |
| propertySheetPage = page; |
| } |
| |
| return propertySheetPage; |
| } |
| |
| private TableViewer createViewer(Composite parent) |
| { |
| TableViewer viewer = new TableViewer(parent, SWT.FULL_SELECTION | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); |
| viewer.getTable().setLayoutData(UIUtil.createGridData()); |
| viewer.getTable().setHeaderVisible(true); |
| viewer.getTable().setLinesVisible(true); |
| createColumns(viewer.getTable()); |
| |
| viewer.setContentProvider(new CDOObjectContainerContentProvider()); |
| viewer.setLabelProvider(new CDOSubscriptionViewLabelProvider(adapterFactory)); |
| viewer.setInput(container); |
| |
| CDOObjectDropAdapter.support(viewer); |
| return viewer; |
| } |
| |
| private void createColumns(Table table) |
| { |
| TableColumn[] columns = new TableColumn[columnNames.length]; |
| for (int i = 0; i < columns.length; i++) |
| { |
| TableColumn column = new TableColumn(table, SWT.LEFT, i); |
| column.setText(columnNames[i]); |
| column.setWidth(columnWidths[i]); |
| column.setMoveable(true); |
| column.setResizable(true); |
| } |
| } |
| |
| /** |
| * @author Victor Roldan Betancort |
| */ |
| private final class TransactionHandler extends CDODefaultTransactionHandler2 |
| { |
| public TransactionHandler() |
| { |
| } |
| |
| @Override |
| public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext) |
| { |
| container.removeAllElements(commitContext.getDetachedObjects().values()); |
| UIUtil.refreshViewer(viewer); |
| } |
| } |
| |
| /** |
| * @author Victor Roldan Betancort |
| */ |
| private final class CDOSubscriptionAdapter extends AdapterImpl implements CDOAdapterPolicy |
| { |
| public CDOSubscriptionAdapter() |
| { |
| } |
| |
| @Override |
| public void notifyChanged(Notification msg) |
| { |
| if (msg instanceof CDODeltaNotification) |
| { |
| checkDetached(msg); |
| // TODO how to retrieve remote commit timestamp? |
| getDataRegistry().addNotification(msg); |
| } |
| } |
| |
| private void checkDetached(Notification msg) |
| { |
| // TODO Remote detach won't be shown in the UI, the object will be just removed from the viewer |
| if (((CDODeltaNotification)msg).getEventType() == CDODeltaNotification.DETACH_OBJECT) |
| { |
| Object obj = msg.getNotifier(); |
| container.removeElement(CDOUtil.getCDOObject((EObject)obj)); |
| getDataRegistry().removeData(obj); |
| } |
| } |
| |
| public boolean isValid(EObject object, Adapter adapter) |
| { |
| return adapter instanceof CDOSubscriptionAdapter; |
| } |
| } |
| |
| /** |
| * @author Victor Roldan Betancort |
| */ |
| private final class CDOObjectContainer extends Container<CDOObject>implements IContainer.Modifiable<CDOObject> |
| { |
| private Set<CDOObject> watchedObjects = new HashSet<CDOObject>(); |
| |
| private CDOSubscriptionAdapter subscriptionAdapter = new CDOSubscriptionAdapter(); |
| |
| private ViewDeactivationListener viewDeactivationListener = new ViewDeactivationListener(); |
| |
| private TransactionHandler transactionHandler = new TransactionHandler(); |
| |
| private CDOViewReferenceCounterManager counterManager = new CDOViewReferenceCounterManager(); |
| |
| public CDOObjectContainer() |
| { |
| } |
| |
| public CDOObject[] getElements() |
| { |
| return watchedObjects.toArray(new CDOObject[watchedObjects.size()]); |
| } |
| |
| @Override |
| public boolean isEmpty() |
| { |
| return watchedObjects.isEmpty(); |
| } |
| |
| /** |
| * @returns true if the element was added successfully to the container |
| */ |
| public boolean addElement(CDOObject element) |
| { |
| if (watchedObjects.add(element)) |
| { |
| postAdd(element); |
| fireElementAddedEvent(element); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /** |
| * @returns true if the element was removed successfully from the container |
| */ |
| public boolean removeElement(CDOObject element) |
| { |
| if (watchedObjects.remove(element)) |
| { |
| postRemove(element); |
| fireElementRemovedEvent(element); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /** |
| * @returns true if at least one element was added. False otherwise. |
| */ |
| public boolean addAllElements(Collection<CDOObject> elements) |
| { |
| ArrayList<CDOObject> addedElements = new ArrayList<CDOObject>(); |
| for (CDOObject cdoObject : elements) |
| { |
| if (watchedObjects.add(cdoObject)) |
| { |
| postAdd(cdoObject); |
| addedElements.add(cdoObject); |
| } |
| } |
| |
| if (!addedElements.isEmpty()) |
| { |
| fireElementsAddedEvent(addedElements.toArray(new CDOObject[addedElements.size()])); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /** |
| * @returns true if at least one element was removed. False otherwise. |
| */ |
| public boolean removeAllElements(Collection<CDOObject> elements) |
| { |
| ArrayList<CDOObject> removedElements = new ArrayList<CDOObject>(); |
| for (CDOObject cdoObject : elements) |
| { |
| if (watchedObjects.remove(cdoObject)) |
| { |
| postRemove(cdoObject); |
| removedElements.add(cdoObject); |
| } |
| } |
| |
| if (!removedElements.isEmpty()) |
| { |
| fireElementsRemovedEvent(removedElements.toArray(new CDOObject[removedElements.size()])); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| private void postAdd(CDOObject element) |
| { |
| element.cdoView().options().addChangeSubscriptionPolicy(subscriptionAdapter); |
| element.eAdapters().add(subscriptionAdapter); |
| increaseViewReference(element); |
| } |
| |
| private void postRemove(CDOObject element) |
| { |
| decreaseViewReference(element); |
| CDOView view = element.cdoView(); |
| if (view != null && !view.isClosed()) |
| { |
| element.eAdapters().remove(subscriptionAdapter); |
| } |
| } |
| |
| private void increaseViewReference(CDOObject referrer) |
| { |
| CDOViewReferenceCounterManager.CDOViewReferenceCounter counter = counterManager.getCounter(referrer); |
| if (counter.increase() == 1) |
| { |
| CDOView view = referrer.cdoView(); |
| view.addListener(viewDeactivationListener); |
| if (view instanceof CDOTransaction) |
| { |
| ((CDOTransaction)view).addTransactionHandler(transactionHandler); |
| } |
| } |
| } |
| |
| private void decreaseViewReference(CDOObject referrer) |
| { |
| CDOViewReferenceCounterManager.CDOViewReferenceCounter counter = counterManager.getCounter(referrer); |
| |
| // CDOObject might be detached, and so CDOView will be null |
| if (counter.decrease() == 0 && referrer.cdoView() != null) |
| { |
| CDOView view = referrer.cdoView(); |
| view.removeListener(viewDeactivationListener); |
| if (view instanceof CDOTransaction) |
| { |
| ((CDOTransaction)view).removeTransactionHandler(transactionHandler); |
| } |
| } |
| } |
| |
| /** |
| * @author Victor Roldan Betancort |
| */ |
| private final class ViewDeactivationListener implements IListener |
| { |
| public void notifyEvent(IEvent event) |
| { |
| if (event instanceof ILifecycleEvent) |
| { |
| if (((ILifecycleEvent)event).getKind() == ILifecycleEvent.Kind.ABOUT_TO_DEACTIVATE) |
| { |
| List<CDOObject> aboutToRemove = new ArrayList<CDOObject>(); |
| for (CDOObject object : getElements()) |
| { |
| if (object.cdoView().equals(event.getSource())) |
| { |
| aboutToRemove.add(object); |
| } |
| } |
| |
| removeAllElements(aboutToRemove); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * @author Victor Roldan Betancort |
| */ |
| private final class CDOViewReferenceCounterManager |
| { |
| private List<CDOViewReferenceCounter> viewReferences = new ArrayList<CDOViewReferenceCounter>(); |
| |
| public CDOViewReferenceCounterManager() |
| { |
| } |
| |
| private class CDOViewReferenceCounter |
| { |
| private final CDOView view; |
| |
| private AtomicLong referenceCount = new AtomicLong(); |
| |
| public CDOViewReferenceCounter(CDOObject cdoObject) |
| { |
| view = cdoObject.cdoView(); |
| referenceCount.set(0); |
| } |
| |
| public long increase() |
| { |
| return referenceCount.incrementAndGet(); |
| } |
| |
| public synchronized long decrease() |
| { |
| Long value = referenceCount.decrementAndGet(); |
| if (value == 0) |
| { |
| viewReferences.remove(this); |
| } |
| |
| return value; |
| } |
| |
| public CDOView getReferencedView() |
| { |
| return view; |
| } |
| } |
| |
| public CDOViewReferenceCounter getCounter(CDOObject cdoObject) |
| { |
| synchronized (viewReferences) |
| { |
| for (CDOViewReferenceCounter counter : viewReferences) |
| { |
| if (counter.getReferencedView().equals(cdoObject.cdoView())) |
| { |
| return counter; |
| } |
| } |
| } |
| |
| CDOViewReferenceCounter counter = new CDOViewReferenceCounter(cdoObject); |
| viewReferences.add(counter); |
| return counter; |
| } |
| } |
| |
| /** |
| * @author Victor Roldan Betancort |
| */ |
| private final class WatchedObjectsDataRegistry extends org.eclipse.net4j.util.event.Notifier implements IListener |
| { |
| private Map<Object, WatchedObjectData> registry = new HashMap<Object, WatchedObjectData>(); |
| |
| private final IEvent dataRegistryEvent = new IEvent() |
| { |
| public INotifier getSource() |
| { |
| return WatchedObjectsDataRegistry.this; |
| } |
| }; |
| |
| public WatchedObjectsDataRegistry() |
| { |
| } |
| |
| public WatchedObjectData getData(Object object) |
| { |
| WatchedObjectData data = registry.get(object); |
| if (data == null) |
| { |
| data = new WatchedObjectData(); |
| registry.put(object, data); |
| } |
| |
| return data; |
| } |
| |
| public void addNotification(Notification msg) |
| { |
| getData(msg.getNotifier()).setNotification(msg); |
| IListener[] listeners = getListeners(); |
| if (listeners != null) |
| { |
| fireEvent(dataRegistryEvent, listeners); |
| } |
| } |
| |
| public void removeNotification(Object object) |
| { |
| getData(object).deleteNotification(); |
| IListener[] listeners = getListeners(); |
| if (listeners != null) |
| { |
| fireEvent(dataRegistryEvent, listeners); |
| } |
| } |
| |
| public void removeData(Object object) |
| { |
| registry.remove(object); |
| } |
| |
| public void removeAllNotification(Collection<Object> objects) |
| { |
| for (WatchedObjectData data : registry.values()) |
| { |
| data.deleteNotification(); |
| } |
| |
| IListener[] listeners = getListeners(); |
| if (listeners != null) |
| { |
| fireEvent(dataRegistryEvent, listeners); |
| } |
| } |
| |
| public Notification getNotification(Object object) |
| { |
| return getData(object).getNotification(); |
| } |
| |
| public void notifyEvent(IEvent event) |
| { |
| if (event instanceof ContainerEvent<?>) |
| { |
| ContainerEvent<?> containerEvent = (ContainerEvent<?>)event; |
| for (IContainerDelta<?> delta : containerEvent.getDeltas()) |
| { |
| if (delta.getKind().equals(IContainerDelta.Kind.REMOVED)) |
| { |
| removeData(delta.getElement()); |
| } |
| } |
| } |
| } |
| |
| /** |
| * @author Victor Roldan Betancort |
| */ |
| private final class WatchedObjectData |
| { |
| private Notification notification; |
| |
| public WatchedObjectData() |
| { |
| } |
| |
| public void setNotification(Notification notification) |
| { |
| this.notification = notification; |
| } |
| |
| public void deleteNotification() |
| { |
| notification = null; |
| } |
| |
| public Notification getNotification() |
| { |
| return notification; |
| } |
| } |
| } |
| |
| /** |
| * @author Victor Roldan Betancort |
| */ |
| private final class CDOSubscriptionViewLabelProvider extends LabelProvider |
| implements ITableLabelProvider, IColorProvider |
| { |
| private final Color YELLOW = UIUtil.getDisplay().getSystemColor(SWT.COLOR_YELLOW); |
| |
| private final String[] eventTypes = { Messages.getString("CDOWatchListView.12"), //$NON-NLS-1$ |
| Messages.getString("CDOWatchListView.25"), Messages.getString("CDOWatchListView.26"), //$NON-NLS-1$ //$NON-NLS-2$ |
| Messages.getString("CDOWatchListView.27"), Messages.getString("CDOWatchListView.28"), //$NON-NLS-1$ //$NON-NLS-2$ |
| Messages.getString("CDOWatchListView.29"), Messages.getString("CDOWatchListView.30"), //$NON-NLS-1$ //$NON-NLS-2$ |
| Messages.getString("CDOWatchListView.31"), //$NON-NLS-1$ |
| Messages.getString("CDOWatchListView.32"), Messages.getString("CDOWatchListView.33") }; //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| private AdapterFactory adapterFactory; |
| |
| public CDOSubscriptionViewLabelProvider(AdapterFactory adapterFactory) |
| { |
| this.adapterFactory = adapterFactory; |
| } |
| |
| public Image getColumnImage(Object object, int columnIndex) |
| { |
| // In case an invalid object arrives (i.e., detached), return CDOState |
| if (FSMUtil.isInvalid(CDOUtil.getCDOObject((EObject)object))) |
| { |
| return null; |
| } |
| |
| switch (columnIndex) |
| { |
| case 0: |
| IItemLabelProvider labelProvider = (IItemLabelProvider)adapterFactory.adapt(object, IItemLabelProvider.class); |
| if (labelProvider != null) |
| { |
| return ExtendedImageRegistry.getInstance().getImage(labelProvider.getImage(object)); |
| } |
| } |
| |
| return null; |
| } |
| |
| public String getColumnText(Object element, int columnIndex) |
| { |
| CDOObject object = CDOUtil.getCDOObject((EObject)element); |
| |
| // In case an invalid object arrives (i.e., detached), return CDOState |
| if (FSMUtil.isInvalid(object)) |
| { |
| return object.cdoState().toString(); |
| } |
| |
| switch (columnIndex) |
| { |
| case 0: |
| IItemLabelProvider labelProvider = (IItemLabelProvider)adapterFactory.adapt(object, IItemLabelProvider.class); |
| if (labelProvider != null) |
| { |
| return labelProvider.getText(object); |
| } |
| |
| return null; |
| |
| case 1: |
| return object.cdoResource().getURI().toString(); |
| |
| case 2: |
| // XXX CDOView view = object.cdoView(); |
| // if (view instanceof CDOTransaction) |
| // { |
| // long time = ((CDOTransaction)view).getLastCommitTime(); |
| // if (time != CDORevision.UNSPECIFIED_DATE) |
| // { |
| // return new Date(time).toString(); |
| // } |
| // } |
| |
| return "?"; //$NON-NLS-1$ |
| |
| case 3: |
| Notification notification = getDataRegistry().getNotification(element); |
| return createEventLabel(notification); |
| } |
| |
| return element.toString(); |
| } |
| |
| public Color getBackground(Object element) |
| { |
| if (element instanceof CDOObject) |
| { |
| if (getDataRegistry().getNotification(element) != null) |
| { |
| return YELLOW; |
| } |
| } |
| |
| return null; |
| } |
| |
| public Color getForeground(Object element) |
| { |
| return null; |
| } |
| |
| private String createEventLabel(Notification notification) |
| { |
| if (notification == null) |
| { |
| return null; |
| } |
| |
| StringBuilder builder = new StringBuilder(); |
| int event = notification.getEventType(); |
| if (event < Notification.EVENT_TYPE_COUNT) |
| { |
| builder.append(eventTypes[event]); |
| } |
| |
| builder.append(": "); //$NON-NLS-1$ |
| builder.append(((EStructuralFeature)notification.getFeature()).getName()); |
| builder.append(" = "); //$NON-NLS-1$ |
| builder.append(notification.getNewValue().toString()); |
| return builder.toString(); |
| } |
| } |
| |
| /** |
| * @author Victor Roldan Betancort |
| */ |
| private final class CDOObjectContainerContentProvider implements IStructuredContentProvider |
| { |
| public CDOObjectContainerContentProvider() |
| { |
| } |
| |
| @SuppressWarnings("unchecked") |
| public Object[] getElements(Object object) |
| { |
| return ((IContainer<Object>)object).getElements(); |
| } |
| |
| public void dispose() |
| { |
| // do nothing |
| } |
| |
| public void inputChanged(Viewer viewer, Object oldInput, Object newInput) |
| { |
| // do nothing |
| } |
| } |
| |
| /** |
| * @author Victor Roldan Betancort |
| */ |
| private final class ResetNotificationAction extends LongRunningAction |
| { |
| private transient List<?> targets; |
| |
| public ResetNotificationAction() |
| { |
| } |
| |
| @Override |
| protected void preRun() throws Exception |
| { |
| ISelection selection = getSelection(); |
| if (selection instanceof IStructuredSelection) |
| { |
| IStructuredSelection ssel = (IStructuredSelection)selection; |
| if (!ssel.isEmpty()) |
| { |
| targets = ssel.toList(); |
| return; |
| } |
| } |
| |
| cancel(); |
| } |
| |
| @Override |
| protected void doRun(IProgressMonitor progressMonitor) throws Exception |
| { |
| if (targets != null) |
| { |
| List<?> useTargets = targets; |
| targets = null; |
| |
| for (Object object : useTargets) |
| { |
| if (object instanceof CDOObject) |
| { |
| getDataRegistry().removeNotification(object); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * @author Victor Roldan Betancort |
| */ |
| private final class ResetAllNotificationAction extends LongRunningAction |
| { |
| public ResetAllNotificationAction() |
| { |
| } |
| |
| @Override |
| protected void doRun(IProgressMonitor progressMonitor) throws Exception |
| { |
| ArrayList<Object> aboutToReset = new ArrayList<Object>(); |
| for (CDOObject cdoObject : container.getElements()) |
| { |
| aboutToReset.add(cdoObject); |
| } |
| |
| getDataRegistry().removeAllNotification(aboutToReset); |
| } |
| } |
| } |