blob: b6d65cd1c2023c20e27455a1a4da800f13c021c9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 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.pde.internal.ui.wizards.extension;
import org.eclipse.pde.internal.ui.dialogs.PluginSelectionDialog;
import java.io.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.PluginRegistry;
import org.eclipse.pde.internal.core.PDECore;
import org.eclipse.pde.internal.core.ischema.IDocumentSection;
import org.eclipse.pde.internal.core.ischema.ISchemaAttribute;
import org.eclipse.pde.internal.core.schema.*;
import org.eclipse.pde.internal.core.util.CoreUtility;
import org.eclipse.pde.internal.core.util.IdUtil;
import org.eclipse.pde.internal.ui.*;
import org.eclipse.pde.internal.ui.util.SWTUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.views.navigator.ResourceComparator;
public abstract class BaseExtensionPointMainPage extends WizardPage {
public static final String SETTINGS_PLUGIN_ID = "BaseExtensionPoint.settings.pluginId"; //$NON-NLS-1$
public static final String SCHEMA_DIR = "schema"; //$NON-NLS-1$
protected IContainer fContainer;
protected Text fIdText;
protected Text fPluginIdText;
protected Text fNameText;
protected Text fSchemaText;
protected Text fSchemaLocationText;
protected Button fOpenSchemaButton;
protected Button fSharedSchemaButton;
protected Button fPluginBrowseButton;
protected Button fFindLocationButton;
public BaseExtensionPointMainPage(IContainer container) {
super("newExtensionPoint"); //$NON-NLS-1$
fContainer = container;
}
public void createControl(Composite parent) {
Composite container = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 3;
layout.verticalSpacing = 9;
layout.makeColumnsEqualWidth = false;
container.setLayout(layout);
Label label;
GridData gd;
if (isPluginIdNeeded()) {
label = new Label(container, SWT.NONE);
label.setText(PDEUIMessages.BaseExtensionPoint_pluginId);
fPluginIdText = new Text(container, SWT.SINGLE | SWT.BORDER);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 1;
gd.widthHint = 275;
fPluginIdText.setLayoutData(gd);
fPluginIdText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
validatePage();
}
});
fPluginBrowseButton = new Button(container, SWT.PUSH);
gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
gd.horizontalSpan = 1;
gd.widthHint = 50;
fPluginBrowseButton.setLayoutData(gd);
fPluginBrowseButton.setText(PDEUIMessages.BaseExtensionPointMainPage_pluginBrowse);
fPluginBrowseButton.setToolTipText(PDEUIMessages.BaseExtensionPointMainPage_pluginId_tooltip);
fPluginBrowseButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
handlePluginBrowse();
}
});
SWTUtil.setButtonDimensionHint(fPluginBrowseButton);
}
label = new Label(container, SWT.NONE);
label.setText(PDEUIMessages.BaseExtensionPoint_id);
fIdText = new Text(container, SWT.SINGLE | SWT.BORDER);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
fIdText.setLayoutData(gd);
fIdText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
// setting the text will trigger validation
// do not implicitly validate here
fSchemaText.setText(getSchemaLocation() + (getSchemaLocation().length() > 0 ? "/" : "") + fIdText.getText() + ".exsd"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
});
label = new Label(container, SWT.NONE);
label.setText(PDEUIMessages.BaseExtensionPoint_name);
fNameText = new Text(container, SWT.SINGLE | SWT.BORDER);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
fNameText.setLayoutData(gd);
fNameText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
validatePage();
}
});
if (isPluginIdNeeded() && !isPluginIdFinal()) {
label = new Label(container, SWT.NONE);
label.setText(PDEUIMessages.BaseExtensionPoint_schemaLocation);
fSchemaLocationText = new Text(container, SWT.SINGLE | SWT.BORDER);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.widthHint = 150;
gd.grabExcessHorizontalSpace = true;
fSchemaLocationText.setLayoutData(gd);
fSchemaLocationText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
validatePage();
}
});
fFindLocationButton = new Button(container, SWT.PUSH);
gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
gd.widthHint = 50;
fFindLocationButton.setLayoutData(gd);
fFindLocationButton.setText(PDEUIMessages.BaseExtensionPointMainPage_findBrowse);
fFindLocationButton.setToolTipText(PDEUIMessages.BaseExtensionPointMainPage_schemaLocation_tooltip);
fFindLocationButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
handleSchemaLocation();
}
});
SWTUtil.setButtonDimensionHint(fFindLocationButton);
}
label = new Label(container, SWT.NONE);
label.setText(PDEUIMessages.BaseExtensionPoint_schema);
fSchemaText = new Text(container, SWT.SINGLE | SWT.BORDER);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
fSchemaText.setLayoutData(gd);
fSchemaText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
validatePage();
}
});
if (isSharedSchemaSwitchNeeded()) {
fSharedSchemaButton = new Button(container, SWT.CHECK);
fSharedSchemaButton.setText(PDEUIMessages.BaseExtensionPoint_shared);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
fSharedSchemaButton.setLayoutData(gd);
}
fOpenSchemaButton = new Button(container, SWT.CHECK);
fOpenSchemaButton.setText(PDEUIMessages.BaseExtensionPoint_edit);
fOpenSchemaButton.setSelection(true);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
fOpenSchemaButton.setLayoutData(gd);
if (isPluginIdNeeded())
fPluginIdText.setFocus();
else
fIdText.setFocus();
setControl(container);
initializeValues();
validatePage();
// do not start with an error message, convert to regular message
String error = getErrorMessage();
if (error != null) {
setMessage(error);
setErrorMessage(null);
}
Dialog.applyDialogFont(container);
PlatformUI.getWorkbench().getHelpSystem().setHelp(container, IHelpContextIds.NEW_SCHEMA);
}
private InputStream createSchemaStream(String pluginId, String pointId, String name, boolean shared) {
if (name.length() == 0)
name = pointId;
EditableSchema schema = new EditableSchema(pluginId, pointId, name, false);
schema.setDescription(PDEUIMessages.BaseExtensionPoint_sections_overview);
DocumentSection section;
section = new DocumentSection(schema, IDocumentSection.SINCE, PDEUIMessages.BaseExtensionPointMainPage_since);
section.setDescription(PDEUIMessages.BaseExtensionPoint_sections_since);
schema.addDocumentSection(section);
SchemaElement element;
if (!shared) {
element = new SchemaRootElement(schema, "extension"); //$NON-NLS-1$
SchemaComplexType complexType = new SchemaComplexType(schema);
element.setType(complexType);
SchemaAttribute attribute = new SchemaAttribute(element, "point"); //$NON-NLS-1$
attribute.setType(new SchemaSimpleType(schema, "string")); //$NON-NLS-1$
attribute.setUse(ISchemaAttribute.REQUIRED);
complexType.addAttribute(attribute);
attribute = new SchemaAttribute(element, "id"); //$NON-NLS-1$
attribute.setType(new SchemaSimpleType(schema, "string")); //$NON-NLS-1$
complexType.addAttribute(attribute);
attribute = new SchemaAttribute(element, "name"); //$NON-NLS-1$
attribute.setType(new SchemaSimpleType(schema, "string")); //$NON-NLS-1$
attribute.setTranslatableProperty(true);
complexType.addAttribute(attribute);
schema.addElement(element);
}
section = new DocumentSection(schema, IDocumentSection.EXAMPLES, "Examples"); //$NON-NLS-1$
section.setDescription(PDEUIMessages.BaseExtensionPoint_sections_usage);
schema.addDocumentSection(section);
section = new DocumentSection(schema, IDocumentSection.API_INFO, "API Information"); //$NON-NLS-1$
section.setDescription(PDEUIMessages.BaseExtensionPoint_sections_api);
schema.addDocumentSection(section);
section = new DocumentSection(schema, IDocumentSection.IMPLEMENTATION, "Supplied Implementation"); //$NON-NLS-1$
section.setDescription(PDEUIMessages.BaseExtensionPoint_sections_supplied);
schema.addDocumentSection(section);
section = new DocumentSection(schema, IDocumentSection.COPYRIGHT, "Copyright"); //$NON-NLS-1$
section.setDescription(PDEUIMessages.BaseExtensionPoint_sections_copyright);
schema.addDocumentSection(section);
StringWriter swriter = new StringWriter();
try {
PrintWriter writer = new PrintWriter(swriter, true);
schema.save(writer);
swriter.close();
} catch (IOException e) {
PDEPlugin.logException(e);
}
try {
return new ByteArrayInputStream(swriter.toString().getBytes("UTF8")); //$NON-NLS-1$
} catch (UnsupportedEncodingException e) {
return new ByteArrayInputStream(new byte[0]);
}
}
private IFile generateSchemaFile(String pluginId, String id, String name, boolean shared, String schema, IProgressMonitor monitor) throws CoreException {
IFile schemaFile = null;
IWorkspace workspace = fContainer.getWorkspace();
IPath schemaPath = new Path(schema).removeLastSegments(1);
IPath newSchemaPath = fContainer.getProjectRelativePath().append(schemaPath);
monitor.subTask(PDEUIMessages.BaseExtensionPoint_generating);
if (newSchemaPath.isEmpty() == false) {
IFolder folder = fContainer.getProject().getFolder(newSchemaPath);
CoreUtility.createFolder(folder);
}
InputStream source = createSchemaStream(pluginId, id, name, shared);
IPath filePath = fContainer.getFullPath().append(schema);
schemaFile = workspace.getRoot().getFile(filePath);
if (!schemaFile.exists()) {
// create for the first time
schemaFile.create(source, true, monitor);
} else {
schemaFile.setContents(source, true, false, monitor);
}
IDE.setDefaultEditor(schemaFile, IPDEUIConstants.SCHEMA_EDITOR_ID);
return schemaFile;
}
public IRunnableWithProgress getOperation() {
final boolean openFile = fOpenSchemaButton.getSelection();
final String id = fIdText.getText();
final String name = fNameText.getText();
final String schema = fSchemaText.getText();
final boolean shared = fSharedSchemaButton != null ? fSharedSchemaButton.getSelection() : false;
IRunnableWithProgress operation = new WorkspaceModifyOperation() {
public void execute(final IProgressMonitor monitor) {
try {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
String schemaName = schema;
if (!schema.endsWith(".exsd")) //$NON-NLS-1$
schemaName = schema + ".exsd"; //$NON-NLS-1$
IFile file = fContainer.getFile(new Path(schema));
// do not overwrite if schema already exists
if (!file.exists())
try {
file = generateSchemaFile(getPluginId(), id, name, shared, schemaName, monitor);
} catch (CoreException e) {
PDEPlugin.logException(e);
}
if (file != null && openFile) {
fSchemaText.setText(file.getProjectRelativePath().toString());
openSchemaFile(file);
}
}
});
} finally {
monitor.done();
}
}
};
return operation;
}
public String getSchemaLocation() {
if (fSchemaText != null) {
String schema = fSchemaText.getText();
if (schema.length() == 0) {
if (fSchemaLocationText != null && SCHEMA_DIR.equals(new Path(fSchemaLocationText.getText()).lastSegment())) {
return ""; //$NON-NLS-1$
}
return SCHEMA_DIR;
}
int loc = schema.lastIndexOf("/"); //$NON-NLS-1$
if (loc != -1)
return schema.substring(0, loc);
}
return ""; //$NON-NLS-1$
}
public String getPluginId() {
if (fPluginIdText != null) {
return fPluginIdText.getText();
}
return ""; //$NON-NLS-1$
}
protected boolean isPluginIdNeeded() {
return false;
}
protected boolean isPluginIdFinal() {
return false;
}
protected boolean isSharedSchemaSwitchNeeded() {
return false;
}
private void openSchemaFile(final IFile file) {
final IWorkbenchWindow ww = PDEPlugin.getActiveWorkbenchWindow();
Display d = ww.getShell().getDisplay();
d.asyncExec(new Runnable() {
public void run() {
try {
String editorId = IPDEUIConstants.SCHEMA_EDITOR_ID;
ww.getActivePage().openEditor(new FileEditorInput(file), editorId);
} catch (PartInitException e) {
PDEPlugin.logException(e);
}
}
});
}
private void validatePage() {
// clear opening message
setMessage(null);
String message = validateFieldContents();
setErrorMessage(message);
setPageComplete(message == null);
}
protected abstract String validateFieldContents();
protected abstract void initializeValues();
protected String validateExtensionPointID() {
// Verify not zero length
String id = fIdText.getText();
if (id.length() == 0)
return PDEUIMessages.BaseExtensionPointMainPage_missingExtensionPointID;
// For 3.2 or greater plug-ins verify that it is a valid composite ID
// and that it has a valid namespace
// For 3.1 and lower plug-ins verify that it is a valid simple ID
String pluginID = getPluginId();
IPluginModelBase model = PluginRegistry.findModel(pluginID);
// Verify that the plugin was found
if (model == null) {
return NLS.bind(PDEUIMessages.BaseExtensionPointMainPage_errorMsgPluginNotFound, pluginID);
}
String schemaVersion = model.getPluginBase().getSchemaVersion();
if (schemaVersion == null || Float.parseFloat(schemaVersion) >= 3.2) {
if (!IdUtil.isValidCompositeID(id))
return PDEUIMessages.BaseExtensionPointMainPage_invalidCompositeID;
} else if (!IdUtil.isValidSimpleID(id))
return PDEUIMessages.BaseExtensionPointMainPage_invalidSimpleID;
return null;
}
protected String validateExtensionPointName() {
// Verify not zero length
if (fNameText.getText().length() == 0)
return PDEUIMessages.BaseExtensionPointMainPage_missingExtensionPointName;
return null;
}
protected String validateExtensionPointSchema() {
// Verify not zero length
if (fSchemaText.getText().length() == 0)
return PDEUIMessages.BaseExtensionPointMainPage_missingExtensionPointSchema;
return null;
}
private void handlePluginBrowse() {
PluginSelectionDialog dialog = new PluginSelectionDialog(getShell(), PluginRegistry.getWorkspaceModels(), false);
dialog.create();
if (dialog.open() == Window.OK) {
IPluginModelBase workspaceModelBase = (IPluginModelBase) dialog.getFirstResult();
fPluginIdText.setText(workspaceModelBase.getPluginBase().getId());
}
}
private void handleSchemaLocation() {
ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(), new WorkbenchContentProvider());
dialog.setTitle(PDEUIMessages.BaseExtensionPointMainPage_schemaLocation_title);
dialog.setMessage(PDEUIMessages.BaseExtensionPointMainPage_schemaLocation_desc);
dialog.setDoubleClickSelects(false);
dialog.setAllowMultiple(false);
dialog.addFilter(new ViewerFilter() {
public boolean select(Viewer viewer, Object parentElement, Object element) {
if (element instanceof IFile)
return false;
return true;
}
});
dialog.setInput(PDEPlugin.getWorkspace().getRoot());
dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
dialog.setInitialSelection(fContainer);
dialog.create();
PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(), IHelpContextIds.CONTAINER_SELECTION);
if (dialog.open() == Window.OK) {
Object[] elements = dialog.getResult();
if (elements.length > 0) {
IResource elem = (IResource) elements[0];
String newPath = getWorkspaceRelativePath(elem.getLocation().toString());
fSchemaLocationText.setText(newPath + "/"); //$NON-NLS-1$
}
}
}
private String getWorkspaceRelativePath(String path) {
String workspacePath = PDECore.getWorkspace().getRoot().getLocation().toString();
if (path.startsWith(workspacePath))
path = path.replaceFirst(workspacePath, ""); //$NON-NLS-1$
return path;
}
public String getInvalidIdMessage() {
// No validation done (other than making sure id is not blank)
return null;
}
}