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