Android Open Source - Gui2Go In Memory Tree State Manager






From Project

Back to project page Gui2Go.

License

The source code is released under:

MIT License

If you think the Android project Gui2Go listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.ami.gui2go.tree;
//from   w  w w  .  j  a  va  2  s  .  c  o m
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import android.database.DataSetObserver;

/**
 * In-memory manager of tree state.
 * 
 * @param <T>
 *            type of identifier
 */
public class InMemoryTreeStateManager<T> implements TreeStateManager<T> {
    private final Map<T, InMemoryTreeNode<T>> allNodes = new HashMap<T, InMemoryTreeNode<T>>();
    private final InMemoryTreeNode<T> topSentinel = new InMemoryTreeNode<T>(
            null, null, -1, true);
    private List<T> visibleListCache = null; // lasy initialised
    private List<T> unmodifiableVisibleList = null;
    private boolean visibleByDefault = true;
    private final Set<DataSetObserver> observers = new HashSet<DataSetObserver>();

    private synchronized void internalDataSetChanged() {
        visibleListCache = null;
        unmodifiableVisibleList = null;
        for (final DataSetObserver observer : observers) {
            observer.onChanged();
        }
    }

    /**
     * If true new nodes are visible by default.
     * 
     * @param visibleByDefault
     *            if true, then newly added nodes are expanded by default
     */
    public void setVisibleByDefault(final boolean visibleByDefault) {
        this.visibleByDefault = visibleByDefault;
    }

    private InMemoryTreeNode<T> getNodeFromTreeOrThrow(final T id) {
        if (id == null) {
            throw new NodeNotInTreeException("(null)");
        }
        final InMemoryTreeNode<T> node = allNodes.get(id);
        if (node == null) {
            throw new NodeNotInTreeException(id.toString());
        }
        return node;
    }

    private InMemoryTreeNode<T> getNodeFromTreeOrThrowAllowRoot(final T id) {
        if (id == null) {
            return topSentinel;
        }
        return getNodeFromTreeOrThrow(id);
    }

    private void expectNodeNotInTreeYet(final T id) {
        final InMemoryTreeNode<T> node = allNodes.get(id);
        if (node != null) {
            throw new NodeAlreadyInTreeException(id.toString(), node.toString());
        }
    }

    @Override
    public synchronized TreeNodeInfo<T> getNodeInfo(final T id) {
        final InMemoryTreeNode<T> node = getNodeFromTreeOrThrow(id);
        final List<InMemoryTreeNode<T>> children = node.getChildren();
        boolean expanded = false;
        if (!children.isEmpty() && children.get(0).isVisible()) {
            expanded = true;
        }
        return new TreeNodeInfo<T>(id, node.getLevel(), !children.isEmpty(),
                node.isVisible(), expanded);
    }

    @Override
    public synchronized List<T> getChildren(final T id) {
        final InMemoryTreeNode<T> node = getNodeFromTreeOrThrowAllowRoot(id);
        return node.getChildIdList();
    }

    @Override
    public synchronized T getParent(final T id) {
        final InMemoryTreeNode<T> node = getNodeFromTreeOrThrowAllowRoot(id);
        return node.getParent();
    }

    private boolean getChildrenVisibility(final InMemoryTreeNode<T> node) {
        boolean visibility;
        final List<InMemoryTreeNode<T>> children = node.getChildren();
        if (children.isEmpty()) {
            visibility = visibleByDefault;
        } else {
            visibility = children.get(0).isVisible();
        }
        return visibility;
    }

    @Override
    public synchronized void addBeforeChild(final T parent, final T newChild,
            final T beforeChild) {
        expectNodeNotInTreeYet(newChild);
        final InMemoryTreeNode<T> node = getNodeFromTreeOrThrowAllowRoot(parent);
        final boolean visibility = getChildrenVisibility(node);
        // top nodes are always expanded.
        if (beforeChild == null) {
            final InMemoryTreeNode<T> added = node.add(0, newChild, visibility);
            allNodes.put(newChild, added);
        } else {
            final int index = node.indexOf(beforeChild);
            final InMemoryTreeNode<T> added = node.add(index == -1 ? 0 : index,
                    newChild, visibility);
            allNodes.put(newChild, added);
        }
        if (visibility) {
            internalDataSetChanged();
        }
    }

