diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 26839a99a8..08b4d8e019 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -2,6 +2,11 @@ This page describes the noteworthy improvements provided by each release of Eclipse Wild Web Developer. +## 1.0.1 + +#### Editing improvements + * Bind schema/grammar (XSD, DTD, RelaxNG) with codelens in XML file + ## 1.0.0 * 📅 Release Date: November 4th, 2022 diff --git a/org.eclipse.wildwebdeveloper.feature/feature.xml b/org.eclipse.wildwebdeveloper.feature/feature.xml index ee7824e5f6..c10628ae91 100644 --- a/org.eclipse.wildwebdeveloper.feature/feature.xml +++ b/org.eclipse.wildwebdeveloper.feature/feature.xml @@ -2,7 +2,7 @@ @@ -25,7 +25,7 @@ optional="true"/> - + 1.0.0-SNAPSHOT eclipse-feature - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT diff --git a/org.eclipse.wildwebdeveloper.xml.feature/feature.xml b/org.eclipse.wildwebdeveloper.xml.feature/feature.xml index 6cb4396d5b..46f810e0e1 100644 --- a/org.eclipse.wildwebdeveloper.xml.feature/feature.xml +++ b/org.eclipse.wildwebdeveloper.xml.feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/org.eclipse.wildwebdeveloper.xml.feature/pom.xml b/org.eclipse.wildwebdeveloper.xml.feature/pom.xml index 9b48503eab..f644217864 100644 --- a/org.eclipse.wildwebdeveloper.xml.feature/pom.xml +++ b/org.eclipse.wildwebdeveloper.xml.feature/pom.xml @@ -7,7 +7,7 @@ 1.0.0-SNAPSHOT eclipse-feature - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT diff --git a/org.eclipse.wildwebdeveloper.xml/META-INF/MANIFEST.MF b/org.eclipse.wildwebdeveloper.xml/META-INF/MANIFEST.MF index 08e5a01d89..f32114aa2b 100644 --- a/org.eclipse.wildwebdeveloper.xml/META-INF/MANIFEST.MF +++ b/org.eclipse.wildwebdeveloper.xml/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.wildwebdeveloper.xml;singleton:=true -Bundle-Version: 1.0.0.qualifier +Bundle-Version: 1.0.1.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Automatic-Module-Name: org.eclipse.wildwebdeveloper.xml @@ -21,7 +21,8 @@ Require-Bundle: org.eclipse.tm4e.registry;bundle-version="0.3.0", org.eclipse.core.net;bundle-version="1.3.0", org.eclipse.lsp4j.jsonrpc, org.eclipse.text, - org.eclipse.jface.text;bundle-version="3.20.100" + org.eclipse.jface.text;bundle-version="3.20.100", + com.google.gson Bundle-ActivationPolicy: lazy Bundle-Activator: org.eclipse.wildwebdeveloper.xml.internal.Activator Export-Package: org.eclipse.wildwebdeveloper.xml;x-friends:="org.eclipse.m2e.editor.lemminx" diff --git a/org.eclipse.wildwebdeveloper.xml/plugin.xml b/org.eclipse.wildwebdeveloper.xml/plugin.xml index cd09b5432a..7573878647 100644 --- a/org.eclipse.wildwebdeveloper.xml/plugin.xml +++ b/org.eclipse.wildwebdeveloper.xml/plugin.xml @@ -238,4 +238,12 @@ class="org.eclipse.wildwebdeveloper.xml.internal.ui.preferences.XMLPreferenceInitializer"> + + + + + diff --git a/org.eclipse.wildwebdeveloper.xml/pom.xml b/org.eclipse.wildwebdeveloper.xml/pom.xml index 1b9be6cbae..a48c67d20f 100644 --- a/org.eclipse.wildwebdeveloper.xml/pom.xml +++ b/org.eclipse.wildwebdeveloper.xml/pom.xml @@ -7,7 +7,7 @@ 1.0.0-SNAPSHOT eclipse-plugin - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT diff --git a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/XMLLanguageServer.java b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/XMLLanguageServer.java index a9be0587df..18d2239e3c 100644 --- a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/XMLLanguageServer.java +++ b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/XMLLanguageServer.java @@ -18,6 +18,7 @@ import java.net.URI; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -45,13 +46,28 @@ @SuppressWarnings("restriction") public class XMLLanguageServer extends ProcessStreamConnectionProvider { + + private static final String XML_LANGUAGE_SERVER_ID = "org.eclipse.wildwebdeveloper.xml"; + private static final String SETTINGS_KEY = "settings"; private static final String XML_KEY = "xml"; + // Extended capabilities for set CodeLens capabilities + private static final String EXTENDED_CLIENT_CAPABILITIES_KEY = "extendedClientCapabilities"; + private static final String CODE_LENS_KEY = "codeLens"; + private static final String CODE_LENS_KIND_KEY = "codeLensKind"; + private static final String VALUE_SET_KEY = "valueSet"; + private static final String BINDING_WIZARD_SUPPORT_KEY = "bindingWizardSupport"; + + private static enum CodeLensKind { + association; + } + private static final XMLExtensionRegistry extensionJarRegistry = new XMLExtensionRegistry(); private static final IPreferenceStore store = Activator.getDefault().getPreferenceStore(); private static final LanguageServerDefinition lemminxDefinition = LanguageServersRegistry.getInstance() - .getDefinition("org.eclipse.wildwebdeveloper.xml"); + .getDefinition(XML_LANGUAGE_SERVER_ID); + private static final IPropertyChangeListener psListener = event -> { XMLPreferenceServerConstants.getLemminxPreference(event).ifPresent(pref -> { Map config = mergeCustomInitializationOptions( @@ -153,16 +169,29 @@ private String computeJavaPath() { "bin/java" + (Platform.getOS().equals(Platform.OS_WIN32) ? ".exe" : "")).getAbsolutePath(); } - @Override - public String toString() { - return "XML Language Server: " + super.toString(); - } - @Override public Object getInitializationOptions(URI rootUri) { - return mergeCustomInitializationOptions(extensionJarRegistry.getInitiatizationOptions()); + Map initializationOptions = new HashMap<>(); + Map settings = mergeCustomInitializationOptions( + extensionJarRegistry.getInitiatizationOptions()); + initializationOptions.put(SETTINGS_KEY, settings.get(SETTINGS_KEY)); + Object extendedClientCapabilities = createExtendedClientCapabilities(); + initializationOptions.put(EXTENDED_CLIENT_CAPABILITIES_KEY, extendedClientCapabilities); + return initializationOptions; } + private static Object createExtendedClientCapabilities() { + Map extendedClientCapabilities = new HashMap<>(); + Map codeLens = new HashMap<>(); + extendedClientCapabilities.put(CODE_LENS_KEY, codeLens); + Map codeLensKind = new HashMap<>(); + codeLens.put(CODE_LENS_KIND_KEY, codeLensKind); + List valueSet = Arrays.asList(CodeLensKind.association.name()); + codeLensKind.put(VALUE_SET_KEY, valueSet); + extendedClientCapabilities.put(BINDING_WIZARD_SUPPORT_KEY, Boolean.TRUE); + return extendedClientCapabilities; + } + private static Map mergeCustomInitializationOptions(Map defaults) { Map xmlOpts = new HashMap<>(defaults); XMLPreferenceServerConstants.storePreferencesToLemminxOptions(store, xmlOpts); @@ -180,4 +209,9 @@ public void stop() { store.removePropertyChangeListener(psListener); super.stop(); } + + @Override + public String toString() { + return "XML Language Server: " + super.toString(); + } } diff --git a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/commands/AssociateGrammarDialog.java b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/commands/AssociateGrammarDialog.java new file mode 100644 index 0000000000..b41e85fa04 --- /dev/null +++ b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/commands/AssociateGrammarDialog.java @@ -0,0 +1,315 @@ +/******************************************************************************* + * Copyright (c) 2022 Red Hat Inc. and others. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Angelo ZERR (Red Hat Inc.) - initial implementation + *******************************************************************************/ +package org.eclipse.wildwebdeveloper.xml.internal.commands; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ComboViewer; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +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.FilteredResourcesSelectionDialog; +import org.eclipse.wildwebdeveloper.xml.internal.Activator; +import org.eclipse.wildwebdeveloper.xml.internal.ui.Messages; + +/** + * Dialog to select a grammar file (XSD, DTD, RelaxNG) and a binding type + * -standard, xml-model) + * + * @author Angelo ZERR + * + */ +public class AssociateGrammarDialog extends TitleAreaDialog { + + private final static List W3C_GRAMMAR_FILE_EXTENSION = Arrays.asList("xsd", "dtd"); + + private final static List RELAXNG_GRAMMAR_FILE_EXTENSION = Arrays.asList("rng", "rnc"); + + private final static List ALL_GRAMMAR_FILE_EXTENSION = Stream + .concat(W3C_GRAMMAR_FILE_EXTENSION.stream(), RELAXNG_GRAMMAR_FILE_EXTENSION.stream()).toList(); + + public static enum BindingType { + + standard("standard", "Standard (xsi, DOCTYPE)"), xmlmodel("xml-model", "XML Model association"); + + private final String code; + private final String label; + + private BindingType(String code, String label) { + this.code = code; + this.label = label; + } + + public String getCode() { + return code; + } + + public String getLabel() { + return label; + } + } + + private final IPath xmlFilePath; + private final IContainer xmlResourceContainer; + + private Text grammarURIText; + private ComboViewer bindingTypeViewer; + private String grammarURI; + private BindingType bindingType; + + public AssociateGrammarDialog(Shell parentShell, IPath xmlFilePath) { + super(parentShell); + this.xmlFilePath = xmlFilePath; + this.xmlResourceContainer = getResourceContainer(xmlFilePath); + } + + private IContainer getResourceContainer(IPath xmlFilePath) { + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(xmlFilePath); + if (file != null && file.exists()) { + return file.getProject(); + } + return ResourcesPlugin.getWorkspace().getRoot(); + } + + @Override + public void create() { + super.create(); + setTitle(Messages.AssociateGrammarDialog_title); + validate(); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite area = (Composite) super.createDialogArea(parent); + Composite container = new Composite(area, SWT.NONE); + container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout layout = new GridLayout(3, false); + container.setLayout(layout); + + createGrammarURIField(container); + createLastName(container); + return area; + } + + /** + * Create the Grammar text field with a Browse button. + * + * @param parent the parent composite. + */ + private void createGrammarURIField(Composite parent) { + // Label + Label grammarURILabel = new Label(parent, SWT.NONE); + grammarURILabel.setText(Messages.AssociateGrammarDialog_grammar_field); + + // Text field + grammarURIText = new Text(parent, SWT.BORDER); + grammarURIText.addModifyListener(e -> validate()); + GridData data = new GridData(); + data.grabExcessHorizontalSpace = true; + data.horizontalAlignment = GridData.FILL; + grammarURIText.setLayoutData(data); + + // Browse button + Button browseButton = new Button(parent, SWT.NONE); + browseButton.setText(Messages.Browse_button); + browseButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + FilteredResourcesSelectionDialog dialog = new FilteredResourcesSelectionDialog(getParentShell(), false, + xmlResourceContainer, IResource.FILE); + dialog.setInitialPattern("*."); + if (dialog.open() == OK) { + IFile selectedFile = (IFile) dialog.getFirstResult(); + IPath absolutePath = selectedFile.getFullPath().makeRelativeTo(xmlFilePath.removeLastSegments(1)); + grammarURIText.setText(absolutePath.toString()); + } + } + }); + } + + /** + * Create the association type combo. + * + * @param parent the parent composite. + */ + private void createLastName(Composite parent) { + // Label + Label bindingTypeLabel = new Label(parent, SWT.NONE); + bindingTypeLabel.setText(Messages.AssociateGrammarDialog_bindingType_field); + + // Combo + bindingTypeViewer = new ComboViewer(parent); + bindingTypeViewer.setContentProvider(ArrayContentProvider.getInstance()); + bindingTypeViewer.setLabelProvider(new LabelProvider() { + @Override + public String getText(Object element) { + if (element instanceof BindingType) { + BindingType bindingType = (BindingType) element; + return bindingType.getLabel(); + } + return super.getText(element); + } + }); + bindingTypeViewer.addSelectionChangedListener(e -> validate()); + + GridData daya = new GridData(); + daya.grabExcessHorizontalSpace = true; + daya.horizontalAlignment = GridData.FILL; + daya.horizontalSpan = 2; + bindingTypeViewer.getCombo().setLayoutData(daya); + bindingTypeViewer.setInput(BindingType.values()); + bindingTypeViewer.setSelection(new StructuredSelection(BindingType.standard)); + } + + @Override + protected boolean isResizable() { + return true; + } + + // save content of the Text fields because they get disposed + // as soon as the Dialog closes + private void saveInput() { + grammarURI = grammarURIText.getText(); + bindingType = (BindingType) bindingTypeViewer.getStructuredSelection().getFirstElement(); + } + + /** + * Validate fields and display a proper message in the dialog. + * + */ + private void validate() { + IStatus status = performValidation(); + switch (status.getSeverity()) { + case IStatus.ERROR: + setErrorMessage(status.getMessage()); + break; + default: + setErrorMessage(null); + if (status.isOK()) { + setMessage(""); + } else { + setMessage(status.getMessage(), getMessageType(status.getSeverity())); + } + break; + } + } + + /** + * Validate grammar file text and binding type combo selection. + * + * @return the status of the validation. + */ + private IStatus performValidation() { + String grammarURI = grammarURIText.getText(); + // Test if grammar file is filled + if (grammarURI.isBlank()) { + return createStatus(IStatus.ERROR, Messages.AssociateGrammarDialog_validation_grammar_file_required); + } + // Test if grammar file exists + IFile file = xmlResourceContainer.getFile(new Path(grammarURI)); + if (file == null || !file.exists()) { + return createStatus(IStatus.WARNING, + Messages.bind(Messages.AssociateGrammarDialog_validation_grammar_file_notExists, grammarURI)); + } + // In case of RelaxNG file, only xml-model association is allowed + if (isRelaxNGGrammarFile(file.getFileExtension())) { + BindingType bindingType = (BindingType) bindingTypeViewer.getStructuredSelection().getFirstElement(); + if (bindingType == BindingType.standard) { + return createStatus(IStatus.ERROR, + Messages.bind( + Messages.AssociateGrammarDialog_validation_grammar_file_invalid_association_for_relaxng, + grammarURI, BindingType.standard.getLabel())); + } + return Status.OK_STATUS; + } + // Test if selected grammar file is a XSD, DTD or RelaxNG (rnc, rng) file + if (!isStandardGramarFile(file.getFileExtension())) { + return createStatus(IStatus.WARNING, + Messages.bind(Messages.AssociateGrammarDialog_validation_grammar_file_invalid_fileExtension, + grammarURI, ALL_GRAMMAR_FILE_EXTENSION.stream().collect(Collectors.joining(", ")))); + } + return Status.OK_STATUS; + } + + private static int getMessageType(int severity) { + switch (severity) { + case IStatus.INFO: + return IMessageProvider.INFORMATION; + case IStatus.WARNING: + return IMessageProvider.WARNING; + case IStatus.ERROR: + return IMessageProvider.ERROR; + } + return IMessageProvider.NONE; + } + + private static IStatus createStatus(int severity, String message) { + return new Status(severity, Activator.PLUGIN_ID, message, null); + } + + private static boolean isStandardGramarFile(String fileExtension) { + return W3C_GRAMMAR_FILE_EXTENSION.contains(fileExtension); + } + + private static boolean isRelaxNGGrammarFile(String fileExtension) { + return RELAXNG_GRAMMAR_FILE_EXTENSION.contains(fileExtension); + } + + /** + * Returns the grammar file URI to associate. + * + * @return the grammar file URI to associate. + */ + public String getGrammarURI() { + return grammarURI; + } + + /** + * Returns the binding type to use for association. + * + * @return the binding type to use for association. + */ + public BindingType getBindingType() { + return bindingType; + } + + @Override + protected void okPressed() { + saveInput(); + super.okPressed(); + } + +} \ No newline at end of file diff --git a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/commands/AssociateGrammarHandler.java b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/commands/AssociateGrammarHandler.java new file mode 100644 index 0000000000..e5dcde1d30 --- /dev/null +++ b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/commands/AssociateGrammarHandler.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2022 Red Hat Inc. and others. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Angelo ZERR (Red Hat Inc.) - initial implementation + *******************************************************************************/ +package org.eclipse.wildwebdeveloper.xml.internal.commands; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.function.Predicate; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.lsp4e.LSPEclipseUtils; +import org.eclipse.lsp4e.LanguageServiceAccessor; +import org.eclipse.lsp4e.command.LSPCommandHandler; +import org.eclipse.lsp4j.Command; +import org.eclipse.lsp4j.ExecuteCommandOptions; +import org.eclipse.lsp4j.ExecuteCommandParams; +import org.eclipse.lsp4j.ServerCapabilities; +import org.eclipse.lsp4j.TextDocumentEdit; +import org.eclipse.lsp4j.TextDocumentIdentifier; +import org.eclipse.lsp4j.WorkspaceEdit; +import org.eclipse.lsp4j.jsonrpc.messages.Either; +import org.eclipse.lsp4j.services.LanguageServer; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.wildwebdeveloper.xml.internal.Activator; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +/** + * LSP command handler called by "Bind to grammar/schema..." code lens from an + * XML file which is not associated with a grammar. This handler: + * + *
    + *
  • open a dialog to select the grammar file to associate and the binding + * type (xsi, DOCTYPE, xml-model, ...)
  • + *
  • insert in the XML the proper syntax to associate the selected grammar + * file / binding type by consuming the "xml.associate.grammar.insert" XML + * language server command.
  • + *
