001    /**
002     * Copyright (c) 2000-present 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.portlet;
016    
017    import com.liferay.portal.kernel.exception.NoSuchLayoutException;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.model.Layout;
020    import com.liferay.portal.kernel.model.LayoutConstants;
021    import com.liferay.portal.kernel.model.LayoutTypePortlet;
022    import com.liferay.portal.kernel.model.PortletConstants;
023    import com.liferay.portal.kernel.security.permission.ActionKeys;
024    import com.liferay.portal.kernel.security.permission.PermissionChecker;
025    import com.liferay.portal.kernel.service.LayoutLocalServiceUtil;
026    import com.liferay.portal.kernel.service.permission.LayoutPermissionUtil;
027    import com.liferay.portal.kernel.theme.ThemeDisplay;
028    import com.liferay.portal.kernel.util.PortalUtil;
029    import com.liferay.portal.kernel.util.StringBundler;
030    import com.liferay.sites.kernel.util.SitesUtil;
031    
032    /**
033     * @author Adolfo Pérez
034     */
035    public abstract class BasePortletLayoutFinder implements PortletLayoutFinder {
036    
037            @Override
038            public Result find(ThemeDisplay themeDisplay, long groupId)
039                    throws PortalException {
040    
041                    String[] portletIds = getPortletIds();
042    
043                    if ((themeDisplay.getPlid() != LayoutConstants.DEFAULT_PLID) &&
044                            (groupId == themeDisplay.getScopeGroupId())) {
045    
046                            try {
047                                    Layout layout = LayoutLocalServiceUtil.getLayout(
048                                            themeDisplay.getPlid());
049    
050                                    LayoutTypePortlet layoutTypePortlet =
051                                            (LayoutTypePortlet)layout.getLayoutType();
052    
053                                    for (String portletId : portletIds) {
054                                            if (!layoutTypePortlet.hasPortletId(portletId, false) ||
055                                                    !LayoutPermissionUtil.contains(
056                                                            themeDisplay.getPermissionChecker(), layout,
057                                                            ActionKeys.VIEW)) {
058    
059                                                    continue;
060                                            }
061    
062                                            portletId = getPortletId(layoutTypePortlet, portletId);
063    
064                                            return new ResultImpl(themeDisplay.getPlid(), portletId);
065                                    }
066                            }
067                            catch (NoSuchLayoutException nsle) {
068                            }
069                    }
070    
071                    Object[] plidAndPortletId = fetchPlidAndPortletId(
072                            themeDisplay.getPermissionChecker(), groupId, portletIds);
073    
074                    if ((plidAndPortletId == null) &&
075                            SitesUtil.isUserGroupLayoutSetViewable(
076                                    themeDisplay.getPermissionChecker(),
077                                    themeDisplay.getScopeGroup())) {
078    
079                            plidAndPortletId = fetchPlidAndPortletId(
080                                    themeDisplay.getPermissionChecker(),
081                                    themeDisplay.getScopeGroupId(), portletIds);
082                    }
083    
084                    if (plidAndPortletId != null) {
085                            return new ResultImpl(
086                                    (long)plidAndPortletId[0], (String)plidAndPortletId[1]);
087                    }
088    
089                    StringBundler sb = new StringBundler(portletIds.length * 2 + 5);
090    
091                    sb.append("{groupId=");
092                    sb.append(groupId);
093                    sb.append(", plid=");
094                    sb.append(themeDisplay.getPlid());
095    
096                    for (String portletId : portletIds) {
097                            sb.append(", portletId=");
098                            sb.append(portletId);
099                    }
100    
101                    sb.append("}");
102    
103                    throw new NoSuchLayoutException(sb.toString());
104            }
105    
106            protected Object[] fetchPlidAndPortletId(
107                            PermissionChecker permissionChecker, long groupId,
108                            String[] portletIds)
109                    throws PortalException {
110    
111                    for (String portletId : portletIds) {
112                            long plid = PortalUtil.getPlidFromPortletId(groupId, portletId);
113    
114                            if (plid == LayoutConstants.DEFAULT_PLID) {
115                                    continue;
116                            }
117    
118                            Layout layout = LayoutLocalServiceUtil.getLayout(plid);
119    
120                            if (!LayoutPermissionUtil.contains(
121                                            permissionChecker, layout, ActionKeys.VIEW)) {
122    
123                                    continue;
124                            }
125    
126                            LayoutTypePortlet layoutTypePortlet =
127                                    (LayoutTypePortlet)layout.getLayoutType();
128    
129                            portletId = getPortletId(layoutTypePortlet, portletId);
130    
131                            return new Object[] {plid, portletId};
132                    }
133    
134                    return null;
135            }
136    
137            protected String getPortletId(
138                    LayoutTypePortlet layoutTypePortlet, String portletId) {
139    
140                    for (String curPortletId : layoutTypePortlet.getPortletIds()) {
141                            String curRootPortletId = PortletConstants.getRootPortletId(
142                                    curPortletId);
143    
144                            if (portletId.equals(curRootPortletId)) {
145                                    return curPortletId;
146                            }
147                    }
148    
149                    return portletId;
150            }
151    
152            protected abstract String[] getPortletIds();
153    
154            protected class ResultImpl implements PortletLayoutFinder.Result {
155    
156                    public ResultImpl(long plid, String portletId) {
157                            _plid = plid;
158                            _portletId = portletId;
159                    }
160    
161                    @Override
162                    public long getPlid() {
163                            return _plid;
164                    }
165    
166                    @Override
167                    public String getPortletId() {
168                            return _portletId;
169                    }
170    
171                    private final long _plid;
172                    private final String _portletId;
173    
174            }
175    
176    }