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