DashboardService.java
- /*
- * Copyright (c) 2002-2022, 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.portal.service.dashboard;
- import fr.paris.lutece.portal.business.dashboard.DashboardFactory;
- import fr.paris.lutece.portal.business.dashboard.DashboardFilter;
- import fr.paris.lutece.portal.business.dashboard.DashboardHome;
- import fr.paris.lutece.portal.business.user.AdminUser;
- import fr.paris.lutece.portal.service.plugin.Plugin;
- import fr.paris.lutece.portal.service.spring.SpringContextService;
- import fr.paris.lutece.portal.service.util.AppLogService;
- import fr.paris.lutece.portal.service.util.AppPropertiesService;
- import fr.paris.lutece.util.ReferenceList;
- import fr.paris.lutece.util.sort.AttributeComparator;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.commons.collections.CollectionUtils;
- /**
- * Dashboard Service
- */
- public final class DashboardService
- {
- // Properties
- private static final String PROPERTY_COLUMN_COUNT = "dashboard.columnCount";
- // Constants
- private static final String ALL = "ALL";
- private static final String EMPTY_STRING = "";
- private static final String ORDER = "order";
- private static final int CONSTANTE_FIRST_ORDER = 1;
- private static final int CONSTANTE_DEFAULT_COLUMN_COUNT = 3;
- private static DashboardService _singleton = new DashboardService( );
- /**
- * Private Constructor
- */
- private DashboardService( )
- {
- }
- /**
- * Return the unique instance
- *
- * @return The instance
- */
- public static DashboardService getInstance( )
- {
- return _singleton;
- }
- /**
- * Returns the column count, with {@link DashboardService#PROPERTY_COLUMN_COUNT}. Default is {@link DashboardService#CONSTANTE_DEFAULT_COLUMN_COUNT}
- *
- * @return the column count
- */
- public int getColumnCount( )
- {
- return AppPropertiesService.getPropertyInt( PROPERTY_COLUMN_COUNT, CONSTANTE_DEFAULT_COLUMN_COUNT );
- }
- /**
- * All known dashboards as declared in SpringContext
- *
- * @return dashboards list
- */
- public List<IDashboardComponent> getAllDashboardComponents( )
- {
- return DashboardFactory.getAllDashboardComponents( );
- }
- /**
- *
- * @param nColumn
- * the column id
- * @return all dashboards for this column
- */
- public List<IDashboardComponent> getDashboardComponents( int nColumn )
- {
- DashboardFilter filter = new DashboardFilter( );
- filter.setFilterColumn( nColumn );
- return DashboardHome.findByFilter( filter );
- }
- /**
- * Register a Dashboard Component
- *
- * @param entry
- * The DashboardComponent entry defined in the plugin's XML file
- * @param plugin
- * The plugin
- */
- public void registerDashboardComponent( DashboardComponentEntry entry, Plugin plugin )
- {
- try
- {
- DashboardComponent dc = (DashboardComponent) Class.forName( entry.getComponentClass( ) ).newInstance( );
- dc.setName( entry.getName( ) );
- dc.setRight( entry.getRight( ) );
- dc.setPlugin( plugin );
- boolean bRegistered = DashboardFactory.registerDashboardComponent( dc );
- if ( bRegistered )
- {
- AppLogService.info( "New Dashboard Component registered : " + entry.getName( ) );
- }
- else
- {
- AppLogService.error( " Dashboard Component not registered : " + entry.getName( ) + " : " + entry.getComponentClass( ) );
- }
- }
- catch( ClassNotFoundException | IllegalAccessException | InstantiationException e )
- {
- AppLogService.error( "Error registering a DashboardComponent : " + e.getMessage( ), e );
- }
- }
- /**
- * Moves the dashboard.
- *
- * @param dashboard
- * to move, with new values
- * @param nOldColumn
- * previous column id
- * @param nOldOrder
- * previous order
- * @param bCreate
- * <code>true</code> if this is a new dashboard, <code>false</code> otherwise.
- */
- public void doMoveDashboard( IDashboardComponent dashboard, int nOldColumn, int nOldOrder, boolean bCreate )
- {
- int nColumn = dashboard.getZone( );
- int nOrder = dashboard.getOrder( );
- // find the dashboard already with this order and column
- DashboardFilter filter = new DashboardFilter( );
- filter.setFilterColumn( nColumn );
- List<IDashboardComponent> listColumnDashboards = DashboardHome.findByFilter( filter );
- if ( CollectionUtils.isNotEmpty( listColumnDashboards ) )
- {
- if ( AppLogService.isDebugEnabled( ) )
- {
- AppLogService.debug( "Reordering dashboard column " + dashboard.getZone( ) );
- }
- // sort by order
- Collections.sort( listColumnDashboards );
- int nMaxOrder = listColumnDashboards.get( listColumnDashboards.size( ) - 1 ).getOrder( );
- if ( ( nOldColumn == 0 ) || ( nOldColumn != nColumn ) )
- {
- // was not in this column before, put to the end
- dashboard.setOrder( nMaxOrder + 1 );
- }
- else
- {
- updateDashboardComponents( dashboard, listColumnDashboards, nOldOrder );
- // dashboard are singletons, values are modified by getting it from database
- dashboard.setOrder( nOrder );
- dashboard.setZone( nColumn );
- }
- }
- else
- {
- dashboard.setOrder( 1 );
- }
- if ( bCreate )
- {
- // create dashboard
- DashboardHome.create( dashboard );
- }
- else
- {
- // update dashboard
- DashboardHome.update( dashboard );
- }
- }
- private void updateDashboardComponents( IDashboardComponent dashboard, List<IDashboardComponent> listColumnDashboards, int nOldOrder )
- {
- int nOrder = dashboard.getOrder( );
- for ( IDashboardComponent dc : listColumnDashboards )
- {
- if ( dc.equals( dashboard ) )
- {
- continue;
- }
- if ( nOrder < nOldOrder )
- {
- int nCurrentOrder = dc.getOrder( );
- if ( ( nCurrentOrder >= nOrder ) && ( nCurrentOrder < nOldOrder ) )
- {
- dc.setOrder( nCurrentOrder + 1 );
- DashboardHome.update( dc );
- }
- }
- else
- if ( nOrder > nOldOrder )
- {
- int nCurrentOrder = dc.getOrder( );
- if ( ( nCurrentOrder <= nOrder ) && ( nCurrentOrder > nOldOrder ) )
- {
- dc.setOrder( nCurrentOrder - 1 );
- DashboardHome.update( dc );
- }
- }
- }
- }
- /**
- * Returns all dashboards with no column/order set
- *
- * @return all dashboards with no column/order set
- */
- public List<IDashboardComponent> getNotSetDashboards( )
- {
- List<IDashboardComponent> listDashboards = DashboardHome.findAll( );
- List<IDashboardComponent> listSpringDashboards = getAllDashboardComponents( );
- List<IDashboardComponent> listUnsetDashboards = new ArrayList<>( );
- for ( IDashboardComponent dashboard : listSpringDashboards )
- {
- if ( !listDashboards.contains( dashboard ) )
- {
- listUnsetDashboards.add( dashboard );
- }
- }
- return listUnsetDashboards;
- }
- /**
- * Finds all dashboard with column and order set.
- *
- * @param user
- * the current user
- * @return a map where key is the column id, and value is the column's dashboard list.
- */
- public Map<String, List<IDashboardComponent>> getAllSetDashboards( AdminUser user )
- {
- Map<String, List<IDashboardComponent>> mapDashboardComponents = new HashMap<>( );
- List<IDashboardComponent> listDashboards = DashboardHome.findAll( );
- for ( IDashboardComponent dashboard : listDashboards )
- {
- int nColumn = dashboard.getZone( );
- boolean bRight = user.checkRight( dashboard.getRight( ) ) || dashboard.getRight( ).equalsIgnoreCase( ALL );
- if ( !bRight )
- {
- continue;
- }
- String strColumn = Integer.toString( nColumn );
- // find this column list
- List<IDashboardComponent> listDashboardsColumn = mapDashboardComponents.computeIfAbsent( strColumn, s -> new ArrayList<>( ) );
- // add dashboard to the list
- listDashboardsColumn.add( dashboard );
- }
- return mapDashboardComponents;
- }
- /**
- * Gets Data from all components of the zone
- *
- * @param user
- * The user
- * @param nZone
- * The dasboard zone
- * @param request
- * HttpServletRequest
- * @return Data of all components of the zone
- */
- public String getDashboardData( AdminUser user, int nZone, HttpServletRequest request )
- {
- StringBuilder sbDashboardData = new StringBuilder( );
- for ( IDashboardComponent dc : getDashboardComponents( nZone ) )
- {
- boolean bRight = user.checkRight( dc.getRight( ) ) || dc.getRight( ).equalsIgnoreCase( ALL );
- if ( ( dc.getZone( ) == nZone ) && dc.isEnabled( ) && bRight )
- {
- sbDashboardData.append( dc.getDashboardData( user, request ) );
- }
- }
- return sbDashboardData.toString( );
- }
- /**
- * Get the list of dashboard from plugins
- *
- * @param user
- * the current user
- * @param request
- * HttpServletRequest
- * @return the list of dashboards
- */
- public List<IDashboardComponent> getDashboards( AdminUser user, HttpServletRequest request )
- {
- List<IDashboardComponent> listDashboards = new ArrayList<>( );
- // Attributes associated to the plugins
- for ( DashboardListenerService dashboardListenerService : SpringContextService.getBeansOfType( DashboardListenerService.class ) )
- {
- dashboardListenerService.getDashboardComponents( listDashboards, user, request );
- }
- return listDashboards;
- }
- /**
- * Gets Data from all components of the zone
- *
- * @param listDashboards
- * the list of dashboards
- * @param user
- * The user
- * @param nZone
- * The dasboard zone
- * @param request
- * HttpServletRequest
- * @return Data of all components of the zone
- */
- public String getDashboardData( List<IDashboardComponent> listDashboards, AdminUser user, int nZone, HttpServletRequest request )
- {
- List<IDashboardComponent> listDashboardComponents = new ArrayList<>( );
- for ( IDashboardComponent dc : listDashboards )
- {
- if ( dc.getZone( ) == nZone )
- {
- listDashboardComponents.add( dc );
- }
- }
- Collections.sort( listDashboardComponents, new AttributeComparator( ORDER, true ) );
- StringBuilder sbDashboardData = new StringBuilder( );
- for ( IDashboardComponent dc : listDashboardComponents )
- {
- boolean bRight = user.checkRight( dc.getRight( ) ) || dc.getRight( ).equalsIgnoreCase( ALL );
- if ( ( dc.getZone( ) == nZone ) && dc.isEnabled( ) && bRight )
- {
- sbDashboardData.append( dc.getDashboardData( user, request ) );
- }
- }
- return sbDashboardData.toString( );
- }
- /**
- * Reorders column's dashboard
- *
- * @param nColumn
- * the column to reorder
- */
- public void doReorderColumn( int nColumn )
- {
- int nOrder = CONSTANTE_FIRST_ORDER;
- for ( IDashboardComponent dc : getDashboardComponents( nColumn ) )
- {
- dc.setOrder( nOrder++ );
- DashboardHome.update( dc );
- }
- }
- /**
- * Builds the map to with column id as key, and <code>true</code> as value if column is well ordered, <code>false</code> otherwise.
- *
- * @return the map
- */
- public Map<String, Boolean> getOrderedColumnsStatus( )
- {
- Map<String, Boolean> mapOrderedStatus = new HashMap<>( );
- List<Integer> listColumns = DashboardHome.findColumns( );
- for ( Integer nIdColumn : listColumns )
- {
- mapOrderedStatus.put( nIdColumn.toString( ), isWellOrdered( nIdColumn ) );
- }
- return mapOrderedStatus;
- }
- /**
- * Determines if the column is well ordered
- *
- * @param nColumn
- * the column id
- * @return true if well ordered, <code>false</code> otherwise.
- */
- private boolean isWellOrdered( int nColumn )
- {
- int nOrder = CONSTANTE_FIRST_ORDER;
- for ( IDashboardComponent dc : getDashboardComponents( nColumn ) )
- {
- if ( nOrder != dc.getOrder( ) )
- {
- return false;
- }
- nOrder++;
- }
- return true;
- }
- /**
- * Returns list with available column
- *
- * @return all available columns
- */
- public ReferenceList getListAvailableColumns( )
- {
- ReferenceList refList = new ReferenceList( );
- // add empty item
- refList.addItem( EMPTY_STRING, EMPTY_STRING );
- for ( int nColumnIndex = 1; nColumnIndex <= getColumnCount( ); nColumnIndex++ )
- {
- refList.addItem( nColumnIndex, Integer.toString( nColumnIndex ) );
- }
- return refList;
- }
- /**
- * Builds all refList order for all columns
- *
- * @return the map with column id as key
- */
- public Map<String, ReferenceList> getMapAvailableOrders( )
- {
- Map<String, ReferenceList> mapAvailableOrders = new HashMap<>( );
- // get columns
- for ( Integer nColumn : DashboardHome.findColumns( ) )
- {
- // get orders
- mapAvailableOrders.put( nColumn.toString( ), getListAvailableOrders( nColumn ) );
- }
- return mapAvailableOrders;
- }
- /**
- * Orders reference list for the given column
- *
- * @param nColumn
- * column
- * @return the refList
- */
- public ReferenceList getListAvailableOrders( int nColumn )
- {
- ReferenceList refList = new ReferenceList( );
- // add empty item
- refList.addItem( EMPTY_STRING, EMPTY_STRING );
- int nMaxOrder = DashboardHome.findMaxOrder( nColumn );
- for ( int nOrder = 1; nOrder <= nMaxOrder; nOrder++ )
- {
- refList.addItem( nOrder, Integer.toString( nOrder ) );
- }
- return refList;
- }
- }