    @Override
    public synchronized void addAfterChild(final T parent, final T newChild,
            final T afterChild) {
        expectNodeNotInTreeYet(newChild);
        final InMemoryTreeNode<T> node = getNodeFromTreeOrThrowAllowRoot(parent);
        final boolean visibility = getChildrenVisibility(node);
        if (afterChild == null) {
            final InMemoryTreeNode<T> added = node.add(
                    node.getChildrenListSize(), newChild, visibility);
            allNodes.put(newChild, added);
        } else {
            final int index = node.indexOf(afterChild);
            final InMemoryTreeNode<T> added = node.add(
                    index == -1 ? node.getChildrenListSize() : index, newChild,
                    visibility);
            allNodes.put(newChild, added);
        }
        if (visibility) {
            internalDataSetChanged();
        }
    }

    @Override
    public synchronized void removeNodeRecursively(final T id) {
        final InMemoryTreeNode<T> node = getNodeFromTreeOrThrowAllowRoot(id);
        final boolean visibleNodeChanged = removeNodeRecursively(node);
        final T parent = node.getParent();
        final InMemoryTreeNode<T> parentNode = getNodeFromTreeOrThrowAllowRoot(parent);
        parentNode.removeChild(id);
        if (visibleNodeChanged) {
            internalDataSetChanged();
        }
    }

    private boolean removeNodeRecursively(final InMemoryTreeNode<T> node) {
        boolean visibleNodeChanged = false;
        for (final InMemoryTreeNode<T> child : node.getChildren()) {
            if (removeNodeRecursively(child)) {
                visibleNodeChanged = true;
            }
        }
        node.clearChildren();
        if (node.getId() != null) {
            allNodes.remove(node.getId());
            if (node.isVisible()) {
                visibleNodeChanged = true;
            }
        }
        return visibleNodeChanged;
    }

    private void setChildrenVisibility(final InMemoryTreeNode<T> node,
            final boolean visible, final boolean recursive) {
        for (final InMemoryTreeNode<T> child : node.getChildren()) {
            child.setVisible(visible);
            if (recursive) {
                setChildrenVisibility(child, visible, true);
            }
        }
    }

    @Override
    public synchronized void expandDirectChildren(final T id) {
        final InMemoryTreeNode<T> node = getNodeFromTreeOrThrowAllowRoot(id);
        setChildrenVisibility(node, true, false);
        internalDataSetChanged();
    }

    @Override
    public synchronized void expandEverythingBelow(final T id) {
        final InMemoryTreeNode<T> node = getNodeFromTreeOrThrowAllowRoot(id);
        setChildrenVisibility(node, true, true);
        internalDataSetChanged();
    }

    @Override
    public synchronized void collapseChildren(final T id) {
        final InMemoryTreeNode<T> node = getNodeFromTreeOrThrowAllowRoot(id);
        if (node == topSentinel) {
            for (final InMemoryTreeNode<T> n : topSentinel.getChildren()) {
                setChildrenVisibility(n, false, true);
            }
        } else {
            setChildrenVisibility(node, false, true);
        }
        internalDataSetChanged();
    }

    @Override
    public synchronized T getNextSibling(final T id) {
        final T parent = getParent(id);
        final InMemoryTreeNode<T> parentNode = getNodeFromTreeOrThrowAllowRoot(parent);
        boolean returnNext = false;
        for (final InMemoryTreeNode<T> child : parentNode.getChildren()) {
            if (returnNext) {
                return child.getId();
            }
            if (child.getId().equals(id)) {
                returnNext = true;
            }
        }
        return null;
    }

    @Override
    public synchronized T getPreviousSibling(final T id) {
        final T parent = getParent(id);
        final InMemoryTreeNode<T> parentNode = getNodeFromTreeOrThrowAllowRoot(parent);
        final T previousSibling = null;
        for (final InMemoryTreeNode<T> child : parentNode.getChildren()) {
            if (child.getId().equals(id)) {
                return previousSibling;
            }
        }
        return null;
    }

    @Override
    public synchronized boolean isInTree(final T id) {
        return allNodes.containsKey(id);
    }

    @Override
    public synchronized int getVisibleCount() {
        return getVisibleList().size();
    }

    @Override
    public synchronized List<T> getVisibleList() {
        T currentId = null;
        if (visibleListCache == null) {
            visibleListCache = new ArrayList<T>(allNodes.size());
            do {
                currentId = getNextVisible(currentId);
                if (currentId == null) {
                    break;
                } else {
                    visibleListCache.add(currentId);
                }
            } while (true);
        }
        if (unmodifiableVisibleList == null) {
            unmodifiableVisibleList = Collections
                    .unmodifiableList(visibleListCache);
        }
        return unmodifiableVisibleList;
    }

