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.graph.requests;
023    
024    import java.io.Serializable;
025    import java.util.concurrent.atomic.AtomicBoolean;
026    import org.jboss.dna.graph.connectors.RepositoryConnection;
027    
028    /**
029     * The abstract base class for all classes representing requests to be executed against a {@link RepositoryConnection}.
030     * 
031     * @author Randall Hauch
032     */
033    public abstract class Request implements Serializable {
034    
035        private static final long serialVersionUID = 1L;
036    
037        private Throwable error;
038        private AtomicBoolean cancelled;
039    
040        protected Request() {
041            this.cancelled = new AtomicBoolean(false);
042        }
043    
044        /**
045         * Set the error for this request.
046         * 
047         * @param error the error to be associated with this request, or null if this request is to have no error
048         */
049        public void setError( Throwable error ) {
050            this.error = error;
051        }
052    
053        /**
054         * Return whether there is an error associated with this request
055         * 
056         * @return true if there is an error, or false otherwise
057         */
058        public boolean hasError() {
059            return this.error != null;
060        }
061    
062        /**
063         * Get the error associated with this request, if there is such an error.
064         * 
065         * @return the error, or null if there is none
066         */
067        public Throwable getError() {
068            return error;
069        }
070    
071        /**
072         * Check whether this request has been cancelled. Although it is a recommendation that the result of this method be followed
073         * wherever possible, it is not required to immediately stop processing the request if this method returns <code>true</code>.
074         * For example, if processing is almost complete, it may be appropriate to simply finish processing the request.
075         * <p>
076         * This method is safe to be called by different threads.
077         * </p>
078         * 
079         * @return true if this request has been cancelled, or false otherwise.
080         */
081        public boolean isCancelled() {
082            return cancelled.get();
083        }
084    
085        /**
086         * Set the cancelled state of this request. All requests are initially marked as not cancelled. Note that this is designed so
087         * that the same {@link AtomicBoolean} instance can be passed to multiple requests, allowing a single flag to dictate the
088         * cancelled state of all of those requests.
089         * <p>
090         * So, by default, each request should already be set up to not be cancelled, so for most cases this method does not need to
091         * be called at all. This method should be called when this flag is to be shared among multiple requests, usually when the
092         * requests are being initialized or assembled.
093         * </p>
094         * 
095         * @param cancelled the new (potentially shared) cancelled state for the request; may not be null
096         */
097        /*package*/void setCancelledFlag( AtomicBoolean cancelled ) {
098            assert cancelled != null;
099            this.cancelled = cancelled;
100        }
101    
102        /**
103         * Get this request's cancelled flag.
104         * 
105         * @return the cancelled flag
106         */
107        /*package*/AtomicBoolean getCancelledFlag() {
108            return cancelled;
109        }
110    
111        /**
112         * Cancel this request. After this method is called, the {@link #isCancelled() cancellation flag} is set, and any current or
113         * future processing of the request may be affected by the cancellation. (Note however, that processors may choose to not
114         * respect this request.)
115         * <p>
116         * This method is safe to be called by different threads.
117         * </p>
118         */
119        public void cancel() {
120            this.cancelled.set(true);
121        }
122    
123        /**
124         * Return whether this request only reads information.
125         * 
126         * @return true if this request reads information, or false if it requests that the repository content be changed in some way
127         */
128        public abstract boolean isReadOnly();
129    }