1 16 package org.apache.commons.collections.functors; 17 18 import java.io.ByteArrayInputStream ; 19 import java.io.ByteArrayOutputStream ; 20 import java.io.IOException ; 21 import java.io.ObjectInputStream ; 22 import java.io.ObjectOutputStream ; 23 import java.io.Serializable ; 24 import java.lang.reflect.InvocationTargetException ; 25 import java.lang.reflect.Method ; 26 27 import org.apache.commons.collections.Factory; 28 import org.apache.commons.collections.FunctorException; 29 30 38 public class PrototypeFactory { 39 40 57 public static Factory getInstance(Object prototype) { 58 if (prototype == null) { 59 return ConstantFactory.NULL_INSTANCE; 60 } 61 try { 62 Method method = prototype.getClass().getMethod("clone", null); 63 return new PrototypeCloneFactory(prototype, method); 64 65 } catch (NoSuchMethodException ex) { 66 try { 67 prototype.getClass().getConstructor(new Class [] { prototype.getClass()}); 68 return new InstantiateFactory( 69 prototype.getClass(), 70 new Class [] { prototype.getClass()}, 71 new Object [] { prototype }); 72 73 } catch (NoSuchMethodException ex2) { 74 if (prototype instanceof Serializable ) { 75 return new PrototypeSerializationFactory((Serializable ) prototype); 76 } 77 } 78 } 79 throw new IllegalArgumentException ("The prototype must be cloneable via a public clone method"); 80 } 81 82 86 private PrototypeFactory() { 87 super(); 88 } 89 90 95 static class PrototypeCloneFactory implements Factory, Serializable { 96 97 98 static final long serialVersionUID = 5604271422565175555L; 99 100 101 private final Object iPrototype; 102 103 private transient Method iCloneMethod; 104 105 108 private PrototypeCloneFactory(Object prototype, Method method) { 109 super(); 110 iPrototype = prototype; 111 iCloneMethod = method; 112 } 113 114 117 private void findCloneMethod() { 118 try { 119 iCloneMethod = iPrototype.getClass().getMethod("clone", null); 120 121 } catch (NoSuchMethodException ex) { 122 throw new IllegalArgumentException ("PrototypeCloneFactory: The clone method must exist and be public "); 123 } 124 } 125 126 131 public Object create() { 132 if (iCloneMethod == null) { 134 findCloneMethod(); 135 } 136 137 try { 138 return iCloneMethod.invoke(iPrototype, null); 139 140 } catch (IllegalAccessException ex) { 141 throw new FunctorException("PrototypeCloneFactory: Clone method must be public", ex); 142 } catch (InvocationTargetException ex) { 143 throw new FunctorException("PrototypeCloneFactory: Clone method threw an exception", ex); 144 } 145 } 146 } 147 148 153 static class PrototypeSerializationFactory implements Factory, Serializable { 154 155 156 static final long serialVersionUID = -8704966966139178833L; 157 158 159 private final Serializable iPrototype; 160 161 164 private PrototypeSerializationFactory(Serializable prototype) { 165 super(); 166 iPrototype = prototype; 167 } 168 169 174 public Object create() { 175 ByteArrayOutputStream baos = new ByteArrayOutputStream (512); 176 ByteArrayInputStream bais = null; 177 try { 178 ObjectOutputStream out = new ObjectOutputStream (baos); 179 out.writeObject(iPrototype); 180 181 bais = new ByteArrayInputStream (baos.toByteArray()); 182 ObjectInputStream in = new ObjectInputStream (bais); 183 return in.readObject(); 184 185 } catch (ClassNotFoundException ex) { 186 throw new FunctorException(ex); 187 } catch (IOException ex) { 188 throw new FunctorException(ex); 189 } finally { 190 try { 191 if (bais != null) { 192 bais.close(); 193 } 194 } catch (IOException ex) { 195 } 197 try { 198 if (baos != null) { 199 baos.close(); 200 } 201 } catch (IOException ex) { 202 } 204 } 205 } 206 } 207 208 } 209 | Popular Tags |