Skip to content

Commit

Permalink
DTD hover/completion support for documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Seiphon committed Nov 6, 2019
1 parent 6e8d4f1 commit 503bf4e
Show file tree
Hide file tree
Showing 6 changed files with 982 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;

import org.apache.xerces.impl.dtd.XMLAttributeDecl;
import org.apache.xerces.impl.dtd.XMLSimpleType;
Expand All @@ -24,6 +25,15 @@
*/
public class CMDTDAttributeDeclaration extends XMLAttributeDecl implements CMAttributeDeclaration {

private String documentation;
private final CMDTDDocument document;
private CMDTDElementDeclaration elementDecl;

public CMDTDAttributeDeclaration(CMDTDDocument document, CMDTDElementDeclaration elementDecl) {
this.document = document;
this.elementDecl = elementDecl;
}

@Override
public String getName() {
return super.name.localpart;
Expand All @@ -45,7 +55,14 @@ public Collection<String> getEnumerationValues() {

@Override
public String getDocumentation() {
return null;
if (documentation != null) {
return documentation;
}
Map<String, String> commentsMap = document.getCommentsMap();
if (commentsMap != null) {
documentation = commentsMap.get(elementDecl.getName() + ":" + getName());
}
return documentation;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.xerces.impl.dtd.DTDGrammar;
import org.apache.xerces.impl.dtd.XMLDTDLoader;
import org.apache.xerces.xni.Augmentations;
import org.apache.xerces.xni.XMLString;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.grammars.Grammar;
import org.apache.xerces.xni.parser.XMLInputSource;
Expand Down Expand Up @@ -50,6 +51,8 @@ public class CMDTDDocument extends XMLDTDLoader implements CMDocument {
private DTDGrammar grammar;
private Set<String> hierarchies;
private FilesChangedTracker tracker;
private Map<String, String> commentsMap;
private String comment;

public CMDTDDocument() {
this(null);
Expand Down Expand Up @@ -124,6 +127,12 @@ public void startContentModel(String elementName, Augmentations augs) throws XNI
if (hierarchiesMap == null) {
hierarchiesMap = new HashMap<>();
}
if (commentsMap == null) {
commentsMap = new HashMap<>();
}
if (comment != null) {
commentsMap.put(elementName, comment);
}
hierarchies = new LinkedHashSet<String>();
hierarchiesMap.put(elementName, hierarchies);
super.startContentModel(elementName, augs);
Expand All @@ -137,10 +146,36 @@ public void element(String elementName, Augmentations augs) throws XNIException

@Override
public void endContentModel(Augmentations augs) throws XNIException {
comment = null;
hierarchies = null;
super.endContentModel(augs);
}

@Override
public void startAttlist(String elementName, Augmentations augs) throws XNIException {
if (commentsMap == null) {
commentsMap = new HashMap<>();
}
super.startAttlist(elementName, augs);
}

@Override
public void attributeDecl(String elementName, String attributeName, String type, String[] enumeration,
String defaultType, XMLString defaultValue, XMLString nonNormalizedDefaultValue, Augmentations augs)
throws XNIException {
if (comment != null) {
commentsMap.put(elementName + ":" + attributeName, comment);
}
super.attributeDecl(elementName, attributeName, type, enumeration, defaultType, defaultValue, nonNormalizedDefaultValue,
augs);
}

@Override
public void endAttlist(Augmentations augs) throws XNIException {
comment = null;
super.endAttlist(augs);
}

@Override
public Grammar loadGrammar(XMLInputSource source) throws IOException, XNIException {
grammar = (DTDGrammar) super.loadGrammar(source);
Expand All @@ -164,6 +199,18 @@ public void loadInternalDTD(String internalSubset, String baseSystemId, String s
fDTDScanner.scanDTDInternalSubset(true, false, systemId != null);
}

@Override
public void comment(XMLString text, Augmentations augs) throws XNIException {
if (text != null) {
comment = text.toString();
}
super.comment(text, augs);
}

public Map<String, String> getCommentsMap() {
return commentsMap;
}

void collectElementsDeclaration(String elementName, List<CMElementDeclaration> elements) {
if (hierarchiesMap == null) {
return;
Expand All @@ -184,7 +231,7 @@ void collectAttributesDeclaration(CMDTDElementDeclaration elementDecl, List<CMAt
int elementDeclIndex = grammar.getElementDeclIndex(elementDecl.name);
int index = grammar.getFirstAttributeDeclIndex(elementDeclIndex);
while (index != -1) {
CMDTDAttributeDeclaration attributeDecl = new CMDTDAttributeDeclaration();
CMDTDAttributeDeclaration attributeDecl = new CMDTDAttributeDeclaration(this, elementDecl);
grammar.getAttributeDecl(index, attributeDecl);
attributes.add(attributeDecl);
index = grammar.getNextAttributeDeclIndex(index);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.xerces.impl.dtd.XMLElementDecl;
import org.eclipse.lsp4xml.dom.DOMElement;
Expand All @@ -29,6 +30,7 @@ public class CMDTDElementDeclaration extends XMLElementDecl implements CMElement
private final CMDTDDocument document;
private List<CMElementDeclaration> elements;
private List<CMAttributeDeclaration> attributes;
private String documentation;

public CMDTDElementDeclaration(CMDTDDocument document, int index) {
this.document = document;
Expand Down Expand Up @@ -91,7 +93,14 @@ public CMAttributeDeclaration findCMAttribute(String attributeName) {

@Override
public String getDocumentation() {
return null;
if (documentation != null) {
return documentation;
}
Map<String, String> commentsMap = document.getCommentsMap();
if (commentsMap != null) {
documentation = commentsMap.get(getName());
}
return documentation;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ public void testCompletionDocumentationWithSource() throws BadLocationException
" \"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd\">\r\n" + //
"\r\n" + //
" <|";
testCompletionFor(xml, c("catalog", te(5, 2, 5, 3, "<catalog>$1</catalog>$0"), "<catalog", "Source: catalog.dtd", MarkupKind.PLAINTEXT));
testCompletionFor(xml, c("catalog", te(5, 2, 5, 3, "<catalog>$1</catalog>$0"), "<catalog", " $Id: catalog.dtd,v 1.10 2002/10/18 23:54:58 ndw Exp $ "
+
System.lineSeparator() +
System.lineSeparator() + "Source: catalog.dtd", MarkupKind.PLAINTEXT));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Copyright (c) 2018 Angelo ZERR and Liferay Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Angelo Zerr <[email protected]> - initial API and implementation
* Seiphon Wang <[email protected]>
*/
package org.eclipse.lsp4xml.extensions.contentmodel;

import org.apache.xerces.util.URI.MalformedURIException;
import org.eclipse.lsp4xml.XMLAssert;
import org.eclipse.lsp4xml.commons.BadLocationException;
import org.eclipse.lsp4xml.services.XMLLanguageService;
import org.junit.Test;

public class DTDHoverExtensionsTest {

@Test
public void testTagHover() throws BadLocationException, MalformedURIException {
String xml = "<?xml version=\"1.0\"?>\r\n" + //
"<!DOCTYPE service-builder PUBLIC \"-//Liferay//DTD Service Builder 7.2.0//EN\" \"http://www.liferay.com/dtd/liferay-service-builder_7_2_0.dtd\">"
+ "<service-builder dependency-injector=\"ds\" package-path=\"testSB\"></servi|ce-builder>";
assertHover(xml,"The service-builder element is the root of the deployment descriptor for" + //
" a Service Builder descriptor that is used to generate services available to" +
" portlets. The Service Builder saves the developer time by generating Spring" +
" utilities, SOAP utilities, and Hibernate persistence classes to ease the" +
" development of services."
+ //
System.lineSeparator() + //
System.lineSeparator() + "Source: [liferay-service-builder_7_2_0.dtd](http://www.liferay.com/dtd/liferay-service-builder_7_2_0.dtd)",
206);
}

@Test
public void testAttributeNameHover() throws BadLocationException, MalformedURIException {
String xml = "<?xml version=\"1.0\"?>\r\n" + //
"<!DOCTYPE service-builder PUBLIC \"-//Liferay//DTD Service Builder 7.2.0//EN\" \"http://www.liferay.com/dtd/liferay-service-builder_7_2_0.dtd\">"
+ "<service-builder dependency-injector=\"ds\" pa|ckage-path=\"testSB\"></service-builder>";
assertHover(xml,
"The package-path value specifies the package of the generated code."
+ //
System.lineSeparator() + //
System.lineSeparator() + "Source: [liferay-service-builder_7_2_0.dtd](http://www.liferay.com/dtd/liferay-service-builder_7_2_0.dtd)",
null);
}

private static void assertHover(String value, String expectedHoverLabel, Integer expectedHoverOffset)
throws BadLocationException {
XMLAssert.assertHover(new XMLLanguageService(), value, "src/test/resources/catalogs/service.xml", null,
expectedHoverLabel, expectedHoverOffset);
}

}
Loading

0 comments on commit 503bf4e

Please sign in to comment.