Home | History | Annotate | Download | only in omadm
      1 package com.android.hotspot2.omadm;
      2 
      3 import java.io.IOException;
      4 import java.io.InputStream;
      5 import java.io.OutputStream;
      6 import java.util.Collection;
      7 import java.util.HashMap;
      8 import java.util.Iterator;
      9 import java.util.LinkedList;
     10 import java.util.List;
     11 import java.util.Map;
     12 
     13 public abstract class OMANode {
     14     private final OMAConstructed mParent;
     15     private final String mName;
     16     private final String mContext;
     17     private final Map<String, String> mAttributes;
     18 
     19     protected OMANode(OMAConstructed parent, String name, String context,
     20                       Map<String, String> avps) {
     21         mParent = parent;
     22         mName = name;
     23         mContext = context;
     24         mAttributes = avps;
     25     }
     26 
     27     protected static Map<String, String> buildAttributes(String[] avps) {
     28         if (avps == null) {
     29             return null;
     30         }
     31         Map<String, String> attributes = new HashMap<>();
     32         for (int n = 0; n < avps.length; n += 2) {
     33             attributes.put(avps[n], avps[n + 1]);
     34         }
     35         return attributes;
     36     }
     37 
     38     protected Map<String, String> getAttributes() {
     39         return mAttributes;
     40     }
     41 
     42     public OMAConstructed getParent() {
     43         return mParent;
     44     }
     45 
     46     public String getName() {
     47         return mName;
     48     }
     49 
     50     public String getContext() {
     51         return mContext;
     52     }
     53 
     54     public List<String> getPath() {
     55         LinkedList<String> path = new LinkedList<>();
     56         for (OMANode node = this; node != null; node = node.getParent()) {
     57             path.addFirst(node.getName());
     58         }
     59         return path;
     60     }
     61 
     62     public String getPathString() {
     63         StringBuilder sb = new StringBuilder();
     64         for (String element : getPath()) {
     65             sb.append('/').append(element);
     66         }
     67         return sb.toString();
     68     }
     69 
     70     public abstract OMANode reparent(OMAConstructed parent);
     71 
     72     public abstract String getScalarValue(Iterator<String> path) throws OMAException;
     73 
     74     public abstract OMANode getListValue(Iterator<String> path) throws OMAException;
     75 
     76     public abstract boolean isLeaf();
     77 
     78     public abstract Collection<OMANode> getChildren();
     79 
     80     public abstract OMANode getChild(String name) throws OMAException;
     81 
     82     public abstract String getValue();
     83 
     84     public abstract OMANode addChild(String name, String context, String value, String path)
     85             throws IOException;
     86 
     87     public abstract void marshal(OutputStream out, int level) throws IOException;
     88 
     89     public abstract void toString(StringBuilder sb, int level);
     90 
     91     public abstract void fillPayload(StringBuilder sb);
     92 
     93     public void toXml(StringBuilder sb) {
     94         sb.append('<').append(MOTree.NodeTag);
     95         if (mAttributes != null && !mAttributes.isEmpty()) {
     96             for (Map.Entry<String, String> avp : mAttributes.entrySet()) {
     97                 sb.append(' ').append(avp.getKey()).append("=\"")
     98                         .append(avp.getValue()).append('"');
     99             }
    100         }
    101         sb.append(">\n");
    102 
    103         sb.append('<').append(MOTree.NodeNameTag).append('>');
    104         sb.append(getName());
    105         sb.append("</").append(MOTree.NodeNameTag).append(">\n");
    106 
    107         fillPayload(sb);
    108 
    109         sb.append("</").append(MOTree.NodeTag).append(">\n");
    110     }
    111 
    112     @Override
    113     public String toString() {
    114         StringBuilder sb = new StringBuilder();
    115         toString(sb, 0);
    116         return sb.toString();
    117     }
    118 
    119     public static OMAConstructed unmarshal(InputStream in) throws IOException {
    120         OMANode node = buildNode(in, null);
    121         if (node == null || node.isLeaf()) {
    122             throw new IOException("Bad OMA tree");
    123         }
    124         unmarshal(in, (OMAConstructed) node);
    125         return (OMAConstructed) node;
    126     }
    127 
    128     private static void unmarshal(InputStream in, OMAConstructed parent) throws IOException {
    129         for (; ; ) {
    130             OMANode node = buildNode(in, parent);
    131             if (node == null) {
    132                 return;
    133             } else if (!node.isLeaf()) {
    134                 unmarshal(in, (OMAConstructed) node);
    135             }
    136         }
    137     }
    138 
    139     private static OMANode buildNode(InputStream in, OMAConstructed parent) throws IOException {
    140         String name = OMAConstants.deserializeString(in);
    141         if (name == null) {
    142             return null;
    143         }
    144 
    145         String urn = null;
    146         int next = in.read();
    147         if (next == '(') {
    148             urn = OMAConstants.readURN(in);
    149             next = in.read();
    150         }
    151 
    152         if (next == '=') {
    153             String value = OMAConstants.deserializeString(in);
    154             return parent.addChild(name, urn, value, null);
    155         } else if (next == '+') {
    156             if (parent != null) {
    157                 return parent.addChild(name, urn, null, null);
    158             } else {
    159                 return new OMAConstructed(null, name, urn);
    160             }
    161         } else {
    162             throw new IOException("Parse error: expected = or + after node name");
    163         }
    164     }
    165 }
    166