001 /** 002 * Copyright (c) 2010 Yahoo! Inc. All rights reserved. 003 * Licensed under the Apache License, Version 2.0 (the "License"); 004 * you may not use this file except in compliance with the License. 005 * You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software 010 * distributed under the License is distributed on an "AS IS" BASIS, 011 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 * See the License for the specific language governing permissions and 013 * limitations under the License. See accompanying LICENSE file. 014 */ 015 package org.apache.oozie.util; 016 017 import org.apache.hadoop.io.Writable; 018 import org.apache.hadoop.util.ReflectionUtils; 019 020 import java.io.ByteArrayInputStream; 021 import java.io.ByteArrayOutputStream; 022 import java.io.DataInputStream; 023 import java.io.DataOutputStream; 024 import java.io.IOException; 025 import java.io.DataOutput; 026 import java.io.DataInput; 027 028 /** 029 * Utility class to write/read Hadoop writables to/from a byte array. 030 */ 031 public class WritableUtils { 032 033 /** 034 * Write a writable to a byte array. 035 * 036 * @param writable writable to write. 037 * @return array containing the serialized writable. 038 */ 039 public static byte[] toByteArray(Writable writable) { 040 try { 041 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 042 DataOutputStream daos = new DataOutputStream(baos); 043 writable.write(daos); 044 daos.close(); 045 return baos.toByteArray(); 046 } 047 catch (IOException ex) { 048 throw new RuntimeException(ex); 049 } 050 } 051 052 /** 053 * Read a writable from a byte array. 054 * 055 * @param array byte array with the serialized writable. 056 * @param clazz writable class. 057 * @return writable deserialized from the byte array. 058 */ 059 @SuppressWarnings("unchecked") 060 public static <T extends Writable> T fromByteArray(byte[] array, Class<T> clazz) { 061 try { 062 T o = (T) ReflectionUtils.newInstance(clazz, null); 063 o.readFields(new DataInputStream(new ByteArrayInputStream(array))); 064 return o; 065 } 066 catch (IOException ex) { 067 throw new RuntimeException(ex); 068 } 069 } 070 071 private static final String NULL = "||"; 072 073 /** 074 * Write a string to a data output supporting <code>null</code> values. <p/> It uses the '||' token to represent 075 * <code>null</code>. 076 * 077 * @param dataOutput data output. 078 * @param str string to write. 079 * @throws IOException thrown if the string could not be written. 080 */ 081 public static void writeStr(DataOutput dataOutput, String str) throws IOException { 082 str = (str != null) ? str : NULL; 083 dataOutput.writeUTF(str); 084 } 085 086 /** 087 * Read a string from a data input supporting <code>null</code> values. <p/> It uses the '||' token to represent 088 * <code>null</code>. 089 * 090 * @param dataInput data input. 091 * @return read string, <code>null</code> if the '||' token was read. 092 * @throws IOException thrown if the string could not be read. 093 */ 094 public static String readStr(DataInput dataInput) throws IOException { 095 String str = dataInput.readUTF(); 096 return (str.equals(NULL)) ? null : str; 097 } 098 }