Clover coverage report -
Coverage timestamp: Sun Nov 1 2009 23:08:24 UTC
file stats: LOC: 696   Methods: 28
NCLOC: 411   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
CollectionImpl.java 66.2% 67.3% 89.3% 69.1%
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: CollectionImpl.java 643240 2008-04-01 01:53:39Z natalia $
 18    */
 19   
 20    package org.apache.xindice.client.xmldb.embed;
 21   
 22    import org.apache.xindice.client.xmldb.ResourceSetImpl;
 23    import org.apache.xindice.client.xmldb.XindiceCollection;
 24    import org.apache.xindice.client.xmldb.resources.BinaryResourceImpl;
 25    import org.apache.xindice.client.xmldb.resources.XMLResourceImpl;
 26    import org.apache.xindice.core.Collection;
 27    import org.apache.xindice.core.DBException;
 28    import org.apache.xindice.core.Database;
 29    import org.apache.xindice.core.FaultCodes;
 30    import org.apache.xindice.core.data.Entry;
 31    import org.apache.xindice.core.data.NodeSet;
 32    import org.apache.xindice.core.meta.MetaData;
 33    import org.apache.xindice.core.query.QueryUtil;
 34    import org.apache.xindice.util.Configuration;
 35    import org.apache.xindice.xml.TextWriter;
 36    import org.apache.xindice.xml.dom.DocumentImpl;
 37    import org.w3c.dom.Document;
 38    import org.w3c.dom.Element;
 39    import org.w3c.dom.Node;
 40    import org.xmldb.api.base.ErrorCodes;
 41    import org.xmldb.api.base.Resource;
 42    import org.xmldb.api.base.ResourceSet;
 43    import org.xmldb.api.base.XMLDBException;
 44    import org.xmldb.api.modules.BinaryResource;
 45    import org.xmldb.api.modules.XMLResource;
 46   
 47    import java.util.Hashtable;
 48    import java.util.StringTokenizer;
 49   
 50    /**
 51    * Implementation of XML:DB's <code>Collection</code> interface using
 52    * direct access to interact with database server
 53    *
 54    * @author <a href="mailto:james.bates@amplexor.com">James Bates</a>
 55    * @author <a href="mailto:kstaken@xmldatabases.org">Kimbro Staken</a>
 56    * @version $Revision: 643240 $, $Date: 2008-04-01 01:53:39 +0000 (Tue, 01 Apr 2008) $
 57    */
 58    public class CollectionImpl extends XindiceCollection {
 59   
 60    private Database db;
 61    private Collection col;
 62   
 63    /**
 64    * Creates new <code>CollectionImpl</code> instance representing connection
 65    * to server collection.
 66    *
 67    * @param db Database this collection resides in
 68    * @param collPath Canonical path of this collection (including database name)
 69    * @exception XMLDBException thrown if a connection could not be established,
 70    * because of URL syntax errors, or connection failure, or if no
 71    * collection with path <code>collPath</code> could be located.
 72    */
 73  2278 public CollectionImpl(Database db, String collPath) throws XMLDBException {
 74  2278 super(collPath);
 75  2278 this.db = db;
 76   
 77    // Extract path of the collection within database
 78  2278 String collName = "/";
 79  2278 int colIndex = collPath.indexOf('/', 1);
 80  2278 if (colIndex != -1) {
 81  2268 collName = collPath.substring(colIndex);
 82  2268 if (collName.equals("")) {
 83  0 collName = "/";
 84    }
 85    }
 86   
 87  2278 try {
 88  2278 this.col = db.getCollection(collName);
 89    } catch (Exception e) {
 90  0 throw FaultCodes.createXMLDBException(ErrorCodes.INVALID_COLLECTION,
 91    "Collection not available: " + collPath, e);
 92    }
 93   
 94  2278 if (this.col == null) {
 95  2 throw new XMLDBException(ErrorCodes.NO_SUCH_COLLECTION,
 96    "Collection not found: " + collPath);
 97    }
 98    }
 99   
 100    /**
 101    * Retrieves a <code>Resource</code> from the database. If the
 102    * <code>Resource</code> could not be
 103    * located a null value will be returned.
 104    *
 105    * @param id the unique id for the requested resource.
 106    * @return The retrieved <code>Resource</code> instance.
 107    * @exception XMLDBException with expected error codes.<br />
 108    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 109    * specific errors that occur.<br />
 110    * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code>
 111    * method has been called on the <code>Collection</code><br />
 112    */
 113  356 public Resource getResource(String id) throws XMLDBException {
 114   
 115  356 checkOpen();
 116  356 try {
 117  356 Entry entry = col.getEntry(id);
 118  356 if (entry == null) {
 119  14 return null;
 120    }
 121   
 122  342 switch (entry.getEntryType()) {
 123  338 case Entry.DOCUMENT:
 124  338 DocumentImpl doc = (DocumentImpl) entry.getValue();
 125   
 126    // This should probably just pass the document.
 127  338 if (doc.getDataBytes() == null) {
 128  169 return new XMLResourceImpl(id, id, this, TextWriter.toString(doc));
 129    } else {
 130  169 return new XMLResourceImpl(id, id, this, doc.getSymbols(), doc.getDataBytes());
 131    }
 132   
 133  4 case Entry.BINARY:
 134  4 return new BinaryResourceImpl(id, this, (byte[]) entry.getValue());
 135   
 136  0 default:
 137  0 throw new XMLDBException(ErrorCodes.UNKNOWN_RESOURCE_TYPE,
 138    "Internal error: Unexpected resource type " + entry.getEntryType());
 139    }
 140   
 141    } catch (Exception e) {
 142  0 throw FaultCodes.createXMLDBException("Resource not available: " + id, e);
 143    }
 144    }
 145   
 146    /**
 147    * Returns the number of resources currently stored in this collection or 0
 148    * if the collection is empty.
 149    *
 150    * @return the number of resource in the collection.
 151    * @exception XMLDBException with expected error codes.<br />
 152    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 153    * specific errors that occur.<br />
 154    * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code>
 155    * method has been called on the <code>Collection</code><br />
 156    */
 157  42 public int getResourceCount() throws XMLDBException {
 158   
 159  42 checkOpen();
 160  42 try {
 161  42 return (int) col.getDocumentCount();
 162    } catch (Exception e) {
 163  0 throw FaultCodes.createXMLDBException(e);
 164    }
 165    }
 166   
 167    /**
 168    * Stores the provided resource into the database. If the resource does not
 169    * already exist it will be created. If it does already exist it will be
 170    * updated.
 171    *
 172    * @param res the resource to store in the database.
 173    * @exception XMLDBException with expected error codes.<br />
 174    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 175    * specific errors that occur.<br />
 176    * <code>ErrorCodes.INVALID_RESOURCE</code> if the <code>Resource</code> is
 177    * not valid..<br />
 178    * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code>
 179    * method has been called on the <code>Collection</code><br />
 180    */
 181  822 public void storeResource(Resource res) throws XMLDBException {
 182  822 if (res.getContent() == null) {
 183  0 throw new XMLDBException(ErrorCodes.INVALID_RESOURCE, "No resource data");
 184    }
 185   
 186  822 checkOpen();
 187   
 188  822 try {
 189  822 if (res instanceof XMLResource) {
 190  814 Node content = getXMLContent(res);
 191  814 if (res.getId() != null) {
 192  814 col.setDocument(res.getId(), (Document) content);
 193    } else {
 194  0 String name = col.insertDocument((Document) content).toString();
 195  0 ((XMLResourceImpl) res).setId(name);
 196    }
 197   
 198  8 } else if (res instanceof BinaryResource) {
 199  8 byte[] bytes = getBinaryContent(res);
 200  8 if (res.getId() != null) {
 201  8 col.setBinary(res.getId(), bytes);
 202    } else {
 203  0 String name = col.insertBinary(bytes).toString();
 204  0 ((BinaryResourceImpl) res).setId(name);
 205    }
 206   
 207    } else {
 208  0 throw new XMLDBException(ErrorCodes.INVALID_RESOURCE,
 209    "Only XMLResource and BinaryResource supported");
 210    }
 211    } catch (DBException e) {
 212  0 throw FaultCodes.createXMLDBException(e.faultCode, e.getMessage(), e);
 213    } catch (XMLDBException e) {
 214  0 throw e;
 215    } catch (Exception e) {
 216  0 throw FaultCodes.createXMLDBException(ErrorCodes.INVALID_RESOURCE,
 217    "Invalid resource: " + res.getId(), e);
 218    }
 219    }
 220   
 221    /**
 222    * Inserts the provided resource into the database.
 223    *
 224    * @param res the resource to insert.
 225    * @exception XMLDBException with expected error codes.<br />
 226    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 227    * specific errors that occur.<br />
 228    * <code>ErrorCodes.INVALID_RESOURCE</code> if the <code>Resource</code> is
 229    * not valid..<br />
 230    * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code>
 231    * method has been called on the <code>Collection</code><br />
 232    */
 233  4 public void insertResource(Resource res) throws XMLDBException {
 234  4 if (res.getContent() == null) {
 235  0 throw new XMLDBException(ErrorCodes.INVALID_RESOURCE, "No resource data");
 236    }
 237   
 238  4 checkOpen();
 239   
 240  4 try {
 241  4 if (res instanceof BinaryResource) {
 242  0 byte[] bytes = getBinaryContent(res);
 243  0 if (res.getId() != null) {
 244  0 col.insertBinary(res.getId(), bytes);
 245    } else {
 246  0 String name = col.insertBinary(bytes).toString();
 247  0 ((BinaryResourceImpl) res).setId(name);
 248    }
 249  4 } else if (res instanceof XMLResource) {
 250  4 Node content = getXMLContent(res);
 251  4 if (res.getId() != null) {
 252  4 col.insertDocument(res.getId(), (Document) content);
 253    } else {
 254  0 String name = col.insertDocument((Document) content).toString();
 255  0 ((XMLResourceImpl) res).setId(name);
 256    }
 257   
 258    } else {
 259  0 throw new XMLDBException(ErrorCodes.INVALID_RESOURCE,
 260    "Only XMLResource and BinaryResource supported");
 261    }
 262    } catch (DBException e) {
 263  2 throw FaultCodes.createXMLDBException(e.faultCode, e.getMessage(), e);
 264    } catch (XMLDBException e) {
 265  0 throw e;
 266    } catch (Exception e) {
 267  0 throw FaultCodes.createXMLDBException(ErrorCodes.INVALID_RESOURCE,
 268    "Invalid resource: " + res.getId(), e);
 269    }
 270    }
 271   
 272    /**
 273    * Updates the provided resource in the database.
 274    *
 275    * @param res the resource to update.
 276    * @exception XMLDBException with expected error codes.<br />
 277    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 278    * specific errors that occur.<br />
 279    * <code>ErrorCodes.INVALID_RESOURCE</code> if the <code>Resource</code> is
 280    * not valid.<br/>
 281    * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code>
 282    * method has been called on the <code>Collection</code><br />
 283    */
 284  4 public void updateResource(Resource res) throws XMLDBException {
 285  4 if (res.getContent() == null) {
 286  0 throw new XMLDBException(ErrorCodes.INVALID_RESOURCE, "No resource data");
 287    }
 288   
 289  4 if (res.getId() == null) {
 290  0 throw new XMLDBException(ErrorCodes.INVALID_RESOURCE, "Resource must have valid ID.");
 291    }
 292   
 293  4 checkOpen();
 294   
 295  4 try {
 296  4 if (res instanceof BinaryResource) {
 297  0 byte[] bytes = getBinaryContent(res);
 298  0 col.updateBinary(res.getId(), bytes);
 299   
 300  4 } else if (res instanceof XMLResource) {
 301  4 Node content = getXMLContent(res);
 302  4 col.updateDocument(res.getId(), (Document) content);
 303   
 304    } else {
 305  0 throw new XMLDBException(ErrorCodes.INVALID_RESOURCE,
 306    "Only XMLResource and BinaryResource supported");
 307    }
 308    } catch (DBException e) {
 309  2 throw FaultCodes.createXMLDBException(e.faultCode, e.getMessage(), e);
 310    } catch (XMLDBException e) {
 311  0 throw e;
 312    } catch (Exception e) {
 313  0 throw FaultCodes.createXMLDBException(ErrorCodes.INVALID_RESOURCE,
 314    "Invalid resource: " + res.getId(), e);
 315    }
 316    }
 317   
 318  8 private byte[] getBinaryContent(Resource res) throws XMLDBException {
 319  8 Object content = res.getContent();
 320  8 byte[] bytes;
 321  8 if (content instanceof byte[]) {
 322  8 bytes = (byte[]) content;
 323    } else {
 324  0 throw new XMLDBException(ErrorCodes.INVALID_RESOURCE,
 325    "The contents of a binary resource must have type byte[].");
 326    }
 327  8 return bytes;
 328    }
 329   
 330  822 private Node getXMLContent(Resource res) throws XMLDBException {
 331  822 Node content = ((XMLResourceImpl) res).getContentAsDOM();
 332  822 if (content == null || !(content instanceof Document)) {
 333  0 throw new XMLDBException(ErrorCodes.INVALID_RESOURCE,
 334    "A resource must be a document in order to be stored.");
 335    }
 336  822 return content;
 337    }
 338   
 339    /* see superclass for documentation */
 340  3228 public boolean isOpen() {
 341  3228 return (col != null);
 342    }
 343   
 344    /* see superclass for documentation */
 345  0 public String getURI() {
 346  0 return "xmldb:" + DatabaseImpl.DRIVER_NAME + "://" + getCanonicalName();
 347    }
 348   
 349    /**
 350    * Returns a <code>Collection</code> instance for the requested child collection
 351    * if it exists.
 352    *
 353    * @param name the name of the child collection to retrieve.
 354    * @return the requested child collection or null if it couldn't be found.
 355    * @exception XMLDBException with expected error codes.<br />
 356    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 357    * specific errors that occur.<br />
 358    * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code>
 359    * method has been called on the <code>Collection</code><br />
 360    */
 361  256 public org.xmldb.api.base.Collection getChildCollection(String name) throws XMLDBException {
 362   
 363  256 if (name.indexOf('/') != -1) {
 364  2 throw new XMLDBException(ErrorCodes.INVALID_COLLECTION,
 365    "Invalid collection: " + name);
 366    }
 367   
 368  254 try {
 369  254 return new CollectionImpl(db, getCanonicalName() + "/" + name);
 370    } catch (XMLDBException e) {
 371  0 if (e.errorCode == ErrorCodes.NO_SUCH_COLLECTION) {
 372    // per getChildCollection contract, return null if not found
 373  0 return null;
 374    }
 375  0 throw e;
 376    } catch (Exception e) {
 377  0 throw FaultCodes.createXMLDBException(ErrorCodes.INVALID_COLLECTION,
 378    "Invalid collection: " + name, e);
 379    }
 380    }
 381   
 382    /**
 383    * Creates a new unique ID within the context of the <code>Collection</code>
 384    *
 385    * @return the created id as a string.
 386    * @exception XMLDBException with expected error codes.<br />
 387    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 388    * specific errors that occur.<br />
 389    * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code>
 390    * method has been called on the <code>Collection</code><br />
 391    */
 392  8 public String createId() throws XMLDBException {
 393   
 394  8 checkOpen();
 395  8 return col.createNewOID().toString();
 396    }
 397   
 398    /**
 399    * Releases all resources consumed by the <code>Collection</code>.
 400    * The <code>close</code> method must
 401    * always be called when use of a <code>Collection</code> is complete. It is
 402    * not safe to use a <code>Collection</code> after the <code>close</code>
 403    * method has been called.
 404    *
 405    * @exception XMLDBException with expected error codes.<br />
 406    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 407    * specific errors that occur.<br />
 408    */
 409  2 public void close() throws XMLDBException {
 410  2 col = null;
 411    // FIXME Should not be necessary here:
 412  2 db.flushConfig();
 413    }
 414   
 415    /**
 416    * Returns the parent collection for this collection or null if no parent
 417    * collection exists.
 418    *
 419    * @return the parent <code>Collection</code> instance.
 420    * @exception XMLDBException with expected error codes.<br />
 421    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 422    * specific errors that occur.<br />
 423    * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code>
 424    * method has been called on the <code>Collection</code><br />
 425    */
 426  8 public org.xmldb.api.base.Collection getParentCollection() throws XMLDBException {
 427   
 428    // If there's only one slash then it's the root.
 429  8 if (collPath.lastIndexOf("/") == 0) {
 430  2 return null;
 431    }
 432   
 433  6 try {
 434  6 return new CollectionImpl(db, collPath.substring(0, collPath.lastIndexOf('/')));
 435    } catch (XMLDBException e) {
 436  0 if (e.errorCode == ErrorCodes.NO_SUCH_COLLECTION) {
 437    // per getParentCollection contract, return null if no parent
 438  0 return null;
 439    }
 440  0 throw e;
 441    }
 442    }
 443   
 444    /**
 445    * Removes the <code>Resource</code> from the database.
 446    *
 447    * @param res the resource to remove.
 448    * @exception XMLDBException with expected error codes.<br />
 449    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 450    * specific errors that occur.<br />
 451    * <code>ErrorCodes.INVALID_RESOURCE</code> if the <code>Resource</code> is
 452    * not valid.<br />
 453    * <code>ErrorCodes.NO_SUCH_RESOURCE</code> if the <code>Resource</code> is
 454    * not known to this <code>Collection</code>.
 455    * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code>
 456    * method has been called on the <code>Collection</code><br />
 457    */
 458  310 public void removeResource(Resource res) throws XMLDBException {
 459   
 460  310 if (res == null || res.getId() == null || res.getId().length() == 0) {
 461    // Query result resource will have null ID
 462  6 throw new XMLDBException(ErrorCodes.INVALID_RESOURCE,
 463    "Resource passed is null or its ID is empty.");
 464    }
 465   
 466  304 checkOpen();
 467  304 try {
 468  304 col.remove(res.getId());
 469    } catch (Exception e) {
 470  0 throw FaultCodes.createXMLDBException(e);
 471    }
 472    }
 473   
 474    /**
 475    * Returns a list of collection names naming all child collections
 476    * of the current collection. If no child collections exist an empty list is
 477    * returned.
 478    *
 479    * @return an array containing collection names for all child
 480    * collections.
 481    * @exception XMLDBException with expected error codes.<br />
 482    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 483    * specific errors that occur.<br />
 484    * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code>
 485    * method has been called on the <code>Collection</code><br />
 486    */
 487  10 public String[] listChildCollections() throws XMLDBException {
 488   
 489  10 checkOpen();
 490  10 try {
 491  10 return col.listCollections();
 492    } catch (Exception e) {
 493  0 throw FaultCodes.createXMLDBException(e);
 494    }
 495    }
 496   
 497    /**
 498    * Returns the number of child collections under this
 499    * <code>Collection</code> or 0 if no child collections exist.
 500    *
 501    * @return the number of child collections.
 502    * @exception XMLDBException with expected error codes.<br />
 503    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 504    * specific errors that occur.<br />
 505    * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code>
 506    * method has been called on the <code>Collection</code><br />
 507    */
 508  12 public int getChildCollectionCount() throws XMLDBException {
 509   
 510  12 checkOpen();
 511  12 try {
 512  12 return (int) col.countCollections();
 513    } catch (Exception e) {
 514  0 throw FaultCodes.createXMLDBException(e);
 515    }
 516    }
 517   
 518    /**
 519    * Returns a list of the ids for all resources stored in the collection.
 520    *
 521    * @return a string array containing the names for all
 522    * <code>Resource</code>s in the collection.
 523    * @exception XMLDBException with expected error codes.<br />
 524    * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
 525    * specific errors that occur.<br />
 526    * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code>
 527    * method has been called on the <code>Collection</code><br />
 528    */
 529  14 public String[] listResources() throws XMLDBException {
 530   
 531  14 checkOpen();
 532  14 try {
 533  14 return col.listDocuments();
 534    } catch (Exception e) {
 535  0 throw FaultCodes.createXMLDBException(e);
 536    }
 537    }
 538   
 539    /* see superclass for documentation */
 540  238 public ResourceSet query(String name, String queryLang, String query, Hashtable nsMap) throws XMLDBException {
 541   
 542  238 checkOpen();
 543  238 try {
 544  238 NodeSet nodeSet;
 545  238 if (name != null) {
 546  4 nodeSet = col.queryDocument(queryLang, query, QueryUtil.mapNamespaces(nsMap), name);
 547    } else {
 548  234 nodeSet = col.queryCollection(queryLang, query, QueryUtil.mapNamespaces(nsMap));
 549    }
 550   
 551  238 return new ResourceSetImpl(this, QueryUtil.queryResultsToDOM(nodeSet));
 552    } catch (Exception e) {
 553  0 throw FaultCodes.createXMLDBException(FaultCodes.QRY_PROCESSING_ERROR,
 554    "Query error: " + e.getMessage(), e);
 555    }
 556    }
 557   
 558    /* see superclass for documentation */
 559  0 public org.xmldb.api.base.Collection createCollection(String name) throws XMLDBException {
 560   
 561  0 checkOpen();
 562  0 try {
 563  0 Document doc = new DocumentImpl();
 564   
 565  0 Element colEle = doc.createElement("collection");
 566  0 colEle.setAttribute("compressed", "true");
 567  0 colEle.setAttribute("name", name);
 568  0 doc.appendChild(colEle);
 569   
 570  0 Element filEle = doc.createElement("filer");
 571  0 filEle.setAttribute("class", "org.apache.xindice.core.filer.BTreeFiler");
 572  0 colEle.appendChild(filEle);
 573   
 574  0 return createCollection(name, doc);
 575    } catch (Exception e) {
 576  0 throw FaultCodes.createXMLDBException(ErrorCodes.INVALID_COLLECTION,
 577    FaultCodes.GEN_UNKNOWN,
 578    "Cannot create child collection", e);
 579    }
 580    }
 581   
 582    // See superclass for documentation. Note that first argument is the path, not the name.
 583  260 public org.xmldb.api.base.Collection createCollection(String path, Document configuration) throws XMLDBException {
 584  260 checkOpen();
 585  260 try {
 586  260 Configuration config = new Configuration(configuration.getDocumentElement(), false);
 587  260 col.createCollection(path, config);
 588   
 589    // Traverse path to get newly created collection
 590  252 org.xmldb.api.base.Collection col = this;
 591  252 if (path.indexOf("/") != -1) {
 592  2 StringTokenizer st = new StringTokenizer(path, "/");
 593  4 while (col != null && st.hasMoreTokens()) {
 594  4 path = st.nextToken().trim();
 595  4 if (path.length() == 0) {
 596  0 continue;
 597    }
 598   
 599  4 if (st.hasMoreTokens()) {
 600  2 col = col.getChildCollection(path);
 601    } else {
 602  2 break;
 603    }
 604    }
 605    }
 606   
 607  252 return col.getChildCollection(path);
 608    } catch (Exception e) {
 609  8 throw FaultCodes.createXMLDBException(ErrorCodes.INVALID_COLLECTION,
 610    FaultCodes.GEN_UNKNOWN,
 611    "Cannot create child collection", e);
 612    }
 613    }
 614   
 615    /* see superclass for documentation */
 616  258 public void removeCollection(String childName) throws XMLDBException {
 617   
 618  258 if (null == childName || childName.length() == 0) {
 619  4 throw new XMLDBException(ErrorCodes.NO_SUCH_COLLECTION,
 620    FaultCodes.COL_COLLECTION_NOT_FOUND,
 621    "Cannot remove child collection '" + childName + "': Name is empty");
 622    }
 623   
 624  254 checkOpen();
 625  254 try {
 626  254 col.dropCollection(col.getCollection(childName));
 627    } catch (Exception e) {
 628  4 throw FaultCodes.createXMLDBException(ErrorCodes.INVALID_COLLECTION,
 629    FaultCodes.GEN_UNKNOWN,
 630    "Cannot remove child collection '" + childName + "'", e);
 631    }
 632    }
 633   
 634    /* see superclass for documentation */
 635  10 public String[] listIndexers() throws XMLDBException {
 636  10 checkOpen();
 637  10 try {
 638  10 return col.listIndexers();
 639    } catch (Exception e) {
 640  0 throw FaultCodes.createXMLDBException(e);
 641    }
 642    }
 643   
 644    /* see superclass for documentation */
 645  60 public void createIndexer(Document configuration) throws XMLDBException {
 646  60 checkOpen();
 647  60 try {
 648  60 col.createIndexer(new Configuration(configuration, false));
 649    } catch (Exception e) {
 650  8 throw FaultCodes.createXMLDBException(e);
 651    }
 652    }
 653   
 654    /* see superclass for documentation */
 655  44 public void dropIndexer(String name) throws XMLDBException {
 656  44 checkOpen();
 657  44 try {
 658  44 col.dropIndexer(col.getIndexer(name));
 659    } catch (Exception e) {
 660  6 throw FaultCodes.createXMLDBException(e);
 661    }
 662    }
 663   
 664    /* see superclass for documentation */
 665  0 public void shutdown() throws XMLDBException {
 666  0 try {
 667  0 db.close();
 668    } catch (Exception e) {
 669  0 throw FaultCodes.createXMLDBException(e);
 670    }
 671    }
 672   
 673  36 public MetaData getMetaData(String id) throws XMLDBException {
 674  36 try {
 675  36 if (id == null) {
 676  14 return col.getCollectionMeta();
 677    } else {
 678  22 return col.getDocumentMeta(id);
 679    }
 680    } catch (Exception e) {
 681  0 throw FaultCodes.createXMLDBException(e);
 682    }
 683    }
 684   
 685  12 public void setMetaData(String id, MetaData meta) throws XMLDBException {
 686  12 try {
 687  12 if (id == null) {
 688  4 col.setCollectionMeta(meta);
 689    } else {
 690  8 col.setDocumentMeta(id, meta);
 691    }
 692    } catch (Exception e) {
 693  0 throw FaultCodes.createXMLDBException(e);
 694    }
 695    }
 696    }