001    /**
002     * Copyright (c) 2000-2013 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.dao.orm.QueryPos;
018    import com.liferay.portal.kernel.dao.orm.SQLQuery;
019    import com.liferay.portal.kernel.dao.orm.Session;
020    import com.liferay.portal.kernel.exception.PortalException;
021    import com.liferay.portal.kernel.exception.SystemException;
022    import com.liferay.portal.kernel.workflow.WorkflowConstants;
023    import com.liferay.portal.model.TreeModel;
024    
025    import java.util.ArrayList;
026    import java.util.Deque;
027    import java.util.LinkedList;
028    import java.util.List;
029    
030    /**
031     * @author Shinn Lok
032     */
033    public class TreePathUtil {
034    
035            /**
036             * @deprecated As of 7.0.0, replaced by {@link #rebuildTree(long, long,
037             *             String, TreeModelFinder<?>)}
038             */
039            @Deprecated
040            public static void rebuildTree(
041                            long companyId, long defaultParentPrimaryKey,
042                            TreeModelFinder<?> treeModelFinder)
043                    throws SystemException {
044    
045                    try {
046                            TreePathUtil.rebuildTree(
047                                    companyId, defaultParentPrimaryKey, StringPool.SLASH,
048                                    treeModelFinder);
049                    }
050                    catch (PortalException e) {
051                            throw new SystemException(e);
052                    }
053            }
054    
055            public static void rebuildTree(
056                            long companyId, long parentPrimaryKey, String parentTreePath,
057                            TreeModelFinder<?> treeModelFinder)
058                    throws PortalException, SystemException {
059    
060                    List<TreeModel> modifiedTreeModels = new ArrayList<TreeModel>();
061    
062                    int size = GetterUtil.getInteger(
063                            PropsUtil.get(
064                                    PropsKeys.MODEL_TREE_REBUILD_QUERY_RESULTS_BATCH_SIZE));
065    
066                    Deque<Object[]> traces = new LinkedList<Object[]>();
067    
068                    traces.push(new Object[] {parentPrimaryKey, parentTreePath, 0L});
069    
070                    Object[] trace = null;
071    
072                    while ((trace = traces.poll()) != null) {
073                            Long curParentPrimaryKey = (Long)trace[0];
074                            String curParentTreePath = (String)trace[1];
075                            Long previousPrimaryKey = (Long)trace[2];
076    
077                            if (curParentTreePath.equals(StringPool.SLASH)) {
078                                    treeModelFinder.rebuildDependentModelsTreePaths(
079                                            curParentPrimaryKey, "/0/");
080                            }
081                            else {
082                                    treeModelFinder.rebuildDependentModelsTreePaths(
083                                            curParentPrimaryKey, curParentTreePath);
084                            }
085    
086                            List<? extends TreeModel> treeModels =
087                                    treeModelFinder.findTreeModels(
088                                            previousPrimaryKey, companyId, curParentPrimaryKey, size);
089    
090                            if (treeModels.isEmpty()) {
091                                    continue;
092                            }
093    
094                            if (treeModels.size() == size) {
095                                    TreeModel treeModel = treeModels.get(treeModels.size() - 1);
096    
097                                    trace[2] = treeModel.getPrimaryKeyObj();
098    
099                                    traces.push(trace);
100                            }
101    
102                            for (TreeModel treeModel : treeModels) {
103                                    String treePath = curParentTreePath.concat(
104                                            String.valueOf(treeModel.getPrimaryKeyObj())).concat(
105                                                    StringPool.SLASH);
106    
107                                    treeModel.updateTreePath(treePath);
108    
109                                    traces.push(
110                                            new Object[] {treeModel.getPrimaryKeyObj(), treePath, 0L});
111    
112                                    modifiedTreeModels.add(treeModel);
113                            }
114                    }
115    
116                    treeModelFinder.reindexTreeModels(modifiedTreeModels);
117            }
118    
119            /**
120             * @deprecated As of 7.0.0, with no direct replacement
121             */
122            @Deprecated
123            public static void rebuildTree(
124                    Session session, long companyId, String tableName,
125                    String parentTableName, String parentPrimaryKeyColumnName,
126                    boolean statusColumn) {
127    
128                    rebuildTree(
129                            session, companyId, tableName, parentTableName,
130                            parentPrimaryKeyColumnName, statusColumn, false);
131                    rebuildTree(
132                            session, companyId, tableName, parentTableName,
133                            parentPrimaryKeyColumnName, statusColumn, true);
134            }
135    
136            /**
137             * @deprecated As of 7.0.0, with no direct replacement
138             */
139            @Deprecated
140            protected static void rebuildTree(
141                    Session session, long companyId, String tableName,
142                    String parentTableName, String parentPrimaryKeyColumnName,
143                    boolean statusColumn, boolean rootParent) {
144    
145                    StringBundler sb = new StringBundler(26);
146    
147                    sb.append("update ");
148                    sb.append(tableName);
149                    sb.append(" set ");
150    
151                    if (rootParent) {
152                            sb.append("treePath = '/0/' ");
153                    }
154                    else {
155                            sb.append("treePath = (select ");
156                            sb.append(parentTableName);
157                            sb.append(".treePath from ");
158                            sb.append(parentTableName);
159                            sb.append(" where ");
160                            sb.append(parentTableName);
161                            sb.append(".");
162                            sb.append(parentPrimaryKeyColumnName);
163                            sb.append(" = ");
164                            sb.append(tableName);
165                            sb.append(".");
166                            sb.append(parentPrimaryKeyColumnName);
167                            sb.append(") ");
168                    }
169    
170                    sb.append("where (");
171                    sb.append(tableName);
172                    sb.append(".companyId = ?) and (");
173                    sb.append(tableName);
174                    sb.append(".");
175                    sb.append(parentPrimaryKeyColumnName);
176    
177                    if (rootParent) {
178                            sb.append(" = 0)");
179                    }
180                    else {
181                            sb.append(" != 0)");
182                    }
183    
184                    if (statusColumn) {
185                            sb.append(" and (");
186                            sb.append(tableName);
187                            sb.append(".status != ?)");
188                    }
189    
190                    SQLQuery sqlQuery = session.createSQLQuery(sb.toString());
191    
192                    QueryPos qPos = QueryPos.getInstance(sqlQuery);
193    
194                    qPos.add(companyId);
195    
196                    if (statusColumn) {
197                            qPos.add(WorkflowConstants.STATUS_IN_TRASH);
198                    }
199    
200                    sqlQuery.executeUpdate();
201            }
202    
203    }