Clover coverage report -
Coverage timestamp: Sun Nov 1 2009 23:08:24 UTC
file stats: LOC: 312   Methods: 13
NCLOC: 188   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
CollectionManager.java 76% 88% 100% 85.2%
coverage coverage
 1    /*
 2    * Licensed to the Apache Software Foundation (ASF) under one or more
 3    * contributor license agreements. See the NOTICE file distributed with
 4    * this work for additional information regarding copyright ownership.
 5    * The ASF licenses this file to You under the Apache License, Version 2.0
 6    * (the "License"); you may not use this file except in compliance with
 7    * the License. You may obtain a copy of the License at
 8    *
 9    * http://www.apache.org/licenses/LICENSE-2.0
 10    *
 11    * Unless required by applicable law or agreed to in writing, software
 12    * distributed under the License is distributed on an "AS IS" BASIS,
 13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14    * See the License for the specific language governing permissions and
 15    * limitations under the License.
 16    *
 17    * $Id: CollectionManager.java 571354 2007-08-31 01:49:58Z natalia $
 18    */
 19   
 20    package org.apache.xindice.core;
 21   
 22    import org.apache.commons.logging.Log;
 23    import org.apache.commons.logging.LogFactory;
 24    import org.apache.xindice.util.Configurable;
 25    import org.apache.xindice.util.Configuration;
 26    import org.apache.xindice.util.ConfigurationCallback;
 27    import org.apache.xindice.util.XindiceException;
 28   
 29    import java.util.Collections;
 30    import java.util.HashMap;
 31    import java.util.Iterator;
 32    import java.util.Map;
 33    import java.util.StringTokenizer;
 34   
 35    /**
 36    * CollectionManager is the base class for both Database and Collection.
 37    *
 38    * @version $Revision: 571354 $, $Date: 2007-08-30 18:49:58 -0700 (Thu, 30 Aug 2007) $
 39    */
 40    public class CollectionManager implements Configurable {
 41   
 42    private static final Log log = LogFactory.getLog(CollectionManager.class);
 43   
 44    private static final String COLLECTIONS = "collections";
 45    private static final String COLLECTION = "collection";
 46    private static final String NAME = "name";
 47   
 48    private static final String[] EMPTY_STRINGS = new String[0];
 49   
 50    private final Map collections = Collections.synchronizedMap(new HashMap());
 51    private Configuration config;
 52   
 53   
 54  1784 protected CollectionManager() {
 55    }
 56   
 57    /**
 58    * @param collection a collection to add
 59    */
 60  245 protected void addCollection(Collection collection) {
 61  245 this.collections.put(collection.getName(), collection);
 62    }
 63   
 64    /**
 65    * Returns number of child collections
 66    *
 67    * @return number of collections
 68    * @throws DBException never
 69    */
 70  18 public final long countCollections() throws DBException {
 71  18 return (long) collections.size();
 72    }
 73   
 74    /**
 75    * createCollection creates a new Collection object and any associated
 76    * system resources that the Collection will need.
 77    *
 78    * @param path The relative path of the Collection
 79    * @param cfg The Collection's configuration
 80    * @return The newly created Collection
 81    * @throws DBException if operation failed
 82    */
 83  1062 public Collection createCollection(String path, Configuration cfg) throws DBException {
 84  1062 if (path == null || "".equals(path)) {
 85  2 throw new DBException(FaultCodes.COL_CANNOT_CREATE,
 86    "Null or empty collection name");
 87    }
 88  1060 if (cfg == null) {
 89  1 throw new DBException(FaultCodes.COL_CANNOT_CREATE,
 90    "Error creating collection '" + path + "': null config");
 91    }
 92  1059 if (!COLLECTION.equals(cfg.getName())) {
 93  0 throw new DBException(FaultCodes.COL_CANNOT_CREATE,
 94    "Cannot create collection " + path +
 95    ". Collection configuration top element must be '" + COLLECTION + "'");
 96    }
 97   
 98  1059 if (path.indexOf("/") != -1) {
 99  3 CollectionManager cm = this;
 100  3 StringTokenizer st = new StringTokenizer(path, "/");
 101  6 while (cm != null && st.hasMoreTokens()) {
 102  6 path = st.nextToken().trim();
 103  6 if (path.length() == 0) {
 104  0 continue;
 105    }
 106   
 107  6 if (!st.hasMoreTokens()) {
 108  3 return cm.createCollection(path, cfg);
 109    }
 110   
 111  3 cm = (CollectionManager) cm.collections.get(path);
 112    }
 113   
 114  0 throw new DBException(FaultCodes.COL_COLLECTION_NOT_FOUND,
 115    "Parent Collection '" + path + "' doesn't exist");
 116    }
 117   
 118    // Get collection name and do a check
 119  1056 String n = cfg.getAttribute(NAME);
 120  1056 if (n == null || n.trim().equals("")) {
 121  3 throw new DBException(FaultCodes.COL_CANNOT_CREATE,
 122    "No name specified in collection configuration");
 123    }
 124   
 125  1053 if (!n.equals(path)) {
 126  7 throw new DBException(FaultCodes.COL_CANNOT_CREATE,
 127    "Name does not match with path name");
 128    }
 129   
 130  1046 Collection collection = new Collection((Collection) this);
 131  1046 synchronized (collections) {
 132  1046 try {
 133  1046 if (getCollection(n) != null) {
 134  13 throw new DBException(FaultCodes.COL_DUPLICATE_COLLECTION,
 135    "Duplicate Collection '" + n + "'");
 136    }
 137   
 138  1033 Configuration colConfig = this.config.getChild(COLLECTIONS, true);
 139  1033 colConfig.add(cfg);
 140   
 141  1033 collection.setConfig(cfg);
 142  1033 collection.create();
 143  1033 collections.put(n, collection);
 144  1033 if (log.isInfoEnabled()) {
 145  252 log.info("Created a new collection named '" + n + "'");
 146    }
 147    } catch (DBException e) {
 148    // Do not wrap DBException
 149  13 throw e;
 150    } catch (Exception e) {
 151  0 throw new DBException(FaultCodes.COL_CANNOT_CREATE,
 152    "Error Creating Collection '" + path + "'", e);
 153    }
 154   
 155  1033 return collection;
 156    }
 157    }
 158   
 159  736 public boolean close() throws DBException {
 160  736 synchronized (collections) {
 161  736 for (Iterator i = collections.values().iterator(); i.hasNext(); ) {
 162  613 Collection collection = (Collection) i.next();
 163  613 try {
 164  613 collection.close();
 165    } catch (DBException e) {
 166  0 if (log.isWarnEnabled()) {
 167  0 log.warn("ignored exception", e);
 168    }
 169    }
 170    }
 171    }
 172   
 173  736 return true;
 174    }
 175   
 176    /**
 177    * dropCollection physically removes the specified Collection and any
 178    * associated system resources that the Collection uses.
 179    *
 180    * @param collection The Collection to drop
 181    * @return Whether or not the Collection was dropped
 182    * @throws DBException if operation failed
 183    */
 184  1558 public boolean dropCollection(Collection collection) throws DBException {
 185  1558 if (collection == null) {
 186  25 throw new DBException(FaultCodes.COL_COLLECTION_NOT_FOUND,
 187    "Collection Value Null");
 188    }
 189   
 190  1533 Collection cm = collection.getParentCollection();
 191  1533 if (cm == null) {
 192  0 throw new DBException(FaultCodes.DBE_CANNOT_DROP,
 193    "You Cannot Drop The Database");
 194    }
 195   
 196  1533 if (cm != this) {
 197  497 return cm.dropCollection(collection);
 198    }
 199   
 200  1036 final String name = collection.getName();
 201   
 202  1036 synchronized (collections) {
 203  1036 boolean dropped = collection.drop();
 204  1036 if (dropped) {
 205  1036 collections.remove(name);
 206  1036 Configuration colConfig = config.getChild(COLLECTIONS);
 207  1036 colConfig.processChildren(COLLECTION, new ConfigurationCallback() {
 208  1167 public void process(Configuration cfg) {
 209  1167 try {
 210  1167 if (cfg.getAttribute(NAME).equals(name)) {
 211  1035 cfg.delete();
 212    }
 213    } catch (Exception e) {
 214  0 if (log.isWarnEnabled()) {
 215  0 log.warn("ignored exception", e);
 216    }
 217    }
 218    }
 219    });
 220    }
 221   
 222  1036 return dropped;
 223    }
 224    }
 225   
 226    /**
 227    * getCollection retrieves a Collection by name.
 228    *
 229    * @param path The Collection path
 230    * @return The Collection (or null)
 231    * @throws DBException if operation failed
 232    */
 233  46045 public Collection getCollection(String path) throws DBException {
 234  46044 if (path == null) {
 235  0 return null;
 236    }
 237   
 238  46043 if (path.indexOf("/") != -1) {
 239  4282 CollectionManager cm = this;
 240  4282 StringTokenizer st = new StringTokenizer(path, "/");
 241  4282 while (cm != null && st.hasMoreTokens()) {
 242  8096 path = st.nextToken().trim();
 243  8096 if (path.length() == 0) {
 244  0 continue;
 245    }
 246   
 247  8096 cm = (CollectionManager) cm.collections.get(path);
 248    }
 249   
 250  4282 return (Collection) cm;
 251    }
 252   
 253  41719 return (Collection) collections.get(path);
 254    }
 255   
 256    /**
 257    * @return The collections map
 258    */
 259  123 protected Map getCollections() {
 260  123 return Collections.unmodifiableMap(this.collections);
 261    }
 262   
 263    /**
 264    * @see org.apache.xindice.util.Configurable#getConfig()
 265    */
 266  11834 public Configuration getConfig() {
 267  11834 return config;
 268    }
 269   
 270    /**
 271    * listCollections retrieves a list of Collections as an array of
 272    * Strings.
 273    *
 274    * @return The Collection list
 275    * @throws DBException never
 276    */
 277  1061 public final String[] listCollections() throws DBException {
 278  1061 synchronized (collections) {
 279  1061 return (String[]) collections.keySet().toArray(EMPTY_STRINGS);
 280    }
 281    }
 282   
 283    /**
 284    * @see org.apache.xindice.util.Configurable#setConfig(org.apache.xindice.util.Configuration)
 285    */
 286  1894 public void setConfig(Configuration config) throws XindiceException {
 287  1894 this.config = config;
 288   
 289  1894 Configuration colConfig = config.getChild(COLLECTIONS);
 290  1894 if (colConfig != null) {
 291  484 colConfig.processChildren(COLLECTION, new ConfigurationCallback() {
 292  370 public void process(Configuration cfg) throws XindiceException {
 293    // check for an existing Collection by name and, if found, skip creating a new Collection
 294    // else, create a new child Collection, configure it an add it
 295    // if the Collection already exists in our collections list,
 296    // creating a new one will cause the old one to be discarded
 297    // while holding open file handles, etc.
 298  370 Collection col = (Collection) collections.get(cfg.getAttribute(NAME));
 299  370 if (col == null) {
 300  370 col = new Collection((Collection) CollectionManager.this);
 301  370 col.setConfig(cfg);
 302  370 collections.put(col.getName(), col);
 303    }
 304    // else, assume col is configured elsewhere...
 305    // I'm not sure this should be happening, but it does
 306    // it is not safe to call col.setConfig again since it does a bunch
 307    // of stuff (like creating a new Filer and overwriting the existing one, etc.)
 308    }
 309    });
 310    }
 311    }
 312    }