Coverage report

  %line %branch
ca.spaz.cron.datasource.Datasources
0% 
0% 

 1  
 /*
 2  
  *******************************************************************************
 3  
  * Copyright (c) 2005 Chris Rose and AIMedia
 4  
  * All rights reserved. Datasources and the accompanying materials
 5  
  * are made available under the terms of the Common Public License v1.0
 6  
  * which accompanies this distribution, and is available at
 7  
  * http://www.eclipse.org/legal/cpl-v10.html
 8  
  * 
 9  
  * Contributors:
 10  
  *     Chris Rose
 11  
  *******************************************************************************/
 12  
 package ca.spaz.cron.datasource;
 13  
 
 14  
 import java.io.*;
 15  
 import java.lang.reflect.*;
 16  
 import java.util.*;
 17  
 import java.util.regex.*;
 18  
 
 19  
 import org.apache.log4j.Logger;
 20  
 
 21  
 import ca.spaz.cron.CRONConfiguration;
 22  
 import ca.spaz.util.ProgressListener;
 23  
 
 24  
 /**
 25  
  * A class for managing datasources.
 26  
  * 
 27  
  * @author Chris Rose
 28  
  */
 29  
 public class Datasources {
 30  
    /**
 31  
     * Logger for this class
 32  
     */
 33  0
    private static final Logger logger = Logger.getLogger(Datasources.class);
 34  
 
 35  
    private static Datasources instance;
 36  
 
 37  
    private Map mutablemap;
 38  
 
 39  
    private Map dsmap;
 40  
 
 41  
    private static List dbIDList;
 42  
 
 43  
    public static final Datasources getInstance() {
 44  0
       if (null == instance) {
 45  0
          instance = new Datasources(true);
 46  
       }
 47  0
       return instance;
 48  
    }
 49  
    
 50  
    public static final void initialize(ProgressListener pl) {
 51  0
       if (null == instance) {
 52  0
          instance = new Datasources(false);
 53  
       }
 54  0
       instance.initDatasources(pl);
 55  0
    }
 56  
    
 57  0
    private Datasources(boolean initialize) {
 58  0
       this.dsmap = new HashMap();
 59  0
       this.mutablemap = new HashMap();
 60  0
       if (initialize) {
 61  0
          initDatasources(null);
 62  
       }
 63  0
    }
 64  
 
 65  
    /**
 66  
     * 
 67  
     */
 68  
    private void initDatasources(ProgressListener pl) {
 69  0
       if (null != pl) {
 70  0
          pl.progressStart();
 71  
       }
 72  0
       Pattern dsPattern = Pattern.compile("datasource\\.(\\d+)\\.class");
 73  0
       if (null != pl) {
 74  0
          pl.progress(5);
 75  
       }
 76  0
       ArrayList keys = new ArrayList();
 77  0
       for (Iterator iter = getProperties().keySet().iterator(); iter.hasNext();) {
 78  0
          String key = (String) iter.next();
 79  0
          keys.add(key);
 80  0
       }
 81  0
       int pstep = 95 / (keys.size() + 1);
 82  0
       int progress = 5;
 83  0
       for (Iterator iter = keys.iterator(); iter.hasNext();) {
 84  0
          String key = (String) iter.next();
 85  0
          Matcher m = dsPattern.matcher(key);
 86  0
          if (m.matches()) {
 87  0
             String dsID = m.group(1);
 88  0
             IFoodDatasource ds = null;
 89  
             try {
 90  0
                ds = getFoodDataSource(dsID);
 91  0
             } catch (Exception e1) {
 92  0
                logger.error("initDatasources(ProgressListener)", e1);
 93  0
             }
 94  0
             if (null != ds) {
 95  0
                dsmap.put(dsID, ds);
 96  
             }
 97  0
             if (!ds.isAvailable()) {
 98  0
                ds.initialize();
 99  
             }
 100  
          }
 101  0
          progress += pstep;
 102  0
          if (null != pl) {
 103  0
             pl.progress(progress);
 104  
          }
 105  0
       }
 106  0
       getMutableDataSource();
 107  0
       if (null != pl) {
 108  0
          pl.progress(100);
 109  0
          pl.progressFinish();
 110  
       }
 111  0
    }
 112  
    
 113  
    /**
 114  
     * @return
 115  
     * @throws IOException
 116  
     */
 117  
    private CRONConfiguration getProperties() {
 118  0
       return CRONConfiguration.getInstance();
 119  
    }
 120  
 
 121  
    /**
 122  
     * Retrieve the unique instance of the user data source.  This data source must
 123  
     * accept writing.
 124  
     * 
 125  
     * @return an <code>ILocalFoodDatasource</code> instance for this run of the application.
 126  
     */
 127  
    public ILocalFoodDatasource getMutableDataSource() {
 128  0
       ILocalFoodDatasource ds = (ILocalFoodDatasource) mutablemap.get("user");
 129  0
       if (null == ds) {
 130  
          try {
 131  0
             ds = (ILocalFoodDatasource) getFoodDataSource("user");
 132  0
             if (!ds.isAvailable()) {
 133  0
                ds.initialize();
 134  
             }
 135  0
          } catch (Exception e) {
 136  0
             logger.error("getMutableDataSource()", e);
 137  0
             throw new IllegalStateException("Unable to provide user DS", e);
 138  0
          }
 139  0
          mutablemap.put("user", ds);
 140  
       }
 141  0
       return ds;
 142  
 
 143  
    }
 144  
    
 145  
    private IFoodDatasource getFoodDataSource(String dskey) throws Exception {
 146  0
       String dsClassName = getProperties().getProperty("datasource." + dskey + ".class");
 147  0
       int pcount = Integer.valueOf(getProperties().getProperty("datasource." + dskey + ".parametercount", "0")).intValue();
 148  0
       Class[] paramClasses = new Class[pcount];
 149  0
       String[] paramValues = new String[pcount];
 150  0
       for (int i = 0; i < pcount; i++) {
 151  0
          int pid = i + 1;
 152  0
          String dsParameterValue = getProperties().getProperty("datasource." + dskey + ".parameter." + pid + ".value");
 153  0
          paramClasses[i] = String.class;
 154  0
          paramValues[i] = dsParameterValue;
 155  
       }
 156  
       
 157  0
       Class dsClass = Class.forName(dsClassName);
 158  0
       Method dsMethod = dsClass.getMethod(getProperties().getProperty("datasource." + dskey + ".method", "createReadonlyFoodSource"), paramClasses);
 159  0
       if (!Modclass="keyword">ifier.isStatic(dsMethod.getModclass="keyword">ifiers())) {
 160  0
          throw new IllegalStateException(dsClass + " must have a static method to create the DS");
 161  
       }
 162  0
       IFoodDatasource ret = (IFoodDatasource) dsMethod.invoke(null, paramValues);
 163  0
       return ret;
 164  
    }
 165  
 
 166  
    /**
 167  
     * Retrieve a list of all functional data sources in the application.  This list will
 168  
     * not contain any Datasources that have indicated that they are not available.
 169  
     * 
 170  
     * @return a <code>List</code> of <code>IFoodDatasource</code> instances consisting of
 171  
     * only those for which <code>isAvailable()</code> returns <code>true</code>.
 172  
     */
 173  
    public List getDatasources() {
 174  0
       return getDatasources(false);
 175  
    }
 176  
    
 177  
    /**
 178  
     * Closes all data sources in the application.
 179  
     */
 180  
    public void closeAll() {
 181  0
       List ds = getDatasources(true);
 182  0
       for (Iterator iter = ds.iterator(); iter.hasNext();) {
 183  0
          IFoodDatasource element = (IFoodDatasource) iter.next();
 184  0
          element.close();
 185  0
       }
 186  0
    }
 187  
    
 188  
    /**
 189  
     * Retrieve a list of the Food Groups consisting of the union of all food groups in the
 190  
     * various supported data sources.
 191  
     * 
 192  
     * @return The food groups available in the application.
 193  
     */
 194  
    public List getFoodGroups() {
 195  0
       Set fgs = new HashSet();
 196  0
       for (Iterator iter = mutablemap.values().iterator(); iter.hasNext();) {
 197  0
          IFoodDatasource element = (IFoodDatasource) iter.next();
 198  0
          fgs.addAll(element.getFoodGroups());
 199  0
       }
 200  0
       for (Iterator iter = dsmap.values().iterator(); iter.hasNext();) {
 201  0
          IFoodDatasource element = (IFoodDatasource) iter.next();
 202  0
          fgs.addAll(element.getFoodGroups());
 203  0
       }
 204  0
       return new ArrayList(fgs);
 205  
    }
 206  
 
 207  
    /**
 208  
     * Retrieve a list of the Sources listed in the food data sources.
 209  
     * 
 210  
     * @return a list of sources.
 211  
     */
 212  
    public List getSources() {
 213  0
       Set fgs = new HashSet();
 214  0
       for (Iterator iter = mutablemap.values().iterator(); iter.hasNext();) {
 215  0
          IFoodDatasource element = (IFoodDatasource) iter.next();
 216  0
          fgs.addAll(element.getSources());
 217  0
       }
 218  0
       for (Iterator iter = dsmap.values().iterator(); iter.hasNext();) {
 219  0
          IFoodDatasource element = (IFoodDatasource) iter.next();
 220  0
          fgs.addAll(element.getSources());
 221  0
       }
 222  0
       return new ArrayList(fgs);
 223  
    }
 224  
 
 225  
    /**
 226  
     * Retrieve a list of data sources available in the application.
 227  
     * 
 228  
     * @param includeUnAvailable Set this to true if the datasources list should 
 229  
     * include data sources that indicate that they are unavailable.
 230  
     * @return A List of <code>IFoodDatasource</code> objects representing all
 231  
     * loaded datasources.  if <code>includeUnAvailable</code> is <code>true</code>,
 232  
     * this list will include Datasources that are not operational.
 233  
     */
 234  
    public List getDatasources(boolean includeUnAvailable) {
 235  0
       List ret = new ArrayList();
 236  0
       if (includeUnAvailable) {
 237  0
          ret.addAll(mutablemap.values());
 238  0
          ret.addAll(dsmap.values());
 239  0
       } else {
 240  0
          for (Iterator iter = mutablemap.values().iterator(); iter.hasNext();) {
 241  0
             ILocalFoodDatasource ds = (ILocalFoodDatasource) iter.next();
 242  0
             if (ds.isAvailable()) {
 243  0
                ret.add(ds);
 244  
             }
 245  0
          }
 246  0
          for (Iterator iter = dsmap.values().iterator(); iter.hasNext();) {
 247  0
             IFoodDatasource ds = (IFoodDatasource) iter.next();
 248  0
             if (ds.isAvailable()) {
 249  0
                ret.add(ds);
 250  
             }
 251  0
          }
 252  
       }
 253  0
       return ret;
 254  
    }
 255  
 
 256  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.