1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.hadoop.record; 20 21 import java.io.InputStream; 22 import java.io.IOException; 23 import java.util.ArrayList; 24 25 import org.apache.hadoop.classification.InterfaceAudience; 26 import org.apache.hadoop.classification.InterfaceStability; 27 import org.xml.sax.*; 28 import org.xml.sax.helpers.DefaultHandler; 29 import javax.xml.parsers.SAXParserFactory; 30 import javax.xml.parsers.SAXParser; 31 32 /** 33 * XML Deserializer. 34 * 35 * @deprecated Replaced by <a href="http://hadoop.apache.org/avro/">Avro</a>. 36 */ 37 @Deprecated 38 @InterfaceAudience.Public 39 @InterfaceStability.Stable 40 public class XmlRecordInput implements RecordInput { 41 42 static private class Value { 43 private String type; 44 private StringBuffer sb; 45 Value(String t)46 public Value(String t) { 47 type = t; 48 sb = new StringBuffer(); 49 } addChars(char[] buf, int offset, int len)50 public void addChars(char[] buf, int offset, int len) { 51 sb.append(buf, offset, len); 52 } getValue()53 public String getValue() { return sb.toString(); } getType()54 public String getType() { return type; } 55 } 56 57 private static class XMLParser extends DefaultHandler { 58 private boolean charsValid = false; 59 60 private ArrayList<Value> valList; 61 XMLParser(ArrayList<Value> vlist)62 private XMLParser(ArrayList<Value> vlist) { 63 valList = vlist; 64 } 65 66 @Override startDocument()67 public void startDocument() throws SAXException {} 68 69 @Override endDocument()70 public void endDocument() throws SAXException {} 71 72 @Override startElement(String ns, String sname, String qname, Attributes attrs)73 public void startElement(String ns, 74 String sname, 75 String qname, 76 Attributes attrs) throws SAXException { 77 charsValid = false; 78 if ("boolean".equals(qname) || 79 "i4".equals(qname) || 80 "int".equals(qname) || 81 "string".equals(qname) || 82 "double".equals(qname) || 83 "ex:i1".equals(qname) || 84 "ex:i8".equals(qname) || 85 "ex:float".equals(qname)) { 86 charsValid = true; 87 valList.add(new Value(qname)); 88 } else if ("struct".equals(qname) || 89 "array".equals(qname)) { 90 valList.add(new Value(qname)); 91 } 92 } 93 94 @Override endElement(String ns, String sname, String qname)95 public void endElement(String ns, 96 String sname, 97 String qname) throws SAXException { 98 charsValid = false; 99 if ("struct".equals(qname) || 100 "array".equals(qname)) { 101 valList.add(new Value("/"+qname)); 102 } 103 } 104 105 @Override characters(char buf[], int offset, int len)106 public void characters(char buf[], int offset, int len) 107 throws SAXException { 108 if (charsValid) { 109 Value v = valList.get(valList.size()-1); 110 v.addChars(buf, offset, len); 111 } 112 } 113 114 } 115 116 private class XmlIndex implements Index { 117 @Override done()118 public boolean done() { 119 Value v = valList.get(vIdx); 120 if ("/array".equals(v.getType())) { 121 valList.set(vIdx, null); 122 vIdx++; 123 return true; 124 } else { 125 return false; 126 } 127 } 128 @Override incr()129 public void incr() {} 130 } 131 132 private ArrayList<Value> valList; 133 private int vLen; 134 private int vIdx; 135 next()136 private Value next() throws IOException { 137 if (vIdx < vLen) { 138 Value v = valList.get(vIdx); 139 valList.set(vIdx, null); 140 vIdx++; 141 return v; 142 } else { 143 throw new IOException("Error in deserialization."); 144 } 145 } 146 147 /** Creates a new instance of XmlRecordInput */ XmlRecordInput(InputStream in)148 public XmlRecordInput(InputStream in) { 149 try{ 150 valList = new ArrayList<Value>(); 151 DefaultHandler handler = new XMLParser(valList); 152 SAXParserFactory factory = SAXParserFactory.newInstance(); 153 SAXParser parser = factory.newSAXParser(); 154 parser.parse(in, handler); 155 vLen = valList.size(); 156 vIdx = 0; 157 } catch (Exception ex) { 158 throw new RuntimeException(ex); 159 } 160 } 161 162 @Override readByte(String tag)163 public byte readByte(String tag) throws IOException { 164 Value v = next(); 165 if (!"ex:i1".equals(v.getType())) { 166 throw new IOException("Error deserializing "+tag+"."); 167 } 168 return Byte.parseByte(v.getValue()); 169 } 170 171 @Override readBool(String tag)172 public boolean readBool(String tag) throws IOException { 173 Value v = next(); 174 if (!"boolean".equals(v.getType())) { 175 throw new IOException("Error deserializing "+tag+"."); 176 } 177 return "1".equals(v.getValue()); 178 } 179 180 @Override readInt(String tag)181 public int readInt(String tag) throws IOException { 182 Value v = next(); 183 if (!"i4".equals(v.getType()) && 184 !"int".equals(v.getType())) { 185 throw new IOException("Error deserializing "+tag+"."); 186 } 187 return Integer.parseInt(v.getValue()); 188 } 189 190 @Override readLong(String tag)191 public long readLong(String tag) throws IOException { 192 Value v = next(); 193 if (!"ex:i8".equals(v.getType())) { 194 throw new IOException("Error deserializing "+tag+"."); 195 } 196 return Long.parseLong(v.getValue()); 197 } 198 199 @Override readFloat(String tag)200 public float readFloat(String tag) throws IOException { 201 Value v = next(); 202 if (!"ex:float".equals(v.getType())) { 203 throw new IOException("Error deserializing "+tag+"."); 204 } 205 return Float.parseFloat(v.getValue()); 206 } 207 208 @Override readDouble(String tag)209 public double readDouble(String tag) throws IOException { 210 Value v = next(); 211 if (!"double".equals(v.getType())) { 212 throw new IOException("Error deserializing "+tag+"."); 213 } 214 return Double.parseDouble(v.getValue()); 215 } 216 217 @Override readString(String tag)218 public String readString(String tag) throws IOException { 219 Value v = next(); 220 if (!"string".equals(v.getType())) { 221 throw new IOException("Error deserializing "+tag+"."); 222 } 223 return Utils.fromXMLString(v.getValue()); 224 } 225 226 @Override readBuffer(String tag)227 public Buffer readBuffer(String tag) throws IOException { 228 Value v = next(); 229 if (!"string".equals(v.getType())) { 230 throw new IOException("Error deserializing "+tag+"."); 231 } 232 return Utils.fromXMLBuffer(v.getValue()); 233 } 234 235 @Override startRecord(String tag)236 public void startRecord(String tag) throws IOException { 237 Value v = next(); 238 if (!"struct".equals(v.getType())) { 239 throw new IOException("Error deserializing "+tag+"."); 240 } 241 } 242 243 @Override endRecord(String tag)244 public void endRecord(String tag) throws IOException { 245 Value v = next(); 246 if (!"/struct".equals(v.getType())) { 247 throw new IOException("Error deserializing "+tag+"."); 248 } 249 } 250 251 @Override startVector(String tag)252 public Index startVector(String tag) throws IOException { 253 Value v = next(); 254 if (!"array".equals(v.getType())) { 255 throw new IOException("Error deserializing "+tag+"."); 256 } 257 return new XmlIndex(); 258 } 259 260 @Override endVector(String tag)261 public void endVector(String tag) throws IOException {} 262 263 @Override startMap(String tag)264 public Index startMap(String tag) throws IOException { 265 return startVector(tag); 266 } 267 268 @Override endMap(String tag)269 public void endMap(String tag) throws IOException { endVector(tag); } 270 271 } 272