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