View Javadoc
1   /*
2    * Copyright (c) 2002-2021, City of 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.plugins.extend.web.component;
35  
36  import fr.paris.lutece.plugins.extend.business.extender.ResourceExtenderDTO;
37  import fr.paris.lutece.plugins.extend.business.extender.config.IExtenderConfig;
38  import fr.paris.lutece.plugins.extend.business.extender.history.ResourceExtenderHistory;
39  import fr.paris.lutece.plugins.extend.business.extender.history.ResourceExtenderHistoryFilter;
40  import fr.paris.lutece.plugins.extend.service.extender.IResourceExtender;
41  import fr.paris.lutece.plugins.extend.service.extender.IResourceExtenderService;
42  import fr.paris.lutece.plugins.extend.service.extender.history.IResourceExtenderHistoryService;
43  import fr.paris.lutece.plugins.extend.util.ExtendErrorException;
44  import fr.paris.lutece.plugins.extend.util.ExtendUtils;
45  import fr.paris.lutece.portal.service.admin.AdminUserService;
46  import fr.paris.lutece.portal.service.i18n.I18nService;
47  import fr.paris.lutece.portal.service.spring.SpringContextService;
48  import fr.paris.lutece.portal.service.template.AppTemplateService;
49  import fr.paris.lutece.portal.service.util.AppLogService;
50  import fr.paris.lutece.portal.service.util.AppPropertiesService;
51  import fr.paris.lutece.portal.web.util.LocalizedPaginator;
52  import fr.paris.lutece.util.ReferenceItem;
53  import fr.paris.lutece.util.ReferenceList;
54  import fr.paris.lutece.util.beanvalidation.BeanValidationUtil;
55  import fr.paris.lutece.util.html.HtmlTemplate;
56  import fr.paris.lutece.util.html.Paginator;
57  import fr.paris.lutece.util.url.UrlItem;
58  
59  import org.apache.commons.beanutils.BeanUtils;
60  import org.apache.commons.lang3.StringUtils;
61  
62  import java.lang.reflect.InvocationTargetException;
63  
64  import java.util.HashMap;
65  import java.util.List;
66  import java.util.Locale;
67  import java.util.Map;
68  import java.util.Set;
69  
70  import javax.inject.Inject;
71  
72  import javax.servlet.http.HttpServletRequest;
73  
74  import javax.validation.ConstraintViolation;
75  
76  /**
77   *
78   * ResourceExtenderComponentManager
79   *
80   */
81  public class ResourceExtenderComponentManager implements IResourceExtenderComponentManager
82  {
83      /** The Constant BEAN_MANAGER. */
84      public static final String BEAN_MANAGER = "extend.resourceExtenderComponentManager";
85  
86      // CONSTANTS
87      private static final String ORDER_BY_DATE_CREATION = " date_creation ";
88  
89      // PROPERTIES
90      private static final String PROPERTY_DEFAULT_LIST_HISTORIES_PER_PAGE = "extend.listHistories.itemsPerPage";
91  
92      // PARAMETERS
93      private static final String PARAMETER_ID_EXTENDER = "idExtender";
94      private static final String PARAMETER_FROM_URL = "from_url";
95      private static final String PARAMETER_MANAGE_BY_RESOURCE = "manageByResource";
96  
97      // MARKS
98      private static final String MARK_RESOURCE_EXTENDER = "resourceExtender";
99      private static final String MARK_LOCALE = "locale";
100     private static final String MARK_RESOURCE_EXTENDER_CONFIG = "resourceExtenderConfig";
101     private static final String MARK_RESOURCE_EXTENDER_INFO = "resourceExtenderInfo";
102     private static final String MARK_LIST_HISTORIES = "listHistories";
103     private static final String MARK_PAGINATOR = "paginator";
104     private static final String MARK_NB_ITEMS_PER_PAGE = "nb_items_per_page";
105     private static final String MARK_FROM_URL = "from_url";
106     private static final String MARK_EXTENDER_TYPE_MODIFY_CONFIG = "extenderTypeModifyConfig";
107     private static final String MARK_RESOURCE_EXTENDER_CONFIGURABLE = "configurableExtenderTypes";
108 
109     // TEMPLATES
110     private static final String TEMPLATE_RESOURCE_EXTENDER_CONFIG = "admin/plugins/extend/resource_extender_config.html";
111     private static final String TEMPLATE_RESOURCE_EXTENDER_DEFAULT_CONFIG = "admin/plugins/extend/resource_extender_default_config.html";
112     private static final String TEMPLATE_RESOURCE_EXTENDER_INFO = "admin/plugins/extend/resource_extender_info.html";
113     private static final String TEMPLATE_RESOURCE_EXTENDER_HISTORY = "admin/plugins/extend/resource_extender_history.html";
114 
115     // JSP
116     private static final String JSP_URL_VIEW_EXTENDER_HISTORY = "jsp/admin/plugins/extend/ViewExtenderHistory.jsp";
117 
118     // MESSAGES
119     private static final String MESSAGE_STOP_GENERIC_MESSAGE = "extend.message.stop.genericMessage";
120 
121     // CONSTANT
122     private static final String CONSTANT_AND = "&";
123     private static final String CONSTANT_AND_HTML = "%26";
124 
125     // SERVICES
126     @Inject
127     private IResourceExtenderService _resourceExtenderService;
128     @Inject
129     private IResourceExtenderHistoryService _resourceHistoryService;
130 
131     // VARIABLES
132     private int _nItemsPerPage;
133     private int _nDefaultItemsPerPage;
134     private String _strCurrentPageIndex;
135 
136     /**
137      * {@inheritDoc}
138      */
139     @Override
140     public IResourceExtenderComponent getResourceExtenderComponent( String strExtenderType )
141     {
142         if ( StringUtils.isNotBlank( strExtenderType ) )
143         {
144             for ( IResourceExtenderComponent component : SpringContextService.getBeansOfType( IResourceExtenderComponent.class ) )
145             {
146                 if ( component.getResourceExtender( ).getKey( ).equals( strExtenderType ) )
147                 {
148                     return component;
149                 }
150             }
151         }
152 
153         return null;
154     }
155 
156     /**
157      * {@inheritDoc}
158      */
159     @Override
160     public void buildXmlAddOn( ResourceExtenderDTO resourceExtender, StringBuffer strXml )
161     {
162         if ( resourceExtender != null )
163         {
164             IResourceExtenderComponent component = getResourceExtenderComponent( resourceExtender.getExtenderType( ) );
165 
166             if ( component != null )
167             {
168                 component.buildXmlAddOn( resourceExtender.getIdExtendableResource( ), resourceExtender.getExtendableResourceType( ),
169                         resourceExtender.getParameters( ), strXml );
170             }
171         }
172     }
173 
174     /**
175      * {@inheritDoc}
176      */
177     @Override
178     public String getPageAddOn( ResourceExtenderDTO resourceExtender, HttpServletRequest request )
179     {
180         if ( resourceExtender != null )
181         {
182             IResourceExtenderComponent component = getResourceExtenderComponent( resourceExtender.getExtenderType( ) );
183 
184             if ( component != null )
185             {
186                 return component.getPageAddOn( resourceExtender.getIdExtendableResource( ), resourceExtender.getExtendableResourceType( ),
187                         resourceExtender.getParameters( ), request );
188             }
189         }
190 
191         return StringUtils.EMPTY;
192     }
193 
194     /**
195      * {@inheritDoc}
196      */
197     @Override
198     public String getConfigHtml( ResourceExtenderDTO resourceExtender, Locale locale, HttpServletRequest request )
199     {
200         if ( resourceExtender != null )
201         {
202             IResourceExtenderComponent component = getResourceExtenderComponent( resourceExtender.getExtenderType( ) );
203 
204             if ( component != null )
205             {
206                 Map<String, Object> model = new HashMap<String, Object>( );
207                 model.put( MARK_RESOURCE_EXTENDER, resourceExtender );
208                 model.put( MARK_LOCALE, locale );
209                 model.put( MARK_RESOURCE_EXTENDER_CONFIG, component.getConfigHtml( resourceExtender, locale, request ) );
210                 model.put( MARK_FROM_URL, StringUtils.replace( request.getParameter( PARAMETER_FROM_URL ), CONSTANT_AND, CONSTANT_AND_HTML ) );
211 
212                 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_RESOURCE_EXTENDER_CONFIG, locale, model );
213 
214                 return template.getHtml( );
215             }
216         }
217 
218         return StringUtils.EMPTY;
219     }
220 
221     /**
222      * {@inheritDoc}
223      */
224     @Override
225     public String getDefaultConfigHtml( String strExtenderType, Locale locale, HttpServletRequest request )
226     {
227         ResourceExtenderDTOtender/ResourceExtenderDTO.html#ResourceExtenderDTO">ResourceExtenderDTO resourceExtender = new ResourceExtenderDTO( );
228         resourceExtender.setIdExtender( -1 );
229         resourceExtender.setExtenderType( strExtenderType );
230 
231         IResourceExtenderComponent component = getResourceExtenderComponent( resourceExtender.getExtenderType( ) );
232 
233         if ( component != null )
234         {
235             Map<String, Object> model = new HashMap<String, Object>( );
236             model.put( MARK_RESOURCE_EXTENDER, resourceExtender );
237             model.put( MARK_LOCALE, locale );
238             model.put( MARK_RESOURCE_EXTENDER_CONFIG, component.getConfigHtml( resourceExtender, locale, request ) );
239             model.put( MARK_FROM_URL, StringUtils.replace( request.getParameter( PARAMETER_FROM_URL ), CONSTANT_AND, CONSTANT_AND_HTML ) );
240             model.put( MARK_EXTENDER_TYPE_MODIFY_CONFIG, strExtenderType );
241             model.put( PARAMETER_MANAGE_BY_RESOURCE, Boolean.parseBoolean( request.getParameter( PARAMETER_MANAGE_BY_RESOURCE ) ) );
242 
243             List<IResourceExtender> listExtenders = _resourceExtenderService.getResourceExtenders( );
244             ReferenceList refListExtenderTypes = new ReferenceList( );
245 
246             for ( IResourceExtender resourceExtenderDto : listExtenders )
247             {
248                 if ( resourceExtenderDto.isConfigRequired( ) )
249                 {
250                     ReferenceItem refItem = new ReferenceItem( );
251                     refItem.setCode( resourceExtenderDto.getKey( ) );
252                     refItem.setName( resourceExtenderDto.getTitle( AdminUserService.getLocale( request ) ) );
253                     refListExtenderTypes.add( refItem );
254                 }
255             }
256 
257             model.put( MARK_RESOURCE_EXTENDER_CONFIGURABLE, refListExtenderTypes );
258 
259             HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_RESOURCE_EXTENDER_DEFAULT_CONFIG, locale, model );
260 
261             return template.getHtml( );
262         }
263 
264         return StringUtils.EMPTY;
265     }
266 
267     /**
268      * {@inheritDoc}
269      */
270     @Override
271     public String getInfoHtml( ResourceExtenderDTO resourceExtender, Locale locale, HttpServletRequest request )
272     {
273         if ( resourceExtender != null )
274         {
275             IResourceExtenderComponent component = getResourceExtenderComponent( resourceExtender.getExtenderType( ) );
276 
277             if ( component != null )
278             {
279                 Map<String, Object> model = new HashMap<String, Object>( );
280                 model.put( MARK_RESOURCE_EXTENDER, resourceExtender );
281                 model.put( MARK_LOCALE, locale );
282                 model.put( MARK_RESOURCE_EXTENDER_INFO, component.getInfoHtml( resourceExtender, locale, request ) );
283                 model.put( MARK_FROM_URL, StringUtils.replace( request.getParameter( PARAMETER_FROM_URL ), CONSTANT_AND_HTML, CONSTANT_AND ) );
284 
285                 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_RESOURCE_EXTENDER_INFO, locale, model );
286 
287                 return template.getHtml( );
288             }
289         }
290 
291         return StringUtils.EMPTY;
292     }
293 
294     /**
295      * {@inheritDoc}
296      */
297     @Override
298     public String getHistoryHtml( ResourceExtenderDTO resourceExtender, Locale locale, HttpServletRequest request )
299     {
300         if ( resourceExtender != null )
301         {
302             ResourceExtenderHistoryFiltertender/history/ResourceExtenderHistoryFilter.html#ResourceExtenderHistoryFilter">ResourceExtenderHistoryFilter filter = new ResourceExtenderHistoryFilter( );
303             filter.setExtenderType( resourceExtender.getExtenderType( ) );
304             filter.setIdExtendableResource( resourceExtender.getIdExtendableResource( ) );
305             filter.setExtendableResourceType( resourceExtender.getExtendableResourceType( ) );
306             filter.setSortedAttributeName( ORDER_BY_DATE_CREATION );
307             filter.setAscSort( true );
308 
309             List<ResourceExtenderHistory> listHistories = _resourceHistoryService.findByFilter( filter );
310 
311             // PAGINATOR
312             _strCurrentPageIndex = Paginator.getPageIndex( request, Paginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
313             _nDefaultItemsPerPage = AppPropertiesService.getPropertyInt( PROPERTY_DEFAULT_LIST_HISTORIES_PER_PAGE, 50 );
314             _nItemsPerPage = Paginator.getItemsPerPage( request, Paginator.PARAMETER_ITEMS_PER_PAGE, _nItemsPerPage, _nDefaultItemsPerPage );
315 
316             UrlItem url = new UrlItem( JSP_URL_VIEW_EXTENDER_HISTORY );
317             url.addParameter( PARAMETER_ID_EXTENDER, resourceExtender.getIdExtender( ) );
318 
319             LocalizedPaginator<ResourceExtenderHistory> paginator = new LocalizedPaginator<ResourceExtenderHistory>( listHistories, _nItemsPerPage,
320                     url.getUrl( ), Paginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex, request.getLocale( ) );
321 
322             Map<String, Object> model = new HashMap<String, Object>( );
323             model.put( MARK_LIST_HISTORIES, paginator.getPageItems( ) );
324             model.put( MARK_RESOURCE_EXTENDER, resourceExtender );
325             model.put( MARK_LOCALE, locale );
326             model.put( MARK_PAGINATOR, paginator );
327             model.put( MARK_NB_ITEMS_PER_PAGE, Integer.toString( paginator.getItemsPerPage( ) ) );
328 
329             HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_RESOURCE_EXTENDER_HISTORY, locale, model );
330 
331             return template.getHtml( );
332         }
333 
334         return StringUtils.EMPTY;
335     }
336 
337     /**
338      * {@inheritDoc}
339      */
340     @Override
341     public void doSaveConfig( ResourceExtenderDTO resourceExtender, HttpServletRequest request ) throws ExtendErrorException
342     {
343         if ( resourceExtender != null )
344         {
345             IResourceExtenderComponent component = getResourceExtenderComponent( resourceExtender.getExtenderType( ) );
346 
347             if ( component != null )
348             {
349                 IExtenderConfig config = component.getConfig( resourceExtender.getIdExtender( ) );
350 
351                 // If the config is not found, then create it
352                 if ( config == null )
353                 {
354                     IResourceExtender extender = _resourceExtenderService.getResourceExtender( resourceExtender.getExtenderType( ) );
355 
356                     if ( extender != null )
357                     {
358                         extender.doCreateResourceAddOn( resourceExtender );
359                         config = component.getConfig( resourceExtender.getIdExtender( ) );
360                     }
361                 }
362 
363                 if ( config != null )
364                 {
365                     try
366                     {
367                         BeanUtils.populate( config, request.getParameterMap( ) );
368                     }
369                     catch( IllegalAccessException e )
370                     {
371                         AppLogService.error( "Unable to fetch data from request", e );
372                     }
373                     catch( InvocationTargetException e )
374                     {
375                         AppLogService.error( "Unable to fetch data from request", e );
376                     }
377 
378                     // Check mandatory fields
379                     Set<ConstraintViolation<IExtenderConfig>> constraintViolations = BeanValidationUtil.validate( config );
380 
381                     if ( constraintViolations.size( ) > 0 )
382                     {
383                         Object [ ] params = {
384                                 ExtendUtils.buildStopMessage( constraintViolations )
385                         };
386 
387                         throw new ExtendErrorException( I18nService.getLocalizedString( MESSAGE_STOP_GENERIC_MESSAGE, params, request.getLocale( ) ) );
388                     }
389 
390                     component.doSaveConfig( request, config );
391                 }
392             }
393         }
394     }
395 }