001
014
015 package com.liferay.taglib.ui;
016
017 import com.liferay.portal.kernel.language.LanguageUtil;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.servlet.taglib.ui.BreadcrumbEntry;
021 import com.liferay.portal.kernel.util.ArrayUtil;
022 import com.liferay.portal.kernel.util.CookieKeys;
023 import com.liferay.portal.kernel.util.GetterUtil;
024 import com.liferay.portal.kernel.util.HtmlUtil;
025 import com.liferay.portal.kernel.util.HttpUtil;
026 import com.liferay.portal.kernel.util.PropsKeys;
027 import com.liferay.portal.kernel.util.PropsUtil;
028 import com.liferay.portal.kernel.util.StringBundler;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.kernel.util.StringUtil;
031 import com.liferay.portal.kernel.util.UnicodeProperties;
032 import com.liferay.portal.kernel.util.Validator;
033 import com.liferay.portal.kernel.util.WebKeys;
034 import com.liferay.portal.model.Account;
035 import com.liferay.portal.model.Group;
036 import com.liferay.portal.model.GroupConstants;
037 import com.liferay.portal.model.Layout;
038 import com.liferay.portal.model.LayoutConstants;
039 import com.liferay.portal.model.LayoutSet;
040 import com.liferay.portal.model.Organization;
041 import com.liferay.portal.model.User;
042 import com.liferay.portal.service.GroupLocalServiceUtil;
043 import com.liferay.portal.service.LayoutLocalServiceUtil;
044 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
045 import com.liferay.portal.service.OrganizationLocalServiceUtil;
046 import com.liferay.portal.service.UserLocalServiceUtil;
047 import com.liferay.portal.theme.PortletDisplay;
048 import com.liferay.portal.theme.ThemeDisplay;
049 import com.liferay.portal.util.PortalUtil;
050 import com.liferay.taglib.aui.AUIUtil;
051 import com.liferay.taglib.util.IncludeTag;
052
053 import java.util.List;
054 import java.util.Map;
055
056 import javax.portlet.PortletURL;
057
058 import javax.servlet.http.HttpServletRequest;
059 import javax.servlet.http.HttpSession;
060
061
064 public class BreadcrumbTag extends IncludeTag {
065
066 public void setDisplayStyle(String displayStyle) {
067 _displayStyle = displayStyle;
068 }
069
070 public void setPortletURL(PortletURL portletURL) {
071 _portletURL = portletURL;
072 }
073
074 public void setSelLayout(Layout selLayout) {
075 _selLayout = selLayout;
076 }
077
078 public void setSelLayoutParam(String selLayoutParam) {
079 _selLayoutParam = selLayoutParam;
080 }
081
082 public void setShowCurrentGroup(boolean showCurrentGroup) {
083 _showCurrentGroup = showCurrentGroup;
084 }
085
086 public void setShowCurrentPortlet(boolean showCurrentPortlet) {
087 _showCurrentPortlet = showCurrentPortlet;
088 }
089
090 public void setShowGuestGroup(boolean showGuestGroup) {
091 _showGuestGroup = showGuestGroup;
092 }
093
094 public void setShowLayout(boolean showLayout) {
095 _showLayout = showLayout;
096 }
097
098 public void setShowParentGroups(boolean showParentGroups) {
099 _showParentGroups = showParentGroups;
100 }
101
102 public void setShowPortletBreadcrumb(boolean showPortletBreadcrumb) {
103 _showPortletBreadcrumb = showPortletBreadcrumb;
104 }
105
106 protected void buildGroupsBreadcrumb(
107 LayoutSet layoutSet, PortletURL portletURL,
108 ThemeDisplay themeDisplay, boolean includeParentGroups,
109 StringBundler sb)
110 throws Exception {
111
112 Group group = layoutSet.getGroup();
113
114 if (group.isControlPanel()) {
115 return;
116 }
117
118 if (includeParentGroups) {
119 LayoutSet parentLayoutSet = getParentLayoutSet(layoutSet);
120
121 if (parentLayoutSet != null) {
122 buildGroupsBreadcrumb(
123 parentLayoutSet, portletURL, themeDisplay, true, sb);
124 }
125 }
126
127 int layoutsPageCount = 0;
128
129 if (layoutSet.isPrivateLayout()) {
130 layoutsPageCount = group.getPrivateLayoutsPageCount();
131 }
132 else {
133 layoutsPageCount = group.getPublicLayoutsPageCount();
134 }
135
136 if ((layoutsPageCount > 0) && !group.isGuest()) {
137 String layoutSetFriendlyURL = PortalUtil.getLayoutSetFriendlyURL(
138 layoutSet, themeDisplay);
139
140 if (themeDisplay.isAddSessionIdToURL()) {
141 layoutSetFriendlyURL = PortalUtil.getURLWithSessionId(
142 layoutSetFriendlyURL, themeDisplay.getSessionId());
143 }
144
145 sb.append("<li><a href=\"");
146 sb.append(layoutSetFriendlyURL);
147 sb.append("\">");
148 sb.append(HtmlUtil.escape(group.getDescriptiveName()));
149 sb.append("</a><span class=\"divider\">/</span></li>");
150 }
151 }
152
153 protected void buildGuestGroupBreadcrumb(
154 ThemeDisplay themeDisplay, StringBundler sb)
155 throws Exception {
156
157 Group group = GroupLocalServiceUtil.getGroup(
158 themeDisplay.getCompanyId(), GroupConstants.GUEST);
159
160 if (group.getPublicLayoutsPageCount() == 0) {
161 return;
162 }
163
164 sb.append("<li><a href=\"");
165
166 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
167 group.getGroupId(), false);
168
169 String layoutSetFriendlyURL = PortalUtil.getLayoutSetFriendlyURL(
170 layoutSet, themeDisplay);
171
172 if (themeDisplay.isAddSessionIdToURL()) {
173 layoutSetFriendlyURL = PortalUtil.getURLWithSessionId(
174 layoutSetFriendlyURL, themeDisplay.getSessionId());
175 }
176
177 sb.append(layoutSetFriendlyURL);
178
179 sb.append("\">");
180
181 Account account = themeDisplay.getAccount();
182
183 sb.append(HtmlUtil.escape(account.getName()));
184
185 sb.append("</a><span class=\"divider\">/</span></li>");
186 }
187
188 protected void buildLayoutBreadcrumb(
189 Layout selLayout, String selLayoutParam, boolean selectedLayout,
190 PortletURL portletURL, ThemeDisplay themeDisplay, StringBundler sb)
191 throws Exception {
192
193 if (selLayout.getParentLayoutId() !=
194 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
195
196 Layout parentLayout = LayoutLocalServiceUtil.getParentLayout(
197 selLayout);
198
199 buildLayoutBreadcrumb(
200 parentLayout, selLayoutParam, false, portletURL, themeDisplay,
201 sb);
202 }
203
204 sb.append("<li><a href=\"");
205
206 String layoutURL = getBreadcrumbLayoutURL(
207 selLayout, selLayoutParam, portletURL, themeDisplay);
208
209 if (themeDisplay.isAddSessionIdToURL()) {
210 layoutURL = PortalUtil.getURLWithSessionId(
211 layoutURL, themeDisplay.getSessionId());
212 }
213
214 if (selLayout.isTypeControlPanel()) {
215 layoutURL = HttpUtil.removeParameter(
216 layoutURL, "controlPanelCategory");
217 }
218
219 sb.append(layoutURL);
220
221 sb.append("\" ");
222
223 String layoutName = selLayout.getName(themeDisplay.getLocale());
224
225 if (selLayout.isTypeControlPanel()) {
226 sb.append("target=\"_top\"");
227
228 if (layoutName.equals(LayoutConstants.NAME_CONTROL_PANEL_DEFAULT)) {
229 layoutName = LanguageUtil.get(
230 themeDisplay.getLocale(), "control-panel");
231 }
232 }
233 else {
234 String target = PortalUtil.getLayoutTarget(selLayout);
235
236 sb.append(target);
237 }
238
239 sb.append(StringPool.GREATER_THAN);
240 sb.append(HtmlUtil.escape(layoutName));
241 sb.append("</a><span class=\"divider\">/</span></li>");
242 }
243
244 protected void buildPortletBreadcrumb(
245 HttpServletRequest request, boolean showCurrentGroup,
246 boolean showCurrentPortlet, ThemeDisplay themeDisplay,
247 StringBundler sb)
248 throws Exception {
249
250 List<BreadcrumbEntry> breadcrumbEntries =
251 PortalUtil.getPortletBreadcrumbs(request);
252
253 if (breadcrumbEntries == null) {
254 return;
255 }
256
257 for (int i = 0; i < breadcrumbEntries.size(); i++) {
258 BreadcrumbEntry breadcrumbEntry = breadcrumbEntries.get(i);
259
260 Map<String, Object> data = breadcrumbEntry.getData();
261
262 String breadcrumbTitle = breadcrumbEntry.getTitle();
263 String breadcrumbURL = breadcrumbEntry.getURL();
264
265 if (!showCurrentGroup) {
266 String siteGroupName = themeDisplay.getSiteGroupName();
267
268 if (siteGroupName.equals(breadcrumbTitle)) {
269 continue;
270 }
271 }
272
273 if (!showCurrentPortlet) {
274 PortletDisplay portletDisplay =
275 themeDisplay.getPortletDisplay();
276
277 String portletTitle = PortalUtil.getPortletTitle(
278 portletDisplay.getId(), themeDisplay.getUser());
279
280 if (portletTitle.equals(breadcrumbTitle)) {
281 continue;
282 }
283 }
284
285 if (!CookieKeys.hasSessionId(request) &&
286 Validator.isNotNull(breadcrumbURL)) {
287
288 HttpSession session = request.getSession();
289
290 breadcrumbURL = PortalUtil.getURLWithSessionId(
291 breadcrumbURL, session.getId());
292 }
293
294 sb.append("<li>");
295
296 if (i < (breadcrumbEntries.size() - 1)) {
297 if (Validator.isNotNull(breadcrumbURL)) {
298 sb.append("<a href=\"");
299 sb.append(HtmlUtil.escape(breadcrumbURL));
300 sb.append("\"");
301 sb.append(AUIUtil.buildData(data));
302 sb.append(">");
303 }
304
305 sb.append(HtmlUtil.escape(breadcrumbTitle));
306
307 if (Validator.isNotNull(breadcrumbURL)) {
308 sb.append("</a>");
309 }
310
311 sb.append("<span class=\"divider\">/</span>");
312 }
313 else {
314 sb.append(HtmlUtil.escape(breadcrumbTitle));
315 }
316
317 sb.append("</li>");
318 }
319 }
320
321 @Override
322 protected void cleanUp() {
323 _displayStyle = _DISPLAY_STYLE;
324 _portletURL = null;
325 _selLayout = null;
326 _selLayoutParam = null;
327 _showCurrentGroup = true;
328 _showCurrentPortlet = true;
329 _showGuestGroup = _SHOW_GUEST_GROUP;
330 _showLayout = true;
331 _showParentGroups = null;
332 _showPortletBreadcrumb = true;
333 }
334
335 protected String getBreadcrumbLayoutURL(
336 Layout selLayout, String selLayoutParam, PortletURL portletURL,
337 ThemeDisplay themeDisplay)
338 throws Exception {
339
340 if (portletURL == null) {
341 return PortalUtil.getLayoutFullURL(selLayout, themeDisplay);
342 }
343
344 portletURL.setParameter(
345 selLayoutParam, String.valueOf(selLayout.getPlid()));
346
347 if (selLayout.isTypeControlPanel()) {
348 if (themeDisplay.getDoAsGroupId() > 0) {
349 portletURL.setParameter(
350 "doAsGroupId",
351 String.valueOf(themeDisplay.getDoAsGroupId()));
352 }
353
354 if (themeDisplay.getRefererPlid() != LayoutConstants.DEFAULT_PLID) {
355 portletURL.setParameter(
356 "refererPlid",
357 String.valueOf(themeDisplay.getRefererPlid()));
358 }
359 }
360
361 return portletURL.toString();
362 }
363
364 protected String getBreadcrumbString(HttpServletRequest request) {
365 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
366 WebKeys.THEME_DISPLAY);
367
368 StringBundler sb = new StringBundler();
369
370 try {
371 if (Validator.isNull(_selLayout)) {
372 setSelLayout(themeDisplay.getLayout());
373 }
374
375 Group group = _selLayout.getGroup();
376
377 if (_showGuestGroup) {
378 buildGuestGroupBreadcrumb(themeDisplay, sb);
379 }
380
381 if (_showParentGroups) {
382 LayoutSet parentLayoutSet = getParentLayoutSet(
383 _selLayout.getLayoutSet());
384
385 if (parentLayoutSet != null) {
386 buildGroupsBreadcrumb(
387 parentLayoutSet, _portletURL, themeDisplay, true, sb);
388 }
389 }
390
391 if (_showCurrentGroup) {
392 buildGroupsBreadcrumb(
393 _selLayout.getLayoutSet(), _portletURL, themeDisplay, false,
394 sb);
395 }
396
397 if (_showLayout && !group.isLayoutPrototype()) {
398 buildLayoutBreadcrumb(
399 _selLayout, _selLayoutParam, true, _portletURL,
400 themeDisplay, sb);
401 }
402
403 if (_showPortletBreadcrumb) {
404 buildPortletBreadcrumb(
405 request, _showCurrentGroup, _showCurrentPortlet,
406 themeDisplay, sb);
407 }
408 }
409 catch (Exception e) {
410 _log.error(e, e);
411 }
412
413 String breadcrumbString = sb.toString();
414
415 if (Validator.isNull(breadcrumbString)) {
416 return StringPool.BLANK;
417 }
418
419 String breadcrumbTruncateClass = StringPool.BLANK;
420
421 String[] breadcrumbArray = breadcrumbString.split("<li", -1);
422
423 boolean breadcrumbTruncate = false;
424
425 if (breadcrumbArray.length > 3) {
426 breadcrumbTruncate = true;
427 }
428
429 if (breadcrumbTruncate) {
430 breadcrumbTruncateClass = " breadcrumb-truncate";
431 }
432
433 int x = breadcrumbString.indexOf("<li") + 3;
434 int y = breadcrumbString.lastIndexOf("<li") + 3;
435
436 if (x == y) {
437 breadcrumbString = StringUtil.insert(
438 breadcrumbString,
439 " class=\"active only" + breadcrumbTruncateClass + "\"", x);
440 }
441 else {
442 breadcrumbString = StringUtil.insert(
443 breadcrumbString,
444 " class=\"active last" + breadcrumbTruncateClass + "\"", y);
445
446 breadcrumbString = StringUtil.insert(
447 breadcrumbString,
448 " class=\"first" + breadcrumbTruncateClass + "\"", x);
449 }
450
451 if (breadcrumbTruncate) {
452 y = breadcrumbString.lastIndexOf("<li");
453
454 int z = breadcrumbString.lastIndexOf("<li", y - 1) + 3;
455
456 breadcrumbString = StringUtil.insert(
457 breadcrumbString,
458 " class=\"current-parent" + breadcrumbTruncateClass + "\"", z);
459 }
460
461 return breadcrumbString;
462 }
463
464 @Override
465 protected String getPage() {
466 return _PAGE;
467 }
468
469 protected LayoutSet getParentLayoutSet(LayoutSet layoutSet)
470 throws Exception {
471
472 Group group = layoutSet.getGroup();
473
474 if (group.isSite()) {
475 Group parentGroup = group.getParentGroup();
476
477 if (parentGroup != null) {
478 return LayoutSetLocalServiceUtil.getLayoutSet(
479 parentGroup.getGroupId(), layoutSet.isPrivateLayout());
480 }
481 }
482 else if (group.isUser()) {
483 User user = UserLocalServiceUtil.getUser(group.getClassPK());
484
485 List<Organization> organizations =
486 OrganizationLocalServiceUtil.getUserOrganizations(
487 user.getUserId());
488
489 if (!organizations.isEmpty()) {
490 Organization organization = organizations.get(0);
491
492 Group parentGroup = organization.getGroup();
493
494 return LayoutSetLocalServiceUtil.getLayoutSet(
495 parentGroup.getGroupId(), layoutSet.isPrivateLayout());
496 }
497 }
498
499 return null;
500 }
501
502 protected void initShowParentGroups(HttpServletRequest request) {
503 if (_showParentGroups != null) {
504 return;
505 }
506
507 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
508 WebKeys.THEME_DISPLAY);
509
510 try {
511 if (Validator.isNull(_selLayout)) {
512 setSelLayout(themeDisplay.getLayout());
513 }
514
515 Group group = _selLayout.getGroup();
516
517 UnicodeProperties typeSettingsProperties =
518 group.getTypeSettingsProperties();
519
520 _showParentGroups = GetterUtil.getBoolean(
521 typeSettingsProperties.getProperty(
522 "breadcrumbShowParentGroups"),
523 _SHOW_PARENT_GROUPS);
524 }
525 catch (Exception e) {
526 _log.error(e, e);
527 }
528 }
529
530 @Override
531 protected void setAttributes(HttpServletRequest request) {
532 initShowParentGroups(request);
533
534 request.setAttribute(
535 "liferay-ui:breadcrumb:breadcrumbString",
536 getBreadcrumbString(request));
537
538 String displayStyle = _displayStyle;
539
540 if (!ArrayUtil.contains(_DISPLAY_STYLE_OPTIONS, displayStyle)) {
541 displayStyle = _DISPLAY_STYLE_OPTIONS[0];
542 }
543
544 request.setAttribute(
545 "liferay-ui:breadcrumb:displayStyle", displayStyle);
546 request.setAttribute("liferay-ui:breadcrumb:portletURL", _portletURL);
547 request.setAttribute("liferay-ui:breadcrumb:selLayout", _selLayout);
548 request.setAttribute(
549 "liferay-ui:breadcrumb:selLayoutParam", _selLayoutParam);
550 request.setAttribute(
551 "liferay-ui:breadcrumb:showCurrentGroup",
552 String.valueOf(_showCurrentGroup));
553 request.setAttribute(
554 "liferay-ui:breadcrumb:showCurrentPortlet",
555 String.valueOf(_showCurrentPortlet));
556 request.setAttribute(
557 "liferay-ui:breadcrumb:showGuestGroup",
558 String.valueOf(_showGuestGroup));
559 request.setAttribute(
560 "liferay-ui:breadcrumb:showLayout", String.valueOf(_showLayout));
561 request.setAttribute(
562 "liferay-ui:breadcrumb:showParentGroups",
563 String.valueOf(_showParentGroups));
564 request.setAttribute(
565 "liferay-ui:breadcrumb:showPortletBreadcrumb",
566 String.valueOf(_showPortletBreadcrumb));
567 }
568
569 private static final String _DISPLAY_STYLE = GetterUtil.getString(
570 PropsUtil.get(PropsKeys.BREADCRUMB_DISPLAY_STYLE_DEFAULT));
571
572 private static final String[] _DISPLAY_STYLE_OPTIONS = PropsUtil.getArray(
573 PropsKeys.BREADCRUMB_DISPLAY_STYLE_OPTIONS);
574
575 private static final String _PAGE = "/html/taglib/ui/breadcrumb/page.jsp";
576
577 private static final boolean _SHOW_GUEST_GROUP = GetterUtil.getBoolean(
578 PropsUtil.get(PropsKeys.BREADCRUMB_SHOW_GUEST_GROUP));
579
580 private static final boolean _SHOW_PARENT_GROUPS = GetterUtil.getBoolean(
581 PropsUtil.get(PropsKeys.BREADCRUMB_SHOW_PARENT_GROUPS));
582
583 private static Log _log = LogFactoryUtil.getLog(BreadcrumbTag.class);
584
585 private String _displayStyle = _DISPLAY_STYLE;
586 private PortletURL _portletURL;
587 private Layout _selLayout;
588 private String _selLayoutParam;
589 private boolean _showCurrentGroup = true;
590 private boolean _showCurrentPortlet = true;
591 private boolean _showGuestGroup = _SHOW_GUEST_GROUP;
592 private boolean _showLayout = true;
593 private Boolean _showParentGroups = null;
594 private boolean _showPortletBreadcrumb = true;
595
596 }