Clover coverage report - Ledge Components - SNAPSHOT
Coverage timestamp: Fri Nov 17 2006 05:13:20 CET
file stats: LOC: 724   Methods: 23
NCLOC: 493   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
DefaultCacheFactory.java 77% 91.9% 95.7% 88.5%
coverage coverage
 1    //
 2    //Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 3    //All rights reserved.
 4    //
 5    //Redistribution and use in source and binary forms, with or without modification,
 6    //are permitted provided that the following conditions are met:
 7    //
 8    //* Redistributions of source code must retain the above copyright notice,
 9    //this list of conditions and the following disclaimer.
 10    //* Redistributions in binary form must reproduce the above copyright notice,
 11    //this list of conditions and the following disclaimer in the documentation
 12    //and/or other materials provided with the distribution.
 13    //* Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 14    //nor the names of its contributors may be used to endorse or promote products
 15    //derived from this software without specific prior written permission.
 16    //
 17    //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 18    //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19    //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 20    //IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 21    //INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 22    //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 23    //OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 24    //WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 25    //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 26    //POSSIBILITY OF SUCH DAMAGE.
 27    //
 28   
 29    package org.objectledge.cache;
 30   
 31    import java.io.PrintWriter;
 32    import java.lang.reflect.Modifier;
 33    import java.util.ArrayList;
 34    import java.util.HashMap;
 35    import java.util.HashSet;
 36    import java.util.Iterator;
 37    import java.util.List;
 38    import java.util.Map;
 39    import java.util.Set;
 40    import java.util.SortedMap;
 41    import java.util.TreeMap;
 42   
 43    import org.jcontainer.dna.Configuration;
 44    import org.jcontainer.dna.ConfigurationException;
 45    import org.jcontainer.dna.Logger;
 46    import org.objectledge.ComponentInitializationError;
 47    import org.objectledge.cache.spi.CacheFactorySPI;
 48    import org.objectledge.cache.spi.ConfigurableMap;
 49    import org.objectledge.cache.spi.ConfigurableValueFactory;
 50    import org.objectledge.cache.spi.DistributedMap;
 51    import org.objectledge.cache.spi.FactoryMap;
 52    import org.objectledge.cache.spi.ForgetfullMap;
 53    import org.objectledge.cache.spi.LRUMap;
 54    import org.objectledge.cache.spi.LayeredMap;
 55    import org.objectledge.cache.spi.SoftMap;
 56    import org.objectledge.cache.spi.StatisticsMap;
 57    import org.objectledge.cache.spi.TimeoutMap;
 58    import org.objectledge.context.Context;
 59    import org.objectledge.database.persistence.Persistence;
 60    import org.objectledge.notification.Notification;
 61    import org.objectledge.threads.Task;
 62    import org.objectledge.threads.ThreadPool;
 63   
 64    /**
 65    * DefaultCacheFactory component.
 66    *
 67    * <p>An instance declaration is a list of map layer declarations.
 68    * A map layer declaration is composed of a map type name (both
 69    * standard and custom types may be used) and a pair of parentheses. Optional
 70    * configuration string may be placed betweene the parens. The meaning of the
 71    * string is depenant upon the implementation class. If there is a non-empty
 72    * configuration string, the map implementation is required to support {@link
 73    * ConfigurableMap} interface. Layers declared first are the deeper than those
 74    * declared later. The implemenation of map types used on layers deeper than
 75    * layer one are required to support {@link LayeredMap} interface. The layer
 76    * number <i>n</i> becomes the delegate of the layer <i>n+1</i>.</p>
 77    *
 78    * @author <a href="mailto:rafal@caltha.pl">Rafal Krzewski</a>
 79    * @version $Id: DefaultCacheFactory.java,v 1.4 2006/02/08 18:19:56 zwierzem Exp $
 80    */
 81    public class DefaultCacheFactory
 82    implements CacheFactorySPI, CacheFactory
 83    {
 84    // constants ////////////////////////////////////////////////////////////
 85    /** Type constant for HashMap. */
 86    public static final String HASH_MAP_TYPE = "HashMap";
 87   
 88    /** Type constant for TimeoutMap. */
 89    public static final String TIMEOUT_MAP_TYPE = "TimeoutMap";
 90   
 91    /** Type constant for LRUMap. */
 92    public static final String LRU_MAP_TYPE = "LRUMap";
 93   
 94    /** Type constant for SoftMap. */
 95    public static final String SOFT_MAP_TYPE = "SoftMap";
 96   
 97    /** Type constant for FactoryMap. */
 98    public static final String FACTORY_MAP_TYPE = "FactoryMap";
 99   
 100    /** Type constant for DistributedMap. */
 101    public static final String DISTRIBUTED_MAP_TYPE = "DistributedMap";
 102   
 103    /** Type constant for StatisticsMap. */
 104    public static final String STATISTICS_MAP_TYPE = "StatisticsMap";
 105   
 106    /** Type constant for ForgetFullMap. */
 107    public static final String FORGETFULL_MAP_TYPE = "ForgetfullMap";
 108   
 109    /** The default implementation HashMap implementation. */
 110    public static final String HASH_MAP_CLASS_DEFALUT =
 111    "java.util.HashMap";
 112   
 113    /** The default implementation TimeoutMap implementation. */
 114    public static final String TIMEOUT_MAP_CLASS_DEFALUT =
 115    "org.objectledge.cache.impl.TimeoutMapImpl";
 116   
 117    /** The default implementation LRUMap implementation. */
 118    public static final String LRU_MAP_CLASS_DEFALUT =
 119    "org.objectledge.cache.impl.LRUMapImpl";
 120   
 121    /** The default implementation SoftMap implementation. */
 122    public static final String SOFT_MAP_CLASS_DEFALUT =
 123    "org.objectledge.cache.impl.SoftMapImpl";
 124   
 125    /** The default implementation DistributedMap implementation. */
 126    public static final String DISTRIBUTED_MAP_CLASS_DEFALUT =
 127    "org.objectledge.cache.impl.DistributedMapImpl";
 128   
 129    /** The default implementation FactoryMap implementation. */
 130    public static final String FACTORY_MAP_CLASS_DEFALUT =
 131    "org.objectledge.cache.impl.FactoryMapImpl";
 132   
 133    /** The default implementation StatisticsMap implementation. */
 134    public static final String STATISTICS_MAP_CLASS_DEFALUT =
 135    "org.objectledge.cache.impl.StatisticsMapImpl";
 136   
 137    /** The default implementation StatisticsMap implementation. */
 138    public static final String FORGETFULL_MAP_CLASS_DEFALUT =
 139    "org.objectledge.cache.impl.ForgetfullMapImpl";
 140    // member objects ////////////////////////////////////////////////////////
 141   
 142    /** The registered StatisticsMaps */
 143    private List<StatisticsMap> statistics = new ArrayList<StatisticsMap>();
 144   
 145    /** Mapping of *_TYPE constants into configured implementation classes. */
 146    private Map<String,Class> implClasses = new HashMap<String,Class>();
 147   
 148    /** instance prepared configurations map. */
 149    private Map<String,Configuration> instanceConfigurations = new HashMap<String,Configuration>();
 150   
 151    /** Factory configurations */
 152    private Map<String,Configuration> factoryConfigurations = new HashMap<String,Configuration>();
 153   
 154    /** Configured map instances. */
 155    private Map<String,Map> instances = new HashMap<String,Map>();
 156   
 157    /** DelayedUpdate queue (target update time -&gt; object)*/
 158    private SortedMap<Long,Set<DelayedUpdate>> queue = new TreeMap<Long,Set<DelayedUpdate>>();
 159   
 160    /** DelayedUpdate queue helper map (object -&gt; target update time)*/
 161    private Map<DelayedUpdate,Long> queueHelper = new HashMap<DelayedUpdate,Long>();
 162   
 163    /** The configuration */
 164    private Configuration config;
 165   
 166    /** The logging facility. */
 167    private Logger logger;
 168   
 169    /** The thread pool */
 170    private ThreadPool threadPool;
 171   
 172    /** The notification */
 173    private Notification notification;
 174   
 175    /** The persistence */
 176    private Persistence persistence;
 177   
 178    // initialization ////////////////////////////////////////////////////////
 179   
 180    /**
 181    * Component constructor.
 182    *
 183    * @param config the configuration.
 184    * @param logger the logger.
 185    * @param threadPool the thread pool.
 186    * @param notification the notification.
 187    * @param persistence the persistence.
 188    * @throws ConfigurationException thrown if configuration is invalid.
 189    * @throws ClassNotFoundException thrown if one of the class not found.
 190    */
 191  782 public DefaultCacheFactory(Configuration config, Logger logger,
 192    ThreadPool threadPool, Notification notification,
 193    Persistence persistence)
 194    throws ConfigurationException, ClassNotFoundException
 195    {
 196  782 this.config = config;
 197  782 this.logger = logger;
 198  782 this.threadPool = threadPool;
 199  782 this.notification = notification;
 200  782 this.persistence = persistence;
 201   
 202  782 Map<String, String> classMap = new HashMap<String, String>();
 203  782 classMap.put(HASH_MAP_TYPE, HASH_MAP_CLASS_DEFALUT);
 204  782 classMap.put(TIMEOUT_MAP_TYPE, TIMEOUT_MAP_CLASS_DEFALUT);
 205  782 classMap.put(LRU_MAP_TYPE, LRU_MAP_CLASS_DEFALUT);
 206  782 classMap.put(SOFT_MAP_TYPE, SOFT_MAP_CLASS_DEFALUT);
 207  782 classMap.put(DISTRIBUTED_MAP_TYPE, DISTRIBUTED_MAP_CLASS_DEFALUT);
 208  782 classMap.put(FACTORY_MAP_TYPE, FACTORY_MAP_CLASS_DEFALUT);
 209  782 classMap.put(STATISTICS_MAP_TYPE, STATISTICS_MAP_CLASS_DEFALUT);
 210  782 classMap.put(FORGETFULL_MAP_TYPE, FORGETFULL_MAP_CLASS_DEFALUT);
 211   
 212  782 Map<String, Class> ifaceMap = new HashMap<String, Class>();
 213  782 ifaceMap.put(HASH_MAP_TYPE, Map.class);
 214  782 ifaceMap.put(TIMEOUT_MAP_TYPE, TimeoutMap.class);
 215  782 ifaceMap.put(LRU_MAP_TYPE, LRUMap.class);
 216  782 ifaceMap.put(SOFT_MAP_TYPE, SoftMap.class);
 217  782 ifaceMap.put(DISTRIBUTED_MAP_TYPE, DistributedMap.class);
 218  782 ifaceMap.put(FACTORY_MAP_TYPE, FactoryMap.class);
 219  782 ifaceMap.put(STATISTICS_MAP_TYPE, StatisticsMap.class);
 220  782 ifaceMap.put(FORGETFULL_MAP_TYPE, ForgetfullMap.class);
 221   
 222  782 Configuration[] custom = config.getChildren("implementation");
 223  782 for(int i=0; i<custom.length; i++)
 224    {
 225  1564 String type = custom[i].getAttribute("type");
 226  1564 String clazz = custom[i].getAttribute("class");
 227  1564 classMap.put(type,clazz);
 228    }
 229  782 Iterator it = classMap.keySet().iterator();
 230  782 while(it.hasNext())
 231    {
 232  7820 String type = (String)it.next();
 233  7820 String clazz = (String)classMap.get(type);
 234  7820 Class iface = (Class)ifaceMap.get(type);
 235  7820 if(iface == null)
 236    {
 237  1564 iface = Map.class;
 238    }
 239  7820 initImpl(type, clazz, iface);
 240    }
 241   
 242  782 Configuration[] aliases = config.getChildren("alias");
 243  782 for(int i = 0; i < aliases.length; i++)
 244    {
 245  1564 String name = aliases[i].getAttribute("name");
 246  1564 instanceConfigurations.put(name,aliases[i]);
 247    }
 248  782 Configuration[] factories = config.getChildren("factory");
 249  782 for(int i = 0; i < factories.length; i++)
 250    {
 251  782 String name = factories[i].getAttribute("name");
 252  782 factoryConfigurations.put(name,factories[i]);
 253    }
 254  782 Configuration[] instanceNodes = config.getChildren("instance");
 255  782 for(int i =0; i < instanceNodes.length;i++)
 256    {
 257  8602 String name = instanceNodes[i].getAttribute("name");
 258  8602 Configuration instanceConfig = instanceNodes[i];
 259  8602 String alias = instanceNodes[i].getAttribute("alias",null);
 260  8602 if(alias != null)
 261    {
 262  1564 instanceConfig = (Configuration)instanceConfigurations.get(alias);
 263  1564 if(instanceConfig == null)
 264    {
 265  0 throw new ComponentInitializationError(
 266    "cannot find conifured alias: '"+alias+"'");
 267    }
 268    }
 269  8602 Map map = buildInstance(name, instanceConfig);
 270  8602 instances.put(name, map);
 271    }
 272  782 threadPool.runDaemon(new DelayedUpdateTask());
 273    }
 274   
 275    // CacheFactorySPI interface ////////////////////////////////////////////////
 276   
 277    /**
 278    * {@inheritDoc}
 279    */
 280  13064 public Map getMap(String type)
 281    {
 282  13064 Class cl = (Class)implClasses.get(type);
 283  13064 if(cl == null)
 284    {
 285  46 throw new IllegalArgumentException("unknown map type "+type);
 286    }
 287  13018 try
 288    {
 289  13018 return (Map)cl.newInstance();
 290    }
 291    ///CLOVER:OFF
 292    catch(VirtualMachineError t)
 293    {
 294    throw t;
 295    }
 296    catch(ThreadDeath t)
 297    {
 298    throw t;
 299    }
 300    catch(Throwable t)
 301    {
 302    throw new RuntimeException("failed to instantaite map of type "+type, t);
 303    }
 304    ///CLOVER:ON
 305    }
 306   
 307    /**
 308    * {@inheritDoc}
 309    */
 310  598 public synchronized Map getInstance(String name)
 311    {
 312  598 Map map = (Map)instances.get(name);
 313  598 if(map == null)
 314    {
 315  46 throw new IllegalArgumentException("configuration "+name+
 316    " not defined in config file");
 317    }
 318  552 return map;
 319    }
 320   
 321    /**
 322    * {@inheritDoc}
 323    */
 324  138 public synchronized Map getInstance(String name, String configAlias)
 325    throws ConfigurationException
 326    {
 327  138 Map map = (Map)instances.get(name);
 328  138 if(map == null)
 329    {
 330  92 Configuration instanceConfiguration =
 331    (Configuration)instanceConfigurations.get(configAlias);
 332  92 if(instanceConfiguration == null)
 333    {
 334  46 throw new IllegalArgumentException("configuration "+configAlias+
 335    " not defined in config file");
 336    }
 337  46 map = buildInstance(name, instanceConfiguration);
 338  46 instances.put(name, map);
 339    }
 340  92 return map;
 341    }
 342   
 343    /**
 344    * {@inheritDoc}
 345    */
 346  782 public ValueFactory getValueFactory(String factory, String map)
 347    {
 348  782 Configuration factoryConfig = (Configuration)factoryConfigurations.get(factory);
 349  782 String fclass = factoryConfig.getAttribute("class",null);
 350  782 Object obj;
 351  782 if(fclass == null)
 352    {
 353  0 throw new IllegalArgumentException("factory "+factory+" not defined in config file");
 354    }
 355  782 try
 356    {
 357  782 obj = Class.forName(fclass).newInstance();
 358    }
 359    catch(ClassNotFoundException e)
 360    {
 361  0 throw new IllegalArgumentException(fclass+" not found");
 362    }
 363    catch(Exception e)
 364    {
 365  0 throw new IllegalArgumentException(fclass+" not found");
 366    }
 367   
 368  782 if(!(obj instanceof ConfigurableValueFactory))
 369    {
 370  0 throw new IllegalArgumentException(fclass+" does not implement " +
 371    "ConfigurableValueFactory interface");
 372    }
 373  782 ((ConfigurableValueFactory)obj).configure(this, map, factoryConfig);
 374  782 return (ValueFactory)obj;
 375    }
 376   
 377    /**
 378    * {@inheritDoc}
 379    */
 380  46 public Map getHashMap()
 381    {
 382  46 Map map = getMap(HASH_MAP_TYPE);
 383  46 return map;
 384    }
 385   
 386    /**
 387    * {@inheritDoc}
 388    */
 389  46 public Map getTimeoutMap(long timeoutMillis)
 390    {
 391  46 TimeoutMap map = (TimeoutMap)getMap(TIMEOUT_MAP_TYPE);
 392  46 map.setTimeout(timeoutMillis);
 393  46 return map;
 394    }
 395   
 396    /**
 397    * {@inheritDoc}
 398    */
 399  46 public Map getLRUMap(int capacity)
 400    {
 401  46 LRUMap map = (LRUMap)getMap(LRU_MAP_TYPE);
 402  46 map.setCapacity(capacity);
 403  46 return map;
 404    }
 405   
 406    /**
 407    * {@inheritDoc}
 408    */
 409  46 public Map getSoftMap(int protect)
 410    {
 411  46 SoftMap map = (SoftMap)getMap(SOFT_MAP_TYPE);
 412  46 map.setProtect(protect);
 413  46 return map;
 414    }
 415   
 416    /**
 417    * {@inheritDoc}
 418    */
 419  46 public org.objectledge.cache.DistributedMap getDistributedMap(String name, Map delegate)
 420    {
 421  46 DistributedMap map = (DistributedMap)getMap(DISTRIBUTED_MAP_TYPE);
 422  46 map.setDelegate(delegate);
 423  46 map.attach(notification, name);
 424  46 return map;
 425    }
 426   
 427    /**
 428    * {@inheritDoc}
 429    */
 430  46 public Map getFactoryMap(ValueFactory factory, Map delegate)
 431    {
 432  46 FactoryMap map = (FactoryMap)getMap(FACTORY_MAP_TYPE);
 433  46 map.setDelegate(delegate);
 434  46 map.setFactory(factory);
 435  46 return map;
 436    }
 437   
 438    /**
 439    * {@inheritDoc}
 440    */
 441  46 public Map getStatisticsMap(String name, Map delegate)
 442    {
 443  46 StatisticsMap map = (StatisticsMap)getMap(STATISTICS_MAP_TYPE);
 444  46 map.setDelegate(delegate);
 445  46 map.setName(name);
 446  46 addStatisticsMap(map);
 447  46 return map;
 448    }
 449   
 450    /**
 451    * {@inheritDoc}
 452    */
 453  46 public ValueFactory getPersitenceValueFactory(Class valueClass)
 454    {
 455  46 PersistenceValueFactory factory = new PersistenceValueFactory();
 456  46 factory.init(valueClass, persistence);
 457  46 return factory;
 458    }
 459   
 460    /**
 461    * {@inheritDoc}
 462    */
 463  368 public void register(DelayedUpdate object)
 464    {
 465  368 synchronized(queue)
 466    {
 467    // queue helper provides a reverse mapping, so we don't need have
 468    // to perform liner search
 469  368 Long target = (Long)queueHelper.get(object);
 470  368 Set<DelayedUpdate> set;
 471  368 if(target != null)
 472