Package entagged.tageditor.tools.renaming.model

Source Code of entagged.tageditor.tools.renaming.model.DefaultTreeModel

/*
*  ********************************************************************   **
*  Copyright notice                                                       **
*  **                                     **
*  (c) 2003 Entagged Developpement Team                           **
*  http://www.sourceforge.net/projects/entagged                           **
*  **                                     **
*  All rights reserved                                                    **
*  **                                     **
*  This script is part of the Entagged project. The Entagged          **
*  project is free software; you can redistribute it and/or modify        **
*  it under the terms of the GNU General Public License as published by   **
*  the Free Software Foundation; either version 2 of the License, or      **
*  (at your option) any later version.                                    **
*  **                                     **
*  The GNU General Public License can be found at                         **
*  http://www.gnu.org/copyleft/gpl.html.                                  **
*  **                                     **
*  This copyright notice MUST APPEAR in all copies of the file!           **
*  ********************************************************************
*/

package entagged.tageditor.tools.renaming.model;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;

import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

import entagged.tageditor.tools.renaming.data.AbstractFile;
import entagged.tageditor.tools.renaming.data.ConfigurationChangeListener;
import entagged.tageditor.tools.renaming.data.DirectoryDescriptor;
import entagged.tageditor.tools.renaming.data.FileDescriptor;

/**
* This class is a treemodel for
* {@link entagged.tageditor.tools.renaming.data.DirectoryDescriptor} objects.<br>
* This class will apply a given filter to all its results.
*
* @author Christian Laireiter
*/
public class DefaultTreeModel implements TreeModel, ConfigurationChangeListener {

  /**
   * This field holds the filter which reduces the tree represented by this
   * model.
   */
  private final DefaultFilter filter;

  /**
   * This field contains the {@link TreeModelListener} objects, added by
   * {@link #addTreeModelListener(TreeModelListener)}
   */
  private final ArrayList listener = new ArrayList();

  /**
   * This field contains those directories, which are given during
   * construction and applied to the given filter.
   */
  private final ArrayList topDirectories;

  /**
   * This string will represent the root of the represented tree.
   */
  private final String treeRoot;

  /**
   * This field will contain all paths of target directories, which have been
   * rejected for display in the target tree.<br>
   * This is used for directories which would remain empty after processing.<br>
   * Those directories won't be created, however they would be displayed.<br>
   * This field will be cleared when {@link #optionHasChanged()} is called.
   */
  private final HashSet rejectedPaths;

  /**
   * Similiar to {@link #rejectedPaths}. But here the accepted are stored.
   */
  private final HashSet acceptedPaths;

  /**
   * Creates an instance which will process the given directories (<code>treeRoots</code>)
   * and use <code>treeFilter</code> to reduce the strucutre.<br>
   *
   * @param treeRoots
   *            The directories which represent the top level of the tree.
   *            <b>Caution:</b> They are held against the given filter.
   * @param treeFilter
   *            The filter which reduces the tree structure represented by the
   *            {@link DirectoryDescriptor} objects themselves.
   * @param treeRootTitle
   *            A String which will be used to name the root node of the
   *            represented tree.
   */
  public DefaultTreeModel(DirectoryDescriptor[] treeRoots,
      DefaultFilter treeFilter, String treeRootTitle) {
    assert treeFilter != null;
    assert treeRoots != null;
    this.filter = treeFilter;
    topDirectories = new ArrayList();
    this.rejectedPaths = new HashSet();
    this.acceptedPaths = new HashSet();
    for (int i = 0; i < treeRoots.length; i++) {
      if (filter.accept(treeRoots[i])) {
        topDirectories.add(treeRoots[i]);
      }
    }
    /*
     * Now create a root object for the tree
     */
    // create a new one for unique use.
    this.treeRoot = new String(treeRootTitle);
  }

  /**
   * (overridden)
   *
   * @see javax.swing.tree.TreeModel#addTreeModelListener(javax.swing.event.TreeModelListener)
   */
  public synchronized void addTreeModelListener(TreeModelListener l) {
    if (!this.listener.contains(l)) {
      this.listener.add(l);
    }
  }

