001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.executor;
016    
017    import com.liferay.portal.kernel.concurrent.ThreadPoolExecutor;
018    import com.liferay.portal.kernel.executor.PortalExecutorFactory;
019    import com.liferay.portal.kernel.executor.PortalExecutorManager;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    
023    import java.util.Map;
024    import java.util.concurrent.Callable;
025    import java.util.concurrent.ConcurrentHashMap;
026    import java.util.concurrent.ExecutionException;
027    import java.util.concurrent.Future;
028    import java.util.concurrent.TimeUnit;
029    import java.util.concurrent.TimeoutException;
030    
031    /**
032     * @author Shuyang Zhou
033     */
034    public class PortalExecutorManagerImpl implements PortalExecutorManager {
035    
036            public void afterPropertiesSet() {
037                    if (_portalExecutorFactory == null) {
038                            throw new IllegalArgumentException(
039                                    "portal executor factory is null");
040                    }
041            }
042    
043            public <T> Future<T> execute(String name, Callable<T> callable) {
044                    ThreadPoolExecutor portalExecutor = getPortalExecutor(name);
045    
046                    return portalExecutor.submit(callable);
047            }
048    
049            public <T> T execute(
050                            String name, Callable<T> callable, long timeout, TimeUnit timeUnit)
051                    throws ExecutionException, InterruptedException, TimeoutException {
052    
053                    ThreadPoolExecutor portalExecutor = getPortalExecutor(name);
054    
055                    Future<T> future = portalExecutor.submit(callable);
056    
057                    return future.get(timeout, timeUnit);
058            }
059    
060            public ThreadPoolExecutor getPortalExecutor(String name) {
061                    return getPortalExecutor(name, true);
062            }
063    
064            public ThreadPoolExecutor getPortalExecutor(
065                    String name, boolean createIfAbsent) {
066    
067                    ThreadPoolExecutor portalExecutor = _portalExecutors.get(name);
068    
069                    if ((portalExecutor == null) && createIfAbsent) {
070                            synchronized (_portalExecutors) {
071                                    portalExecutor = _portalExecutors.get(name);
072    
073                                    if (portalExecutor == null) {
074                                            portalExecutor =
075                                                    _portalExecutorFactory.createPortalExecutor(name);
076    
077                                            _portalExecutors.put(name, portalExecutor);
078                                    }
079                            }
080                    }
081    
082                    return portalExecutor;
083            }
084    
085            public void setPortalExecutorFactory(
086                    PortalExecutorFactory portalExecutorFactory) {
087    
088                    _portalExecutorFactory = portalExecutorFactory;
089            }
090    
091            public void setPortalExecutors(
092                    Map<String, ThreadPoolExecutor> portalExecutors) {
093    
094                    if (portalExecutors != null) {
095                            _portalExecutors =
096                                    new ConcurrentHashMap<String, ThreadPoolExecutor>(
097                                            portalExecutors);
098                    }
099            }
100    
101            public void shutdown() {
102                    shutdown(false);
103            }
104    
105            public void shutdown(boolean interrupt) {
106                    for (ThreadPoolExecutor portalExecutor : _portalExecutors.values()) {
107                            if (interrupt) {
108                                    portalExecutor.shutdownNow();
109                            }
110                            else {
111                                    portalExecutor.shutdown();
112                            }
113                    }
114    
115                    _portalExecutors.clear();
116            }
117    
118            public void shutdown(String name) {
119                    shutdown(name, false);
120            }
121    
122            public void shutdown(String name, boolean interrupt) {
123                    ThreadPoolExecutor portalExecutor = _portalExecutors.remove(name);
124    
125                    if (portalExecutor == null) {
126                            if (_log.isDebugEnabled()) {
127                                    _log.debug("No portal executor found for name " + name);
128                            }
129    
130                            return;
131                    }
132    
133                    if (interrupt) {
134                            portalExecutor.shutdownNow();
135                    }
136                    else {
137                            portalExecutor.shutdown();
138                    }
139            }
140    
141            private static Log _log = LogFactoryUtil.getLog(
142                    PortalExecutorManagerImpl.class);
143    
144            private PortalExecutorFactory _portalExecutorFactory;
145            private Map<String, ThreadPoolExecutor> _portalExecutors =
146                    new ConcurrentHashMap<String, ThreadPoolExecutor>();
147    
148    }