blob: d82d905c6549759a4aa89e7f1d6315932b82b5ea [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2010, 2011 Mia-Software.
* 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:
* Gregoire Dupe (Mia-Software) - initial API and implementation
* Nicolas Bros (Mia-Software)
* Nicolas Guyomar (Mia-Software) - Bug 333652 Extension point offering the possibility to declare an EPackage browser
*******************************************************************************/
package org.eclipse.modisco.facet.util.emf.ui.internal.view;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EPackage.Registry;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
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.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.modisco.facet.common.ui.internal.views.AbstractTreeView;
import org.eclipse.modisco.facet.util.core.Logger;
import org.eclipse.modisco.facet.util.emf.core.IBrowserRegistry;
import org.eclipse.modisco.facet.util.emf.ui.internal.Activator;
import org.eclipse.modisco.facet.util.emf.ui.internal.Messages;
import org.eclipse.modisco.facet.util.emf.ui.internal.utils.ImageUtils;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IWorkbenchActionConstants;
/**
* An Eclipse view that displays a list of available Ecore meta-models.
*/
public class PackageRegistryView extends AbstractTreeView implements IMenuListener {
private static final String NAME_COLUMN = "PackageRegistryView_NameColumn"; //$NON-NLS-1$
private static final String NSURI_COLUMN = "PackageRegistryView_NsURIColumn"; //$NON-NLS-1$
private static final int COLUMN_WIDTH = 200;
private static final String DEBUG_ID = "org.eclipse.emf.facet.infra.common.ui/debug/PackageRegistryView/event_debug"; //$NON-NLS-1$
private static final boolean DEBUG = Activator.getDefault().isDebugging()
&& new Boolean(Platform.getDebugOption(PackageRegistryView.DEBUG_ID)).booleanValue();
@Override
public void createPartControl(final Composite parent) {
super.createPartControl(parent);
createContextMenu();
}
@Override
protected void createContextMenu() {
final MenuManager contextMenu = new MenuManager("#PopUp"); //$NON-NLS-1$
contextMenu.add(this.actionCopyNsURI);
contextMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
contextMenu.addMenuListener(this);
final Menu menu = contextMenu.createContextMenu(getViewer().getControl());
getViewer().getControl().setMenu(menu);
getSite().registerContextMenu(contextMenu, getViewer());
}
@Override
public void dispose() {
super.dispose();
}
@Override
protected void createColumns() {
createNameColumn();
createNsUriColumn();
}
private void createNameColumn() {
ColumnLabelProvider columnLabelProvider = new ColumnLabelProvider() {
@Override
public String getText(final Object element) {
if (element instanceof EPackage) {
EPackage ePackage = (EPackage) element;
return ePackage.getName();
} else if (element instanceof String) {
return (String) element;
}
return ""; //$NON-NLS-1$
}
@Override
public Image getImage(final Object element) {
return ImageUtils.getImage(element);
}
};
createColumn(Messages.PackageRegistryView_Name, PackageRegistryView.NAME_COLUMN,
PackageRegistryView.COLUMN_WIDTH, columnLabelProvider);
}
private void createNsUriColumn() {
ColumnLabelProvider columnLabelProvider = new ColumnLabelProvider() {
@Override
public String getText(final Object element) {
if (!(element instanceof EPackage)) {
return ""; //$NON-NLS-1$
}
EPackage ePackage = (EPackage) element;
return ePackage.getNsURI();
}
};
createColumn(Messages.PackageRegistryView_nsURI, PackageRegistryView.NSURI_COLUMN,
PackageRegistryView.COLUMN_WIDTH * 2, columnLabelProvider);
}
/**
* Reads the registry in a non-UI thread, so that the UI thread will be able to access it faster
*
* @param registry
* the registry to preload
*/
private static void preloadRegistry(final Registry registry) {
// avoid ConcurrentModificationException
List<String> keys = new ArrayList<String>();
keys.addAll(registry.keySet());
for (String nsURI : keys) {
try {
registry.getEPackage(nsURI);
} catch (Exception e) {
Logger.logWarning(e,
"An error happened while loading an EPackage from Package.Registry.INSTANCE: " //$NON-NLS-1$
+ nsURI, Activator.getDefault());
} catch (LinkageError e) {
Logger.logError(e, "An error prevented an EPackage from being loaded: " //$NON-NLS-1$
+ nsURI, Activator.getDefault());
}
}
}
/**
* An {@link EObject} was added to the package registry
*
* @param eObject
* @param file
*/
public void added(final EObject eObject, final IFile file) {
if (PackageRegistryView.DEBUG) {
System.out.println(this.getClass().getSimpleName() + ".added(EObject,IFile)"); //$NON-NLS-1$
}
refresh(true);
}
/**
* An {@link EObject} was changed in the package registry
*
* @param eObject
* @param file
*/
public void changed(final EObject eObject, final IFile file) {
if (PackageRegistryView.DEBUG) {
System.out.println(this.getClass().getSimpleName() + ".changed(EObject,IFile)"); //$NON-NLS-1$
}
refresh(true);
}
/**
* A file was removed from the package registry
*
* @param file
*/
public void removed(final IFile file) {
if (PackageRegistryView.DEBUG) {
System.out.println(this.getClass().getSimpleName() + ".removed(EObject,IFile)"); //$NON-NLS-1$
}
refresh(true);
}
@Override
protected IContentProvider getContentProvider() {
return new ITreeContentProvider() {
public Object[] getElements(final Object inputElement) {
if (inputElement instanceof EPackage.Registry) {
EPackage.Registry registry = (EPackage.Registry) inputElement;
List<EPackage> ePackages = new ArrayList<EPackage>();
// avoid a ConcurrentModificationException
List<String> keys = new ArrayList<String>();
keys.addAll(registry.keySet());
for (String nsURI : keys) {
try {
EPackage ePackage = registry.getEPackage(nsURI);
if (ePackage == null) {
throw new Exception("ePackage is null for : " //$NON-NLS-1$
+ nsURI);
}
ePackages.add(ePackage);
} catch (Exception e) {
Logger.logWarning(e,
"An error happened while loading an EPackage from Package.Registry.INSTANCE: " //$NON-NLS-1$
+ nsURI, Activator.getDefault());
}
}
return ePackages.toArray();
} else if (inputElement == null) {
return new Object[] {};
} else if (inputElement instanceof String) {
String message = (String) inputElement;
return new Object[] { message };
} else {
throw new RuntimeException("Unexpected element type: " //$NON-NLS-1$
+ inputElement.getClass().getName());
}
}
public void inputChanged(final Viewer viewer, final Object oldInput,
final Object newInput) {
// Nothing to do
}
public Object[] getChildren(final Object parentElement) {
if (parentElement instanceof EPackage.Registry) {
EPackage.Registry registry = (EPackage.Registry) parentElement;
return registry.values().toArray();
} else if (parentElement == null || parentElement instanceof String) {
return new Object[] {};
} else {
throw new RuntimeException("Unexpected element type: " //$NON-NLS-1$
+ parentElement.getClass().getName());
}
}
public Object getParent(final Object element) {
return null;
}
public boolean hasChildren(final Object element) {
if (element instanceof EPackage.Registry) {
return true;
}
return false;
}
public void dispose() {
// Nothing to do
}
};
}
@Override
protected void openElement(final Object element) {
if (element instanceof EPackage) {
EPackage ePackage = (EPackage) element;
IBrowserRegistry.INSTANCE.browseEPackage(ePackage);
}
}
@Override
protected String getRefreshMessage() {
return Messages.PackageRegistryView_RefreshingPackageRegistryView;
}
@Override
protected void doRefresh() {
// display a message while initializing
// (initialization can take a while)
Display.getDefault().syncExec(new Runnable() {
public void run() {
getViewer().setInput(Messages.PackageRegistryView_initializing);
}
});
final EPackage.Registry registry = EPackage.Registry.INSTANCE;
// Read a first time in a non-UI thread so as to avoid
// blocking. Then it will be cached for the UI thread.
preloadRegistry(registry);
Display.getDefault().syncExec(new Runnable() {
public void run() {
// the control might be disposed if the view was closed
// in the meantime
if (!getViewer().getControl().isDisposed()) {
getViewer().setInput(registry);
getViewer().refresh();
}
}
});
}
@Override
protected Object getInput() {
return EPackage.Registry.INSTANCE;
}
private final Action actionCopyNsURI = new Action(Messages.PackageRegistryView_copyNsURI,
IAction.AS_PUSH_BUTTON) {
@Override
public void run() {
EPackage selectedPackage = PackageRegistryView.this.getSelectedPackage();
if (selectedPackage != null) {
String nsURI = selectedPackage.getNsURI();
Clipboard clipboard = new Clipboard(Display.getDefault());
clipboard.setContents(new Object[] { nsURI },
new Transfer[] { TextTransfer.getInstance() });
clipboard.dispose();
}
}
};
protected EPackage getSelectedPackage() {
ISelection selection = getViewer().getSelection();
if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
Object element = structuredSelection.getFirstElement();
if (element instanceof EPackage) {
EPackage ePackage = (EPackage) element;
return ePackage;
}
}
return null;
}
public void menuAboutToShow(final IMenuManager manager) {
this.actionCopyNsURI.setEnabled(getSelectedPackage() != null);
}
}