001/* 002 * #%L 003 * Netarchivesuite - common - test 004 * %% 005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023package dk.netarkivet.testutils; 024 025import java.io.ByteArrayInputStream; 026import java.io.ByteArrayOutputStream; 027import java.io.IOException; 028import java.io.ObjectInputStream; 029import java.io.ObjectOutputStream; 030import java.io.Serializable; 031import java.lang.reflect.Field; 032import java.lang.reflect.Modifier; 033import java.util.Arrays; 034 035import junit.framework.TestCase; 036 037/** 038 * Created by IntelliJ IDEA. User: csr Date: Mar 4, 2005 Time: 2:26:06 PM To change this template use File | Settings | 039 * File Templates. 040 */ 041public class Serial { 042 043 /** 044 * Serializes an Object, deserializes it, and then returns it. 045 * 046 * @param input_object 047 * @return Object 048 * @throws IOException 049 * @throws ClassNotFoundException 050 */ 051 @SuppressWarnings("unchecked") 052 public static <T extends Serializable> T serial(T input_object) throws IOException, ClassNotFoundException { 053 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 054 055 ObjectOutputStream ous = new ObjectOutputStream(baos); 056 ous.writeObject(input_object); 057 ous.close(); 058 baos.close(); 059 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); 060 return (T) ois.readObject(); 061 } 062 063 /** 064 * Check that transient fields are properly initialized after the object has been serialized and deserialized. 065 * 066 * @param obj A Serializable object to test. 067 * @param excludedFields Names of fields that we do not care are not initialized after deserialization. Could be 068 * integers that are properly initialized to 0 or the like. Only include fields here if you are sure that 069 * initialization is not required! 070 * @throws IOException 071 * @throws ClassNotFoundException 072 * @throws IllegalAccessException 073 */ 074 public static <T extends Serializable> void assertTransientFieldsInitialized(T obj, String... excludedFields) 075 throws IOException, ClassNotFoundException, IllegalAccessException { 076 T obj2 = serial(obj); 077 Field[] fields = obj2.getClass().getDeclaredFields(); 078 for (Field f : fields) { 079 if (Modifier.isTransient(f.getModifiers())) { 080 if (!Arrays.asList(excludedFields).contains(f.getName())) { 081 f.setAccessible(true); 082 final Class<?> type = f.getType(); 083 final Object value = f.get(obj2); 084 if (type.isPrimitive()) { 085 if (value == null) { 086 TestCase.fail("Primitive field " + f + " is strangely null after deserialization"); 087 } 088 if (type == Boolean.TYPE && value.equals(Boolean.valueOf(false)) || type == Byte.TYPE 089 && value.equals(Byte.valueOf((byte) 0)) || type == Character.TYPE 090 && value.equals(Character.valueOf('\0')) || type == Short.TYPE 091 && value.equals(Short.valueOf((short) 0)) || type == Integer.TYPE 092 && value.equals(Integer.valueOf(0)) || type == Long.TYPE 093 && value.equals(Long.valueOf(0L)) || type == Float.TYPE 094 && value.equals(Float.valueOf(0.0f)) || type == Double.TYPE 095 && value.equals(Double.valueOf(0.0))) { 096 TestCase.fail("Primitive field " + f + " has default value " + value 097 + " after deserialization"); 098 } 099 } else { 100 if (value == null) { 101 TestCase.fail("Field " + f + " is null after deserialization"); 102 } 103 } 104 } 105 } 106 } 107 } 108}