CustomMenusJspBean.java
/*
* Copyright (c) 2002-2025, City of Paris
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright notice
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* License 1.0
*/
package fr.paris.lutece.plugins.menus.web;
import fr.paris.lutece.plugins.menus.business.CustomMenu;
import fr.paris.lutece.plugins.menus.business.CustomMenuHome;
import fr.paris.lutece.plugins.menus.business.CustomMenuItem;
import fr.paris.lutece.plugins.menus.business.CustomMenuItemHome;
import fr.paris.lutece.plugins.menus.service.CustomMenuService;
import fr.paris.lutece.plugins.menus.service.MainTreeMenuService;
import fr.paris.lutece.plugins.menus.service.MainTreeMenuAllPagesService;
import fr.paris.lutece.plugins.menus.web.validator.ValidatorCustomItemForm;
import fr.paris.lutece.portal.service.cache.CacheService;
import fr.paris.lutece.portal.service.cache.CacheableService;
import fr.paris.lutece.portal.service.datastore.DatastoreService;
import fr.paris.lutece.portal.service.i18n.I18nService;
import fr.paris.lutece.portal.service.message.AdminMessage;
import fr.paris.lutece.portal.service.message.AdminMessageService;
import fr.paris.lutece.portal.util.mvc.admin.annotations.Controller;
import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
import fr.paris.lutece.util.ReferenceList;
import fr.paris.lutece.util.url.UrlItem;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
/**
* Custom Menus JSP Bean using MVC annotations
*/
@Controller( controllerJsp = "ManageCustomMenus.jsp", controllerPath = "jsp/admin/plugins/menus/", right = "CUSTOM_MENUS_MANAGEMENT" )
public class CustomMenusJspBean extends PaginatedJspBean < Integer, Object >
{
private static final long serialVersionUID = 1L;
public static final String RIGHT_MANAGE_CUSTOM_MENUS = "CUSTOM_MENUS_MANAGEMENT";
// Views
private static final String VIEW_MANAGE_CUSTOM_MENUS = "manageCustomMenus";
private static final String VIEW_CREATE_CUSTOM_MENU = "createCustomMenu";
private static final String VIEW_MODIFY_CUSTOM_MENU = "modifyCustomMenu";
private static final String VIEW_CONFIRM_REMOVE_CUSTOM_MENU = "removeCustomMenu";
private static final String VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS = "createCustomMenuWithItems";
private static final String VIEW_MODIFY_CUSTOM_MENU_ITEM = "modifyCustomMenuItem";
private static final String VIEW_MODIFY_CUSTOM_MENU_WITH_ITEMS = "modifyCustomMenuWithItems";
private static final String VIEW_CONFIRM_REMOVE_CUSTOM_MENU_ITEM = "removeCustomMenuItem";
// Actions
private static final String ACTION_CREATE_CUSTOM_MENU = "createCustomMenu";
private static final String ACTION_MODIFY_CUSTOM_MENU = "modifyCustomMenu";
private static final String ACTION_REMOVE_CUSTOM_MENU = "removeCustomMenu";
private static final String ACTION_CREATE_CUSTOM_MENU_ITEMS = "createCustomMenuItems";
private static final String ACTION_MODIFY_CUSTOM_MENU_ITEM = "modifyCustomMenuItem";
private static final String ACTION_REMOVE_CUSTOM_MENU_ITEM = "removeCustomMenuItem";
private static final String ACTION_SEARCH_ITEMS = "searchItems";
private static final String ACTION_CHANGE_ITEMS_ORDER = "changeMenuItemsOrder";
private static final String ACTION_MODIFY_NATIVE_MENU_SETTINGS = "doModifyNativeMenuSettings";
// Marks
private static final String MARK_ID_CUSTOM_MENU = "id_current_custom_menu";
private static final String MARK_CUSTOM_MENUS_LIST = "custom_menus_list";
private static final String MARK_CUSTOM_MENU = "custom_menu";
private static final String MARK_CUSTOM_MENU_ITEM = "custom_menu_item";
private static final String MARK_CUSTOM_MENU_ITEMS_LIST = "custom_menu_items_list";
private static final String MARK_MENU_TYPES_LIST = "menu_types_list";
private static final String MARK_ITEM_TYPES_LIST = "item_types_list";
private static final String MARK_AVAILABLE_MENUS_LIST = "available_menus_list";
private static final String MARK_AVAILABLE_XPAGES_LIST = "available_xpages_list";
private static final String MARK_AVAILABLE_PAGES_LIST = "available_pages_list";
private static final String MARK_CREATE_CUSTOM_MENU_ITEM_ERROR = "create_items_errors_list";
private static final String MARK_MODIFY_CUSTOM_MENU_ITEM_ERROR = "modify_items_errors_list";
private static final String MARK_SEARCH_CRITERIA = "search_criteria";
private static final String MARK_MAX_ORDER_SIZE = "max_order_size";
private static final String MARK_DEPTH_MENU_MAIN = "depth_menu_main";
private static final String MARK_DEPTH_MENU_TREE = "depth_menu_tree";
private static final String MARK_DEPTH_MENU_TREE_ALL_PAGES = "depth_menu_tree_all_pages";
private static final String MARK_OPTION_DEPTH_MAIN = "depth_options_main";
private static final String MARK_OPTION_DEPTH_TREE = "depth_options_tree";
// Parameters
private static final String PARAMETER_ID = "id";
private static final String PARAMETER_SEARCH_CRITERIA = "search";
private static final String PARAMETER_ACTION_CREATE_CUSTOM_MENU_BUTTON = "actionCreateCustomMenuButton";
private static final String PARAMETER_ACTION_MODIFY_CUSTOM_MENU_BUTTON = "actionModifyCustomMenuButton";
private static final String PARAMETER_ACTION_SEARCH_ITEMS_BUTTON = "searchItemsButton";
private static final String PARAMETER_ORDER_ID = "order_id";
private static final String PARAMETER_MENU_TYPE = "menu_type";
private static final String PARAMETER_DEPTH_VALUE = "depth_value";
// Button action value
private static final String VALUE_ACTION_CREATE_CUSTOM_MENU_BUTTON = "create_custom_menu_with_items";
private static final String VALUE_ACTION_MODIFY_CUSTOM_MENU_BUTTON = "modify_custom_menu_with_items";
private static final String VALUE_CLEAN_BUTTON = "clean";
// Templates
private static final String TEMPLATE_MANAGE_CUSTOM_MENUS = "/admin/plugins/menus/manage_custom_menus.html";
private static final String TEMPLATE_CREATE_CUSTOM_MENU = "/admin/plugins/menus/create_custom_menu.html";
private static final String TEMPLATE_MODIFY_CUSTOM_MENU = "/admin/plugins/menus/modify_custom_menu.html";
private static final String TEMPLATE_CREATE_CUSTOM_MENU_WITH_ITEMS = "/admin/plugins/menus/create_custom_menu_with_items.html";
private static final String TEMPLATE_MODIFY_CUSTOM_MENU_ITEM = "/admin/plugins/menus/modify_custom_menu_item.html";
private static final String TEMPLATE_MODIFY_CUSTOM_MENU_WITH_ITEMS = "/admin/plugins/menus/modify_custom_menu_with_items.html";
// Properties for page titles
private static final String PROPERTY_PAGE_TITLE_MANAGE_CUSTOM_MENUS = "menus.manage_custom_menus.pageTitle";
private static final String PROPERTY_PAGE_TITLE_CREATE_CUSTOM_MENU = "menus.create_custom_menu.pageTitle";
private static final String PROPERTY_PAGE_TITLE_CREATE_CUSTOM_MENU_WITH_ITEMS = "menus.create_custom_menu_with_items.pageTitle";
private static final String PROPERTY_PAGE_TITLE_MODIFY_CUSTOM_MENU = "menus.modify_custom_menu.pageTitle";
private static final String PROPERTY_PAGE_TITLE_MODIFY_CUSTOM_MENU_WITH_ITEMS = "menus.modify_custom_menu_with_items.pageTitle";
private static final String PROPERTY_MENU_MAIN = "menus.mainTreeMenu.depth.main";
private static final String PROPERTY_MENU_TREE = "menus.mainTreeMenu.depth.tree";
private static final String PROPERTY_MENU_TREE_ALL_PAGES = "menus.mainTreeMenu.depth.tree.allpages";
// Jsp paths
private static final String JSP_MANAGE_MENUS = "jsp/admin/plugins/menus/ManageCustomMenus.jsp";
private static final String JSP_CREATE_ITEM = "jsp/admin/plugins/menus/ManageCustomMenus.jsp?view=createCustomMenuWithItems";
private static final String JSP_MODIFY_ITEM = "jsp/admin/plugins/menus/ManageCustomMenus.jsp?view=modifyCustomMenuWithItems";
// Info messages
private static final String INFO_CUSTOM_MENU_CREATED = "menus.info.custom_menu.created";
private static final String INFO_CUSTOM_MENU_UPDATED = "menus.info.custom_menu.updated";
private static final String INFO_CUSTOM_MENU_REMOVED = "menus.info.custom_menu.removed";
private static final String INFO_CUSTOM_MENU_ITEM_CREATED = "menus.info.custom_menu_item.created";
private static final String INFO_CUSTOM_MENU_ITEM_UPDATED = "menus.info.custom_menu_item.updated";
private static final String INFO_CUSTOM_MENU_ITEM_REMOVED = "menus.info.custom_menu_item.removed";
private static final String EMPTY_MENU_TYPE = "menus.constant_custom_menu_item.type.emtpy";
private static final String MESSAGE_CONFIRM_REMOVE_MENU = "menus.manage_custom_menus.confirmRemove";
private static final String MESSAGE_CONFIRM_REMOVE_MENU_ITEM = "menus.manage_custom_menu_items.confirmRemove";
private static final String MESSAGE_BOOKMARK_NOT_UNIQUE = "menus.manage_custom_menu.bookmark.notUnique";
private static final String MESSAGE_NATIVE_MENU_SETTINGS_UPDATE = "menus.info.native_menu_settings.updated";
private static final String MESSAGE_ERROR_UNAUTHORIZED_PROPERTY = "menus.error.unauthorized_property";
private static final String MESSAGE_ERROR_INVALID_DEPTH = "menus.error.invalid_depth_value";
private static final String MESSAGE_ERROR_INVALID_NUMBER_FORMAT = "menus.error.invalid_number_format";
private static final String MESSAGE_ERROR_MISSING_PARAMETER = "menus.error.missing_parameters";
// Validation
private static final String VALIDATION_ATTRIBUTES_PREFIX = "menus.model.entity.custom_menu";
// Constants
private static final String MENU_TYPE_MAIN = "main";
private static final String MENU_TYPE_SUBMENU = "submenu";
private static final String MENU_TYPE_MENU_MAIN = "menuMain";
private static final String MENU_TYPE_MENU_TREE = "menuTree";
private static final String MENU_TYPE_MENU_TREE_ALL_PAGES = "menuTreeAllPages";
private static final String MENU_TYPE_INTERNAL = "internal";
private static final String MENU_TYPE_SIDEBAR = "sidebar";
private static final String MENU_ITEM_TYPE_EMPTY = "";
private static final String MENU_ITEM_TYPE_XPAGE = "xpage";
private static final String MENU_ITEM_TYPE_PAGE = "page";
private static final String MENU_ITEM_TYPE_EXTERNAL_URL = "external_url";
private static final String MENU_ITEM_TYPE_MENU = "menu";
private static final Integer ID_CACHE_PAGE_SERVICE_CACHE = 2;
private static final String DEFAULT_MAX_DEPTH_MAIN_MENU= "1";
private static final String DEFAULT_MAX_DEPTH_TREE_MENU="2";
// Instance variable for custom menu
private CustomMenu _currentCustomMenu;
private CustomMenuItem _currentCustomMenuItem;
private ReferenceList _listMenuTypes;
private ReferenceList _listMenuItemTypes;
private ValidatorCustomItemForm _itemValidator;
private String _strFilterCriteria;
// /////////////////////////////////////////////////
// ////////////////CUSTOM_MENUS/////////////////////
// /////////////////////////////////////////////////
// /////////////MANAGE_CUSTOM_MENUS/////////////////
/**
* Returns the list of custom menus
*
* @param request The Http request
* @return the View
*/
@View( value = VIEW_MANAGE_CUSTOM_MENUS, defaultView = true )
public String getManageCustomMenus( HttpServletRequest request )
{
_currentCustomMenu = null;
_currentCustomMenuItem = null;
initReferenceLists( ); // init constant lists : _listMenuTypes and _listMenuItemTypes
List < Integer > listCustomMenusIds = CustomMenuHome.getIdMenusList( );
Map < String, Object > model = getPaginatedListModelForCustomMenu( request, MARK_CUSTOM_MENUS_LIST,
listCustomMenusIds,
JSP_MANAGE_MENUS );
model.put( MARK_MENU_TYPES_LIST, _listMenuTypes );
model.put( MARK_OPTION_DEPTH_MAIN, getDepthOptions( 1 ) );
model.put( MARK_OPTION_DEPTH_TREE, getDepthOptions( 2 ) );
model.put( MARK_DEPTH_MENU_MAIN, getDepthPropertyValue( PROPERTY_MENU_MAIN, DEFAULT_MAX_DEPTH_MAIN_MENU ) );
model.put( MARK_DEPTH_MENU_TREE, getDepthPropertyValue( PROPERTY_MENU_TREE, DEFAULT_MAX_DEPTH_TREE_MENU ) );
model.put( MARK_DEPTH_MENU_TREE_ALL_PAGES,
getDepthPropertyValue( PROPERTY_MENU_TREE_ALL_PAGES, DEFAULT_MAX_DEPTH_TREE_MENU ) );
return getPage( PROPERTY_PAGE_TITLE_MANAGE_CUSTOM_MENUS, TEMPLATE_MANAGE_CUSTOM_MENUS, model );
}
// /////////////CREATE_CUSTOM_MENU/////////////////
/**
* Returns the form to create a custom menu
*
* @param request The Http request
* @return the View
*/
@View( VIEW_CREATE_CUSTOM_MENU )
public String getCreateCustomMenu( HttpServletRequest request )
{
initReferenceLists( ); // init constant lists : _listMenuTypes and _listMenuItemTypes
Map < String, Object > model = getModel( );
model.put( MARK_MENU_TYPES_LIST, _listMenuTypes );
return getPage( PROPERTY_PAGE_TITLE_CREATE_CUSTOM_MENU, TEMPLATE_CREATE_CUSTOM_MENU, model );
}
/**
* Process the data capture form of a new custom menu
*
* @param request The Http Request
* @return The JSP URL which displays the process result
*/
@Action( ACTION_CREATE_CUSTOM_MENU )
public String doCreateCustomMenu( HttpServletRequest request )
{
_currentCustomMenu = new CustomMenu( );
populate( _currentCustomMenu, request, getLocale( ) );
Boolean bIsUniqueBookmark = CustomMenuHome.isUniqueBookmark( _currentCustomMenu, true );
if( ! validateBean( _currentCustomMenu, VALIDATION_ATTRIBUTES_PREFIX ) || ! bIsUniqueBookmark )
{
if( ! bIsUniqueBookmark )
{
addError( I18nService.getLocalizedString( MESSAGE_BOOKMARK_NOT_UNIQUE, getLocale( ) ) );
}
return redirectView( request, VIEW_MANAGE_CUSTOM_MENUS );
}
CustomMenuHome.create( _currentCustomMenu );
addInfo( INFO_CUSTOM_MENU_CREATED, getLocale( ) );
resetPagesCache( );
String action = request.getParameter( PARAMETER_ACTION_CREATE_CUSTOM_MENU_BUTTON );
if( Strings.CS.equals( VALUE_ACTION_CREATE_CUSTOM_MENU_BUTTON, action ) )
{
return redirectView( request, VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS );
}
else
{
return redirectView( request, VIEW_MANAGE_CUSTOM_MENUS );
}
}
// /////////////MODIFY_CUSTOM_MENU/////////////////
/**
* Returns the form to modify a custom menu
*
* @param request The Http request
* @return the View
*/
@View( VIEW_MODIFY_CUSTOM_MENU )
public String getModifyCustomMenu( HttpServletRequest request )
{
initReferenceLists( ); // init constant lists : _listMenuTypes and _listMenuItemTypes
int nId = Integer.parseInt( request.getParameter( PARAMETER_ID ) );
_currentCustomMenu = CustomMenuHome.findByPrimaryKey( nId );
Map < String, Object > model = getModel( );
model.put( MARK_CUSTOM_MENU, _currentCustomMenu );
model.put( MARK_MENU_TYPES_LIST, _listMenuTypes );
return getPage( PROPERTY_PAGE_TITLE_MODIFY_CUSTOM_MENU, TEMPLATE_MODIFY_CUSTOM_MENU, model );
}
/**
* Process the data capture form of a custom menu to modify
*
* @param request The Http Request
* @return The JSP URL which displays the process result
*/
@Action( ACTION_MODIFY_CUSTOM_MENU )
public String doModifyCustomMenu( HttpServletRequest request )
{
_currentCustomMenu = new CustomMenu( );
populate( _currentCustomMenu, request, getLocale( ) );
Boolean bIsUniqueBookmark = CustomMenuHome.isUniqueBookmark( _currentCustomMenu, false );
if( ! validateBean( _currentCustomMenu, VALIDATION_ATTRIBUTES_PREFIX ) || ! bIsUniqueBookmark )
{
if( ! bIsUniqueBookmark )
{
addError( I18nService.getLocalizedString( MESSAGE_BOOKMARK_NOT_UNIQUE, getLocale( ) ) );
}
return redirectView( request, VIEW_MANAGE_CUSTOM_MENUS );
}
CustomMenuHome.update( _currentCustomMenu );
addInfo( INFO_CUSTOM_MENU_UPDATED, getLocale( ) );
resetPagesCache( );
String action = request.getParameter( PARAMETER_ACTION_MODIFY_CUSTOM_MENU_BUTTON );
if( Strings.CS.equals( VALUE_ACTION_MODIFY_CUSTOM_MENU_BUTTON, action ) )
{
return redirectView( request, VIEW_MODIFY_CUSTOM_MENU_WITH_ITEMS );
}
else
{
return redirectView( request, VIEW_MANAGE_CUSTOM_MENUS );
}
}
/**
* Returns the form to modify a custom menu
*
* @param request The Http request
* @return the View
*/
@View( VIEW_MODIFY_CUSTOM_MENU_WITH_ITEMS )
public String getModifyCustomMenuWithItems( HttpServletRequest request )
{
if( _currentCustomMenu == null )
{
return redirectView( request, VIEW_MANAGE_CUSTOM_MENUS );
}
initReferenceLists( ); // init constant lists : _listMenuTypes and _listMenuItemTypes
List < CustomMenuItem > listCustomMenuItems = CustomMenuItemHome
.getCustomMenuItemsListByMenuId( _currentCustomMenu.getId( ) );
Map < String, Object > model = getPaginatedListModelForCustomMenuItem( request, MARK_CUSTOM_MENU_ITEMS_LIST,
listCustomMenuItems, JSP_MODIFY_ITEM );
model.put( MARK_ID_CUSTOM_MENU, _currentCustomMenu.getId( ) );
model.put( MARK_ITEM_TYPES_LIST, _listMenuItemTypes );
model.put( MARK_AVAILABLE_PAGES_LIST,
CustomMenuService.getInstance( ).getAvailablePagesReferenceList( _strFilterCriteria ) );
model.put( MARK_AVAILABLE_XPAGES_LIST,
CustomMenuService.getInstance( ).getAvailableXpagesReferenceList( _strFilterCriteria ) );
model.put( MARK_AVAILABLE_MENUS_LIST, CustomMenuService.getInstance( )
.getAvailableMenusReferenceList( _currentCustomMenu, _strFilterCriteria ) );
model.put( MARK_SEARCH_CRITERIA, _strFilterCriteria );
model.put( MARK_MAX_ORDER_SIZE, listCustomMenuItems.size( ) );
if( _itemValidator != null )
{
model.put( MARK_CREATE_CUSTOM_MENU_ITEM_ERROR, _itemValidator.getListErrors( ) );
_itemValidator = null;
}
return getPage( PROPERTY_PAGE_TITLE_MODIFY_CUSTOM_MENU_WITH_ITEMS, TEMPLATE_MODIFY_CUSTOM_MENU_WITH_ITEMS,
model );
}
// /////////////REMOVE_CUSTOM_MENU/////////////////
/**
* Manages the removal form of a custom menu whose identifier is in the http
* request
*
* @param request The Http request
* @return the html code to confirm
*/
@View( VIEW_CONFIRM_REMOVE_CUSTOM_MENU )
public String getConfirmRemoveCustomMenu( HttpServletRequest request )
{
int nId = Integer.parseInt( request.getParameter( PARAMETER_ID ) );
UrlItem url = new UrlItem( getActionUrl( ACTION_REMOVE_CUSTOM_MENU ) );
url.addParameter( PARAMETER_ID, nId );
String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_REMOVE_MENU,
url.getUrl( ), AdminMessage.TYPE_CONFIRMATION );
return redirect( request, strMessageUrl );
}
/**
* Handles the removal form of a custom menu
*
* @param request The Http request
* @return the JSP URL to display the form to manage custom menus
*/
@Action( ACTION_REMOVE_CUSTOM_MENU )
public String doRemoveCustomMenu( HttpServletRequest request )
{
int nId = Integer.parseInt( request.getParameter( PARAMETER_ID ) );
CustomMenuHome.remove( nId );
addInfo( INFO_CUSTOM_MENU_REMOVED, getLocale( ) );
resetPagesCache( );
return redirectView( request, VIEW_MANAGE_CUSTOM_MENUS );
}
// /////////////////////////////////////////////////////
// ////////////////CUSTOM_MENU_ITEMS////////////////////
// /////////////////////////////////////////////////////
// /////////////CREATE_CUSTOM_MENU_ITEMS////////////////
/**
* Returns the form to create a custom menu
*
* @param request The Http request
* @return the View
*/
@View( VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS )
public String getCreateCustomMenuWithItems( HttpServletRequest request )
{
initReferenceLists( ); // init constant lists : _listMenuTypes and _listMenuItemTypes
if( _currentCustomMenu == null )
{
return redirectView( request, VIEW_MANAGE_CUSTOM_MENUS );
}
List < CustomMenuItem > listCustomMenuItems = CustomMenuItemHome
.getCustomMenuItemsListByMenuId( _currentCustomMenu.getId( ) );
Map < String, Object > model = getPaginatedListModelForCustomMenuItem( request, MARK_CUSTOM_MENU_ITEMS_LIST,
listCustomMenuItems, JSP_CREATE_ITEM );
model.put( MARK_ID_CUSTOM_MENU, _currentCustomMenu.getId( ) );
model.put( MARK_ITEM_TYPES_LIST, _listMenuItemTypes );
model.put( MARK_AVAILABLE_PAGES_LIST,
CustomMenuService.getInstance( ).getAvailablePagesReferenceList( _strFilterCriteria ) );
model.put( MARK_AVAILABLE_XPAGES_LIST,
CustomMenuService.getInstance( ).getAvailableXpagesReferenceList( _strFilterCriteria ) );
model.put( MARK_AVAILABLE_MENUS_LIST, CustomMenuService.getInstance( )
.getAvailableMenusReferenceList( _currentCustomMenu, _strFilterCriteria ) );
model.put( MARK_SEARCH_CRITERIA, _strFilterCriteria );
model.put( MARK_MAX_ORDER_SIZE, listCustomMenuItems.size( ) );
if( _itemValidator != null )
{
model.put( MARK_CREATE_CUSTOM_MENU_ITEM_ERROR, _itemValidator.getListErrors( ) );
_itemValidator = null;
}
return getPage( PROPERTY_PAGE_TITLE_CREATE_CUSTOM_MENU_WITH_ITEMS, TEMPLATE_CREATE_CUSTOM_MENU_WITH_ITEMS,
model );
}
/**
* Process the data capture form of a custom menu to create
*
* @param request The Http Request
* @return The JSP URL which displays the process result
*/
@Action( ACTION_CREATE_CUSTOM_MENU_ITEMS )
public String docreateCustomMenuItems( HttpServletRequest request )
{
_itemValidator = new ValidatorCustomItemForm( );
_currentCustomMenuItem = new CustomMenuItem( );
populate( _currentCustomMenuItem, request, getLocale( ) );
// Validate the bean
if( ! validateBean( _currentCustomMenuItem, VALIDATION_ATTRIBUTES_PREFIX )
|| ! _itemValidator.isValid( _currentCustomMenuItem, getLocale( ) ) )
{
return redirectView( request, VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS );
}
CustomMenuItemHome.create( _currentCustomMenuItem );
addInfo( INFO_CUSTOM_MENU_ITEM_CREATED, getLocale( ) );
resetPagesCache( );
_currentCustomMenuItem = null;
return redirectView( request, VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS );
}
// /////////////MODIFY_CUSTOM_MENU_ITEM////////////////
/**
* Returns the form to modify a custom menu item
*
* @param request The Http request
* @return the View
*/
@View( VIEW_MODIFY_CUSTOM_MENU_ITEM )
public String getModifyCustomMenuItem( HttpServletRequest request )
{
if( _currentCustomMenu == null )
{
return redirectView( request, VIEW_MANAGE_CUSTOM_MENUS );
}
initReferenceLists( ); // init constant lists : _listMenuTypes and _listMenuItemTypes
int nId = Integer.parseInt( request.getParameter( PARAMETER_ID ) );
_currentCustomMenuItem = CustomMenuItemHome.findByPrimaryKey( nId );
if( _currentCustomMenuItem == null || _currentCustomMenuItem.getParentMenuId( ) != _currentCustomMenu.getId( ) )
{
// The item does not exist or does not belong to the current menu
return redirectView( request, VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS );
}
Map < String, Object > model = getModel( );
model.put( MARK_ID_CUSTOM_MENU, _currentCustomMenu.getId( ) );
model.put( MARK_CUSTOM_MENU_ITEM, _currentCustomMenuItem );
model.put( MARK_ITEM_TYPES_LIST, _listMenuItemTypes );
model.put( MARK_AVAILABLE_PAGES_LIST,
CustomMenuService.getInstance( ).getAvailablePagesReferenceList( _strFilterCriteria ) );
model.put( MARK_AVAILABLE_XPAGES_LIST,
CustomMenuService.getInstance( ).getAvailableXpagesReferenceList( _strFilterCriteria ) );
model.put( MARK_AVAILABLE_MENUS_LIST, CustomMenuService.getInstance( )
.getAvailableMenusReferenceList( _currentCustomMenu, _strFilterCriteria ) );
if( _itemValidator != null )
{
model.put( MARK_MODIFY_CUSTOM_MENU_ITEM_ERROR, _itemValidator.getListErrors( ) );
_itemValidator = null;
}
return getPage( PROPERTY_PAGE_TITLE_MODIFY_CUSTOM_MENU, TEMPLATE_MODIFY_CUSTOM_MENU_ITEM, model );
}
/**
* Process the data capture form of a custom menu item to modify
*
* @param request The Http Request
* @return The JSP URL which displays the process result
*/
@Action( ACTION_MODIFY_CUSTOM_MENU_ITEM )
public String doModifyCustomMenuItem( HttpServletRequest request )
{
_itemValidator = new ValidatorCustomItemForm( );
_currentCustomMenuItem = new CustomMenuItem( );
populate( _currentCustomMenuItem, request, getLocale( ) );
// Validate the bean
if( ! validateBean( _currentCustomMenuItem, VALIDATION_ATTRIBUTES_PREFIX )
|| ! _itemValidator.isValid( _currentCustomMenuItem, getLocale( ) ) )
{
return redirectView( request, VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS );
}
CustomMenuItemHome.update( _currentCustomMenuItem );
addInfo( INFO_CUSTOM_MENU_ITEM_UPDATED, getLocale( ) );
resetPagesCache( );
_currentCustomMenuItem = null;
return redirectView( request, VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS );
}
// /////////////REMOVE_CUSTOM_MENU_ITEM////////////////
/**
* Returns the page with confirmation to remove message for a custom menu item
*
* @param request The Http request
* @return the View
*/
@View( VIEW_CONFIRM_REMOVE_CUSTOM_MENU_ITEM )
public String getConfirmRemoveCustomMenuItem( HttpServletRequest request )
{
int nId = Integer.parseInt( request.getParameter( PARAMETER_ID ) );
UrlItem url = new UrlItem( getActionUrl( ACTION_REMOVE_CUSTOM_MENU_ITEM ) );
url.addParameter( PARAMETER_ID, nId );
String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_REMOVE_MENU_ITEM,
url.getUrl( ), AdminMessage.TYPE_CONFIRMATION );
return redirect( request, strMessageUrl );
}
/**
* Handles the removal form of a custom menu item
*
* @param request The Http request
* @return the JSP URL to display the form to manage custom menus
*/
@Action( ACTION_REMOVE_CUSTOM_MENU_ITEM )
public String doRemoveCustomMenuItem( HttpServletRequest request )
{
// Retrieve the ID of the item to delete
int nItemId = Integer.parseInt( request.getParameter( PARAMETER_ID ) );
// Retrieve the item to delete to obtain its order
CustomMenuItem itemToRemove = CustomMenuItemHome.findByPrimaryKey( nItemId );
if( itemToRemove == null )
{
// Item doesn't exist
return redirectView( request, VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS );
}
// Check that the current menu exists and that the item belongs to this menu
if( _currentCustomMenu == null || itemToRemove.getParentMenuId( ) != _currentCustomMenu.getId( ) )
{
return redirectView( request, VIEW_MANAGE_CUSTOM_MENUS );
}
int removedItemOrder = itemToRemove.getOrder( );
// Delete the item from the database
CustomMenuItemHome.remove( nItemId );
// Retrieve all items in the current menu after deletion
List < CustomMenuItem > menuItems = CustomMenuItemHome
.getCustomMenuItemsListByMenuId( _currentCustomMenu.getId( ) );
// Update the order: decrement by 1 for all items with an order higher than the
// one deleted.
for( CustomMenuItem item : menuItems )
{
if( item.getOrder( ) > removedItemOrder )
{
item.setOrder( item.getOrder( ) - 1 );
CustomMenuItemHome.update( item );
}
}
addInfo( INFO_CUSTOM_MENU_ITEM_REMOVED, getLocale( ) );
resetPagesCache( );
return redirectView( request, VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS );
}
// /////////////////////////////////////////
// /////////////SEARCH_ITEMS////////////////
// /////////////////////////////////////////
/**
* Set strFilterCriteria variable for the search of pages, xpages, and menus
*
* @param request The Http request
* @return JSON response with search results
*/
@Action( ACTION_SEARCH_ITEMS )
public String doSearchItems( HttpServletRequest request )
{
String strButtonValue = request.getParameter( PARAMETER_ACTION_SEARCH_ITEMS_BUTTON );
if( Strings.CS.equals( strButtonValue, VALUE_CLEAN_BUTTON ) )
{
_strFilterCriteria = null;
}
else
{
_strFilterCriteria = request.getParameter( PARAMETER_SEARCH_CRITERIA );
}
return redirectView( request, VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS );
}
// ///////////////////////////////////////////////
// /////////////CHANGE_ITEMS_ORDER////////////////
// ///////////////////////////////////////////////
/**
* Change order items
*
* @param request The Http request
* @return a view
*/
@Action( ACTION_CHANGE_ITEMS_ORDER )
public String doChangeItemOrder( HttpServletRequest request )
{
if( _currentCustomMenu == null )
{
return redirectView( request, VIEW_MANAGE_CUSTOM_MENUS );
}
int nItemId = Integer.parseInt( request.getParameter( PARAMETER_ID ) );
int nNewOrder = Integer.parseInt( request.getParameter( PARAMETER_ORDER_ID ) );
// Get item to change
CustomMenuItem itemToMove = CustomMenuItemHome.findByPrimaryKey( nItemId );
if( itemToMove == null || itemToMove.getParentMenuId( ) != _currentCustomMenu.getId( ) )
{
// Item doesn't find
return redirectView( request, VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS );
}
// Get all item of the current menu
List < CustomMenuItem > menuItems = CustomMenuItemHome
.getCustomMenuItemsListByMenuId( _currentCustomMenu.getId( ) );
// Get the item whose has the order choosen for the item to change
CustomMenuItem itemWithTargetOrder = null;
for( CustomMenuItem item : menuItems )
{
if( item.getOrder( ) == nNewOrder && item.getId( ) != nItemId )
{
itemWithTargetOrder = item;
break;
}
}
// Exchange of orders
int oldOrder = itemToMove.getOrder( );
itemToMove.setOrder( nNewOrder );
CustomMenuItemHome.update( itemToMove );
// If an item already occupied this position, it is given the old order
if( itemWithTargetOrder != null )
{
itemWithTargetOrder.setOrder( oldOrder );
CustomMenuItemHome.update( itemWithTargetOrder );
}
resetPagesCache( );
return redirectView( request, VIEW_CREATE_CUSTOM_MENU_WITH_ITEMS );
}
// /////////////////////////////////////////
// ///////////INIT REFERENCE LISTS//////////
// /////////////////////////////////////////
/**
* Init reference list fo select menu types and item types
*
*/
private void initReferenceLists( )
{
if( _listMenuTypes == null )
{
initMenuTypeReferenceList( );
}
if( _listMenuItemTypes == null )
{
initMenuItemTypeReferenceList( );
}
}
/**
* Get the type reference list
*
* @return the reference list
*/
private void initMenuTypeReferenceList( )
{
_listMenuTypes = new ReferenceList( );
_listMenuTypes.addItem( MENU_TYPE_MAIN, I18nService.getLocalizedString( CustomMenu.TYPE_MAIN, getLocale( ) ) );
_listMenuTypes.addItem( MENU_TYPE_INTERNAL,
I18nService.getLocalizedString( CustomMenu.TYPE_INTERNAL, getLocale( ) ) );
_listMenuTypes.addItem( MENU_TYPE_SIDEBAR,
I18nService.getLocalizedString( CustomMenu.TYPE_SIDEBAR, getLocale( ) ) );
_listMenuTypes.addItem( MENU_TYPE_SUBMENU,
I18nService.getLocalizedString( CustomMenu.TYPE_SUBMENU, getLocale( ) ) );
}
/**
* Get the item type reference list
*
* @return the reference list
*/
private void initMenuItemTypeReferenceList( )
{
_listMenuItemTypes = new ReferenceList( );
_listMenuItemTypes.addItem( MENU_ITEM_TYPE_EMPTY,
I18nService.getLocalizedString( EMPTY_MENU_TYPE, getLocale( ) ) );
_listMenuItemTypes.addItem( MENU_ITEM_TYPE_XPAGE,
I18nService.getLocalizedString( CustomMenuItem.TYPE_XPAGE, getLocale( ) ) );
_listMenuItemTypes.addItem( MENU_ITEM_TYPE_PAGE,
I18nService.getLocalizedString( CustomMenuItem.TYPE_PAGE, getLocale( ) ) );
_listMenuItemTypes.addItem( MENU_ITEM_TYPE_EXTERNAL_URL,
I18nService.getLocalizedString( CustomMenuItem.TYPE_EXTERNAL_URL, getLocale( ) ) );
_listMenuItemTypes.addItem( MENU_ITEM_TYPE_MENU,
I18nService.getLocalizedString( CustomMenuItem.TYPE_MENU, getLocale( ) ) );
}
// ////////////////////////////////////////////
// ///////////////PAGINATORS AND TOOLS/////////
// ////////////////////////////////////////////
// /////////PAGINATOR FOR CUSTOM MENU//////////
@Override
List < Object > getItemsFromIds( List < Integer > listIds )
{
return getMenusListFromIds( listIds );
}
/**
* Get MenuList from a list ids of menu
*
* @param listIds
* list of Ids
* @return menu list
*/
private List < Object > getMenusListFromIds( List < Integer > listIds )
{
List < CustomMenu > listCustomMenus = CustomMenuHome.getMenusListByIds( listIds );
Map < String, String > mapMenuType = _listMenuTypes.toMap( );
// Set Type values according to message ressource file.
for( CustomMenu cm : listCustomMenus )
{
cm.setType( mapMenuType.containsKey( cm.getType( ) ) ? mapMenuType.get( cm.getType( ) ) : "" );
}
// keep original order
return listCustomMenus.stream( ).sorted( Comparator.comparingInt( menu -> listIds.indexOf( menu.getId( ) ) ) )
.collect( Collectors.toList( ) );
}
/**
* Reset Cache of Page Service Cache
*
*/
private void resetPagesCache( )
{
CacheableService cs = CacheService.getCacheableServicesList( ).get( ID_CACHE_PAGE_SERVICE_CACHE );
if( cs != null )
{
cs.resetCache( );
}
}
// ////////////////////////////////////////////////////////////////////////////////////
// Methods for native menu depth management
// ////////////////////////////////////////////////////////////////////////////////////
/**
* Action to modify native menu depth settings
*
* @param request The Http request
* @return The URL to go after performing the action
*/
@Action( ACTION_MODIFY_NATIVE_MENU_SETTINGS )
public String doModifyNativeMenuSettings( HttpServletRequest request )
{
String menuType = request.getParameter( PARAMETER_MENU_TYPE );
String propertyKey = getMenuProperty( menuType );
String depthValue = request.getParameter( PARAMETER_DEPTH_VALUE );
if( StringUtils.isNotBlank( propertyKey ) && StringUtils.isNotBlank( depthValue ) )
{
try
{
int depth = Integer.parseInt( depthValue );
int maxDepth = getMaxDepthForProperty( propertyKey );
if( depth >= 0 && depth <= maxDepth )
{
if( isAuthorizedPropertyKey( propertyKey ) )
{
DatastoreService.setDataValue( propertyKey, depthValue );
clearMenuCache( menuType );
resetPagesCache( );
addInfo( I18nService.getLocalizedString( MESSAGE_NATIVE_MENU_SETTINGS_UPDATE, getLocale( ) ) );
}
else
{
addError( I18nService.getLocalizedString( MESSAGE_ERROR_UNAUTHORIZED_PROPERTY, getLocale( ) ) );
}
}
else
{
addError( I18nService.getLocalizedString( MESSAGE_ERROR_INVALID_DEPTH, getLocale( ) ) + " (0-"
+ maxDepth + ")" );
}
}
catch( NumberFormatException e )
{
addError( I18nService.getLocalizedString( MESSAGE_ERROR_INVALID_NUMBER_FORMAT, getLocale( ) ) );
}
}
else
{
addError( I18nService.getLocalizedString( MESSAGE_ERROR_MISSING_PARAMETER, getLocale( ) ) );
}
return redirectView( request, VIEW_MANAGE_CUSTOM_MENUS );
}
/**
* Get depth options for select elements
*
* @param maxDepth maximum depth allowed
* @return ReferenceList with depth options
*/
private ReferenceList getDepthOptions( int maxDepth )
{
ReferenceList depthOptions = new ReferenceList( );
depthOptions.addItem( "0",
I18nService.getLocalizedString( "menus.manage_custom_menus.depth.empty", getLocale( ) ) );
for( int i = 1 ; i <= maxDepth ; i ++ )
{
depthOptions.addItem( String.valueOf( i ),
I18nService.getLocalizedString( "menus.manage_custom_menus.depth", getLocale( ) ) + ' ' + i );
}
return depthOptions;
}
/**
* Get current depth property value from datastore
*
* @param propertyKey the property key
* @param defaultValue the default value if property doesn't exist
* @return the property value
*/
private String getDepthPropertyValue( String propertyKey, String defaultValue )
{
String strDepth = DatastoreService.getDataValue( propertyKey, defaultValue );
// The depth must be between 0 and 1 for the main menu, and between 0 and 2 for
// the other menus
try
{
int nDepth = Integer.parseInt( strDepth );
int nDefaultValue = Integer.parseInt( defaultValue );
if( nDepth < 0 )
{
DatastoreService.setDataValue( propertyKey, "0" );
strDepth = "0";
}
if( nDepth > nDefaultValue )
{
DatastoreService.setDataValue( propertyKey, defaultValue );
strDepth = defaultValue;
}
}
catch( Exception e )
{
strDepth = defaultValue;
}
return strDepth;
}
/**
* Get property name associated to a menuType
*
* @param menuType
* @return the name property
*/
private String getMenuProperty( String menuType )
{
if( MENU_TYPE_MENU_MAIN.equals( menuType ) )
return PROPERTY_MENU_MAIN;
if( MENU_TYPE_MENU_TREE.equals( menuType ) )
return PROPERTY_MENU_TREE;
if( MENU_TYPE_MENU_TREE_ALL_PAGES.equals( menuType ) )
return PROPERTY_MENU_TREE_ALL_PAGES;
return "";
}
/**
* Check if property key is authorized for modification
*
* @param propertyKey the property key to check
* @return true if authorized, false otherwise
*/
private boolean isAuthorizedPropertyKey( String propertyKey )
{
return PROPERTY_MENU_MAIN.equals( propertyKey ) ||
PROPERTY_MENU_TREE.equals( propertyKey ) ||
PROPERTY_MENU_TREE_ALL_PAGES.equals( propertyKey );
}
/**
* Get maximum depth allowed for a specific property
*
* @param propertyKey the property key
* @return maximum depth allowed (1 for main menu, 2 for others)
*/
private int getMaxDepthForProperty( String propertyKey )
{
if( PROPERTY_MENU_MAIN.equals( propertyKey ) )
{
return 1;
}
else if( PROPERTY_MENU_TREE.equals( propertyKey ) ||
PROPERTY_MENU_TREE_ALL_PAGES.equals( propertyKey ) )
{
return 2;
}
return 0;
}
/**
* Clear menu cache based on menu type
*
* @param menuType the menu type
*/
private void clearMenuCache( String menuType )
{
if( MENU_TYPE_MENU_MAIN.equals( menuType ) )
{
MainTreeMenuService.getInstance( ).getCacheService( ).resetCache( );
}
else if( MENU_TYPE_MENU_TREE.equals( menuType ) )
{
MainTreeMenuService.getInstance( ).getCacheService( ).resetCache( );
}
else if( MENU_TYPE_MENU_TREE_ALL_PAGES.equals( menuType ) )
{
MainTreeMenuAllPagesService.getInstance( ).getCacheService( ).resetCache( );
}
}
}