001    /*
002     * JBoss DNA (http://www.jboss.org/dna)
003     * See the COPYRIGHT.txt file distributed with this work for information
004     * regarding copyright ownership.  Some portions may be licensed
005     * to Red Hat, Inc. under one or more contributor license agreements.
006     * See the AUTHORS.txt file in the distribution for a full listing of 
007     * individual contributors. 
008     *
009     * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010     * is licensed to you under the terms of the GNU Lesser General Public License as
011     * published by the Free Software Foundation; either version 2.1 of
012     * the License, or (at your option) any later version.
013     *
014     * JBoss DNA is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017     * Lesser General Public License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this software; if not, write to the Free
021     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023     */
024    package org.jboss.dna.common.collection;
025    
026    import java.util.ArrayList;
027    import java.util.Collections;
028    import java.util.LinkedList;
029    import java.util.List;
030    import java.util.concurrent.locks.ReadWriteLock;
031    import java.util.concurrent.locks.ReentrantReadWriteLock;
032    import net.jcip.annotations.ThreadSafe;
033    
034    /**
035     * A thread-safe list of problems for some execution context. The problems will be {@link #iterator() returned} in the order in
036     * which they were encountered.
037     * 
038     * @author Randall Hauch
039     */
040    @ThreadSafe
041    public class ThreadSafeProblems extends AbstractProblems {
042    
043        private final ReadWriteLock lock = new ReentrantReadWriteLock();
044        private final List<Problem> problems = new LinkedList<Problem>();
045    
046        /**
047         * {@inheritDoc}
048         * 
049         * @see org.jboss.dna.common.collection.AbstractProblems#hasErrors()
050         */
051        @Override
052        public boolean hasErrors() {
053            try {
054                lock.readLock().lock();
055                return super.hasErrors();
056            } finally {
057                lock.readLock().unlock();
058            }
059        }
060    
061        /**
062         * {@inheritDoc}
063         * 
064         * @see org.jboss.dna.common.collection.AbstractProblems#hasProblems()
065         */
066        @Override
067        public boolean hasProblems() {
068            try {
069                lock.readLock().lock();
070                return super.hasProblems();
071            } finally {
072                lock.readLock().unlock();
073            }
074        }
075    
076        /**
077         * {@inheritDoc}
078         * 
079         * @see org.jboss.dna.common.collection.AbstractProblems#hasInfo()
080         */
081        @Override
082        public boolean hasInfo() {
083            try {
084                lock.readLock().lock();
085                return super.hasInfo();
086            } finally {
087                lock.readLock().unlock();
088            }
089        }
090    
091        /**
092         * {@inheritDoc}
093         * 
094         * @see org.jboss.dna.common.collection.AbstractProblems#hasWarnings()
095         */
096        @Override
097        public boolean hasWarnings() {
098            try {
099                lock.readLock().lock();
100                return super.hasWarnings();
101            } finally {
102                lock.readLock().unlock();
103            }
104        }
105    
106        /**
107         * {@inheritDoc}
108         * 
109         * @see org.jboss.dna.common.collection.AbstractProblems#isEmpty()
110         */
111        @Override
112        public boolean isEmpty() {
113            try {
114                lock.readLock().lock();
115                return super.isEmpty();
116            } finally {
117                lock.readLock().unlock();
118            }
119        }
120    
121        /**
122         * {@inheritDoc}
123         * 
124         * @see org.jboss.dna.common.collection.AbstractProblems#size()
125         */
126        @Override
127        public int size() {
128            try {
129                lock.readLock().lock();
130                return super.size();
131            } finally {
132                lock.readLock().unlock();
133            }
134        }
135    
136        /**
137         * {@inheritDoc}
138         * 
139         * @see org.jboss.dna.common.collection.AbstractProblems#addProblem(Problem)
140         */
141        @Override
142        protected void addProblem( Problem problem ) {
143            try {
144                lock.writeLock().lock();
145                problems.add(problem);
146            } finally {
147                lock.writeLock().unlock();
148            }
149        }
150    
151        /**
152         * {@inheritDoc}
153         * 
154         * @see org.jboss.dna.common.collection.AbstractProblems#getProblems()
155         */
156        @Override
157        protected List<Problem> getProblems() {
158            // Return an unmodifiable copy ...
159            try {
160                lock.readLock().lock();
161                return Collections.unmodifiableList(new ArrayList<Problem>(this.problems));
162            } finally {
163                lock.readLock().unlock();
164            }
165        }
166    }