171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistpackage com.android.server.wifi.hotspot2.omadm;
271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistimport org.xml.sax.Attributes;
471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistimport org.xml.sax.SAXException;
571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistimport java.io.IOException;
771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistimport java.util.ArrayList;
871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistimport java.util.Arrays;
971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistimport java.util.Collections;
1071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistimport java.util.HashMap;
1171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistimport java.util.List;
1271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistimport java.util.Map;
1371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
1471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistpublic class XMLNode {
1571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    private final String mTag;
1671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    private final Map<String, NodeAttribute> mAttributes;
1771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    private final List<XMLNode> mChildren;
1871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    private final XMLNode mParent;
1971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    private MOTree mMO;
2071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    private StringBuilder mTextBuilder;
2171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    private String mText;
2271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
2371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    public XMLNode(XMLNode parent, String tag, Attributes attributes) throws SAXException {
2471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        mTag = tag;
2571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
2671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        mAttributes = new HashMap<String, NodeAttribute>();
2771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
2871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        if (attributes.getLength() > 0) {
2971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist            for (int n = 0; n < attributes.getLength(); n++)
3071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist                mAttributes.put(attributes.getQName(n), new NodeAttribute(attributes.getQName(n),
3171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist                        attributes.getType(n), attributes.getValue(n)));
3271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        }
3371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
3471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        mParent = parent;
3571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        mChildren = new ArrayList<XMLNode>();
3671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
3771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        mTextBuilder = new StringBuilder();
3871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
3971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
4071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    public void addText(char[] chs, int start, int length) {
4171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        String s = new String(chs, start, length);
4271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        String trimmed = s.trim();
4371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        if (trimmed.isEmpty())
4471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist            return;
4571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
4671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        if (s.charAt(0) != trimmed.charAt(0))
4771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist            mTextBuilder.append(' ');
4871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        mTextBuilder.append(trimmed);
4971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        if (s.charAt(s.length() - 1) != trimmed.charAt(trimmed.length() - 1))
5071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist            mTextBuilder.append(' ');
5171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
5271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
5371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    public void addChild(XMLNode child) {
5471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        mChildren.add(child);
5571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
5671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
5771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    public void close() throws IOException, SAXException {
5871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        String text = mTextBuilder.toString().trim();
5971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        StringBuilder filtered = new StringBuilder(text.length());
6071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        for (int n = 0; n < text.length(); n++) {
6171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist            char ch = text.charAt(n);
6271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist            if (ch >= ' ')
6371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist                filtered.append(ch);
6471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        }
6571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
6671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        mText = filtered.toString();
6771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        mTextBuilder = null;
6871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
6971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        if (OMAConstants.isMOContainer(mTag)) {
7071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist            NodeAttribute urn = mAttributes.get(OMAConstants.ATTR_URN);
7171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist            OMAParser omaParser = new OMAParser();
7271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist            mMO = omaParser.parse(mText, urn.getValue());
7371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        }
7471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
7571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
7671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    public String getTag() {
7771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        return mTag;
7871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
7971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
8071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    public XMLNode getParent() {
8171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        return mParent;
8271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
8371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
8471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    public String getText() {
8571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        return mText;
8671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
8771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
8871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    public Map<String, NodeAttribute> getAttributes() {
8971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        return Collections.unmodifiableMap(mAttributes);
9071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
9171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
9271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    public String getAttributeValue(String name) {
9371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        NodeAttribute nodeAttribute = mAttributes.get(name);
9471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        return nodeAttribute != null ? nodeAttribute.getValue() : null;
9571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
9671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
9771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    public List<XMLNode> getChildren() {
9871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        return mChildren;
9971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
10071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
10171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    public MOTree getMOTree() {
10271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        return mMO;
10371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
10471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
10571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    private void toString(char[] indent, StringBuilder sb) {
10671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        Arrays.fill(indent, ' ');
10771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
10871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        sb.append(indent).append('<').append(mTag).append("> ").append(mAttributes.values());
10971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
11071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        if (mMO != null)
11171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist            sb.append('\n').append(mMO);
11271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        else if (!mText.isEmpty())
11371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist            sb.append(", text: ").append(mText);
11471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
11571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        sb.append('\n');
11671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
11771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        char[] subIndent = Arrays.copyOf(indent, indent.length + 2);
11871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        for (XMLNode child : mChildren)
11971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist            child.toString(subIndent, sb);
12071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
12171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist
12271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    @Override
12371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    public String toString() {
12471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        StringBuilder sb = new StringBuilder();
12571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        toString(new char[0], sb);
12671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist        return sb.toString();
12771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist    }
12871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist}
129