Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright SpringSource Inc 2009.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package com.springsource.util.common;
 
 import java.util.List;

ThreadSafeArrayListTree is a value with an ordered collection of subtrees of the same type as the main tree.

Concurrent Semantics
This class is thread safe.

Parameters:
<V> type of values in tree
Author(s):
Glyn Normington
Since:
jersey
 
 
 public final class ThreadSafeArrayListTree<V> implements Tree<V> {
 
     private volatile V value;
 
     private final Object monitor;
 
     private static final Object tieMonitor = new Object();
 
     private final List<ThreadSafeArrayListTree<V>> children = new ArrayList<ThreadSafeArrayListTree<V>>();
 
     private Tree<V> parent;

    
Construct a tree with the given value, which may be null.

Parameters:
value the value of the tree, which may be null
 
     public ThreadSafeArrayListTree(V value) {
         this(valuenew Object());
     }
 
     protected ThreadSafeArrayListTree(V valueObject monitor) {
         this. = value;
         this. = monitor;
     }

    
Construct a tree by deeply copying the given tree, using the given parent, and inheriting the given monitor.

Parameters:
tree the tree to copy
parent the parent of the new tree or null
monitor the monitor to inherit
 
     protected ThreadSafeArrayListTree(Tree<V> treeTree<V> parentObject monitor) {
         this. = tree.getValue();
         this. = monitor;
         this. = parent;
         for (Tree<V> child : tree.getChildren()) {
             this..add(new ThreadSafeArrayListTree<V>(childthisthis.));
         }
     }

    
Returns the tree's value. If there is no value associated with this tree, returns null.

Returns:
the value, which may be null
 
     public final V getValue() {
         return this.;
     }

    
Returns a list of this tree's children (not copies of the children). If the tree has no children, returns an empty list. Never returns null .

The returned list is synchronized to preserve thread safety, but may still result in ConcurrentModificationException being thrown.

Returns:
this tree's children
 
     public List<Tree<V>> getChildren() {
         synchronized (this.) {
             return new SynchronizedList<Tree<V>>(this.this.);
         }
     }

    
Adds a new child tree to this node's children. The child tree is copied, although its values are not. The copy shares this tree's monitor.

Parameters:
child the child tree to add
Returns:
the copy of the child tree
    public Tree<V> addChild(Tree<V> child) {
        synchronized (this.) {
            ThreadSafeArrayListTree<V> childCopy = new ThreadSafeArrayListTree<V>(childthisthis.);
            this..add(childCopy);
            return childCopy;
        }
    }

    
Removes the first occurrence of the given child tree from this node's children. Returns true if the child was found and removed, otherwise false.

Parameters:
child the child tree to remove
Returns:
true if the child tree was removed successfully, otherwise false.
See also:
java.util.List.remove(java.lang.Object)
    public boolean removeChild(Tree<V> child) {
        synchronized (this.) {
            boolean removed = this..remove(child);
            if (removed) {
                setParent(childnull);
            }
            return removed;
        }
    }
    /*
     * All the children in this.children share this.monitor.
     */
    private void setParent(Tree<V> childTree<V> parent) {
        synchronized (this.) {
            if (child instanceof ThreadSafeArrayListTree<?>) {
                ThreadSafeArrayListTree<V> concreteChild = (ThreadSafeArrayListTree<V>) child;
                concreteChild.parent = parent;
            }
        }
    }

    
Traverse this ThreadSafeArrayListTree in preorder (see below) and call the visit method of the given Tree.TreeVisitor at each node. The visitor determines whether the children of each visited tree should also be visited.

Preorder traversal visits the tree and then visits, in preorder, each child of the tree.

Parameters:
visitor a Tree.TreeVisitor
    public void visit(TreeVisitor<V> visitor) {
        if (visitor.visit(this)) {
            for (int i = 0; i < numChildren(); i++) {
                ThreadSafeArrayListTree<V> nextChild = getChild(i);
                if (nextChild != null) {
                    nextChild.visit(visitor);
                } else {
                    break;
                }
            }
        }
    }

    
    public <E extends Exceptionvoid visit(ExceptionThrowingTreeVisitor<V, E> visitorthrows E {
        if (visitor.visit(this)) {
            for (int i = 0; i < numChildren(); i++) {
                ThreadSafeArrayListTree<V> nextChild = getChild(i);
                if (nextChild != null) {
                    nextChild.visit(visitor);
                } else {
                    break;
                }
            }
        }
    }
    private ThreadSafeArrayListTree<V> getChild(int i) {
        synchronized (this.) {
            try {
                return this..get(i);
            } catch (IndexOutOfBoundsException e) {
                return null;
            }
        }
    }
    private int numChildren() {
        synchronized (this.) {
            return this..size();
        }
    }

    
Returns the number of nodes in the tree. This is one plus the sum of the number of nodes in each of the children.

If there are more than Integer.MAX_VALUE node, the return value is undefined and the user should seek professional help.

Returns:
the number of non-null nodes in the tree
    public int size() {
        int size = 1;
        synchronized (this.) {
            for (ThreadSafeArrayListTree<V> child : this.) {
                size += child.size();
            }
        }
        return size;
    }

    
    @Override
    public int hashCode() {
        synchronized (this.) {
            final int prime = 31;
            int result = 1;
            result = prime * result + .hashCode();
            result = prime * result + (( == null) ? 0 : .hashCode());
            return result;
        }
    }

    
    @SuppressWarnings("unchecked")
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        ThreadSafeArrayListTree<V> other = (ThreadSafeArrayListTree<V>) obj;
        int thisHash = System.identityHashCode(this);
        int otherHash = System.identityHashCode(other);
        if (thisHash < otherHash) {
            synchronized (this.) {
                synchronized (other.monitor) {
                    if (!.equals(other.children)) {
                        return false;
                    }
                }
            }
        } else if (thisHash > otherHash) {
            synchronized (other.monitor) {
                synchronized (this.) {
                    if (!.equals(other.children)) {
                        return false;
                    }
                }
            }
        } else {
            synchronized () {
                synchronized (this.) {
                    synchronized (other.monitor) {
                        if (!.equals(other.children)) {
                            return false;
                        }
                    }
                }
            }
        }
        if ( == null) {
            if (other.value != null) {
                return false;
            }
        } else if (!.equals(other.value)) {
            return false;
        }
        return true;
    }

    
    @Override
    public String toString() {
        StringBuffer result = new StringBuffer();
        result.append(this. != null ? this. : "null").append("<");
        synchronized (this.) {
            boolean first = true;
            for (ThreadSafeArrayListTree<V> child : this.) {
                if (!first) {
                    result.append(", ");
                }
                result.append(child.toString());
                first = false;
            }
        }
        result.append(">");
        return result.toString();
    }

    
    public Tree<V> getParent() {
        return this.;
    }
New to GrepCode? Check out our FAQ X