001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.lang3.concurrent;
018    
019    import java.util.concurrent.Callable;
020    import java.util.concurrent.ExecutorService;
021    
022    /**
023     * <p>
024     * A specialized {@link BackgroundInitializer} implementation that wraps a
025     * {@code Callable} object.
026     * </p>
027     * <p>
028     * An instance of this class is initialized with a {@code Callable} object when
029     * it is constructed. The implementation of the {@link #initialize()} method
030     * defined in the super class delegates to this {@code Callable} so that the
031     * {@code Callable} is executed in the background thread.
032     * </p>
033     * <p>
034     * The {@code java.util.concurrent.Callable} interface is a standard mechanism
035     * of the JDK to define tasks to be executed by another thread. The {@code
036     * CallableBackgroundInitializer} class allows combining this standard interface
037     * with the background initializer API.
038     * </p>
039     * <p>
040     * Usage of this class is very similar to the default usage pattern of the
041     * {@link BackgroundInitializer} class: Just create an instance and provide the
042     * {@code Callable} object to be executed, then call the initializer's
043     * {@link #start()} method. This causes the {@code Callable} to be executed in
044     * another thread. When the results of the {@code Callable} are needed the
045     * initializer's {@link #get()} method can be called (which may block until
046     * background execution is complete). The following code fragment shows a
047     * typical usage example:
048     *
049     * <pre>
050     * // a Callable that performs a complex computation
051     * Callable&lt;Integer&gt; computationCallable = new MyComputationCallable();
052     * // setup the background initializer
053     * CallableBackgroundInitializer&lt;Integer&gt; initializer =
054     *     new CallableBackgroundInitializer(computationCallable);
055     * initializer.start();
056     * // Now do some other things. Initialization runs in a parallel thread
057     * ...
058     * // Wait for the end of initialization and access the result
059     * Integer result = initializer.get();
060     * </pre>
061     *
062     * </p>
063     *
064     * @since 3.0
065     * @version $Id: CallableBackgroundInitializer.java 1082044 2011-03-16 04:26:58Z bayard $
066     * @param <T> the type of the object managed by this initializer class
067     */
068    public class CallableBackgroundInitializer<T> extends BackgroundInitializer<T> {
069        /** The Callable to be executed. */
070        private final Callable<T> callable;
071    
072        /**
073         * Creates a new instance of {@code CallableBackgroundInitializer} and sets
074         * the {@code Callable} to be executed in a background thread.
075         *
076         * @param call the {@code Callable} (must not be <b>null</b>)
077         * @throws IllegalArgumentException if the {@code Callable} is <b>null</b>
078         */
079        public CallableBackgroundInitializer(Callable<T> call) {
080            checkCallable(call);
081            callable = call;
082        }
083    
084        /**
085         * Creates a new instance of {@code CallableBackgroundInitializer} and
086         * initializes it with the {@code Callable} to be executed in a background
087         * thread and the {@code ExecutorService} for managing the background
088         * execution.
089         *
090         * @param call the {@code Callable} (must not be <b>null</b>)
091         * @param exec an external {@code ExecutorService} to be used for task
092         * execution
093         * @throws IllegalArgumentException if the {@code Callable} is <b>null</b>
094         */
095        public CallableBackgroundInitializer(Callable<T> call, ExecutorService exec) {
096            super(exec);
097            checkCallable(call);
098            callable = call;
099        }
100    
101        /**
102         * Performs initialization in a background thread. This implementation
103         * delegates to the {@code Callable} passed at construction time of this
104         * object.
105         *
106         * @return the result of the initialization
107         * @throws Exception if an error occurs
108         */
109        @Override
110        protected T initialize() throws Exception {
111            return callable.call();
112        }
113    
114        /**
115         * Tests the passed in {@code Callable} and throws an exception if it is
116         * undefined.
117         *
118         * @param call the object to check
119         * @throws IllegalArgumentException if the {@code Callable} is <b>null</b>
120         */
121        private void checkCallable(Callable<T> call) {
122            if (call == null) {
123                throw new IllegalArgumentException("Callable must not be null!");
124            }
125        }
126    }