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     * @version $Id: CallableBackgroundInitializer.java 889215 2009-12-10 11:56:38Z bayard $
065     * @param <T> the type of the object managed by this initializer class
066     */
067    public class CallableBackgroundInitializer<T> extends BackgroundInitializer<T> {
068        /** The Callable to be executed. */
069        private final Callable<T> callable;
070    
071        /**
072         * Creates a new instance of {@code CallableBackgroundInitializer} and sets
073         * the {@code Callable} to be executed in a background thread.
074         *
075         * @param call the {@code Callable} (must not be <b>null</b>)
076         * @throws IllegalArgumentException if the {@code Callable} is <b>null</b>
077         */
078        public CallableBackgroundInitializer(Callable<T> call) {
079            checkCallable(call);
080            callable = call;
081        }
082    
083        /**
084         * Creates a new instance of {@code CallableBackgroundInitializer} and
085         * initializes it with the {@code Callable} to be executed in a background
086         * thread and the {@code ExecutorService} for managing the background
087         * execution.
088         *
089         * @param call the {@code Callable} (must not be <b>null</b>)
090         * @param exec an external {@code ExecutorService} to be used for task
091         * execution
092         * @throws IllegalArgumentException if the {@code Callable} is <b>null</b>
093         */
094        public CallableBackgroundInitializer(Callable<T> call, ExecutorService exec) {
095            super(exec);
096            checkCallable(call);
097            callable = call;
098        }
099    
100        /**
101         * Performs initialization in a background thread. This implementation
102         * delegates to the {@code Callable} passed at construction time of this
103         * object.
104         *
105         * @return the result of the initialization
106         * @throws Exception if an error occurs
107         */
108        @Override
109        protected T initialize() throws Exception {
110            return callable.call();
111        }
112    
113        /**
114         * Tests the passed in {@code Callable} and throws an exception if it is
115         * undefined.
116         *
117         * @param call the object to check
118         * @throws IllegalArgumentException if the {@code Callable} is <b>null</b>
119         */
120        private void checkCallable(Callable<T> call) {
121            if (call == null) {
122                throw new IllegalArgumentException("Callable must not be null!");
123            }
124        }
125    }