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 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}