/Users/lyon/j4p/src/classUtils/pack/util/pool2/BasePooledObject.java

1    package classUtils.pack.util.pool2; 
2     
3    import java.io.BufferedInputStream; 
4    import java.io.BufferedOutputStream; 
5    import java.io.File; 
6    import java.io.FileInputStream; 
7    import java.io.FileNotFoundException; 
8    import java.io.FileOutputStream; 
9    import java.io.IOException; 
10   import java.io.NotSerializableException; 
11   import java.io.ObjectInputStream; 
12   import java.io.ObjectOutputStream; 
13   import java.io.Serializable; 
14   import java.util.Random; 
15    
16    
17    
18   /** 
19    * A base implementation of a pooled object employing file serialization  
20    * for passivation purposes. 
21    * <p>  
22    * This class offer support for handling the passivability and passivation state,  
23    * and for object passivation/activation.  
24    * 
25    * @version 1.0 
26    * @author Cristiano Sadun 
27    *  
28    */ 
29   public abstract class BasePooledObject implements PooledObject { 
30    
31       private static Random random = new Random(); 
32       private Object original; 
33       private boolean passivated; 
34       private boolean originalAcquired; 
35       private Object passivationLock = new Object(); 
36       private ObjectPool objectPool; 
37    
38       private File serializedFile; 
39    
40       protected BasePooledObject(ObjectPool objectPool, Object original) { 
41           this.objectPool = objectPool; 
42           this.original = original; 
43           this.passivated = false; 
44           this.originalAcquired = false; 
45       } 
46    
47       /** 
48        * @see classUtils.pack.util.pool2.PooledObject#_getOriginal() 
49        */ 
50       public final Object _getOriginal() throws ActivationException { 
51           synchronized (passivationLock) { 
52               if (original == null) 
53                   _activate(); 
54               originalAcquired = true; 
55           } 
56           return original; 
57    
58       } 
59    
60       /** 
61        * @see classUtils.pack.util.pool2.PooledObject#_releaseOriginal() 
62        */ 
63       public final void _releaseOriginal() { 
64           originalAcquired = false; 
65       } 
66    
67       /** 
68        * Activate the object. If the object has not been passivated, 
69        * this method does nothing. 
70        *  
71        * @see classUtils.pack.util.pool2.PooledObject#_activate() 
72        */ 
73       public final void _activate() throws ActivationException { 
74           synchronized (passivationLock) { 
75               if (!passivated) 
76                   return; 
77                    
78               if (objectPool.getLogStream()!=null) { 
79                   objectPool.getLogStream().println("Activating passivated object from "+serializedFile); 
80               }    
81                    
82               ObjectInputStream ois = null; 
83               try { 
84                   try { 
85                       ois = 
86                           new ObjectInputStream( 
87                               new BufferedInputStream( 
88                                   new FileInputStream(serializedFile))); 
89                   } catch (IOException e) { 
90                       throw new ActivationException( 
91                           "Could not open passivated file " + serializedFile, e); 
92                   } 
93                   original = ois.readObject(); 
94                   serializedFile = null; 
95                   passivated = false; 
96    
97               } catch (ClassNotFoundException e) { 
98                   throw new ActivationException( 
99                       "Could not find the class with which the pooled object has been serialized", 
100                      e); 
101              } catch (IOException e) { 
102                  throw new ActivationException( 
103                      "Could not read the serialized object from file " 
104                          + serializedFile, 
105                      e); 
106              } finally { 
107                  if (ois != null) 
108                      try { 
109                          ois.close(); 
110                      } catch (IOException e) { 
111                          throw new ActivationException( 
112                              "Could not close the serialized object file " 
113                                  + serializedFile, 
114                              e); 
115                      } 
116              } 
117   
118          } 
119      } 
120   
121      /** 
122       * This method passivates objects via serialization. 
123       * <p> 
124       * The original object must be Serializable. 
125       * <p> 
126       * The object is assigned an unique file name in a directory 
127       * whose name is the class name of the original object; it is 
128       * then serialized using an <tt>ObjectOutputStream</tt>. 
129       *  
130       * @see classUtils.pack.util.pool2.PooledObject#_passivate() 
131       */ 
132      public final void _passivate() throws PassivationException { 
133          // Serialize the object to a file 
134          synchronized (passivationLock) { 
135               
136              if (passivated) throw new PassivationException("Already passivated"); 
137               
138              if (!objectPool.getPassivationManager().canPassivate(original.getClass())) 
139                  throw new PassivationException( 
140                      "Object " + original.toString() + " is intrinsecally not passivable"); 
141                       
142              if (originalAcquired) throw new PassivationException("Original object acquired"); 
143                       
144              File objDir = 
145                  new File( 
146                      objectPool.getConfiguration().getStorageDirectory(), 
147                      original.getClass().getName()); 
148              if (!objDir.exists()) 
149                  if (!objDir.mkdirs()) 
150                      throw new PassivationException( 
151                          "Cannot create passivation directory " + objDir); 
152              serializedFile = new File(objDir, mkTmpFileName(original)); 
153               
154              if (objectPool.getLogStream()!=null) { 
155                  objectPool.getLogStream().println("Passivating "+this+" to "+serializedFile); 
156              }        
157               
158              ObjectOutputStream oos = null; 
159              try { 
160                  try { 
161                      oos = 
162                          new ObjectOutputStream( 
163                              new BufferedOutputStream( 
164                                  new FileOutputStream(serializedFile))); 
165                  } catch (IOException e) { 
166                      throw new PassivationException( 
167                          "Could not create file for passivated object", 
168                          e); 
169                  } 
170   
171                  oos.writeObject(original); 
172                  original = null; 
173                  passivated = true; 
174              } catch (NotSerializableException e) { 
175                  throw new PassivationException( 
176                      "The pooled object is not Serializable", 
177                      e); 
178              } catch (IOException e) { 
179                  throw new PassivationException( 
180                      "Could not write passivated object to file", 
181                      e); 
182              } finally { 
183                  if (oos != null) 
184                      try { 
185                          oos.close(); 
186                      } catch (IOException e) { 
187                          throw new PassivationException( 
188                              "Could not close passivated object file", 
189                              e); 
190                      } 
191              } 
192          } 
193   
194      } 
195   
196      /** 
197       * Method mkTmpFileName. 
198       */ 
199      private String mkTmpFileName(Object obj) { 
200          return System.currentTimeMillis() 
201              + "_" 
202              + obj.getClass().getName() 
203              + random.nextInt(1000); 
204      } 
205   
206      /** 
207       * Return the current passivable.state. 
208       * @return boolean 
209       */ 
210      public boolean _isPassivableNow() { 
211          return _isPassivable() && passivated==false && originalAcquired==false; 
212      } 
213   
214      /** 
215       * Return the invariant passivable.state, as determined by the passivation manager  
216       * associated to this pooled object. 
217       * <p> 
218       * For example, a passivation manager may require that an object be serializable 
219       * or implement a specific interface. 
220       * @see BasePassivationManager#canPassivate(java.lang.Class) 
221       * @return boolean 
222       */ 
223      public boolean _isPassivable() { 
224          //return  Serializable.class.isAssignableFrom(objectPool.getObjectType()); 
225          return objectPool.getPassivationManager().canPassivate(objectPool.getObjectType()); 
226      } 
227       
228      /** 
229       * Returns the passivated state. 
230       * @return boolean 
231       */ 
232      public boolean _isPassivated() { 
233          return passivated; 
234      } 
235   
236      /** 
237       * Return the serialized File, or <b>null</b> if the object is not 
238       * passivated. 
239       * @return File 
240       */ 
241      public File getSerializedFile() { 
242          synchronized (passivationLock) { 
243              return serializedFile; 
244          } 
245      } 
246   
247      public String toString() { 
248          StringBuffer sb = new StringBuffer(); 
249          sb.append( 
250              "Pooled "); 
251          sb.append(objectPool.getObjectType().getName()); 
252          sb.append(" object"); 
253          if (passivated) { 
254              sb.append("(passivated)"); 
255          } else { 
256               
257              if (original!=null) { 
258                  sb.append(" ["); 
259                  sb.append(original.toString()); 
260                  sb.append("] "); 
261              } 
262               
263              if (_isPassivable()) 
264                  sb.append("(active)"); 
265              else 
266                  sb.append("(not passivable)"); 
267          } 
268          return sb.toString(); 
269      } 
270      /** 
271       * Returns the original. 
272       * @return Object 
273       */ 
274      protected Object getOriginal() { 
275          return original; 
276      } 
277   
278      /** 
279       * Returns the objectPool. 
280       * @return ExtendedObjectPool 
281       */ 
282      public final ObjectPool getObjectPool() { 
283          return objectPool; 
284      } 
285       
286      final void setObjectPool(ObjectPool pool) { 
287          if (objectPool!=null) throw new IllegalStateException("Object pool can be set only once"); 
288          this.objectPool=pool; 
289      } 
290  } 
291