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.IOException; 022import java.util.TreeMap; 023import java.util.ArrayList; 024import java.io.PrintStream; 025import java.io.OutputStream; 026import java.io.UnsupportedEncodingException; 027import java.util.Stack; 028 029import org.apache.hadoop.classification.InterfaceAudience; 030import 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 040public 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}