Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The 'uri' attribute in all the catalog entries that have it is now a document link. Closes #220 Signed-off-by: David Thompson <davthomp@redhat.com>
- Loading branch information
1 parent
2aad97f
commit c8d8382
Showing
4 changed files
with
267 additions
and
2 deletions.
There are no files selected for viewing
86 changes: 86 additions & 0 deletions
86
org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/CatalogUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2020 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 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.lemminx.extensions.catalog; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
import org.eclipse.lemminx.dom.DOMAttr; | ||
import org.eclipse.lemminx.dom.DOMDocument; | ||
import org.eclipse.lemminx.dom.DOMElement; | ||
import org.eclipse.lemminx.dom.DOMNode; | ||
import org.eclipse.lemminx.utils.DOMUtils; | ||
|
||
/** | ||
* Utility functions for working with XML catalog documents | ||
*/ | ||
public class CatalogUtils { | ||
|
||
/** | ||
* The catalog entries that have a 'uri' attribute | ||
*/ | ||
private static final Collection<String> CATALOG_NAMES = Arrays.asList("public", "system", "uri", "systemSuffix", | ||
"uriSuffix"); | ||
|
||
private static final String CATALOG_ENTITY_NAME = "catalog"; | ||
|
||
private static final String URI_ATTRIBUTE_NAME = "uri"; | ||
|
||
/** | ||
* Returns a list of all the catalog entries that have the attribute 'uri', or | ||
* an empty list if the document is not a catalog. | ||
* | ||
* @param document The document to collect the catalog entries from | ||
* @return A list of all the catalog entries that have the attribute 'uri', or | ||
* an empty list if the document is not a catalog. | ||
*/ | ||
public static List<DOMElement> getCatalogEntries(DOMDocument document) { | ||
if (!DOMUtils.isCatalog(document)) { | ||
return Collections.emptyList(); | ||
} | ||
for (DOMNode n : document.getChildren()) { | ||
if (CATALOG_ENTITY_NAME.equals(n.getNodeName())) { | ||
return n.getChildren().stream().filter(CatalogUtils::isCatalogURIEntry).map((el) -> { | ||
return (DOMElement) el; | ||
}).collect(Collectors.toList()); | ||
} | ||
} | ||
return Collections.emptyList(); | ||
} | ||
|
||
/** | ||
* Returns the uri attribute node of the given catalog entry or null if there is | ||
* no uri attribute | ||
* | ||
* @param element The catalog entry to get the uri attribute of | ||
* @return the uri attribute node of the given catalog entry or null if there is | ||
* no uri attribute | ||
*/ | ||
public static DOMAttr getCatalogEntryURI(DOMElement element) { | ||
return element.getAttributeNode(URI_ATTRIBUTE_NAME); | ||
} | ||
|
||
/** | ||
* Checks if this node is a catalog entry that is required to have the 'uri' | ||
* attribute | ||
* | ||
* @param node The node to check | ||
* @return true if this node is an catalog entry that is required to have the | ||
* 'uri' attribute and false otherwise | ||
*/ | ||
private static boolean isCatalogURIEntry(DOMNode node) { | ||
return node.isElement() && CATALOG_NAMES.contains(node.getNodeName()); | ||
} | ||
|
||
} |
67 changes: 67 additions & 0 deletions
67
...c/main/java/org/eclipse/lemminx/extensions/catalog/XMLCatalogDocumentLinkParticipant.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2020 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 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.lemminx.extensions.catalog; | ||
|
||
import java.util.List; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
import org.apache.xerces.impl.XMLEntityManager; | ||
import org.apache.xerces.util.URI.MalformedURIException; | ||
import org.eclipse.lemminx.commons.BadLocationException; | ||
import org.eclipse.lemminx.dom.DOMAttr; | ||
import org.eclipse.lemminx.dom.DOMDocument; | ||
import org.eclipse.lemminx.dom.DOMElement; | ||
import org.eclipse.lemminx.dom.DOMNode; | ||
import org.eclipse.lemminx.services.extensions.IDocumentLinkParticipant; | ||
import org.eclipse.lemminx.utils.FilesUtils; | ||
import org.eclipse.lemminx.utils.XMLPositionUtility; | ||
import org.eclipse.lsp4j.DocumentLink; | ||
|
||
/** | ||
* Document links that are specific to catalogs | ||
*/ | ||
public class XMLCatalogDocumentLinkParticipant implements IDocumentLinkParticipant { | ||
|
||
private static Logger LOGGER = Logger.getLogger(XMLCatalogDocumentLinkParticipant.class.getName()); | ||
|
||
@Override | ||
public void findDocumentLinks(DOMDocument document, List<DocumentLink> links) { | ||
for (DOMElement entry : CatalogUtils.getCatalogEntries(document)) { | ||
DOMAttr catalogReference = CatalogUtils.getCatalogEntryURI(entry); | ||
DOMNode valueLocation = catalogReference.getNodeAttrValue(); | ||
try { | ||
String path = getResolvedLocation(FilesUtils.removeFileScheme(document.getDocumentURI()), | ||
catalogReference.getValue()); | ||
links.add(XMLPositionUtility.createDocumentLink(valueLocation, path, true)); | ||
} catch (BadLocationException e) { | ||
LOGGER.log(Level.SEVERE, "Creation of document link failed", e); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Returns the expanded system location | ||
* | ||
* @return the expanded system location | ||
*/ | ||
private static String getResolvedLocation(String documentURI, String location) { | ||
if (location == null) { | ||
return null; | ||
} | ||
try { | ||
return XMLEntityManager.expandSystemId(location, documentURI, false); | ||
} catch (MalformedURIException e) { | ||
return location; | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
...minx/src/test/java/org/eclipse/lemminx/extensions/catalog/XMLCatalogDocumentLinkTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2020 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 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.lemminx.extensions.catalog; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.eclipse.lemminx.XMLAssert.testDocumentLinkFor; | ||
import static org.eclipse.lemminx.XMLAssert.dl; | ||
import static org.eclipse.lemminx.XMLAssert.r; | ||
|
||
/** | ||
* Tests for the document links in XML catalog files | ||
*/ | ||
public class XMLCatalogDocumentLinkTest { | ||
|
||
private static String CATALOG_PATH = "src/test/resources/catalog.xml"; | ||
|
||
@Test | ||
public void testPublicEntryDocumentLink() { | ||
String xml = "<catalog xmlns=\"urn:oasis:names:tc:entity:xmlns:xml:catalog\">\n" + // | ||
" <public id=\"http://example.org\" uri=\"mySchema.xsd\" />\n" + // | ||
"</catalog>"; | ||
testDocumentLinkFor(xml, CATALOG_PATH, // | ||
dl(r(1, 39, 1, 51), "src/test/resources/mySchema.xsd")); | ||
} | ||
|
||
@Test | ||
public void testSystemEntryDocumentLink() { | ||
String xml = "<catalog xmlns=\"urn:oasis:names:tc:entity:xmlns:xml:catalog\">\n" + // | ||
" <system id=\"http://example.org\"\n" + // | ||
" uri=\"otherSchema.xsd\" />\n" + // | ||
"</catalog>"; | ||
testDocumentLinkFor(xml, CATALOG_PATH, // | ||
dl(r(2, 9, 2, 24), "src/test/resources/otherSchema.xsd")); | ||
} | ||
|
||
@Test | ||
public void testURIEntryDocumentLink() { | ||
String xml = "<catalog xmlns=\"urn:oasis:names:tc:entity:xmlns:xml:catalog\">\n" + // | ||
" <uri\n" + // | ||
" id=\"http://example.org\"\n" + // | ||
" uri=\"neatSchema.xsd\" />\n" + // | ||
"</catalog>"; | ||
testDocumentLinkFor(xml, CATALOG_PATH, // | ||
dl(r(3, 9, 3, 23), "src/test/resources/neatSchema.xsd")); | ||
} | ||
|
||
@Test | ||
public void testSystemSuffixEntryDocumentLink() { | ||
String xml = "<catalog xmlns=\"urn:oasis:names:tc:entity:xmlns:xml:catalog\">\n" + // | ||
" <systemSuffix id=\"http://example.org\" uri=\"mySchema.xsd\"></systemSuffix>\n" + // | ||
"</catalog>"; | ||
testDocumentLinkFor(xml, CATALOG_PATH, // | ||
dl(r(1, 45, 1, 57), "src/test/resources/mySchema.xsd")); | ||
} | ||
|
||
@Test | ||
public void testURISuffixEntryDocumentLink() { | ||
String xml = "<catalog xmlns=\"urn:oasis:names:tc:entity:xmlns:xml:catalog\">\n" + // | ||
" <uriSuffix id=\"http://example.org\" uri=\"mySchema.xsd\"></uriSuffix>\n" + // | ||
"</catalog>"; | ||
testDocumentLinkFor(xml, CATALOG_PATH, // | ||
dl(r(1, 42, 1, 54), "src/test/resources/mySchema.xsd")); | ||
} | ||
|
||
@Test | ||
public void testMustBeCatalog1() { | ||
String xml = "<catalog><public url=\"document.xsd\" /></catalog>"; | ||
testDocumentLinkFor(xml, CATALOG_PATH); | ||
} | ||
|
||
@Test | ||
public void testMustBeCatalog2() { | ||
String xml = "<aaa xmlns=\"urn:oasis:names:tc:entity:xmlns:xml:catalog\">\n" + // | ||
" <public url=\"document.xsd\" />\n" + // | ||
"</aaa>"; | ||
testDocumentLinkFor(xml, CATALOG_PATH); | ||
} | ||
|
||
@Test | ||
public void testOnlyEntriesHaveLinks() { | ||
String xml = "<catalog xmlns=\"urn:oasis:names:tc:entity:xmlns:xml:catalog\">\n" + // | ||
" <aaa id=\"http://example.org\" uri=\"mySchema.xsd\"></aaa>\n" + // | ||
"</catalog>"; | ||
testDocumentLinkFor(xml, CATALOG_PATH); | ||
} | ||
|
||
@Test | ||
public void testPublicEntryWithSpacesDocumentLink() { | ||
String xml = "<catalog xmlns=\"urn:oasis:names:tc:entity:xmlns:xml:catalog\">\n" + // | ||
" <public id=\"http://example.org\" uri=\"my%20schema.xsd\" />\n" + // | ||
"</catalog>"; | ||
testDocumentLinkFor(xml, CATALOG_PATH, // | ||
dl(r(1, 39, 1, 54), "src/test/resources/my schema.xsd")); | ||
} | ||
|
||
} |