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="http://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 public void writeByte(byte b, String tag) throws IOException {
153 printBeginEnvelope(tag);
154 stream.print("<ex:i1>");
155 stream.print(Byte.toString(b));
156 stream.print("</ex:i1>");
157 printEndEnvelope(tag);
158 }
159
160 public void writeBool(boolean b, String tag) throws IOException {
161 printBeginEnvelope(tag);
162 stream.print("<boolean>");
163 stream.print(b ? "1" : "0");
164 stream.print("</boolean>");
165 printEndEnvelope(tag);
166 }
167
168 public void writeInt(int i, String tag) throws IOException {
169 printBeginEnvelope(tag);
170 stream.print("<i4>");
171 stream.print(Integer.toString(i));
172 stream.print("</i4>");
173 printEndEnvelope(tag);
174 }
175
176 public void writeLong(long l, String tag) throws IOException {
177 printBeginEnvelope(tag);
178 stream.print("<ex:i8>");
179 stream.print(Long.toString(l));
180 stream.print("</ex:i8>");
181 printEndEnvelope(tag);
182 }
183
184 public void writeFloat(float f, String tag) throws IOException {
185 printBeginEnvelope(tag);
186 stream.print("<ex:float>");
187 stream.print(Float.toString(f));
188 stream.print("</ex:float>");
189 printEndEnvelope(tag);
190 }
191
192 public void writeDouble(double d, String tag) throws IOException {
193 printBeginEnvelope(tag);
194 stream.print("<double>");
195 stream.print(Double.toString(d));
196 stream.print("</double>");
197 printEndEnvelope(tag);
198 }
199
200 public void writeString(String s, String tag) throws IOException {
201 printBeginEnvelope(tag);
202 stream.print("<string>");
203 stream.print(Utils.toXMLString(s));
204 stream.print("</string>");
205 printEndEnvelope(tag);
206 }
207
208 public void writeBuffer(Buffer buf, String tag)
209 throws IOException {
210 printBeginEnvelope(tag);
211 stream.print("<string>");
212 stream.print(Utils.toXMLBuffer(buf));
213 stream.print("</string>");
214 printEndEnvelope(tag);
215 }
216
217 public void startRecord(Record r, String tag) throws IOException {
218 insideRecord(tag);
219 stream.print("<struct>\n");
220 addIndent();
221 }
222
223 public void endRecord(Record r, String tag) throws IOException {
224 closeIndent();
225 putIndent();
226 stream.print("</struct>");
227 outsideRecord(tag);
228 }
229
230 public void startVector(ArrayList v, String tag) throws IOException {
231 insideVector(tag);
232 stream.print("<array>\n");
233 addIndent();
234 }
235
236 public void endVector(ArrayList v, String tag) throws IOException {
237 closeIndent();
238 putIndent();
239 stream.print("</array>");
240 outsideVector(tag);
241 }
242
243 public void startMap(TreeMap v, String tag) throws IOException {
244 insideMap(tag);
245 stream.print("<array>\n");
246 addIndent();
247 }
248
249 public void endMap(TreeMap v, String tag) throws IOException {
250 closeIndent();
251 putIndent();
252 stream.print("</array>");
253 outsideMap(tag);
254 }
255
256 }