org.jsoup.nodes.Attributes Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of html2pdf Show documentation
Show all versions of html2pdf Show documentation
pdfHTML is an iText add-on that lets you to parse (X)HTML snippets and the associated CSS and converts
them to PDF.
package org.jsoup.nodes;
import org.jsoup.SerializationException;
import org.jsoup.helper.Validate;
import java.io.IOException;
import java.util.*;
/**
* The attributes of an Element.
*
* Attributes are treated as a map: there can be only one value associated with an attribute key.
*
*
* Attribute key and value comparisons are done case insensitively, and keys are normalised to
* lower-case.
*
*
* @author Jonathan Hedley, [email protected]
*/
public class Attributes implements Iterable, Cloneable {
protected static final String dataPrefix = "data-";
private LinkedHashMap attributes = null;
// linked hash map to preserve insertion order.
// null be default as so many elements have no attributes -- saves a good chunk of memory
/**
Get an attribute value by key.
@param key the attribute key
@return the attribute value if set; or empty string if not set.
@see #hasKey(String)
*/
public String get(String key) {
Validate.notEmpty(key);
if (attributes == null)
return "";
Attribute attr = attributes.get(key.toLowerCase());
return attr != null ? attr.getValue() : "";
}
/**
Set a new attribute, or replace an existing one by key.
@param key attribute key
@param value attribute value
*/
public void put(String key, String value) {
Attribute attr = new Attribute(key, value);
put(attr);
}
/**
Set a new boolean attribute, remove attribute if value is false.
@param key attribute key
@param value attribute value
*/
public void put(String key, boolean value) {
if (value)
put(new BooleanAttribute(key));
else
remove(key);
}
/**
Set a new attribute, or replace an existing one by key.
@param attribute attribute
*/
public void put(Attribute attribute) {
Validate.notNull(attribute);
if (attributes == null)
attributes = new LinkedHashMap(2);
attributes.put(attribute.getKey(), attribute);
}
/**
Remove an attribute by key.
@param key attribute key to remove
*/
public void remove(String key) {
Validate.notEmpty(key);
if (attributes == null)
return;
attributes.remove(key.toLowerCase());
}
/**
Tests if these attributes contain an attribute with this key.
@param key key to check for
@return true if key exists, false otherwise
*/
public boolean hasKey(String key) {
return attributes != null && attributes.containsKey(key.toLowerCase());
}
/**
Get the number of attributes in this set.
@return size
*/
public int size() {
if (attributes == null)
return 0;
return attributes.size();
}
/**
Add all the attributes from the incoming set to this set.
@param incoming attributes to add to these attributes.
*/
public void addAll(Attributes incoming) {
if (incoming.size() == 0)
return;
if (attributes == null)
attributes = new LinkedHashMap(incoming.size());
attributes.putAll(incoming.attributes);
}
public Iterator iterator() {
return asList().iterator();
}
/**
Get the attributes as a List, for iteration. Do not modify the keys of the attributes via this view, as changes
to keys will not be recognised in the containing set.
@return an view of the attributes as a List.
*/
public List asList() {
if (attributes == null)
return Collections.emptyList();
List list = new ArrayList(attributes.size());
for (Map.Entry entry : attributes.entrySet()) {
list.add(entry.getValue());
}
return Collections.unmodifiableList(list);
}
/**
* Retrieves a filtered view of attributes that are HTML5 custom data attributes; that is, attributes with keys
* starting with {@code data-}.
* @return map of custom data attributes.
*/
public Map dataset() {
return new Dataset();
}
/**
Get the HTML representation of these attributes.
@return HTML
@throws SerializationException if the HTML representation of the attributes cannot be constructed.
*/
public String html() {
StringBuilder accum = new StringBuilder();
try {
html(accum, (new Document("")).outputSettings()); // output settings a bit funky, but this html() seldom used
} catch (IOException e) { // ought never happen
throw new SerializationException(e);
}
return accum.toString();
}
void html(Appendable accum, Document.OutputSettings out) throws IOException {
if (attributes == null)
return;
for (Map.Entry entry : attributes.entrySet()) {
Attribute attribute = entry.getValue();
accum.append(" ");
attribute.html(accum, out);
}
}
@Override
public String toString() {
return html();
}
/**
* Checks if these attributes are equal to another set of attributes, by comparing the two sets
* @param o attributes to compare with
* @return if both sets of attributes have the same content
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Attributes)) return false;
Attributes that = (Attributes) o;
return !(attributes != null ? !attributes.equals(that.attributes) : that.attributes != null);
}
/**
* Calculates the hashcode of these attributes, by iterating all attributes and summing their hashcodes.
* @return calculated hashcode
*/
@Override
public int hashCode() {
return attributes != null ? attributes.hashCode() : 0;
}
@Override
public Object clone() {
if (attributes == null)
return new Attributes();
Attributes clone;
try {
clone = (Attributes) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
clone.attributes = new LinkedHashMap(attributes.size());
for (Attribute attribute: this)
clone.attributes.put(attribute.getKey(), (Attribute)attribute.clone());
return clone;
}
private class Dataset extends AbstractMap {
private Dataset() {
if (attributes == null)
attributes = new LinkedHashMap(2);
}
public Set> entrySet() {
return new EntrySet();
}
public String put(String key, String value) {
String dataKey = dataKey(key);
String oldValue = hasKey(dataKey) ? attributes.get(dataKey).getValue() : null;
Attribute attr = new Attribute(dataKey, value);
attributes.put(dataKey, attr);
return oldValue;
}
private class EntrySet extends AbstractSet> {
@Override
public Iterator> iterator() {
return new DatasetIterator();
}
@Override
public int size() {
int count = 0;
Iterator iter = new DatasetIterator();
while (iter.hasNext())
count++;
return count;
}
}
private class DatasetIterator implements Iterator> {
private Iterator attrIter = attributes.values().iterator();
private Attribute attr;
public boolean hasNext() {
while (attrIter.hasNext()) {
attr = attrIter.next();
if (attr.isDataAttribute()) return true;
}
return false;
}
public Entry next() {
return new Attribute(attr.getKey().substring(dataPrefix.length()), attr.getValue());
}
public void remove() {
attributes.remove(attr.getKey());
}
}
}
private static String dataKey(String key) {
return dataPrefix + key;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy