001: // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
002:
003: package jodd.util;
004:
005: import jodd.io.FastByteArrayOutputStream;
006: import jodd.io.StreamUtil;
007:
008: import java.io.BufferedInputStream;
009: import java.io.BufferedOutputStream;
010: import java.io.ByteArrayInputStream;
011: import java.io.File;
012: import java.io.FileInputStream;
013: import java.io.FileOutputStream;
014: import java.io.IOException;
015: import java.io.ObjectInputStream;
016: import java.io.ObjectOutputStream;
017: import java.io.Serializable;
018: import java.util.Arrays;
019:
020: /**
021: * Various object utilities.
022: */
023: public class ObjectUtil {
024:
025: /**
026: * Safely compares two objects just like <code>equals()</code> would, except
027: * it allows any of the 2 objects to be <code>null</code>.
028: *
029: * @return <code>true</code> if arguments are equal, otherwise <code>false</code>
030: */
031: public static boolean equals(Object obj1, Object obj2) {
032: return (obj1 != null) ? (obj1.equals(obj2)) : (obj2 == null);
033: }
034:
035: /**
036: * Compares two objects or two object arrays. Useful for {@link Object#equals(Object)}.
037: * @see #equals(Object, Object)
038: */
039: public static boolean equalsEx(Object obj1, Object obj2) {
040: if (obj1 == null) {
041: return (obj2 == null);
042: }
043: if (obj2 == null) {
044: return false;
045: }
046: if (obj1.getClass().isArray()) {
047: if (obj2.getClass().isArray() == false) {
048: return false;
049: }
050: return Arrays.equals((Object[]) obj1, (Object[]) obj2);
051: } else {
052: return obj1.equals(obj2);
053: }
054: }
055:
056: /**
057: * Non-symetric utility for comparing types of two objects. Useful for {@link Object#equals(Object)}.
058: * @param object <code>equals()</code> argument
059: * @param thiz current class that overrides <code>equals()</code>
060: */
061: public static boolean equalsType(Object object, Object thiz) {
062: return (object != null)
063: && (object.getClass().equals(thiz.getClass()));
064: }
065:
066: // ---------------------------------------------------------------- clone
067:
068: /**
069: * Clone an object by invoking it's <code>clone()</code> method, even if it is not overriden.
070: */
071: public static Object clone(Object source)
072: throws CloneNotSupportedException {
073: if (source == null) {
074: return null;
075: }
076: try {
077: return ReflectUtil.invokeDeclared(source, "clone",
078: new Class[] {}, new Object[] {});
079: } catch (Exception ex) {
080: throw new CloneNotSupportedException(
081: "Can't invoke clone() on object due to: "
082: + ex.getMessage());
083: }
084: }
085:
086: // ---------------------------------------------------------------- clone
087:
088: /**
089: * Create object copy using serialization mechanism.
090: */
091: public static Object cloneViaSerialization(Serializable obj)
092: throws IOException, ClassNotFoundException {
093: FastByteArrayOutputStream bytes = new FastByteArrayOutputStream();
094: ObjectOutputStream out = null;
095: try {
096: out = new ObjectOutputStream(bytes);
097: out.writeObject(obj);
098: } finally {
099: StreamUtil.close(out);
100: }
101:
102: ObjectInputStream in = null;
103: Object objCopy = null;
104: try {
105: in = new ObjectInputStream(new ByteArrayInputStream(bytes
106: .toByteArray()));
107: objCopy = in.readObject();
108: } finally {
109: StreamUtil.close(in);
110: }
111: return objCopy;
112: }
113:
114: // ---------------------------------------------------------------- serialization to file
115:
116: /**
117: * @see #writeObject(java.io.File, Object)
118: */
119: public static void writeObject(String dest, Object object)
120: throws IOException {
121: writeObject(new File(dest), object);
122: }
123:
124: /**
125: * Writes serializable object to a file. Existing file will be overwritten.
126: */
127: public static void writeObject(File dest, Object object)
128: throws IOException {
129: BufferedOutputStream bos = null;
130: ObjectOutputStream oos = null;
131: try {
132: bos = new BufferedOutputStream(new FileOutputStream(dest));
133: oos = new ObjectOutputStream(bos);
134: oos.writeObject(object);
135: } finally {
136: StreamUtil.close(oos);
137: StreamUtil.close(bos);
138: }
139: }
140:
141: /**
142: * @see #readObject(java.io.File)
143: */
144: public static Object readObject(String source) throws IOException,
145: ClassNotFoundException {
146: return readObject(new File(source));
147: }
148:
149: /**
150: * Reads serialized object from the file.
151: */
152: public static Object readObject(File source) throws IOException,
153: ClassNotFoundException {
154: Object result = null;
155: BufferedInputStream bis = null;
156: ObjectInputStream ois = null;
157: try {
158: bis = new BufferedInputStream(new FileInputStream(source));
159: ois = new ObjectInputStream(bis);
160: result = ois.readObject();
161: } finally {
162: StreamUtil.close(ois);
163: StreamUtil.close(bis);
164: }
165: return result;
166: }
167:
168: // ---------------------------------------------------------------- serialization to byte array
169:
170: /**
171: * Serialize an object to byte array.
172: */
173: public static byte[] objectToByteArray(Object obj)
174: throws IOException {
175: FastByteArrayOutputStream bos = new FastByteArrayOutputStream();
176: ObjectOutputStream oos = null;
177: try {
178: oos = new ObjectOutputStream(bos);
179: oos.writeObject(obj);
180: oos.flush();
181: } finally {
182: StreamUtil.close(oos);
183: }
184: return bos.toByteArray();
185: }
186:
187: /**
188: * Deserialize an object from byte array.
189: */
190: public static Object byteArrayToObject(byte[] data)
191: throws IOException, ClassNotFoundException {
192: Object retObj = null;
193: ByteArrayInputStream bais = new ByteArrayInputStream(data);
194: ObjectInputStream ois = null;
195: try {
196: ois = new ObjectInputStream(bais);
197: retObj = ois.readObject();
198: } finally {
199: StreamUtil.close(ois);
200: }
201: return retObj;
202: }
203: }
|