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.portlet.layoutsadmin.util;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.json.JSONArray;
019    import com.liferay.portal.kernel.json.JSONFactoryUtil;
020    import com.liferay.portal.kernel.json.JSONObject;
021    import com.liferay.portal.kernel.staging.LayoutStagingUtil;
022    import com.liferay.portal.kernel.staging.StagingUtil;
023    import com.liferay.portal.kernel.util.ArrayUtil;
024    import com.liferay.portal.kernel.util.HtmlUtil;
025    import com.liferay.portal.kernel.util.ParamUtil;
026    import com.liferay.portal.kernel.util.StringBundler;
027    import com.liferay.portal.kernel.util.StringPool;
028    import com.liferay.portal.kernel.util.WebKeys;
029    import com.liferay.portal.model.Layout;
030    import com.liferay.portal.model.LayoutBranch;
031    import com.liferay.portal.model.LayoutRevision;
032    import com.liferay.portal.model.LayoutSetBranch;
033    import com.liferay.portal.model.User;
034    import com.liferay.portal.model.impl.VirtualLayout;
035    import com.liferay.portal.security.permission.ActionKeys;
036    import com.liferay.portal.service.LayoutLocalServiceUtil;
037    import com.liferay.portal.service.LayoutServiceUtil;
038    import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
039    import com.liferay.portal.service.permission.GroupPermissionUtil;
040    import com.liferay.portal.service.permission.LayoutPermissionUtil;
041    import com.liferay.portal.theme.ThemeDisplay;
042    import com.liferay.portal.util.PortalUtil;
043    import com.liferay.portal.util.PropsValues;
044    import com.liferay.portal.util.SessionClicks;
045    import com.liferay.portlet.sites.util.SitesUtil;
046    
047    import java.util.List;
048    
049    import javax.servlet.http.HttpServletRequest;
050    import javax.servlet.http.HttpSession;
051    
052    /**
053     * @author Brian Wing Shun Chan
054     * @author Eduardo Lundgren
055     * @author Bruno Basto
056     */
057    public class LayoutsTreeUtil {
058    
059            public static String getLayoutsJSON(
060                            HttpServletRequest request, long groupId, boolean privateLayout,
061                            long parentLayoutId, boolean incomplete)
062                    throws Exception {
063    
064                    return getLayoutsJSON(
065                            request, groupId, privateLayout, parentLayoutId, null, incomplete);
066            }
067    
068            public static String getLayoutsJSON(
069                            HttpServletRequest request, long groupId, boolean privateLayout,
070                            long parentLayoutId, long[] expandedLayoutIds, boolean incomplete)
071                    throws Exception {
072    
073                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
074                            WebKeys.THEME_DISPLAY);
075    
076                    JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
077    
078                    List<Layout> layoutAncestors = null;
079    
080                    List<Layout> layouts = LayoutServiceUtil.getLayouts(
081                            groupId, privateLayout, parentLayoutId, incomplete,
082                            QueryUtil.ALL_POS, QueryUtil.ALL_POS);
083    
084                    long selPlid = ParamUtil.getLong(request, "selPlid");
085    
086                    if (selPlid != 0) {
087                            Layout selLayout = LayoutLocalServiceUtil.getLayout(selPlid);
088    
089                            layoutAncestors = LayoutServiceUtil.getAncestorLayouts(selPlid);
090    
091                            layoutAncestors.add(selLayout);
092                    }
093    
094                    int start = 0;
095                    int end = layouts.size();
096    
097                    if (PropsValues.LAYOUT_MANAGE_PAGES_INITIAL_CHILDREN > -1) {
098                            start = ParamUtil.getInteger(request, "start");
099                            start = Math.max(0, Math.min(start, layouts.size()));
100    
101                            end = ParamUtil.getInteger(
102                                    request, "end",
103                                    start + PropsValues.LAYOUT_MANAGE_PAGES_INITIAL_CHILDREN);
104    
105                            int loadedLayoutsCount = _getLoadedLayoutsCount(
106                                    request, parentLayoutId);
107    
108                            if (loadedLayoutsCount > end) {
109                                    end = loadedLayoutsCount;
110                            }
111    
112                            end = Math.max(start, Math.min(end, layouts.size()));
113                    }
114    
115                    boolean hasManageLayoutsPermission = GroupPermissionUtil.contains(
116                            themeDisplay.getPermissionChecker(), groupId,
117                            ActionKeys.MANAGE_LAYOUTS);
118    
119                    for (Layout layout : layouts.subList(start, end)) {
120                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
121    
122                            if ((layoutAncestors != null) && layoutAncestors.contains(layout) ||
123                                    ArrayUtil.contains(expandedLayoutIds, layout.getLayoutId())) {
124    
125                                    String childrenJSON = StringPool.BLANK;
126    
127                                    if (layout instanceof VirtualLayout) {
128                                            VirtualLayout virtualLayout = (VirtualLayout)layout;
129    
130                                            childrenJSON = getLayoutsJSON(
131                                                    request, virtualLayout.getSourceGroupId(),
132                                                    virtualLayout.getPrivateLayout(),
133                                                    virtualLayout.getLayoutId(), expandedLayoutIds,
134                                                    incomplete);
135    
136                                    }
137                                    else {
138                                            childrenJSON = getLayoutsJSON(
139                                                    request, groupId, layout.getPrivateLayout(),
140                                                    layout.getLayoutId(), expandedLayoutIds, incomplete);
141                                    }
142    
143                                    jsonObject.put(
144                                            "children", JSONFactoryUtil.createJSONObject(childrenJSON));
145                            }
146    
147                            jsonObject.put("contentDisplayPage", layout.isContentDisplayPage());
148                            jsonObject.put("friendlyURL", layout.getFriendlyURL());
149    
150                            if (layout instanceof VirtualLayout) {
151                                    VirtualLayout virtualLayout = (VirtualLayout)layout;
152    
153                                    jsonObject.put("groupId", virtualLayout.getSourceGroupId());
154                            }
155                            else {
156                                    jsonObject.put("groupId", layout.getGroupId());
157                            }
158    
159                            jsonObject.put("hasChildren", layout.hasChildren());
160                            jsonObject.put("layoutId", layout.getLayoutId());
161                            jsonObject.put("name", layout.getName(themeDisplay.getLocale()));
162                            jsonObject.put("parentable", PortalUtil.isLayoutParentable(layout));
163                            jsonObject.put("parentLayoutId", layout.getParentLayoutId());
164                            jsonObject.put("plid", layout.getPlid());
165                            jsonObject.put("priority", layout.getPriority());
166                            jsonObject.put("privateLayout", layout.isPrivateLayout());
167                            jsonObject.put(
168                                    "sortable",
169                                            hasManageLayoutsPermission &&
170                                            SitesUtil.isLayoutSortable(layout));
171                            jsonObject.put("type", layout.getType());
172                            jsonObject.put(
173                                    "updateable",
174                                            LayoutPermissionUtil.contains(
175                                                    themeDisplay.getPermissionChecker(), layout,
176                                                    ActionKeys.UPDATE));
177                            jsonObject.put("uuid", layout.getUuid());
178    
179                            LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
180                                    layout);
181    
182                            if (layoutRevision != null) {
183                                    User user = themeDisplay.getUser();
184    
185                                    long recentLayoutSetBranchId =
186                                            StagingUtil.getRecentLayoutSetBranchId(
187                                                    user, layout.getLayoutSet().getLayoutSetId());
188    
189                                    if (StagingUtil.isIncomplete(layout, recentLayoutSetBranchId)) {
190                                            jsonObject.put("incomplete", true);
191                                    }
192    
193                                    long layoutSetBranchId = layoutRevision.getLayoutSetBranchId();
194    
195                                    LayoutSetBranch layoutSetBranch =
196                                            LayoutSetBranchLocalServiceUtil.getLayoutSetBranch(
197                                                    layoutSetBranchId);
198    
199                                    LayoutBranch layoutBranch = layoutRevision.getLayoutBranch();
200    
201                                    if (!layoutBranch.isMaster()) {
202                                            jsonObject.put(
203                                                    "layoutBranchId", layoutBranch.getLayoutBranchId());
204                                            jsonObject.put("layoutBranchName", layoutBranch.getName());
205                                    }
206    
207                                    jsonObject.put(
208                                            "layoutRevisionId", layoutRevision.getLayoutRevisionId());
209                                    jsonObject.put("layoutSetBranchId", layoutSetBranchId);
210                                    jsonObject.put(
211                                            "layoutSetBranchName", layoutSetBranch.getName());
212                            }
213    
214                            jsonArray.put(jsonObject);
215                    }
216    
217                    JSONObject responseJSONObject = JSONFactoryUtil.createJSONObject();
218    
219                    responseJSONObject.put("layouts", jsonArray);
220                    responseJSONObject.put("total", layouts.size());
221    
222                    return responseJSONObject.toString();
223            }
224    
225            private static int _getLoadedLayoutsCount(
226                            HttpServletRequest request, long layoutId)
227                    throws Exception {
228    
229                    HttpSession session = request.getSession();
230    
231                    String treeId = ParamUtil.getString(request, "treeId");
232                    long groupId = ParamUtil.getLong(request, "groupId");
233                    boolean privateLayout = ParamUtil.getBoolean(request, "privateLayout");
234    
235                    StringBundler sb = new StringBundler(7);
236    
237                    sb.append(treeId);
238                    sb.append(StringPool.COLON);
239                    sb.append(groupId);
240                    sb.append(StringPool.COLON);
241                    sb.append(privateLayout);
242                    sb.append(StringPool.COLON);
243                    sb.append("Pagination");
244    
245                    String paginationJSON = SessionClicks.get(
246                            session, sb.toString(), JSONFactoryUtil.getNullJSON());
247    
248                    JSONObject paginationJSONObject = JSONFactoryUtil.createJSONObject(
249                            HtmlUtil.unescape(paginationJSON));
250    
251                    return paginationJSONObject.getInt(String.valueOf(layoutId));
252            }
253    
254    }