| /******************************************************************************* |
| * Copyright (c) 2000, 2006 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ui.internal; |
| |
| import java.util.HashMap; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.IExtension; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.MultiStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler; |
| import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker; |
| import org.eclipse.jface.util.SafeRunnable; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.IViewPart; |
| import org.eclipse.ui.IViewReference; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.views.IViewDescriptor; |
| import org.eclipse.ui.views.IViewRegistry; |
| |
| /** |
| * The ViewFactory is used to control the creation and disposal of views. |
| * It implements a reference counting strategy so that one view can be shared |
| * by more than one client. |
| */ |
| /*package*/class ViewFactory implements IExtensionChangeHandler { |
| |
| private ReferenceCounter counter; |
| |
| private HashMap mementoTable = new HashMap(); |
| |
| WorkbenchPage page; |
| |
| IViewRegistry viewReg; |
| |
| /** |
| * Separates a view's primary id from its secondary id in view key strings. |
| */ |
| static final String ID_SEP = ":"; //$NON-NLS-1$ |
| |
| /** |
| * Returns a string representing a view with the given id and (optional) secondary id, |
| * suitable for use as a key in a map. |
| * |
| * @param id primary id of the view |
| * @param secondaryId secondary id of the view or <code>null</code> |
| * @return the key |
| */ |
| static String getKey(String id, String secondaryId) { |
| return secondaryId == null ? id : id + ID_SEP + secondaryId; |
| } |
| |
| /** |
| * Returns a string representing the given view reference, suitable for use as a key in a map. |
| * |
| * @param viewRef the view reference |
| * @return the key |
| */ |
| static String getKey(IViewReference viewRef) { |
| return getKey(viewRef.getId(), viewRef.getSecondaryId()); |
| } |
| |
| /** |
| * Extracts ths primary id portion of a compound id. |
| * @param compoundId a compound id of the form: primaryId [':' secondaryId] |
| * @return the primary id |
| */ |
| static String extractPrimaryId(String compoundId) { |
| int i = compoundId.lastIndexOf(ID_SEP); |
| if (i == -1) { |
| return compoundId; |
| } |
| return compoundId.substring(0, i); |
| } |
| |
| /** |
| * Extracts ths secondary id portion of a compound id. |
| * @param compoundId a compound id of the form: primaryId [':' secondaryId] |
| * @return the secondary id, or <code>null</code> if none |
| */ |
| static String extractSecondaryId(String compoundId) { |
| int i = compoundId.lastIndexOf(ID_SEP); |
| if (i == -1) { |
| return null; |
| } |
| return compoundId.substring(i + 1); |
| } |
| |
| /** |
| * Returns whether the given view id contains a wildcard. Wildcards cannot |
| * be used in regular view ids, only placeholders. |
| * |
| * @param viewId the view id |
| * @return <code>true</code> if the given view id contains a wildcard, |
| * <code>false</code> otherwise |
| * |
| * @since 3.1 |
| */ |
| static boolean hasWildcard(String viewId) { |
| return viewId.indexOf(PartPlaceholder.WILD_CARD) >= 0; |
| } |
| |
| /** |
| * Constructs a new view factory. |
| */ |
| public ViewFactory(WorkbenchPage page, IViewRegistry reg) { |
| super(); |
| this.page = page; |
| this.viewReg = reg; |
| counter = new ReferenceCounter(); |
| page.getExtensionTracker().registerHandler(this, null); |
| } |
| |
| /** |
| * Creates an instance of a view defined by id. |
| * |
| * This factory implements reference counting. The first call to this |
| * method will return a new view. Subsequent calls will return the |
| * first view with an additional reference count. The view is |
| * disposed when releaseView is called an equal number of times |
| * to getView. |
| */ |
| public IViewReference createView(final String id) throws PartInitException { |
| return createView(id, null); |
| } |
| |
| /** |
| * Creates an instance of a view defined by id and secondary id. |
| * |
| * This factory implements reference counting. The first call to this |
| * method will return a new view. Subsequent calls will return the |
| * first view with an additional reference count. The view is |
| * disposed when releaseView is called an equal number of times |
| * to createView. |
| */ |
| public IViewReference createView(String id, String secondaryId) |
| throws PartInitException { |
| IViewDescriptor desc = viewReg.find(id); |
| // ensure that the view id is valid |
| if (desc == null) { |
| throw new PartInitException(NLS.bind(WorkbenchMessages.ViewFactory_couldNotCreate, id )); |
| } |
| // ensure that multiple instances are allowed if a secondary id is given |
| if (secondaryId != null) { |
| if (!desc.getAllowMultiple()) { |
| throw new PartInitException(NLS.bind(WorkbenchMessages.ViewFactory_noMultiple, id)); |
| } |
| } |
| String key = getKey(id, secondaryId); |
| IViewReference ref = (IViewReference) counter.get(key); |
| if (ref == null) { |
| IMemento memento = (IMemento) mementoTable.get(key); |
| ref = new ViewReference(this, id, secondaryId, memento); |
| mementoTable.remove(key); |
| counter.put(key, ref); |
| getWorkbenchPage().partAdded((ViewReference)ref); |
| } else { |
| counter.addRef(key); |
| } |
| return ref; |
| } |
| |
| /** |
| * Returns the set of views being managed by this factory |
| * |
| * @return the set of views being managed by this factory |
| */ |
| public IViewReference[] getViewReferences() { |
| List values = counter.values(); |
| |
| return (IViewReference[]) values.toArray(new IViewReference[values.size()]); |
| } |
| |
| /** |
| * Returns the view with the given id, or <code>null</code> if not found. |
| */ |
| public IViewReference getView(String id) { |
| return getView(id, null); |
| } |
| |
| /** |
| * Returns the view with the given id and secondary id, or <code>null</code> if not found. |
| */ |
| public IViewReference getView(String id, String secondaryId) { |
| String key = getKey(id, secondaryId); |
| return (IViewReference) counter.get(key); |
| } |
| |
| /** |
| * @return the <code>IViewRegistry</code> used by this factory. |
| * @since 3.0 |
| */ |
| public IViewRegistry getViewRegistry() { |
| return viewReg; |
| } |
| |
| /** |
| * Returns a list of views which are open. |
| */ |
| public IViewReference[] getViews() { |
| List list = counter.values(); |
| IViewReference[] array = new IViewReference[list.size()]; |
| list.toArray(array); |
| return array; |
| } |
| |
| /** |
| * @return the <code>WorkbenchPage</code> used by this factory. |
| * @since 3.0 |
| */ |
| public WorkbenchPage getWorkbenchPage() { |
| return page; |
| } |
| |
| /** |
| * |
| * @param viewRef |
| * @return the current reference count for the given view |
| */ |
| public int getReferenceCount(IViewReference viewRef) { |
| String key = getKey(viewRef); |
| IViewReference ref = (IViewReference) counter.get(key); |
| return ref==null ? 0 : counter.getRef(key); |
| } |
| |
| /** |
| * Releases an instance of a view. |
| * |
| * This factory does reference counting. For more info see |
| * getView. |
| */ |
| public void releaseView(IViewReference viewRef) { |
| String key = getKey(viewRef); |
| IViewReference ref = (IViewReference) counter.get(key); |
| if (ref == null) { |
| return; |
| } |
| int count = counter.removeRef(key); |
| if (count <= 0) { |
| getWorkbenchPage().partRemoved((ViewReference)ref); |
| } |
| } |
| |
| /** |
| * Restore view states. |
| * |
| * @param memento the <code>IMemento</code> to restore from. |
| * @return <code>IStatus</code> |
| */ |
| public IStatus restoreState(IMemento memento) { |
| IMemento mem[] = memento.getChildren(IWorkbenchConstants.TAG_VIEW); |
| for (int i = 0; i < mem.length; i++) { |
| //for dynamic UI - add the next line to replace subsequent code that is commented out |
| restoreViewState(mem[i]); |
| } |
| return new Status(IStatus.OK, PlatformUI.PLUGIN_ID, 0, "", null); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Save view states. |
| * |
| * @param memento the <code>IMemento</code> to save to. |
| * @return <code>IStatus</code> |
| */ |
| public IStatus saveState(IMemento memento) { |
| final MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, |
| IStatus.OK, WorkbenchMessages.ViewFactory_problemsSavingViews, null); |
| |
| final IViewReference refs[] = getViews(); |
| for (int i = 0; i < refs.length; i++) { |
| //for dynamic UI - add the following line to replace subsequent code which is commented out |
| saveViewState(memento, refs[i], result); |
| } |
| return result; |
| } |
| |
| // for dynamic UI |
| public IMemento saveViewState(IMemento memento, IViewReference ref, |
| MultiStatus res) { |
| final MultiStatus result = res; |
| final IMemento viewMemento = memento |
| .createChild(IWorkbenchConstants.TAG_VIEW); |
| viewMemento.putString(IWorkbenchConstants.TAG_ID, ViewFactory |
| .getKey(ref)); |
| if (ref instanceof ViewReference) { |
| viewMemento.putString(IWorkbenchConstants.TAG_PART_NAME, |
| ((ViewReference) ref).getPartName()); |
| } |
| final IViewReference viewRef = ref; |
| final IViewPart view = (IViewPart) ref.getPart(false); |
| if (view != null) { |
| Platform.run(new SafeRunnable() { |
| public void run() { |
| view.saveState(viewMemento |
| .createChild(IWorkbenchConstants.TAG_VIEW_STATE)); |
| } |
| |
| public void handleException(Throwable e) { |
| result |
| .add(new Status( |
| IStatus.ERROR, |
| PlatformUI.PLUGIN_ID, |
| 0, |
| NLS.bind(WorkbenchMessages.ViewFactory_couldNotSave, viewRef.getTitle() ), |
| e)); |
| } |
| }); |
| } else { |
| IMemento mem = null; |
| |
| // if we've created the reference once, any previous workbench |
| // state memento is there. After once, there is no previous |
| // session state, so it should be null. |
| if (ref instanceof ViewReference) { |
| mem = ((ViewReference) ref).getMemento(); |
| if (mem!=null) { |
| mem = mem.getChild(IWorkbenchConstants.TAG_VIEW_STATE); |
| } |
| } |
| if (mem != null) { |
| IMemento child = viewMemento |
| .createChild(IWorkbenchConstants.TAG_VIEW_STATE); |
| child.putMemento(mem); |
| } |
| } |
| return viewMemento; |
| } |
| |
| // for dynamic UI |
| public void restoreViewState(IMemento memento) { |
| String compoundId = memento.getString(IWorkbenchConstants.TAG_ID); |
| mementoTable.put(compoundId, memento); |
| } |
| |
| IMemento getViewState(String key) { |
| IMemento memento = (IMemento) mementoTable.get(key); |
| |
| if (memento == null) { |
| return null; |
| } |
| |
| return memento.getChild(IWorkbenchConstants.TAG_VIEW_STATE); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.core.runtime.dynamicHelpers.IExtensionChangeHandler#removeExtension(org.eclipse.core.runtime.IExtension, java.lang.Object[]) |
| */ |
| public void removeExtension(IExtension source, Object[] objects) { |
| for (int i = 0; i < objects.length; i++) { |
| if (objects[i] instanceof IViewPart) { |
| IViewPart part = (IViewPart) objects[i]; |
| // String primaryViewId = part.getViewSite().getId(); |
| // String secondaryViewId = part.getViewSite().getSecondaryId(); |
| // IViewReference viewRef = page.findViewReference( |
| // primaryViewId, secondaryViewId); |
| // IPerspectiveDescriptor[] descs = |
| // page.getOpenedPerspectives(); |
| // Perspective active = page.getActivePerspective(); |
| // for (int i = 0; i < descs.length; i++) { |
| // Perspective nextPerspective = page.findPerspective(descs[i]); |
| // |
| // if (nextPerspective == null || active == nextPerspective) |
| // continue; |
| // |
| // page.hideView(nextPerspective, viewRef); |
| // } |
| page.hideView(part); |
| } |
| |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.core.runtime.dynamicHelpers.IExtensionChangeHandler#addExtension(org.eclipse.core.runtime.dynamicHelpers.IExtensionTracker, org.eclipse.core.runtime.IExtension) |
| */ |
| public void addExtension(IExtensionTracker tracker,IExtension extension) { |
| //Do nothing |
| } |
| |
| } |
| |