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