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 }