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