| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.hadoop.record; |
| |
| import java.io.InputStream; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| |
| import org.apache.hadoop.classification.InterfaceAudience; |
| import org.apache.hadoop.classification.InterfaceStability; |
| import org.xml.sax.*; |
| import org.xml.sax.helpers.DefaultHandler; |
| import javax.xml.parsers.SAXParserFactory; |
| import javax.xml.parsers.SAXParser; |
| |
| /** |
| * XML Deserializer. |
| * |
| * @deprecated Replaced by <a href="http://hadoop.apache.org/avro/">Avro</a>. |
| */ |
| @Deprecated |
| @InterfaceAudience.Public |
| @InterfaceStability.Stable |
| public class XmlRecordInput implements RecordInput { |
| |
| static private class Value { |
| private String type; |
| private StringBuffer sb; |
| |
| public Value(String t) { |
| type = t; |
| sb = new StringBuffer(); |
| } |
| public void addChars(char[] buf, int offset, int len) { |
| sb.append(buf, offset, len); |
| } |
| public String getValue() { return sb.toString(); } |
| public String getType() { return type; } |
| } |
| |
| private static class XMLParser extends DefaultHandler { |
| private boolean charsValid = false; |
| |
| private ArrayList<Value> valList; |
| |
| private XMLParser(ArrayList<Value> vlist) { |
| valList = vlist; |
| } |
| |
| @Override |
| public void startDocument() throws SAXException {} |
| |
| @Override |
| public void endDocument() throws SAXException {} |
| |
| @Override |
| public void startElement(String ns, |
| String sname, |
| String qname, |
| Attributes attrs) throws SAXException { |
| charsValid = false; |
| if ("boolean".equals(qname) || |
| "i4".equals(qname) || |
| "int".equals(qname) || |
| "string".equals(qname) || |
| "double".equals(qname) || |
| "ex:i1".equals(qname) || |
| "ex:i8".equals(qname) || |
| "ex:float".equals(qname)) { |
| charsValid = true; |
| valList.add(new Value(qname)); |
| } else if ("struct".equals(qname) || |
| "array".equals(qname)) { |
| valList.add(new Value(qname)); |
| } |
| } |
| |
| @Override |
| public void endElement(String ns, |
| String sname, |
| String qname) throws SAXException { |
| charsValid = false; |
| if ("struct".equals(qname) || |
| "array".equals(qname)) { |
| valList.add(new Value("/"+qname)); |
| } |
| } |
| |
| @Override |
| public void characters(char buf[], int offset, int len) |
| throws SAXException { |
| if (charsValid) { |
| Value v = valList.get(valList.size()-1); |
| v.addChars(buf, offset, len); |
| } |
| } |
| |
| } |
| |
| private class XmlIndex implements Index { |
| @Override |
| public boolean done() { |
| Value v = valList.get(vIdx); |
| if ("/array".equals(v.getType())) { |
| valList.set(vIdx, null); |
| vIdx++; |
| return true; |
| } else { |
| return false; |
| } |
| } |
| @Override |
| public void incr() {} |
| } |
| |
| private ArrayList<Value> valList; |
| private int vLen; |
| private int vIdx; |
| |
| private Value next() throws IOException { |
| if (vIdx < vLen) { |
| Value v = valList.get(vIdx); |
| valList.set(vIdx, null); |
| vIdx++; |
| return v; |
| } else { |
| throw new IOException("Error in deserialization."); |
| } |
| } |
| |
| /** Creates a new instance of XmlRecordInput */ |
| public XmlRecordInput(InputStream in) { |
| try{ |
| valList = new ArrayList<Value>(); |
| DefaultHandler handler = new XMLParser(valList); |
| SAXParserFactory factory = SAXParserFactory.newInstance(); |
| SAXParser parser = factory.newSAXParser(); |
| parser.parse(in, handler); |
| vLen = valList.size(); |
| vIdx = 0; |
| } catch (Exception ex) { |
| throw new RuntimeException(ex); |
| } |
| } |
| |
| @Override |
| public byte readByte(String tag) throws IOException { |
| Value v = next(); |
| if (!"ex:i1".equals(v.getType())) { |
| throw new IOException("Error deserializing "+tag+"."); |
| } |
| return Byte.parseByte(v.getValue()); |
| } |
| |
| @Override |
| public boolean readBool(String tag) throws IOException { |
| Value v = next(); |
| if (!"boolean".equals(v.getType())) { |
| throw new IOException("Error deserializing "+tag+"."); |
| } |
| return "1".equals(v.getValue()); |
| } |
| |
| @Override |
| public int readInt(String tag) throws IOException { |
| Value v = next(); |
| if (!"i4".equals(v.getType()) && |
| !"int".equals(v.getType())) { |
| throw new IOException("Error deserializing "+tag+"."); |
| } |
| return Integer.parseInt(v.getValue()); |
| } |
| |
| @Override |
| public long readLong(String tag) throws IOException { |
| Value v = next(); |
| if (!"ex:i8".equals(v.getType())) { |
| throw new IOException("Error deserializing "+tag+"."); |
| } |
| return Long.parseLong(v.getValue()); |
| } |
| |
| @Override |
| public float readFloat(String tag) throws IOException { |
| Value v = next(); |
| if (!"ex:float".equals(v.getType())) { |
| throw new IOException("Error deserializing "+tag+"."); |
| } |
| return Float.parseFloat(v.getValue()); |
| } |
| |
| @Override |
| public double readDouble(String tag) throws IOException { |
| Value v = next(); |
| if (!"double".equals(v.getType())) { |
| throw new IOException("Error deserializing "+tag+"."); |
| } |
| return Double.parseDouble(v.getValue()); |
| } |
| |
| @Override |
| public String readString(String tag) throws IOException { |
| Value v = next(); |
| if (!"string".equals(v.getType())) { |
| throw new IOException("Error deserializing "+tag+"."); |
| } |
| return Utils.fromXMLString(v.getValue()); |
| } |
| |
| @Override |
| public Buffer readBuffer(String tag) throws IOException { |
| Value v = next(); |
| if (!"string".equals(v.getType())) { |
| throw new IOException("Error deserializing "+tag+"."); |
| } |
| return Utils.fromXMLBuffer(v.getValue()); |
| } |
| |
| @Override |
| public void startRecord(String tag) throws IOException { |
| Value v = next(); |
| if (!"struct".equals(v.getType())) { |
| throw new IOException("Error deserializing "+tag+"."); |
| } |
| } |
| |
| @Override |
| public void endRecord(String tag) throws IOException { |
| Value v = next(); |
| if (!"/struct".equals(v.getType())) { |
| throw new IOException("Error deserializing "+tag+"."); |
| } |
| } |
| |
| @Override |
| public Index startVector(String tag) throws IOException { |
| Value v = next(); |
| if (!"array".equals(v.getType())) { |
| throw new IOException("Error deserializing "+tag+"."); |
| } |
| return new XmlIndex(); |
| } |
| |
| @Override |
| public void endVector(String tag) throws IOException {} |
| |
| @Override |
| public Index startMap(String tag) throws IOException { |
| return startVector(tag); |
| } |
| |
| @Override |
| public void endMap(String tag) throws IOException { endVector(tag); } |
| |
| } |