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.IOException;
022 import java.util.TreeMap;
023 import java.util.ArrayList;
024 import java.io.PrintStream;
025 import java.io.OutputStream;
026 import java.io.UnsupportedEncodingException;
027 import java.util.Stack;
028
029 import org.apache.hadoop.classification.InterfaceAudience;
030 import org.apache.hadoop.classification.InterfaceStability;
031
032 /**
033 * XML Serializer.
034 *
035 * @deprecated Replaced by <a href="https://hadoop.apache.org/avro/">Avro</a>.
036 */
037 @Deprecated
038 @InterfaceAudience.Public
039 @InterfaceStability.Stable
040 public class XmlRecordOutput implements RecordOutput {
041
042 private PrintStream stream;
043
044 private int indent = 0;
045
046 private Stack<String> compoundStack;
047
048 private void putIndent() {
049 StringBuilder sb = new StringBuilder("");
050 for (int idx = 0; idx < indent; idx++) {
051 sb.append(" ");
052 }
053 stream.print(sb.toString());
054 }
055
056 private void addIndent() {
057 indent++;
058 }
059
060 private void closeIndent() {
061 indent--;
062 }
063
064 private void printBeginEnvelope(String tag) {
065 if (!compoundStack.empty()) {
066 String s = compoundStack.peek();
067 if ("struct".equals(s)) {
068 putIndent();
069 stream.print("<member>\n");
070 addIndent();
071 putIndent();
072 stream.print("<name>"+tag+"</name>\n");
073 putIndent();
074 stream.print("<value>");
075 } else if ("vector".equals(s)) {
076 stream.print("<value>");
077 } else if ("map".equals(s)) {
078 stream.print("<value>");
079 }
080 } else {
081 stream.print("<value>");
082 }
083 }
084
085 private void printEndEnvelope(String tag) {
086 if (!compoundStack.empty()) {
087 String s = compoundStack.peek();
088 if ("struct".equals(s)) {
089 stream.print("</value>\n");
090 closeIndent();
091 putIndent();
092 stream.print("</member>\n");
093 } else if ("vector".equals(s)) {
094 stream.print("</value>\n");
095 } else if ("map".equals(s)) {
096 stream.print("</value>\n");
097 }
098 } else {
099 stream.print("</value>\n");
100 }
101 }
102
103 private void insideVector(String tag) {
104 printBeginEnvelope(tag);
105 compoundStack.push("vector");
106 }
107
108 private void outsideVector(String tag) throws IOException {
109 String s = compoundStack.pop();
110 if (!"vector".equals(s)) {
111 throw new IOException("Error serializing vector.");
112 }
113 printEndEnvelope(tag);
114 }
115
116 private void insideMap(String tag) {
117 printBeginEnvelope(tag);
118 compoundStack.push("map");
119 }
120
121 private void outsideMap(String tag) throws IOException {
122 String s = compoundStack.pop();
123 if (!"map".equals(s)) {
124 throw new IOException("Error serializing map.");
125 }
126 printEndEnvelope(tag);
127 }
128
129 private void insideRecord(String tag) {
130 printBeginEnvelope(tag);
131 compoundStack.push("struct");
132 }
133
134 private void outsideRecord(String tag) throws IOException {
135 String s = compoundStack.pop();
136 if (!"struct".equals(s)) {
137 throw new IOException("Error serializing record.");
138 }
139 printEndEnvelope(tag);
140 }
141
142 /** Creates a new instance of XmlRecordOutput */
143 public XmlRecordOutput(OutputStream out) {
144 try {
145 stream = new PrintStream(out, true, "UTF-8");
146 compoundStack = new Stack<String>();
147 } catch (UnsupportedEncodingException ex) {
148 throw new RuntimeException(ex);
149 }
150 }
151
152 @Override
153 public void writeByte(byte b, String tag) throws IOException {
154 printBeginEnvelope(tag);
155 stream.print("<ex:i1>");
156 stream.print(Byte.toString(b));
157 stream.print("</ex:i1>");
158 printEndEnvelope(tag);
159 }
160
161 @Override
162 public void writeBool(boolean b, String tag) throws IOException {
163 printBeginEnvelope(tag);
164 stream.print("<boolean>");
165 stream.print(b ? "1" : "0");
166 stream.print("</boolean>");
167 printEndEnvelope(tag);
168 }
169
170 @Override
171 public void writeInt(int i, String tag) throws IOException {
172 printBeginEnvelope(tag);
173 stream.print("<i4>");
174 stream.print(Integer.toString(i));
175 stream.print("</i4>");
176 printEndEnvelope(tag);
177 }
178
179 @Override
180 public void writeLong(long l, String tag) throws IOException {
181 printBeginEnvelope(tag);
182 stream.print("<ex:i8>");
183 stream.print(Long.toString(l));
184 stream.print("</ex:i8>");
185 printEndEnvelope(tag);
186 }
187
188 @Override
189 public void writeFloat(float f, String tag) throws IOException {
190 printBeginEnvelope(tag);
191 stream.print("<ex:float>");
192 stream.print(Float.toString(f));
193 stream.print("</ex:float>");
194 printEndEnvelope(tag);
195 }
196
197 @Override
198 public void writeDouble(double d, String tag) throws IOException {
199 printBeginEnvelope(tag);
200 stream.print("<double>");
201 stream.print(Double.toString(d));
202 stream.print("</double>");
203 printEndEnvelope(tag);
204 }
205
206 @Override
207 public void writeString(String s, String tag) throws IOException {
208 printBeginEnvelope(tag);
209 stream.print("<string>");
210 stream.print(Utils.toXMLString(s));
211 stream.print("</string>");
212 printEndEnvelope(tag);
213 }
214
215 @Override
216 public void writeBuffer(Buffer buf, String tag)
217 throws IOException {
218 printBeginEnvelope(tag);
219 stream.print("<string>");
220 stream.print(Utils.toXMLBuffer(buf));
221 stream.print("</string>");
222 printEndEnvelope(tag);
223 }
224
225 @Override
226 public void startRecord(Record r, String tag) throws IOException {
227 insideRecord(tag);
228 stream.print("<struct>\n");
229 addIndent();
230 }
231
232 @Override
233 public void endRecord(Record r, String tag) throws IOException {
234 closeIndent();
235 putIndent();
236 stream.print("</struct>");
237 outsideRecord(tag);
238 }
239
240 @Override
241 public void startVector(ArrayList v, String tag) throws IOException {
242 insideVector(tag);
243 stream.print("<array>\n");
244 addIndent();
245 }
246
247 @Override
248 public void endVector(ArrayList v, String tag) throws IOException {
249 closeIndent();
250 putIndent();
251 stream.print("</array>");
252 outsideVector(tag);
253 }
254
255 @Override
256 public void startMap(TreeMap v, String tag) throws IOException {
257 insideMap(tag);
258 stream.print("<array>\n");
259 addIndent();
260 }
261
262 @Override
263 public void endMap(TreeMap v, String tag) throws IOException {
264 closeIndent();
265 putIndent();
266 stream.print("</array>");
267 outsideMap(tag);
268 }
269
270 }