+ * + * @author Angelo ZERR + * + */ +public class AssociateGrammarHandler extends LSPCommandHandler { + + private static final String ASSOCIATE_GRAMMAR_INSERT = "xml.associate.grammar.insert"; + + @Override + public Object execute(ExecutionEvent event, Command command, IPath path) throws ExecutionException { + String uri = (String) command.getArguments().get(0); + // Open the association grammar dialog. + AssociateGrammarDialog dialog = new AssociateGrammarDialog(HandlerUtil.getActiveShell(event), path); + if (dialog.open() == IDialogConstants.OK_ID) { + String grammarURI = dialog.getGrammarURI(); + String bindingType = dialog.getBindingType().getCode(); + TextDocumentIdentifier identifier = new TextDocumentIdentifier(uri); + try { + executeServerCommand(ASSOCIATE_GRAMMAR_INSERT, identifier, grammarURI, bindingType) // + .thenAccept(result -> { + // Insert the proper syntax for binding + Gson gson = new Gson(); + JsonObject jsonObject = gson.toJsonTree(result).getAsJsonObject(); + TextDocumentEdit edit = gson.fromJson(jsonObject, TextDocumentEdit.class); + WorkspaceEdit workEdits = new WorkspaceEdit(); + workEdits.setDocumentChanges(new ArrayList<>()); + workEdits.getDocumentChanges().add(Either.forLeft(edit)); + LSPEclipseUtils.applyWorkspaceEdit(workEdits, ASSOCIATE_GRAMMAR_INSERT); + }); + } catch (Exception e) { + Activator.getDefault().getLog().error("Error while insert grammar association", e); + } + } + return null; + } + + private static CompletableFuture executeServerCommand(String commandId, Object... params) throws Exception { + List commandHandlers = LanguageServiceAccessor + .getActiveLanguageServers(handlesCommand(commandId)); + if (commandHandlers != null) { + if (commandHandlers.size() == 1) { + LanguageServer handler = commandHandlers.get(0); + return handler.getWorkspaceService() + .executeCommand(new ExecuteCommandParams(commandId, Arrays.asList(params))); + } else if (commandHandlers.size() > 1) { + throw new IllegalStateException( + "Multiple language servers have registered to handle command '" + commandId + "'"); + } + } + throw new UnsupportedOperationException( + "No language server has registered to handle command '" + commandId + "'"); + } + + private static Predicate handlesCommand(String commandId) { + return (serverCaps) -> { + ExecuteCommandOptions executeCommandProvider = serverCaps.getExecuteCommandProvider(); + if (executeCommandProvider != null) { + return executeCommandProvider.getCommands().contains(commandId); + } + return false; + }; + } + +} diff --git a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/Messages.java b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/Messages.java index 617f09ab05..823dcd7b79 100644 --- a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/Messages.java +++ b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/Messages.java @@ -19,7 +19,7 @@ public class Messages extends NLS { public static String XMLPreferencePage_XMLCatalogsLink; public static String XMLPreferencePage_downloadExternalResources_enabled; public static String XMLPreferencePage_completion_autoCloseTags; - + // --------- XML Catalog preference page public static String XMLCatalogPreferencePage_Entries; public static String XMLCatalogPreferencePage_Edit; @@ -53,9 +53,19 @@ public class Messages extends NLS { public static String XMLValidationPreferencePage_validation_resolveExternalEntities; public static String XMLValidationPreferencePage_validation_noGrammar; + // --------- Associate Grammar Dialog + public static String AssociateGrammarDialog_title; + public static String AssociateGrammarDialog_grammar_field; + public static String AssociateGrammarDialog_bindingType_field; + public static String AssociateGrammarDialog_validation_grammar_file_required; + public static String AssociateGrammarDialog_validation_grammar_file_notExists; + public static String AssociateGrammarDialog_validation_grammar_file_invalid_fileExtension; + public static String AssociateGrammarDialog_validation_grammar_file_invalid_association_for_relaxng; + // --------- Buttons - public static String PreferencePage_Add; - public static String PreferencePage_Remove; + public static String Add_button; + public static String Remove_button; + public static String Browse_button; static { NLS.initializeMessages("org.eclipse.wildwebdeveloper.xml.internal.ui.messages", Messages.class); //$NON-NLS-1$ diff --git a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/messages.properties b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/messages.properties index ec2e09d562..7c84d54c5a 100644 --- a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/messages.properties +++ b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/messages.properties @@ -48,5 +48,16 @@ XMLValidationPreferencePage_validation_disallowDocTypeDecl=Enable if a fatal err XMLValidationPreferencePage_validation_resolveExternalEntities=Allow &resolution of external entities (\u26A0\uFE0F Security risk) XMLValidationPreferencePage_validation_noGrammar=Severity when document has no associated &grammar -PreferencePage_Add=\u2795 &Add... -PreferencePage_Remove=\uD83D\uDDD1 &Remove +# Associate Grammar Dialog +AssociateGrammarDialog_title=Associate grammar +AssociateGrammarDialog_grammar_field=Grammar file: +AssociateGrammarDialog_bindingType_field=Association type: +AssociateGrammarDialog_validation_grammar_file_required=The grammar file is required. +AssociateGrammarDialog_validation_grammar_file_notExists=The grammar file ''{0}'' doesn''t exist. +AssociateGrammarDialog_validation_grammar_file_invalid_fileExtension=The grammar file ''{0}'' should have ''{1}'' file extension. +AssociateGrammarDialog_validation_grammar_file_invalid_association_for_relaxng=The RelaxNG grammar file ''{0}'' cannot be associated with ''{1}'' type. + +# Buttons +Add_button=\u2795 &Add... +Remove_button=\uD83D\uDDD1 &Remove +Browse_button=Browse... \ No newline at end of file diff --git a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/preferences/XMLCatalogPreferencePage.java b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/preferences/XMLCatalogPreferencePage.java index 9268cbfee2..4a78e619f6 100644 --- a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/preferences/XMLCatalogPreferencePage.java +++ b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/preferences/XMLCatalogPreferencePage.java @@ -94,7 +94,7 @@ protected Control createContents(Composite parent) { Button addButton = new Button(buttonComposite, SWT.PUSH); addButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - addButton.setText(Messages.PreferencePage_Add); + addButton.setText(Messages.Add_button); addButton.addSelectionListener(widgetSelectedAdapter(e -> { File result = openSelectFileDialog(); if (result == null) { @@ -108,7 +108,7 @@ protected Control createContents(Composite parent) { final Button removeButton = new Button(buttonComposite, SWT.PUSH); removeButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - removeButton.setText(Messages.PreferencePage_Remove); + removeButton.setText(Messages.Remove_button); removeButton.setEnabled(false); removeButton.addSelectionListener(widgetSelectedAdapter(e -> { if (selectedEntry != null) { diff --git a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/preferences/XMLPreferenceInitializer.java b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/preferences/XMLPreferenceInitializer.java index 90da1d4ff9..d11212cc26 100644 --- a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/preferences/XMLPreferenceInitializer.java +++ b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/ui/preferences/XMLPreferenceInitializer.java @@ -51,7 +51,7 @@ public void initializeDefaultPreferences() { // Server settings STORE.setDefault(XML_PREFERENCES_DOWNLOAD_EXTERNAL_RESOURCES.preferenceId, true); STORE.setDefault(XML_PREFERENCES_CATAGLOGS.preferenceId, ""); - STORE.setDefault(XML_PREFERENCES_CODELENS_ENABLED.preferenceId, false); + STORE.setDefault(XML_PREFERENCES_CODELENS_ENABLED.preferenceId, true); STORE.setDefault(XML_PREFERENCES_FOLDING_INCLUDE_CLOSING_TAG_IN_FOLD.preferenceId, true); STORE.setDefault(XML_PREFERENCES_FORMAT_EMPTY_ELEMENTS.preferenceId, "ignore"); STORE.setDefault(XML_PREFERENCES_FORMAT_SPACE_BEFORE_EMPTY_CLOSE_TAG.preferenceId, true);