  /**
   * (overridden)
   *
   * @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int)
   */
  public Object getChild(Object parent, int index) {
    Object result = null;
    if (parent == this.treeRoot) {
      result = topDirectories.get(index);
    } else {
      AbstractFile[] children = getFilteredChildren((AbstractFile) parent);
      result = children[index];
    }
    return result;
  }

  /**
   * (overridden)
   *
   * @see javax.swing.tree.TreeModel#getChildCount(java.lang.Object)
   */
  public int getChildCount(Object parent) {
    if (parent == this.treeRoot) {
      return topDirectories.size();
    }
    return getFilteredChildren((AbstractFile) parent).length;
  }

  /**
   * This method returns the subdirectories or files of the given node.<br>
   *
   * @param file
   *            The file object, whose children should be returned.
   * @return Subnodes of given file, held against the filter.
   */
  private AbstractFile[] getFilteredChildren(AbstractFile file) {
    ArrayList result = new ArrayList();

    if (file.isDirectory()) {
      AbstractFile[] children = file.getChildren();
      for (int i = 0; i < children.length; i++) {
        if (children[i] instanceof DirectoryDescriptor) {
          DirectoryDescriptor dir = (DirectoryDescriptor) children[i];
          if (this.filter.accept(dir)) {
            String path = dir.getPath();
            // has this directory already been accepted after
            // last change of options
            if (acceptedPaths.contains(path)) {
              result.add(dir);
            } else if (!rejectedPaths.contains(path)) {
              // If it hast not been rejected, it must
              // be determined, whether it contains files.
              if (getFilteredChildren(children[i]).length > 0) {
                // If it hast children, accept it.
                result.add(children[i]);
                acceptedPaths.add(path);
              } else {
                // mark it as rejected (no contents)
                rejectedPaths.add(path);
              }
            }

          }
        } else {
          if (this.filter.accept((DirectoryDescriptor) file,
              ((FileDescriptor) children[i]))) {
            result.add(children[i]);
          }
        }
      }
    }
    Collections.sort(result);
    AbstractFile[] files = (AbstractFile[]) result
        .toArray(new AbstractFile[result.size()]);
    return files;
  }

  /**
   * (overridden)
   *
   * @see javax.swing.tree.TreeModel#getIndexOfChild(java.lang.Object,
   *      java.lang.Object)
   */
  public int getIndexOfChild(Object parent, Object child) {
    AbstractFile[] children = null;
    if (parent == this.treeRoot) {
      children = (AbstractFile[]) this.topDirectories
          .toArray(new AbstractFile[topDirectories.size()]);
    } else {
      children = getFilteredChildren((AbstractFile) parent);
    }
    int result = Arrays.binarySearch(children, child);
    if (result < 0) {
      result = -1;
    }
    return result;
  }

  /**
   * (overridden)
   *
   * @see javax.swing.tree.TreeModel#getRoot()
   */
  public Object getRoot() {
    return this.treeRoot;
  }

  /**
   * (overridden)
   *
   * @see javax.swing.tree.TreeModel#isLeaf(java.lang.Object)
   */
  public boolean isLeaf(Object node) {
    if (node == treeRoot)
      return false;
    return getFilteredChildren((AbstractFile) node).length == 0;
  }

  /**
   * (overridden)
   *
   * @see entagged.tageditor.tools.renaming.data.ConfigurationChangeListener#optionHasChanged()
   */
  public void optionHasChanged() {
    rejectedPaths.clear();
    acceptedPaths.clear();
    final Iterator it = this.listener.iterator();
    while (it.hasNext()) {
      TreeModelListener current = (TreeModelListener) it.next();
      current.treeStructureChanged(new TreeModelEvent(this, new TreePath(
          getRoot())));
    }
  }

  /**
   * (overridden)
   *
   * @see javax.swing.tree.TreeModel#removeTreeModelListener(javax.swing.event.TreeModelListener)
   */
  public synchronized void removeTreeModelListener(TreeModelListener l) {
    this.listener.remove(l);
  }

  /**
   * (overridden)
   *
   * @see javax.swing.tree.TreeModel#valueForPathChanged(javax.swing.tree.TreePath,
   *      java.lang.Object)
   */
  public synchronized void valueForPathChanged(TreePath path, Object newValue) {
    // Nothing to do
  }

}
TOP

Related Classes of entagged.tageditor.tools.renaming.model.DefaultTreeModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.