Skip to content

Commit

Permalink
XML Files support with settings
Browse files Browse the repository at this point in the history
Fixes eclipse#1464

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Nov 28, 2023
1 parent def27a7 commit d7408ca
Show file tree
Hide file tree
Showing 25 changed files with 1,119 additions and 456 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.eclipse.lemminx.extensions.catalog;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.extensions.filepath.IFilePathExpression;
import org.eclipse.lemminx.extensions.filepath.IFilePathExpressionProvider;
import org.eclipse.lemminx.extensions.filepath.settings.FilePathExpression;
import org.eclipse.lemminx.utils.DOMUtils;

public class CatalogFilePathExpressionProvider implements IFilePathExpressionProvider {

private static final List<IFilePathExpression> CATALOG_FILE_PATH_EXPRESSIONS;

static {
CATALOG_FILE_PATH_EXPRESSIONS = Arrays.asList(createUriExpression());
}

private static FilePathExpression createUriExpression() {
FilePathExpression uri = new FilePathExpression();
uri.setXPath("@uri");
return uri;
}

@Override
public List<IFilePathExpression> getExpressions(DOMDocument document) {
if (!DOMUtils.isCatalog(document)) {
return Collections.emptyList();
}
return CATALOG_FILE_PATH_EXPRESSIONS;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void doDiagnostics(DOMDocument xmlDocument, List<Diagnostic> diagnostics,
// appending it in the case when original URI does not start with 'file://'.
// Ex: originalURI ="foo/bar.xsd" -> path ="file://foo/bar.xsd"
String path = CatalogUtils.getResolvedLocation(xmlDocument, catalogEntry);
if (!FilesUtils.isValidPath(FilesUtils.getPath(path)) && URIUtils.isFileResource(path)) {
if (path != null && !FilesUtils.isValidPath(FilesUtils.getPath(path)) && URIUtils.isFileResource(path)) {
Range range = XMLPositionUtility.selectValueWithoutQuote(catalogEntry.getLinkRange());
String msg = MessageFormat.format(ERROR_STRING, catalogEntry.getResolvedURI());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.eclipse.lemminx.client.PathFeature;
import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelManager;
import org.eclipse.lemminx.extensions.contentmodel.settings.ContentModelSettings;
import org.eclipse.lemminx.extensions.filepath.FilePathPlugin;
import org.eclipse.lemminx.services.IXMLNotificationService;
import org.eclipse.lemminx.services.extensions.IDocumentLinkParticipant;
import org.eclipse.lemminx.services.extensions.IXMLExtension;
Expand Down Expand Up @@ -71,6 +72,8 @@ public void start(InitializeParams params, XMLExtensionsRegistry registry) {
registry.registerDocumentLinkParticipant(documentLinkParticipant);
registry.registerDiagnosticsParticipant(diagnosticsParticipant);
registry.registerCodeLensParticipant(codeLensParticipant);
// register file path support for XML catalog
FilePathPlugin.registerFilePathExpressionProvider(new CatalogFilePathExpressionProvider(), registry);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*******************************************************************************
* Copyright (c) 2019 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lemminx.extensions.filepath;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.extensions.filepath.participants.FilePathCompletionParticipant;
import org.eclipse.lemminx.extensions.filepath.settings.FilePathExpression;
import org.eclipse.lemminx.extensions.filepath.settings.FilePathMapping;
import org.eclipse.lemminx.extensions.filepath.settings.FilePathSupportSettings;
import org.eclipse.lemminx.services.extensions.IXMLExtension;
import org.eclipse.lemminx.services.extensions.XMLExtensionsRegistry;
import org.eclipse.lemminx.services.extensions.save.ISaveContext;
import org.eclipse.lsp4j.InitializeParams;

/**
* FilePathPlugin
*/
public class FilePathPlugin implements IXMLExtension {

private final FilePathCompletionParticipant completionParticipant;
private FilePathSupportSettings filePathsSettings;
private XMLExtensionsRegistry registry;

private static class ContributedProviderCache extends ArrayList<IFilePathExpressionProvider> {

}

public FilePathPlugin() {
completionParticipant = new FilePathCompletionParticipant(this);
}

@Override
public void doSave(ISaveContext context) {
if (context.getType() != ISaveContext.SaveContextType.DOCUMENT) {
// Settings
updateSettings(context);
}
}

private void updateSettings(ISaveContext saveContext) {
Object initializationOptionsSettings = saveContext.getSettings();
FilePathSupportSettings settings = FilePathSupportSettings
.getFilePathsSettings(initializationOptionsSettings);
updateSettings(settings, saveContext);
}

private void updateSettings(FilePathSupportSettings settings, ISaveContext context) {
this.filePathsSettings = settings;
}

@Override
public void start(InitializeParams params, XMLExtensionsRegistry registry) {
this.registry = registry;
registry.registerCompletionParticipant(completionParticipant);
}

@Override
public void stop(XMLExtensionsRegistry registry) {
registry.unregisterCompletionParticipant(completionParticipant);
}

public FilePathSupportSettings getFilePathsSettings() {
return filePathsSettings;
}

/**
* Return the list of {@link FilePathExpression} for the given document and an
* empty list otherwise.
*
* @param xmlDocument the DOM document
*
* @return the list of {@link FilePathExpression} for the given document and an
* empty list otherwise.
*/
public List<IFilePathExpression> findFilePathExpressions(DOMDocument xmlDocument) {
List<IFilePathExpression> expressions = new ArrayList<>();
fillFromContribution(xmlDocument, expressions);
fillFromUserSettings(xmlDocument, expressions);
return expressions;
}

private void fillFromContribution(DOMDocument xmlDocument, List<IFilePathExpression> expressions) {
ContributedProviderCache cache = registry.getComponent(ContributedProviderCache.class);
if (cache != null) {
for (IFilePathExpressionProvider provider : cache) {
List<IFilePathExpression> providerExpressions = provider.getExpressions(xmlDocument);
if (providerExpressions != null && !providerExpressions.isEmpty()) {
expressions.addAll(providerExpressions);
}
}
}
}

private void fillFromUserSettings(DOMDocument xmlDocument, List<IFilePathExpression> expressions) {
FilePathSupportSettings settings = getFilePathsSettings();
if (settings == null) {
return;
}

List<FilePathMapping> mappings = settings.getFilePathMappings();
fillFromMappings(xmlDocument, mappings, expressions);
}

private static void fillFromMappings(DOMDocument xmlDocument, List<FilePathMapping> mappings,
List<IFilePathExpression> expressions) {
if (mappings == null) {
return;
}

for (FilePathMapping filePaths : mappings) {
if (filePaths.matches(xmlDocument.getDocumentURI())) {
expressions.addAll(filePaths.getExpressions());
}
}
}

public static void registerFilePathExpressionProvider(IFilePathExpressionProvider provider,
XMLExtensionsRegistry registry) {
ContributedProviderCache cache = registry.getComponent(ContributedProviderCache.class);
if (cache == null) {
cache = new ContributedProviderCache();
registry.registerComponent(cache);
}
cache.add(provider);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.eclipse.lemminx.extensions.filepath;

import org.w3c.dom.Node;

public interface IFilePathExpression {

boolean match(Node node);

Character getSeparator();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.eclipse.lemminx.extensions.filepath;

import java.util.List;

import org.eclipse.lemminx.dom.DOMDocument;

public interface IFilePathExpressionProvider {

List<IFilePathExpression> getExpressions(DOMDocument document);
}
Loading

0 comments on commit d7408ca

Please sign in to comment.