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.taglib.ui;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.servlet.taglib.ui.BreadcrumbEntry;
020    import com.liferay.portal.kernel.servlet.taglib.ui.BreadcrumbUtil;
021    import com.liferay.portal.kernel.util.ArrayUtil;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.HtmlUtil;
024    import com.liferay.portal.kernel.util.PropsKeys;
025    import com.liferay.portal.kernel.util.PropsUtil;
026    import com.liferay.portal.kernel.util.StringBundler;
027    import com.liferay.portal.kernel.util.StringPool;
028    import com.liferay.portal.kernel.util.StringUtil;
029    import com.liferay.portal.kernel.util.UnicodeProperties;
030    import com.liferay.portal.kernel.util.Validator;
031    import com.liferay.portal.kernel.util.WebKeys;
032    import com.liferay.portal.model.Group;
033    import com.liferay.portal.model.Layout;
034    import com.liferay.portal.theme.ThemeDisplay;
035    import com.liferay.portal.util.PortalUtil;
036    import com.liferay.taglib.aui.AUIUtil;
037    import com.liferay.taglib.util.IncludeTag;
038    
039    import java.util.List;
040    
041    import javax.servlet.http.HttpServletRequest;
042    
043    /**
044     * @author Brian Wing Shun Chan
045     */
046    public class BreadcrumbTag extends IncludeTag {
047    
048            public void setDisplayStyle(String displayStyle) {
049                    _displayStyle = displayStyle;
050            }
051    
052            public void setShowCurrentGroup(boolean showCurrentGroup) {
053                    _showCurrentGroup = showCurrentGroup;
054            }
055    
056            public void setShowGuestGroup(boolean showGuestGroup) {
057                    _showGuestGroup = showGuestGroup;
058            }
059    
060            public void setShowLayout(boolean showLayout) {
061                    _showLayout = showLayout;
062            }
063    
064            public void setShowParentGroups(boolean showParentGroups) {
065                    _showParentGroups = showParentGroups;
066            }
067    
068            public void setShowPortletBreadcrumb(boolean showPortletBreadcrumb) {
069                    _showPortletBreadcrumb = showPortletBreadcrumb;
070            }
071    
072            protected void buildGuestGroupBreadcrumb(
073                            ThemeDisplay themeDisplay, StringBundler sb)
074                    throws Exception {
075    
076                    BreadcrumbEntry breadcrumbEntry =
077                            BreadcrumbUtil.getGuestGroupBreadcrumbEntry(themeDisplay);
078    
079                    if (breadcrumbEntry == null) {
080                            return;
081                    }
082    
083                    sb.append("<li><a href=\"");
084                    sb.append(breadcrumbEntry.getURL());
085                    sb.append("\">");
086                    sb.append(HtmlUtil.escape(breadcrumbEntry.getTitle()));
087                    sb.append("</a></li>");
088            }
089    
090            protected void buildLayoutBreadcrumb(
091                            ThemeDisplay themeDisplay, StringBundler sb)
092                    throws Exception {
093    
094                    List<BreadcrumbEntry> breadcrumbEntries =
095                            BreadcrumbUtil.getLayoutBreadcrumbEntries(themeDisplay);
096    
097                    for (BreadcrumbEntry breadcrumbEntry : breadcrumbEntries) {
098                            sb.append("<li><a href=\"");
099                            sb.append(breadcrumbEntry.getURL());
100                            sb.append("\" ");
101    
102                            Layout layout = (Layout)breadcrumbEntry.getBaseModel();
103    
104                            if (layout.isTypeControlPanel()) {
105                                    sb.append("target=\"_top\"");
106                            }
107                            else {
108                                    sb.append(PortalUtil.getLayoutTarget(layout));
109                            }
110    
111                            sb.append(StringPool.GREATER_THAN);
112                            sb.append(HtmlUtil.escape(breadcrumbEntry.getTitle()));
113                            sb.append("</a></li>");
114                    }
115            }
116    
117            protected void buildParentGroupsBreadcrumb(
118                            ThemeDisplay themeDisplay, StringBundler sb)
119                    throws Exception {
120    
121                    List<BreadcrumbEntry> breadcrumbEntries =
122                            BreadcrumbUtil.getParentGroupBreadcrumbEntries(themeDisplay);
123    
124                    for (BreadcrumbEntry breadcrumbEntry : breadcrumbEntries) {
125                            sb.append("<li><a href=\"");
126                            sb.append(breadcrumbEntry.getURL());
127                            sb.append("\">");
128                            sb.append(HtmlUtil.escape(breadcrumbEntry.getTitle()));
129                            sb.append("</a></li>");
130                    }
131            }
132    
133            protected void buildPortletBreadcrumb(
134                            HttpServletRequest request, ThemeDisplay themeDisplay,
135                            StringBundler sb)
136                    throws Exception {
137    
138                    List<BreadcrumbEntry> breadcrumbEntries =
139                            BreadcrumbUtil.getPortletBreadcrumbEntries(request);
140    
141                    for (BreadcrumbEntry breadcrumbEntry : breadcrumbEntries) {
142                            if (!_showCurrentGroup) {
143                                    String siteGroupName = themeDisplay.getSiteGroupName();
144    
145                                    if (siteGroupName.equals(breadcrumbEntry.getTitle())) {
146                                            continue;
147                                    }
148                            }
149    
150                            sb.append("<li>");
151    
152                            if (Validator.isNotNull(breadcrumbEntry.getURL())) {
153                                    sb.append("<a href=\"");
154                                    sb.append(HtmlUtil.escape(breadcrumbEntry.getURL()));
155                                    sb.append("\"");
156                                    sb.append(AUIUtil.buildData(breadcrumbEntry.getData()));
157                                    sb.append(StringPool.GREATER_THAN);
158    
159                                    sb.append(HtmlUtil.escape(breadcrumbEntry.getTitle()));
160    
161                                    sb.append("</a>");
162                            }
163                            else {
164                                    sb.append(HtmlUtil.escape(breadcrumbEntry.getTitle()));
165                            }
166    
167                            sb.append("</li>");
168                    }
169            }
170    
171            protected void buildScopeGroupBreadcrumb(
172                            ThemeDisplay themeDisplay, StringBundler sb)
173                    throws Exception {
174    
175                    BreadcrumbEntry breadcrumbEntry =
176                            BreadcrumbUtil.getScopeGroupBreadcrumbEntry(themeDisplay);
177    
178                    if (breadcrumbEntry == null) {
179                            return;
180                    }
181    
182                    sb.append("<li><a href=\"");
183                    sb.append(breadcrumbEntry.getURL());
184                    sb.append("\">");
185                    sb.append(HtmlUtil.escape(breadcrumbEntry.getTitle()));
186                    sb.append("</a></li>");
187            }
188    
189            @Override
190            protected void cleanUp() {
191                    _displayStyle = _DISPLAY_STYLE;
192                    _showCurrentGroup = true;
193                    _showGuestGroup = _SHOW_GUEST_GROUP;
194                    _showLayout = true;
195                    _showParentGroups = null;
196                    _showPortletBreadcrumb = true;
197            }
198    
199            protected String getBreadcrumbString(HttpServletRequest request) {
200                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
201                            WebKeys.THEME_DISPLAY);
202    
203                    StringBundler sb = new StringBundler();
204    
205                    try {
206                            if (_showGuestGroup) {
207                                    buildGuestGroupBreadcrumb(themeDisplay, sb);
208                            }
209    
210                            if (_showParentGroups) {
211                                    buildParentGroupsBreadcrumb(themeDisplay, sb);
212                            }
213    
214                            if (_showCurrentGroup) {
215                                    buildScopeGroupBreadcrumb(themeDisplay, sb);
216                            }
217    
218                            if (_showLayout) {
219                                    buildLayoutBreadcrumb(themeDisplay, sb);
220                            }
221    
222                            if (_showPortletBreadcrumb) {
223                                    buildPortletBreadcrumb(request, themeDisplay, sb);
224                            }
225                    }
226                    catch (Exception e) {
227                            _log.error(e, e);
228                    }
229    
230                    String breadcrumbString = sb.toString();
231    
232                    if (Validator.isNull(breadcrumbString)) {
233                            return StringPool.BLANK;
234                    }
235    
236                    String breadcrumbTruncateClass = StringPool.BLANK;
237    
238                    String[] breadcrumbArray = breadcrumbString.split("<li", -1);
239    
240                    boolean breadcrumbTruncate = false;
241    
242                    if (breadcrumbArray.length > 3) {
243                            breadcrumbTruncate = true;
244                    }
245    
246                    if (breadcrumbTruncate) {
247                            breadcrumbTruncateClass = " breadcrumb-truncate";
248                    }
249    
250                    int x = breadcrumbString.indexOf("<li") + 3;
251                    int y = breadcrumbString.lastIndexOf("<li") + 3;
252    
253                    if (x == y) {
254                            breadcrumbString = StringUtil.insert(
255                                    breadcrumbString,
256                                    " class=\"active only" + breadcrumbTruncateClass + "\"", x);
257                    }
258                    else {
259                            breadcrumbString = StringUtil.insert(
260                                    breadcrumbString,
261                                    " class=\"active last" + breadcrumbTruncateClass + "\"", y);
262    
263                            breadcrumbString = StringUtil.insert(
264                                    breadcrumbString,
265                                    " class=\"first" + breadcrumbTruncateClass + "\"", x);
266                    }
267    
268                    if (breadcrumbTruncate) {
269                            y = breadcrumbString.lastIndexOf("<li");
270    
271                            int z = breadcrumbString.lastIndexOf("<li", y - 1) + 3;
272    
273                            breadcrumbString = StringUtil.insert(
274                                    breadcrumbString,
275                                    " class=\"current-parent" + breadcrumbTruncateClass + "\"", z);
276                    }
277    
278                    return breadcrumbString;
279            }
280    
281            @Override
282            protected String getPage() {
283                    return _PAGE;
284            }
285    
286            protected void initShowParentGroups(HttpServletRequest request) {
287                    if (_showParentGroups != null) {
288                            return;
289                    }
290    
291                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
292                            WebKeys.THEME_DISPLAY);
293    
294                    try {
295                            Layout layout = themeDisplay.getLayout();
296    
297                            Group group = layout.getGroup();
298    
299                            UnicodeProperties typeSettingsProperties =
300                                    group.getTypeSettingsProperties();
301    
302                            _showParentGroups = GetterUtil.getBoolean(
303                                    typeSettingsProperties.getProperty(
304                                            "breadcrumbShowParentGroups"),
305                                    _SHOW_PARENT_GROUPS);
306                    }
307                    catch (Exception e) {
308                            _log.error(e, e);
309                    }
310            }
311    
312            @Override
313            protected void setAttributes(HttpServletRequest request) {
314                    initShowParentGroups(request);
315    
316                    request.setAttribute(
317                            "liferay-ui:breadcrumb:breadcrumbString",
318                            getBreadcrumbString(request));
319    
320                    String displayStyle = _displayStyle;
321    
322                    if (!ArrayUtil.contains(_DISPLAY_STYLE_OPTIONS, displayStyle)) {
323                            displayStyle = _DISPLAY_STYLE_OPTIONS[0];
324                    }
325    
326                    request.setAttribute(
327                            "liferay-ui:breadcrumb:displayStyle", displayStyle);
328                    request.setAttribute(
329                            "liferay-ui:breadcrumb:showCurrentGroup",
330                            String.valueOf(_showCurrentGroup));
331                    request.setAttribute(
332                            "liferay-ui:breadcrumb:showGuestGroup",
333                            String.valueOf(_showGuestGroup));
334                    request.setAttribute(
335                            "liferay-ui:breadcrumb:showLayout", String.valueOf(_showLayout));
336                    request.setAttribute(
337                            "liferay-ui:breadcrumb:showParentGroups",
338                            String.valueOf(_showParentGroups));
339                    request.setAttribute(
340                            "liferay-ui:breadcrumb:showPortletBreadcrumb",
341                            String.valueOf(_showPortletBreadcrumb));
342            }
343    
344            private static final String _DISPLAY_STYLE = GetterUtil.getString(
345                    PropsUtil.get(PropsKeys.BREADCRUMB_DISPLAY_STYLE_DEFAULT));
346    
347            private static final String[] _DISPLAY_STYLE_OPTIONS = PropsUtil.getArray(
348                    PropsKeys.BREADCRUMB_DISPLAY_STYLE_OPTIONS);
349    
350            private static final String _PAGE = "/html/taglib/ui/breadcrumb/page.jsp";
351    
352            private static final boolean _SHOW_GUEST_GROUP = GetterUtil.getBoolean(
353                    PropsUtil.get(PropsKeys.BREADCRUMB_SHOW_GUEST_GROUP));
354    
355            private static final boolean _SHOW_PARENT_GROUPS = GetterUtil.getBoolean(
356                    PropsUtil.get(PropsKeys.BREADCRUMB_SHOW_PARENT_GROUPS));
357    
358            private static final Log _log = LogFactoryUtil.getLog(BreadcrumbTag.class);
359    
360            private String _displayStyle = _DISPLAY_STYLE;
361            private boolean _showCurrentGroup = true;
362            private boolean _showGuestGroup = _SHOW_GUEST_GROUP;
363            private boolean _showLayout = true;
364            private Boolean _showParentGroups = null;
365            private boolean _showPortletBreadcrumb = true;
366    
367    }