ProjectSolrSearch.java
/*
* Copyright (c) 2002-2020, 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.participatorybudget.web;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import fr.paris.lutece.plugins.participatorybudget.business.MyInfosForm;
import fr.paris.lutece.plugins.participatorybudget.service.MyInfosService;
import fr.paris.lutece.portal.service.security.LuteceUser;
import fr.paris.lutece.portal.service.security.SecurityService;
import fr.paris.lutece.portal.service.util.AppPropertiesService;
public class ProjectSolrSearch extends HttpServlet
{
private static final long serialVersionUID = -806886865678792152L;
private static final String MARK_THEME = "theme";
private static final String MARK_ARRONDISSEMENT = "arrondissement";
private static final String MARK_ARROND_USER = "user_arrondissement";
private static final String MARK_CATEGORY = "categorie";
private static final String MARK_QUERY = "query";
private static final String MARK_BUDGET = "budget";
private static final String MARK_SORT = "sort";
private static final String MARK_SORT_ORDER = "sort_order";
private static final String MARK_SORT_ALPHABETIQUE = "alpha";
private static final String MARK_SORT_DATE = "date";
private static final String MARK_TYPE_SEARCH = "type_search";
private static final String SEARCH_SIMPLE = "simple";
private static final String SEARCH_AVANCEE = "avancee";
private static final String SEARCH_THEME = "theme";
private static final String SEARCH_ARRONDISSEMENT = "arrondissement";
private static final Logger LOGGER = Logger.getLogger( ProjectSolrSearch.class );
public static final String PROJECT = AppPropertiesService.getProperty( "participatorybudget.type.project" );
public static final String THEME = AppPropertiesService.getProperty( "participatorybudget.name.theme" );
public static final String LOCATION = AppPropertiesService.getProperty( "participatorybudget.name.location_text" );
public static final String BUDGET = AppPropertiesService.getProperty( "participatorybudget.name.budget" );
/**
* Get Project specific parameters and call Solr Module.
*
* @param request
* the request
* @param response
* the response
* @throws ServletException
* the servlet exception
* @throws IOException
* Signals that an I/O exception has occurred.
*/
@Override
protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
{
LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
boolean byProject = false;
StringBuilder sbReq = new StringBuilder( "Portal.jsp?page=search-solr" );
// Sorts
if ( StringUtils.isNotEmpty( request.getParameter( MARK_SORT ) ) )
{
sbReq.append( "&sort_name=" + request.getParameter( MARK_SORT ) );
}
if ( StringUtils.isNotEmpty( request.getParameter( MARK_SORT_ORDER ) ) )
{
sbReq.append( "&sort_order=" + request.getParameter( MARK_SORT_ORDER ) );
}
// By Input search
if ( StringUtils.isNotEmpty( request.getParameter( MARK_QUERY ) ) )
{
String strQuery = request.getParameter( MARK_QUERY ).replaceAll( ":", "" );
sbReq.append( "&query=title:" + strQuery + " OR summary:" + strQuery + " OR identifiant_text:" + strQuery );
sbReq.append( "&fq=type:" + PROJECT );
byProject = true;
}
// By Budget
if ( StringUtils.isNotEmpty( request.getParameter( MARK_BUDGET ) ) )
{
sbReq.append( "&query=" + BUDGET + ":" + request.getParameter( MARK_BUDGET ) );
if ( !byProject )
{
byProject = true;
sbReq.append( "&fq=type:" + PROJECT );
}
} // By Arrondissement
if ( StringUtils.isNotEmpty( getArrondissement( request, user ) ) && !request.getParameter( MARK_ARRONDISSEMENT ).isEmpty( ) )
{
sbReq.append( "&fq=" + LOCATION + ":" + getArrondissement( request, user ) );
if ( !byProject )
{
byProject = true;
sbReq.append( "&fq=type:" + PROJECT );
}
}
else
{
if ( !byProject )
sbReq.append( "&query=*:*&fq=type:" + PROJECT );
}
// By THEME
LOGGER.debug( "Requête SOLR de date, redirection vers " + sbReq.toString( ) );
UriComponents uriComponents = UriComponentsBuilder.fromUriString( sbReq.toString( ) ).build( );
String strEncodedUri = uriComponents.encode( "UTF-8" ).toUriString( );
// Make the redirection
response.sendRedirect( strEncodedUri );
}
/**
* Get Project specific parameters and call Solr Module.
*
* @param request
* the request
* @param response
* the response
* @throws ServletException
* the servlet exception
* @throws IOException
* Signals that an I/O exception has occurred.
*/
protected void doGetOld( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
{
LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
StringBuilder sbReq = new StringBuilder( "Portal.jsp?page=search-solr" );
String sTypeSearch = request.getParameter( MARK_TYPE_SEARCH );
String sTypeSort = request.getParameter( MARK_SORT );
StringBuilder sbFilter = new StringBuilder( "" );
StringBuilder sbSort = null;
String sQuery = request.getParameter( MARK_QUERY );
if ( StringUtils.isNotEmpty( sTypeSort ) && MARK_SORT_ALPHABETIQUE.equals( sTypeSort ) )
{
// sort by title
sbSort = new StringBuilder( "&sort_name=title&sort_order=asc" );
}
else
{
// Sort by date
sTypeSort = MARK_SORT_DATE;
sbSort = new StringBuilder( "&sort_order=desc" );
}
if ( ( StringUtils.isEmpty( sTypeSearch ) || SEARCH_SIMPLE.equals( sTypeSearch ) ) && user == null )
{
// simple search with facets
sTypeSearch = SEARCH_SIMPLE;
sQuery = sQuery.replaceAll( ":", "" );
if ( StringUtils.isNotEmpty( sQuery ) && StringUtils.isNotEmpty( sQuery.trim( ) ) && StringUtils.isNotBlank( ( sQuery.trim( ) ) ) )
{
sbReq.append( "&query=title:" + sQuery + " OR summary:" + sQuery + " OR identifiant_text:" + sQuery );
}
sbFilter.append( "&fq=type:" + PROJECT );
}
else
if ( SEARCH_THEME.equals( sTypeSearch ) && user == null )
{
String sTheme = request.getParameter( MARK_THEME );
if ( StringUtils.isNotEmpty( sTheme ) )
{
// sbReq.append( "&query=*:*" );
sbFilter.append( "&fq=" + THEME + ":" + sTheme );
}
sbFilter.append( "&fq=type:" + PROJECT );
}
else
if ( SEARCH_ARRONDISSEMENT.equals( sTypeSearch ) )
{
sbFilter.append( "&fq=" + LOCATION + ":" + getArrondissement( request, user ) );
sbFilter.append( "&fq=type:" + PROJECT );
}
else
if ( SEARCH_AVANCEE.equals( sTypeSearch ) )
{
SimpleDateFormat sdfXml = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss'Z'" );
String sTheme = request.getParameter( MARK_THEME );
String [ ] categories = request.getParameterValues( MARK_CATEGORY );
String sShowDateStart = request.getParameter( "show_date_start" );
String sShowDateEnd = request.getParameter( "show_date_end" );
if ( StringUtils.isNotEmpty( sTheme ) )
{
sbReq.append( "&query=" + THEME + ":" + sQuery );
}
sbFilter.append( "&fq=type:" + PROJECT );
if ( StringUtils.isNotEmpty( sQuery ) && ArrayUtils.isEmpty( categories ) )
{
sbReq.append( "&query=" + sQuery );
}
else
if ( StringUtils.isNotEmpty( sQuery ) && !ArrayUtils.isEmpty( categories ) )
{
sbReq.append( "&query=(" + sQuery );
sbFilter.append( " AND categorie:(" );
int i = 1;
for ( String categorie : categories )
{
if ( i < categories.length )
{
sbFilter.append( categorie.replace( " ", "*" ) ).append( " OR " );
}
else
{
sbFilter.append( categorie.replace( " ", "*" ) );
}
i++;
}
sbFilter.append( "))" );
}
else
if ( !ArrayUtils.isEmpty( categories ) )
{
sbFilter.append( "&query=categorie:(" );
int i = 1;
for ( String categorie : categories )
{
if ( i < categories.length )
{
sbFilter.append( categorie.replace( " ", "*" ) ).append( " OR " );
}
else
{
sbFilter.append( categorie.replace( " ", "*" ) );
}
i++;
}
sbFilter.append( ")" );
}
if ( StringUtils.isNotEmpty( sShowDateStart ) )
{
// Timestamp showDateStart = DateUtils.getDate( sShowDateStart, true );
// String sXmlShowDateStart = sdfXml.format( showDateStart );
// sbFilter.append( "&fq=end_date:[" ).append( sXmlShowDateStart ).append( " TO *]" );
}
if ( StringUtils.isNotEmpty( sShowDateEnd ) )
{
// Timestamp showDateEnd = DateUtils.getDate( sShowDateEnd, true );
// String sXmlShowDateEnd = sdfXml.format( showDateEnd );
// sbFilter.append( "&fq=start_date:[* TO " ).append( sXmlShowDateEnd ).append( "]" );
}
}
StringBuilder sbType = new StringBuilder( "&type_search=" + sTypeSearch );
if ( sbFilter.toString( ).isEmpty( ) && StringUtils.isEmpty( sQuery ) )
{
// Create default filter
sbReq.append( "&query=*:*" );
}
else
{
sbReq.append( sbFilter.toString( ) );
}
sbReq.append( sbSort.toString( ) );
sbReq.append( sbType.toString( ) );
LOGGER.debug( "Requête SOLR de date, redirection vers " + sbReq.toString( ) );
UriComponents uriComponents = UriComponentsBuilder.fromUriString( sbReq.toString( ) ).build( );
String strEncodedUri = uriComponents.encode( "UTF-8" ).toUriString( );
// Make the redirection
response.sendRedirect( strEncodedUri );
}
/**
* Get arrondissement
*
* @param request
* @param user
* @return
*/
private static String getArrondissement( HttpServletRequest request, LuteceUser user )
{
String strArrondissement = request.getParameter( MARK_ARRONDISSEMENT );
if ( ( StringUtils.isEmpty( strArrondissement ) || strArrondissement.equals( MARK_ARROND_USER ) ) && user != null )
{
MyInfosForm myInfo = MyInfosService.loadUserInfos( user );
Pattern p = Pattern.compile( "75(020|00[1-9]|116|01[0-9])$" );
Matcher m = p.matcher( myInfo.getArrondissement( ) );
if ( m.matches( ) )
strArrondissement = Integer.valueOf( myInfo.getArrondissement( ).substring( 2 ) ) + "e " + MARK_ARRONDISSEMENT;
}
else
if ( strArrondissement != null && strArrondissement.equals( MARK_ARROND_USER ) && user == null )
{
strArrondissement = StringUtils.EMPTY;
}
return strArrondissement;
}
}