Skip to content

Commit

Permalink
Preference to convert single quote attribute values to double quote o…
Browse files Browse the repository at this point in the history
…n format. (#295)

Fixes #263, #294

Signed-off-by: Nikolas <[email protected]>
  • Loading branch information
NikolasKomonen authored Mar 1, 2019
1 parent dbd4b78 commit 1301e93
Show file tree
Hide file tree
Showing 15 changed files with 473 additions and 58 deletions.
28 changes: 28 additions & 0 deletions .vscode/java.test.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"run": {
"default": "",
"items": [
{
"name": "lsp4xml",
"projectName": "lsp4xml",
"workingDirectory": "",
"args": [],
"vmargs": [],
"preLaunchTask": ""
}
]
},
"debug": {
"default": "",
"items": [
{
"name": "lsp4xml",
"projectName": "lsp4xml",
"workingDirectory": "",
"args": [],
"vmargs": [],
"preLaunchTask": ""
}
]
}
}
34 changes: 33 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,38 @@
//Use consistent indentation
"editor.detectIndentation": false,
"editor.tabSize": 4,
"editor.insertSpaces": false
"editor.insertSpaces": false,
"java.test.defaultConfig": "config-41b2e8",
"java.test.config": [
{
"run": {
"default": "",
"items": [
{
"name": "lsp4xml",
"projectName": "lsp4xml",
"workingDirectory": "",
"args": [],
"vmargs": [],
"preLaunchTask": ""
}
]
},
"debug": {
"default": "",
"items": [
{
"name": "lsp4xml",
"projectName": "lsp4xml",
"workingDirectory": "",
"args": [],
"vmargs": [],
"preLaunchTask": ""
}
]
},
"name": "config-41b2e8"
}
]

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ public class DOMAttr extends DOMNode implements org.w3c.dom.Attr {

private DOMNode nodeAttrValue;

private String value;
private String quotelessValue;//Value without quotes

private String originalValue;//Exact value from document

private final DOMNode ownerElement;

private boolean hasDelimiter; // has '='

class AttrNameOrValue extends DOMNode {

private final DOMAttr ownerAttr;
Expand Down Expand Up @@ -110,7 +114,7 @@ public DOMElement getOwnerElement() {
*/
@Override
public String getValue() {
return value;
return quotelessValue;
}

/*
Expand Down Expand Up @@ -157,23 +161,71 @@ public DOMNode getNodeAttrName() {
return nodeAttrName;
}

public void setDelimiter(boolean hasDelimiter) {
this.hasDelimiter = hasDelimiter;
}

public boolean hasDelimiter() {
return this.hasDelimiter;
}

/**
* Get original attribute value from the document.
*
* This will include quotations (", ').
* @return attribute value with quotations if it had them.
*/
public String getOriginalValue() {
return originalValue;
}

public void setValue(String value, int start, int end) {
this.value = getValue(value);
this.originalValue = value;
this.quotelessValue = convertToQuotelessValue(value);
this.nodeAttrValue = start != -1 ? new AttrNameOrValue(start, end, this) : null;
}

private static String getValue(String value) {
/**
* Returns a String of 'value' without surrounding quotes if it had them.
* @param value
* @return
*/
public static String convertToQuotelessValue(String value) {
if (value == null) {
return null;
}
if (value.isEmpty()) {
return value;
}
int start = value.charAt(0) == '\"' ? 1 : 0;
int end = value.charAt(value.length() - 1) == '\"' ? value.length() - 1 : value.length();
char quoteValue = value.charAt(0);
int start = quoteValue == '\"' || quoteValue == '\'' ? 1 : 0;
quoteValue = value.charAt(value.length() - 1);
int end = quoteValue == '\"' || quoteValue == '\'' ? value.length() - 1 : value.length();
return value.substring(start, end);
}

/**
* Checks if 'value' has matching surrounding quotations.
* @param value
* @return
*/
public static boolean isQuoted(String value) {
if (value == null) {
return false;
}
if (value.isEmpty()) {
return false;
}
char quoteValueStart = value.charAt(0);
boolean start = quoteValueStart == '\"' || quoteValueStart == '\'' ? true : false;
if(start == false) {
return false;
}
char quoteValueEnd = value.charAt(value.length() - 1);
boolean end = (quoteValueEnd == '\"' || quoteValueEnd == '\'') && quoteValueEnd == quoteValueStart ? true : false;
return end;
}

public DOMNode getNodeAttrValue() {
return nodeAttrValue;
}
Expand Down Expand Up @@ -201,7 +253,7 @@ public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
result = prime * result + ((quotelessValue == null) ? 0 : quotelessValue.hashCode());
return result;
}

Expand All @@ -219,10 +271,10 @@ public boolean equals(Object obj) {
return false;
} else if (!name.equals(other.name))
return false;
if (value == null) {
if (other.value != null)
if (quotelessValue == null) {
if (other.quotelessValue != null)
return false;
} else if (!value.equals(other.value))
} else if (!quotelessValue.equals(other.quotelessValue))
return false;
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@ public DOMDocument parse(TextDocument document, URIResolverExtensionManager reso
break;
}

case DelimiterAssign: {
if(attr != null) {
//Sets the value to the '=' position in case there is no AttributeValue
attr.setValue(null, scanner.getTokenOffset(), scanner.getTokenEnd());
attr.setDelimiter(true);
}
break;
}

case AttributeValue: {
String value = scanner.getTokenText();
if (curr.hasAttributes() && attr != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public class Constants {

public static final Pattern ATTRIBUTE_NAME_REGEX = Pattern.compile("^[^\\s\"'<>/=\\x00-\\x0F\\x7F\\x80-\\x9F]*");

public static final Pattern ATTRIBUTE_VALUE_REGEX = Pattern.compile("^[^\\s\"'`=<>\\/]+");
public static final Pattern ATTRIBUTE_VALUE_REGEX = Pattern.compile("^(\"[^\"]*\"?)|(\'[^\']*\'?)");

public static final Pattern URL_VALUE_REGEX = Pattern.compile("^(\"|\')[^<>\"]*(\"|\')");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ private Matcher getCachedMatcher(Pattern regex) {
if (matcher == null) {
matcher = regex.matcher(source);
regexpCache.put(regex, matcher);
} else {
matcher.reset(); // Cached regex caused issues, needed to reset it.
}
return matcher;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class XMLScanner implements Scanner {
TokenType tokenType;
String tokenError;

boolean hasSpaceAfterTag;

String lastTag;
String lastAttributeName;
String lastTypeValue;
Expand Down Expand Up @@ -243,7 +243,6 @@ TokenType internalScan() {
lastTypeValue = null;
lastAttributeName = null;
if (lastTag.length() > 0) {
hasSpaceAfterTag = false;
state = ScannerState.WithinTag;
return finishToken(offset, TokenType.StartTag);
}
Expand All @@ -262,21 +261,19 @@ TokenType internalScan() {

case WithinTag:
if (stream.skipWhitespace()) {
hasSpaceAfterTag = true; // remember that we have seen a whitespace
return finishToken(offset, TokenType.Whitespace);
}
if (stream.advanceIfChars(_QMA, _RAN)) { // ?>
state = ScannerState.WithinContent;
return finishToken(offset, TokenType.PrologEnd);
}
if (hasSpaceAfterTag) {

lastAttributeName = nextAttributeName();
if (lastAttributeName.length() > 0) {
state = ScannerState.AfterAttributeName;
hasSpaceAfterTag = false;
return finishToken(offset, TokenType.AttributeName);
}
}

if (stream.advanceIfChars(_FSL, _RAN)) { // />
state = ScannerState.WithinContent;
return finishToken(offset, TokenType.StartTagSelfClose);
Expand All @@ -294,7 +291,6 @@ TokenType internalScan() {

case AfterAttributeName:
if (stream.skipWhitespace()) {
hasSpaceAfterTag = true;
return finishToken(offset, TokenType.Whitespace);
}

Expand All @@ -315,25 +311,10 @@ TokenType internalScan() {
lastTypeValue = attributeValue;
}
state = ScannerState.WithinTag;
hasSpaceAfterTag = false;
return finishToken(offset, TokenType.AttributeValue);
}
int ch = stream.peekChar();
if (ch == _SQO || ch == _DQO || ch == _SIQ) { // " || " || '
stream.advance(1); // consume quote
if (stream.advanceUntilChar(ch)) {
stream.advance(1); // consume quote
}
if ("type".equals(lastAttributeName)) {
lastTypeValue = stream.getSource().substring(offset + 1, stream.pos() - 1);
}
state = ScannerState.WithinTag;
hasSpaceAfterTag = false;
return finishToken(offset, TokenType.AttributeValue);
}
state = ScannerState.WithinTag;
hasSpaceAfterTag = false;
return internalScan(); // no advance yet - jump to WithinTag
return internalScan();

// DTD

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ private int generate(Collection<CMAttributeDeclaration> attributes, int level, i
String value = generateAttributeValue(defaultValue, enumerationValues, canSupportSnippets, snippetIndex,
false);
if (attributesSize != 1) {
xml.addAttribute(attributeDeclaration.getName(), value, attributeIndex, level, tagName);
xml.addAttribute(attributeDeclaration.getName(), value, level, true);
} else {
xml.addSingleAttribute(attributeDeclaration.getName(), value);
xml.addSingleAttribute(attributeDeclaration.getName(), value, true);
}
attributeIndex++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,12 @@ private void format(DOMNode node, int level, int end, XMLBuilder xml) {
List<DOMAttr> attributes = element.getAttributeNodes();
if (attributes.size() == 1) {
DOMAttr singleAttribute = attributes.get(0);
xml.addSingleAttribute(singleAttribute.getName(), singleAttribute.getValue());
xml.addSingleAttribute(singleAttribute.getName(), singleAttribute.getOriginalValue());
} else {
int attributeIndex = 0;
for (DOMAttr attr : attributes) {
String attributeName = attr.getName();
xml.addAttribute(attributeName, attr.getValue(), attributeIndex, level, tag);
xml.addAttribute(attr, level);
attributeIndex++;
}
}
Expand Down Expand Up @@ -205,7 +205,7 @@ private void format(DOMNode node, int level, int end, XMLBuilder xml) {
if (value == null) {
continue;
}
xml.addSingleAttribute(name, value);
xml.addSingleAttribute(name, value, true);
}
}
xml.endPrologOrPI();
Expand Down
Loading

0 comments on commit 1301e93

Please sign in to comment.