View Javadoc
1   /*
2    * Copyright (c) 2002-2017, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  
35  package fr.paris.lutece.plugins.chatbot.service;
36  
37  import fr.paris.lutece.plugins.chatbot.business.BotPost;
38  import fr.paris.lutece.plugins.chatbot.service.bot.ChatBot;
39  import fr.paris.lutece.plugins.chatbot.business.ChatData;
40  import fr.paris.lutece.plugins.chatbot.business.Post;
41  import fr.paris.lutece.portal.service.spring.SpringContextService;
42  import java.util.HashMap;
43  import java.util.List;
44  import java.util.Locale;
45  import java.util.Map;
46  import javax.servlet.http.HttpServletRequest;
47  import org.apache.commons.lang3.StringUtils;
48  
49  /**
50   * ChatService
51   */
52  public final class ChatService
53  {
54      private static final String RESET = "reset";
55  
56      private static Map<String, ChatData> _mapConversations = new HashMap<>( );
57      private static PostRenderer _renderer = SpringContextService.getBean( "chatbot.postRenderer" );
58  
59      /**
60       * Private constructor
61       */
62      private ChatService( )
63      {
64      }
65  
66      /**
67       * Process message
68       * 
69       * @param request
70       *            The request
71       * @param strConversationId
72       *            The conversation ID
73       * @param strMessage
74       *            The message
75       * @param strBotKey
76       *            The bot Key
77       * @param locale
78       *            The locale
79       */
80      public static void processMessage( HttpServletRequest request, String strConversationId, String strMessage, String strBotKey, Locale locale )
81      {
82          ChatBot bot = BotService.getBot( strBotKey );
83          String strUserMessage = extractUserMessage( strMessage );   // Message displayed in the conversation (part before '|')
84          String strUserCodifiedMessage= extractUserCodifiedMessage( strMessage);  // Message send to the bot as user message (part after '|')
85  
86          boolean bResetConversation = RESET.equalsIgnoreCase( strUserCodifiedMessage );
87          if ( bResetConversation )
88          {
89              _mapConversations.remove( strConversationId );
90              bot.reset( strConversationId );
91          }
92          ChatData data = _mapConversations.get( strConversationId );
93          if ( data == null )
94          {
95              data = new ChatData( bot.getWelcomeMessage() );
96              _mapConversations.put( strConversationId, data );
97          }
98          if ( !bResetConversation )
99          {
100             data.addUserPost( strUserMessage );
101         }
102 
103         if ( !bResetConversation || StringUtils.isEmpty( bot.getWelcomeMessage( ) ) )
104         {
105             List<BotPost> listMessages = bot.processUserMessage( strUserCodifiedMessage, strConversationId, locale );
106             for ( BotPost post : listMessages )
107             {
108                 data.addBotPost( post );
109             }
110         }
111     }
112 
113     /**
114      * Get conversation
115      * 
116      * @param strConversationId
117      *            Conversation Id
118      * @param bot The bot
119      * 
120      * @param locale
121      *            The locale
122      * @return The list of post
123      */
124     public static List<Post> getConversation( String strConversationId, ChatBot bot, Locale locale )
125     {
126         ChatData data = _mapConversations.get( strConversationId );
127         if ( data == null )
128         {
129             if ( StringUtils.isEmpty( bot.getWelcomeMessage() ) )
130             {
131                 processMessage( null, strConversationId, "", bot.getKey( ), locale );
132                 data = _mapConversations.get( strConversationId );
133             }
134             else
135             {
136                 data = new ChatData( bot.getWelcomeMessage() );
137             }
138         }
139         return _renderer.render( data.getPosts( ) );
140     }
141 
142     /**
143      * Extract user message : all text before the pipe character
144      * 
145      * @param strMessage
146      *            The input message
147      * @return The output message
148      */
149     private static String extractUserMessage( String strMessage )
150     {
151         int nPos = strMessage.indexOf( '|' );
152         if ( nPos > 0 )
153         {
154             return strMessage.substring( 0, nPos );
155         }
156         return strMessage;
157     }
158 
159     
160     /**
161      * Extract user message : all text before the pipe character
162      * 
163      * @param strMessage
164      *            The input message
165      * @return The output message
166      */
167     private static String extractUserCodifiedMessage( String strMessage )
168     {
169         int nPos = strMessage.indexOf( '|' );
170         if ( ( nPos > 0 ) && ( nPos < strMessage.length() ))
171         {
172             return strMessage.substring( nPos + 1 );
173         }
174         return strMessage;
175     }
176     
177 }