/**
  * Returns the number of children of <code>parent</code>. Returns 0 if the node is a leaf or if it
  * has no children. <code>parent</code> must be a node previously obtained from this data source.
  *
  * @param parent a node in the tree, obtained from this data source
  * @return the number of children of the node <code>parent</code>
  */
 public int getChildCount(Object parent) {
   if (parent instanceof CatalogDirectory) {
     CatalogDirectory catDir = (CatalogDirectory) parent;
     return catDir.getNumCatalogs();
   }
   return 0;
 }
 /**
  * Returns the child of <code>parent</code> at index <code>index</code> in the parent's child
  * array. <code>parent</code> must be a node previously obtained from this data source. This
  * should not return <code>null</code> if <code>index</code> is a valid index for <code>parent
  * </code> (that is <code>index >= 0 &&
  * index < getChildCount(parent</code>)).
  *
  * @param parent a node in the tree, obtained from this data source
  * @return the child of <code>parent</code> at index <code>index</code>
  */
 public Object getChild(Object parent, int index) {
   if (parent instanceof CatalogDirectory) {
     CatalogDirectory catDir = (CatalogDirectory) parent;
     if (index >= 0 && index < catDir.getNumCatalogs()) return catDir.getCatalog(index);
   }
   return null;
 }
 /**
  * Returns the index of child in parent. If <code>parent</code> is <code>null</code> or <code>
  * child</code> is <code>null</code>, returns -1.
  *
  * @param parent a note in the tree, obtained from this data source
  * @param child the node we are interested in
  * @return the index of the child in the parent, or -1 if either <code>child</code> or <code>
  *     parent</code> are <code>null</code>
  */
 public int getIndexOfChild(Object parent, Object child) {
   if (parent instanceof CatalogDirectory && child instanceof Catalog) {
     CatalogDirectory catDir = (CatalogDirectory) parent;
     Catalog cat = (Catalog) child;
     return catDir.indexOf(cat);
   }
   return -1;
 }
 /**
  * Returns the root of the tree. Returns <code>null</code> only if the tree has no nodes.
  *
  * @return the root of the tree
  */
 public Object getRoot() {
   CatalogDirectory rootDir = null, catDir = this;
   while (catDir != null) {
     rootDir = catDir;
     catDir = catDir.getParent();
   }
   return rootDir;
 }
  // Return a tree model event for an operation of the given catalog
  private TreeModelEvent _getTreeModelEvent(Catalog cat) {
    Object source = this;
    CatalogDirectory catDir = cat.getParent();

    Object[] path = null;
    int[] childIndices = null;
    Object[] children = null;
    if (catDir == null) {
      // must be the tree root
      path = new Catalog[1];
      path[0] = cat;
      childIndices = new int[] {0};
    } else {
      path = getPath(catDir);
      childIndices = new int[] {catDir.indexOf(cat)};
    }
    children = new Object[] {cat};

    return new TreeModelEvent(source, path, childIndices, children);
  }
  /** Return an array of catalogs describing the path to the given catalog or catalog directory. */
  public Catalog[] getPath(Catalog cat) {
    if (cat == null) return null;

    List l = new Vector();
    CatalogDirectory dir;
    if (cat instanceof CatalogDirectory) {
      dir = (CatalogDirectory) cat;
    } else {
      dir = cat.getParent();
      l.add(cat);
    }
    while (dir != null) {
      l.add(dir);
      dir = dir.getParent();
    }

    int n = l.size();
    Catalog[] ar = new Catalog[n];
    for (int i = 0; i < n; i++) ar[n - i - 1] = (Catalog) l.get(i);

    return ar;
  }