com.github.davidmoten.aws.lw.client.xml.builder.Xml Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aws-lightweight-client-java Show documentation
Show all versions of aws-lightweight-client-java Show documentation
Lightweight client for all AWS services (but still with useful builders and XML parser)
The newest version!
package com.github.davidmoten.aws.lw.client.xml.builder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.github.davidmoten.aws.lw.client.internal.util.Preconditions;
public final class Xml {
private final String name;
private final Xml parent;
private Map attributes = new HashMap<>();
private List children = new ArrayList<>();
private String content;
private boolean prelude = true;
private Xml(String name) {
this(name, null);
}
private Xml(String name, Xml parent) {
checkPresent(name, "name");
this.name = name;
this.parent = parent;
}
public static Xml create(String name) {
return new Xml(name);
}
public Xml excludePrelude() {
Xml xml = this;
while (xml.parent != null) {
xml = xml.parent;
}
xml.prelude = false;
return this;
}
public Xml element(String name) {
checkPresent(name, "name");
Preconditions.checkArgument(content == null,
"content cannot be already specified if starting a child element");
Xml xml = new Xml(name, this);
this.children.add(xml);
return xml;
}
public Xml e(String name) {
return element(name);
}
public Xml attribute(String name, String value) {
checkPresent(name, "name");
Preconditions.checkNotNull(value);
this.attributes.put(name, value);
return this;
}
public Xml a(String name, String value) {
return attribute(name, value);
}
public Xml content(String content) {
Preconditions.checkArgument(children.isEmpty());
this.content = content;
return this;
}
public Xml up() {
return parent;
}
private static void checkPresent(String s, String name) {
if (s == null || s.trim().isEmpty()) {
throw new IllegalArgumentException(name + " must be non-null and non-blank");
}
}
private String toString(String indent) {
StringBuilder b = new StringBuilder();
if (indent.length() == 0 && prelude) {
b.append("\n");
}
// TODO encode attributes and content for xml
String atts = attributes.entrySet().stream().map(
entry -> " " + entry.getKey() + "=\"" + encodeXml(entry.getValue(), true) + "\"")
.collect(Collectors.joining());
b.append(String.format("%s<%s%s>", indent, name, atts));
if (content != null) {
b.append(encodeXml(content, false));
b.append(String.format("%s>", name));
if (parent != null) {
b.append("\n");
}
} else {
b.append("\n");
for (Xml xml : children) {
b.append(xml.toString(indent + " "));
}
b.append(String.format("%s%s>", indent, name));
if (parent != null) {
b.append("\n");
}
}
return b.toString();
}
public String toString() {
Xml xml = this;
while (xml.parent != null) {
xml = xml.parent;
}
return xml.toString("");
}
private static final Map CONTENT_CHARACTER_MAP = createContentCharacterMap();
private static final Map ATTRIBUTE_CHARACTER_MAP = createAttributeCharacterMap();
private static Map createContentCharacterMap() {
Map m = new HashMap<>();
m.put((int) '&', "&");
m.put((int) '>', ">");
m.put((int) '<', "<");
return m;
}
private static Map createAttributeCharacterMap() {
Map m = new HashMap<>();
m.put((int) '\'', "'");
m.put((int) '\"', """);
return m;
}
private static String encodeXml(CharSequence s, boolean isAttribute) {
StringBuilder b = new StringBuilder();
int len = s.length();
for (int i = 0; i < len; i++) {
int c = s.charAt(i);
if (c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
c = ((c - 0xd7c0) << 10) | (s.charAt(++i) & 0x3ff); // UTF16 decode
}
if (c < 0x80) { // ASCII range: test most common case first
if (c < 0x20 && (c != '\t' && c != '\r' && c != '\n')) {
// Illegal XML character, even encoded. Skip or substitute
b.append("�"); // Unicode replacement character
} else {
String r = CONTENT_CHARACTER_MAP.get(c);
if (r != null) {
b.append(r);
} else if (isAttribute) {
String r2 = ATTRIBUTE_CHARACTER_MAP.get(c);
if (r2 != null) {
b.append(r2);
} else {
b.append((char) c);
}
} else {
b.append((char) c);
}
}
} else if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) {
// Illegal XML character, even encoded. Skip or substitute
b.append("�"); // Unicode replacement character
} else {
b.append("");
b.append(Integer.toHexString(c));
b.append(';');
}
}
return b.toString();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy