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