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.portal.kernel.util;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.model.TreeModel;
019    
020    import java.util.Deque;
021    import java.util.LinkedList;
022    import java.util.List;
023    import java.util.concurrent.ForkJoinPool;
024    import java.util.concurrent.RecursiveAction;
025    
026    /**
027     * @deprecated As of 7.0.0, moved to {@link
028     *             com.liferay.portal.kernel.tree.TreePathUtil}
029     * @author Shinn Lok
030     */
031    @Deprecated
032    public class TreePathUtil {
033    
034            public static void rebuildTree(
035                            long companyId, long parentPrimaryKey, String parentTreePath,
036                            TreeModelTasks<?> treeModelTasks)
037                    throws PortalException {
038    
039                    if (VerifyThreadLocal.isVerifyInProgress() &&
040                            _VERIFY_DATABASE_TRANSACTIONS_DISABLED) {
041    
042                            ForkJoinPool forkJoinPool = new ForkJoinPool();
043    
044                            try {
045                                    forkJoinPool.invoke(
046                                            new RecursiveRebuildTreeTask(
047                                                    treeModelTasks, companyId, parentPrimaryKey,
048                                                    parentTreePath, 0L));
049                            }
050                            finally {
051                                    forkJoinPool.shutdown();
052                            }
053    
054                            return;
055                    }
056    
057                    Deque<Object[]> traces = new LinkedList<>();
058    
059                    traces.push(new Object[] {parentPrimaryKey, parentTreePath, 0L});
060    
061                    Object[] trace = null;
062    
063                    while ((trace = traces.poll()) != null) {
064                            Long curParentPrimaryKey = (Long)trace[0];
065                            String curParentTreePath = (String)trace[1];
066                            Long previousPrimaryKey = (Long)trace[2];
067    
068                            treeModelTasks.rebuildDependentModelsTreePaths(
069                                    curParentPrimaryKey, curParentTreePath);
070    
071                            List<? extends TreeModel> treeModels =
072                                    treeModelTasks.findTreeModels(
073                                            previousPrimaryKey, companyId, curParentPrimaryKey,
074                                            _MODEL_TREE_REBUILD_QUERY_RESULTS_BATCH_SIZE);
075    
076                            if (treeModels.isEmpty()) {
077                                    continue;
078                            }
079    
080                            if (treeModels.size() ==
081                                            _MODEL_TREE_REBUILD_QUERY_RESULTS_BATCH_SIZE) {
082    
083                                    TreeModel treeModel = treeModels.get(treeModels.size() - 1);
084    
085                                    trace[2] = treeModel.getPrimaryKeyObj();
086    
087                                    traces.push(trace);
088                            }
089    
090                            for (TreeModel treeModel : treeModels) {
091                                    String treePath = curParentTreePath.concat(
092                                            String.valueOf(treeModel.getPrimaryKeyObj())).concat(
093                                                    StringPool.SLASH);
094    
095                                    if (!treePath.equals(treeModel.getTreePath())) {
096                                            treeModel.updateTreePath(treePath);
097                                    }
098    
099                                    traces.push(
100                                            new Object[] {treeModel.getPrimaryKeyObj(), treePath, 0L});
101                            }
102                    }
103            }
104    
105            private static final int _MODEL_TREE_REBUILD_QUERY_RESULTS_BATCH_SIZE =
106                    GetterUtil.getInteger(
107                            PropsUtil.get(
108                                    PropsKeys.MODEL_TREE_REBUILD_QUERY_RESULTS_BATCH_SIZE));
109    
110            private static final boolean _VERIFY_DATABASE_TRANSACTIONS_DISABLED =
111                    GetterUtil.getBoolean(
112                            PropsUtil.get(PropsKeys.VERIFY_DATABASE_TRANSACTIONS_DISABLED));
113    
114            private static class RecursiveRebuildTreeTask extends RecursiveAction {
115    
116                    @Override
117                    protected void compute() {
118                            try {
119                                    _treeModelTasks.rebuildDependentModelsTreePaths(
120                                            _parentPrimaryKey, _parentTreePath);
121                            }
122                            catch (PortalException pe) {
123                                    ReflectionUtil.throwException(pe);
124                            }
125    
126                            List<? extends TreeModel> treeModels =
127                                    _treeModelTasks.findTreeModels(
128                                            _previousPrimaryKey, _companyId, _parentPrimaryKey,
129                                            _MODEL_TREE_REBUILD_QUERY_RESULTS_BATCH_SIZE);
130    
131                            if (treeModels.isEmpty()) {
132                                    return;
133                            }
134    
135                            if (treeModels.size() ==
136                                            _MODEL_TREE_REBUILD_QUERY_RESULTS_BATCH_SIZE) {
137    
138                                    TreeModel treeModel = treeModels.get(treeModels.size() - 1);
139    
140                                    RecursiveRebuildTreeTask recursiveRebuildTreeTask =
141                                            new RecursiveRebuildTreeTask(
142                                                    _treeModelTasks, _companyId, _parentPrimaryKey,
143                                                    _parentTreePath, (long)treeModel.getPrimaryKeyObj());
144    
145                                    recursiveRebuildTreeTask.fork();
146                            }
147    
148                            for (TreeModel treeModel : treeModels) {
149                                    String treePath = _parentTreePath.concat(
150                                            String.valueOf(treeModel.getPrimaryKeyObj())).concat(
151                                                    StringPool.SLASH);
152    
153                                    if (!treePath.equals(treeModel.getTreePath())) {
154                                            treeModel.updateTreePath(treePath);
155                                    }
156    
157                                    RecursiveRebuildTreeTask recursiveRebuildTreeTask =
158                                            new RecursiveRebuildTreeTask(
159                                                    _treeModelTasks, _companyId,
160                                                    (long)treeModel.getPrimaryKeyObj(), treePath, 0L);
161    
162                                    recursiveRebuildTreeTask.fork();
163                            }
164                    }
165    
166                    private RecursiveRebuildTreeTask(
167                            TreeModelTasks<?> treeModelTasks, long companyId,
168                            long parentPrimaryKey, String parentTreePath,
169                            long previousPrimaryKey) {
170    
171                            _treeModelTasks = treeModelTasks;
172                            _companyId = companyId;
173                            _parentPrimaryKey = parentPrimaryKey;
174                            _parentTreePath = parentTreePath;
175                            _previousPrimaryKey = previousPrimaryKey;
176                    }
177    
178                    private final long _companyId;
179                    private final long _parentPrimaryKey;
180                    private final String _parentTreePath;
181                    private final long _previousPrimaryKey;
182                    private final TreeModelTasks<?> _treeModelTasks;
183    
184            }
185    
186    }