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
019 package org.apache.hadoop.record;
020
021 import java.io.InputStream;
022 import java.io.IOException;
023 import java.util.ArrayList;
024
025 import org.apache.hadoop.classification.InterfaceAudience;
026 import org.apache.hadoop.classification.InterfaceStability;
027 import org.xml.sax.*;
028 import org.xml.sax.helpers.DefaultHandler;
029 import javax.xml.parsers.SAXParserFactory;
030 import javax.xml.parsers.SAXParser;
031
032 /**
033 * XML Deserializer.
034 *
035 * @deprecated Replaced by <a href="http://hadoop.apache.org/avro/">Avro</a>.
036 */
037 @Deprecated
038 @InterfaceAudience.Public
039 @InterfaceStability.Stable
040 public 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 }