OMANode.java revision af955ffa0082189fb688429732427c333f2491ce
1package com.android.server.wifi.hotspot2.omadm;
2
3import android.util.Log;
4
5import java.io.IOException;
6import java.io.InputStream;
7import java.io.OutputStream;
8import java.util.Collection;
9import java.util.Iterator;
10import java.util.LinkedList;
11import java.util.List;
12
13public abstract class OMANode {
14    private final OMANode mParent;
15    private final String mName;
16    private final String mContext;
17
18    protected OMANode(OMANode parent, String name, String context) {
19        mParent = parent;
20        mName = name;
21        mContext = context;
22    }
23
24    public OMANode getParent() {
25        return mParent;
26    }
27
28    public String getName() {
29        return mName;
30    }
31
32    public String getContext() {
33        return mContext;
34    }
35
36    public List<String> getPath() {
37        LinkedList<String> path = new LinkedList<String>();
38        for (OMANode node = this; node.getParent() != null; node = node.getParent())
39            path.addFirst(node.getName());
40        return path;
41    }
42
43    public String getPathString() {
44        StringBuilder sb = new StringBuilder();
45        for (String element : getPath()) {
46            sb.append('/').append(element);
47        }
48        return sb.toString();
49    }
50
51    public abstract String getScalarValue(Iterator<String> path) throws OMAException;
52
53    public abstract OMAConstructed getListValue(Iterator<String> path) throws OMAException;
54
55    public abstract boolean isLeaf();
56
57    public abstract Collection<OMANode> getChildren();
58
59    public abstract OMANode getChild(String name);
60
61    public abstract String getValue();
62
63    public abstract OMANode addChild(String name, String context, String value, String path)
64            throws IOException;
65
66    public abstract void marshal(OutputStream out, int level) throws IOException;
67
68    public abstract void toString(StringBuilder sb, int level);
69
70    @Override
71    public String toString() {
72        StringBuilder sb = new StringBuilder();
73        toString(sb, 0);
74        return sb.toString();
75    }
76
77    public static OMAConstructed unmarshal(InputStream in) throws IOException {
78        OMANode node = buildNode(in, null);
79        if (node == null || node.isLeaf())
80            throw new IOException("Bad OMA tree");
81        unmarshal(in, (OMAConstructed) node);
82        return (OMAConstructed) node;
83    }
84
85    private static void unmarshal(InputStream in, OMAConstructed parent) throws IOException {
86        for (; ; ) {
87            OMANode node = buildNode(in, parent);
88            if (node == null)
89                return;
90            else if (!node.isLeaf())
91                unmarshal(in, (OMAConstructed) node);
92        }
93    }
94
95    private static OMANode buildNode(InputStream in, OMAConstructed parent) throws IOException {
96        String name = OMAConstants.deserializeString(in);
97        if (name == null) {
98            Log.d("PARSE-LOG", "Could not read node name");
99            return null;
100        }
101
102        Log.d("PARSE-LOG", "name = " + name);
103
104        String urn = null;
105        int next = in.read();
106        if (next == '(') {
107            urn = OMAConstants.readURN(in);
108            Log.d("PARSE-LOG", "Urn = " + urn);
109            next = in.read();
110        }
111
112        if (next == '=') {
113            String value = OMAConstants.deserializeString(in);
114            Log.d("PARSE-LOG", "value = " + value);
115            return parent.addChild(name, urn, value, null);
116        } else if (next == '+') {
117            if (parent != null) {
118                Log.d("PARSE-LOG", "added child node " + name);
119                return parent.addChild(name, urn, null, null);
120            } else {
121                Log.d("PARSE-LOG", "created new node " + name);
122                return new OMAConstructed(null, name, urn);
123            }
124        }
125        else {
126            Log.d("PARSE-LOG", "parsing error");
127            throw new IOException("Parse error: expected = or + after node name");
128        }
129    }
130}
131