View Javadoc
1   /*
2    * Copyright (c) 2002-2014, 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  package fr.paris.lutece.portal.web;
35  
36  import fr.paris.lutece.portal.service.admin.AdminUserService;
37  import fr.paris.lutece.portal.service.content.ContentPostProcessorService;
38  import fr.paris.lutece.portal.service.content.ContentService;
39  import fr.paris.lutece.portal.service.datastore.DatastoreService;
40  import fr.paris.lutece.portal.service.editor.EditorBbcodeService;
41  import fr.paris.lutece.portal.service.i18n.I18nService;
42  import fr.paris.lutece.portal.service.init.AppInfo;
43  import fr.paris.lutece.portal.service.init.AppInit;
44  import fr.paris.lutece.portal.service.mail.MailService;
45  import fr.paris.lutece.portal.service.message.ISiteMessageHandler;
46  import fr.paris.lutece.portal.service.message.SiteMessage;
47  import fr.paris.lutece.portal.service.message.SiteMessageException;
48  import fr.paris.lutece.portal.service.message.SiteMessageService;
49  import fr.paris.lutece.portal.service.portal.PortalService;
50  import fr.paris.lutece.portal.service.portal.ThemesService;
51  import fr.paris.lutece.portal.service.resource.IExtendableResource;
52  import fr.paris.lutece.portal.service.resource.IExtendableResourceService;
53  import fr.paris.lutece.portal.service.security.LuteceUser;
54  import fr.paris.lutece.portal.service.security.SecurityService;
55  import fr.paris.lutece.portal.service.security.UserNotSignedException;
56  import fr.paris.lutece.portal.service.spring.SpringContextService;
57  import fr.paris.lutece.portal.service.template.AppTemplateService;
58  import fr.paris.lutece.portal.service.util.AppLogService;
59  import fr.paris.lutece.portal.service.util.AppPathService;
60  import fr.paris.lutece.portal.service.util.AppPropertiesService;
61  import fr.paris.lutece.portal.web.constants.Markers;
62  import fr.paris.lutece.portal.web.constants.Parameters;
63  import fr.paris.lutece.util.html.HtmlTemplate;
64  import fr.paris.lutece.util.url.UrlItem;
65  
66  import org.apache.commons.lang.StringUtils;
67  
68  import java.io.UnsupportedEncodingException;
69  
70  import java.net.URLEncoder;
71  
72  import java.util.Enumeration;
73  import java.util.HashMap;
74  import java.util.List;
75  import java.util.Map;
76  
77  import javax.servlet.http.HttpServletRequest;
78  import javax.servlet.http.HttpSession;
79  
80  
81  /**
82   * This class provides the methods to display the page of the site
83   */
84  public class PortalJspBean
85  {
86      public static final int MODE_HTML = 0;
87      public static final int MODE_ADMIN = 1;
88      private static final String TEMPLATE_PAGE_ERROR404 = "skin/site/page_error404.html";
89      private static final String TEMPLATE_PAGE_ERROR500 = "skin/site/page_error500.html";
90      private static final String TEMPLATE_POPUP_CREDITS = "skin/site/popup_credits.html";
91      private static final String TEMPLATE_POPUP_LEGAL_INFO = "skin/site/popup_legal_info.html";
92      private static final String TEMPLATE_STARTUP_FAILURE = "skin/site/startup_failure.html";
93      private static final String TEMPLATE_SEND_RESOURCE = "skin/site/popup_send_resource.html";
94      private static final String TEMPLATE_EMAIL_SEND_RESOURCE = "skin/site/mail_send_resource.html";
95      private static final String PROPERTY_INFOS_CNIL = "lutece.legal.infos";
96      private static final String ATTRIBUTE_LOGIN_NEXT_URL = "luteceLoginNextUrl";
97      private static final String ATTRIBUTE_UPLOAD_FILTER_SITE_NEXT_URL = "uploadFilterSiteNextUrl";
98      private static final String MARK_PORTAL_DOMAIN = "portal_domain";
99      private static final String MARK_ADDRESS_INFOS_CNIL = "confidentiality_info";
100     private static final String MARK_APP_VERSION = "app_version";
101     private static final String MARK_FAILURE_MESSAGE = "failure_message";
102     private static final String MARK_FAILURE_DETAILS = "failure_details";
103     private static final String MARK_RESOURCE_URL = "resource_url";
104     private static final String MARK_RESOURCE = "resource";
105     private static final String MARK_ERROR = "error";
106     private static final String MARK_SUCCESS = "success";
107     private static final String MARK_ERROR_CAUSE = "error_cause";
108     private static final String MARK_PLUGIN_THEME = "plugin_theme";
109     private static final String MARK_THEME = "theme";
110     private static final String BEAN_SITE_MESSAGE_HANDLER = "siteMessageHandler";
111     private static final String PARAMETER_EXTENDABLE_RESOURCE_TYPE = "extendableResourceType";
112     private static final String PARAMETER_ID_EXTENDABLE_RESOURCE = "idExtendableResource";
113     private static final String PARAMETER_SENDER_NAME = "senderName";
114     private static final String PARAMETER_SENDER_FIRST_NAME = "senderFirstname";
115     private static final String PARAMETER_SENDER_EMAIL = "senderEmail";
116     private static final String PARAMETER_CONTENT = "content";
117     private static final String PARAMETER_SEND = "send";
118     private static final String MESSAGE_ERROR_WRONG_SENDER_EMAIL = "portal.site.error.wrongEmailFormat";
119     private static final String MESSAGE_ERROR_MANDATORY_FIELDS = "portal.util.message.mandatoryFields";
120     private static final String MESSAGE_NO_RESOURCE_FOUND = "portal.site.error.noResourceFound";
121     private static final String PROPERTY_PAGE_TITLE_ERROR404 = "portal.util.error404.title";
122     private static final String PROPERTY_PAGE_TITLE_CREDITS = "portal.site.popup_credits.pageTitle";
123     private static final String PROPERTY_PAGE_TITLE_LEGAL_INFO = "portal.site.popup_legal_info.pageTitle";
124     private static final String PROPERTY_PAGE_TITLE_STARTUP_FAILURE = "portal.util.startup.failure.title";
125     private static final String PROPERTY_PAGE_TITLE_ERROR500 = "portal.util.error500.title";
126     private static final String PROPERTY_DEBUG = "error.page.debug";
127     private static final String PROPERTY_DEBUG_DEFAULT = "true";
128     private static final String CONSTANT_SPACE = " ";
129     private static final String KEY_WEBMASTER_EMAIL = "portal.site.site_property.noreply_email";
130 
131     /**
132      * Returns the content of a page according to the parameters found in the
133      * http request. One distinguishes article,
134      * page and xpage and the mode.
135      *
136      * @param request The http request
137      * @return the html code for the display of a page of a site
138      * @throws UserNotSignedException The UserNotSignedException
139      * @throws SiteMessageException occurs when a site message need to be
140      *             displayed
141      */
142     public String getContent( HttpServletRequest request )
143         throws UserNotSignedException, SiteMessageException
144     {
145         return getContent( request, MODE_HTML );
146     }
147 
148     /**
149      * Returns the content of a page according to the parameters found in the
150      * http request. One distinguishes article,
151      * page and xpage and the mode.
152      *
153      * @param request The http request
154      * @param nMode The mode (normal or administration)
155      * @return the html code for the display of a page of a site
156      * @throws UserNotSignedException The UserNotSignedException
157      * @throws SiteMessageException occurs when a site message need to be
158      *             displayed
159      */
160     public String getContent( HttpServletRequest request, int nMode )
161         throws UserNotSignedException, SiteMessageException
162     {
163         if ( !AppInit.isWebappSuccessfullyLoaded(  ) )
164         {
165             return getStartUpFailurePage( request );
166         }
167 
168         // Try to register the user in case of external authentication
169         if ( SecurityService.isAuthenticationEnable(  ) )
170         {
171             try
172             {
173                 if ( SecurityService.getInstance(  ).isExternalAuthentication(  ) &&
174                         !SecurityService.getInstance(  ).isMultiAuthenticationSupported(  ) )
175                 {
176                     SecurityService.getInstance(  ).getRemoteUser( request );
177                 }
178                 else
179                 {
180                     LuteceUser user = SecurityService.getInstance(  ).getRegisteredUser( request );
181 
182                     // no checks are needed if the user is already registered
183                     if ( user == null )
184                     {
185                         // if multiauthentication is supported, then when have to check remote user before other check
186                         if ( SecurityService.getInstance(  ).isMultiAuthenticationSupported(  ) )
187                         {
188                             // getRemoteUser needs to be checked before any check so the user is registered
189                             // getRemoteUser throws an exception if no user found, but here we have to bypass this exception to display login page.
190                             SecurityService.getInstance(  ).getRemoteUser( request );
191                         }
192                     }
193                 }
194             }
195             catch ( UserNotSignedException unse )
196             {
197                 // nothing to do,Leave LuteceAuthenticationFilter testing if the access to the content requires authentication
198             }
199         }
200 
201         // Search the content service invoked and call its getPage method
202         ContentService cs = PortalService.getInvokedContentService( request );
203 
204         String strContent = ( cs != null ) ? cs.getPage( request, nMode ) : PortalService.getDefaultPage( request, nMode );
205 
206         if ( ContentPostProcessorService.hasProcessor(  ) )
207         {
208             strContent = ContentPostProcessorService.process( request, strContent );
209         }
210 
211         return strContent;
212     }
213 
214     /**
215      * Returns the content of a page according to the parameters found in the
216      * http request. One distinguishes article,
217      * page and xpage and the mode.
218      *
219      * @param request The http request
220      * @return the html code for the display of a page of a site
221      *
222      */
223     public String getSiteMessageContent( HttpServletRequest request )
224     {
225         return getSiteMessageContent( request, MODE_HTML );
226     }
227 
228     /**
229      * Returns the content of a page according to the parameters found in the
230      * http request. One distinguishes article,
231      * page and xpage and the mode.
232      *
233      * @param request The http request
234      * @param nMode The mode (normal or administration)
235      * @return the html code for the display of a page of a site
236      *
237      */
238     public String getSiteMessageContent( HttpServletRequest request, int nMode )
239     {
240         String strContent = null;
241 
242         if ( !AppInit.isWebappSuccessfullyLoaded(  ) )
243         {
244             return getStartUpFailurePage( request );
245         }
246 
247         ISiteMessageHandler handler = (ISiteMessageHandler) SpringContextService.getBean( BEAN_SITE_MESSAGE_HANDLER );
248 
249         if ( handler.hasMessage( request ) )
250         {
251             strContent = handler.getPage( request, nMode );
252         }
253 
254         return strContent;
255     }
256 
257     /**
258      * Returns the code for the popup of the credits
259      * @param request The HTTP request
260      * @return the html code for the popup credits
261      */
262     public String getStartUpFailurePage( HttpServletRequest request )
263     {
264         HashMap<String, Object> model = new HashMap<String, Object>(  );
265         fillPageModel( request, model );
266         model.put( MARK_FAILURE_MESSAGE, AppInit.getLoadingFailureCause(  ) );
267         model.put( MARK_FAILURE_DETAILS, AppInit.getLoadingFailureDetails(  ) );
268         model.put( Markers.PAGE_TITLE,
269             I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_STARTUP_FAILURE, request.getLocale(  ) ) );
270 
271         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_STARTUP_FAILURE, request.getLocale(  ), model );
272 
273         return template.getHtml(  );
274     }
275 
276     /**
277      * Returns the code for the popup of the credits
278      *
279      * @param request The Http Request
280      * @return the html code for the popup credits
281      */
282     public String getCredits( HttpServletRequest request )
283     {
284         HashMap<String, Object> model = new HashMap<String, Object>(  );
285         fillPageModel( request, model );
286         model.put( MARK_APP_VERSION, AppInfo.getVersion(  ) );
287         model.put( MARK_PORTAL_DOMAIN, PortalService.getSiteName(  ) );
288         model.put( Markers.PAGE_TITLE,
289             I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_CREDITS, request.getLocale(  ) ) );
290 
291         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_POPUP_CREDITS, request.getLocale(  ), model );
292 
293         return template.getHtml(  );
294     }
295 
296     /**
297      * Returns the code for the popup of the legal infos
298      *
299      * @param request The Http Request
300      * @return the html code for the legal infos
301      */
302     public String getLegalInfos( HttpServletRequest request )
303     {
304         HashMap<String, Object> model = new HashMap<String, Object>(  );
305         fillPageModel( request, model );
306         model.put( MARK_ADDRESS_INFOS_CNIL, AppPropertiesService.getProperty( PROPERTY_INFOS_CNIL ) );
307         model.put( MARK_PORTAL_DOMAIN, PortalService.getSiteName(  ) );
308         model.put( Markers.PAGE_TITLE,
309             I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_LEGAL_INFO, request.getLocale(  ) ) );
310 
311         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_POPUP_LEGAL_INFO, request.getLocale(  ), model );
312 
313         return template.getHtml(  );
314     }
315 
316     /**
317      * Returns the 404 Error page
318      * @param request The HTTP request
319      * @return The page
320      */
321     public String getError404Page( HttpServletRequest request )
322     {
323         HashMap<String, Object> model = new HashMap<String, Object>(  );
324         fillPageModel( request, model );
325         model.put( Markers.PAGE_TITLE,
326             I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_ERROR404, request.getLocale(  ) ) );
327 
328         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_PAGE_ERROR404, request.getLocale(  ), model );
329 
330         return template.getHtml(  );
331     }
332 
333     /**
334      * Returns the 500 Error page
335      * @param request The HTTP request
336      * @param exception The Exception
337      * @return The page
338      */
339     public String getError500Page( HttpServletRequest request, Throwable exception )
340     {
341         AppLogService.error( "Error 500 : " + exception.getMessage(  ), exception );
342 
343         String strCause = null;
344 
345         if ( AppPropertiesService.getProperty( PROPERTY_DEBUG, PROPERTY_DEBUG_DEFAULT ).equalsIgnoreCase( "true" ) )
346         {
347             strCause = exception.getMessage(  );
348 
349             if ( exception.getCause(  ) != null )
350             {
351                 strCause += exception.getCause(  ).getMessage(  );
352             }
353         }
354 
355         return getError500Page( request, strCause );
356     }
357 
358     /**
359      * Returns the 500 Error page
360      * @param request The HTTP request
361      * @param strCause The message
362      * @return The page
363      */
364     public String getError500Page( HttpServletRequest request, String strCause )
365     {
366         HashMap<String, Object> model = new HashMap<String, Object>(  );
367         fillPageModel( request, model );
368         model.put( Markers.PAGE_TITLE,
369             I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_ERROR500, request.getLocale(  ) ) );
370         model.put( MARK_ERROR_CAUSE, strCause );
371 
372         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_PAGE_ERROR500, request.getLocale(  ), model );
373 
374         return template.getHtml(  );
375     }
376 
377     /**
378      * Fill the model'map with commons values
379      * @param request The HTTP request
380      * @param model The map containing the model
381      */
382     private static void fillPageModel( HttpServletRequest request, HashMap<String, Object> model )
383     {
384         model.put( Markers.BASE_URL, AppPathService.getBaseUrl( request ) );
385         model.put( MARK_PLUGIN_THEME, null );
386         model.put( MARK_THEME, ThemesService.getGlobalThemeObject(  ) );
387     }
388 
389     /**
390      * This method is called by Portal.jsp when it caught an
391      * UserNotSignedException.
392      * It gives the login url and stores in the session the url asked
393      * @param request The HTTP request
394      * @return The login page URL
395      * @since v1.1
396      */
397     public static String redirectLogin( HttpServletRequest request )
398     {
399         String strNextUrl = request.getRequestURI(  );
400         UrlItem url = new UrlItem( strNextUrl );
401         Enumeration<String> enumParams = request.getParameterNames(  );
402 
403         while ( enumParams.hasMoreElements(  ) )
404         {
405             String strParamName = enumParams.nextElement(  );
406 
407             try
408             {
409                 url.addParameter( strParamName, URLEncoder.encode( request.getParameter( strParamName ), "UTF-8" ) );
410             }
411             catch ( UnsupportedEncodingException ex )
412             {
413                 AppLogService.error( "Redirection error while encoding URL : " + ex.getMessage(  ), ex );
414             }
415         }
416 
417         HttpSession session = request.getSession( true );
418         session.setAttribute( ATTRIBUTE_LOGIN_NEXT_URL, url.getUrl(  ) );
419 
420         String strRedirect = SecurityService.getInstance(  ).getLoginPageUrl(  );
421 
422         return AppPathService.getAbsoluteUrl( request, strRedirect );
423     }
424 
425     /**
426      * Returns the url (asked before login) to redirect after login
427      * @param request The Http request
428      * @return The url asked before login
429      * @since v1.1
430      */
431     public static String getLoginNextUrl( HttpServletRequest request )
432     {
433         HttpSession session = request.getSession(  );
434         String strNextUrl = (String) session.getAttribute( ATTRIBUTE_LOGIN_NEXT_URL );
435 
436         return strNextUrl;
437     }
438 
439     /**
440      * Set the upload filter site next url
441      * @param request the HTTP request
442      */
443     public static void setUploadFilterSiteNextUrl( HttpServletRequest request )
444     {
445         String strNextUrl = request.getRequestURI(  );
446         UrlItem url = new UrlItem( strNextUrl );
447         Enumeration<String> enumParams = request.getParameterNames(  );
448 
449         while ( enumParams.hasMoreElements(  ) )
450         {
451             String strParamName = enumParams.nextElement(  );
452             url.addParameter( strParamName, request.getParameter( strParamName ) );
453         }
454 
455         HttpSession session = request.getSession( true );
456         session.setAttribute( ATTRIBUTE_UPLOAD_FILTER_SITE_NEXT_URL, url.getUrl(  ) );
457     }
458 
459     /**
460      * Get the upload filter site next url
461      * @param request the HTTP request
462      * @return the next url
463      */
464     public static String getUploadFilterSiteNextUrl( HttpServletRequest request )
465     {
466         HttpSession session = request.getSession(  );
467         String strNextUrl = (String) session.getAttribute( ATTRIBUTE_UPLOAD_FILTER_SITE_NEXT_URL );
468 
469         return strNextUrl;
470     }
471 
472     /**
473      * Remove the upload filter next url from the session
474      * @param request the HTTP request
475      */
476     public static void removeUploadFilterSiteNextUrl( HttpServletRequest request )
477     {
478         HttpSession session = request.getSession(  );
479         session.removeAttribute( ATTRIBUTE_UPLOAD_FILTER_SITE_NEXT_URL );
480     }
481 
482     /**
483      * Do send a resource
484      * @param request The request
485      * @return The HTML content to display
486      * @throws SiteMessageException If the resource or its associated service is
487      *             not found
488      */
489     public static String sendResource( HttpServletRequest request )
490         throws SiteMessageException
491     {
492         String strSenderEmail = DatastoreService.getDataValue( KEY_WEBMASTER_EMAIL, "no-reply@mydomain.com" );
493         String strSenderName = request.getParameter( PARAMETER_SENDER_NAME );
494         String strSenderFirstName = request.getParameter( PARAMETER_SENDER_FIRST_NAME );
495         String strReceipientEmail = request.getParameter( Parameters.EMAIL );
496         String strContent = request.getParameter( PARAMETER_CONTENT );
497         String strExtendableResourceType = request.getParameter( PARAMETER_EXTENDABLE_RESOURCE_TYPE );
498         String strIdExtendableResource = request.getParameter( PARAMETER_ID_EXTENDABLE_RESOURCE );
499         String strSend = request.getParameter( PARAMETER_SEND );
500         IExtendableResource resource = null;
501 
502         String strError = null;
503 
504         // If the form was submited, we check data
505         if ( strSend != null )
506         {
507             if ( StringUtils.isBlank( strSenderEmail ) || StringUtils.isBlank( strSenderName ) ||
508                     StringUtils.isBlank( strSenderFirstName ) || StringUtils.isBlank( strReceipientEmail ) ||
509                     StringUtils.isBlank( strContent ) )
510             {
511                 strError = I18nService.getLocalizedString( MESSAGE_ERROR_MANDATORY_FIELDS, request.getLocale(  ) );
512             }
513 
514             if ( ( strError != null ) &&
515                     ( !AdminUserService.checkEmail( strSenderEmail ) ||
516                     !AdminUserService.checkEmail( strReceipientEmail ) ) )
517             {
518                 strError = I18nService.getLocalizedString( MESSAGE_ERROR_WRONG_SENDER_EMAIL, request.getLocale(  ) );
519             }
520         }
521 
522         // We get the resource from its resource service
523         IExtendableResourceService resourceService = null;
524         List<IExtendableResourceService> listExtendableResourceService = SpringContextService.getBeansOfType( IExtendableResourceService.class );
525 
526         for ( IExtendableResourceService extendableResourceService : listExtendableResourceService )
527         {
528             if ( extendableResourceService.isInvoked( strExtendableResourceType ) )
529             {
530                 resourceService = extendableResourceService;
531                 resource = extendableResourceService.getResource( strIdExtendableResource, strExtendableResourceType );
532             }
533         }
534 
535         if ( ( resourceService == null ) || ( resource == null ) )
536         {
537             SiteMessageService.setMessage( request, MESSAGE_NO_RESOURCE_FOUND, SiteMessage.TYPE_ERROR );
538             throw new SiteMessageException(  );
539         }
540 
541         String strResourceUrl = resourceService.getResourceUrl( strIdExtendableResource, strExtendableResourceType );
542         Map<String, Object> model = new HashMap<String, Object>(  );
543         model.put( MARK_RESOURCE, resource );
544         model.put( MARK_RESOURCE_URL, strResourceUrl );
545         model.put( Markers.BASE_URL, AppPathService.getBaseUrl( request ) );
546 
547         if ( ( strSend != null ) && ( strError == null ) )
548         {
549             Map<String, Object> mailModel = new HashMap<String, Object>(  );
550             mailModel.put( Markers.BASE_URL, AppPathService.getBaseUrl( request ) );
551             mailModel.put( MARK_RESOURCE, resource );
552             mailModel.put( PARAMETER_SENDER_EMAIL, strSenderEmail );
553             mailModel.put( PARAMETER_SENDER_NAME, strSenderName );
554             mailModel.put( PARAMETER_SENDER_FIRST_NAME, strSenderFirstName );
555             mailModel.put( Parameters.EMAIL, strReceipientEmail );
556             mailModel.put( PARAMETER_CONTENT, EditorBbcodeService.getInstance(  ).parse( strContent ) );
557             mailModel.put( MARK_RESOURCE_URL,
558                 resourceService.getResourceUrl( strIdExtendableResource, strExtendableResourceType ) );
559 
560             HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_EMAIL_SEND_RESOURCE,
561                     request.getLocale(  ), mailModel );
562             MailService.sendMailHtml( strReceipientEmail, strSenderFirstName + CONSTANT_SPACE + strSenderName,
563                 strSenderEmail, resource.getExtendableResourceName(  ), template.getHtml(  ) );
564             model.put( MARK_SUCCESS, MARK_SUCCESS );
565         }
566         else
567         {
568             model.put( PARAMETER_SENDER_NAME, strSenderName );
569             model.put( PARAMETER_SENDER_FIRST_NAME, strSenderFirstName );
570             model.put( Parameters.EMAIL, strReceipientEmail );
571             model.put( PARAMETER_CONTENT, strContent );
572             model.put( MARK_ERROR, strError );
573         }
574 
575         model.put( Markers.PAGE_MAIN_MENU, StringUtils.EMPTY );
576 
577         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_SEND_RESOURCE, request.getLocale(  ), model );
578 
579         return template.getHtml(  );
580     }
581 }