001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.hadoop.record; 020 021import java.io.InputStream; 022import java.io.IOException; 023import java.util.ArrayList; 024 025import org.apache.hadoop.classification.InterfaceAudience; 026import org.apache.hadoop.classification.InterfaceStability; 027import org.xml.sax.*; 028import org.xml.sax.helpers.DefaultHandler; 029import javax.xml.parsers.SAXParserFactory; 030import javax.xml.parsers.SAXParser; 031 032/** 033 * XML Deserializer. 034 * 035 * @deprecated Replaced by <a href="https://hadoop.apache.org/avro/">Avro</a>. 036 */ 037@Deprecated 038@InterfaceAudience.Public 039@InterfaceStability.Stable 040public class XmlRecordInput implements RecordInput { 041 042 static private class Value { 043 private String type; 044 private StringBuffer sb; 045 046 public Value(String t) { 047 type = t; 048 sb = new StringBuffer(); 049 } 050 public void addChars(char[] buf, int offset, int len) { 051 sb.append(buf, offset, len); 052 } 053 public String getValue() { return sb.toString(); } 054 public String getType() { return type; } 055 } 056 057 private static class XMLParser extends DefaultHandler { 058 private boolean charsValid = false; 059 060 private ArrayList<Value> valList; 061 062 private XMLParser(ArrayList<Value> vlist) { 063 valList = vlist; 064 } 065 066 public void startDocument() throws SAXException {} 067 068 public void endDocument() throws SAXException {} 069 070 public void startElement(String ns, 071 String sname, 072 String qname, 073 Attributes attrs) throws SAXException { 074 charsValid = false; 075 if ("boolean".equals(qname) || 076 "i4".equals(qname) || 077 "int".equals(qname) || 078 "string".equals(qname) || 079 "double".equals(qname) || 080 "ex:i1".equals(qname) || 081 "ex:i8".equals(qname) || 082 "ex:float".equals(qname)) { 083 charsValid = true; 084 valList.add(new Value(qname)); 085 } else if ("struct".equals(qname) || 086 "array".equals(qname)) { 087 valList.add(new Value(qname)); 088 } 089 } 090 091 public void endElement(String ns, 092 String sname, 093 String qname) throws SAXException { 094 charsValid = false; 095 if ("struct".equals(qname) || 096 "array".equals(qname)) { 097 valList.add(new Value("/"+qname)); 098 } 099 } 100 101 public void characters(char buf[], int offset, int len) 102 throws SAXException { 103 if (charsValid) { 104 Value v = valList.get(valList.size()-1); 105 v.addChars(buf, offset, len); 106 } 107 } 108 109 } 110 111 private class XmlIndex implements Index { 112 public boolean done() { 113 Value v = valList.get(vIdx); 114 if ("/array".equals(v.getType())) { 115 valList.set(vIdx, null); 116 vIdx++; 117 return true; 118 } else { 119 return false; 120 } 121 } 122 public void incr() {} 123 } 124 125 private ArrayList<Value> valList; 126 private int vLen; 127 private int vIdx; 128 129 private Value next() throws IOException { 130 if (vIdx < vLen) { 131 Value v = valList.get(vIdx); 132 valList.set(vIdx, null); 133 vIdx++; 134 return v; 135 } else { 136 throw new IOException("Error in deserialization."); 137 } 138 } 139 140 /** Creates a new instance of XmlRecordInput */ 141 public XmlRecordInput(InputStream in) { 142 try{ 143 valList = new ArrayList<Value>(); 144 DefaultHandler handler = new XMLParser(valList); 145 SAXParserFactory factory = SAXParserFactory.newInstance(); 146 SAXParser parser = factory.newSAXParser(); 147 parser.parse(in, handler); 148 vLen = valList.size(); 149 vIdx = 0; 150 } catch (Exception ex) { 151 throw new RuntimeException(ex); 152 } 153 } 154 155 public byte readByte(String tag) throws IOException { 156 Value v = next(); 157 if (!"ex:i1".equals(v.getType())) { 158 throw new IOException("Error deserializing "+tag+"."); 159 } 160 return Byte.parseByte(v.getValue()); 161 } 162 163 public boolean readBool(String tag) throws IOException { 164 Value v = next(); 165 if (!"boolean".equals(v.getType())) { 166 throw new IOException("Error deserializing "+tag+"."); 167 } 168 return "1".equals(v.getValue()); 169 } 170 171 public int readInt(String tag) throws IOException { 172 Value v = next(); 173 if (!"i4".equals(v.getType()) && 174 !"int".equals(v.getType())) { 175 throw new IOException("Error deserializing "+tag+"."); 176 } 177 return Integer.parseInt(v.getValue()); 178 } 179 180 public long readLong(String tag) throws IOException { 181 Value v = next(); 182 if (!"ex:i8".equals(v.getType())) { 183 throw new IOException("Error deserializing "+tag+"."); 184 } 185 return Long.parseLong(v.getValue()); 186 } 187 188 public float readFloat(String tag) throws IOException { 189 Value v = next(); 190 if (!"ex:float".equals(v.getType())) { 191 throw new IOException("Error deserializing "+tag+"."); 192 } 193 return Float.parseFloat(v.getValue()); 194 } 195 196 public double readDouble(String tag) throws IOException { 197 Value v = next(); 198 if (!"double".equals(v.getType())) { 199 throw new IOException("Error deserializing "+tag+"."); 200 } 201 return Double.parseDouble(v.getValue()); 202 } 203 204 public String readString(String tag) throws IOException { 205 Value v = next(); 206 if (!"string".equals(v.getType())) { 207 throw new IOException("Error deserializing "+tag+"."); 208 } 209 return Utils.fromXMLString(v.getValue()); 210 } 211 212 public Buffer readBuffer(String tag) throws IOException { 213 Value v = next(); 214 if (!"string".equals(v.getType())) { 215 throw new IOException("Error deserializing "+tag+"."); 216 } 217 return Utils.fromXMLBuffer(v.getValue()); 218 } 219 220 public void startRecord(String tag) throws IOException { 221 Value v = next(); 222 if (!"struct".equals(v.getType())) { 223 throw new IOException("Error deserializing "+tag+"."); 224 } 225 } 226 227 public void endRecord(String tag) throws IOException { 228 Value v = next(); 229 if (!"/struct".equals(v.getType())) { 230 throw new IOException("Error deserializing "+tag+"."); 231 } 232 } 233 234 public Index startVector(String tag) throws IOException { 235 Value v = next(); 236 if (!"array".equals(v.getType())) { 237 throw new IOException("Error deserializing "+tag+"."); 238 } 239 return new XmlIndex(); 240 } 241 242 public void endVector(String tag) throws IOException {} 243 244 public Index startMap(String tag) throws IOException { 245 return startVector(tag); 246 } 247 248 public void endMap(String tag) throws IOException { endVector(tag); } 249 250}