1 16 package com.blandware.atleap.webapp.util.core; 17 18 import com.blandware.atleap.common.Constants; 19 import com.blandware.atleap.common.util.QueryInfo; 20 import com.blandware.atleap.common.util.ConvertUtil; 21 import com.blandware.atleap.model.core.*; 22 import com.blandware.atleap.service.core.LayoutManager; 23 import com.blandware.atleap.service.core.MenuManager; 24 import com.blandware.atleap.service.core.PageManager; 25 import com.blandware.atleap.service.core.RoleManager; 26 import com.blandware.atleap.service.exception.BeanNotFoundException; 27 import com.blandware.atleap.webapp.exception.MenuUtilException; 28 import com.blandware.atleap.webapp.menu.MenuComponent; 29 import com.blandware.atleap.webapp.menu.MenuRepository; 30 import com.blandware.atleap.webapp.menu.LoadableResourceException; 31 import com.blandware.atleap.webapp.struts.HeritableComponentDefinition; 32 import org.apache.commons.logging.Log; 33 import org.apache.commons.logging.LogFactory; 34 import org.apache.commons.beanutils.Converter; 35 import org.apache.commons.beanutils.ConvertUtils; 36 import org.apache.commons.validator.GenericValidator; 37 import org.apache.struts.tiles.TilesUtil; 38 import org.springframework.context.ApplicationContext; 39 import org.springframework.web.context.support.WebApplicationContextUtils; 40 41 import javax.servlet.ServletContext ; 42 import javax.servlet.http.HttpServletRequest ; 43 import java.io.PrintWriter ; 44 import java.io.StringWriter ; 45 import java.net.MalformedURLException ; 46 import java.util.ArrayList ; 47 import java.util.HashMap ; 48 import java.util.Iterator ; 49 import java.util.LinkedList ; 50 import java.util.List ; 51 import java.util.ListIterator ; 52 import java.util.Map ; 53 54 61 public final class MenuUtil { 62 63 protected transient final Log log = LogFactory.getLog(MenuUtil.class); 64 65 protected transient HttpServletRequest request; 66 67 protected transient ServletContext servletContext; 68 69 protected transient ApplicationContext applicationContext; 70 71 protected transient String contextPath; 72 73 76 protected transient MenuManager menuManager; 77 78 83 public MenuUtil(HttpServletRequest request) { 84 this.request = request; 85 this.servletContext = request.getSession().getServletContext(); 86 this.contextPath = request.getContextPath(); 87 this.applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); 88 this.menuManager = (MenuManager) applicationContext.getBean(Constants.MENU_MANAGER_BEAN); 89 } 90 91 97 public MenuUtil(ServletContext servletContext, String contextPath) { 98 this.request = null; 99 this.servletContext = servletContext; 100 this.contextPath = contextPath; 101 this.applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); 102 this.menuManager = (MenuManager) applicationContext.getBean(Constants.MENU_MANAGER_BEAN); 103 } 104 105 106 public List getMenuItems(Long parentItemId, String layoutDefinition, String pageUri, boolean deleteInvisible) throws MenuUtilException { 107 108 List owners = lookupOwners(layoutDefinition, pageUri); 109 List menuItems = lookupItems(owners, parentItemId, deleteInvisible); 110 111 try { 113 for ( ListIterator iterator = menuItems.listIterator(); iterator.hasNext(); ) { 114 MenuItem menuItem = (MenuItem) iterator.next(); 115 menuItem.setLocation(getLocation(menuItem, WebappConstants.URL_TYPE_CONTEXT_RELATIVE)); 116 } 117 } catch ( MalformedURLException e ) { 118 if ( log.isFatalEnabled() ) { 119 StringWriter sw = new StringWriter (); 120 e.printStackTrace(new PrintWriter (sw)); 121 log.fatal("Setting location failed. See the stack trace for details."); 122 log.fatal(sw.toString()); 123 } 124 } 125 return menuItems; 126 } 127 128 public MenuComponent getMenuComponent(String itemIdentifier, String localeIdentifier, String layoutDefinition, String pageUri, boolean deleteInvisible) throws MenuUtilException { 129 130 LinkedList owners = lookupOwners(layoutDefinition, pageUri); 131 132 int i = 0; 133 MenuItem menuItem = null; 134 for ( i = 0; i < owners.size(); i++ ) { 135 Localizable owner = (Localizable) owners.get(i); 136 Long ownerId = null; 137 if ( owner != null ) { 138 ownerId = owner.getId(); 139 } 140 menuItem = menuManager.findMenuItemByIdentifierAndParentAndOwner(itemIdentifier, null, ownerId); 141 if ( menuItem != null ) { 142 break; 143 } 144 } 145 146 if ( menuItem == null ) { 147 return null; 149 } 150 151 Byte visibility = menuItem.getVisibility(); 152 153 if ( menuItem.isVisibilityHeritable() ) { 154 visibility = new Byte (MenuItem.VISIBILITY_VISIBLE); 155 } 156 157 160 int j; 161 MenuItem redefinitionItem = null; 162 for ( j = owners.size() - 1; j > i; j-- ) { 163 Localizable owner = (Localizable) owners.get(j); 164 Long ownerId = null; 165 if ( owner != null ) { 166 ownerId = owner.getId(); 167 } 168 redefinitionItem = menuManager.findRedefinitionItem(menuItem.getId(), ownerId); 169 if ( redefinitionItem != null ) { 170 menuItem.setVisibility(redefinitionItem.getVisibility()); 171 } 172 } 173 174 if ( redefinitionItem == null && menuItem.isVisibilityHeritable() ) { 175 menuItem.setVisibility(visibility); 176 } else if ( redefinitionItem != null && menuItem.isVisibilityHeritable() ) { 177 if ( j > i + 1 ) { 178 for ( int k = j - 1; k > i; k-- ) { 179 Localizable owner = (Localizable) owners.get(j); 180 Long ownerId = null; 181 if ( owner != null ) { 182 ownerId = owner.getId(); 183 } 184 redefinitionItem = menuManager.findRedefinitionItem(menuItem.getId(), ownerId); 185 if ( redefinitionItem != null && !redefinitionItem.isVisibilityHeritable() ) { 186 menuItem.setVisibility(redefinitionItem.getVisibility()); 187 break; 188 } 189 190 } 191 } 192 if ( menuItem.isVisibilityHeritable() ) { 193 menuItem.setVisibility(visibility); 194 } 195 } 196 197 if ( menuItem.isInvisible() && deleteInvisible ) { 199 return null; 200 } 201 202 return convertToMenuComponent(owners, menuItem, localeIdentifier, deleteInvisible); 203 } 204 205 213 protected List lookupItems(List owners, Long parentItemId, boolean deleteInvisible) throws MenuUtilException { 214 215 List items = new ArrayList (); 216 try { 217 218 for ( Iterator i = owners.iterator(); i.hasNext(); ) { 220 Localizable owner = (Localizable) i.next(); 221 QueryInfo queryInfo = new QueryInfo(); 222 Map queryParameters = new HashMap (); 223 224 if ( owner != null ) { 225 queryParameters.put("ownerId", owner.getId()); 226 } 227 queryParameters.put("parentItemId", parentItemId); 228 229 queryInfo.setQueryParameters(queryParameters); 230 231 List menuItems = menuManager.listMenuItems(queryInfo).asList(); 232 233 for ( Iterator j = menuItems.iterator(); j.hasNext(); ) { 234 235 MenuItem menuItem = (MenuItem) j.next(); 236 237 MenuItem oldItem = null; 239 if ( menuItem.isRedefinition() ) { 240 oldItem = findMenuItem(items, menuItem.getOrigItem().getId()); 241 } 242 243 MenuItem modifiedOldItem = null; 246 if ( oldItem != null ) { 247 modifiedOldItem = new MenuItem(); 248 WebappUtil.copyProperties(modifiedOldItem, oldItem, request); 250 } 251 252 if ( menuItem.getPosition() != null && modifiedOldItem != null ) { 253 int pos = menuItem.getPosition().intValue(); 257 if ( pos >= items.size() ) { 258 pos = items.size() - 1; 259 } 260 int oldPos = items.indexOf(oldItem); 261 262 modifiedOldItem.setVisibility(menuItem.getVisibility()); 263 264 MenuItem tmp = (MenuItem) items.get(pos); 265 items.set(oldPos, tmp); 266 items.set(pos, modifiedOldItem); 267 } else if ( menuItem.getPosition() != null && modifiedOldItem == null ) { 268 int pos = menuItem.getPosition().intValue(); 271 if ( pos < items.size() ) { 272 items.add(pos, menuItem); 273 } else { 274 items.add(menuItem); 275 } 276 } else if ( menuItem.getPosition() == null && modifiedOldItem == null ) { 277 items.add(menuItem); 280 } else if ( menuItem.getPosition() == null && modifiedOldItem != null ) { 281 int tmpPos = items.indexOf(oldItem); 284 modifiedOldItem.setVisibility(menuItem.getVisibility()); 285 items.set(tmpPos, modifiedOldItem); 286 } 287 } 288 } 289 290 for ( Iterator i = items.iterator(); i.hasNext(); ) { 292 MenuItem menuItem = (MenuItem) i.next(); 293 if ( menuItem.isInvisible() && deleteInvisible ) { 294 i.remove(); 295 } 296 } 297 298 } catch ( Exception e ) { 299 throw new MenuUtilException(e); 300 } 301 return items; 302 } 303 304 305 314 protected MenuComponent convertToMenuComponent(List owners, MenuItem menuItem, String localeIdentifier, boolean deleteInvisible) throws MenuUtilException { 315 MenuComponent menuComponent = new MenuComponent(); 316 317 try { 319 WebappUtil.copyProperties(menuComponent, menuItem, request); 320 menuComponent.setName(menuItem.getIdentifier()); 321 322 StringBuffer roles = null; 324 if ( menuItem.getRoles() != null && !menuItem.getRoles().isEmpty() ) { 325 roles = new StringBuffer (); 326 for ( Iterator i = menuItem.getRoles().iterator(); i.hasNext(); ) { 327 Role role = (Role) i.next(); 328 roles.append(role.getName()); 329 if ( i.hasNext() ) { 330 roles.append(","); 331 } 332 } 333 } 334 if ( roles != null ) { 335 menuComponent.setRoles(roles.toString()); 336 } else { 337 menuComponent.setRoles(null); 338 } 339 menuComponent.setTitle(WebappUtil.getFieldValue(menuItem.getTitle(), localeIdentifier, request, true)); 340 menuComponent.setToolTip(WebappUtil.getFieldValue(menuItem.getToolTip(), localeIdentifier, request, true)); 341 342 344 List childItems = lookupItems(owners, menuItem.getId(), deleteInvisible); 345 346 for ( Iterator i = childItems.iterator(); i.hasNext(); ) { 347 MenuItem childItem = (MenuItem) i.next(); 348 menuComponent.addMenuComponent(convertToMenuComponent(owners, childItem, localeIdentifier, deleteInvisible)); 349 } 350 351 } catch ( Exception e ) { 352 if ( !(e instanceof MenuUtilException) ) { 353 throw new MenuUtilException(e); 354 } else { 355 throw (MenuUtilException) e; 356 } 357 } 358 359 return menuComponent; 360 } 361 362 374 protected LinkedList lookupOwners(String layoutDefinition, String pageUri) throws MenuUtilException { 375 LinkedList owners = new LinkedList (); 376 try { 377 if ( pageUri != null ) { 378 PageManager pageManager = (PageManager) applicationContext.getBean(Constants.PAGE_MANAGER_BEAN); 380 Page page = pageManager.findPageByUri(pageUri); 381 if ( page != null ) { 382 owners.add(page); 383 } 384 } 385 386 LayoutManager layoutManager = (LayoutManager) applicationContext.getBean(Constants.LAYOUT_MANAGER_BEAN); 388 do { 389 Layout layout = layoutManager.findLayoutByDefinition(layoutDefinition); 390 if ( layout != null ) { 391 owners.addFirst(layout); 392 } 393 layoutDefinition = ((HeritableComponentDefinition) TilesUtil.getDefinition(layoutDefinition, request, servletContext)).getExtends(); 394 } while ( layoutDefinition != null ); 395 } catch ( Exception e ) { 396 throw new MenuUtilException(e); 397 } 398 399 owners.addFirst(null); 402 403 return owners; 404 } 405 406 412 public MenuComponent recursiveCopy(MenuComponent menuComponent) { 413 MenuComponent menu = new MenuComponent(); 414 try { 415 MenuComponent parentMenu = menuComponent.getParent(); 416 menuComponent.setParent(null); 417 WebappUtil.copyProperties(menu, menuComponent, request); 418 menuComponent.setParent(parentMenu); 419 } catch ( Exception e ) { 420 if ( log.isErrorEnabled() ) { 421 log.error("Failed to perform recursive copy of menu component."); 422 StringWriter sw = new StringWriter (); 423 e.printStackTrace(new PrintWriter (sw)); 424 log.error(sw.toString()); 425 } 426 return null; 427 } 428 MenuComponent[] childComponents = menuComponent.getMenuComponents(); 429 for ( int i = 0; i < childComponents.length; i++ ) { 430 MenuComponent component = (MenuComponent) childComponents[i]; 431 MenuComponent copy = recursiveCopy(component); 432 433 if ( copy != null ) { 435 menu.addMenuComponent(copy); 436 } 437 } 438 439 return menu; 440 } 441 442 449 protected MenuItem findMenuItem(List menuItems, Long id) { 450 MenuItem menuItem = null; 451 for ( Iterator i = menuItems.iterator(); i.hasNext(); ) { 452 menuItem = (MenuItem) i.next(); 453 if ( menuItem.getId().equals(id) ) { 454 break; 455 } 456 menuItem = null; 457 } 458 return menuItem; 459 } 460 461 469 public static MenuComponent findMenuComponent(MenuComponent[] menuComponents, String name) { 470 MenuComponent menuComponent = null; 471 for ( int i = 0; i < menuComponents.length; i++ ) { 472 if ( menuComponents[i].getName().equals(name) ) { 473 menuComponent = menuComponents[i]; 474 break; 475 } 476 } 477 return menuComponent; 478 } 479 480 495 public String getLocation(MenuItem menu, int urlType) 496 throws MalformedURLException { 497 498 String location = null; 499 500 if ( menu.getLocation() == null ) { 504 if ( menu.getAnchor() != null ) { 505 location = new String (); 506 if ( urlType == WebappConstants.URL_TYPE_DOMAIN_RELATIVE ) { 507 location = contextPath; 508 } 509 location += getAnchor(menu.getAnchor()); 510 } else if ( menu.getForward() != null ) { 511 location = WebappUtil.getActionForwardURL(menu.getForward(), null, request, urlType); 512 } else if ( menu.getAction() != null ) { 513 location = WebappUtil.getActionMappingURL(menu.getAction(), null, request, urlType, false); 514 } 515 } else { 516 location = menu.getLocation(); 517 if (!WebappUtil.isAbsoluteURL(location) && !menu.getExternalLocation().booleanValue() ) { 518 if ( !location.startsWith("/") ) { 519 location = "/" + location; 520 } 521 } 522 } 523 524 return location; 525 } 526 527 533 protected String getAnchor(String anchor) { 534 if ( anchor.startsWith("/") ) { 535 return anchor; 536 } else { 537 anchor = "/" + anchor; 538 } 539 540 return anchor; 541 } 542 543 544 547 public MenuRepository initializeMenuRepository() { 548 String menuConfig = servletContext.getInitParameter("menuConfigLocation"); 549 if ( menuConfig == null ) { 550 menuConfig = "/WEB-INF/menu-config.xml"; 551 } 552 553 MenuRepository menuRepository = new MenuRepository(); 554 menuRepository.setLoadParam(menuConfig); 555 menuRepository.setServletContext(servletContext); 556 try { 557 menuRepository.load(); 558 559 if ( log.isDebugEnabled() ) { 560 log.debug("struts-menu initialization successfull"); 561 } 562 } catch ( LoadableResourceException lre ) { 563 if ( log.isFatalEnabled() ) { 564 log.fatal("Failure initializing struts-menu: " + lre.getMessage()); 565 } 566 } 567 568 List menuComponents = menuRepository.getTopMenus(); 570 571 final ContentLocale defaultLocale = LocaleUtil.getInstance(servletContext).getDefaultLocale(); 573 final RoleManager roleManager = (RoleManager) applicationContext.getBean(Constants.ROLE_MANAGER_BEAN); 574 575 Converter structuredPropertiesConverter = new Converter() { 577 public Object convert(Class type, Object value) { 578 579 if ( type == Map .class ) { 580 Map result = new HashMap (); 582 result.put(defaultLocale.getIdentifier(), value); 583 return result; 584 } 585 if ( type == List .class ) { 586 List result = new ArrayList (); 588 if ( value != null ) { 589 List roleNames = ConvertUtil.convertStringToList((String ) value, ",", true); 590 for ( Iterator j = roleNames.iterator(); j.hasNext(); ) { 591 String roleName = (String ) j.next(); 592 Role role = roleManager.retrieveRole(roleName); 593 if ( role == null ) { 594 if ( log.isWarnEnabled() ) { 595 log.warn("Role with name '" + roleName + " not found."); 596 } 597 } else { 598 result.add(role); 599 } 600 } 601 } 602 return result; 603 } else { 604 605 return null; 607 } 608 } 609 }; 610 611 ConvertUtils.register(structuredPropertiesConverter, Map .class); 613 ConvertUtils.register(structuredPropertiesConverter, List .class); 614 615 processRedifinitions(menuComponents, null); 616 617 ConvertUtils.deregister(Map .class); 619 ConvertUtils.deregister(List .class); 620 621 if ( log.isInfoEnabled() ) { 622 log.info("Menu items from file " + menuConfig + " synchronized with database"); 623 } 624 625 return menuRepository; 626 } 627 628 635 protected void setLinkedObjects(MenuItem menuItem, MenuComponent menuComponent) { 636 List linkedPages = new ArrayList (); 638 List linkedResources = new ArrayList (); 639 String image = menuComponent.getImage(); 640 BaseObject linkedObject = WebappUtil.lookupObject(image, servletContext, contextPath); 641 if ( linkedObject != null && linkedObject instanceof ContentImage ) { 642 linkedResources.add(linkedObject); 643 } 644 645 String altImage = menuComponent.getAltImage(); 646 if ( !GenericValidator.isBlankOrNull(altImage) && !altImage.equals(image) ) { 647 linkedObject = WebappUtil.lookupObject(menuComponent.getAltImage(), servletContext, contextPath); 648 if ( linkedObject != null && linkedObject instanceof ContentImage ) { 649 linkedResources.add(linkedObject); 650 } 651 } 652 653 String uri = menuComponent.getLocation(); 655 656 if ( uri == null || uri.length() == 0 ) { 657 uri = menuComponent.getAction(); 658 } 659 660 if ( uri != null && uri.length() > 0 ) { 661 linkedObject = WebappUtil.lookupObject(uri, servletContext, contextPath); 662 if ( linkedObject != null ) { 663 if ( linkedObject instanceof ContentResource ) { 664 linkedResources.add(linkedObject); 665 } else if ( linkedObject instanceof Page ) { 666 linkedPages.add(linkedObject); 667 } 668 } 669 } 670 671 menuItem.setLinkedResources(linkedResources); 672 menuItem.setLinkedPages(linkedPages); 673 } 674 675 681 protected void processRedifinitions(List menuComponents, final Long parentId) { 682 MenuManager menuManager = (MenuManager) applicationContext.getBean(Constants.MENU_MANAGER_BEAN); 683 684 List menuItems = menuManager.findMenuItemsByParentAndOwner(parentId, null); 686 if ( menuItems != null ) { 687 for ( Iterator i = menuItems.iterator(); i.hasNext(); ) { 688 MenuItem menuItem = (MenuItem) i.next(); 689 MenuComponent menuComponent = MenuUtil.findMenuComponent((MenuComponent[]) menuComponents.toArray(new MenuComponent[0]), menuItem.getIdentifier()); 690 if ( menuComponent == null ) { 691 try { 693 menuManager.deleteMenuItem(menuItem.getId()); 694 } catch ( BeanNotFoundException e ) { 695 if ( log.isErrorEnabled() ) { 697 StringWriter sw = new StringWriter (); 698 e.printStackTrace(new PrintWriter (sw)); 699 log.error(sw.toString()); 700 } 701 } 702 } 703 } 704 } 705 706 int k = 0; 708 for ( Iterator i = menuComponents.iterator(); i.hasNext(); k++ ) { 709 MenuComponent menuComponent = (MenuComponent) i.next(); 710 MenuItem menuItem = menuManager.findMenuItemByIdentifierAndParentAndOwner(menuComponent.getName(), parentId, null); 711 712 Long parentItemId = null; 713 714 if ( menuItem != null ) { 715 try { 717 WebappUtil.copyProperties(menuItem, menuComponent); 718 } catch ( Exception e ) { 719 if ( log.isFatalEnabled() ) { 720 StringWriter sw = new StringWriter (); 721 e.printStackTrace(new PrintWriter (sw)); 722 log.fatal("Failed to copy properties. Creation of redifinition skipped."); 723 log.fatal(sw.toString()); 724 } 725 continue; 726 } 727 728 menuItem.setPosition(new Integer (k)); 729 parentItemId = menuItem.getId(); 730 try { 731 menuManager.updateMenuItem(menuItem, parentId, null); 732 733 setLinkedObjects(menuItem, menuComponent); 735 } catch ( Exception e ) { 736 if ( log.isFatalEnabled() ) { 738 StringWriter sw = new StringWriter (); 739 e.printStackTrace(new PrintWriter (sw)); 740 log.fatal("Failed to update redifinition for component: " + menuComponent.getName() + ". Skipped."); 741 log.fatal(sw.toString()); 742 } 743 continue; 744 } 745 } else { 746 menuItem = new MenuItem(); 748 749 try { 750 WebappUtil.copyProperties(menuItem, menuComponent); 751 } catch ( Exception e ) { 752 if ( log.isFatalEnabled() ) { 753 StringWriter sw = new StringWriter (); 754 e.printStackTrace(new PrintWriter (sw)); 755 log.fatal("Failed to copy properties. Creation of redifinition skipped."); 756 log.fatal(sw.toString()); 757 } 758 continue; 759 } 760 761 menuItem.setPosition(new Integer (k)); 762 menuItem.setIdentifier(menuComponent.getName()); 763 menuItem.setVisibility(new Byte (MenuItem.VISIBILITY_VISIBLE)); 764 765 setLinkedObjects(menuItem, menuComponent); 767 768 try { 769 parentItemId = menuManager.createMenuItem(menuItem, parentId, null); 770 } catch ( Exception e ) { 771 if ( log.isFatalEnabled() ) { 773 StringWriter sw = new StringWriter (); 774 e.printStackTrace(new PrintWriter (sw)); 775 log.fatal("Failed to create redifinition for component: " + menuComponent.getName() + ". Skipped."); 776 log.fatal(sw.toString()); 777 } 778 continue; 779 } 780 } 781 782 processRedifinitions(menuComponent.getComponents(), parentItemId); 784 } 785 786 } 787 788 789 } 790 | Popular Tags |