SOAPParser.java revision 71a988c8e9859244b83cd55bb6b6ee913fcaf95c
1package com.android.server.wifi.hotspot2.omadm; 2 3import org.xml.sax.Attributes; 4import org.xml.sax.SAXException; 5import org.xml.sax.helpers.DefaultHandler; 6 7import javax.xml.parsers.ParserConfigurationException; 8import javax.xml.parsers.SAXParser; 9import javax.xml.parsers.SAXParserFactory; 10 11import java.io.*; 12import java.util.*; 13 14import static com.android.server.wifi.hotspot2.omadm.RequestDetail.RequestFields.*; 15 16public class SOAPParser extends DefaultHandler { 17 private XMLNode mRoot; 18 private XMLNode mCurrent; 19 20 private static String[] TagOnly = new String[0]; 21 private static final Map<RequestDetail.RequestFields, String> sSoapMappings = 22 new EnumMap<RequestDetail.RequestFields, String>(RequestDetail.RequestFields.class); 23 private static final Map<String, RequestDetail.RequestFields> sRevMappings = 24 new HashMap<String, RequestDetail.RequestFields>(); 25 private static final Map<String, String[]> sSoapAttributes = 26 new HashMap<String, String[]>(); 27 28 static { 29 sSoapMappings.put(SPPVersion, "spp:sppVersion"); 30 sSoapMappings.put(RedirectURI, "redirectURI"); 31 sSoapMappings.put(RequestReason, "requestReason"); 32 sSoapMappings.put(SessionID, "spp:sessionID"); 33 sSoapMappings.put(SupportedVersions, "spp:supportedSPPVersions"); 34 sSoapMappings.put(SupportedMOs, "spp:supportedMOList"); 35 36 for (Map.Entry<RequestDetail.RequestFields, String> entry : sSoapMappings.entrySet()) { 37 sRevMappings.put(entry.getValue(), entry.getKey()); 38 } 39 40 // Really: The first element inside the body 41 sSoapAttributes.put("spp:sppPostDevDataResponse", new String[]{ 42 sSoapMappings.get(SPPVersion), 43 sSoapMappings.get(RedirectURI), 44 sSoapMappings.get(RequestReason), 45 sSoapMappings.get(SessionID)}); 46 47 sSoapAttributes.put(sSoapMappings.get(SupportedVersions), TagOnly); 48 sSoapAttributes.put(sSoapMappings.get(SupportedMOs), TagOnly); 49 } 50 51 public XMLNode parse(File file) throws IOException, ParserConfigurationException, SAXException { 52 SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); 53 54 BufferedInputStream in = new BufferedInputStream(new FileInputStream(file)); 55 try { 56 parser.parse(in, this); 57 } finally { 58 in.close(); 59 } 60 return mRoot; 61 } 62 63 @Override 64 public void startElement(String uri, String localName, String qName, Attributes attributes) 65 throws SAXException { 66 XMLNode parent = mCurrent; 67 68 mCurrent = new XMLNode(mCurrent, qName, attributes); 69 System.out.println("Added " + mCurrent.getTag() + ", atts " + mCurrent.getAttributes()); 70 71 if (mRoot == null) 72 mRoot = mCurrent; 73 else 74 parent.addChild(mCurrent); 75 } 76 77 @Override 78 public void endElement(String uri, String localName, String qName) throws SAXException { 79 if (!qName.equals(mCurrent.getTag())) 80 throw new SAXException("End tag '" + qName + "' doesn't match current node: " + 81 mCurrent); 82 83 try { 84 mCurrent.close(); 85 } catch (IOException ioe) { 86 throw new SAXException("Failed to close element", ioe); 87 } 88 89 mCurrent = mCurrent.getParent(); 90 } 91 92 @Override 93 public void characters(char[] ch, int start, int length) throws SAXException { 94 mCurrent.addText(ch, start, length); 95 } 96 97 public RequestDetail getRequestDetail() { 98 Map<RequestDetail.RequestFields, String> values = 99 new EnumMap<RequestDetail.RequestFields, String>(RequestDetail.RequestFields.class); 100 List<MOTree> mos = new ArrayList<MOTree>(); 101 extractFields(mRoot, values, mos); 102 return new RequestDetail(values, mos); 103 } 104 105 private static void extractFields(XMLNode node, Map<RequestDetail.RequestFields, 106 String> values, Collection<MOTree> mos) { 107 String[] attributes = sSoapAttributes.get(node.getTag()); 108 109 if (attributes != null) { 110 if (attributes.length == 0) { 111 RequestDetail.RequestFields field = sRevMappings.get(node.getTag()); 112 values.put(field, node.getText()); 113 } else { 114 for (String attribute : attributes) { 115 RequestDetail.RequestFields field = sRevMappings.get(attribute); 116 if (field != null) { 117 String value = node.getAttributeValue(attribute); 118 119 if (value != null) 120 values.put(field, value); 121 } 122 } 123 } 124 } 125 126 if (node.getMOTree() != null) 127 mos.add(node.getMOTree()); 128 129 for (XMLNode child : node.getChildren()) { 130 extractFields(child, values, mos); 131 } 132 } 133 134 public static void main(String[] args) throws Exception { 135 SOAPParser soapParser = new SOAPParser(); 136 XMLNode root = soapParser.parse(new File(args[0])); 137 //System.out.println( root ); 138 System.out.println(soapParser.getRequestDetail()); 139 System.out.println("Marshalled: "); 140 for (MOTree mo : soapParser.getRequestDetail().getMOs()) { 141 ByteArrayOutputStream out = new ByteArrayOutputStream(); 142 mo.marshal(out); 143 System.out.println(out.toString()); 144 MOTree back = MOTree.unmarshal(new ByteArrayInputStream(out.toByteArray())); 145 System.out.println(back); 146 } 147 System.out.println("---"); 148 } 149} 150