001    /**
002     * Copyright (c) 2000-present 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.portlet.exportimport.lar;
016    
017    import com.liferay.portal.kernel.util.AutoResetThreadLocal;
018    
019    import java.util.ArrayList;
020    import java.util.Collections;
021    import java.util.List;
022    import java.util.concurrent.Callable;
023    
024    /**
025     * @author Daniel Kocsis
026     */
027    public class ExportImportProcessCallbackUtil {
028    
029            public static List<Callable<?>> popCallbackList() {
030                    List<List<Callable<?>>> callbackListList =
031                            _callbackListListThreadLocal.get();
032    
033                    return callbackListList.remove(callbackListList.size() - 1);
034            }
035    
036            public static void pushCallbackList() {
037                    List<List<Callable<?>>> callbackListList =
038                            _callbackListListThreadLocal.get();
039    
040                    callbackListList.add(Collections.<Callable<?>>emptyList());
041            }
042    
043            public static void registerCallback(Callable<?> callable) {
044                    List<List<Callable<?>>> callbackListList =
045                            _callbackListListThreadLocal.get();
046    
047                    if (callbackListList.isEmpty()) {
048    
049                            // Not within a transaction boundary and should only happen during
050                            // an upgrade or verify process. See
051                            // DBUpgrader#_disableTransactions.
052    
053                            try {
054                                    callable.call();
055                            }
056                            catch (Exception e) {
057                                    throw new RuntimeException(e);
058                            }
059                    }
060                    else {
061                            int index = callbackListList.size() - 1;
062    
063                            List<Callable<?>> callableList = callbackListList.get(index);
064    
065                            if (callableList == Collections.<Callable<?>>emptyList()) {
066                                    callableList = new ArrayList<>();
067    
068                                    callbackListList.set(index, callableList);
069                            }
070    
071                            callableList.add(callable);
072                    }
073            }
074    
075            private static final ThreadLocal<List<List<Callable<?>>>>
076                    _callbackListListThreadLocal =
077                            new AutoResetThreadLocal<List<List<Callable<?>>>>(
078                                    ExportImportProcessCallbackUtil.class +
079                                            "._callbackListListThreadLocal") {
080    
081                                    @Override
082                                    protected List<List<Callable<?>>> initialValue() {
083                                            return new ArrayList<>();
084                                    }
085    
086                            };
087    
088    }