1package com.android.server.wifi.hotspot2.omadm; 2 3import org.xml.sax.Attributes; 4import org.xml.sax.SAXException; 5 6import java.io.IOException; 7import java.util.ArrayList; 8import java.util.Arrays; 9import java.util.Collections; 10import java.util.HashMap; 11import java.util.List; 12import java.util.Map; 13 14public class XMLNode { 15 private final String mTag; 16 private final Map<String, NodeAttribute> mAttributes; 17 private final List<XMLNode> mChildren; 18 private final XMLNode mParent; 19 private MOTree mMO; 20 private StringBuilder mTextBuilder; 21 private String mText; 22 23 public XMLNode(XMLNode parent, String tag, Attributes attributes) throws SAXException { 24 mTag = tag; 25 26 mAttributes = new HashMap<String, NodeAttribute>(); 27 28 if (attributes.getLength() > 0) { 29 for (int n = 0; n < attributes.getLength(); n++) 30 mAttributes.put(attributes.getQName(n), new NodeAttribute(attributes.getQName(n), 31 attributes.getType(n), attributes.getValue(n))); 32 } 33 34 mParent = parent; 35 mChildren = new ArrayList<XMLNode>(); 36 37 mTextBuilder = new StringBuilder(); 38 } 39 40 public void addText(char[] chs, int start, int length) { 41 String s = new String(chs, start, length); 42 String trimmed = s.trim(); 43 if (trimmed.isEmpty()) 44 return; 45 46 if (s.charAt(0) != trimmed.charAt(0)) 47 mTextBuilder.append(' '); 48 mTextBuilder.append(trimmed); 49 if (s.charAt(s.length() - 1) != trimmed.charAt(trimmed.length() - 1)) 50 mTextBuilder.append(' '); 51 } 52 53 public void addChild(XMLNode child) { 54 mChildren.add(child); 55 } 56 57 public void close() throws IOException, SAXException { 58 String text = mTextBuilder.toString().trim(); 59 StringBuilder filtered = new StringBuilder(text.length()); 60 for (int n = 0; n < text.length(); n++) { 61 char ch = text.charAt(n); 62 if (ch >= ' ') 63 filtered.append(ch); 64 } 65 66 mText = filtered.toString(); 67 mTextBuilder = null; 68 69 if (OMAConstants.isMOContainer(mTag)) { 70 NodeAttribute urn = mAttributes.get(OMAConstants.ATTR_URN); 71 OMAParser omaParser = new OMAParser(); 72 mMO = omaParser.parse(mText, urn.getValue()); 73 } 74 } 75 76 public String getTag() { 77 return mTag; 78 } 79 80 public XMLNode getParent() { 81 return mParent; 82 } 83 84 public String getText() { 85 return mText; 86 } 87 88 public Map<String, NodeAttribute> getAttributes() { 89 return Collections.unmodifiableMap(mAttributes); 90 } 91 92 public String getAttributeValue(String name) { 93 NodeAttribute nodeAttribute = mAttributes.get(name); 94 return nodeAttribute != null ? nodeAttribute.getValue() : null; 95 } 96 97 public List<XMLNode> getChildren() { 98 return mChildren; 99 } 100 101 public MOTree getMOTree() { 102 return mMO; 103 } 104 105 private void toString(char[] indent, StringBuilder sb) { 106 Arrays.fill(indent, ' '); 107 108 sb.append(indent).append('<').append(mTag).append("> ").append(mAttributes.values()); 109 110 if (mMO != null) 111 sb.append('\n').append(mMO); 112 else if (!mText.isEmpty()) 113 sb.append(", text: ").append(mText); 114 115 sb.append('\n'); 116 117 char[] subIndent = Arrays.copyOf(indent, indent.length + 2); 118 for (XMLNode child : mChildren) 119 child.toString(subIndent, sb); 120 } 121 122 @Override 123 public String toString() { 124 StringBuilder sb = new StringBuilder(); 125 toString(new char[0], sb); 126 return sb.toString(); 127 } 128} 129