blob: 8992ee6aef1699a5732d496b2c966181ac2e51ba [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2015 Oracle. 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:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.jaxb.ui.internal.properties;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EventListener;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ColumnWeightData;
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.window.ToolTip;
import org.eclipse.jface.window.Window;
import org.eclipse.jpt.common.ui.internal.WorkbenchTools;
import org.eclipse.jpt.common.ui.internal.swt.ColumnAdapter;
import org.eclipse.jpt.common.ui.internal.swt.TableModelAdapter;
import org.eclipse.jpt.common.ui.internal.swt.bindings.SWTBindingTools;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.collection.CollectionTools;
import org.eclipse.jpt.common.utility.internal.iterable.SingleElementIterable;
import org.eclipse.jpt.common.utility.internal.model.AbstractModel;
import org.eclipse.jpt.common.utility.internal.model.value.AspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.BufferedModifiablePropertyValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.CollectionPropertyValueModelAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.PropertyAspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.SimpleCollectionValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.SimplePropertyValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.SortedListValueModelAdapter;
import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent;
import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener;
import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener;
import org.eclipse.jpt.common.utility.model.value.CollectionValueModel;
import org.eclipse.jpt.common.utility.model.value.ModifiableCollectionValueModel;
import org.eclipse.jpt.common.utility.model.value.ModifiablePropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.jaxb.core.JaxbProject;
import org.eclipse.jpt.jaxb.core.JaxbProjectManager;
import org.eclipse.jpt.jaxb.core.JaxbWorkspace;
import org.eclipse.jpt.jaxb.core.SchemaEntry;
import org.eclipse.jpt.jaxb.core.xsd.XsdUtil;
import org.eclipse.jpt.jaxb.ui.JaxbWorkbench;
import org.eclipse.jpt.jaxb.ui.JptJaxbUiMessages;
import org.eclipse.jpt.jaxb.ui.internal.wizards.classesgen.SelectFileOrXMLCatalogIdPanel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.PropertyPage;
import org.eclipse.wst.xsd.contentmodel.internal.XSDImpl;
import org.eclipse.xsd.XSDSchema;
/**
* Shows the schemas associated with a JAXB project
*/
public class JaxbSchemasPropertiesPage
extends PropertyPage {
private static final int SIZING_SELECTION_PANE_WIDTH = 450;
private final ResourceManager resourceManager;
protected final ModifiablePropertyValueModel<IProject> projectModel;
private final PropertyValueModel<JaxbProject> jaxbProjectModel;
protected final BufferedModifiablePropertyValueModel.Trigger trigger;
private final SchemasModel schemasModel;
private final ModifiableCollectionValueModel<Schema> schemasSelectionModel;
public JaxbSchemasPropertiesPage() {
super();
this.resourceManager = this.buildResourceManager();
this.projectModel = new SimplePropertyValueModel<IProject>();
this.jaxbProjectModel = new JaxbProjectModel(this.projectModel);
this.trigger = new BufferedModifiablePropertyValueModel.Trigger();
this.schemasModel = new SchemasModel(this.jaxbProjectModel, this.trigger);
this.schemasSelectionModel = new SimpleCollectionValueModel<Schema>();
setDescription(JptJaxbUiMessages.SCHEMAS_PAGE_DESCRIPTION);
}
private ResourceManager buildResourceManager() {
return new LocalResourceManager(this.getParentResourceManager());
}
private ResourceManager getParentResourceManager() {
return JFaceResources.getResources();
}
protected IProject getProject() {
return this.projectModel.getValue();
}
@Override
public final void createControl(Composite parent ) {
super.createControl( parent );
Button revertButton = getDefaultsButton();
revertButton.setText(JptJaxbUiMessages.SCHEMAS_PAGE_REVERT);
GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
Point minButtonSize = revertButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
gd.widthHint = Math.max(convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH), minButtonSize.x);
revertButton.setLayoutData(gd);
updateButtons();
getShell().layout(true, true);
}
@Override
protected final Control createContents(Composite parent) {
IAdaptable element = getElement();
IProject project = null;
if (element instanceof IProject) {
project = (IProject) element;
}
else {
project = (IProject) Platform.getAdapterManager().loadAdapter(element, IProject.class.getName());
}
this.projectModel.setValue(project);
Composite pageComponent = new Composite(parent, SWT.NULL);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
layout.marginHeight = 0;
pageComponent.setLayout(layout);
GridData data = new GridData(GridData.FILL_BOTH);
data.widthHint = SIZING_SELECTION_PANE_WIDTH;
pageComponent.setLayoutData(data);
Label schemasLabel = new Label(pageComponent, SWT.LEFT);
schemasLabel.setText(JptJaxbUiMessages.SCHEMAS_PAGE_SCHEMAS);
data = new GridData();
data.horizontalAlignment = GridData.FILL;
data.horizontalSpan = 2;
schemasLabel.setLayoutData(data);
// create the table composite
Composite tableComposite = new Composite(pageComponent, SWT.NONE);
data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.grabExcessHorizontalSpace = true;
data.grabExcessVerticalSpace = true;
data.widthHint = SIZING_SELECTION_PANE_WIDTH;
tableComposite.setLayoutData(data);
// create the table
TableViewer schemasTable = new TableViewer(tableComposite, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI);
TableModelAdapter.adapt(
new SortedListValueModelAdapter<Schema>(this.schemasModel),
this.schemasSelectionModel,
schemasTable.getTable(),
new SchemaColumnAdapter(),
new SchemaTableLabelProvider());
ColumnViewerToolTipSupport.enableFor(schemasTable, ToolTip.NO_RECREATE);
schemasTable.getTable().setHeaderVisible(true);
schemasTable.getTable().setToolTipText(null);
// set the table composite layout (after the table, so that column information is available)
TableColumnLayout tableLayout = new TableColumnLayout();
tableLayout.setColumnData(schemasTable.getTable().getColumn(0), new ColumnWeightData(15));
tableLayout.setColumnData(schemasTable.getTable().getColumn(1), new ColumnWeightData(25));
tableComposite.setLayout(tableLayout);
// set the table layout data
data = new GridData(GridData.FILL_BOTH);
data.heightHint = schemasTable.getTable().getItemHeight() * 7;
data.widthHint = 200;
schemasTable.getTable().setLayoutData(data);
createButtonGroup(pageComponent);
Dialog.applyDialogFont(parent);
return pageComponent;
}
protected void createButtonGroup(Composite parent) {
Composite groupComponent = new Composite(parent, SWT.NULL);
GridLayout groupLayout = new GridLayout();
groupLayout.marginWidth = 0;
groupLayout.marginHeight = 0;
groupComponent.setLayout(groupLayout);
GridData data = new GridData();
data.verticalAlignment = GridData.FILL;
data.horizontalAlignment = GridData.FILL;
groupComponent.setLayoutData(data);
Button addButton = new Button(groupComponent, SWT.PUSH);
addButton.setText(JptJaxbUiMessages.SCHEMAS_PAGE_ADD_BUTTON_LABEL);
addButton.addSelectionListener(
new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
addSchema();
}
});
setButtonLayoutData(addButton);
Button editButton = new Button(groupComponent, SWT.PUSH);
editButton.setText(JptJaxbUiMessages.SCHEMAS_PAGE_EDIT_BUTTON_LABEL);
editButton.addSelectionListener(
new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
editSelectedSchema();
}
});
SWTBindingTools.bindEnabledState(buildEditEnabledModel(), editButton);
setButtonLayoutData(editButton);
Button removeButton = new Button(groupComponent, SWT.PUSH);
removeButton.setText(JptJaxbUiMessages.SCHEMAS_PAGE_REMOVE_BUTTON_LABEL);
removeButton.addSelectionListener(
new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
removeSelectedSchemas();
}
});
SWTBindingTools.bindEnabledState(buildRemoveEnabledModel(), removeButton);
setButtonLayoutData(removeButton);
}
private void addSchema() {
// constructs a dialog for editing the new schema namespace and location
AddEditSchemaDialog dialog =
new AddEditSchemaDialog(
getShell(),
null,
this.schemasModel.getAspectValue(),
this.resourceManager);
// opens the dialog - just returns if the user cancels it
if (dialog.open() == Window.CANCEL) {
return;
}
// otherwise, adds the new schema
Schema schema = this.schemasModel.addSchema(dialog.getNamespace(), dialog.getLocation());
// select the new schema
this.schemasSelectionModel.setValues(new SingleElementIterable<Schema>(schema));
}
private PropertyValueModel<Boolean> buildEditEnabledModel() {
return new CollectionPropertyValueModelAdapter<Boolean, Schema>(this.schemasSelectionModel) {
@Override
protected Boolean buildValue() {
return Boolean.valueOf(this.collectionModel.size() == 1);
}
};
}
private void editSelectedSchema() {
// constructs a dialog for editing the new schema namespace and location
final Schema schema = this.schemasSelectionModel.iterator().next();
AddEditSchemaDialog dialog =
new AddEditSchemaDialog(
getShell(),
schema,
this.schemasModel.getAspectValue(),
this.resourceManager);
// opens the dialog - just returns if the user cancels it
if (dialog.open() == Window.CANCEL) {
return;
}
// otherwise, changes the new schema
schema.setNamespace(dialog.getNamespace());
schema.setLocation(dialog.getLocation());
}
private PropertyValueModel<Boolean> buildRemoveEnabledModel() {
return new CollectionPropertyValueModelAdapter<Boolean, Schema>(this.schemasSelectionModel) {
@Override
protected Boolean buildValue() {
return Boolean.valueOf(this.collectionModel.size() >= 1);
}
};
}
private void removeSelectedSchemas() {
this.schemasModel.removeSchemas(this.schemasSelectionModel);
}
private void updateButtons() {
boolean enableApply = isValid();
boolean enableRevert = true;
Button applyButton = getApplyButton();
if (applyButton != null) {
applyButton.setEnabled(enableApply);
}
Button revertButton = getDefaultsButton();
if (revertButton != null) {
revertButton.setEnabled(enableRevert);
}
}
// ********** OK/Revert/Apply behavior **********
@Override
public boolean performOk() {
try {
// true=fork; false=uncancellable
this.buildOkProgressMonitorDialog().run(true, false, this.buildOkRunnableWithProgress());
}
catch (InterruptedException ex) {
// should *not* happen...
Thread.currentThread().interrupt();
return false;
}
catch (InvocationTargetException ex) {
throw new RuntimeException(ex.getTargetException());
}
return true;
}
private IRunnableContext buildOkProgressMonitorDialog() {
return new ProgressMonitorDialog(this.getShell());
}
private IRunnableWithProgress buildOkRunnableWithProgress() {
return new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
IWorkspace ws = ResourcesPlugin.getWorkspace();
try {
// the build we execute in #performOk_() locks the workspace root,
// so we need to use the workspace root as our scheduling rule here
ws.run(
buildOkWorkspaceRunnable(),
ws.getRoot(),
IWorkspace.AVOID_UPDATE,
monitor);
}
catch (CoreException ex) {
throw new InvocationTargetException(ex);
}
}
};
}
/* private */ IWorkspaceRunnable buildOkWorkspaceRunnable() {
return new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
performOk_(monitor);
}
};
}
void performOk_(IProgressMonitor monitor) throws CoreException {
if (this.schemasModel.hasChanges()) {
this.trigger.accept();
JaxbProjectManager jaxbProjectManager = this.getJaxbProjectManager();
if (jaxbProjectManager != null) {
jaxbProjectManager.rebuildJaxbProject(getProject());
}
getProject().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
}
}
private JaxbProjectManager getJaxbProjectManager() {
JaxbWorkspace jaxbWorkspace = this.getJaxbWorkspace();
return (jaxbWorkspace == null) ? null : jaxbWorkspace.getJaxbProjectManager();
}
private JaxbWorkspace getJaxbWorkspace() {
JaxbWorkbench jaxbWorkbench = this.getJaxbWorkbench();
return (jaxbWorkbench == null) ? null : jaxbWorkbench.getJaxbWorkspace();
}
private JaxbWorkbench getJaxbWorkbench() {
return WorkbenchTools.getAdapter(JaxbWorkbench.class);
}
@Override
protected void performDefaults() {
this.trigger.reset();
}
@Override
public void dispose() {
this.resourceManager.dispose();
super.dispose();
}
static class SchemasModel
extends AspectAdapter<JaxbProject, Collection<Schema>>
implements CollectionValueModel<Schema> {
/**
* The collection of schemas
*/
protected final Collection<Schema> schemas;
/**
* This is the trigger that indicates whether the buffered value
* should be accepted or reset.
*/
protected final PropertyValueModel<Boolean> triggerHolder;
/** This listens to the trigger holder. */
protected final PropertyChangeListener triggerChangeListener;
SchemasModel(PropertyValueModel<JaxbProject> subjectHolder, PropertyValueModel<Boolean> triggerHolder) {
super(subjectHolder);
this.schemas = new ArrayList<Schema>();
this.triggerHolder = triggerHolder;
this.triggerChangeListener = buildTriggerChangeListener();
}
protected PropertyChangeListener buildTriggerChangeListener() {
return new PropertyChangeListener() {
public void propertyChanged(PropertyChangeEvent event) {
triggerChanged(event);
}
};
}
protected Collection<Schema> buildSchemas_() {
ArrayList<Schema> schemas = new ArrayList<Schema>();
for (SchemaEntry entry : this.subject.getSchemaLibrary().getSchemaEntries()) {
schemas.add(new Schema(entry.getNamespace(), entry.getLocation()));
}
return schemas;
}
public boolean hasChanges() {
return (this.subject == null) ? false : ! this.schemas.equals(buildSchemas_());
}
protected void triggerChanged(PropertyChangeEvent event) {
if (hasChanges()) {
if (this.subject != null && ((Boolean) event.getNewValue()).booleanValue()) {
this.accept();
} else {
this.reset();
}
}
}
public void accept() {
List<String> schemaLocations = new Vector<String>();
for (Schema schema : this.schemas) {
schemaLocations.add(schema.getLocation());
}
this.subject.getSchemaLibrary().setSchemaLocations(schemaLocations);
}
public void reset() {
this.schemas.clear();
if (this.subject != null) {
this.schemas.addAll(buildSchemas_());
}
fireCollectionChanged(VALUES, getAspectValue());
}
public Schema addSchema(String namespace, String location) {
Schema schema = new Schema(namespace, location);
addItemToCollection(schema, this.schemas, VALUES);
return schema;
}
public void removeSchemas(Iterable<Schema> schemas) {
removeItemsFromCollection(schemas, this.schemas, VALUES);
}
// ************ AspectAdapter impl ************************************
@Override
protected String getListenerAspectName() {
return VALUES;
}
@Override
protected Class<? extends EventListener> getListenerClass() {
return CollectionChangeListener.class;
}
@Override
protected boolean hasListeners() {
return hasAnyCollectionChangeListeners(VALUES);
}
@Override
protected void fireAspectChanged(Collection<Schema> oldValue, Collection<Schema> newValue) {
this.synchronizeCollection(newValue, new ArrayList<Schema>(oldValue), VALUES);
}
@Override
protected void engageSubject_() {
this.schemas.addAll(buildSchemas_());
}
@Override
protected void disengageSubject_() {
this.schemas.clear();
}
@Override
protected void engageModels() {
super.engageModels();
this.triggerHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.triggerChangeListener);
}
@Override
protected void disengageModels() {
this.triggerHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.triggerChangeListener);
super.disengageModels();
}
@Override
protected Collection<Schema> getAspectValue() {
return CollectionTools.hashBag(iterator());
}
// ************ CollectionValueModel impl *****************************
public Iterator<Schema> iterator() {
return this.schemas.iterator();
}
public int size() {
return this.schemas.size();
}
}
static class Schema
extends AbstractModel
implements Comparable<Schema> {
static String locationDisplayString(String location) {
if (location == null) {
return StringTools.EMPTY_STRING;
}
URI uri = URI.createURI(location);
if (uri.isPlatformResource()) {
return uri.toPlatformString(false);
}
return location;
}
static String namespaceDisplayString(String namespace) {
if (null == namespace || StringTools.EMPTY_STRING.equals(namespace)) {
return JptJaxbUiMessages.SCHEMAS_PAGE_NO_NAMESPACE_TEXT;
}
return namespace;
}
Schema(String namespace, String location) {
super();
this.namespace = namespace;
this.location = location;
}
private String namespace;
final static String NAMESPACE_PROPERTY = "namespace"; //$NON-NLS-1$
private String location;
final static String LOCATION_PROPERTY = "location"; //$NON-NLS-1$
String getNamespace() {
return this.namespace;
}
void setNamespace(String namespace) {
String old = this.namespace;
this.namespace = namespace;
firePropertyChanged(NAMESPACE_PROPERTY, old, namespace);
}
String namespaceDisplayString() {
return namespaceDisplayString(this.namespace);
}
String getLocation() {
return this.location;
}
String locationDisplayString() {
return locationDisplayString(getLocation());
}
void setLocation(String location) {
String old = this.location;
this.location = location;
firePropertyChanged(LOCATION_PROPERTY, old, location);
}
public int compareTo(Schema o) {
return this.namespaceDisplayString().compareTo(o.namespaceDisplayString());
}
}
static class SchemaColumnAdapter
implements ColumnAdapter<Schema> {
static final int COLUMN_COUNT = 2;
static final int NAMESPACE_COLUMN = 0;
static final int LOCATION_COLUMN = 1;
public int columnCount() {
return COLUMN_COUNT;
}
public String columnName(int columnIndex) {
switch (columnIndex) {
case NAMESPACE_COLUMN :
return JptJaxbUiMessages.SCHEMAS_PAGE_NAMESPACE_COLUMN_LABEL;
case LOCATION_COLUMN :
return JptJaxbUiMessages.SCHEMAS_PAGE_LOCATION_COLUMN_LABEL;
default :
return null;
}
}
public ModifiablePropertyValueModel<?>[] cellModels(Schema subject) {
ModifiablePropertyValueModel<?>[] cellModels = new ModifiablePropertyValueModel<?>[COLUMN_COUNT];
cellModels[NAMESPACE_COLUMN] = buildNamespaceCellModel(subject);
cellModels[LOCATION_COLUMN] = buildLocationCellModel(subject);
return cellModels;
}
private ModifiablePropertyValueModel<String> buildNamespaceCellModel(Schema subject) {
return new PropertyAspectAdapter<Schema, String>(Schema.NAMESPACE_PROPERTY, subject) {
@Override
protected String buildValue_() {
return this.subject.getNamespace();
}
};
}
private ModifiablePropertyValueModel<String> buildLocationCellModel(Schema subject) {
return new PropertyAspectAdapter<Schema, String>(Schema.LOCATION_PROPERTY, subject) {
@Override
protected String buildValue_() {
return this.subject.getLocation();
}
};
}
}
static class SchemaTableLabelProvider
extends LabelProvider
implements ITableLabelProvider {
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
public String getColumnText(Object element, int columnIndex) {
switch (columnIndex) {
case SchemaColumnAdapter.NAMESPACE_COLUMN :
return ((Schema) element).namespaceDisplayString();
case SchemaColumnAdapter.LOCATION_COLUMN :
return ((Schema) element).locationDisplayString();
default :
return null;
}
}
}
static class AddEditSchemaDialog
extends TitleAreaDialog {
private final ResourceManager resourceManager;
private final Schema currentSchema;
private String defaultMessage;
private final ModifiablePropertyValueModel<String> location;
private final ModifiablePropertyValueModel<String> namespace;
private XSDSchema resolvedSchema;
private final Mode mode;
private final Iterable<Schema> allSchemas;
public AddEditSchemaDialog(Shell shell, Schema currentSchema, Iterable<Schema> allSchemas, ResourceManager resourceManager) {
super(shell);
this.resourceManager = resourceManager;
this.currentSchema = currentSchema;
this.allSchemas = allSchemas;
this.location = new SimplePropertyValueModel<String>();
this.namespace = new SimplePropertyValueModel<String>();
this.mode = (this.currentSchema == null) ? Mode.ADD : Mode.EDIT;
if (this.mode == Mode.ADD) {
this.defaultMessage = JptJaxbUiMessages.SCHEMAS_PAGE_ADD_SCHEMA_MESSAGE;
this.location.setValue(null);
this.namespace.setValue(null);
}
else {
this.defaultMessage = JptJaxbUiMessages.SCHEMAS_PAGE_EDIT_SCHEMA_MESSAGE;
this.location.setValue(currentSchema.getLocation());
this.namespace.setValue(currentSchema.getNamespace());
}
}
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
if (this.mode == Mode.ADD) {
newShell.setText(JptJaxbUiMessages.SCHEMAS_PAGE_ADD_SCHEMA_DIALOG_TITLE);
}
else {
newShell.setText(JptJaxbUiMessages.SCHEMAS_PAGE_EDIT_SCHEMA_DIALOG_TITLE);
}
}
@Override
protected Control createDialogArea(Composite parent) {
Composite dialogArea = (Composite) super.createDialogArea(parent);
setMessage(this.defaultMessage);
if (this.mode == Mode.ADD) {
setTitle(JptJaxbUiMessages.SCHEMAS_PAGE_ADD_SCHEMA_TITLE);
}
else {
setTitle(JptJaxbUiMessages.SCHEMAS_PAGE_EDIT_SCHEMA_TITLE);
}
Composite composite = new Composite(dialogArea, SWT.NONE);
composite.setLayout(new GridLayout(3, false));
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Label locationLabel = new Label(composite, SWT.NULL);
locationLabel.setText(JptJaxbUiMessages.SCHEMAS_PAGE_LOCATION_LABEL);
locationLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
final Text locationText = new Text(composite, SWT.SINGLE | SWT.BORDER);
locationText.setText(locationDisplayString());
locationText.setEditable(false);
locationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
this.location.addPropertyChangeListener(
PropertyValueModel.VALUE,
new PropertyChangeListener() {
public void propertyChanged(PropertyChangeEvent event) {
locationText.setText(locationDisplayString());
}
});
Button browseButton = new Button(composite, SWT.PUSH);
browseButton.setText(JptJaxbUiMessages.SCHEMAS_PAGE_BROWSE_BUTTON_LABEL);
browseButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, true, 1, 1));
browseButton.addSelectionListener(
new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
browseForSchemaLocation();
}
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
});
Label namespaceLabel = new Label(composite, SWT.NULL);
namespaceLabel.setText(JptJaxbUiMessages.SCHEMAS_PAGE_NAMESPACE_LABEL);
namespaceLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
final Text namespaceText = new Text(composite, SWT.SINGLE | SWT.BORDER);
namespaceText.setText(namespaceDisplayString());
namespaceText.setEditable(false);
namespaceText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
this.namespace.addPropertyChangeListener(
PropertyValueModel.VALUE,
new PropertyChangeListener() {
public void propertyChanged(PropertyChangeEvent event) {
namespaceText.setText(namespaceDisplayString());
}
});
Dialog.applyDialogFont(dialogArea);
return dialogArea;
}
@Override
public void create() {
super.create();
// disable ok button until user does something and then validation takes over
getButton(IDialogConstants.OK_ID).setEnabled(false);
}
@Override
protected boolean isResizable() {
return true;
}
private void browseForSchemaLocation() {
SchemaLocationDialog dialog = new SchemaLocationDialog(getShell(), this.resourceManager);
// opens the dialog - just returns if the user cancels it
if (dialog.open() == Window.CANCEL) {
return;
}
String location = dialog.getLocation();
this.location.setValue(location);
String resolvedUri = XsdUtil.getResolvedUri(location);
XSDSchema schema = XSDImpl.buildXSDModel(resolvedUri);
String newNamespace =
(schema == null) ?
null
: ((schema.getTargetNamespace()) == null ?
StringTools.EMPTY_STRING
: schema.getTargetNamespace());
this.namespace.setValue(newNamespace);
this.resolvedSchema = schema;
validate();
}
public String getNamespace() {
return this.namespace.getValue();
}
protected String namespaceDisplayString() {
return Schema.namespaceDisplayString(getNamespace());
}
public String getLocation() {
return this.location.getValue();
}
protected String locationDisplayString() {
return Schema.locationDisplayString(getLocation());
}
private void validate() {
if (this.resolvedSchema == null) {
setErrorMessage(JptJaxbUiMessages.SCHEMAS_PAGE_SCHEMA_UNRESOLVED_MESSAGE);
}
else if (isDuplicateNamespace()) {
setErrorMessage(JptJaxbUiMessages.SCHEMAS_PAGE_DUPLICATE_NAMESPACE_MESSAGE);
}
else if (StringTools.isBlank(this.location.getValue())) {
setErrorMessage(JptJaxbUiMessages.SCHEMAS_PAGE_NO_LOCATION_MESSAGE);
}
else {
setErrorMessage(null);
setMessage(this.defaultMessage);
}
getButton(IDialogConstants.OK_ID).setEnabled(getErrorMessage() == null);
}
private boolean isDuplicateNamespace() {
for (Schema schema : this.allSchemas) {
if ((this.currentSchema != schema) && getNamespace().equals(schema.getNamespace())) {
return true;
}
}
return false;
}
private enum Mode {
ADD,
EDIT
}
}
static class SchemaLocationDialog
extends TrayDialog {
private final ResourceManager resourceManager;
private SelectFileOrXMLCatalogIdPanel locationPanel;
private String location;
public SchemaLocationDialog(Shell shell, ResourceManager resourceManager) {
super(shell);
this.resourceManager = resourceManager;
}
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText(JptJaxbUiMessages.SCHEMAS_PAGE_CHOOSE_LOCATION_TITLE);
}
@Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
this.locationPanel = new SelectFileOrXMLCatalogIdPanel(composite, StructuredSelection.EMPTY, this.resourceManager);
this.locationPanel.setFilterExtensions(new String[] {".xsd"}); //$NON-NLS-1$
this.locationPanel.update();
this.locationPanel.setVisibleHelper(true);
return composite;
}
@Override
protected boolean isResizable() {
return true;
}
@Override
protected void okPressed() {
IFile file = this.locationPanel.getFile();
if (file != null) {
this.location = URI.createPlatformResourceURI(file.getFullPath().toString(), false).toString();
}
else {
this.location = this.locationPanel.getXMLCatalogId();
}
super.okPressed();
}
public String getLocation() {
return this.location;
}
}
}