From 6f50788a456c50563b2f4e6742d240d6f31093dd Mon Sep 17 00:00:00 2001 From: angelozerr Date: Fri, 19 Oct 2018 16:13:57 +0200 Subject: [PATCH] Use file temp to download XML Schema, DTD + add warning message when validation is done and XML Schema is downloading (see #159) --- .../lsp4xml/XMLTextDocumentService.java | 28 ++++- .../model/ContentModelManager.java | 6 +- .../ContentModelCompletionParticipant.java | 10 +- .../ContentModelHoverParticipant.java | 8 +- .../diagnostics/XMLValidator.java | 6 +- .../XMLCacheResolverExtension.java | 30 +++++- .../CacheResourceDownloadingException.java | 58 ++++++++++ .../CacheResourceLoadingException.java | 24 ----- .../uriresolver/CacheResourcesManager.java | 100 +++++++++++++----- .../uriresolver/URIResolverExtension.java | 10 ++ .../lsp4xml/utils/XMLPositionUtility.java | 7 +- 11 files changed, 214 insertions(+), 73 deletions(-) create mode 100644 org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/CacheResourceDownloadingException.java delete mode 100644 org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/CacheResourceLoadingException.java diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/XMLTextDocumentService.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/XMLTextDocumentService.java index bda28ebdd..94bb67b8d 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/XMLTextDocumentService.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/XMLTextDocumentService.java @@ -31,6 +31,7 @@ import org.eclipse.lsp4j.CompletionList; import org.eclipse.lsp4j.CompletionParams; import org.eclipse.lsp4j.Diagnostic; +import org.eclipse.lsp4j.DiagnosticSeverity; import org.eclipse.lsp4j.DidChangeTextDocumentParams; import org.eclipse.lsp4j.DidCloseTextDocumentParams; import org.eclipse.lsp4j.DidOpenTextDocumentParams; @@ -47,6 +48,7 @@ import org.eclipse.lsp4j.FoldingRangeRequestParams; import org.eclipse.lsp4j.Hover; import org.eclipse.lsp4j.PublishDiagnosticsParams; +import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.RenameParams; import org.eclipse.lsp4j.SymbolInformation; import org.eclipse.lsp4j.TextDocumentClientCapabilities; @@ -61,11 +63,14 @@ import org.eclipse.lsp4xml.commons.LanguageModelCache; import org.eclipse.lsp4xml.commons.TextDocument; import org.eclipse.lsp4xml.commons.TextDocuments; +import org.eclipse.lsp4xml.dom.Element; import org.eclipse.lsp4xml.dom.XMLDocument; import org.eclipse.lsp4xml.dom.XMLParser; import org.eclipse.lsp4xml.services.XMLLanguageService; import org.eclipse.lsp4xml.services.extensions.CompletionSettings; import org.eclipse.lsp4xml.settings.XMLFormattingOptions; +import org.eclipse.lsp4xml.uriresolver.CacheResourceDownloadingException; +import org.eclipse.lsp4xml.utils.XMLPositionUtility; /** * XML text document service. @@ -302,10 +307,25 @@ private void triggerValidation(String uri, int version, BasicCancelChecker monit TextDocument currDocument = getDocument(uri); if (currDocument != null && currDocument.getVersion() == version) { XMLDocument xmlDocument = getXMLDocument(currDocument); - List diagnostics = getXMLLanguageService().doDiagnostics(xmlDocument, monitor); - monitor.checkCanceled(); - xmlLanguageServer.getLanguageClient() - .publishDiagnostics(new PublishDiagnosticsParams(uri, diagnostics)); + try { + List diagnostics = getXMLLanguageService().doDiagnostics(xmlDocument, monitor); + monitor.checkCanceled(); + xmlLanguageServer.getLanguageClient() + .publishDiagnostics(new PublishDiagnosticsParams(uri, diagnostics)); + } catch (CacheResourceDownloadingException e) { + // An XML Schema, DTD is downloading with cache, but it takes too time. In this + // case: + // - 1) we add a warning in the document element to tell that validation cannot be + // occurred because an XML Schema/DTD is downloading. + Element documentElement = xmlDocument.getDocumentElement(); + Range range = XMLPositionUtility.selectStartTag(documentElement); + List diagnostics = new ArrayList<>(); + diagnostics.add(new Diagnostic(range, e.getMessage(), DiagnosticSeverity.Warning, "XML")); + xmlLanguageServer.getLanguageClient() + .publishDiagnostics(new PublishDiagnosticsParams(uri, diagnostics)); + // - 2) we restart the validation only when the XML Schema, DTD is downloaded. + e.getFuture().thenAccept((path) -> triggerValidation(uri, version, monitor)); + } } }, 500, TimeUnit.MILLISECONDS); } diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/model/ContentModelManager.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/model/ContentModelManager.java index 6ab7a411c..7d5a2b670 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/model/ContentModelManager.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/model/ContentModelManager.java @@ -29,7 +29,7 @@ import org.eclipse.lsp4xml.extensions.contentmodel.uriresolver.XMLCatalogResolverExtension; import org.eclipse.lsp4xml.extensions.contentmodel.uriresolver.XMLFileAssociationResolverExtension; import org.eclipse.lsp4xml.extensions.contentmodel.xsd.XSDDocument; -import org.eclipse.lsp4xml.uriresolver.CacheResourceLoadingException; +import org.eclipse.lsp4xml.uriresolver.CacheResourceDownloadingException; import org.eclipse.lsp4xml.uriresolver.URIResolverExtensionManager; import org.w3c.dom.DOMError; import org.w3c.dom.DOMErrorHandler; @@ -63,8 +63,8 @@ public ContentModelManager() { @Override public boolean handleError(DOMError error) { - if (error.getRelatedException() instanceof CacheResourceLoadingException) { - throw ((CacheResourceLoadingException) error.getRelatedException()); + if (error.getRelatedException() instanceof CacheResourceDownloadingException) { + throw ((CacheResourceDownloadingException) error.getRelatedException()); } return false; } diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/ContentModelCompletionParticipant.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/ContentModelCompletionParticipant.java index 073312e0b..ac600d089 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/ContentModelCompletionParticipant.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/ContentModelCompletionParticipant.java @@ -27,7 +27,7 @@ import org.eclipse.lsp4xml.services.extensions.CompletionParticipantAdapter; import org.eclipse.lsp4xml.services.extensions.ICompletionRequest; import org.eclipse.lsp4xml.services.extensions.ICompletionResponse; -import org.eclipse.lsp4xml.uriresolver.CacheResourceLoadingException; +import org.eclipse.lsp4xml.uriresolver.CacheResourceDownloadingException; /** * Extension to support XML completion based on content model (XML Schema @@ -70,7 +70,7 @@ public void onTagOpen(ICompletionRequest request, ICompletionResponse response) } } } - } catch (CacheResourceLoadingException e) { + } catch (CacheResourceDownloadingException e) { addCacheWarningItem(e, response); } } @@ -146,7 +146,7 @@ public void onAttributeName(boolean generateValue, Range fullRange, ICompletionR } } } - } catch (CacheResourceLoadingException e) { + } catch (CacheResourceDownloadingException e) { addCacheWarningItem(e, response); } } @@ -172,12 +172,12 @@ public void onAttributeValue(String valuePrefix, Range fullRange, boolean addQuo }); } } - } catch (CacheResourceLoadingException e) { + } catch (CacheResourceDownloadingException e) { addCacheWarningItem(e, response); } } - private void addCacheWarningItem(CacheResourceLoadingException e, ICompletionResponse response) { + private void addCacheWarningItem(CacheResourceDownloadingException e, ICompletionResponse response) { // Here cache is enabled and some XML Schema, DTD, etc are loading CompletionItem item = new CompletionItem( "Cannot process " + (e.isDTD() ? "DTD" : "XML Schema") + " completion: " + e.getMessage()); diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/ContentModelHoverParticipant.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/ContentModelHoverParticipant.java index 74e0b7edb..0bcec045a 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/ContentModelHoverParticipant.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/ContentModelHoverParticipant.java @@ -20,7 +20,7 @@ import org.eclipse.lsp4xml.extensions.contentmodel.model.ContentModelManager; import org.eclipse.lsp4xml.services.extensions.HoverParticipantAdapter; import org.eclipse.lsp4xml.services.extensions.IHoverRequest; -import org.eclipse.lsp4xml.uriresolver.CacheResourceLoadingException; +import org.eclipse.lsp4xml.uriresolver.CacheResourceDownloadingException; /** * Extension to support XML hover based on content model (XML Schema completion, @@ -42,7 +42,7 @@ public Hover onTag(IHoverRequest hoverRequest) throws Exception { return new Hover(content, hoverRequest.getTagRange()); } } - } catch (CacheResourceLoadingException e) { + } catch (CacheResourceDownloadingException e) { return getCacheWarningHover(e); } return null; @@ -67,13 +67,13 @@ public Hover onAttributeName(IHoverRequest hoverRequest) throws Exception { } } } - } catch (CacheResourceLoadingException e) { + } catch (CacheResourceDownloadingException e) { return getCacheWarningHover(e); } return null; } - private Hover getCacheWarningHover(CacheResourceLoadingException e) { + private Hover getCacheWarningHover(CacheResourceDownloadingException e) { // Here cache is enabled and some XML Schema, DTD, etc are loading MarkupContent content = new MarkupContent(); content.setKind(MarkupKind.PLAINTEXT); diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/diagnostics/XMLValidator.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/diagnostics/XMLValidator.java index 4713fcdef..10583be56 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/diagnostics/XMLValidator.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/diagnostics/XMLValidator.java @@ -27,7 +27,7 @@ import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.jsonrpc.CancelChecker; import org.eclipse.lsp4xml.dom.XMLDocument; -import org.eclipse.lsp4xml.uriresolver.CacheResourceLoadingException; +import org.eclipse.lsp4xml.uriresolver.CacheResourceDownloadingException; import org.eclipse.lsp4xml.uriresolver.IExternalSchemaLocationProvider; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -79,8 +79,10 @@ public static void doDiagnostics(XMLDocument document, XMLEntityResolver entityR inputSource.setSystemId(uri); reader.parse(inputSource); - } catch (IOException | SAXException | CancellationException | CacheResourceLoadingException exception) { + } catch (IOException | SAXException | CancellationException exception) { // ignore error + } catch(CacheResourceDownloadingException e) { + throw e; } catch (Exception e) { LOGGER.log(Level.SEVERE, "Unexpected XMLValidator error", e); } diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/uriresolver/XMLCacheResolverExtension.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/uriresolver/XMLCacheResolverExtension.java index 71a761e6c..83d42619c 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/uriresolver/XMLCacheResolverExtension.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/uriresolver/XMLCacheResolverExtension.java @@ -1,3 +1,13 @@ +/** + * Copyright (c) 2018 Angelo ZERR + * 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: + * Angelo Zerr - initial API and implementation + */ package org.eclipse.lsp4xml.extensions.contentmodel.uriresolver; import java.io.IOException; @@ -10,19 +20,32 @@ import org.eclipse.lsp4xml.uriresolver.CacheResourcesManager; import org.eclipse.lsp4xml.uriresolver.URIResolverExtension; +/** + * URI resolver which download the first time the XML Schema, DTD from "http" or + * "ftp" in the file system. The second time, teh downloaded file is used + * instead of accessing from "http" or "ftp". This cache improves drastically + * the performance of some XML Schema (ex: xml.xsd) + * + */ public class XMLCacheResolverExtension implements URIResolverExtension { @Override public String resolve(String baseLocation, String publicId, String systemId) { + // Don't resolve the URI return null; } @Override public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) throws XNIException, IOException { String url = resourceIdentifier.getExpandedSystemId(); + // Cache is used only for resource coming from "http" or "ftp". if (CacheResourcesManager.getInstance().canUseCache(url)) { - Path file = CacheResourcesManager.getInstance().getResources(url); + // Try to get the downloaded resource. In the case of the resource is + // downloading and takes so many time, + // the exception CacheResourceDownloadingException is thrown. + Path file = CacheResourcesManager.getInstance().getResource(url); if (file != null) { + // The resource is downloaded in the file system, use it. XMLInputSource source = new XMLInputSource(resourceIdentifier); source.setByteStream(Files.newInputStream(file)); return source; @@ -31,6 +54,11 @@ public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) th return null; } + /** + * Set true if cache must be used and false otherwise. + * + * @param useCache true if cache must be used and false otherwise. + */ public void setUseCache(boolean useCache) { CacheResourcesManager.getInstance().setUseCache(useCache); } diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/CacheResourceDownloadingException.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/CacheResourceDownloadingException.java new file mode 100644 index 000000000..a1ef8c55d --- /dev/null +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/CacheResourceDownloadingException.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2018 Angelo ZERR + * 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: + * Angelo Zerr - initial API and implementation + */ +package org.eclipse.lsp4xml.uriresolver; + +import java.nio.file.Path; +import java.text.MessageFormat; +import java.util.concurrent.CompletableFuture; + +/** + * Exception thrown when a resource (XML Schema, DTD) is downloading. + * + */ +public class CacheResourceDownloadingException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + private static final String RESOURCE_LOADING_MSG = "The resource ''{0}'' is downloading."; + + private final String resourceURI; + + private final CompletableFuture future; + + public CacheResourceDownloadingException(String resourceURI, CompletableFuture future) { + super(MessageFormat.format(RESOURCE_LOADING_MSG, resourceURI)); + this.resourceURI = resourceURI; + this.future = future; + } + + /** + * Returns the resource URI which is downloading. + * + * @return the resource URI which is downloading. + */ + public String getResourceURI() { + return resourceURI; + } + + /** + * Returns true if it's a DTD which id downloading and false otherwise. + * + * @return true if it's a DTD which id downloading and false otherwise. + */ + public boolean isDTD() { + return resourceURI != null && resourceURI.endsWith(".dtd"); + } + + public CompletableFuture getFuture() { + return future; + } +} diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/CacheResourceLoadingException.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/CacheResourceLoadingException.java deleted file mode 100644 index adb627e0e..000000000 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/CacheResourceLoadingException.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.eclipse.lsp4xml.uriresolver; - -import java.text.MessageFormat; - -public class CacheResourceLoadingException extends RuntimeException { - - private static final String RESOURCE_LOADING_MSG = "The resource ''{0}'' is loading."; - - private final String resourceURI; - - public CacheResourceLoadingException(String resourceURI) { - super(MessageFormat.format(RESOURCE_LOADING_MSG, resourceURI)); - this.resourceURI = resourceURI; - } - - public String getResourceURI() { - return resourceURI; - } - - public boolean isDTD() { - return resourceURI != null && resourceURI.endsWith(".dtd"); - } - -} diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/CacheResourcesManager.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/CacheResourcesManager.java index 739248dbf..ffc6fda5c 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/CacheResourcesManager.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/CacheResourcesManager.java @@ -1,3 +1,13 @@ +/** + * Copyright (c) 2018 Angelo ZERR + * 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: + * Angelo Zerr - initial API and implementation + */ package org.eclipse.lsp4xml.uriresolver; import java.io.FileOutputStream; @@ -11,12 +21,16 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.CompletableFuture; import org.eclipse.lsp4xml.utils.FilesUtils; +/** + * Cache resources manager. + * + */ public class CacheResourcesManager { private static final CacheResourcesManager INSTANCE = new CacheResourcesManager(); @@ -25,26 +39,45 @@ public static CacheResourcesManager getInstance() { return INSTANCE; } - private final List resourcesLoading; + private final Map> resourcesLoading; private boolean useCache; + class ResourceInfo { + + String resourceURI; + + CompletableFuture future; + + } + private CacheResourcesManager() { - resourcesLoading = new ArrayList<>(); + resourcesLoading = new HashMap<>(); } - public Path getResources(final String resourceURI) throws IOException { + public Path getResource(final String resourceURI) throws IOException { Path resourceCachePath = getResourceCachePath(resourceURI); if (Files.exists(resourceCachePath)) { return resourceCachePath; } + CompletableFuture f = null; synchronized (resourcesLoading) { - if (resourcesLoading.contains(resourceURI)) { - throw new CacheResourceLoadingException(resourceURI); + if (resourcesLoading.containsKey(resourceURI)) { + CompletableFuture future = resourcesLoading.get(resourceURI); + throw new CacheResourceDownloadingException(resourceURI, future); } - resourcesLoading.add(resourceURI); + f = downloadResource(resourceURI, resourceCachePath); + resourcesLoading.put(resourceURI, f); } - CompletableFuture f = CompletableFuture.supplyAsync(() -> { + if (f.getNow(null) == null) { + throw new CacheResourceDownloadingException(resourceURI, f); + } + + return resourceCachePath; + } + + private CompletableFuture downloadResource(final String resourceURI, Path resourceCachePath) { + return CompletableFuture.supplyAsync(() -> { URLConnection conn = null; try { String actualURI = resourceURI; @@ -59,37 +92,32 @@ public Path getResources(final String resourceURI) throws IOException { conn = url.openConnection(); } + // Download resource in a temporary file + Path path = Files.createTempFile(resourceCachePath.getFileName().toString(), ".lsp4xml"); + try (ReadableByteChannel rbc = Channels.newChannel(conn.getInputStream()); + FileOutputStream fos = new FileOutputStream(path.toFile())) { + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + } + + // Move the temporary file in the lsp4xml cache folder. Path dir = resourceCachePath.getParent(); if (!Files.exists(dir)) { Files.createDirectories(dir); } - - ReadableByteChannel rbc = Channels.newChannel(conn.getInputStream()); - FileOutputStream fos = new FileOutputStream(resourceCachePath.toFile()); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - synchronized (resourcesLoading) { - resourcesLoading.remove(resourceURI); - } - + Files.move(path, resourceCachePath); } catch (Exception e) { + // Do nothing + return null; + } finally { synchronized (resourcesLoading) { resourcesLoading.remove(resourceURI); } - } finally { if (conn != null && conn instanceof HttpURLConnection) { ((HttpURLConnection) conn).disconnect(); } } - return ""; + return resourceCachePath; }); - - if (f.getNow(null) == null) { - throw new CacheResourceLoadingException(resourceURI); - } - - return resourceCachePath; } private static Path getResourceCachePath(String resourceURI) throws IOException { @@ -98,14 +126,32 @@ private static Path getResourceCachePath(String resourceURI) throws IOException return FilesUtils.getDeployedPath(resourceCachePath); } + /** + * Returns true if cache is enabled and url comes from "http" or "ftp" and false + * otherwise. + * + * @param url + * @return true if cache is enabled and url comes from "http" or "ftp" and false + * otherwise. + */ public boolean canUseCache(String url) { return isUseCache() && url != null && (url.startsWith("http:") || url.startsWith("ftp:")); } + /** + * Set true if cache must be used and false otherwise. + * + * @param useCache true if cache must be used and false otherwise. + */ public void setUseCache(boolean useCache) { this.useCache = useCache; } + /** + * Returns true if cache must be used and false otherwise. + * + * @return true if cache must be used and false otherwise. + */ public boolean isUseCache() { return useCache; } diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/URIResolverExtension.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/URIResolverExtension.java index c89e563a4..bbbe49b17 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/URIResolverExtension.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/uriresolver/URIResolverExtension.java @@ -1,3 +1,13 @@ +/** + * Copyright (c) 2018 Angelo ZERR + * 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: + * Angelo Zerr - initial API and implementation + */ package org.eclipse.lsp4xml.uriresolver; import java.io.IOException; diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/utils/XMLPositionUtility.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/utils/XMLPositionUtility.java index 193ed0556..5e0cfce7d 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/utils/XMLPositionUtility.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/utils/XMLPositionUtility.java @@ -174,12 +174,12 @@ static Node findChildNode(String childTag, List children) { public static Range selectStartTag(int offset, XMLDocument document) { Node element = document.findNodeAt(offset); if (element != null) { - return selectStartTag(element, document); + return selectStartTag(element); } return null; } - private static Range selectStartTag(Node element, XMLDocument document) { + public static Range selectStartTag(Node element) { int startOffset = element.getStart() + 1; // < int endOffset = startOffset + getStartTagLength(element); if (element.isProcessingInstruction() || element.isProlog()) { @@ -188,6 +188,7 @@ private static Range selectStartTag(Node element, XMLDocument document) { // increment end offset to select '?xml' instead of selecting '?xm' endOffset++; } + XMLDocument document = element.getOwnerDocument(); return createRange(startOffset, endOffset, document); } @@ -324,7 +325,7 @@ public static Range selectText(int offset, XMLDocument document) { } } else if (node.isElement()) { // node has NONE text (ex: , select the start tag - return selectStartTag(node, document); + return selectStartTag(node); } } return null;