Skip to content

Commit

Permalink
Support XML Schema substitutionGroup for completion to fix #165
Browse files Browse the repository at this point in the history
  • Loading branch information
angelozerr committed Oct 19, 2018
1 parent 9dd46ab commit 728f6e0
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.apache.xerces.xs.XSElementDeclaration;
import org.apache.xerces.xs.XSModel;
import org.apache.xerces.xs.XSNamedMap;
import org.apache.xerces.xs.XSObject;
import org.apache.xerces.xs.XSObjectList;
import org.apache.xerces.xs.XSSimpleTypeDefinition;
import org.eclipse.lsp4xml.dom.Element;
import org.eclipse.lsp4xml.extensions.contentmodel.model.CMDocument;
Expand All @@ -47,21 +49,49 @@ public XSDDocument(XSModel model) {

@Override
public Collection<CMElementDeclaration> getElements() {
elements = null;
if (elements == null) {
elements = new ArrayList<>();
XSNamedMap map = model.getComponents(XSConstants.ELEMENT_DECLARATION);
for (int j = 0; j < map.getLength(); j++) {
XSElementDeclaration elementDeclaration = (XSElementDeclaration) map.item(j);
CMElementDeclaration cmElement = getXSDElement(elementDeclaration);
// check element declaration is not already added (ex: xs:annotation)
if (!elements.contains(cmElement)) {
elements.add(cmElement);
}
collectElement(elementDeclaration, elements);
}
}
return elements;
}

/**
* Fill the given elements list from the given Xerces elementDeclaration
*
* @param elementDeclaration
* @param elements
*/
void collectElement(XSElementDeclaration elementDeclaration, Collection<CMElementDeclaration> elements) {
if (elementDeclaration.getAbstract()) {
// element declaration is marked as abstract
// ex with xsl: <xs:element name="declaration" type="xsl:generic-element-type" abstract="true"/>
XSObjectList list = model.getSubstitutionGroup(elementDeclaration);
if (list != null) {
// it exists elements list bind with this abstract declaration with substitutionGroup
// ex xsl : <xs:element name="template" substitutionGroup="xsl:declaration">
for (int i = 0; i < list.getLength(); i++) {
XSObject object = list.item(i);
if (object.getType() == XSConstants.ELEMENT_DECLARATION) {
XSElementDeclaration subElementDeclaration = (XSElementDeclaration) object;
collectElement(subElementDeclaration, elements);
}
}
}
} else {
CMElementDeclaration cmElement = getXSDElement(elementDeclaration);
// check element declaration is not already added (ex: xs:annotation)
if (!elements.contains(cmElement)) {
elements.add(cmElement);
}
}
}

@Override
public CMElementDeclaration findCMElement(Element node, String namespace) {
List<Element> paths = new ArrayList<>();
Expand Down Expand Up @@ -102,7 +132,7 @@ CMElementDeclaration getXSDElement(XSElementDeclaration elementDeclaration) {
}
return element;
}

static Collection<String> getEnumerationValues(XSSimpleTypeDefinition typeDefinition) {
if (typeDefinition != null) {
if (isBooleanType(typeDefinition)) {
Expand All @@ -118,7 +148,7 @@ static Collection<String> getEnumerationValues(XSSimpleTypeDefinition typeDefini
}
return Collections.emptyList();
}

static boolean isBooleanType(XSSimpleTypeDefinition typeDefinition) {
if (typeDefinition instanceof XSSimpleType) {
return ((XSSimpleType) typeDefinition).getPrimitiveKind() == XSSimpleType.PRIMITIVE_BOOLEAN;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ private void collectAttributesDeclaration(XSComplexTypeDefinition typeDefinition

@Override
public Collection<CMElementDeclaration> getElements() {
elements = null;
if (elements == null) {
elements = new ArrayList<>();
collectElementsDeclaration(elementDeclaration, elements);
Expand Down Expand Up @@ -158,11 +159,7 @@ private void collectElementsDeclaration(XSTerm term, Collection<CMElementDeclara
break;
case XSConstants.ELEMENT_DECLARATION:
XSElementDeclaration elementDeclaration = (XSElementDeclaration) term;
CMElementDeclaration cmElement = document.getXSDElement(elementDeclaration);
// check element declaration is not already added (ex: xs:annotation)
if (!elements.contains(cmElement)) {
elements.add(cmElement);
}
document.collectElement(elementDeclaration, elements);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ public void completion() throws BadLocationException {
"<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\r\n" + //
"|";
testCompletionFor(xml,
c("xsl:declaration", te(2, 0, 2, 0, "<xsl:declaration></xsl:declaration>"), "xsl:declaration"), //
c("xsl:import", te(2, 0, 2, 0, "<xsl:import href=\"\" />"), "xsl:import"));
c("xsl:template", te(2, 0, 2, 0, "<xsl:template></xsl:template>"), "xsl:template"), // <-- coming from substition group of xsl:declaration
c("xsl:output", te(2, 0, 2, 0, "<xsl:output></xsl:output>"), "xsl:output"), // <-- coming from substition group of xsl:declaration
c("xsl:import", te(2, 0, 2, 0, "<xsl:import href=\"\" />"), "xsl:import")); // coming from stylesheet children
}

private void testCompletionFor(String xml, CompletionItem... expectedItems) throws BadLocationException {
Expand Down

0 comments on commit 728f6e0

Please sign in to comment.