1 /*
   2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.xml.internal.ws.util;
  27 
  28 import com.sun.xml.internal.ws.api.pipe.Tube;
  29 import com.sun.xml.internal.ws.api.pipe.TubeCloner;
  30 
  31 import javax.xml.bind.JAXBContext;
  32 import javax.xml.bind.JAXBException;
  33 import java.util.concurrent.ConcurrentLinkedQueue;
  34 import java.lang.ref.WeakReference;
  35 
  36 /**
  37  * General-purpose object pool.
  38  *
  39  * <p>
  40  * In many parts of the runtime, we need to pool instances of objects that
  41  * are expensive to create (such as JAXB objects, StAX parsers, {@link Tube} instances.)
  42  *
  43  * <p>
  44  * This class provides a default implementation of such a pool.
  45  *
  46  * TODO: improve the implementation
  47  *
  48  * @author Kohsuke Kawaguchi
  49  */
  50 public abstract class Pool<T> {
  51 
  52     // volatile since multiple threads may access queue reference
  53     private volatile WeakReference<ConcurrentLinkedQueue<T>> queue;
  54 
  55     /**
  56      * Gets a new object from the pool.
  57      *
  58      * <p>
  59      * If no object is available in the pool, this method creates a new one.
  60      *
  61      * @return
  62      *      always non-null.
  63      */
  64     public final T take() {
  65         T t = getQueue().poll();
  66         if(t==null)
  67             return create();
  68         return t;
  69     }
  70 
  71     private ConcurrentLinkedQueue<T> getQueue() {
  72         WeakReference<ConcurrentLinkedQueue<T>> q = queue;
  73         if (q != null) {
  74             ConcurrentLinkedQueue<T> d = q.get();
  75             if (d != null)
  76                 return d;
  77         }
  78 
  79         // overwrite the queue
  80         ConcurrentLinkedQueue<T> d = new ConcurrentLinkedQueue<T>();
  81         queue = new WeakReference<ConcurrentLinkedQueue<T>>(d);
  82 
  83         return d;
  84     }
  85 
  86     /**
  87      * Returns an object back to the pool.
  88      */
  89     public final void recycle(T t) {
  90         getQueue().offer(t);
  91     }
  92 
  93     /**
  94      * Creates a new instance of object.
  95      *
  96      * <p>
  97      * This method is used when someone wants to
  98      * {@link #take() take} an object from an empty pool.
  99      *
 100      * <p>
 101      * Also note that multiple threads may call this method
 102      * concurrently.
 103      */
 104     protected abstract T create();
 105 
 106 
 107     /**
 108      * JAXB {@link javax.xml.bind.Marshaller} pool.
 109      */
 110     public static final class Marshaller extends Pool<javax.xml.bind.Marshaller> {
 111         private final JAXBContext context;
 112 
 113         public Marshaller(JAXBContext context) {
 114             this.context = context;
 115         }
 116 
 117         @Override
 118         protected javax.xml.bind.Marshaller create() {
 119             try {
 120                 return context.createMarshaller();
 121             } catch (JAXBException e) {
 122                 // impossible
 123                 throw new AssertionError(e);
 124             }
 125         }
 126     }
 127 
 128     /**
 129      * JAXB {@link javax.xml.bind.Marshaller} pool.
 130      */
 131     public static final class Unmarshaller extends Pool<javax.xml.bind.Unmarshaller> {
 132         private final JAXBContext context;
 133 
 134         public Unmarshaller(JAXBContext context) {
 135             this.context = context;
 136         }
 137 
 138         @Override
 139         protected javax.xml.bind.Unmarshaller create() {
 140             try {
 141                 return context.createUnmarshaller();
 142             } catch (JAXBException e) {
 143                 // impossible
 144                 throw new AssertionError(e);
 145             }
 146         }
 147     }
 148 
 149     /**
 150      * {@link Tube} pool.
 151      */
 152     public static final class TubePool extends Pool<Tube> {
 153         private final Tube master;
 154 
 155         public TubePool(Tube master) {
 156             this.master = master;
 157             recycle(master);    // we'll use master as a part of the pool, too.
 158         }
 159 
 160         @Override
 161         protected Tube create() {
 162             return TubeCloner.clone(master);
 163         }
 164 
 165         /**
 166          *
 167          * @return master tubeline from pool
 168          * @deprecated Expected to be used in rare cases where access to master
 169          * tubeline is required and safe, such as Stub.close()."
 170          */
 171         @Deprecated()
 172         public final Tube takeMaster() {
 173             return master;
 174         }
 175 
 176     }
 177 }