PublishingService.java
/*
* Copyright (c) 2002-2023, 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.document.service.publishing;
import fr.paris.lutece.plugins.document.business.Document;
import fr.paris.lutece.plugins.document.business.DocumentFilter;
import fr.paris.lutece.plugins.document.business.DocumentHome;
import fr.paris.lutece.plugins.document.business.IndexerAction;
import fr.paris.lutece.plugins.document.business.publication.DocumentPublication;
import fr.paris.lutece.plugins.document.business.publication.DocumentPublicationHome;
import fr.paris.lutece.plugins.document.service.DocumentPlugin;
import fr.paris.lutece.plugins.document.service.search.DocumentIndexer;
import fr.paris.lutece.plugins.document.utils.DocumentIndexerUtils;
import fr.paris.lutece.plugins.document.utils.IntegerUtils;
import fr.paris.lutece.portal.business.portlet.Portlet;
import fr.paris.lutece.portal.business.portlet.PortletHome;
import fr.paris.lutece.portal.business.portlet.PortletType;
import fr.paris.lutece.portal.service.plugin.Plugin;
import fr.paris.lutece.portal.service.plugin.PluginService;
import fr.paris.lutece.portal.service.search.IndexationService;
import fr.paris.lutece.portal.service.spring.SpringContextService;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Locale;
/**
* Publishing service
*/
public class PublishingService
{
private static PublishingService _singleton = new PublishingService( );
private static PublishingEventListenersManager _manager;
/** Creates a new instance of PublishingService */
private PublishingService( )
{
_manager = SpringContextService.getBean( "document.publishingEventListenersManager" );
}
/**
* Get the unique instance of the service
* @return The unique instance
*/
public static PublishingService getInstance( )
{
return _singleton;
}
/**
* Assign {@link Document} to a {@link Portlet}
*
* @param nDocumentId The {@link Document} identifier
* @param nPortletId The {@link Portlet} identifier
*/
public void assign( int nDocumentId, int nPortletId )
{
DocumentPublication documentPublication = new DocumentPublication( );
documentPublication.setPortletId( nPortletId );
documentPublication.setDocumentId( nDocumentId );
documentPublication.setStatus( DocumentPublication.STATUS_UNPUBLISHED );
//FIXME LUTECE-577 : before refactoring, status value was set to null
documentPublication.setDocumentOrder( DocumentPublication.DOCUMENT_ORDER_DEFAULT_VALUE );
documentPublication.setDatePublishing( new Date( ) );
DocumentPublicationHome.create( documentPublication );
}
/**
* Publishing documents assigned to a portlet at the begin of the list
*
* @param nDocumentId the Document id
* @param nPortletId the portlet identifier
*/
public void publish( int nDocumentId, int nPortletId )
{
// Publishing of document : set status to Published
DocumentPublication documentPublication = DocumentPublicationHome.findByPrimaryKey( nPortletId, nDocumentId );
if ( documentPublication != null )
{
documentPublication.setStatus( DocumentPublication.STATUS_PUBLISHED );
documentPublication.setDatePublishing( new Date( ) );
documentPublication.setDocumentOrder( getInstance( ).getMaxDocumentOrderByPortletId( nPortletId ) + 1 );
DocumentPublicationHome.update( documentPublication );
PublishingEvent event = new PublishingEvent( nDocumentId, nPortletId, PublishingEvent.DOCUMENT_PUBLISHED );
_manager.notifyListeners( event );
getInstance( )
.changeDocumentOrder( documentPublication.getDocumentId( ), documentPublication.getPortletId( ), 1 );
}
String strIdDocument = Integer.toString( nDocumentId );
IndexationService.addIndexerAction( strIdDocument, DocumentIndexer.INDEXER_NAME, IndexerAction.TASK_MODIFY,
nPortletId );
DocumentIndexerUtils.addIndexerAction( strIdDocument, IndexerAction.TASK_MODIFY, nPortletId );
}
/**
* UnPublishing documents assigned to a portlet
*
* @param nDocumentId the DocumentListPortlet identifier
* @param nPortletId the portlet identifier
*/
public void unPublish( int nDocumentId, int nPortletId )
{
// Publishing of document : set status to Unpublished
DocumentPublication documentPublication = DocumentPublicationHome.findByPrimaryKey( nPortletId, nDocumentId );
// Move the document at the end of the list
int nNewOrder = getInstance( ).getMaxDocumentOrderByPortletId( nPortletId );
getInstance( ).changeDocumentOrder( nDocumentId, nPortletId, nNewOrder );
if ( documentPublication != null )
{
documentPublication.setStatus( DocumentPublication.STATUS_UNPUBLISHED );
//FIXME LUTECE-577 : before refactoring, documentOrder value was set to null
documentPublication.setDocumentOrder( DocumentPublication.DOCUMENT_ORDER_DEFAULT_VALUE );
DocumentPublicationHome.update( documentPublication );
PublishingEvent event = new PublishingEvent( nDocumentId, nPortletId, PublishingEvent.DOCUMENT_UNPUBLISHED );
_manager.notifyListeners( event );
}
String strIdDocument = Integer.toString( nDocumentId );
IndexationService.addIndexerAction( strIdDocument + "_" + DocumentIndexer.SHORT_NAME,
DocumentIndexer.INDEXER_NAME, IndexerAction.TASK_DELETE, nPortletId );
DocumentIndexerUtils.addIndexerAction( strIdDocument, IndexerAction.TASK_DELETE, nPortletId );
}
/**
* unAssign {@link Document} to a {@link Portlet}
*
* @param nDocumentId The {@link Document} identifier
* @param nPortletId The {@link Portlet} identifier
*/
public void unAssign( int nDocumentId, int nPortletId )
{
DocumentPublicationHome.remove( nPortletId, nDocumentId );
}
/**
* Change the {@link Document} order in a {@link Portlet}
*
* @param nDocumentId the {@link Document} identifier
* @param nPortletId the {@link Portlet} identifier
* @param nNewOrder The new place in the list
*/
public void changeDocumentOrder( int nDocumentId, int nPortletId, int nNewOrder )
{
DocumentPublication documentPublication = DocumentPublicationHome.findByPrimaryKey( nPortletId, nDocumentId );
if ( documentPublication == null )
{
return;
}
Collection<DocumentPublication> listDocumentPublication = DocumentPublicationHome.findByPortletIdAndStatus( nPortletId,
DocumentPublication.STATUS_PUBLISHED );
if ( nNewOrder < documentPublication.getDocumentOrder( ) )
{
for ( DocumentPublication documentPublicationToUpdate : listDocumentPublication )
{
int nDocumentToUpdateOrder = documentPublicationToUpdate.getDocumentOrder( );
if ( ( nDocumentToUpdateOrder >= nNewOrder ) &&
( nDocumentToUpdateOrder < documentPublication.getDocumentOrder( ) ) )
{
documentPublicationToUpdate.setDocumentOrder( nDocumentToUpdateOrder + 1 );
DocumentPublicationHome.update( documentPublicationToUpdate );
}
}
}
else if ( nNewOrder > documentPublication.getDocumentOrder( ) )
{
for ( DocumentPublication documentPublicationToUpdate : listDocumentPublication )
{
int nDocumentToUpdateOrder = documentPublicationToUpdate.getDocumentOrder( );
if ( ( nDocumentToUpdateOrder <= nNewOrder ) &&
( nDocumentToUpdateOrder > documentPublication.getDocumentOrder( ) ) )
{
documentPublicationToUpdate.setDocumentOrder( nDocumentToUpdateOrder - 1 );
DocumentPublicationHome.update( documentPublicationToUpdate );
}
}
}
documentPublication.setDocumentOrder( nNewOrder );
DocumentPublicationHome.update( documentPublication );
}
/**
* Check if the specified {@link Document} is published into the specified {@link Portlet}
* @param nDocumentId The {@link Document} identifier
* @param nPortletId The {@link Portlet} identifier
* @return True if {@link Document} is published, false else (unpublished or not assigned)
*/
public boolean isPublished( int nDocumentId, int nPortletId )
{
DocumentPublication documentPublication = DocumentPublicationHome.findByPrimaryKey( nPortletId, nDocumentId );
return ( documentPublication != null ) &&
( documentPublication.getStatus( ) == DocumentPublication.STATUS_PUBLISHED );
}
/**
* Check if the specified {@link Document} is published into the specified {@link Portlet}
* @param nDocumentId The {@link Document} identifier
* @return True if {@link Document} is published, false else (unpublished or not assigned)
*/
public boolean isPublished( int nDocumentId )
{
Collection<DocumentPublication> listDocumentPublication = DocumentPublicationHome.findByDocumentIdAndStatus( nDocumentId,
DocumentPublication.STATUS_PUBLISHED );
return ( ( listDocumentPublication.size( ) > 0 ) );
}
/**
* Check if the specified {@link Document} is assigned (unpublished or published) into at least one {@link Portlet}
* @param nDocumentId The {@link Document} identifier
* @return True if {@link Document} is assigned (published or unpublished), false else (not assigned)
*/
public boolean isAssigned( int nDocumentId )
{
Collection<DocumentPublication> listDocumentPublication = DocumentPublicationHome.findByDocumentId( nDocumentId );
return ( listDocumentPublication.size( ) > 0 );
}
/**
* Check if the specified {@link Document} is assigned (unpublished or published) into the specified {@link Portlet}
* @param nDocumentId The {@link Document} identifier
* @param nPortletId The {@link Portlet} identifier
* @return True if {@link Document} is assigned (published or unpublished), false else (not assigned)
*/
public boolean isAssigned( int nDocumentId, int nPortletId )
{
DocumentPublication documentPublication = DocumentPublicationHome.findByPrimaryKey( nPortletId, nDocumentId );
return ( documentPublication != null );
}
/**
* Return a {@link DocumentPublication} from a {@link Portlet} identifier and {@link Document} identifier
* @param nPortletId the {@link Portlet} identifier
* @param nDocumentId the {@link Document} identifier
* @return a {@link DocumentPublication} or null if no object match
*/
public DocumentPublication getDocumentPublication( int nPortletId, int nDocumentId )
{
return DocumentPublicationHome.findByPrimaryKey( nPortletId, nDocumentId );
}
/**
* Returns a {@link Collection} of {@link Document} objects from a {@link Portlet} identifier
* {@link Document} can be assigned or published.
* @param nPortletId the {@link Portlet} identifier
* @return a {@link Collection} of {@link Document} objects
*/
public Collection<Document> getAssignedDocumentsByPortletId( int nPortletId )
{
Collection<DocumentPublication> listDocumentPublications = DocumentPublicationHome.findByPortletId( nPortletId );
Collection<Document> listDocuments = new ArrayList<Document>( );
for ( DocumentPublication documentPublication : listDocumentPublications )
{
//FIXME LUTECE-577 : use a single call to DocumentHome, but be careful to the list order !
listDocuments.add( DocumentHome.findByPrimaryKeyWithoutBinaries( documentPublication.getDocumentId( ) ) );
}
//FIXME LUTECE-577 : the list was order by document_order ASC
return listDocuments;
}
/**
* Loads the list of the documents whose type is the same as the one specified in parameter
* Return published documents from a specified portlet
*
* @param nPortletId the portlet identifier
* @return the list of the document in form of a List
*/
public Collection<Document> getPublishedDocumentsByPortletId( int nPortletId )
{
Collection<DocumentPublication> listDocumentPublication = DocumentPublicationHome.findByPortletIdAndStatus( nPortletId,
DocumentPublication.STATUS_PUBLISHED );
Collection<Document> listDocuments = new ArrayList<Document>( );
for ( DocumentPublication documentPublication : listDocumentPublication )
{
listDocuments.add( DocumentHome.findByPrimaryKeyWithoutBinaries( documentPublication.getDocumentId( ) ) );
}
return listDocuments;
}
/**
* Get the first valid document published in a portlet or null if there are none
* @param nPortletId the portlet identifier
* @return The document
*/
public Document getFirstValidPublishedDocument( int nPortletId )
{
Collection<DocumentPublication> listDocumentPublication = DocumentPublicationHome.findByPortletIdAndStatus( nPortletId,
DocumentPublication.STATUS_PUBLISHED );
for ( DocumentPublication documentPublication : listDocumentPublication )
{
Document document = DocumentHome.findByPrimaryKeyWithoutBinaries( documentPublication.getDocumentId( ) );
if ( document.isValid( ) )
{
return document;
}
}
return null;
}
/**
* Loads the list of the documents whose filter and date publication is specified
* Return published documents since the publication date. The is also filtered with the documentFilter
*
* @param datePublishing The start publication date
* @param documentFilter The filter for the published documents. The filter can be null or empty. The array of Ids will not be taked in account.
* @param locale The locale is used to get the list of documents with the findByFilter method
* @return the list of the document in form of a List. return null if datePublishing is null
*/
public Collection<Document> getPublishedDocumentsSinceDate( Date datePublishing, DocumentFilter documentFilter,
Locale locale )
{
if ( datePublishing == null )
{
return null;
}
Collection<DocumentPublication> listDocumentPublication = DocumentPublicationHome.findSinceDatePublishingAndStatus( datePublishing,
DocumentPublication.STATUS_PUBLISHED );
if ( ( listDocumentPublication == null ) || ( listDocumentPublication.size( ) == 0 ) )
{
return new ArrayList<Document>( );
}
int[] arrayIds = new int[listDocumentPublication.size( )];
int i = 0;
DocumentFilter publishedDocumentFilter = documentFilter;
if ( publishedDocumentFilter == null )
{
publishedDocumentFilter = new DocumentFilter( );
}
for ( DocumentPublication documentPublication : listDocumentPublication )
{
arrayIds[i++] = documentPublication.getDocumentId( );
}
publishedDocumentFilter.setIds( arrayIds );
Collection<Document> listDocuments = DocumentHome.findByFilter( publishedDocumentFilter, locale );
return listDocuments;
}
/**
* Loads the list of the portlets whoes contain Document specified by id
*
* @param strDocumentId the document identifier
* @return the {@link Collection} of the portlets
*/
public Collection<Portlet> getPortletsByDocumentId( String strDocumentId )
{
Collection<DocumentPublication> listDocumentPublication = DocumentPublicationHome.findByDocumentId( IntegerUtils.convert(
strDocumentId ) );
Collection<Portlet> listPortlets = new ArrayList<Portlet>( );
for ( DocumentPublication documentPublication : listDocumentPublication )
{
listPortlets.add( PortletHome.findByPrimaryKey( documentPublication.getPortletId( ) ) );
}
return listPortlets;
}
/**
* Loads the list of portlets who contain published documents
*
* @return the {@link Collection} of the portlets
*/
public Collection<Portlet> getPublishedPortlets( )
{
Plugin plugin = PluginService.getPlugin( DocumentPlugin.PLUGIN_NAME );
Collection<Portlet> listPortletsAll = new ArrayList<Portlet>( );
Collection<Portlet> listPortlets = new ArrayList<Portlet>( );
for ( PortletType portletType : plugin.getPortletTypes( ) )
{
listPortletsAll.addAll( PortletHome.findByType( portletType.getId( ) ) );
}
for ( Portlet portlet : listPortletsAll )
{
if ( ( DocumentPublicationHome.findByPortletId( portlet.getId( ) ).size( ) > 0 ) &&
( portlet.getStatus( ) == Portlet.STATUS_PUBLISHED ) )
{
listPortlets.add( portlet );
}
}
return listPortlets;
}
/**
* Get the max document order from a {@link Portlet} id
* @param nPortletId the {@link Portlet} identifer
* @return The max document order
*/
public int getMaxDocumentOrderByPortletId( int nPortletId )
{
return DocumentPublicationHome.findMaxDocumentOrderByPortletId( nPortletId );
}
}