code: /*******************************************************************************
   * Copyright 2018 572682
   * 
   * Licensed under the Apache License, Version 2.0 (the "License"); you may not
   * use this file except in compliance with the License.  You may obtain a copy
   * of the License at
   * 
   *   http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
   * License for the specific language governing permissions and limitations under
   * the License.
   ******************************************************************************/
  package us.dot.its.jpo.ode.util;
  
  import java.io.Serializable;
  import java.util.Enumeration;
  import java.util.Hashtable;
  
  public abstract class SerializableObjectPool<T> implements Serializable {
     private static final long serialVersionUID = 914977959079989774L;
  
     private long expirationTime;
  
     private Hashtable<T, Long> locked, unlocked;
  
     public SerializableObjectPool() {
        expirationTime = 30000; // 30 seconds
        locked = new Hashtable<T, Long>();
        unlocked = new Hashtable<T, Long>();
     }
  
     protected abstract T create();
  
     public abstract boolean validate(T o);
  
     public abstract void expire(T o);
  
     public synchronized T checkOut() {
        long now = System.currentTimeMillis();
        T t;
        if (unlocked.size() > 0) {
           Enumeration<T> e = unlocked.keys();
           while (e.hasMoreElements()) {
              t = e.nextElement();
              if ((now - unlocked.get(t)) > expirationTime) {
                 // object has expired
                 unlocked.remove(t);
                 expire(t);
                 t = null;	//NOSONAR
              } else {
                 if (validate(t)) {
                    unlocked.remove(t);
                    locked.put(t, now);
                    return (t);
                 } else {
                    // object failed validation
                    unlocked.remove(t);
                    expire(t);
                    t = null;	//NOSONAR
                 }
              }
           }
        }
        // no objects available, create a new one
        t = create();
        locked.put(t, now);
        return (t);
     }
  
     public synchronized void checkIn(T t) {
        locked.remove(t);
        unlocked.put(t, System.currentTimeMillis());
     }
  }
  