Coverage Report - nextgrid.api.builder.POMBuilderFinder
 
Classes in this File Line Coverage Branch Coverage Complexity
POMBuilderFinder
0%
0/38
0%
0/10
0
 
 1  
 /*
 2  
  Copyright (C) 2007 Grid Systems, S.A.
 3  
 
 4  
  This library is free software; you can redistribute it and/or
 5  
  modify it under the terms of the GNU Lesser General Public
 6  
  License as published by the Free Software Foundation; either
 7  
  version 2.1 of the License, or (at your option) any later version.
 8  
 
 9  
  This library is distributed in the hope that it will be useful,
 10  
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  
  Lesser General Public License for more details.
 13  
 
 14  
  You should have received a copy of the GNU Lesser General Public
 15  
  License along with this library; if not, write to the Free Software
 16  
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 17  
 */
 18  
 package nextgrid.api.builder;
 19  
 
 20  
 import java.net.URI;
 21  
 import java.util.concurrent.ConcurrentHashMap;
 22  
 import java.util.concurrent.ConcurrentMap;
 23  
 
 24  
 import org.apache.commons.discovery.ResourceNameIterator;
 25  
 import org.apache.commons.discovery.resource.ClassLoaders;
 26  
 import org.apache.commons.discovery.resource.names.DiscoverServiceNames;
 27  
 import org.apache.commons.logging.Log;
 28  
 import org.apache.commons.logging.LogFactory;
 29  
 
 30  
 /**
 31  
  * POMBuilder finder.
 32  
  *
 33  
  * @author Rodrigo Ruiz
 34  
  */
 35  
 public final class POMBuilderFinder {
 36  
 
 37  
   /**
 38  
    * Class logger.
 39  
    */
 40  0
   private static final Log LOG = LogFactory.getLog(POMBuilderFinder.class);
 41  
 
 42  
   /**
 43  
    * Builder map initial capacity.
 44  
    */
 45  
   private static final int INITIAL_CAPACITY = 5;
 46  
 
 47  
   /**
 48  
    * Builder map load factor.
 49  
    */
 50  
   private static final float LOAD_FACTOR = 0.75f;
 51  
 
 52  
   /**
 53  
    * Builder map concurrency level.
 54  
    */
 55  
   private static final int CONCURRENCY_LEVEL = 2;
 56  
 
 57  
   /**
 58  
    * Builder map.
 59  
    */
 60  
   private static final ConcurrentMap<Class<?>, POMBuilder<?>> TYPE_REGISTRY;
 61  
 
 62  
   /**
 63  
    * Builder map.
 64  
    */
 65  
   private static final ConcurrentMap<URI, POMBuilder<?>> URI_REGISTRY;
 66  
 
 67  
   static {
 68  0
     TYPE_REGISTRY = new ConcurrentHashMap<Class<?>, POMBuilder<?>>(
 69  
       INITIAL_CAPACITY, LOAD_FACTOR, CONCURRENCY_LEVEL);
 70  
 
 71  0
     URI_REGISTRY = new ConcurrentHashMap<URI, POMBuilder<?>>(
 72  
         INITIAL_CAPACITY, LOAD_FACTOR, CONCURRENCY_LEVEL);
 73  
 
 74  
     // Discover builder implementations
 75  0
     ClassLoaders loaders = new ClassLoaders();
 76  0
     loaders.put(Thread.currentThread().getContextClassLoader());
 77  0
     DiscoverServiceNames dsn = new DiscoverServiceNames(loaders);
 78  
 
 79  0
     ResourceNameIterator it = dsn.findResourceNames(POMBuilder.class.getName());
 80  0
     while (it.hasNext()) {
 81  0
       String name = it.nextResourceName();
 82  
       try {
 83  0
         Class<?> c = Class.forName(name);
 84  0
         if (POMBuilder.class.isAssignableFrom(c)) {
 85  0
           POMBuilder<?> builder = (POMBuilder<?>)c.newInstance();
 86  
           // Builders are found in class-path order, so the first instance
 87  
           // found is "the right one". To ensure this order is honoured, we
 88  
           // set the override parameter to "false"
 89  0
           register(builder, false);
 90  
         }
 91  
         // CHECKSTYLE:OFF
 92  0
       } catch (Exception e) {
 93  
         // CHECKSTYLE:ON
 94  0
         LOG.warn("Could not load builder '" + name + "'", e);
 95  0
       }
 96  0
     }
 97  0
   }
 98  
 
 99  
   /**
 100  
    * Creates an instance.
 101  
    */
 102  0
   private POMBuilderFinder() { }
 103  
 
 104  
   /**
 105  
    * Manually registers a builder, so it is available through the finder.
 106  
    *
 107  
    * @param builder The builder instance to register
 108  
    */
 109  
   public static void register(POMBuilder<?> builder) {
 110  0
     register(builder, true);
 111  0
   }
 112  
 
 113  
   /**
 114  
    * Registers a builder instance.
 115  
    *
 116  
    * @param builder   The builder instance to register
 117  
    * @param override  Whether to override previous registry entries or not
 118  
    */
 119  
   private static void register(POMBuilder<?> builder, boolean override) {
 120  0
     if (builder == null) {
 121  0
       return;
 122  
     }
 123  
 
 124  0
     Class<?> modelClass = builder.getModelType();
 125  0
     if (modelClass != null) {
 126  0
       if (override) {
 127  0
         TYPE_REGISTRY.put(modelClass, builder);
 128  0
       } else {
 129  0
         TYPE_REGISTRY.putIfAbsent(modelClass, builder);
 130  
       }
 131  
     }
 132  0
     URI modelURI = builder.getURI();
 133  0
     if (modelURI != null) {
 134  0
       if (override) {
 135  0
         URI_REGISTRY.put(modelURI, builder);
 136  0
       } else {
 137  0
         URI_REGISTRY.putIfAbsent(modelURI, builder);
 138  
       }
 139  
     }
 140  0
   }
 141  
 
 142  
   /**
 143  
    * Gets a builder for the specified model type.
 144  
    *
 145  
    * @param c The model type
 146  
    * @param <T> Used for return value type checking
 147  
    * @return A builder for the specified model type, or null if none found
 148  
    */
 149  
   @SuppressWarnings("unchecked")
 150  
   public static <T> POMBuilder<T> findBuilderFor(Class<T> c) {
 151  0
     return (POMBuilder<T>)TYPE_REGISTRY.get(c);
 152  
   }
 153  
 
 154  
   /**
 155  
    * Gets a builder by its URI id.
 156  
    *
 157  
    * @param uri The builder id
 158  
    * @return The builder, or null if none found
 159  
    */
 160  
   public static POMBuilder<?> findBuilderByURI(URI uri) {
 161  0
     return URI_REGISTRY.get(uri);
 162  
   }
 163  
 }