MultiDirectoryJspBean.java
/*
* Copyright (c) 2002-2018, Mairie de 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.directory.modules.multiview.web;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import fr.paris.lutece.plugins.directory.modules.multiview.business.record.DirectoryRecordItem;
import fr.paris.lutece.plugins.directory.modules.multiview.business.record.DirectoryRecordItemComparator;
import fr.paris.lutece.plugins.directory.modules.multiview.business.record.DirectoryRecordItemComparatorConfig;
import fr.paris.lutece.plugins.directory.modules.multiview.business.record.column.IRecordColumn;
import fr.paris.lutece.plugins.directory.modules.multiview.business.record.column.RecordColumnFactory;
import fr.paris.lutece.plugins.directory.modules.multiview.business.record.filter.IRecordFilter;
import fr.paris.lutece.plugins.directory.modules.multiview.business.record.filter.RecordFilterFactory;
import fr.paris.lutece.plugins.directory.modules.multiview.business.record.panel.IRecordPanel;
import fr.paris.lutece.plugins.directory.modules.multiview.business.record.panel.RecordPanelFactory;
import fr.paris.lutece.plugins.directory.modules.multiview.service.IDirectoryMultiviewService;
import fr.paris.lutece.plugins.directory.modules.multiview.service.search.IDirectoryMultiviewSearchService;
import fr.paris.lutece.plugins.directory.modules.multiview.util.DirectoryMultiviewConstants;
import fr.paris.lutece.plugins.directory.modules.multiview.web.record.column.display.IRecordColumnDisplay;
import fr.paris.lutece.plugins.directory.modules.multiview.web.record.column.display.RecordColumnDisplayFactory;
import fr.paris.lutece.plugins.directory.modules.multiview.web.record.filter.display.IRecordFilterDisplay;
import fr.paris.lutece.plugins.directory.modules.multiview.web.record.filter.display.RecordFilterDisplayFactory;
import fr.paris.lutece.plugins.directory.modules.multiview.web.record.panel.display.IRecordPanelDisplay;
import fr.paris.lutece.plugins.directory.modules.multiview.web.record.panel.display.factory.RecordPanelDisplayFactory;
import fr.paris.lutece.plugins.directory.modules.multiview.web.record.util.RecordListPositionComparator;
import fr.paris.lutece.plugins.directory.modules.multiview.web.record.util.RecordListTemplateBuilder;
import fr.paris.lutece.plugins.directory.modules.multiview.web.record.util.RecordListUtil;
import fr.paris.lutece.portal.service.admin.AccessDeniedException;
import fr.paris.lutece.portal.service.spring.SpringContextService;
import fr.paris.lutece.portal.util.mvc.admin.annotations.Controller;
import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
import fr.paris.lutece.util.html.Paginator;
import fr.paris.lutece.util.url.UrlItem;
/**
* This class provides the user interface to manage form features ( manage, create, modify, remove)
*/
@Controller( controllerJsp = "ManageMultiDirectoryRecords.jsp", controllerPath = "jsp/admin/plugins/directory/modules/multiview/", right = "DIRECTORY_MULTIVIEW" )
public class MultiDirectoryJspBean extends AbstractJspBean
{
// Public properties
private static final String CONTROLLER_JSP_NAME = "ManageMultiDirectoryRecords.jsp";
/**
* Generated serial version UID
*/
private static final long serialVersionUID = -8417121042985481292L;
// Templates
private static final String TEMPLATE_MANAGE_MULTI_DIRECTORY_RECORD = "admin/plugins/directory/modules/multiview/manage_multi_directory_record.html";
// Properties
private static final String PROPERTY_MANAGE_DIRECTORY_RECORD_PAGE_TITLE = "module.directory.multiview.manage_directory_multirecord.pageTitle.label";
// Views
private static final String VIEW_MULTIVIEW = "view_multiview";
// Markers
private static final String MARK_LOCALE = "locale";
private static final String MARK_PAGINATOR = "paginator";
private static final String MARK_SEARCH_TEXT = "search_text";
private static final String MARK_RECORD_PANEL_LIST = "record_panel_list";
private static final String MARK_CURRENT_SELECTED_PANEL = "current_selected_panel";
private static final String MARK_RECORD_FILTER_LIST = "record_filter_list";
private static final String MARK_TABLE_TEMPLATE = "table_template";
// JSP URL
private static final String JSP_MANAGE_MULTIVIEW = "jsp/admin/plugins/directory/modules/multiview/ManageMultiDirectoryRecords.jsp";
// Parameters
private static final String PARAMETER_PAGE_INDEX = "page_index";
// Constants
private static final String BASE_SORT_URL_PATTERN = JSP_MANAGE_MULTIVIEW + "?current_selected_panel=%s";
// Session fields
private String _strSearchedText = StringUtils.EMPTY;
private String _strSelectedPanelTechnicalCode = StringUtils.EMPTY;
private transient List<IRecordColumn> _listRecordColumn;
private transient List<IRecordFilterDisplay> _listRecordFilterDisplay;
private transient List<IRecordColumnDisplay> _listRecordColumnDisplay;
private transient List<IRecordPanelDisplay> _listRecordPanelDisplay;
private transient IRecordPanelDisplay _recordPanelDisplayActive;
private transient DirectoryRecordItemComparatorConfig _directoryRecordItemComparatorConfig;
private final transient IDirectoryMultiviewService _directoryMultiviewService = SpringContextService.getBean( IDirectoryMultiviewService.BEAN_NAME );
private final transient IDirectoryMultiviewSearchService _directoryMultiviewSearchService = SpringContextService
.getBean( IDirectoryMultiviewSearchService.BEAN_NAME );
/**
* Return management of directory record ( list of directory record ).
*
* @param request
* The Http request
* @throws AccessDeniedException
* the {@link AccessDeniedException}
* @return IPluginActionResult
*/
@View( value = VIEW_MULTIVIEW, defaultView = true )
public String getManageDirectoryRecord( HttpServletRequest request ) throws AccessDeniedException
{
// Retrieve the list of all filters, columns and panels if the pagination and the sort are not used
boolean bIsSessionLost = isSessionLost( );
if ( isPaginationAndSortNotUsed( request ) || bIsSessionLost )
{
initRecordRelatedLists( request );
_strSearchedText = request.getParameter( DirectoryMultiviewConstants.PARAMETER_SEARCHED_TEXT );
manageSelectedPanel( );
}
// Build the Column for the Panel and save their values for the active panel
buildRecordPanelDisplayWithData( request );
// Sort the list of DirectoryRecordItem of the RecordPanel with the request information
sortDirectoryRecordItemList( request, _recordPanelDisplayActive.getDirectoryRecordItemList( ) );
// Build the template of each record filter display
if ( isPaginationAndSortNotUsed( request ) || bIsSessionLost )
{
_listRecordFilterDisplay.stream( ).forEach( recordFilterDisplay -> recordFilterDisplay.buildTemplate( request ) );
Collections.sort( _listRecordFilterDisplay, new RecordListPositionComparator( ) );
}
// Retrieve the list of all id of record of the active RecordListPanelDisplay
List<Integer> listIdRecord = RecordListUtil.getListIdRecordOfRecordPanel( _recordPanelDisplayActive );
// Build the model
Map<String, Object> model = getPaginatedListModel( request, Paginator.PARAMETER_PAGE_INDEX, listIdRecord, JSP_MANAGE_MULTIVIEW,
_strSelectedPanelTechnicalCode );
model.put( MARK_PAGINATOR, getPaginator( ) );
model.put( MARK_LOCALE, getLocale( ) );
model.put( MARK_SEARCH_TEXT, _strSearchedText );
model.put( MARK_RECORD_FILTER_LIST, _listRecordFilterDisplay );
// Add the template of column to the model
String strSortUrl = String.format( BASE_SORT_URL_PATTERN, _strSelectedPanelTechnicalCode );
String strRedirectionDetailsBaseUrl = buildRedirectionDetailsBaseUrl( );
List<DirectoryRecordItem> listDirectoryRecordItemToDisplay = buildDirectoryRecordItemListToDisplay( );
String strTableTemplate = RecordListTemplateBuilder.buildTableTemplate( _listRecordColumnDisplay, listDirectoryRecordItemToDisplay, getLocale( ),
strRedirectionDetailsBaseUrl, strSortUrl );
model.put( MARK_TABLE_TEMPLATE, strTableTemplate );
// Add the list of all record panel
model.put( MARK_RECORD_PANEL_LIST, _listRecordPanelDisplay );
model.put( MARK_CURRENT_SELECTED_PANEL, _strSelectedPanelTechnicalCode );
return getPage( PROPERTY_MANAGE_DIRECTORY_RECORD_PAGE_TITLE, TEMPLATE_MANAGE_MULTI_DIRECTORY_RECORD, model );
}
/**
* Return the boolean which tell if the pagination and the sort are not used
*
* @param request
* The request to retrieve the information from
* @return the boolean which tell if the pagination and the sort are not used
*/
private boolean isPaginationAndSortNotUsed( HttpServletRequest request )
{
return request.getParameter( PARAMETER_PAGE_INDEX ) == null
&& request.getParameter( DirectoryMultiviewConstants.PARAMETER_SORT_COLUMN_POSITION ) == null;
}
/**
* Return the boolean which tell if the session is lost
*
* @return the boolean which tell if the session is lost
*/
private boolean isSessionLost( )
{
return _listRecordColumn == null || _listRecordFilterDisplay == null || _listRecordColumnDisplay == null || _listRecordPanelDisplay == null
|| _recordPanelDisplayActive == null;
}
/**
* Build the list of all columns, filters and record panels and all of their display equivalents
*
* @param request
* The request used to build the list of the records elements
*/
private void initRecordRelatedLists( HttpServletRequest request )
{
List<IRecordFilter> listRecordFilter = new RecordFilterFactory( ).buildRecordFilterList( );
List<IRecordPanel> listRecordPanel = new RecordPanelFactory( ).buildRecordPanelList( );
RecordColumnFactory recordColumnFactory = SpringContextService.getBean( RecordColumnFactory.BEAN_NAME );
_listRecordColumn = recordColumnFactory.buildRecordColumnList( );
_listRecordFilterDisplay = new RecordFilterDisplayFactory( ).createRecordFilterDisplayList( request, listRecordFilter );
_listRecordColumnDisplay = new RecordColumnDisplayFactory( ).createRecordColumnDisplayList( _listRecordColumn );
_listRecordPanelDisplay = new RecordPanelDisplayFactory( ).createRecordPanelDisplayList( request, listRecordPanel );
}
/**
* Retrieve the technical code of the selected panel and change the value of the previous selected one if it wasn't the same and reset the pagination in
* this case
*/
private void manageSelectedPanel( )
{
IRecordPanelDisplay recordPanelDisplay = _directoryMultiviewService.findActiveRecordPanel( _listRecordPanelDisplay );
if ( recordPanelDisplay != null )
{
String strSelectedPanelTechnicalCode = recordPanelDisplay.getTechnicalCode( );
if ( StringUtils.isNotBlank( strSelectedPanelTechnicalCode ) && !_strSelectedPanelTechnicalCode.equals( strSelectedPanelTechnicalCode ) )
{
_strSelectedPanelTechnicalCode = strSelectedPanelTechnicalCode;
resetCurrentPaginatorPageIndex( );
}
}
}
/**
* Build all the record panels by building their template and retrieve the data of their columns for the given list of filter and the specified text to
* search
*/
private void buildRecordPanelDisplayWithData( HttpServletRequest request )
{
// Retrieve the list of all RecordFilter
List<IRecordFilter> listRecordFilter = _listRecordFilterDisplay.stream( ).map( IRecordFilterDisplay::getRecordFilter ).collect( Collectors.toList( ) );
for ( IRecordPanelDisplay recordPanelDisplay : _listRecordPanelDisplay )
{
// Retrieve the RecordPanel from the RecordPanelDisplay
IRecordPanel recordPanel = recordPanelDisplay.getRecordPanel( );
// Populate the RecordColumns from the information of the list of RecordFilterItem of the given RecordPanel
_directoryMultiviewService.populateRecordColumns( recordPanel, _listRecordColumn, listRecordFilter );
// Filter the record with RBAC on directory
_directoryMultiviewService.filterByAuthorizedDirectory( recordPanel, request );
if ( StringUtils.isNotBlank( _strSearchedText ) )
{
_directoryMultiviewSearchService.filterBySearchedText( recordPanel, _strSearchedText );
}
// Associate for each RecordColumnDisplay its RecordColumnValues if the panel is active
if ( recordPanelDisplay.isActive( ) )
{
_recordPanelDisplayActive = recordPanelDisplay;
}
// Build the template of the record list panel
recordPanelDisplay.buildTemplate( getLocale( ) );
}
}
/**
* Build the list of DirectoryRecordItem to display for the given IRecordFilterPanelDisplay based on the number of items of the current paginator
*
* @return list of DirectoryRecordItem to display for the given IRecordFilterPanelDisplay
*/
private List<DirectoryRecordItem> buildDirectoryRecordItemListToDisplay( )
{
List<DirectoryRecordItem> listDirectoryRecordItemToDisplay = new ArrayList<>( );
List<Integer> listIdRecordPaginated = getPaginator( ).getPageItems( );
List<DirectoryRecordItem> listDirectoryRecordItem = _recordPanelDisplayActive.getDirectoryRecordItemList( );
if ( listIdRecordPaginated != null && !listIdRecordPaginated.isEmpty( ) && listDirectoryRecordItem != null && !listDirectoryRecordItem.isEmpty( ) )
{
for ( DirectoryRecordItem directoryRecordItem : listDirectoryRecordItem )
{
Integer nIdRecord = directoryRecordItem.getIdRecord( );
if ( listIdRecordPaginated.contains( nIdRecord ) )
{
listDirectoryRecordItemToDisplay.add( directoryRecordItem );
}
}
}
return listDirectoryRecordItemToDisplay;
}
/**
* Sort the given list of DirectoryRecordItem from the values contains in the request
*
* @param request
* The request to retrieve the values used for the sort
* @param listDirectoryRecordItem
* The list of DirectoryRecordItem to sort
*/
private void sortDirectoryRecordItemList( HttpServletRequest request, List<DirectoryRecordItem> listDirectoryRecordItem )
{
if ( request.getParameter( DirectoryMultiviewConstants.PARAMETER_SORT_COLUMN_POSITION ) != null )
{
buildDirectoryRecordItemComparatorConfiguration( request );
}
if ( listDirectoryRecordItem != null && !listDirectoryRecordItem.isEmpty( ) )
{
DirectoryRecordItemComparator directoryRecordItemComparator = new DirectoryRecordItemComparator( _directoryRecordItemComparatorConfig );
Collections.sort( listDirectoryRecordItem, directoryRecordItemComparator );
}
}
/**
* Build the configuration to use for sort the DirectoryRecordItem with the information from the request
*
* @param request
* The request to retrieve the values for the sort from
*/
private void buildDirectoryRecordItemComparatorConfiguration( HttpServletRequest request )
{
String strColumnToSortPosition = request.getParameter( DirectoryMultiviewConstants.PARAMETER_SORT_COLUMN_POSITION );
int nColumnToSortPosition = NumberUtils.toInt( strColumnToSortPosition, NumberUtils.INTEGER_MINUS_ONE );
String strSortKey = request.getParameter( DirectoryMultiviewConstants.PARAMETER_SORT_ATTRIBUTE_NAME );
String strAscSort = request.getParameter( DirectoryMultiviewConstants.PARAMETER_SORT_ASC_VALUE );
boolean bAscSort = Boolean.parseBoolean( strAscSort );
_directoryRecordItemComparatorConfig = new DirectoryRecordItemComparatorConfig( nColumnToSortPosition, strSortKey, bAscSort );
}
/**
* Build the base url to use for redirect to the page of the details of a record
*
* @return the base url to use for redirect to the details page of a record
*/
private String buildRedirectionDetailsBaseUrl( )
{
UrlItem urlRedirectionDetails = new UrlItem( MultiviewRecordDetailsJspBean.getMultiviewRecordDetailsBaseUrl( ) );
if ( !CollectionUtils.isEmpty( _listRecordFilterDisplay ) )
{
for ( IRecordFilterDisplay recordFilterDisplay : _listRecordFilterDisplay )
{
// Add all the filters values
String strFilterValue = recordFilterDisplay.getValue( );
if ( !StringUtils.isEmpty( strFilterValue ) )
{
String strFilterFullName = DirectoryMultiviewConstants.PARAMETER_URL_FILTER_PREFIX + recordFilterDisplay.getParameterName( );
urlRedirectionDetails.addParameter( strFilterFullName, strFilterValue );
}
}
}
// Add the search text
if ( !StringUtils.isEmpty( _strSearchedText ) )
{
urlRedirectionDetails.addParameter( DirectoryMultiviewConstants.PARAMETER_SEARCHED_TEXT, _strSearchedText );
}
// Add the selected panel technical code
urlRedirectionDetails.addParameter( DirectoryMultiviewConstants.PARAMETER_SELECTED_PANEL, _strSelectedPanelTechnicalCode );
// Add sort filter data to the url
addFilterSortConfigToUrl( urlRedirectionDetails );
return urlRedirectionDetails.getUrl( );
}
/**
* Add the information for rebuild the used sort
*
* @param urlRedirectionDetails
* The UrlItem which represent the url to use for redirect to the records details page
*/
private void addFilterSortConfigToUrl( UrlItem urlRedirectionDetails )
{
if ( _directoryRecordItemComparatorConfig != null )
{
String strSortPosition = Integer.toString( _directoryRecordItemComparatorConfig.getColumnToSortPosition( ) );
String strAttributeName = _directoryRecordItemComparatorConfig.getSortAttributeName( );
String strAscSort = String.valueOf( _directoryRecordItemComparatorConfig.isAscSort( ) );
urlRedirectionDetails.addParameter( DirectoryMultiviewConstants.PARAMETER_SORT_COLUMN_POSITION, strSortPosition );
urlRedirectionDetails.addParameter( DirectoryMultiviewConstants.PARAMETER_SORT_ATTRIBUTE_NAME, strAttributeName );
urlRedirectionDetails.addParameter( DirectoryMultiviewConstants.PARAMETER_SORT_ASC_VALUE, strAscSort );
}
}
/**
* Return the base url of the controller for the view which display the list of records
*
* @return the base url of the controller for the view which display the list of records
*/
protected static String getMultiviewBaseViewUrl( )
{
return CONTROLLER_JSP_NAME + "?view=" + VIEW_MULTIVIEW;
}
}