    public synchronized T getNextVisible(final T id) {
        final InMemoryTreeNode<T> node = getNodeFromTreeOrThrowAllowRoot(id);
        if (!node.isVisible()) {
            return null;
        }
        final List<InMemoryTreeNode<T>> children = node.getChildren();
        if (!children.isEmpty()) {
            final InMemoryTreeNode<T> firstChild = children.get(0);
            if (firstChild.isVisible()) {
                return firstChild.getId();
            }
        }
        final T sibl = getNextSibling(id);
        if (sibl != null) {
            return sibl;
        }
        T parent = node.getParent();
        do {
            if (parent == null) {
                return null;
            }
            final T parentSibling = getNextSibling(parent);
            if (parentSibling != null) {
                return parentSibling;
            }
            parent = getNodeFromTreeOrThrow(parent).getParent();
        } while (true);
    }

    @Override
    public synchronized void registerDataSetObserver(
            final DataSetObserver observer) {
        observers.add(observer);
    }

    @Override
    public synchronized void unregisterDataSetObserver(
            final DataSetObserver observer) {
        observers.remove(observer);
    }

    @Override
    public int getLevel(final T id) {
        return getNodeFromTreeOrThrow(id).getLevel();
    }

    @Override
    public Integer[] getHierarchyDescription(final T id) {
        final int level = getLevel(id);
        final Integer[] hierarchy = new Integer[level + 1];
        int currentLevel = level;
        T currentId = id;
        T parent = getParent(currentId);
        while (currentLevel >= 0) {
            hierarchy[currentLevel--] = getChildren(parent).indexOf(currentId);
            currentId = parent;
            parent = getParent(parent);
        }
        return hierarchy;
    }

    private void appendToSb(final StringBuilder sb, final T id) {
        if (id != null) {
            final TreeNodeInfo<T> node = getNodeInfo(id);
            final int indent = node.getLevel() * 4;
            final char[] indentString = new char[indent];
            Arrays.fill(indentString, ' ');
            sb.append(indentString);
            sb.append(node.toString());
            sb.append(Arrays.asList(getHierarchyDescription(id)).toString());
            sb.append("\n");
        }
        final List<T> children = getChildren(id);
        for (final T child : children) {
            appendToSb(sb, child);
        }
    }

    @Override
    public synchronized String toString() {
        final StringBuilder sb = new StringBuilder();
        appendToSb(sb, null);
        return sb.toString();
    }

    @Override
    public synchronized void clear() {
        allNodes.clear();
        topSentinel.clearChildren();
        internalDataSetChanged();
    }

    @Override
    public void refresh() {
        internalDataSetChanged();
    }

}




Java Source Code List

com.ami.gui2go.ActivityManager.java
com.ami.gui2go.EditorActivity.java
com.ami.gui2go.FileDialogFragment.java
com.ami.gui2go.GridViewItemClickListener.java
com.ami.gui2go.HomeActivity.java
com.ami.gui2go.LongClickListener.java
com.ami.gui2go.ProjectManagerActivity.java
com.ami.gui2go.ResourceManagerActivity.java
com.ami.gui2go.UserGuideActivity.java
com.ami.gui2go.models.ActivityInfo.java
com.ami.gui2go.models.ProjectInfo.java
com.ami.gui2go.models.WidgetAttribute.java
com.ami.gui2go.models.WidgetTypes.java
com.ami.gui2go.models.WidgetWrapper.java
com.ami.gui2go.models.Widget.java
com.ami.gui2go.tree.AbstractTreeViewAdapter.java
com.ami.gui2go.tree.InMemoryTreeNode.java
com.ami.gui2go.tree.InMemoryTreeStateManager.java
com.ami.gui2go.tree.NodeAlreadyInTreeException.java
com.ami.gui2go.tree.NodeNotInTreeException.java
com.ami.gui2go.tree.SimpleStandardAdapter.java
com.ami.gui2go.tree.TreeBuilder.java
com.ami.gui2go.tree.TreeConfigurationException.java
com.ami.gui2go.tree.TreeNodeInfo.java
com.ami.gui2go.tree.TreeStateManager.java
com.ami.gui2go.tree.TreeViewList.java
com.ami.gui2go.utils.FileHelper.java
com.ami.gui2go.utils.LayoutXMLCreator.java
com.ami.gui2go.utils.ProjectXMLParser.java
com.ami.gui2go.utils.TextValidator.java
com.ami.gui2go.views.ColorPickerDialog.java