blob: 8eab9923e6d03f1a67a1a226eaa6b4bfdb3e5dae [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 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.wst.sse.ui.tests;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPersistableElement;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ResourceSelectionDialog;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.texteditor.IElementStateListener;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.wst.sse.core.utils.StringUtils;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.provisional.extensions.breakpoint.IExtendedStorageEditorInput;
/**
* @author nitin
*
* A view to assist in testing out StructuredTextEditor's EditorInput
* handling.
*
* Permanently in-progress.
*/
public class ExtendedStorageEditorInputView extends ViewPart {
class AddFileInputAction extends Action {
public AddFileInputAction() {
super("Add FileEditorInput");
}
public void run() {
super.run();
ResourceSelectionDialog dlg = new ResourceSelectionDialog(fInputList.getControl().getShell(), ResourcesPlugin.getWorkspace().getRoot(), "Choose");
int retval = dlg.open();
if (retval == Window.OK) {
Object[] files = dlg.getResult();
for (int i = 0; i < files.length; i++) {
fInputs.add(new FileEditorInput((IFile) files[i]));
}
fInputList.refresh(true);
}
}
}
class AddStorageInputAction extends Action {
public AddStorageInputAction() {
super("Add StorageEditorInput");
}
public void run() {
super.run();
FileDialog dlg = new FileDialog(fInputList.getControl().getShell());
String fileName = dlg.open();
if (fileName != null) {
fInputs.add(new FileStorageEditorInput(new File(fileName)));
fInputList.refresh(true);
}
}
}
class DoubleClickListener implements IDoubleClickListener {
public void doubleClick(DoubleClickEvent event) {
new InputOpenAction().run();
}
}
class EditorInputLabelProvider implements ITableLabelProvider {
ILabelProvider baseProvider = new WorkbenchLabelProvider();
public void addListener(ILabelProviderListener listener) {
// not implemented
}
public void dispose() {
// no need
}
public Image getColumnImage(Object element, int columnIndex) {
if (element instanceof IFileEditorInput && columnIndex == 0) {
return baseProvider.getImage(((IFileEditorInput) element).getFile());
}
return null;
}
public String getColumnText(Object element, int columnIndex) {
IEditorInput input = (IEditorInput) element;
String text = null;
switch (columnIndex) {
case 0 :
try {
if (element instanceof FileStorageEditorInput) {
IPath fullpath = ((FileStorageEditorInput) element).getStorage().getFullPath();
text = fullpath != null ? fullpath.toString() : ((FileStorageEditorInput) element).getName();
if (((FileStorageEditorInput) element).isDirty()) {
text = "*" + text;
}
}
else if (element instanceof IFileEditorInput) {
text = ((IFileEditorInput) element).getFile().getFullPath().toString();
}
}
catch (CoreException e) {
e.printStackTrace();
}
break;
case 1 :
if (element instanceof FileStorageEditorInput) {
text = "FileStorageEditorInput";
}
else if (element instanceof IFileEditorInput) {
text = "FileEditorInput";
}
else {
text = input.getClass().getName();
}
break;
}
if (text == null)
text = "";
return text;
}
public boolean isLabelProperty(Object element, String property) {
return false;
}
public void removeListener(ILabelProviderListener listener) {
// not implemented
}
}
class FileBackedStorage implements IStorage {
File fFile = null;
FileBackedStorage(File file) {
super();
fFile = file;
}
boolean exists() {
return fFile.exists();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
*/
public Object getAdapter(Class adapter) {
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.resources.IStorage#getContents()
*/
public InputStream getContents() throws CoreException {
InputStream contents = null;
try {
contents = new FileInputStream(fFile);
ByteBuffer buffer = ByteBuffer.allocate((int) fFile.length());
byte[] bytes = new byte[2048];
while (contents.available() > 0) {
int count = contents.read(bytes);
buffer.put(bytes, 0, count);
}
contents.close();
contents = new ByteArrayInputStream(buffer.array());
}
catch (FileNotFoundException e) {
contents = new ByteArrayInputStream(new byte[0]);
}
catch (IOException e) {
contents = new ByteArrayInputStream(new byte[0]);
}
return contents;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.resources.IStorage#getFullPath()
*/
public IPath getFullPath() {
if (provideIStorageFullPath) {
return new Path(fFile.getAbsolutePath());
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.resources.IStorage#getName()
*/
public String getName() {
return fFile.getName();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.resources.IStorage#isReadOnly()
*/
public boolean isReadOnly() {
return true;
}
}
class FileStorageEditorInput implements IExtendedStorageEditorInput {
List fElementStateListeners = new Vector(0);
boolean fIsDirty = false;
FileBackedStorage fStorage = null;
FileStorageEditorInput(File file) {
fStorage = new FileBackedStorage(file);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.sse.ui.extensions.breakpoint.IExtendedStorageEditorInput#addElementStateListener(org.eclipse.ui.texteditor.IElementStateListener)
*/
public void addElementStateListener(IElementStateListener listener) {
fElementStateListeners.add(listener);
}
void elementContentAboutToBeReplaced() {
for (int i = 0; i < fElementStateListeners.size(); i++) {
((IElementStateListener) fElementStateListeners.get(i)).elementContentAboutToBeReplaced(FileStorageEditorInput.this);
}
}
void elementContentReplaced() {
for (int i = 0; i < fElementStateListeners.size(); i++) {
((IElementStateListener) fElementStateListeners.get(i)).elementContentReplaced(FileStorageEditorInput.this);
}
}
void elementDeleted() {
for (int i = 0; i < fElementStateListeners.size(); i++) {
((IElementStateListener) fElementStateListeners.get(i)).elementDeleted(FileStorageEditorInput.this);
}
}
void elementDirtyStateChanged(boolean dirty) {
setDirty(dirty);
for (int i = 0; i < fElementStateListeners.size(); i++) {
((IElementStateListener) fElementStateListeners.get(i)).elementDirtyStateChanged(FileStorageEditorInput.this, dirty);
}
}
void elementMoved(Object oldElement, Object newElement) {
for (int i = 0; i < fElementStateListeners.size(); i++) {
((IElementStateListener) fElementStateListeners.get(i)).elementMoved(FileStorageEditorInput.this, FileStorageEditorInput.this);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IEditorInput#exists()
*/
public boolean exists() {
return fStorage.exists();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
*/
public Object getAdapter(Class adapter) {
return null;
}
File getFile() {
return fStorage.fFile;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IEditorInput#getImageDescriptor()
*/
public ImageDescriptor getImageDescriptor() {
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IEditorInput#getName()
*/
public String getName() {
return fStorage.getName();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IEditorInput#getPersistable()
*/
public IPersistableElement getPersistable() {
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IStorageEditorInput#getStorage()
*/
public IStorage getStorage() throws CoreException {
return fStorage;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IEditorInput#getToolTipText()
*/
public String getToolTipText() {
return fStorage.getFullPath() != null ? fStorage.getFullPath().toString() : fStorage.getName();
}
boolean isDirty() {
return fIsDirty;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.sse.ui.extensions.breakpoint.IExtendedStorageEditorInput#removeElementStateListener(org.eclipse.ui.texteditor.IElementStateListener)
*/
public void removeElementStateListener(IElementStateListener listener) {
fElementStateListeners.remove(listener);
}
void setDirty(boolean dirty) {
fIsDirty = dirty;
}
}
class InputChangeDirtyStateAction extends Action implements IUpdate {
public InputChangeDirtyStateAction() {
super("Toggle dirty flag");
}
public void run() {
super.run();
IEditorInput[] inputs = getSelectedInputs();
for (int i = 0; i < inputs.length; i++) {
if (inputs[i] instanceof FileStorageEditorInput) {
((FileStorageEditorInput) inputs[i]).elementDirtyStateChanged(!((FileStorageEditorInput) inputs[i]).isDirty());
}
}
fInputList.refresh(true);
}
public void update() {
setEnabled(fSelectedElement != null && fSelectedElement instanceof FileStorageEditorInput);
}
}
class InputDeleteAction extends Action implements IUpdate {
public InputDeleteAction() {
super("Delete Input");
}
public void run() {
super.run();
IEditorInput[] inputs = getSelectedInputs();
for (int i = 0; i < inputs.length; i++) {
if (inputs[i] instanceof FileStorageEditorInput) {
((FileStorageEditorInput) inputs[i]).elementDeleted();
}
}
for (int i = 0; i < inputs.length; i++) {
fInputs.remove(inputs[i]);
}
fInputList.refresh();
}
public void update() {
setEnabled(fSelectedElement != null && fSelectedElement instanceof FileStorageEditorInput);
}
}
class InputMoveAction extends Action implements IUpdate {
public InputMoveAction() {
super("Move Input");
}
public void run() {
super.run();
IEditorInput[] inputs = getSelectedInputs();
for (int i = 0; i < inputs.length; i++) {
if (inputs[i] instanceof FileStorageEditorInput) {
((FileStorageEditorInput) inputs[i]).elementMoved(inputs[i], inputs[i]);
}
}
}
public void update() {
setEnabled(fSelectedElement != null && fSelectedElement instanceof FileStorageEditorInput);
}
}
class InputOpenAction extends Action {
public InputOpenAction() {
super("Open");
}
public void run() {
super.run();
IEditorInput[] inputs = getSelectedInputs();
for (int i = 0; i < inputs.length; i++) {
try {
getSite().getWorkbenchWindow().getActivePage().openEditor(inputs[i], getEditorId(inputs[i]));
}
catch (PartInitException e) {
openError(getSite().getWorkbenchWindow().getActivePage().getWorkbenchWindow().getShell(), "OpenSystemEditorAction.dialogTitle", e.getMessage(), e);
}
}
}
}
class InputReplaceContentsAction extends Action implements IUpdate {
public InputReplaceContentsAction() {
super("Replace Input's Contents");
}
public void run() {
super.run();
IEditorInput[] inputs = getSelectedInputs();
for (int i = 0; i < inputs.length; i++) {
((FileStorageEditorInput) inputs[i]).elementContentAboutToBeReplaced();
((FileStorageEditorInput) inputs[i]).elementContentReplaced();
}
}
public void update() {
setEnabled(fSelectedElement != null && fSelectedElement instanceof FileStorageEditorInput);
}
}
class RemoveInputAction extends Action {
public RemoveInputAction() {
super("Remove");
}
public void run() {
super.run();
IEditorInput[] inputs = getSelectedInputs();
for (int i = 0; i < inputs.length; i++) {
fInputs.remove(inputs[i]);
}
fInputList.refresh();
}
}
class ReuseEditorAction extends Action implements IUpdate {
public ReuseEditorAction() {
super("Reuse Editor");
}
public void run() {
super.run();
IEditorInput[] inputs = getSelectedInputs();
for (int i = 0; i < inputs.length; i++) {
IEditorPart editor = getSite().getWorkbenchWindow().getActivePage().getActiveEditor();
if (editor instanceof IReusableEditor) {
getSite().getWorkbenchWindow().getActivePage().reuseEditor(((IReusableEditor) editor), inputs[i]);
}
else {
SSEUIPlugin.getDefault().getWorkbench().getDisplay().beep();
}
}
}
public void update() {
boolean enable = true;
try {
enable = fSelectedElement != null && getSite().getWorkbenchWindow().getActivePage().getActiveEditor() instanceof IReusableEditor;
}
catch (Exception e) {
enable = true;
}
setEnabled(enable);
}
}
public static final boolean provideIStorageFullPath = true;
/**
* Open an error style dialog for PartInitException by including any extra
* information from the nested CoreException if present.
*/
public static void openError(Shell parent, String title, String message, PartInitException exception) {
// Check for a nested CoreException
CoreException nestedException = null;
IStatus status = exception.getStatus();
if (status != null && status.getException() instanceof CoreException)
nestedException = (CoreException) status.getException();
if (nestedException != null) {
// Open an error dialog and include the extra
// status information from the nested CoreException
ErrorDialog.openError(parent, title, message, nestedException.getStatus());
}
else {
// Open a regular error dialog since there is no
// extra information to display
MessageDialog.openError(parent, title, message);
}
}
private List actions = null;
TableViewer fInputList = null;
List fInputs = new ArrayList(0);
Object fSelectedElement = null;
public ExtendedStorageEditorInputView() {
super();
actions = new ArrayList();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {
fInputList = new TableViewer(parent, SWT.FULL_SELECTION | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
fInputList.setContentProvider(new ArrayContentProvider());
fInputList.setLabelProvider(new EditorInputLabelProvider());
fInputList.addDoubleClickListener(new DoubleClickListener());
fInputList.getTable().setHeaderVisible(true);
fInputList.getTable().setLinesVisible(true);
String[] columns = new String[]{"Path", "Type"};
fInputList.setLabelProvider(new EditorInputLabelProvider());
TableLayout tlayout = new TableLayout();
CellEditor[] cellEditors = new CellEditor[5];
for (int i = 0; i < columns.length; i++) {
tlayout.addColumnData(new ColumnWeightData(1));
TableColumn tc = new TableColumn(fInputList.getTable(), SWT.NONE);
tc.setText(columns[i]);
tc.setResizable(true);
tc.setWidth(Display.getCurrent().getBounds().width / 14);
}
fInputList.setCellEditors(cellEditors);
fInputList.setColumnProperties(columns);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
fInputList.getTable().setLayoutData(gd);
MenuManager menuManager = new MenuManager("#popup"); //$NON-NLS-1$
menuManager.setRemoveAllWhenShown(false);
menuManager.add(new InputOpenAction());
menuManager.add(new Separator());
menuManager.add(new InputMoveAction());
menuManager.add(new InputChangeDirtyStateAction());
menuManager.add(new InputDeleteAction());
menuManager.add(new InputReplaceContentsAction());
menuManager.add(new Separator());
menuManager.add(new RemoveInputAction());
Menu menu = menuManager.createContextMenu(fInputList.getControl());
fInputList.getControl().setMenu(menu);
SSETestsPlugin.getDefault().getPluginPreferences().setDefault(getInputsPreferenceName(), "");
String paths[] = StringUtils.unpack(SSETestsPlugin.getDefault().getPluginPreferences().getString(getInputsPreferenceName()));
for (int i = 0; i < paths.length; i++) {
if (paths[i].startsWith("S!")) {
fInputs.add(new FileStorageEditorInput(new File(paths[i].substring(2))));
}
else if (paths[i].startsWith("F!")) {
fInputs.add(new FileEditorInput(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(paths[i].substring(2)))));
}
}
fInputList.setInput(fInputs);
fInputList.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection sel = ((IStructuredSelection) event.getSelection());
fSelectedElement = sel.getFirstElement();
}
});
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPart#dispose()
*/
public void dispose() {
List paths = new ArrayList(0);
for (int i = 0; i < fInputs.size(); i++) {
try {
Object input = fInputs.get(i);
String path = null;
if (input instanceof FileStorageEditorInput) {
path = "S!" + ((FileStorageEditorInput) input).getFile().getCanonicalPath();
}
else if (input instanceof IFileEditorInput) {
path = "F!" + ((IFileEditorInput) input).getFile().getFullPath().toString();
}
if (path != null) {
paths.add(path);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
SSETestsPlugin.getDefault().getPluginPreferences().setValue(getInputsPreferenceName(), StringUtils.pack((String[]) paths.toArray(new String[0])));
SSETestsPlugin.getDefault().savePluginPreferences();
}
String getEditorId(IEditorInput input) {
IWorkbench workbench = PlatformUI.getWorkbench();
IEditorRegistry editorRegistry = workbench.getEditorRegistry();
IContentType[] types = null;
String editorID = null;
if (input instanceof IStorageEditorInput) {
InputStream inputStream = null;
try {
inputStream = ((IStorageEditorInput) input).getStorage().getContents();
}
catch (CoreException e) {
e.printStackTrace();
}
try {
types = Platform.getContentTypeManager().findContentTypesFor(inputStream, input.getName());
}
catch (IOException e) {
e.printStackTrace();
}
try {
if (inputStream != null) {
inputStream.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
IEditorDescriptor descriptor = editorRegistry.getDefaultEditor(input.getName(), types[0]);
if (descriptor != null) {
editorID = descriptor.getId();
}
if (editorID == null) {
editorID = EditorsUI.DEFAULT_TEXT_EDITOR_ID;
}
return editorID;
}
/**
* @return
*/
String getInputsPreferenceName() {
return "ExtendedStorageEditorInputView:inputs";
}
IEditorInput[] getSelectedInputs() {
ISelection selection = fInputList.getSelection();
if (selection instanceof IStructuredSelection) {
IStructuredSelection sel = (IStructuredSelection) selection;
if (sel.isEmpty()) {
return new IEditorInput[0];
}
Object[] arr = sel.toArray();
IEditorInput[] inputs = new IEditorInput[arr.length];
System.arraycopy(arr, 0, inputs, 0, inputs.length);
return inputs;
}
return new IEditorInput[0];
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite)
*/
public void init(IViewSite site) throws PartInitException {
super.init(site);
site.getActionBars().getToolBarManager().add(rememberAction(new AddStorageInputAction()));
site.getActionBars().getToolBarManager().add(rememberAction(new AddFileInputAction()));
site.getActionBars().getToolBarManager().add(rememberAction(new ReuseEditorAction()));
site.getActionBars().getToolBarManager().add(rememberAction(new RemoveInputAction()));
site.getActionBars().getMenuManager().add(rememberAction(new InputOpenAction()));
site.getActionBars().getMenuManager().add(rememberAction(new ReuseEditorAction()));
site.getActionBars().getMenuManager().add(new Separator());
site.getActionBars().getMenuManager().add(rememberAction(new InputMoveAction()));
site.getActionBars().getMenuManager().add(rememberAction(new InputChangeDirtyStateAction()));
site.getActionBars().getMenuManager().add(rememberAction(new InputDeleteAction()));
site.getActionBars().getMenuManager().add(rememberAction(new InputReplaceContentsAction()));
}
IAction rememberAction(IAction action) {
actions.add(action);
return action;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPart#setFocus()
*/
public void setFocus() {
fInputList.getControl().setFocus();
}
protected void updateEnablement() {
for (int i = 0; i < actions.size(); i++) {
Object action = actions.get(i);
if (action instanceof IUpdate) {
((IUpdate) action).update();
}
}
}
}