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 package org.apache.oozie.util; 019 020 import org.apache.hadoop.io.Writable; 021 import org.apache.hadoop.util.ReflectionUtils; 022 023 import java.io.ByteArrayInputStream; 024 import java.io.ByteArrayOutputStream; 025 import java.io.DataInputStream; 026 import java.io.DataOutputStream; 027 import java.io.IOException; 028 import java.io.DataOutput; 029 import java.io.DataInput; 030 031 /** 032 * Utility class to write/read Hadoop writables to/from a byte array. 033 */ 034 public class WritableUtils { 035 036 /** 037 * Write a writable to a byte array. 038 * 039 * @param writable writable to write. 040 * @return array containing the serialized writable. 041 */ 042 public static byte[] toByteArray(Writable writable) { 043 try { 044 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 045 DataOutputStream daos = new DataOutputStream(baos); 046 writable.write(daos); 047 daos.close(); 048 return baos.toByteArray(); 049 } 050 catch (IOException ex) { 051 throw new RuntimeException(ex); 052 } 053 } 054 055 /** 056 * Read a writable from a byte array. 057 * 058 * @param array byte array with the serialized writable. 059 * @param clazz writable class. 060 * @return writable deserialized from the byte array. 061 */ 062 @SuppressWarnings("unchecked") 063 public static <T extends Writable> T fromByteArray(byte[] array, Class<T> clazz) { 064 try { 065 T o = (T) ReflectionUtils.newInstance(clazz, null); 066 o.readFields(new DataInputStream(new ByteArrayInputStream(array))); 067 return o; 068 } 069 catch (IOException ex) { 070 throw new RuntimeException(ex); 071 } 072 } 073 074 private static final String NULL = "||"; 075 076 /** 077 * Write a string to a data output supporting <code>null</code> values. <p/> It uses the '||' token to represent 078 * <code>null</code>. 079 * 080 * @param dataOutput data output. 081 * @param str string to write. 082 * @throws IOException thrown if the string could not be written. 083 */ 084 public static void writeStr(DataOutput dataOutput, String str) throws IOException { 085 str = (str != null) ? str : NULL; 086 dataOutput.writeUTF(str); 087 } 088 089 /** 090 * Read a string from a data input supporting <code>null</code> values. <p/> It uses the '||' token to represent 091 * <code>null</code>. 092 * 093 * @param dataInput data input. 094 * @return read string, <code>null</code> if the '||' token was read. 095 * @throws IOException thrown if the string could not be read. 096 */ 097 public static String readStr(DataInput dataInput) throws IOException { 098 String str = dataInput.readUTF(); 099 return (str.equals(NULL)) ? null : str; 100 } 101 }