diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMDocumentType.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMDocumentType.java index 4a5789dd04..79855459fb 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMDocumentType.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMDocumentType.java @@ -16,27 +16,20 @@ * A doctype node. * */ -public class DOMDocumentType extends DOMNode implements org.w3c.dom.DocumentType { +public class DOMDocumentType extends DTDDeclNode implements org.w3c.dom.DocumentType { public enum DocumentTypeKind { PUBLIC, SYSTEM, INVALID } - - // Offset values relative to start of the XML Document - Integer nameStart, nameEnd; - Integer kindStart, kindEnd; - Integer publicIdStart, publicIdEnd; - Integer systemIdStart, systemIdEnd; - Integer internalSubsetStart, internalSubsetEnd; - - private String name; - private String kind; // SYSTEM || PUBLIC - private String publicId; - private String systemId; - private String internalSubset; + DTDDeclParameter name; + DTDDeclParameter kind; // SYSTEM || PUBLIC + DTDDeclParameter publicId; + DTDDeclParameter systemId; + DTDDeclParameter internalSubset; private String content; // || + //private String unrecognizedParameters; public DOMDocumentType(int start, int end, DOMDocument ownerDocument) { super(start, end, ownerDocument); @@ -49,43 +42,30 @@ public String getContent() { return content; } - void setEnd(int end) { - this.end = end; - this.content = getOwnerDocument().getText().substring(start, end); - } - /** * The text immediately after DOCTYPE, " */ - Integer elementNameStart, elementNameEnd; - Integer attributeNameStart, attributeNameEnd; - Integer attributeTypeStart, attributeTypeEnd; - Integer attributeValueStart, attributeValueEnd; + DTDDeclParameter elementName; + DTDDeclParameter attributeName; + DTDDeclParameter attributeType; + DTDDeclParameter attributeValue; - String elementName; - String attributeName; - String attributeType; - String attributeValue; - - ArrayList internalChildren; + ArrayList internalChildren; //Holds all additional internal attlist declaractions public DTDAttlistDecl(int start, int end, DOMDocumentType parentDocumentType) { super(start, end, parentDocumentType); @@ -65,8 +60,11 @@ public String getNodeName() { * @return the element name */ public String getElementName() { - elementName = getValueFromOffsets(parentDocumentType, elementName, elementNameStart, elementNameEnd); - return elementName; + return elementName != null ? elementName.getParameter() : null; + } + + public void setElementName(int start, int end) { + elementName = addNewParameter(start, end); } /** @@ -75,18 +73,27 @@ public String getElementName() { * @return the attribute name */ public String getAttributeName() { - attributeName = getValueFromOffsets(parentDocumentType, attributeName, attributeNameStart, attributeNameEnd); - return attributeName; + return attributeName != null ? attributeName.getParameter() : null; + } + + public void setAttributeName(int start, int end) { + attributeName = addNewParameter(start, end); } public String getAttributeType() { - attributeType = getValueFromOffsets(parentDocumentType, attributeType, attributeTypeStart, attributeTypeEnd); - return attributeType; + return attributeType != null ? attributeType.getParameter() : null; + } + + public void setAttributeType(int start, int end) { + attributeType = addNewParameter(start, end); } public String getAttributeValue() { - attributeValue = getValueFromOffsets(parentDocumentType, attributeValue, attributeValueStart, attributeValueEnd); - return attributeValue; + return attributeValue != null ? attributeValue.getParameter() : null; + } + + public void setAttributeValue(int start, int end) { + attributeValue = addNewParameter(start, end); } @Override @@ -123,4 +130,9 @@ public boolean isRootAttlist() { return this.parent.isDoctype(); } + @Override + public String getDeclTypeAsString() { + return "ATTLIST"; + } + } diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDDeclNode.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDDeclNode.java index 12c3103baf..d69f1df51c 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDDeclNode.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDDeclNode.java @@ -12,6 +12,8 @@ package org.eclipse.lsp4xml.dom; +import java.util.ArrayList; + /** * DTDNode */ @@ -25,14 +27,22 @@ public class DTDDeclNode extends DOMNode{ */ protected final DOMDocumentType parentDocumentType; + protected final DOMDocument parentDocument; - Integer unrecognizedStart, unrecognizedEnd; + DTDDeclParameter unrecognized; // holds all content after parsing goes wrong in a DTD declaration (ENTITY, ATTLIST, ELEMENT). - String unrecognized; // holds all content after parsing goes wrong in a DTD declaration (ENTITY, ATTLIST, ELEMENT). + ArrayList parameters; public DTDDeclNode(int start, int end, DOMDocumentType parentDocumentType) { super(start, end, parentDocumentType != null ? parentDocumentType.getOwnerDocument() : null); this.parentDocumentType = parentDocumentType; + this.parentDocument = null; + } + + public DTDDeclNode(int start, int end, DOMDocument parentDocumentType) { + super(start, end, parentDocumentType != null ? parentDocumentType : null); + this.parentDocument = parentDocumentType; + this.parentDocumentType = null; } @Override @@ -46,8 +56,11 @@ public short getNodeType() { } public String getUnrecognized() { - unrecognized = getValueFromOffsets(parentDocumentType, unrecognized, unrecognizedStart, unrecognizedEnd); - return unrecognized; + return unrecognized.getParameter(); + } + + public void setUnrecognized(int start, int end) { + unrecognized = addNewParameter(start, end); } public static String getValueFromOffsets(DOMDocumentType document, String value, Integer start, Integer end) { @@ -55,7 +68,34 @@ public static String getValueFromOffsets(DOMDocumentType document, String value, return document.getSubstring(start, end); } return value; + } + + public DTDDeclParameter addNewParameter(int start, int end) { + if(parameters == null) { + parameters = new ArrayList(); + } + DTDDeclParameter parameter = new DTDDeclParameter(parentDocumentType == null ? parentDocument.getDoctype() : parentDocumentType, start, end); + parameters.add(parameter); + this.end = end; // updates end position of the node. + return parameter; } - + public void updateLastParameterEnd(int end) { + if(parameters != null && parameters.size() > 0) { + DTDDeclParameter last = parameters.get(parameters.size() - 1); + last.end = end; + this.end = end; + } + } + + public ArrayList getParameters() { + if(parameters == null) { + parameters = new ArrayList(); + } + return parameters; + } + + public String getDeclTypeAsString() { + return null; + } } \ No newline at end of file diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDDeclParameter.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDDeclParameter.java new file mode 100644 index 0000000000..38f2857568 --- /dev/null +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDDeclParameter.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat Inc. and others. + * 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: + * Red Hat Inc. - initial API and implementation + * + *******************************************************************************/ + +package org.eclipse.lsp4xml.dom; + +/** + * DTDDeclParameter + */ +public class DTDDeclParameter { + + String parameter; + + int start, end; + + DOMDocumentType parentDoctype; + + public DTDDeclParameter(DOMDocumentType doctype, int start, int end) { + this.parentDoctype = doctype; + this.start = start; + this.end = end; + } + + + public String getParameter() { + if (parameter == null) { + parameter = parentDoctype.getSubstring(start, end); + } + return parameter; + } + + /** + * Will get the parameter with the first and last character removed + * + * Can be used to remove the quotations from a URL value... + */ + public String getParameterWithoutFirstAndLastChar() { + if (parameter == null) { + parameter = parentDoctype.getSubstring(start + 1, end - 1); + } + return parameter; + } + + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof DTDDeclParameter)) { + return false; + } + DTDDeclParameter temp = (DTDDeclParameter) obj; + return start == temp.start && end == temp.end; + } + +} \ No newline at end of file diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDElementDecl.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDElementDecl.java index 7d9673288b..e650182676 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDElementDecl.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDElementDecl.java @@ -27,13 +27,9 @@ public class DTDElementDecl extends DTDDeclNode { */ - Integer nameStart, nameEnd; // - Integer categoryStart, categoryEnd; // - Integer contentStart,contentEnd; // - - String name; - String category; - String content; + DTDDeclParameter name; + DTDDeclParameter category; + DTDDeclParameter content; public DTDElementDecl(int start, int end, DOMDocumentType parentDocumentType) { @@ -50,18 +46,27 @@ public String getNodeName() { } public String getName() { - name = getValueFromOffsets(parentDocumentType, name, nameStart, nameEnd); - return name; + return name != null ? name.getParameter() : null; + } + + public void setName(int start, int end) { + name = addNewParameter(start, end); } public String getCategory() { - category = getValueFromOffsets(parentDocumentType, category, categoryStart, categoryEnd); - return category; + return category != null ? category.getParameter() : null; + } + + public void setCategory(int start, int end) { + category = addNewParameter(start, end); } public String getContent() { - content = getValueFromOffsets(parentDocumentType, content, contentStart, contentEnd); - return content; + return content != null ? content.getParameter() : null; + } + + public void setContent(int start, int end) { + content = addNewParameter(start, end); } @Override @@ -78,4 +83,10 @@ public int getEndElementTag() { return getStart() + " */ - - String name; - String value; - String kind; - String publicId; - String systemId; - - Integer percentStart, percentEnd; - Integer nameStart, nameEnd; - Integer valueStart, valueEnd; - Integer kindStart, kindEnd; - Integer publicIdStart, publicIdEnd; - Integer systemIdStart, systemIdEnd; + DTDDeclParameter percent; + DTDDeclParameter name; + DTDDeclParameter value; + DTDDeclParameter kind; + DTDDeclParameter publicId; + DTDDeclParameter systemId; public DTDEntityDecl(int start, int end, DOMDocumentType parentDocumentType) { @@ -66,10 +59,11 @@ public DTDEntityDecl(int start, int end, DOMDocumentType parentDocumentType) { } public String getPercent() { - if(percentStart != null && percentEnd != null) { - return "%"; - } - return null; + return percent != null ? percent.getParameter() : null; + } + + public void setPercent(int start, int end) { + percent = addNewParameter(start, end); } /* @@ -79,18 +73,27 @@ public String getPercent() { */ @Override public String getNodeName() { - name = getValueFromOffsets(parentDocumentType, name, nameStart, nameEnd); - return name; + return name != null ? name.getParameter() : null; + } + + public void setNodeName(int start, int end) { + name = addNewParameter(start, end); } public String getValue() { - value = getValueFromOffsets(parentDocumentType, value, valueStart, valueEnd); - return value; + return value != null ? value.getParameter() : null; + } + + public void setValue(int start, int end) { + value = addNewParameter(start, end); } public String getKind() { - kind = getValueFromOffsets(parentDocumentType, kind, kindStart, kindEnd); - return kind; + return kind != null ? kind.getParameter() : null; + } + + public void setKind(int start, int end) { + kind = addNewParameter(start, end); } @Override @@ -125,8 +128,11 @@ public String getNotationName() { */ @Override public String getPublicId() { - publicId = getValueFromOffsets(parentDocumentType, publicId, publicIdStart, publicIdEnd); - return publicId; + return publicId != null ? publicId.getParameter() : null; + } + + public void setPublicId(int start, int end) { + publicId = addNewParameter(start, end); } /* @@ -136,8 +142,11 @@ public String getPublicId() { */ @Override public String getSystemId() { - systemId = getValueFromOffsets(parentDocumentType, systemId, systemIdStart, systemIdEnd); - return systemId; + return systemId != null ? systemId.getParameter() : null; + } + + public void setSystemId(int start, int end) { + systemId = addNewParameter(start, end); } /* @@ -160,4 +169,10 @@ public String getXmlVersion() { throw new UnsupportedOperationException(); } + @Override + public String getDeclTypeAsString() { + return "ENTITY"; + } + + } diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDNotationDecl.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDNotationDecl.java index f8b1aaa041..60de3259b9 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDNotationDecl.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDNotationDecl.java @@ -33,62 +33,55 @@ public class DTDNotationDecl extends DTDDeclNode { * */ - Integer nameStart, nameEnd; - Integer kindStart, kindEnd; - Integer publicIdStart, publicIdEnd; - Integer systemIdStart, systemIdEnd; - - String name; - String kind; - String publicId; - String systemId; + DTDDeclParameter name; + DTDDeclParameter kind; + DTDDeclParameter publicId; + DTDDeclParameter systemId; public DTDNotationDecl(int start, int end, DOMDocumentType parentDocumentType) { super(start, end, parentDocumentType); } void setName(int start, int end) { - nameStart = start; - nameEnd = end; + name = addNewParameter(start, end); } public String getName() { - name = getValueFromOffsets(parentDocumentType, name, nameStart, nameEnd); - return name; + return name != null ? name.getParameter() : null; } void setKind(int start, int end) { - kindStart = start; - kindEnd = end; + kind = addNewParameter(start, end); } public String getKind() { - kind = getValueFromOffsets(parentDocumentType, kind, kindStart, kindEnd); - return kind; + return kind != null ? kind.getParameter() : null; } void setPublicId(int start, int end) { - publicIdStart = start; - publicIdEnd = end; + publicId = addNewParameter(start, end); } public String getPublicId() { - publicId = getValueFromOffsets(parentDocumentType, publicId, publicIdStart, publicIdEnd); - return publicId; + return publicId != null ? publicId.getParameter() : null; } void setSystemId(int start, int end) { - systemIdStart = start; - systemIdEnd = end; + systemId = addNewParameter(start, end); } public String getSystemId() { - systemId = getValueFromOffsets(parentDocumentType, systemId, systemIdStart, systemIdEnd); - return systemId; + return systemId != null ? systemId.getParameter() : null; } @Override public short getNodeType() { return DOMNode.DTD_NOTATION_DECL; } + + @Override + public String getDeclTypeAsString() { + return "NOTATION"; + } + } \ No newline at end of file diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/LineIndentInfo.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/LineIndentInfo.java index 437dd4d29a..2089faebc0 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/LineIndentInfo.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/LineIndentInfo.java @@ -1,3 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat Inc. and others. + * 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.dom; public class LineIndentInfo { diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/Constants.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/Constants.java index a223578343..ffda5cfb9d 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/Constants.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/Constants.java @@ -70,7 +70,7 @@ public class Constants { public static final Pattern DTD_ELEMENT_CATEGORY = Pattern.compile("^(EMPTY|ANY)([\\s<>\"'])"); - public static final Pattern DTD_ELEMENT_CONTENT = Pattern.compile("^(\\(((\\S,)*(\\S))\\)|\\(\\))"); + public static final Pattern DTD_ELEMENT_CONTENT = Pattern.compile("^(\\((([^\\s,]+,)*[^\\s,]+)\\))|\\(\\)"); public static final Pattern DTD_PCDATA = Pattern.compile("^#PCDATA"); diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/XMLScanner.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/XMLScanner.java index 00d307250b..81b91cb60e 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/XMLScanner.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/XMLScanner.java @@ -34,14 +34,14 @@ public class XMLScanner implements Scanner { String url; boolean isInsideDTDContent = false; // Either internal dtd in xml file OR external dtd in dtd file boolean isDeclCompleted = false; // If any type of DTD declaration was supplied with all the required properties - + TokenType tempToken; /** * boolean completedInitialAttDef; * * If the first attribute definition was completed in an ATTLIST declaration * eg: * */ @@ -65,7 +65,7 @@ String nextAttributeName() { } String doctypeName() { - return stream.advanceIfRegExp(ATTRIBUTE_NAME_REGEX).toLowerCase(); + return stream.advanceIfRegExp(ELEMENT_NAME_REGEX).toLowerCase(); } /** @@ -394,7 +394,7 @@ TokenType internalScan() { state = ScannerState.DTDAfterDoctypeSYSTEM; return finishToken(offset, TokenType.DTDDocTypeKindSYSTEM); } - state = ScannerState.DTDWithinDoctype; + state = ScannerState.DTDUnrecognizedParameters; return internalScan(); case DTDAfterDoctypePUBLIC: @@ -435,7 +435,7 @@ TokenType internalScan() { return internalScan(); case DTDWithinContent: - if (stream.advanceIfChar(_CSB)) { // ] + if (stream.advanceIfChar(_CSB) || stream.peekChar() == _RAN) { // ] || > state = ScannerState.DTDWithinDoctype; isInsideDTDContent = false; return finishToken(offset, TokenType.DTDEndInternalSubset); @@ -469,13 +469,7 @@ TokenType internalScan() { } } - if (stream.advanceIfChar(_CSB)) { // ] - state = ScannerState.DTDWithinDoctype; - isInsideDTDContent = false; - return finishToken(offset, TokenType.DTDEndInternalSubset); - } - - stream.advanceUntilAnyOfChars(_LAN, _CSB); // < || ] + stream.advanceUntilAnyOfChars(_RAN, _LAN, _CSB); // > || < || ] return finishToken(offset, TokenType.Content); @@ -486,12 +480,13 @@ TokenType internalScan() { } if(stream.advanceIfChar(_RAN)) { // > - state = ScannerState.DTDWithinContent; - return finishToken(offset, TokenType.DTDEndTag); + state = isInsideDTDContent ? ScannerState.DTDWithinContent : ScannerState.WithinContent; + tempToken = isInsideDTDContent ? TokenType.DTDEndTag : TokenType.EndTagClose; + return finishToken(offset, tempToken); } if(stream.peekChar() == _LAN) { // < - state = ScannerState.DTDWithinContent; + state = isInsideDTDContent ? ScannerState.DTDWithinContent : ScannerState.WithinContent; return internalScan(); } diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/dtd/contentmodel/CMDTDContentModelProvider.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/dtd/contentmodel/CMDTDContentModelProvider.java index 80c3d64ada..ee09136dcd 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/dtd/contentmodel/CMDTDContentModelProvider.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/dtd/contentmodel/CMDTDContentModelProvider.java @@ -53,7 +53,7 @@ public String getSystemId(DOMDocument xmlDocument, String namespaceURI) { * "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"> */ DOMDocumentType documentType = xmlDocument.getDoctype(); - return documentType.getSystemId(); + return documentType.getSystemIdWithoutQuotes(); } @Override diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/services/XMLFormatter.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/services/XMLFormatter.java index 048c3244ca..f8516a5d4f 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/services/XMLFormatter.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/services/XMLFormatter.java @@ -11,6 +11,7 @@ package org.eclipse.lsp4xml.services; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -30,8 +31,12 @@ import org.eclipse.lsp4xml.dom.DOMParser; import org.eclipse.lsp4xml.dom.DOMProcessingInstruction; import org.eclipse.lsp4xml.dom.DOMText; +import org.eclipse.lsp4xml.dom.DTDAttlistDecl; +import org.eclipse.lsp4xml.dom.DTDDeclNode; +import org.eclipse.lsp4xml.dom.DTDDeclParameter; import org.eclipse.lsp4xml.services.extensions.XMLExtensionsRegistry; import org.eclipse.lsp4xml.settings.XMLFormattingOptions; +import org.eclipse.lsp4xml.utils.StringUtils; import org.eclipse.lsp4xml.utils.XMLBuilder; /** @@ -66,7 +71,7 @@ public List format(TextDocument document, Range range, XMLFo // Parse the content to format to create an XML document with full data (CData, // comments, etc) String text = document.getText().substring(start, end); - DOMDocument doc = DOMParser.getInstance().parse(text, null, null); + DOMDocument doc = DOMParser.getInstance().parse(text, document.getUri(), null); // Format the content XMLBuilder xml = new XMLBuilder(formattingOptions, "", document.lineDelimiter(startPosition.getLine())); @@ -86,9 +91,14 @@ public List format(TextDocument document, Range range, XMLFo private void format(DOMNode node, int level, int end, XMLBuilder xml) { if (node.getNodeType() != DOMNode.DOCUMENT_NODE) { - boolean doLineFeed = !(node.isComment() && ((DOMComment) node).isCommentSameLineEndTag()) + boolean doLineFeed; + if(node.getOwnerDocument().isDTD()) { + doLineFeed = false; + } else { + doLineFeed = !(node.isComment() && ((DOMComment) node).isCommentSameLineEndTag()) && (!isPreviousNodeType(node, DOMNode.TEXT_NODE) || xml.isJoinContentLines()) && (!node.isText() || ((xml.isJoinContentLines() && !isFirstChildNode(node)))); + } if (level > 0 && doLineFeed) { // add new line + indent @@ -96,66 +106,7 @@ private void format(DOMNode node, int level, int end, XMLBuilder xml) { xml.indent(level); } // generate start element - if (node.isCDATA()) { - DOMCDATASection cdata = (DOMCDATASection) node; - xml.startCDATA(); - xml.addContentCDATA(cdata.getData()); - xml.endCDATA(); - } else if (node.isComment()) { - DOMComment comment = (DOMComment) node; - xml.startComment(comment); - xml.addContentComment(comment.getData()); - xml.endComment(); - if (level == 0) { - xml.linefeed(); - } - } else if (node.isProcessingInstruction()) { - DOMProcessingInstruction processingInstruction = (DOMProcessingInstruction) node; - xml.startPrologOrPI(processingInstruction.getTarget()); - xml.addContentPI(processingInstruction.getData()); - xml.endPrologOrPI(); - if (level == 0) { - xml.linefeed(); - } - } else if (node.isProlog()) { - DOMProcessingInstruction processingInstruction = (DOMProcessingInstruction) node; - xml.startPrologOrPI(processingInstruction.getTarget()); - if (node.hasAttributes()) { - // generate attributes - String[] attributes = new String[3]; - attributes[0] = "version"; - attributes[1] = "encoding"; - attributes[2] = "standalone"; - - for (int i = 0; i < attributes.length; i++) { - String name = attributes[i]; - String value = node.getAttribute(attributes[i]); - if (value == null) { - continue; - } - xml.addSingleAttribute(name, value); - } - } - xml.endPrologOrPI(); - xml.linefeed(); - } else if (node.isDoctype()) { - DOMDocumentType documentType = (DOMDocumentType) node; - xml.startDoctype(documentType.getName()); - xml.setDoctypeInternalSubset(documentType.getInternalSubset()); - xml.endDoctype(); - xml.linefeed(); - } else if (node.isText()) { - DOMText text = (DOMText) node; - if (text.hasData()) { - // Generate content - String content = text.getData(); - if (!content.isEmpty()) { - xml.addContent(content); - } - - } - return; - } else if (node.isElement()) { + if (node.isElement()) { DOMElement element = (DOMElement) node; String tag = element.getTagName(); if (element.hasEndTag() && !element.hasStartTag()) { @@ -217,6 +168,85 @@ private void format(DOMNode node, int level, int end, XMLBuilder xml) { } } return; + + } else if (node.isCDATA()) { + DOMCDATASection cdata = (DOMCDATASection) node; + xml.startCDATA(); + xml.addContentCDATA(cdata.getData()); + xml.endCDATA(); + } else if (node.isComment()) { + DOMComment comment = (DOMComment) node; + xml.startComment(comment); + xml.addContentComment(comment.getData()); + xml.endComment(); + if (level == 0) { + xml.linefeed(); + } + } else if (node.isProcessingInstruction()) { + DOMProcessingInstruction processingInstruction = (DOMProcessingInstruction) node; + xml.startPrologOrPI(processingInstruction.getTarget()); + xml.addContentPI(processingInstruction.getData()); + xml.endPrologOrPI(); + if (level == 0) { + xml.linefeed(); + } + } else if (node.isProlog()) { + DOMProcessingInstruction processingInstruction = (DOMProcessingInstruction) node; + xml.startPrologOrPI(processingInstruction.getTarget()); + if (node.hasAttributes()) { + // generate attributes + String[] attributes = new String[3]; + attributes[0] = "version"; + attributes[1] = "encoding"; + attributes[2] = "standalone"; + + for (int i = 0; i < attributes.length; i++) { + String name = attributes[i]; + String value = node.getAttribute(attributes[i]); + if (value == null) { + continue; + } + xml.addSingleAttribute(name, value); + } + } + xml.endPrologOrPI(); + xml.linefeed(); + } else if (node.isText()) { + DOMText text = (DOMText) node; + if (text.hasData()) { + // Generate content + String content = text.getData(); + if (!content.isEmpty()) { + xml.addContent(content); + } + + } + return; + } else if (node.isDoctype()) { + boolean isDTD = node.getOwnerDocument().isDTD(); + DOMDocumentType documentType = (DOMDocumentType) node; + if(!isDTD) { + xml.startDoctype(); + ArrayList params = documentType.getParameters(); + for (DTDDeclParameter param : params) { + if(!documentType.isInternalSubset(param)) { + xml.addParameter(param.getParameter()); + } else { + xml.linefeed(); + xml.startDoctypeInternalSubset(); + xml.linefeed(); + // level + 1 since the 'level' value is the doctype tag's level + formatDTD(documentType, level + 1, end, xml); + xml.linefeed(); + xml.endDoctypeInternalSubset(); + } + } + xml.endDoctype(); + xml.linefeed(); + } else { + formatDTD(documentType, 0, end, xml); + } + return; } } else if (node.hasChildNodes()) { // Other nodes kind like root @@ -226,6 +256,81 @@ private void format(DOMNode node, int level, int end, XMLBuilder xml) { } } + private static boolean formatDTD(DOMDocumentType doctype, int level, int end, XMLBuilder xml) { + DOMNode previous = null; + for (DOMNode node : doctype.getChildren()) { + if(previous != null) { + xml.linefeed(); + } + + xml.indent(level); + + if(node.isText()) { + xml.addContent(((DOMText)node).getData().trim()); + } + else { + if(node.isComment()) { + DOMComment comment = (DOMComment) node; + xml.startComment(comment); + xml.addContentComment(comment.getData()); + xml.endComment(); + } + else { + boolean setEndBracketOnNewLine = false; + DTDDeclNode decl = (DTDDeclNode) node; + xml.addDeclTagStart(decl); + + if(decl.isDTDAttListDecl()) { + DTDAttlistDecl attlist = (DTDAttlistDecl) decl; + ArrayList internalDecls = attlist.getInternalChildren(); + + if(internalDecls == null) { + for (DTDDeclParameter param : decl.getParameters()) { + xml.addParameter(param.getParameter()); + } + } + else { + boolean didSetElementName = false; + + for (DTDDeclParameter param : attlist.getParameters()) { + if(!didSetElementName) { + didSetElementName = true; + xml.addParameter(param.getParameter()); + if(attlist.getParameters().size() > 1) { //has parameters after elementName + xml.linefeed(); + xml.indent(level + 1); + setEndBracketOnNewLine = true; + } + } else { + xml.addParameter(param.getParameter()); + } + } + + for (DTDAttlistDecl attlistDecl : internalDecls) { + xml.linefeed(); + xml.indent(level + 1); + for (DTDDeclParameter param : attlistDecl.getParameters()) { + xml.addParameter(param.getParameter()); + } + } + } + } else { + for (DTDDeclParameter param : decl.getParameters()) { + xml.addParameter(param.getParameter()); + } + } + if(setEndBracketOnNewLine) { + xml.linefeed(); + xml.indent(level); + } + xml.closeStartElement(); + } + } + previous = node; + } + return true; + } + private static boolean isFirstChildNode(DOMNode node) { return node.equals(node.getParentNode().getFirstChild()); } diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/utils/StringUtils.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/utils/StringUtils.java index c001a01a62..fca660ee6f 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/utils/StringUtils.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/utils/StringUtils.java @@ -83,6 +83,8 @@ public static String getStartWhitespaces(String lineText) { return whitespaces.toString(); } + + public static void trimNewLines(String value, StringBuilder s) { int len = value.length(); int st = 0; diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/utils/XMLBuilder.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/utils/XMLBuilder.java index b1381c93b5..e1ea806b43 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/utils/XMLBuilder.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/utils/XMLBuilder.java @@ -13,6 +13,9 @@ import static org.eclipse.lsp4xml.utils.StringUtils.normalizeSpace; import org.eclipse.lsp4xml.dom.DOMComment; +import org.eclipse.lsp4xml.dom.DOMDocumentType; +import org.eclipse.lsp4xml.dom.DOMNode; +import org.eclipse.lsp4xml.dom.DTDDeclNode; import org.eclipse.lsp4xml.settings.XMLFormattingOptions; /** @@ -206,21 +209,29 @@ public XMLBuilder addContentComment(String content) { return this; } - public XMLBuilder startDoctype(String name) { + public XMLBuilder addDeclTagStart(DTDDeclNode tag) { + + xml.append(" \n" + + " ]\n" + + ">"; + + DOMDocument actual = createDOMDocument(dtd); + Assert.assertEquals(1, actual.getChildren().size()); + Assert.assertTrue(actual.getChild(0).isDoctype()); + DOMDocumentType documentType = (DOMDocumentType) actual.getChild(0); + Assert.assertEquals(0, documentType.getStart()); + Assert.assertEquals(74, documentType.getEnd()); + Assert.assertEquals("foo", documentType.getName()); + Assert.assertTrue(documentType.isClosed()); + + // \n" + " \n "; DOMDocument document = DOMParser.getInstance().parse(xml, null, null); - assertDoctype((DOMDocumentType)(document.getChild(0)), 0, 212, "html", DocumentTypeKind.SYSTEM.name(), null, "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", internal); + assertDoctype((DOMDocumentType)(document.getChild(0)), 0, 212, "html", DocumentTypeKind.SYSTEM.name(), null, "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"", internal); } @@ -548,7 +548,7 @@ public void testDTDExternalUnrecognizedParameters() { doctype.closed = true; DOMNode entity = createEntityDecl(0, 24, 9, 15, null, null, 16, 22, null, null, null, null, null, null); entity.closed = true; - DOMNode element = createElementDecl(25, 49, 35, 39, null, null, 40, 49, null, null); + DOMNode element = createElementDecl(25, 50, 35, 39, null, null, 40, 49, null, null); element.closed = false; DOMNode attlist = createAttlistDecl(50, 81, 60, 67, 68, 72, null, null, null, null, 73, 80); attlist.closed = true; @@ -571,9 +571,9 @@ public void testDTDExternalUnrecognizedParameters2() { DOMNode doctype = createDoctypeNode(0, 81, null, null, null, null, null, null, null, null, null, null); doctype.closed = true; - DOMNode entity = createEntityDecl(0, 24, 9, 15, null, null, 16, 22, null, null, null, null, null, null); + DOMNode entity = createEntityDecl(0, 25, 9, 15, null, null, 16, 22, null, null, null, null, null, null); entity.closed = false; - DOMNode element = createElementDecl(25, 49, 35, 39, null, null, 40, 49, null, null); + DOMNode element = createElementDecl(25, 50, 35, 39, null, null, 40, 49, null, null); element.closed = false; DOMNode attlist = createAttlistDecl(50, 81, 60, 67, 68, 72, null, null, null, null, 73, 80); attlist.closed = true; @@ -595,7 +595,7 @@ public void testDTDExternalUnrecognizedParameters3() { DOMNode doctype = createDoctypeNode(0, 32, null, null, null, null, null, null, null, null, null, null); doctype.closed = true; - DOMNode attlist = createAttlistDecl(0, 15, 10, 14, null, null, null, null, null, null, null, null); + DOMNode attlist = createAttlistDecl(0, 16, 10, 14, null, null, null, null, null, null, null, null); attlist.closed = false; DOMNode element = createElementDecl(16, 32, 26, 30, null, null, null, null, null, null); element.closed = true; @@ -680,7 +680,7 @@ public void testNotationMissingEndTag() { DOMNode doctype = createDoctypeNode(0, 77, null, null, null, null, null, null, null, null, null, null); doctype.closed = true; - DTDNotationDecl notation1 = createNotationDecl(0, 32, 11, 14, 15, 21, 22, 32, null, null, null, null); + DTDNotationDecl notation1 = createNotationDecl(0, 33, 11, 14, 15, 21, 22, 32, null, null, null, null); notation1.closed = false; DTDNotationDecl notation2 = createNotationDecl(33, 77, 44, 47, 48, 54, 55, 64, 65, 76, null, null); notation2.closed = true; @@ -700,7 +700,7 @@ public void testNotationMissingEndTagMissingAndExtraValues() { DOMNode doctype = createDoctypeNode(0, 81, null, null, null, null, null, null, null, null, null, null); doctype.closed = true; - DTDNotationDecl notation1 = createNotationDecl(0, 32, 11, 14, 15, 21, 22, 32, null, null, null, null); + DTDNotationDecl notation1 = createNotationDecl(0, 33, 11, 14, 15, 21, 22, 32, null, null, null, null); notation1.closed = false; DTDNotationDecl notation2 = createNotationDecl(33, 81, 44, 47, 48, 54, 55, 64, 65, 76, 77, 80); notation2.closed = true; @@ -786,30 +786,21 @@ private static DTDAttlistDecl createAttlistDecl(int start, int end, Integer elem Integer attributeNameEnd, Integer attributeTypeStart, Integer attributeTypeEnd, Integer attributeValueStart, Integer attributeValueEnd, Integer unrecognizedStart, Integer unrecognizedEnd) { DTDAttlistDecl attlist = new DTDAttlistDecl(start, end, null); - attlist.elementNameStart = elementNameStart; - attlist.elementNameEnd = elementNameEnd; - attlist.attributeNameStart = attributeNameStart; - attlist.attributeNameEnd = attributeNameEnd; - attlist.attributeTypeStart = attributeTypeStart; - attlist.attributeTypeEnd = attributeTypeEnd; - attlist.attributeValueStart = attributeValueStart; - attlist.attributeValueEnd = attributeValueEnd; - attlist.unrecognizedStart = unrecognizedStart; - attlist.unrecognizedEnd = unrecognizedEnd; + attlist.elementName = elementNameStart != null ? new DTDDeclParameter(null, elementNameStart, elementNameEnd) : null; + attlist.attributeName = attributeNameStart != null ? new DTDDeclParameter(null, attributeNameStart, attributeNameEnd) : null; + attlist.attributeType = attributeTypeStart != null ? new DTDDeclParameter(null, attributeTypeStart, attributeTypeEnd) : null; + attlist.attributeValue = attributeValueStart != null ? new DTDDeclParameter(null, attributeValueStart, attributeValueEnd) : null; + attlist.unrecognized = unrecognizedStart != null ? new DTDDeclParameter(null, unrecognizedStart, unrecognizedEnd) : null; return attlist; } private static DTDElementDecl createElementDecl(int start, int end, Integer nameStart, Integer nameEnd, Integer categoryStart, Integer categoryEnd, Integer contentStart, Integer contentEnd, Integer unrecognizedStart, Integer unrecognizedEnd) { DTDElementDecl element = new DTDElementDecl(start, end, null); - element.nameStart = nameStart; - element.nameEnd = nameEnd; - element.categoryStart = categoryStart; - element.categoryEnd = categoryEnd; - element.contentStart = contentStart; - element.contentEnd = contentEnd; - element.unrecognizedStart = unrecognizedStart; - element.unrecognizedEnd = unrecognizedEnd; + element.name = nameStart != null ? new DTDDeclParameter(null, nameStart, nameEnd) : null; + element.category = categoryStart != null ? new DTDDeclParameter(null, categoryStart, categoryEnd) : null; + element.content = contentStart != null ? new DTDDeclParameter(null, contentStart, contentEnd) : null; + element.unrecognized = unrecognizedStart != null ? new DTDDeclParameter(null, unrecognizedStart, unrecognizedEnd) : null; return element; } @@ -817,34 +808,23 @@ private static DTDEntityDecl createEntityDecl(int start, int end, Integer nameSt Integer valueEnd, Integer kindStart, Integer kindEnd, Integer publicIdStart, Integer publicIdEnd, Integer systemIdStart, Integer systemIdEnd, Integer unrecognizedStart, Integer unrecognizedEnd) { DTDEntityDecl entity = new DTDEntityDecl(start, end, null); - entity.nameStart = nameStart; - entity.nameEnd = nameEnd; - entity.valueStart = valueStart; - entity.valueEnd = valueEnd; - entity.kindStart = kindStart; - entity.kindEnd = kindEnd; - entity.publicIdStart = publicIdStart; - entity.publicIdEnd = publicIdEnd; - entity.systemIdStart = systemIdStart; - entity.systemIdEnd = systemIdEnd; - entity.unrecognizedStart = unrecognizedStart; - entity.unrecognizedEnd = unrecognizedEnd; + entity.name = nameStart != null ? new DTDDeclParameter(null, nameStart, nameEnd) : null; + entity.value = valueStart != null ? new DTDDeclParameter(null, valueStart, valueEnd) : null; + entity.kind = kindStart != null ? new DTDDeclParameter(null, kindStart, kindEnd) : null; + entity.publicId = publicIdStart != null ? new DTDDeclParameter(null, publicIdStart, publicIdEnd) : null; + entity.systemId = systemIdStart != null ? new DTDDeclParameter(null, systemIdStart, systemIdEnd) : null; + entity.unrecognized = unrecognizedStart != null ? new DTDDeclParameter(null, unrecognizedStart, unrecognizedEnd) : null; return entity; } private static DTDNotationDecl createNotationDecl(int start, int end, Integer nameStart, Integer nameEnd, Integer kindStart, Integer kindEnd, Integer publicIdStart, Integer publicIdEnd, Integer systemIdStart, Integer systemIdEnd, Integer unrecognizedStart, Integer unrecognizedEnd) { DTDNotationDecl notation = new DTDNotationDecl(start, end, null); - notation.nameStart = nameStart; - notation.nameEnd = nameEnd; - notation.kindStart = kindStart; - notation.kindEnd = kindEnd; - notation.publicIdStart = publicIdStart; - notation.publicIdEnd = publicIdEnd; - notation.systemIdStart = systemIdStart; - notation.systemIdEnd = systemIdEnd; - notation.unrecognizedStart = unrecognizedStart; - notation.unrecognizedEnd = unrecognizedEnd; + notation.name = nameStart != null ? new DTDDeclParameter(null, nameStart, nameEnd) : null; + notation.kind = kindStart != null ? new DTDDeclParameter(null, kindStart, kindEnd) : null; + notation.publicId = publicIdStart != null ? new DTDDeclParameter(null, publicIdStart, publicIdEnd) : null; + notation.systemId = systemIdStart != null ? new DTDDeclParameter(null, systemIdStart, systemIdEnd) : null; + notation.unrecognized = unrecognizedStart != null ? new DTDDeclParameter(null, unrecognizedStart, unrecognizedEnd) : null; return notation; } @@ -852,16 +832,11 @@ private static DOMDocumentType createDoctypeNode(int start, int end, Integer nam Integer kindEnd, Integer publicIdStart, Integer publicIdEnd, Integer systemIdStart, Integer systemIdEnd, Integer internalSubsetStart, Integer internalSubsetEnd) { DOMDocumentType doctype = new DOMDocumentType(start, end, null); - doctype.nameStart = nameStart; - doctype.nameEnd = nameEnd; - doctype.kindStart = kindStart; - doctype.kindEnd = kindEnd; - doctype.publicIdStart = publicIdStart; - doctype.publicIdEnd = publicIdEnd; - doctype.systemIdStart = systemIdStart; - doctype.systemIdEnd = systemIdEnd; - doctype.internalSubsetStart = internalSubsetStart; - doctype.internalSubsetEnd = internalSubsetEnd; + doctype.name = nameStart != null ? new DTDDeclParameter(null, nameStart, nameEnd) : null;; + doctype.kind = kindStart != null ? new DTDDeclParameter(null, kindStart, kindEnd) : null;; + doctype.publicId = publicIdStart != null ? new DTDDeclParameter(null, publicIdStart, publicIdEnd) : null;; + doctype.systemId = systemIdEnd != null ? new DTDDeclParameter(null, systemIdStart, systemIdEnd) : null;; + doctype.internalSubset = internalSubsetStart != null ? new DTDDeclParameter(null, internalSubsetStart, internalSubsetEnd) : null;; return doctype; } @@ -1011,16 +986,11 @@ private static void compareTrees(DOMNode expectedNode, DOMNode actualNode) { assertEquals(true, actualNode.isDTDAttListDecl()); DTDAttlistDecl expectedTemp = (DTDAttlistDecl) expectedNode; DTDAttlistDecl actualTemp = (DTDAttlistDecl) actualNode; - assertEquals(expectedTemp.elementNameStart, actualTemp.elementNameStart); - assertEquals(expectedTemp.elementNameEnd, actualTemp.elementNameEnd); - assertEquals(expectedTemp.attributeNameStart, actualTemp.attributeNameStart); - assertEquals(expectedTemp.attributeNameEnd, actualTemp.attributeNameEnd); - assertEquals(expectedTemp.attributeTypeStart, actualTemp.attributeTypeStart); - assertEquals(expectedTemp.attributeTypeEnd, actualTemp.attributeTypeEnd); - assertEquals(expectedTemp.attributeValueStart, actualTemp.attributeValueStart); - assertEquals(expectedTemp.attributeValueEnd, actualTemp.attributeValueEnd); - assertEquals(expectedTemp.unrecognizedStart, actualTemp.unrecognizedStart); - assertEquals(expectedTemp.unrecognizedEnd, actualTemp.unrecognizedEnd); + assertEquals(expectedTemp.elementName, actualTemp.elementName); + assertEquals(expectedTemp.attributeName, actualTemp.attributeName); + assertEquals(expectedTemp.attributeType, actualTemp.attributeType); + assertEquals(expectedTemp.attributeValue, actualTemp.attributeValue); + assertEquals(expectedTemp.unrecognized, actualTemp.unrecognized); ArrayList expectedInternalChildren = expectedTemp.getInternalChildren(); ArrayList actualInternalChildren = actualTemp.getInternalChildren(); @@ -1037,72 +1007,52 @@ private static void compareTrees(DOMNode expectedNode, DOMNode actualNode) { assertEquals(true, actualNode.isDTDElementDecl()); DTDElementDecl expectedTemp = (DTDElementDecl) expectedNode; DTDElementDecl actualTemp = (DTDElementDecl) actualNode; - assertEquals(expectedTemp.nameStart, actualTemp.nameStart); - assertEquals(expectedTemp.nameEnd, actualTemp.nameEnd); - assertEquals(expectedTemp.categoryStart, actualTemp.categoryStart); - assertEquals(expectedTemp.categoryEnd, actualTemp.categoryEnd); - assertEquals(expectedTemp.contentStart, actualTemp.contentStart); - assertEquals(expectedTemp.contentEnd, actualTemp.contentEnd); - assertEquals(expectedTemp.unrecognizedStart, actualTemp.unrecognizedStart); - assertEquals(expectedTemp.unrecognizedEnd, actualTemp.unrecognizedEnd); + assertEquals(expectedTemp.name, actualTemp.name); + assertEquals(expectedTemp.category, actualTemp.category); + assertEquals(expectedTemp.content, actualTemp.content); + assertEquals(expectedTemp.unrecognized, actualTemp.unrecognized); } else if(expectedNode.isDTDEntityDecl()) { assertEquals(true, actualNode.isDTDEntityDecl()); DTDEntityDecl expectedTemp = (DTDEntityDecl) expectedNode; DTDEntityDecl actualTemp = (DTDEntityDecl) actualNode; - assertEquals(expectedTemp.nameStart, actualTemp.nameStart); - assertEquals(expectedTemp.nameEnd, actualTemp.nameEnd); - assertEquals(expectedTemp.valueStart, actualTemp.valueStart); - assertEquals(expectedTemp.valueEnd, actualTemp.valueEnd); - assertEquals(expectedTemp.kindStart, actualTemp.kindStart); - assertEquals(expectedTemp.kindEnd, actualTemp.kindEnd); - assertEquals(expectedTemp.publicIdStart, actualTemp.publicIdStart); - assertEquals(expectedTemp.publicIdEnd, actualTemp.publicIdEnd); - assertEquals(expectedTemp.systemIdStart, actualTemp.systemIdStart); - assertEquals(expectedTemp.systemIdEnd, actualTemp.systemIdEnd); - assertEquals(expectedTemp.unrecognizedStart, actualTemp.unrecognizedStart); - assertEquals(expectedTemp.unrecognizedEnd, actualTemp.unrecognizedEnd); + assertEquals(expectedTemp.name, actualTemp.name); + assertEquals(expectedTemp.value, actualTemp.value); + assertEquals(expectedTemp.kind, actualTemp.kind); + assertEquals(expectedTemp.publicId, actualTemp.publicId); + assertEquals(expectedTemp.systemId, actualTemp.systemId); + assertEquals(expectedTemp.unrecognized, actualTemp.unrecognized); } else if(expectedNode.isDTDNotationDecl()) { assertEquals(true, actualNode.isDTDNotationDecl()); DTDNotationDecl expectedTemp = (DTDNotationDecl) expectedNode; DTDNotationDecl actualTemp = (DTDNotationDecl) actualNode; - assertEquals(expectedTemp.nameStart, actualTemp.nameStart); - assertEquals(expectedTemp.nameEnd, actualTemp.nameEnd); - assertEquals(expectedTemp.kindStart, actualTemp.kindStart); - assertEquals(expectedTemp.kindEnd, actualTemp.kindEnd); - assertEquals(expectedTemp.publicIdStart, actualTemp.publicIdStart); - assertEquals(expectedTemp.publicIdEnd, actualTemp.publicIdEnd); - assertEquals(expectedTemp.systemIdStart, actualTemp.systemIdStart); - assertEquals(expectedTemp.systemIdEnd, actualTemp.systemIdEnd); - assertEquals(expectedTemp.unrecognizedStart, actualTemp.unrecognizedStart); - assertEquals(expectedTemp.unrecognizedEnd, actualTemp.unrecognizedEnd); + assertEquals(expectedTemp.name, actualTemp.name); + assertEquals(expectedTemp.kind, actualTemp.kind); + assertEquals(expectedTemp.publicId, actualTemp.publicId); + assertEquals(expectedTemp.systemId, actualTemp.systemId); + assertEquals(expectedTemp.unrecognized, actualTemp.unrecognized); } else if(expectedNode.isDoctype()) { assertEquals(true, actualNode.isDoctype()); DOMDocumentType expectedTemp = (DOMDocumentType) expectedNode; DOMDocumentType actualTemp = (DOMDocumentType) actualNode; - assertEquals(expectedTemp.nameStart, actualTemp.nameStart); - assertEquals(expectedTemp.nameEnd, actualTemp.nameEnd); - assertEquals(expectedTemp.kindStart, actualTemp.kindStart); - assertEquals(expectedTemp.kindEnd, actualTemp.kindEnd); - assertEquals(expectedTemp.publicIdStart, actualTemp.publicIdStart); - assertEquals(expectedTemp.publicIdEnd, actualTemp.publicIdEnd); - assertEquals(expectedTemp.systemIdStart, actualTemp.systemIdStart); - assertEquals(expectedTemp.systemIdEnd, actualTemp.systemIdEnd); - assertEquals(expectedTemp.internalSubsetStart, actualTemp.internalSubsetStart); - assertEquals(expectedTemp.internalSubsetEnd, actualTemp.internalSubsetEnd); + assertEquals(expectedTemp.name, actualTemp.name); + assertEquals(expectedTemp.kind, actualTemp.kind); + assertEquals(expectedTemp.publicId, actualTemp.publicId); + assertEquals(expectedTemp.systemId, actualTemp.systemId); + assertEquals(expectedTemp.internalSubset, actualTemp.internalSubset); } else if(expectedNode.isGenericDTDDecl()) { DTDDeclNode expectedTemp = (DTDDeclNode) expectedNode; DTDDeclNode actualTemp = (DTDDeclNode) actualNode; - assertEquals(expectedTemp.unrecognizedStart, actualTemp.unrecognizedStart); - assertEquals(expectedTemp.unrecognizedEnd, actualTemp.unrecognizedEnd); + assertEquals(expectedTemp.unrecognized.start, actualTemp.unrecognized.start); + assertEquals(expectedTemp.unrecognized.end, actualTemp.unrecognized.end); } assertEquals(expectedNode.isClosed(), actualNode.isClosed()); @@ -1117,25 +1067,13 @@ else if(expectedNode.isGenericDTDDecl()) { } public static void assertInternalAttlist(DTDAttlistDecl expected, DTDAttlistDecl actual) { - assertEquals(expected.attributeNameStart, actual.attributeNameStart); - assertEquals(expected.attributeNameEnd, actual.attributeNameEnd); - assertEquals(expected.attributeTypeStart, actual.attributeTypeStart); - assertEquals(expected.attributeTypeEnd, actual.attributeTypeEnd); - assertEquals(expected.attributeValueStart, actual.attributeValueStart); - assertEquals(expected.attributeValueEnd, actual.attributeValueEnd); - } - - public static void assertInternalNotation(DTDNotationDecl expected, DTDNotationDecl actual) { - assertEquals(expected.nameStart, actual.nameStart); - assertEquals(expected.nameEnd, actual.nameEnd); - assertEquals(expected.kindStart, actual.kindStart); - assertEquals(expected.kindEnd, actual.kindEnd); - assertEquals(expected.publicIdStart, actual.publicIdStart); - assertEquals(expected.publicIdEnd, actual.publicIdEnd); - assertEquals(expected.systemIdStart, actual.systemIdStart); - assertEquals(expected.systemIdEnd, actual.systemIdEnd); + assertEquals(expected.elementName, actual.elementName); + assertEquals(expected.attributeName, actual.attributeName); + assertEquals(expected.attributeType, actual.attributeType); + assertEquals(expected.attributeValue, actual.attributeValue); } + public void insertIntoAttributes(DOMNode n, String key, String value) { n.setAttribute(key, value); } diff --git a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLFormatterTest.java b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLFormatterTest.java index 239ddc29f9..6c5d0cfab9 100644 --- a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLFormatterTest.java +++ b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLFormatterTest.java @@ -724,6 +724,373 @@ public void testContentFormatting6() throws BadLocationException { ""; format(content, expected, formattingOptions); } + + @Test public void testDoctypeNoInternalSubset() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + "\r\n" + + "\r\n" + + " Fred\r\n" + + "\r\n" + + " Jani\r\n" + + "\r\n" + + " Reminder\r\n" + + " \r\n" + + " Don't forget me this weekend\r\n" + + ""; + String expected = + "\r\n" + + "\r\n" + + " Fred\r\n" + + " Jani\r\n" + + " Reminder\r\n" + + " Don't forget me this weekend\r\n" + + ""; + format(content, expected, formattingOptions); + } + + @Test public void testDoctypeInternalSubset() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + "]>\r\n" + + "\r\n" + + " Fred\r\n" + + "\r\n" + + "\r\n" + + " Jani\r\n" + + " \r\n" + + " Reminder\r\n" + + " Don't forget me this weekend\r\n" + + ""; + String expected = + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + "]>\r\n" + + "\r\n" + + " Fred\r\n" + + " Jani\r\n" + + " Reminder\r\n" + + " Don't forget me this weekend\r\n" + + ""; + format(content, expected, formattingOptions); + } + + @Test public void testDoctypeInternalDeclSpacesBetweenParameters() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + "]>\r\n" + + "\r\n" + + " Fred\r\n" + + " Jani\r\n" + + " Reminder\r\n" + + " Don't forget me this weekend\r\n" + + " "; + String expected = + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + "]>\r\n" + + "\r\n" + + " Fred\r\n" + + " Jani\r\n" + + " Reminder\r\n" + + " Don't forget me this weekend\r\n" + + ""; + format(content, expected, formattingOptions); + } + + @Test public void testDoctypeInternalWithAttlist() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + "\r\n" + + "\r\n" + + " \r\n" + + "\r\n" + + " \r\n" + + "\r\n" + + "]>\r\n" + + "\r\n" + + "\r\n" + + " \r\n" + + " Fred\r\n" + + ""; + String expected = + "\r\n" + + " \r\n" + + " \r\n" + + "]>\r\n" + + "\r\n" + + " Fred\r\n" + + ""; + format(content, expected, formattingOptions); + } + + @Test public void testDoctypeInternalAllDecls() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + "\r\n" + + "\r\n" + + " \r\n" + + "\r\n" + + " \r\n" + + "\r\n" + + " \r\n" + + "]>\r\n" + + ""; + String expected = + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + "]>\r\n" + + ""; + format(content, expected, formattingOptions); + } + + @Test public void testDoctypeInternalWithComments() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + "\r\n" + + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + "]>\r\n" + + ""; + String expected = + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + "]>\r\n" + + ""; + format(content, expected, formattingOptions); + } + + @Test public void testDoctypeInternalWithText() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + "\r\n" + + "\r\n" + + "\r\n" + + " garbageazg df\r\n" + + " gdf\r\n" + + "garbageazgdfg\r\n" + + " df\r\n" + + " gd\r\n" + + "\r\n" + + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + "]>"; + String expected = + "\r\n" + + " garbageazg df\r\n" + + " gdf\r\n" + + "garbageazgdfg\r\n" + + " df\r\n" + + " gd\r\n" + + " \r\n" + + "]>\r\n"; + format(content, expected, formattingOptions); + } + + @Test public void testDTDMultiParameterAttlist() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + "\r\n"; + String expected = + ""; + format(content, expected, formattingOptions, "test.dtd"); + } + + @Test public void testDTDIndentation() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " "; + String expected = + "\r\n" + + "\r\n" + + "\r\n" + + ""; + format(content, expected, formattingOptions, "test.dtd"); + } + + @Test public void testDTDNotEndBrackets() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + "\r\n" + + "\r\n" + + "\r\n" + + ""; + format(content, expected, formattingOptions, "test.dtd"); + } + + @Test public void testDTDUnknownDeclNameAndText() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + "\r\n" + + "\r\n" + + "\r\n" + + " \r\n" + + "\r\n" + + " asdasd\r\n" + + " asd\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + ""; + String expected = + "\r\n" + + "\r\n" + + "asdasd\r\n" + + " asd\r\n" + + "\r\n" + + "\r\n" + + ""; + format(content, expected, formattingOptions, "test.dtd"); + } + + @Test public void testAllDoctypeParameters() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + "\r\n" + + "\r\n" + + " \r\n" + + " \r\n" + + "\r\n" + + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + "]\r\n" + + "\r\n" + + "\r\n" + + ">\r\n" + + "\r\n" + + " sdsd\r\n" + + "\r\n" + + " \r\n" + + " \r\n" + + " er\r\n" + + " dd\r\n" + + " \r\n" + + ""; + String expected = + "\r\n" + + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + "]>\r\n" + + "\r\n" + + " sdsd\r\n" + + " \r\n" + + " er\r\n" + + " dd\r\n" + + " \r\n" + + ""; + format(content, expected, formattingOptions); + } + + @Test public void testTemplate() throws BadLocationException { + XMLFormattingOptions formattingOptions = createDefaultFormattingOptions(); + + String content = + ""; + String expected = + ""; + format(content, expected, formattingOptions); + } + + //-------------------------Tools----------------------------------------- @@ -733,8 +1100,12 @@ private static void format(String unformatted, String actual) throws BadLocation private static void format(String unformatted, String expected, XMLFormattingOptions formattingOptions) throws BadLocationException { + format(unformatted, expected, formattingOptions, "test://test.html"); + } + + private static void format(String unformatted, String expected, XMLFormattingOptions formattingOptions, String uri) + throws BadLocationException { Range range = null; - String uri = "test://test.html"; int rangeStart = unformatted.indexOf('|'); int rangeEnd = unformatted.lastIndexOf('|'); if (rangeStart != -1 && rangeEnd != -1) {