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.SystemException;
021    import com.liferay.portal.kernel.workflow.WorkflowConstants;
022    import com.liferay.portal.model.TreeModel;
023    
024    import java.util.Deque;
025    import java.util.LinkedList;
026    import java.util.List;
027    
028    /**
029     * @author Shinn Lok
030     */
031    public class TreePathUtil {
032    
033            public static void rebuildTree(
034                            long companyId, long defaultParentPrimaryKey,
035                            TreeModelFinder<?> treeModelFinder)
036                    throws SystemException {
037    
038                    int size = GetterUtil.getInteger(
039                            PropsUtil.get(
040                                    PropsKeys.MODEL_TREE_REBUILD_QUERY_RESULTS_BATCH_SIZE));
041    
042                    Deque<Object[]> traces = new LinkedList<Object[]>();
043    
044                    traces.push(
045                            new Object[] {defaultParentPrimaryKey, StringPool.SLASH, 0L});
046    
047                    Object[] trace = null;
048    
049                    while ((trace = traces.poll()) != null) {
050                            Long parentPrimaryKey = (Long)trace[0];
051                            String parentPath = (String)trace[1];
052                            Long previousPrimaryKey = (Long)trace[2];
053    
054                            List<? extends TreeModel> treeModels =
055                                    treeModelFinder.findTreeModels(
056                                            previousPrimaryKey, companyId, parentPrimaryKey, size);
057    
058                            if (treeModels.isEmpty()) {
059                                    continue;
060                            }
061    
062                            if (treeModels.size() == size) {
063                                    TreeModel treeModel = treeModels.get(treeModels.size() - 1);
064    
065                                    trace[2] = treeModel.getPrimaryKeyObj();
066    
067                                    traces.push(trace);
068                            }
069    
070                            for (TreeModel treeModel : treeModels) {
071                                    String treePath = parentPath.concat(
072                                            String.valueOf(treeModel.getPrimaryKeyObj())).concat(
073                                                    StringPool.SLASH);
074    
075                                    treeModel.updateTreePath(treePath);
076    
077                                    traces.push(
078                                            new Object[] {treeModel.getPrimaryKeyObj(), treePath, 0L});
079                            }
080                    }
081            }
082    
083            public static void rebuildTree(
084                    Session session, long companyId, String tableName,
085                    String parentTableName, String parentPrimaryKeyColumnName,
086                    boolean statusColumn) {
087    
088                    rebuildTree(
089                            session, companyId, tableName, parentTableName,
090                            parentPrimaryKeyColumnName, statusColumn, false);
091                    rebuildTree(
092                            session, companyId, tableName, parentTableName,
093                            parentPrimaryKeyColumnName, statusColumn, true);
094            }
095    
096            protected static void rebuildTree(
097                    Session session, long companyId, String tableName,
098                    String parentTableName, String parentPrimaryKeyColumnName,
099                    boolean statusColumn, boolean rootParent) {
100    
101                    StringBundler sb = new StringBundler(26);
102    
103                    sb.append("update ");
104                    sb.append(tableName);
105                    sb.append(" set ");
106    
107                    if (rootParent) {
108                            sb.append("treePath = '/0/' ");
109                    }
110                    else {
111                            sb.append("treePath = (select ");
112                            sb.append(parentTableName);
113                            sb.append(".treePath from ");
114                            sb.append(parentTableName);
115                            sb.append(" where ");
116                            sb.append(parentTableName);
117                            sb.append(".");
118                            sb.append(parentPrimaryKeyColumnName);
119                            sb.append(" = ");
120                            sb.append(tableName);
121                            sb.append(".");
122                            sb.append(parentPrimaryKeyColumnName);
123                            sb.append(") ");
124                    }
125    
126                    sb.append("where (");
127                    sb.append(tableName);
128                    sb.append(".companyId = ?) and (");
129                    sb.append(tableName);
130                    sb.append(".");
131                    sb.append(parentPrimaryKeyColumnName);
132    
133                    if (rootParent) {
134                            sb.append(" = 0)");
135                    }
136                    else {
137                            sb.append(" != 0)");
138                    }
139    
140                    if (statusColumn) {
141                            sb.append(" and (");
142                            sb.append(tableName);
143                            sb.append(".status != ?)");
144                    }
145    
146                    SQLQuery sqlQuery = session.createSQLQuery(sb.toString());
147    
148                    QueryPos qPos = QueryPos.getInstance(sqlQuery);
149    
150                    qPos.add(companyId);
151    
152                    if (statusColumn) {
153                            qPos.add(WorkflowConstants.STATUS_IN_TRASH);
154                    }
155    
156                    sqlQuery.executeUpdate();
157            }
158    
159    }