View Javadoc
1   /*
2    * Copyright (c) 2002-2025, 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.pluginwizard.web;
35  
36  import fr.paris.lutece.plugins.pluginwizard.business.ConfigurationKey;
37  
38  import fr.paris.lutece.plugins.pluginwizard.business.ConfigurationKeyHome;
39  import fr.paris.lutece.plugins.pluginwizard.business.ModelHome;
40  import fr.paris.lutece.plugins.pluginwizard.business.model.Application;
41  import fr.paris.lutece.plugins.pluginwizard.business.model.Attribute;
42  import fr.paris.lutece.plugins.pluginwizard.business.model.BusinessClass;
43  import fr.paris.lutece.plugins.pluginwizard.business.model.Feature;
44  import fr.paris.lutece.plugins.pluginwizard.business.model.PluginModel;
45  import fr.paris.lutece.plugins.pluginwizard.business.model.Portlet;
46  import fr.paris.lutece.plugins.pluginwizard.business.model.Rest;
47  import fr.paris.lutece.plugins.pluginwizard.service.MapperService;
48  import fr.paris.lutece.plugins.pluginwizard.service.ModelService;
49  import fr.paris.lutece.plugins.pluginwizard.service.QualityService;
50  import fr.paris.lutece.plugins.pluginwizard.service.generator.GeneratorService;
51  import fr.paris.lutece.plugins.pluginwizard.web.formbean.BusinessClassFormBean;
52  import fr.paris.lutece.plugins.pluginwizard.web.formbean.ConfigurationFormBean;
53  import fr.paris.lutece.plugins.pluginwizard.web.formbean.DescriptionFormBean;
54  import fr.paris.lutece.plugins.pluginwizard.web.formbean.FormBean;
55  import fr.paris.lutece.plugins.pluginwizard.web.formbean.ModuleNameFormBean;
56  import fr.paris.lutece.plugins.pluginwizard.web.formbean.PluginNameFormBean;
57  import fr.paris.lutece.plugins.pluginwizard.web.formbean.WorkflowTaskNameFormBean;
58  import fr.paris.lutece.portal.service.message.SiteMessageException;
59  import fr.paris.lutece.portal.service.plugin.Plugin;
60  import fr.paris.lutece.portal.service.security.UserNotSignedException;
61  import fr.paris.lutece.portal.service.util.AppPropertiesService;
62  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
63  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
64  import fr.paris.lutece.portal.util.mvc.utils.MVCMessageBox;
65  import fr.paris.lutece.portal.util.mvc.utils.MVCUtils;
66  import fr.paris.lutece.portal.util.mvc.xpage.MVCApplication;
67  import fr.paris.lutece.portal.util.mvc.xpage.annotations.Controller;
68  import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
69  import fr.paris.lutece.portal.web.xpages.XPage;
70  import fr.paris.lutece.util.url.UrlItem;
71  
72  import java.io.Serializable;
73  import java.nio.charset.StandardCharsets;
74  import java.util.ArrayList;
75  import java.util.Enumeration;
76  import java.util.List;
77  import java.util.Map;
78  
79  import javax.servlet.http.HttpServletRequest;
80  
81  import org.apache.commons.fileupload.FileItem;
82  import org.apache.commons.fileupload.FileUploadException;
83  import org.apache.commons.lang3.StringUtils;
84  
85  /**
86   * The class manage pluginwizard Page
87   */
88  @Controller( xpageName = "pluginwizard", pagePathI18nKey = "pluginwizard.pagePathLabel", pageTitleI18nKey = "pluginwizard.pageTitle" )
89  public class PluginWizardApp extends MVCApplication implements Serializable
90  {
91      /**
92       * 
93       */
94      private static final long serialVersionUID = 1L;
95      // Constants
96      private static final String MARK_PLUGIN_ID = "plugin_id";
97      private static final String MARK_PLUGIN_MODEL = "plugin_model";
98  
99      // Management Bookmarks
100     private static final String MARK_PLUGIN_PORTLETS = "plugin_portlets";
101     private static final String MARK_PLUGIN_APPLICATIONS = "plugin_applications";
102     private static final String MARK_PLUGIN_REST = "plugin_rest";
103     private static final String MARK_ADMIN_FEATURES = "admin_features";
104     private static final String MARK_BUSINESS_CLASSES = "business_classes";
105     private static final String MARK_BUSINESS_CLASS = "business_class";
106     private static final String MARK_BUSINESS_CLASS_ID = "business_class_id";
107     private static final String MARK_BUSINESS_CLASSES_COMBO = "combo_business_classes";
108     private static final String MARK_ATTRIBUTE_TYPE_COMBO = "combo_attribute_type";
109     private static final String MARK_SCHEMES_COMBO = "combo_schemes";
110     private static final String MARK_ATTRIBUTES_LIST = "attributes_list";
111     private static final String MARK_WORKFLOW_CONFIGURATION = "configuration";
112     private static final String MARK_PROJECT_TYPE = "project_type";
113 
114     // Modification bookmarks
115     private static final String MARK_FEATURE = "feature";
116     private static final String MARK_ATTRIBUTE = "attribute";
117     private static final String MARK_APPLICATION = "application";
118     private static final String MARK_PORTLET = "portlet";
119     private static final String TEMPLATE_CREATE_PLUGIN = "/skin/plugins/pluginwizard/pluginwizard_create_plugin.html";
120     private static final String TEMPLATE_CREATE_PLUGIN_DESCRIPTION = "/skin/plugins/pluginwizard/pluginwizard_create_plugin_description.html";
121     private static final String TEMPLATE_MODIFY_PLUGIN_DESCRIPTION = "/skin/plugins/pluginwizard/pluginwizard_modify_plugin_description.html";
122     private static final String TEMPLATE_CREATE_WORKFLOW_CONFIGURATION = "/skin/plugins/pluginwizard/pluginwizard_create_workflow_configuration.html";
123     private static final String TEMPLATE_MODIFY_WORKFLOW_CONFIGURATION = "/skin/plugins/pluginwizard/pluginwizard_modify_workflow_configuration.html";
124     private static final String TEMPLATE_MODIFY_PLUGIN = "/skin/plugins/pluginwizard/pluginwizard_modify_plugin.html";
125     private static final String TEMPLATE_MODIFY_BUSINESS_CLASS = "/skin/plugins/pluginwizard/pluginwizard_modify_business_class.html";
126     private static final String TEMPLATE_MANAGE_ADMIN_FEATURES = "/skin/plugins/pluginwizard/pluginwizard_manage_admin_features.html";
127     private static final String TEMPLATE_MANAGE_PLUGIN_PORTLETS = "/skin/plugins/pluginwizard/pluginwizard_manage_portlets.html";
128     private static final String TEMPLATE_MANAGE_PLUGIN_APPLICATIONS = "/skin/plugins/pluginwizard/pluginwizard_manage_applications.html";
129     private static final String TEMPLATE_MANAGE_BUSINESS_CLASSES = "/skin/plugins/pluginwizard/pluginwizard_manage_business_classes.html";
130     private static final String TEMPLATE_MANAGE_REST = "/skin/plugins/pluginwizard/pluginwizard_manage_rest.html";
131     private static final String TEMPLATE_GET_RECAPITULATE = "/skin/plugins/pluginwizard/pluginwizard_plugin_recapitulate.html";
132     private static final String TEMPLATE_CREATE_CONFIGURATION_CLASS = "/skin/plugins/pluginwizard/pluginwizard_create_configuration_class.html";
133     private static final String TEMPLATE_MODIFY_CONFIGURATION_CLASS = "/skin/plugins/pluginwizard/pluginwizard_modify_configuration_class.html";
134 
135     // CREATE
136     private static final String TEMPLATE_CREATE_ADMIN_FEATURE = "/skin/plugins/pluginwizard/pluginwizard_create_admin_feature.html";
137     private static final String TEMPLATE_CREATE_PLUGIN_PORTLET = "/skin/plugins/pluginwizard/pluginwizard_create_portlet.html";
138     private static final String TEMPLATE_CREATE_PLUGIN_APPLICATION = "/skin/plugins/pluginwizard/pluginwizard_create_application.html";
139     private static final String TEMPLATE_CREATE_BUSINESS_CLASS = "/skin/plugins/pluginwizard/pluginwizard_create_business_class.html";
140     private static final String TEMPLATE_CREATE_ATTRIBUTE = "/skin/plugins/pluginwizard/pluginwizard_create_attribute.html";
141     private static final String PARAM_PROJECT_TYPE = "type";
142     private static final String PROJECT_TYPE_PLUGIN = "PLUGIN";
143     private static final String PROJECT_TYPE_MODULE = "MODULE";
144     private static final String PROJECT_TYPE_WORKFLOW_TASK = "WORKFLOWTASK";
145 
146     // MODIFY
147     private static final String TEMPLATE_MODIFY_ATTRIBUTE = "/skin/plugins/pluginwizard/pluginwizard_modify_attribute.html";
148     private static final String TEMPLATE_MODIFY_ADMIN_FEATURE = "/skin/plugins/pluginwizard/pluginwizard_modify_admin_feature.html";
149     private static final String TEMPLATE_MODIFY_PLUGIN_PORTLET = "/skin/plugins/pluginwizard/pluginwizard_modify_portlet.html";
150     private static final String TEMPLATE_MODIFY_PLUGIN_APPLICATION = "/skin/plugins/pluginwizard/pluginwizard_modify_application.html";
151     private static final String TEMPLATE_MESSAGE_BOX_CONFIRMATION = "/skin/plugins/pluginwizard/message_confirmation.html";
152     private static final String TEMPLATE_MESSAGE_BOX_EXISTS = "/skin/plugins/pluginwizard/message_exists.html";
153     private static final String PARAM_ACTION = "action";
154     private static final String PARAM_VIEW = "view";
155     private static final String PARAM_PAGE = "page";
156     private static final String PARAM_FILE = "file";
157     private static final String PARAM_BUSINESS_CLASS_ID = "business_class_id";
158     private static final String PARAM_ATTRIBUTE_ID = "attribute_id";
159     private static final String PARAM_FEATURE_ID = "feature_id";
160     private static final String PARAM_APPLICATION_ID = "application_id";
161     private static final String PARAM_PORTLET_ID = "portletId";
162     private static final String PARAM_REFRESH = "refresh";
163     private static final String PARAM_ID_BUSINESS_CLASS = "id_business_class";
164 
165     // PLUGIN DESCRIPTION
166     private static final String VIEW_CREATE_PLUGIN = "createPlugin";
167     private static final String VIEW_MODIFY_PLUGIN = "modifyPlugin";
168     private static final String VIEW_CREATE_DESCRIPTION = "createDescription";
169     private static final String VIEW_MODIFY_DESCRIPTION = "modifyDescription";
170     private static final String ACTION_CREATE_PLUGIN = "createPlugin";
171     private static final String ACTION_LOAD_PLUGIN = "loadPlugin";
172     private static final String ACTION_DESCRIPTION_PREVIOUS = "descriptionPrevious";
173     private static final String ACTION_DESCRIPTION_NEXT = "descriptionNext";
174     private static final String ACTION_RESET_DATA = "resetData";
175     private static final String PROPERTY_SEARCH_DUPLICATES = "pluginwizard.searchDuplicates";
176 
177     //CONFIGURATION
178     private static final String VIEW_CREATE_WORKFLOW_CONFIGURATION = "createWorkflowConfiguration";
179     private static final String VIEW_MODIFY_WORKFLOW_CONFIGURATION = "modifyWorkflowConfiguration";
180     private static final String ACTION_WORKFLOW_CONFIGURATION_NEXT = "configurationNext";
181     private static final String ACTION_MODIFY_CONFIGURATION_CLASS = "modifyConfigurationClass";
182 
183     // REST
184     private static final String VIEW_MANAGE_REST = "manageRest";
185     private static final String ACTION_MODIFY_REST_BACK = "modifyRestBack";
186     private static final String ACTION_MODIFY_REST_NEXT = "modifyRestNext";
187 
188     // ADMIN FEATURES
189     private static final String VIEW_MANAGE_ADMIN_FEATURES = "manageAdminFeatures";
190     private static final String VIEW_CREATE_ADMIN_FEATURE = "createAdminFeature";
191     private static final String VIEW_MODIFY_ADMIN_FEATURE = "modifyAdminFeature";
192     private static final String ACTION_CREATE_ADMIN_FEATURE = "createAdminFeature";
193     private static final String ACTION_MODIFY_ADMIN_FEATURE = "modifyAdminFeature";
194     private static final String ACTION_CONFIRM_REMOVE_ADMIN_FEATURE = "confirmRemoveAdminFeature";
195     private static final String ACTION_REMOVE_ADMIN_FEATURE = "removeAdminFeature";
196     private static final String PROPERTY_CONFIRM_REMOVE_FEATURE_MESSAGE = "pluginwizard.siteMessage.confirmRemoveFeature.alertMessage";
197 
198     // BUSINESS CLASS
199     private static final String VIEW_MANAGE_BUSINESS_CLASSES = "manageBusinessClasses";
200     private static final String VIEW_CREATE_BUSINESS_CLASS = "createBusinessClass";
201     private static final String VIEW_MODIFY_BUSINESS_CLASS = "modifyBusinessClass";
202     private static final String ACTION_CREATE_BUSINESS_CLASS = "createBusinessClass";
203     private static final String ACTION_MODIFY_BUSINESS_CLASS = "modifyBusinessClass";
204     private static final String ACTION_CONFIRM_REMOVE_BUSINESS_CLASS = "confirmRemoveBusinessClass";
205     private static final String ACTION_REMOVE_BUSINESS_CLASS = "removeBusinessClass";
206     private static final String ACTION_PREVIOUS_BUSINESS_CLASS = "previousBusinessClass";
207     private static final String PROPERTY_CONFIRM_REMOVE_BUSINESS_CLASS_MESSAGE = "pluginwizard.siteMessage.confirmRemoveBusinessClass.title";
208     private static final String VIEW_CREATE_CONFIGURATION_CLASS = "createConfigurationClass";
209     private static final String VIEW_MODIFY_CONFIGURATION_CLASS = "modifyConfigurationClass";
210     private static final String ACTION_CREATE_CONFIGURATION_CLASS = "createConfigurationClass";
211     private static final String ACTION_NEXT_MANAGE_CONFIGURATION_CLASS = "nextManageConfigurationClass";
212     private static final String ACTION_VALIDATE_CONFIGURATION_CLASS = "validateConfigurationClass";
213     private static final String PREFIX_WORKFLOW_TASK_TABLE = "workflow_task_";
214 
215     // ATTRIBUTE
216     private static final String VIEW_CREATE_ATTRIBUTE = "createAttribute";
217     private static final String VIEW_MODIFY_ATTRIBUTE = "modifyAttribute";
218     private static final String ACTION_CREATE_ATTRIBUTE = "createAttribute";
219     private static final String ACTION_MODIFY_ATTRIBUTE = "modifyAttribute";
220     private static final String ACTION_CONFIRM_REMOVE_ATTRIBUTE = "confirmRemoveAttribute";
221     private static final String ACTION_REMOVE_ATTRIBUTE = "removeAttribute";
222     private static final String ACTION_VALIDATE_ATTRIBUTES = "validateAttributes";
223     private static final String PROPERTY_CONFIRM_REMOVE_ATTRIBUTE_MESSAGE = "pluginwizard.siteMessage.confirmRemoveAttribute.alertMessage";
224 
225     // APPLICATION
226     private static final String VIEW_MANAGE_APPLICATIONS = "manageApplications";
227     private static final String VIEW_CREATE_APPLICATION = "createApplication";
228     private static final String VIEW_MODIFY_APPLICATION = "modifyApplication";
229     private static final String ACTION_CREATE_APPLICATION = "createApplication";
230     private static final String ACTION_MODIFY_APPLICATION = "modifyApplication";
231     private static final String ACTION_CONFIRM_REMOVE_APPLICATION = "confirmRemoveApplication";
232     private static final String ACTION_REMOVE_APPLICATION = "removeApplication";
233     private static final String PROPERTY_CONFIRM_REMOVE_APPLICATION_MESSAGE = "pluginwizard.siteMessage.confirmRemoveApplication.title";
234 
235     // PORTLET
236     private static final String VIEW_MANAGE_PORTLETS = "managePortlets";
237     private static final String VIEW_CREATE_PORTLET = "createPortlet";
238     private static final String VIEW_MODIFY_PORTLET = "modifyPortlet";
239     private static final String ACTION_CREATE_PORTLET = "createPortlet";
240     private static final String ACTION_MODIFY_PORTLET = "modifyPortlet";
241     private static final String ACTION_CONFIRM_REMOVE_PORTLET = "confirmRemovePortlet";
242     private static final String ACTION_REMOVE_PORTLET = "removePortlet";
243     private static final String PROPERTY_CONFIRM_REMOVE_PORTLET_MESSAGE = "pluginwizard.siteMessage.confirmRemovePortlet.alertMessage";
244 
245     // RECAPITULATE
246     private static final String VIEW_RECAPITULATE = "recapitulate";
247     private static final String JSP_PAGE_PORTAL = "jsp/site/Portal.jsp";
248     private static final String PLUGIN_NAME = "pluginwizard";
249 
250     // ERRORS
251     public static final String ERROR_TABLE_PREFIX = "pluginwizard.error.attribute.tablePrefix";
252     public static final String ERROR_WORKFLOW_TASK_TABLE_PREFIX = "pluginwizard.error.attribute.tablePrefixWorkflowTask";
253     public static final String ERROR_PRIMARY_TYPE = "pluginwizard.error.attribute.primaryType";
254     public static final String ERROR_DESCRIPTION_TYPE = "pluginwizard.error.attribute.descriptionType";
255     public static final String ERROR_LOAD_PLUGIN = "pluginwizard.error.plugin.file";
256     public static final String ERROR_MODULE_NAME = "pluginwizard.error.module.name.pattern";
257     public static final String ERROR_PLUGIN_NAME = "pluginwizard.error.plugin.name.pattern";
258     public static final String ERROR_FEATURE_RIGHT_DUPLICATE = "pluginwizard.error.feature.right.duplicate";
259     public static final String ERROR_FEATURE_TECH_NAME_DUPLICATE = "pluginwizard.error.feature.name.duplicate";
260     public static final String ERROR_FEATURE_TITLE_DUPLICATE = "pluginwizard.error.feature.title.duplicate";
261     public static final String ERROR_INSUFFICIENT_ATTRIBUTES = "pluginwizard.error.attribute.insufficientAttributes";
262     public static final String ERROR_ATTRIBUTE_NAME_DUPLICATE = "pluginwizard.error.attribute.name.duplicate";
263     public static final String ERROR_BUSINESS_CLASS_NAME_DUPLICATE = "pluginwizard.error.businessClass.class.duplicate";
264     public static final String ERROR_BUSINESS_CLASS_TABLE_NAME_DUPLICATE = "pluginwizard.error.businessClass.tableName.duplicate";
265     public static final String ERROR_BUSINESS_CLASS_PLURAL_NAME_DUPLICATE = "pluginwizard.error.businessClass.pluralBusinessClass.duplicate";
266     public static final String ERROR_APPLICATION_NAME_DUPLICATE = "pluginwizard.error.application.name.duplicate";
267     public static final String ERROR_APPLICATION_CLASS_DUPLICATE = "pluginwizard.error.application.class.duplicate";
268     public static final String ERROR_FEATURE_NO_BUSINESS_CLASS = "pluginwizard.error.feature.businessClass.noBusinessClass";
269     public static final String ERROR_APPLICATION_NO_BUSINESS_CLASS = "pluginwizard.error.application.businessClass.noBusinessClass";
270     public static final String ERROR_PORTLET_CLASS_NAME_DUPLICATE = "pluginwizard.error.portlet.class.duplicate";
271     public static final String ERROR_PORTLET_TYPE_DUPLICATE = "pluginwizard.error.portlet.type.duplicate";
272     public static final String ERROR_PORTLET_JSP_NAME_DUPLICATE = "pluginwizard.error.portlet.jspBaseName.duplicate";
273     public static final String ERROR_UNIQUE_CONFIGURATION_CLASSE = "pluginwizard.error.configurationClass.class.unique";
274     public static final String ERROR_MANDATORY_CONFIGURATION_CLASSE = "pluginwizard.error.configurationClass.class.mandatory";
275 
276     // NOTIFICATIONS
277     public static final String INFO_SESSION_EXPIRED = "pluginwizard.info.sessionExpired";
278     public static final String INFO_PLUGIN_CREATED = "pluginwizard.info.pluginCreated";
279     public static final String INFO_DATA_RESET = "pluginwizard.info.dataReset";
280     public static final String INFO_FEATURE_CREATED = "pluginwizard.info.feature.created";
281     public static final String INFO_FEATURE_UPDATED = "pluginwizard.info.feature.updated";
282     public static final String INFO_FEATURE_DELETED = "pluginwizard.info.feature.deleted";
283     public static final String INFO_BUSINESS_CLASS_CREATED = "pluginwizard.info.businessClass.created";
284     public static final String INFO_BUSINESS_CLASS_UPDATED = "pluginwizard.info.businessClass.updated";
285     public static final String INFO_BUSINESS_CLASS_DELETED = "pluginwizard.info.businessClass.deleted";
286     public static final String INFO_ATTRIBUTE_CREATED = "pluginwizard.info.attribute.created";
287     public static final String INFO_ATTRIBUTE_UPDATED = "pluginwizard.info.attribute.updated";
288     public static final String INFO_ATTRIBUTE_DELETED = "pluginwizard.info.attribute.deleted";
289     public static final String INFO_APPLICATION_CREATED = "pluginwizard.info.application.created";
290     public static final String INFO_APPLICATION_UPDATED = "pluginwizard.info.application.updated";
291     public static final String INFO_APPLICATION_DELETED = "pluginwizard.info.application.deleted";
292     public static final String INFO_PORTLET_CREATED = "pluginwizard.info.portlet.created";
293     public static final String INFO_PORTLET_UPDATED = "pluginwizard.info.portlet.updated";
294     public static final String INFO_PORTLET_DELETED = "pluginwizard.info.portlet.deleted";
295 
296     private int _nPluginId;
297     private String _strPluginName;
298     private String _strProjectType;
299     private DescriptionFormBean _description;
300     private ConfigurationFormBean _configuration;
301     private Feature _feature;
302     private BusinessClassFormBean _businessClass;
303     private Attribute _attribute;
304     private Application _application;
305     private Portlet _portlet;
306     private Rest _rest;
307 
308     /**
309      * {@inheritDoc }
310      */
311     @Override
312     public XPage getPage( HttpServletRequest request, int nMode, Plugin plugin ) throws SiteMessageException, UserNotSignedException
313     {
314         if ( _nPluginId == 0 )
315         {
316             String strAction = MVCUtils.getAction( request );
317             String strView = MVCUtils.getView( request );
318 
319             if ( !ACTION_LOAD_PLUGIN.equals( strAction ) && !ACTION_CREATE_PLUGIN.equals( strAction ) && !VIEW_CREATE_PLUGIN.equals( strView ) )
320             {
321                 if ( ( strAction != null ) || ( strView != null ) )
322                 {
323                     addInfo( INFO_SESSION_EXPIRED, getLocale( request ) );
324                 }
325 
326                 return getCreatePlugin( request );
327             }
328         }
329 
330         return super.getPage( request, nMode, plugin );
331     }
332 
333     // //////////////////////////////////////////////////////////////////////////
334     // PLUGIN CREATION
335 
336     /**
337      * The Creation form of the plugin
338      *
339      * @param request
340      *            The Http Request
341      * @return The html code of the plugin
342      */
343     @View( value = VIEW_CREATE_PLUGIN, defaultView = true )
344     public XPage getCreatePlugin( HttpServletRequest request )
345     {
346         return getXPage( TEMPLATE_CREATE_PLUGIN, getLocale( request ) );
347     }
348 
349     /**
350      * The modification form of the plugin
351      *
352      * @param request
353      *            The Http Request
354      * @return The html code of the creation of plugin description
355      */
356     @View( VIEW_MODIFY_PLUGIN )
357     public XPage getModifyPlugin( HttpServletRequest request )
358     {
359         return getXPage( TEMPLATE_MODIFY_PLUGIN, getLocale( request ), getPluginModel( ) );
360     }
361 
362     /**
363      * The modification action of the plugin
364      *
365      * @param request
366      *            The Http Request
367      * @return The plugin id
368      */
369     @Action( ACTION_CREATE_PLUGIN )
370     public XPage doCreatePlugin( HttpServletRequest request )
371     {
372 
373         FormBean form = getFormBean( request );
374         populate( form, request );
375 
376         if ( !validateBean( form, getLocale( request ) ) )
377         {
378             return redirectView( request, VIEW_CREATE_PLUGIN );
379         }
380 
381         _strPluginName = form.getName( );
382 
383         // search duplicates plugin names
384         if ( AppPropertiesService.getPropertyBoolean( PROPERTY_SEARCH_DUPLICATES, false ) )
385         {
386             _nPluginId = ModelHome.exists( form.getName( ) );
387         }
388         else
389         {
390             _nPluginId = -1;
391         }
392 
393         // The plugin doesn't exists
394         if ( _nPluginId == -1 )
395         {
396             addInfo( INFO_PLUGIN_CREATED, getLocale( request ) );
397             _nPluginId = ModelService.createModel( form.getName( ) );
398             _strProjectType = form.getType( );
399             _configuration = null;
400 
401             return redirectView( request, VIEW_CREATE_DESCRIPTION );
402         }
403 
404         return redirectMessageBox( request, buildExistsMessageBox( ) );
405     }
406 
407     private FormBean getFormBean( HttpServletRequest request )
408     {
409 
410         String projectType = request.getParameter( PARAM_PROJECT_TYPE );
411 
412         if ( StringUtils.isBlank( projectType ) || StringUtils.equals( projectType, PROJECT_TYPE_PLUGIN ) )
413         {
414             return new PluginNameFormBean( );
415         }
416         else
417             if ( StringUtils.equals( projectType, PROJECT_TYPE_MODULE ) )
418             {
419                 return new ModuleNameFormBean( );
420             }
421             else
422                 if ( StringUtils.equals( projectType, PROJECT_TYPE_WORKFLOW_TASK ) )
423                 {
424                     return new WorkflowTaskNameFormBean( );
425                 }
426                 else
427                 {
428                     return new PluginNameFormBean( );
429                 }
430 
431     }
432 
433     /**
434      * The load action of the plugin
435      *
436      * @param request
437      *            The Http Request
438      * @return The plugin id
439      * @throws org.apache.commons.fileupload.FileUploadException
440      */
441     @Action( ACTION_LOAD_PLUGIN )
442     public XPage doLoadPlugin( HttpServletRequest request ) throws FileUploadException
443     {
444         MultipartHttpServletRequest multipartRequest = ( MultipartHttpServletRequest ) request;
445         FileItem fileItem = multipartRequest.getFile( PARAM_FILE );
446 
447         if ( fileItem.getName( ) == null || fileItem.getName( ).isEmpty( ) )
448         {
449             addError( ERROR_LOAD_PLUGIN, getLocale( request ) );
450             return redirectView( request, VIEW_CREATE_PLUGIN );
451         }
452 
453         String strJson = new String( fileItem.get( ), StandardCharsets.UTF_8 );
454         PluginModel pluginModel = MapperService.readJson( strJson );
455 
456         _nPluginId = ModelService.savePluginModelFromJson( pluginModel );
457         _description = ModelService.getDescription( _nPluginId );
458         _strPluginName = ( "MODULE".equals( pluginModel.getType( ) ) ? pluginModel.getModuleName( ) : pluginModel.getPluginName( ) );
459         _strProjectType = _description.getType( );
460         _configuration = null;
461 
462         return redirectView( request, VIEW_MODIFY_DESCRIPTION );
463     }
464 
465     @Action( ACTION_RESET_DATA )
466     public XPage doResetData( HttpServletRequest request )
467     {
468         ModelService.removeAll( _nPluginId );
469         addInfo( INFO_DATA_RESET, getLocale( request ) );
470 
471         return redirectView( request, VIEW_CREATE_PLUGIN );
472     }
473 
474     // //////////////////////////////////////////////////////////////////////////
475     // DESCRIPTION
476 
477     /**
478      * Gets the create plugin description page
479      *
480      * @param request
481      *            The HTTP request
482      * @return The page
483      */
484     @View( VIEW_CREATE_DESCRIPTION )
485     public XPage getCreatePluginDescription( HttpServletRequest request )
486     {
487         Map<String, Object> model = getPluginModel( );
488 
489         _description = new DescriptionFormBean( );
490 
491         for ( ConfigurationKey key : ConfigurationKeyHome.getConfigurationKeysList( ) )
492         {
493             model.put( key.getKeyDescription( ).trim( ), key.getKeyValue( ) );
494         }
495 
496         model.put( MARK_PLUGIN_ID, _nPluginId );
497         model.put( MARK_PROJECT_TYPE, _strProjectType );
498 
499         return getXPage( TEMPLATE_CREATE_PLUGIN_DESCRIPTION, getLocale( request ), model );
500     }
501 
502     /**
503      * The modification form of the plugin description
504      *
505      * @param request
506      *            The Http Request
507      * @return The html code of the creation of plugin description
508      */
509     @View( VIEW_MODIFY_DESCRIPTION )
510     public XPage getModifyPluginDescription( HttpServletRequest request )
511     {
512         Map<String, Object> model = getPluginModel( );
513         _description = ( _description != null ) ? _description : ModelService.getDescription( _nPluginId );
514         model.put( MARK_PLUGIN_MODEL, _description );
515         model.put( MARK_PROJECT_TYPE, _strProjectType );
516 
517         return getXPage( TEMPLATE_MODIFY_PLUGIN_DESCRIPTION, getLocale( request ), model );
518     }
519 
520     /**
521      * Action for leaving description form with previous button
522      *
523      * @param request
524      *            The Http Request
525      * @return The XPage
526      */
527     @Action( ACTION_DESCRIPTION_PREVIOUS )
528     public XPage doDescritionPrevious( HttpServletRequest request )
529     {
530         return redirectView( request, VIEW_CREATE_PLUGIN );
531     }
532 
533     /**
534      * Action for leaving description form with previous button
535      *
536      * @param request
537      *            The Http Request
538      * @return The XPage
539      */
540     @Action( ACTION_DESCRIPTION_NEXT )
541     public XPage doDescritionNext( HttpServletRequest request )
542     {
543         if( StringUtils.equalsIgnoreCase( _strProjectType, PROJECT_TYPE_WORKFLOW_TASK ) ) 
544         {
545     		return doModifyPlugin( request, VIEW_CREATE_WORKFLOW_CONFIGURATION );
546     	}
547 
548         return doModifyPlugin( request, VIEW_MANAGE_BUSINESS_CLASSES );
549     }
550 
551     /**
552      * Modify plugin's info
553      * 
554      * @param request
555      *            The HTTP request
556      * @param strView
557      *            The view
558      * @return The page
559      */
560     private XPage doModifyPlugin( HttpServletRequest request, String strView )
561     {
562         populate( _description, request );
563         
564         //Set project type with project type entry on the previous page.
565         _description.setType( _strProjectType );
566         _description.setModule( StringUtils.equalsIgnoreCase( _strProjectType, PROJECT_TYPE_MODULE ) );
567         
568         if ( !validateBean( _description, getLocale( request ) ) )
569         {	
570             return redirectView( request, VIEW_MODIFY_DESCRIPTION );
571         }
572 
573         _description.setPluginClass( "fr.paris.lutece.portal.service.plugin.PluginDefaultImplementation" );
574         
575         if( StringUtils.equals( _strProjectType, PROJECT_TYPE_WORKFLOW_TASK ) )
576         {
577         	_description.setPluginIconUrl( "images/admin/skin/plugins/"+ _strPluginName +"/feature_default_icon.png" );
578         }
579         else
580         {
581         	_description.setPluginIconUrl( "images/admin/skin/feature_default_icon.png" );
582         }
583         
584         ModelService.updateDescription( _nPluginId, _description );
585 
586         return redirectView( request, strView );
587     }
588 
589     // //////////////////////////////////////////////////////////////////////////
590     // CONFIGURATION
591     
592     /**
593      * The create form of the workflow configuration
594      *
595      * @param request
596      *            The Http Request
597      * @return The html code of the creation of workflow configuration
598      */
599     @View( VIEW_CREATE_WORKFLOW_CONFIGURATION )
600     public XPage getCreateWorkflowConfiguration( HttpServletRequest request )
601     {	
602     	_configuration = new ConfigurationFormBean( );
603     	
604     	Map<String, Object> model = getPluginModel( );
605     	
606         model.put( MARK_PLUGIN_ID, _nPluginId );
607         model.put( MARK_PROJECT_TYPE, _strProjectType );
608         
609         return getXPage( TEMPLATE_CREATE_WORKFLOW_CONFIGURATION, getLocale( request ), model );
610     }
611     
612     /**
613      * The modification form of the workflow configuration
614      *
615      * @param request
616      *            The Http Request
617      * @return The html code of the creation of workflow configuration
618      */
619     @View( VIEW_MODIFY_WORKFLOW_CONFIGURATION )
620     public XPage getModifyWorkflowConfiguration( HttpServletRequest request )
621     {
622         Map<String, Object> model = getPluginModel( );
623         
624         model.put( MARK_PLUGIN_ID, _nPluginId );
625         model.put( MARK_PROJECT_TYPE, _strProjectType );
626         
627         return getXPage( TEMPLATE_MODIFY_WORKFLOW_CONFIGURATION, getLocale( request ), model );
628     }
629     
630     /**
631      * The creation of an 
632      *
633      * @param request
634      *            The Http Request
635      * @return The XPage
636      */
637     @Action( ACTION_WORKFLOW_CONFIGURATION_NEXT )
638     public XPage doCreateWorkflowConfiguration( HttpServletRequest request )
639     {
640         populate( _configuration, request );
641         
642         //When task is automatic, WorkflowFormTaskRequired has to be equal to 0
643         if( StringUtils.equals( _configuration.getWorkflowTaskForAutomaticAction( ), "1" ) )
644         {
645         	_configuration.setWorkflowFormTaskRequired( "0" );
646         }
647         
648         if ( !validateBean( _configuration, getLocale( request ) ) )
649         {	     	
650             return redirectView( request, VIEW_MODIFY_WORKFLOW_CONFIGURATION );
651         }
652                 
653         ModelService.updateConfiguration( _nPluginId, _configuration );
654         
655         return redirectView( request, VIEW_MANAGE_BUSINESS_CLASSES );    
656     }
657 
658     // //////////////////////////////////////////////////////////////////////////
659     // ADMIN FEATURES
660     /**
661      * The management screen of the admin features
662      *
663      * @param request
664      *            The Http Request
665      * @return The html code of the admin features
666      */
667     @View( VIEW_MANAGE_ADMIN_FEATURES )
668     public XPage getManageAdminFeatures( HttpServletRequest request )
669     {
670         PluginModel pm = ModelService.getPluginModel( _nPluginId );
671 
672         Map<String, Object> model = getModel( );
673 
674         model.put( MARK_PLUGIN_ID, Integer.toString( _nPluginId ) );
675         model.put( MARK_ADMIN_FEATURES, pm.getFeatures( ) );
676         model.put( MARK_PROJECT_TYPE, _strProjectType );
677 
678         return getXPage( TEMPLATE_MANAGE_ADMIN_FEATURES, getLocale( request ), model );
679     }
680 
681     /**
682      * The creation form of the admin _feature
683      *
684      * @param request
685      *            The Http Request
686      * @return The html code of the admin _feature
687      */
688     @View( VIEW_CREATE_ADMIN_FEATURE )
689     public XPage getCreateAdminFeature( HttpServletRequest request )
690     {
691         PluginModel pm = ModelService.getPluginModel( _nPluginId );
692         _feature = ( _feature != null ) ? _feature : new Feature( );
693 
694         Map<String, Object> model = getPluginModel( );
695         model.put( MARK_ADMIN_FEATURES, pm.getFeatures( ) );
696         model.put( MARK_FEATURE, _feature );
697         model.put( MARK_BUSINESS_CLASSES_COMBO, ModelService.getComboBusinessClasses( _nPluginId ) );
698         model.put( MARK_PROJECT_TYPE, _strProjectType );        
699 
700         return getXPage( TEMPLATE_CREATE_ADMIN_FEATURE, getLocale( request ), model );
701     }
702 
703     /**
704      * The modification screen of the admin _feature
705      *
706      * @param request
707      *            The Http Request
708      * @return The html code of the admin _feature
709      */
710     @View( VIEW_MODIFY_ADMIN_FEATURE )
711     public XPage getModifyAdminFeature( HttpServletRequest request )
712     {
713         PluginModel pm = ModelService.getPluginModel( _nPluginId );
714         int nFeatureId = Integer.parseInt( request.getParameter( PARAM_FEATURE_ID ) );
715 
716         if ( ( _feature == null ) || ( _feature.getId( ) != nFeatureId ) )
717         {
718             _feature = ModelService.getFeature( _nPluginId, nFeatureId );
719         }
720 
721         Map<String, Object> model = getPluginModel( );
722         model.put( MARK_FEATURE, _feature );
723         model.put( MARK_ADMIN_FEATURES, pm.getFeatures( ) );
724         model.put( MARK_BUSINESS_CLASSES_COMBO, ModelService.getComboBusinessClasses( _nPluginId ) );
725         model.put( MARK_PROJECT_TYPE, _strProjectType );
726 
727         return getXPage( TEMPLATE_MODIFY_ADMIN_FEATURE, getLocale( request ), model );
728     }
729 
730     /**
731      * The creation of an admin _feature
732      *
733      * @param request
734      *            The Http Request
735      * @return The XPage
736      */
737     @Action( ACTION_CREATE_ADMIN_FEATURE )
738     public XPage doCreateAdminFeature( HttpServletRequest request )
739     {
740         populate( _feature, request );
741 
742         List<Integer> listBusinessClasses = getBusinessClasses( request );
743 
744         // Case where no business class is selected
745         if ( listBusinessClasses.isEmpty( ) )
746         {
747             addError( ERROR_FEATURE_NO_BUSINESS_CLASS, getLocale( request ) );
748             return redirectView( request, VIEW_CREATE_ADMIN_FEATURE );
749         }
750 
751         _feature.setIdBusinessClasses( listBusinessClasses );
752 
753         if ( !validateBean( _feature, getLocale( request ) ) )
754         {
755 
756             return redirectView( request, VIEW_CREATE_ADMIN_FEATURE );
757         }
758 
759         else
760             if ( QualityService.existsDuplicateFeatureFields( _feature, ModelService.getPluginModel( _nPluginId ).getFeatures( ) ) )
761             {
762 
763                 addDupplicateAdminFeatureErrorMessages( request );
764                 return redirectView( request, VIEW_CREATE_ADMIN_FEATURE );
765             }
766 
767             else
768             {
769                 ModelService.addFeature( _nPluginId, _feature );
770                 _feature = null;
771                 addInfo( INFO_FEATURE_CREATED, getLocale( request ) );
772 
773                 return redirectView( request, VIEW_MANAGE_ADMIN_FEATURES );
774             }
775     }
776 
777     /**
778      * The modification action of an admin _feature
779      *
780      * @param request
781      *            The Http Request
782      * @return The XPage
783      */
784     @Action( ACTION_MODIFY_ADMIN_FEATURE )
785     public XPage doModifyAdminFeature( HttpServletRequest request )
786     {
787         populate( _feature, request );
788 
789         List<Integer> listBusinessClasses = getBusinessClasses( request );
790 
791         // Case where no business class is selected
792         if ( listBusinessClasses.isEmpty( ) )
793         {
794             addError( ERROR_FEATURE_NO_BUSINESS_CLASS, getLocale( request ) );
795             return redirect( request, VIEW_MODIFY_ADMIN_FEATURE, PARAM_FEATURE_ID, _feature.getId( ) );
796         }
797 
798         _feature.setIdBusinessClasses( listBusinessClasses );
799 
800         if ( !validateBean( _feature, getLocale( request ) ) )
801         {
802             return redirect( request, VIEW_MODIFY_ADMIN_FEATURE, PARAM_FEATURE_ID, _feature.getId( ) );
803         }
804 
805         else
806             if ( QualityService.existsDuplicateFeatureFields( _feature, ModelService.getPluginModel( _nPluginId ).getFeatures( ) ) )
807             {
808 
809                 addDupplicateAdminFeatureErrorMessages( request );
810                 return redirect( request, VIEW_MODIFY_ADMIN_FEATURE, PARAM_FEATURE_ID, _feature.getId( ) );
811             }
812 
813             else
814             {
815                 ModelService.updateFeature( _nPluginId, _feature );
816                 _feature = null;
817                 addInfo( INFO_FEATURE_UPDATED, getLocale( request ) );
818 
819                 return redirectView( request, VIEW_MANAGE_ADMIN_FEATURES );
820             }
821     }
822 
823     /**
824      * The confirmation of the removal of an admin _feature
825      *
826      * @param request
827      *            The Http Request
828      * @return The XPage
829      */
830     @Action( ACTION_CONFIRM_REMOVE_ADMIN_FEATURE )
831     public XPage doConfirmRemoveAdminFeature( HttpServletRequest request )
832     {
833         UrlItem url = new UrlItem( JSP_PAGE_PORTAL );
834 
835         url.addParameter( PARAM_PAGE, PLUGIN_NAME );
836         url.addParameter( PARAM_ACTION, ACTION_REMOVE_ADMIN_FEATURE );
837         url.addParameter( PARAM_FEATURE_ID, request.getParameter( PARAM_FEATURE_ID ) );
838 
839         return redirectMessageBox( request,
840                 buildConfirmMessageBox( PROPERTY_CONFIRM_REMOVE_FEATURE_MESSAGE, url.getUrl( ), getViewFullUrl( VIEW_MANAGE_ADMIN_FEATURES ) ) );
841     }
842 
843     /**
844      * The removal screen of an admin _feature
845      *
846      * @param request
847      *            The Http Request
848      * @return The XPage
849      */
850     @Action( ACTION_REMOVE_ADMIN_FEATURE )
851     public XPage doRemoveAdminFeature( HttpServletRequest request )
852     {
853         int nFeatureId = Integer.parseInt( request.getParameter( PARAM_FEATURE_ID ) );
854         ModelService.removeFeature( _nPluginId, nFeatureId );
855         addInfo( INFO_FEATURE_DELETED, getLocale( request ) );
856 
857         return redirectView( request, VIEW_MANAGE_ADMIN_FEATURES );
858     }
859 
860     /**
861      * Add error duplicate admin feature messages to request
862      * 
863      * @param request
864      *            The Http Request
865      */
866 
867     private void addDupplicateAdminFeatureErrorMessages( HttpServletRequest request )
868     {
869 
870         if ( !QualityService.bValideUniqueFeatureTitle )
871         {
872             addError( ERROR_FEATURE_TITLE_DUPLICATE, getLocale( request ) );
873         }
874 
875         if ( !QualityService.bValideUniqueFeatureTechName )
876         {
877             addError( ERROR_FEATURE_TECH_NAME_DUPLICATE, getLocale( request ) );
878         }
879 
880         if ( !QualityService.bValideUniqueFeatureRight )
881         {
882             addError( ERROR_FEATURE_RIGHT_DUPLICATE, getLocale( request ) );
883         }
884 
885     }
886 
887     // //////////////////////////////////////////////////////////////////////////
888     // BUSINESS CLASSES
889     /**
890      * The management screen of business classes associated to the plugin which is generated
891      *
892      * @param request
893      *            The Http Request
894      * @return The html code of the management screen of the business classes
895      */
896     @View( VIEW_MANAGE_BUSINESS_CLASSES )
897     public XPage getManageBusinessClasses( HttpServletRequest request )
898     {
899         Map<String, Object> model = getModel( );
900         model.put( MARK_PLUGIN_ID, Integer.toString( _nPluginId ) );
901         model.put( MARK_BUSINESS_CLASSES, ModelService.getPluginModel( _nPluginId ).getBusinessClasses( ) );
902         model.put( MARK_PROJECT_TYPE, _strProjectType );
903 
904         return getXPage( TEMPLATE_MANAGE_BUSINESS_CLASSES, getLocale( request ), model );
905     }
906 
907     /**
908      * The creation form of a business class
909      *
910      * @param request
911      *            The Http Request
912      * @return The html code of the creation of a business class
913      */
914     @View( VIEW_CREATE_BUSINESS_CLASS )
915     public XPage getCreateBusinessClass( HttpServletRequest request )
916     {
917         _businessClass = ( _businessClass != null ) ? _businessClass : new BusinessClassFormBean( );
918 
919         Map<String, Object> model = getPluginModel( );
920 
921         model.put( MARK_BUSINESS_CLASS, _businessClass );
922         model.put( MARK_PROJECT_TYPE, _strProjectType );
923 
924         return getXPage( TEMPLATE_CREATE_BUSINESS_CLASS, getLocale( request ), model );
925     }
926 
927     /**
928      * Gets the modify business class page
929      *
930      * @param request
931      *            The HTTP request
932      * @return The page
933      */
934     @View( VIEW_MODIFY_BUSINESS_CLASS )
935     public XPage getModifyBusinessClass( HttpServletRequest request )
936     {
937         int nBusinessClassId = Integer.parseInt( request.getParameter( PARAM_BUSINESS_CLASS_ID ) );
938         String strRefresh = request.getParameter( PARAM_REFRESH );
939 
940         if ( ( _businessClass == null ) || ( _businessClass.getId( ) != nBusinessClassId ) || ( strRefresh != null ) )
941         {
942             _businessClass = ModelService.getFormBusinessClass( _nPluginId, nBusinessClassId );
943         }
944 
945         _attribute = null;
946 
947         Map<String, Object> model = getPluginModel( );
948         model.put( MARK_BUSINESS_CLASS, _businessClass );
949         model.put( MARK_ATTRIBUTES_LIST, ModelService.getBusinessClass( _nPluginId, nBusinessClassId ).getAttributes( ) );
950         model.put( MARK_PROJECT_TYPE, _strProjectType );
951 
952         return getXPage( TEMPLATE_MODIFY_BUSINESS_CLASS, getLocale( request ), model );
953     }
954 
955     /**
956      * The creation action of the business class
957      *
958      * @param request
959      *            The Http Request
960      * @return The business class id
961      */
962     @Action( ACTION_CREATE_BUSINESS_CLASS )
963     public XPage doCreateBusinessClass( HttpServletRequest request )
964     {
965         populate( _businessClass, request );
966 
967         boolean bValidateBean = validateBean( _businessClass, getLocale( request ) );
968         boolean bValidateTablePrefix = validateTablePrefix( request, _businessClass );
969         boolean bValid = bValidateBean && bValidateTablePrefix;
970 
971         if ( !bValid )
972         {
973             return redirectView( request, VIEW_CREATE_BUSINESS_CLASS );
974         }
975         else
976             if ( QualityService.existsDuplicateBusinessClassFields( _businessClass, ModelService.getPluginModel( _nPluginId ).getBusinessClasses( ) , true ) )
977             {
978                 addDupplicateBusinessClassErrorMessages( request );
979                 return redirectView( request, VIEW_CREATE_BUSINESS_CLASS );
980             }
981 
982         BusinessClass businessClass = ModelService.addBusinessClass( _nPluginId, _businessClass );
983         _businessClass = null;
984         addInfo( INFO_BUSINESS_CLASS_CREATED, getLocale( request ) );
985 
986         return redirect( request, VIEW_MODIFY_BUSINESS_CLASS, PARAM_BUSINESS_CLASS_ID, businessClass.getId( ) );
987     }
988 
989     /**
990      * The modification action for the business class
991      *
992      * @param request
993      *            The Http Request
994      * @return The XPage
995      */
996     @Action( ACTION_MODIFY_BUSINESS_CLASS )
997     public XPage doModifyBusinessClass( HttpServletRequest request )
998     {
999         populate( _businessClass, request );
1000 
1001         boolean bValidateBean = validateBean( _businessClass, getLocale( request ) );
1002         boolean bValidateTablePrefix = validateTablePrefix( request, _businessClass );
1003         boolean bValid = bValidateBean && bValidateTablePrefix;
1004 
1005         if ( !bValid )
1006         {
1007             return redirect( request, VIEW_MODIFY_BUSINESS_CLASS, PARAM_BUSINESS_CLASS_ID, _businessClass.getId( ) );
1008         }
1009         else
1010             if ( ModelService.getBusinessClass( _nPluginId, _businessClass.getId( ) ).getAttributes( ).size( ) < 1 )
1011             {
1012                 addError( ERROR_INSUFFICIENT_ATTRIBUTES, getLocale( request ) );
1013                 return redirect( request, VIEW_MODIFY_BUSINESS_CLASS, PARAM_BUSINESS_CLASS_ID, _businessClass.getId( ) );
1014             }
1015             else
1016                 if ( QualityService.existsDuplicateBusinessClassFields( _businessClass, ModelService.getPluginModel( _nPluginId ).getBusinessClasses( ), false ) )
1017                 {
1018                     addDupplicateBusinessClassErrorMessages( request );
1019                     return redirect( request, VIEW_MODIFY_BUSINESS_CLASS, PARAM_BUSINESS_CLASS_ID, _businessClass.getId( ) );
1020                 }
1021 
1022         ModelService.updateBusinessClass( _nPluginId, _businessClass );
1023         _businessClass = null;
1024         addInfo( INFO_BUSINESS_CLASS_UPDATED, getLocale( request ) );
1025 
1026         return redirectView( request, VIEW_MANAGE_BUSINESS_CLASSES );
1027     }
1028 
1029     /**
1030      * Validate table prefix
1031      * 
1032      * @param request
1033      *            The HTTP request
1034      * @param businessClass
1035      *            The Business class
1036      * @return True if OK
1037      */
1038     private boolean validateTablePrefix( HttpServletRequest request, BusinessClassFormBean businessClass )
1039     {
1040         Boolean isWorkflowTaskProject = StringUtils.equalsIgnoreCase( _strProjectType, PROJECT_TYPE_WORKFLOW_TASK );
1041     	String strTablePrefix = isWorkflowTaskProject ? PREFIX_WORKFLOW_TASK_TABLE : _strPluginName.replace( "-", "_" ) + "_";
1042     	
1043         boolean bValidate = businessClass.getBusinessTableName( ).startsWith( strTablePrefix );
1044 
1045         if ( !bValidate )
1046         {
1047             if( isWorkflowTaskProject )
1048         	{
1049         		addError( ERROR_WORKFLOW_TASK_TABLE_PREFIX, getLocale( request ) );
1050         	}
1051         	else
1052         	{
1053         		addError( ERROR_TABLE_PREFIX, getLocale( request ) );
1054         	}
1055         }
1056 
1057         return bValidate;
1058     }
1059 
1060     /**
1061      * The confirmation of a business class removal
1062      *
1063      * @param request
1064      *            The Http Request
1065      * @return The XPage
1066      */
1067     @Action( ACTION_CONFIRM_REMOVE_BUSINESS_CLASS )
1068     public XPage doConfirmRemoveBusinessClass( HttpServletRequest request )
1069     {
1070         String strBusinessClassId = request.getParameter( PARAM_BUSINESS_CLASS_ID );
1071         UrlItem url = new UrlItem( JSP_PAGE_PORTAL );
1072         url.addParameter( PARAM_PAGE, PLUGIN_NAME );
1073         url.addParameter( PARAM_ACTION, ACTION_REMOVE_BUSINESS_CLASS );
1074         url.addParameter( PARAM_BUSINESS_CLASS_ID, strBusinessClassId );
1075         url.addParameter( PARAM_FEATURE_ID, request.getParameter( PARAM_FEATURE_ID ) );
1076 
1077         return redirectMessageBox( request,
1078                 buildConfirmMessageBox( PROPERTY_CONFIRM_REMOVE_BUSINESS_CLASS_MESSAGE, url.getUrl( ), getViewFullUrl( VIEW_MANAGE_BUSINESS_CLASSES ) ) );
1079     }
1080 
1081     /**
1082      * The removal action of a plugin application
1083      *
1084      * @param request
1085      *            The Http Request
1086      * @return The XPage
1087      */
1088     @Action( ACTION_REMOVE_BUSINESS_CLASS )
1089     public XPage doRemoveBusinessClass( HttpServletRequest request )
1090     {
1091         int nBusinessClassId = Integer.parseInt( request.getParameter( PARAM_BUSINESS_CLASS_ID ) );
1092 
1093         ModelService.removeBusinessClass( _nPluginId, nBusinessClassId );
1094         addInfo( INFO_BUSINESS_CLASS_DELETED, getLocale( request ) );
1095 
1096         return redirectView( request, VIEW_MANAGE_BUSINESS_CLASSES );
1097     }
1098 
1099     /**
1100      * Add error duplicate business class messages to request
1101      * 
1102      * @param request
1103      *            The Http Request
1104      */
1105 
1106     private void addDupplicateBusinessClassErrorMessages( HttpServletRequest request )
1107     {
1108 
1109         if ( !QualityService.bValidUniqueBusinessClassName )
1110         {
1111             addError( ERROR_BUSINESS_CLASS_NAME_DUPLICATE, getLocale( request ) );
1112         }
1113 
1114         if ( !QualityService.bValidUniquePluralBusinessClassName )
1115         {
1116             addError( ERROR_BUSINESS_CLASS_PLURAL_NAME_DUPLICATE, getLocale( request ) );
1117         }
1118 
1119         if ( !QualityService.bValidUniqueTableName )
1120         {
1121             addError( ERROR_BUSINESS_CLASS_TABLE_NAME_DUPLICATE, getLocale( request ) );
1122         }
1123 
1124     }
1125 
1126     @Action( ACTION_PREVIOUS_BUSINESS_CLASS )
1127     public XPage doPreviousBusinessClass( HttpServletRequest request ) 
1128     {
1129 		
1130 	if ( StringUtils.equalsIgnoreCase(_strProjectType,PROJECT_TYPE_WORKFLOW_TASK ) ) 
1131         {
1132 		return redirectView( request, VIEW_MODIFY_WORKFLOW_CONFIGURATION );
1133 	}
1134 	
1135 	return redirectView( request, VIEW_MODIFY_DESCRIPTION );
1136     }
1137 	
1138 	
1139 	
1140 	   // //////////////////////////////////////////////////////////////////////////
1141     // CONFIGURATION CLASS
1142 	
1143 	/**
1144      * The creation form of a configuration class
1145      *
1146      * @param request
1147      *            The Http Request
1148      * @return The html code of the creation of a configuration class
1149      */
1150     @View( VIEW_CREATE_CONFIGURATION_CLASS )
1151     public XPage getCreateConfigurationClass( HttpServletRequest request )
1152     {
1153         _businessClass = ( _businessClass != null ) ? _businessClass : new BusinessClassFormBean( );
1154 
1155         Map<String, Object> model = getPluginModel( );
1156 
1157         model.put( MARK_BUSINESS_CLASS, _businessClass );
1158         model.put( MARK_WORKFLOW_CONFIGURATION, _configuration );
1159         model.put( MARK_PROJECT_TYPE, _strProjectType );
1160 
1161         return getXPage( TEMPLATE_CREATE_CONFIGURATION_CLASS, getLocale( request ), model );
1162     }
1163 
1164     /**
1165      * Gets the modify configuration class page
1166      *
1167      * @param request
1168      *            The HTTP request
1169      * @return The page
1170      */
1171     @View( VIEW_MODIFY_CONFIGURATION_CLASS )
1172     public XPage getModifyConfigurationClass( HttpServletRequest request )
1173     {
1174         int nBusinessClassId = Integer.parseInt( request.getParameter( PARAM_BUSINESS_CLASS_ID ) );
1175 
1176         _businessClass = ModelService.getFormBusinessClass( _nPluginId, nBusinessClassId );
1177         _attribute = null;
1178 
1179         Map<String, Object> model = getPluginModel( );
1180         model.put( MARK_BUSINESS_CLASS, _businessClass );
1181         model.put( MARK_ATTRIBUTES_LIST, ModelService.getBusinessClass( _nPluginId, nBusinessClassId ).getAttributes( ) );
1182         model.put( MARK_WORKFLOW_CONFIGURATION, _configuration );
1183         model.put( MARK_PROJECT_TYPE, _strProjectType );
1184         
1185         return getXPage( TEMPLATE_MODIFY_CONFIGURATION_CLASS, getLocale( request ), model );
1186     }
1187     
1188     /**
1189      * The creation action of the configuration class
1190      *
1191      * @param request
1192      *            The Http Request
1193      * @return The configuration class id
1194      */
1195     @Action( ACTION_CREATE_CONFIGURATION_CLASS )
1196     public XPage doCreateConfigurationClass( HttpServletRequest request )
1197     {	
1198     	 	 
1199         populate( _businessClass, request );
1200 
1201         boolean bValidateBean = validateBean( _businessClass, getLocale( request ) );
1202         boolean bValidateTablePrefix = validateTablePrefix( request, _businessClass );
1203         boolean bValid = bValidateBean && bValidateTablePrefix;
1204         
1205         if ( !bValid )
1206         {	
1207             return redirectView( request, VIEW_CREATE_CONFIGURATION_CLASS );
1208         }
1209         else if ( QualityService.existsDuplicateBusinessClassFields( _businessClass, ModelService.getPluginModel(_nPluginId).getBusinessClasses( ), true ) ) 
1210         {	
1211         	addDupplicateBusinessClassErrorMessages( request );
1212             return redirectView( request, VIEW_CREATE_CONFIGURATION_CLASS );
1213         }
1214 
1215         BusinessClass businessClass = ModelService.addBusinessClass( _nPluginId, _businessClass );
1216         _businessClass = null;
1217         addInfo( INFO_BUSINESS_CLASS_CREATED, getLocale( request ) );
1218 
1219         return redirect( request, VIEW_MODIFY_CONFIGURATION_CLASS, PARAM_BUSINESS_CLASS_ID, businessClass.getId( ) );
1220     }
1221     
1222     /**
1223      * The modification action for the configuration class
1224      *
1225      * @param request
1226      *            The Http Request
1227      * @return The XPage
1228      */
1229     @Action( ACTION_MODIFY_CONFIGURATION_CLASS )
1230     public XPage doModifyConfigurationClass( HttpServletRequest request )
1231     {
1232         populate( _businessClass, request );
1233 
1234         boolean bValidateBean = validateBean( _businessClass, getLocale( request ) );
1235         boolean bValidateTablePrefix = validateTablePrefix( request, _businessClass );
1236         boolean bValid = bValidateBean && bValidateTablePrefix;    	
1237     	
1238         if ( !bValid)
1239         {	
1240             return redirect( request, VIEW_MODIFY_CONFIGURATION_CLASS, PARAM_BUSINESS_CLASS_ID, _businessClass.getId( ) );
1241         }
1242         else if ( QualityService.existsDuplicateBusinessClassFields( _businessClass, ModelService.getPluginModel(_nPluginId).getBusinessClasses( ), false ) ) 
1243         {	
1244         	addDupplicateBusinessClassErrorMessages( request );
1245         	return redirect( request, VIEW_MODIFY_CONFIGURATION_CLASS, PARAM_BUSINESS_CLASS_ID, _businessClass.getId( ) );
1246         }
1247 
1248         ModelService.updateBusinessClass( _nPluginId, _businessClass );
1249         _businessClass = null;
1250         addInfo( INFO_BUSINESS_CLASS_UPDATED, getLocale( request ) );
1251         
1252         return redirectView( request, VIEW_MANAGE_BUSINESS_CLASSES );
1253     }
1254     
1255     /**
1256      * Check if a new configuration class can be created
1257      *
1258      * @param request
1259      *            The Http Request
1260      * @return The XPage
1261      */
1262     @Action( ACTION_NEXT_MANAGE_CONFIGURATION_CLASS )
1263     public XPage doNextManageConfigurationClass( HttpServletRequest request )
1264     {
1265 		if ( StringUtils.equalsIgnoreCase( _strProjectType, PROJECT_TYPE_WORKFLOW_TASK ) && ModelService.getPluginModel(_nPluginId).getBusinessClasses( ).size( ) > 0 )
1266 	    {	
1267 	   		addError( ERROR_UNIQUE_CONFIGURATION_CLASSE, getLocale( request ) );
1268 	        return redirectView( request, VIEW_MANAGE_BUSINESS_CLASSES );
1269 	    }
1270 		
1271 		
1272 		return redirectView( request, VIEW_CREATE_CONFIGURATION_CLASS );
1273     }
1274 	
1275     /**
1276      * Check if a new configuration class can be created
1277      *
1278      * @param request
1279      *            The Http Request
1280      * @return The XPage
1281      */
1282     @Action( ACTION_VALIDATE_CONFIGURATION_CLASS )
1283     public XPage doValidateConfigurationClass( HttpServletRequest request )
1284     {
1285 		if ( StringUtils.equalsIgnoreCase( _strProjectType, PROJECT_TYPE_WORKFLOW_TASK ) && ModelService.getPluginModel( _nPluginId ).getBusinessClasses( ).size( ) == 0 )
1286 	    {	
1287 	   		addError( ERROR_MANDATORY_CONFIGURATION_CLASSE, getLocale( request ) );
1288 	        return redirectView( request, VIEW_MANAGE_BUSINESS_CLASSES );
1289 	    }
1290 		
1291 		
1292 		return redirectView( request, VIEW_RECAPITULATE );
1293     }    
1294     
1295     // //////////////////////////////////////////////////////////////////////////
1296     // ATTRIBUTE
1297 
1298     /**
1299      * The creation form of the attribute associated to a business class
1300      *
1301      * @param request
1302      *            The Http Request
1303      * @return The XPage
1304      */
1305     @View( VIEW_CREATE_ATTRIBUTE )
1306     public XPage getCreateAttribute( HttpServletRequest request )
1307     {
1308         String strBusinessClassId = request.getParameter( PARAM_BUSINESS_CLASS_ID );
1309 
1310         if ( _attribute == null )
1311         {
1312             _attribute = new Attribute( );
1313         }
1314         
1315         Map<String, Object> model = getModel( );
1316         model.put( MARK_BUSINESS_CLASS_ID, strBusinessClassId );
1317         model.put( MARK_ATTRIBUTE_TYPE_COMBO, ModelService.getAttributeTypes( getLocale( request ) ) );
1318         model.put( MARK_WORKFLOW_CONFIGURATION, _configuration );
1319         model.put( MARK_ATTRIBUTE, _attribute );
1320         model.put( MARK_PROJECT_TYPE, _strProjectType );
1321 
1322         return getXPage( TEMPLATE_CREATE_ATTRIBUTE, getLocale( request ), model );
1323     }
1324 
1325     /**
1326      * The modification form of an attribute
1327      *
1328      * @param request
1329      *            The Http Request
1330      * @return The XPage
1331      */
1332     @View( VIEW_MODIFY_ATTRIBUTE )
1333     public XPage getModifyAttribute( HttpServletRequest request )
1334     {
1335         Map<String, Object> model = getModel( );
1336         int nIdBusinessClass = Integer.parseInt( request.getParameter( PARAM_BUSINESS_CLASS_ID ) );
1337         int nIdAttribute = Integer.parseInt( request.getParameter( PARAM_ATTRIBUTE_ID ) );
1338 
1339         if ( ( _attribute == null ) || ( _attribute.getId( ) != nIdAttribute ) )
1340         {
1341             _attribute = ModelService.getAttribute( _nPluginId, nIdBusinessClass, nIdAttribute );
1342         }
1343         
1344         model.put( MARK_PLUGIN_ID, _nPluginId );
1345         model.put( MARK_BUSINESS_CLASS_ID, nIdBusinessClass );
1346         model.put( MARK_ATTRIBUTE_TYPE_COMBO, ModelService.getAttributeTypes( getLocale( request ) ) );
1347         model.put( MARK_WORKFLOW_CONFIGURATION, _configuration );
1348         model.put( MARK_ATTRIBUTE, _attribute );
1349         model.put( MARK_PROJECT_TYPE, _strProjectType );
1350 
1351         return getXPage( TEMPLATE_MODIFY_ATTRIBUTE, getLocale( request ), model );
1352     }
1353 
1354     /**
1355      * The creation action of an attribute
1356      *
1357      * @param request
1358      *            The Http Request
1359      * @return The XPage
1360      */
1361     @Action( ACTION_CREATE_ATTRIBUTE )
1362     public XPage doCreateAttribute( HttpServletRequest request )
1363     {
1364         int nBusinessClassId = Integer.parseInt( request.getParameter( PARAM_BUSINESS_CLASS_ID ) );
1365         populate( _attribute, request );
1366 
1367         if ( !validateBean( _attribute, getLocale( request ) ) )
1368         {
1369             return redirect( request, VIEW_CREATE_ATTRIBUTE, PARAM_BUSINESS_CLASS_ID, nBusinessClassId, PARAM_ATTRIBUTE_ID, _attribute.getId( ) );
1370         }
1371         else
1372             if ( QualityService.existsDuplicateAttributeFields( _attribute, ModelService.getBusinessClass( _nPluginId, nBusinessClassId ).getAttributes( ) ) )
1373             {
1374 
1375                 addError( ERROR_ATTRIBUTE_NAME_DUPLICATE, getLocale( request ) );
1376                 return redirect( request, VIEW_CREATE_ATTRIBUTE, PARAM_BUSINESS_CLASS_ID, nBusinessClassId, PARAM_ATTRIBUTE_ID, _attribute.getId( ) );
1377             }
1378 
1379         ModelService.addAttribute( _nPluginId, nBusinessClassId, _attribute );
1380         _attribute = null;
1381         addInfo( INFO_ATTRIBUTE_CREATED, getLocale( request ) );
1382 
1383         if( StringUtils.equalsIgnoreCase( _strProjectType , PROJECT_TYPE_WORKFLOW_TASK ) )
1384     	{
1385     		return redirect( request, VIEW_MODIFY_CONFIGURATION_CLASS, PARAM_BUSINESS_CLASS_ID, nBusinessClassId, PARAM_REFRESH, 1  );
1386     	}
1387 
1388         return redirect( request, VIEW_MODIFY_BUSINESS_CLASS, PARAM_BUSINESS_CLASS_ID, nBusinessClassId, PARAM_REFRESH, 1 );
1389     }
1390 
1391     /**
1392      * The modification action for the attribute
1393      *
1394      * @param request
1395      *            The Http Request
1396      * @return The XPage
1397      */
1398     @Action( ACTION_MODIFY_ATTRIBUTE )
1399     public XPage doModifyAttribute( HttpServletRequest request )
1400     {
1401         int nBusinessClassId = Integer.parseInt( request.getParameter( PARAM_BUSINESS_CLASS_ID ) );
1402         // We reset boolean values provided by checkboxes : chabowes not checked can not be populated.
1403         _attribute.setNotNull( false );
1404         populate( _attribute, request );
1405 
1406         if ( !validateBean( _attribute, getLocale( request ) ) )
1407         {
1408             return redirect( request, VIEW_MODIFY_ATTRIBUTE, PARAM_BUSINESS_CLASS_ID, nBusinessClassId, PARAM_ATTRIBUTE_ID, _attribute.getId( ) );
1409         }
1410         else
1411             if ( QualityService.existsDuplicateAttributeFields( _attribute, ModelService.getBusinessClass( _nPluginId, nBusinessClassId ).getAttributes( ) ) )
1412             {
1413 
1414                 addError( ERROR_ATTRIBUTE_NAME_DUPLICATE, getLocale( request ) );
1415                 return redirect( request, VIEW_MODIFY_ATTRIBUTE, PARAM_BUSINESS_CLASS_ID, nBusinessClassId, PARAM_ATTRIBUTE_ID, _attribute.getId( ) );
1416             }
1417 
1418         ModelService.updateAttribute( _nPluginId, nBusinessClassId, _attribute );
1419         _attribute = null;
1420         addInfo( INFO_ATTRIBUTE_UPDATED, getLocale( request ) );
1421         
1422         if( StringUtils.equalsIgnoreCase( _strProjectType , PROJECT_TYPE_WORKFLOW_TASK ) )
1423     	{
1424     		return redirect( request, VIEW_MODIFY_CONFIGURATION_CLASS, PARAM_BUSINESS_CLASS_ID, nBusinessClassId, PARAM_REFRESH, 1  );
1425     	}
1426 
1427         return redirect( request, VIEW_MODIFY_BUSINESS_CLASS, PARAM_BUSINESS_CLASS_ID, nBusinessClassId, PARAM_REFRESH, 1 );
1428     }
1429 
1430     /**
1431      * The confirmation of the attribute removal
1432      *
1433      * @param request
1434      *            The Http Request
1435      * @return The XPage
1436      */
1437     @Action( ACTION_CONFIRM_REMOVE_ATTRIBUTE )
1438     public XPage getConfirmRemoveAttribute( HttpServletRequest request )
1439     {
1440         String strView = StringUtils.equalsIgnoreCase( _strProjectType , PROJECT_TYPE_WORKFLOW_TASK ) ? VIEW_MODIFY_CONFIGURATION_CLASS : VIEW_MODIFY_BUSINESS_CLASS;
1441     	
1442         UrlItem url = new UrlItem( JSP_PAGE_PORTAL );
1443         url.addParameter( PARAM_PAGE, PLUGIN_NAME );
1444         url.addParameter( PARAM_ACTION, ACTION_REMOVE_ATTRIBUTE );
1445         url.addParameter( PARAM_ATTRIBUTE_ID, request.getParameter( PARAM_ATTRIBUTE_ID ) );
1446         url.addParameter( PARAM_BUSINESS_CLASS_ID, request.getParameter( PARAM_BUSINESS_CLASS_ID ) );
1447 
1448         UrlItem urlBack = new UrlItem( JSP_PAGE_PORTAL );
1449         urlBack.addParameter( PARAM_PAGE, PLUGIN_NAME );
1450         urlBack.addParameter( PARAM_VIEW, strView );
1451         urlBack.addParameter( PARAM_BUSINESS_CLASS_ID, request.getParameter( PARAM_BUSINESS_CLASS_ID ) );
1452 
1453         return redirectMessageBox( request, buildConfirmMessageBox( PROPERTY_CONFIRM_REMOVE_ATTRIBUTE_MESSAGE, url.getUrl( ), urlBack.getUrl( ) ) );
1454     }
1455 
1456     /**
1457      * Remove Business Attribute
1458      *
1459      * @param request
1460      *            The Http Request
1461      * @return The XPage
1462      */
1463     @Action( ACTION_REMOVE_ATTRIBUTE )
1464     public XPage doRemoveAttribute( HttpServletRequest request )
1465     {
1466         int nBusinessClassId = Integer.parseInt( request.getParameter( PARAM_BUSINESS_CLASS_ID ) );
1467         int nAttributeId = Integer.parseInt( request.getParameter( PARAM_ATTRIBUTE_ID ) );
1468 
1469         ModelService.removeAttribute( _nPluginId, nBusinessClassId, nAttributeId );
1470         addInfo( INFO_ATTRIBUTE_DELETED, getLocale( request ) );
1471         
1472         if( StringUtils.equalsIgnoreCase( _strProjectType , PROJECT_TYPE_WORKFLOW_TASK ) )
1473     	{
1474     		return redirect( request, VIEW_MODIFY_CONFIGURATION_CLASS, PARAM_BUSINESS_CLASS_ID, nBusinessClassId, PARAM_REFRESH, 1 );
1475     	}
1476 
1477         return redirect( request, VIEW_MODIFY_BUSINESS_CLASS, PARAM_BUSINESS_CLASS_ID, nBusinessClassId, PARAM_REFRESH, 1 );
1478     }
1479 
1480     @Action( ACTION_VALIDATE_ATTRIBUTES )
1481     public XPage doValidateAttributes( HttpServletRequest request )
1482     {
1483         
1484         if( !StringUtils.equalsIgnoreCase( _strProjectType , PROJECT_TYPE_WORKFLOW_TASK ) )
1485         {
1486         
1487 	        int nBusinessClassId = Integer.parseInt( request.getParameter( PARAM_BUSINESS_CLASS_ID ) );
1488 	        
1489 	        if ( ModelService.getBusinessClass( _nPluginId, nBusinessClassId ).getAttributes( ).size( ) < 1 )
1490 	        {
1491 	            addError( ERROR_INSUFFICIENT_ATTRIBUTES, getLocale( request ) );
1492 	            return redirect( request, VIEW_MODIFY_BUSINESS_CLASS, PARAM_BUSINESS_CLASS_ID, _businessClass.getId( ) ); 
1493 	        }
1494         }
1495         
1496         return redirect( request, VIEW_MANAGE_BUSINESS_CLASSES, PARAM_BUSINESS_CLASS_ID,  _businessClass.getId( ) );
1497     }
1498 
1499     // //////////////////////////////////////////////////////////////////////////
1500     // APPLICATION
1501 
1502     /**
1503      * The management of the plugin applications associated to the generated plugin
1504      *
1505      * @param request
1506      *            The Http Request
1507      * @return The XPage
1508      */
1509     @View( VIEW_MANAGE_APPLICATIONS )
1510     public XPage getManageApplications( HttpServletRequest request )
1511     {
1512         Map<String, Object> model = getModel( );
1513         model.put( MARK_PLUGIN_ID, Integer.toString( _nPluginId ) );
1514         model.put( MARK_PLUGIN_APPLICATIONS, ModelService.getPluginModel( _nPluginId ).getApplications( ) );
1515         model.put( MARK_PROJECT_TYPE, _strProjectType );
1516 
1517         return getXPage( TEMPLATE_MANAGE_PLUGIN_APPLICATIONS, getLocale( request ), model );
1518     }
1519 
1520     /**
1521      * The creation screen of a plugin application
1522      *
1523      * @param request
1524      *            The Http Request
1525      * @return The XPage
1526      */
1527     @View( VIEW_CREATE_APPLICATION )
1528     public XPage getCreateApplication( HttpServletRequest request )
1529     {
1530         PluginModel pm = ModelService.getPluginModel( _nPluginId );
1531         _application = ( _application != null ) ? _application : new Application( );
1532 
1533         Map<String, Object> model = getPluginModel( );
1534         model.put( MARK_APPLICATION, _application );
1535         model.put( MARK_PLUGIN_APPLICATIONS, pm.getApplications( ) );
1536         model.put( MARK_BUSINESS_CLASSES_COMBO, ModelService.getComboBusinessClasses( _nPluginId ) );
1537         model.put( MARK_PROJECT_TYPE, _strProjectType );
1538 
1539         return getXPage( TEMPLATE_CREATE_PLUGIN_APPLICATION, getLocale( request ), model );
1540     }
1541 
1542     /**
1543      * The modification screen of a plugin application
1544      *
1545      * @param request
1546      *            The Http Request
1547      * @return The XPage
1548      */
1549     @View( VIEW_MODIFY_APPLICATION )
1550     public XPage getModifyApplication( HttpServletRequest request )
1551     {
1552         PluginModel pm = ModelService.getPluginModel( _nPluginId );
1553         int nApplicationId = Integer.parseInt( request.getParameter( PARAM_APPLICATION_ID ) );
1554 
1555         if ( ( _application == null ) || ( _application.getId( ) != nApplicationId ) )
1556         {
1557             _application = ModelService.getApplication( _nPluginId, nApplicationId );
1558         }
1559 
1560         Map<String, Object> model = getPluginModel( );
1561         model.put( MARK_APPLICATION, _application );
1562         model.put( MARK_PLUGIN_APPLICATIONS, pm.getApplications( ) );
1563         model.put( MARK_BUSINESS_CLASSES_COMBO, ModelService.getComboBusinessClasses( _nPluginId ) );
1564         model.put( MARK_PLUGIN_ID, Integer.toString( _nPluginId ) );
1565         model.put( MARK_PROJECT_TYPE, _strProjectType );
1566 
1567         return getXPage( TEMPLATE_MODIFY_PLUGIN_APPLICATION, getLocale( request ), model );
1568     }
1569 
1570     /**
1571      * The creation action of the plugin application
1572      *
1573      * @param request
1574      *            The Http Request
1575      * @return The XPage
1576      */
1577     @Action( ACTION_CREATE_APPLICATION )
1578     public XPage doCreateApplication( HttpServletRequest request )
1579     {
1580         populate( _application, request );
1581 
1582         List<Integer> listBusinessClasses = getBusinessClasses( request );
1583 
1584         // Case where no business class has been checked
1585         if ( listBusinessClasses.isEmpty( ) )
1586         {
1587             addError( ERROR_APPLICATION_NO_BUSINESS_CLASS, getLocale( request ) );
1588             return redirectView( request, VIEW_CREATE_APPLICATION );
1589         }
1590 
1591         _application.setIdBusinessClasses( listBusinessClasses );
1592 
1593         if ( !validateBean( _application, getLocale( request ) ) )
1594         {
1595             return redirectView( request, VIEW_CREATE_APPLICATION );
1596         }
1597 
1598         else
1599             if ( QualityService.existsDuplicateApplicationFields( _application, ModelService.getPluginModel( _nPluginId ).getApplications( ) ) )
1600             {
1601                 addDupplicateApplicationErrorMessages( request );
1602                 return redirectView( request, VIEW_CREATE_APPLICATION );
1603             }
1604 
1605         ModelService.addApplication( _nPluginId, _application );
1606         _application = null;
1607         addInfo( INFO_APPLICATION_CREATED, getLocale( request ) );
1608 
1609         return redirectView( request, VIEW_MANAGE_APPLICATIONS );
1610     }
1611 
1612     /**
1613      * The modification action of the plugin application
1614      *
1615      * @param request
1616      *            The Http Request
1617      * @return The XPage
1618      */
1619     @Action( ACTION_MODIFY_APPLICATION )
1620     public XPage doModifyApplication( HttpServletRequest request )
1621     {
1622         populate( _application, request );
1623 
1624         List<Integer> listBusinessClasses = getBusinessClasses( request );
1625 
1626         if ( listBusinessClasses.isEmpty( ) )
1627         {
1628             addError( ERROR_APPLICATION_NO_BUSINESS_CLASS, getLocale( request ) );
1629             return redirect( request, VIEW_MODIFY_APPLICATION, PARAM_APPLICATION_ID, _application.getId( ) );
1630         }
1631 
1632         _application.setIdBusinessClasses( listBusinessClasses );
1633 
1634         if ( !validateBean( _application, getLocale( request ) ) )
1635         {
1636             return redirect( request, VIEW_MODIFY_APPLICATION, PARAM_APPLICATION_ID, _application.getId( ) );
1637         }
1638         else
1639             if ( QualityService.existsDuplicateApplicationFields( _application, ModelService.getPluginModel( _nPluginId ).getApplications( ) ) )
1640             {
1641                 addDupplicateApplicationErrorMessages( request );
1642                 return redirect( request, VIEW_MODIFY_APPLICATION, PARAM_APPLICATION_ID, _application.getId( ) );
1643             }
1644 
1645         ModelService.updateApplication( _nPluginId, _application );
1646         _application = null;
1647         addInfo( INFO_APPLICATION_UPDATED, getLocale( request ) );
1648 
1649         return redirectView( request, VIEW_MANAGE_APPLICATIONS );
1650     }
1651 
1652     /**
1653      * The confirmation of an application removal
1654      *
1655      * @param request
1656      *            The Http Request
1657      * @return The XPage
1658      */
1659     @Action( ACTION_CONFIRM_REMOVE_APPLICATION )
1660     public XPage doConfirmRemoveApplication( HttpServletRequest request )
1661     {
1662         UrlItem url = new UrlItem( JSP_PAGE_PORTAL );
1663         url.addParameter( PARAM_PAGE, PLUGIN_NAME );
1664         url.addParameter( PARAM_ACTION, ACTION_REMOVE_APPLICATION );
1665         url.addParameter( PARAM_APPLICATION_ID, request.getParameter( PARAM_APPLICATION_ID ) );
1666 
1667         return redirectMessageBox( request,
1668                 buildConfirmMessageBox( PROPERTY_CONFIRM_REMOVE_APPLICATION_MESSAGE, url.getUrl( ), getViewFullUrl( VIEW_MANAGE_APPLICATIONS ) ) );
1669     }
1670 
1671     /**
1672      * The removal action of a plugin application
1673      *
1674      * @param request
1675      *            The Http Request
1676      * @return The XPage
1677      */
1678     @Action( ACTION_REMOVE_APPLICATION )
1679     public XPage doRemoveApplication( HttpServletRequest request )
1680     {
1681         int nApplicationId = Integer.parseInt( request.getParameter( PARAM_APPLICATION_ID ) );
1682         ModelService.removeApplication( _nPluginId, nApplicationId );
1683         addInfo( INFO_APPLICATION_DELETED, getLocale( request ) );
1684 
1685         return redirectView( request, VIEW_MANAGE_APPLICATIONS );
1686     }
1687 
1688     /**
1689      * Add error duplicate application messages to request
1690      * 
1691      * @param request
1692      *            The Http Request
1693      */
1694 
1695     private void addDupplicateApplicationErrorMessages( HttpServletRequest request )
1696     {
1697 
1698         if ( !QualityService.bValideUniqueAdministrationName )
1699         {
1700             addError( ERROR_APPLICATION_NAME_DUPLICATE, getLocale( request ) );
1701         }
1702 
1703         if ( !QualityService.bValideUniqueAdministrationClass )
1704         {
1705             addError( ERROR_APPLICATION_CLASS_DUPLICATE, getLocale( request ) );
1706         }
1707 
1708     }
1709 
1710     // //////////////////////////////////////////////////////////////////////////
1711     // PORTLET
1712 
1713     /**
1714      * The screen for management of portlets associated to the generated plugin
1715      *
1716      * @param request
1717      *            The Http Request
1718      * @return The XPage
1719      */
1720     @View( VIEW_MANAGE_PORTLETS )
1721     public XPage getManagePortlets( HttpServletRequest request )
1722     {
1723         Map<String, Object> model = getModel( );
1724         model.put( MARK_PLUGIN_ID, Integer.toString( _nPluginId ) );
1725         model.put( MARK_PLUGIN_PORTLETS, ModelService.getPluginModel( _nPluginId ).getPortlets( ) );
1726         model.put( MARK_PROJECT_TYPE, _strProjectType );
1727 
1728         return getXPage( TEMPLATE_MANAGE_PLUGIN_PORTLETS, getLocale( request ), model );
1729     }
1730 
1731     /**
1732      * The creation screen of a portlet
1733      *
1734      * @param request
1735      *            The Http Request
1736      * @return The XPage
1737      */
1738     @View( VIEW_CREATE_PORTLET )
1739     public XPage getCreatePortlet( HttpServletRequest request )
1740     {
1741         _portlet = ( _portlet != null ) ? _portlet : new Portlet( );
1742 
1743         Map<String, Object> model = getPluginModel( );
1744         model.put( MARK_PORTLET, _portlet );
1745         model.put( MARK_PROJECT_TYPE, _strProjectType );
1746 
1747         return getXPage( TEMPLATE_CREATE_PLUGIN_PORTLET, getLocale( request ), model );
1748     }
1749 
1750     /**
1751      * The modification page of the portlet
1752      *
1753      * @param request
1754      *            The Http Request
1755      * @return The XPage
1756      */
1757     @View( VIEW_MODIFY_PORTLET )
1758     public XPage getModifyPortlet( HttpServletRequest request )
1759     {
1760         int nPortletId = Integer.parseInt( request.getParameter( PARAM_PORTLET_ID ) );
1761 
1762         if ( ( _portlet == null ) || ( _portlet.getId( ) != nPortletId ) )
1763         {
1764             _portlet = ModelService.getPortlet( _nPluginId, nPortletId );
1765         }
1766 
1767         Map<String, Object> model = getModel( );
1768         model.put( MARK_PORTLET, _portlet );
1769         model.put( MARK_PROJECT_TYPE, _strProjectType );
1770 
1771         return getXPage( TEMPLATE_MODIFY_PLUGIN_PORTLET, getLocale( request ), model );
1772     }
1773 
1774     /**
1775      * The creation action of the portlet
1776      *
1777      * @param request
1778      *            The Http Request
1779      * @return The XPage
1780      */
1781     @Action( ACTION_CREATE_PORTLET )
1782     public XPage doCreatePortlet( HttpServletRequest request )
1783     {
1784         populate( _portlet, request );
1785 
1786         if ( !validateBean( _portlet, getLocale( request ) ) )
1787         {
1788             return redirectView( request, VIEW_CREATE_PORTLET );
1789         }
1790         else
1791             if ( QualityService.existsDuplicatePortletFields( _portlet, ModelService.getPluginModel( _nPluginId ).getPortlets( ) ) )
1792             {
1793 
1794                 addDupplicatePortletErrorMessages( request );
1795                 return redirectView( request, VIEW_CREATE_PORTLET );
1796             }
1797 
1798         ModelService.addPortlet( _nPluginId, _portlet );
1799         _portlet = null;
1800         addInfo( INFO_PORTLET_CREATED, getLocale( request ) );
1801 
1802         return redirectView( request, VIEW_MANAGE_PORTLETS );
1803     }
1804 
1805     /**
1806      * The modification action of the portlet
1807      *
1808      * @param request
1809      *            The Http Request
1810      * @return The XPage
1811      */
1812     @Action( ACTION_MODIFY_PORTLET )
1813     public XPage doModifyPluginPortlet( HttpServletRequest request )
1814     {
1815         populate( _portlet, request );
1816 
1817         if ( !validateBean( _portlet, getLocale( request ) ) )
1818         {
1819             return redirect( request, ACTION_MODIFY_PORTLET, PARAM_PORTLET_ID, _portlet.getId( ) );
1820         }
1821         else
1822             if ( QualityService.existsDuplicatePortletFields( _portlet, ModelService.getPluginModel( _nPluginId ).getPortlets( ) ) )
1823             {
1824 
1825                 addDupplicatePortletErrorMessages( request );
1826                 return redirect( request, ACTION_MODIFY_PORTLET, PARAM_PORTLET_ID, _portlet.getId( ) );
1827             }
1828 
1829         ModelService.updatePortlet( _nPluginId, _portlet );
1830         _portlet = null;
1831         addInfo( INFO_PORTLET_UPDATED, getLocale( request ) );
1832 
1833         return redirectView( request, VIEW_MANAGE_PORTLETS );
1834     }
1835 
1836     /**
1837      * The confirmation of the plugin removal
1838      *
1839      * @param request
1840      *            The Http Request
1841      * @return The XPage
1842      */
1843     @Action( ACTION_CONFIRM_REMOVE_PORTLET )
1844     public XPage doConfirmRemovePortlet( HttpServletRequest request )
1845     {
1846         UrlItem url = new UrlItem( JSP_PAGE_PORTAL );
1847         url.addParameter( PARAM_PAGE, PLUGIN_NAME );
1848         url.addParameter( PARAM_ACTION, ACTION_REMOVE_PORTLET );
1849         url.addParameter( PARAM_PORTLET_ID, request.getParameter( PARAM_PORTLET_ID ) );
1850 
1851         return redirectMessageBox( request,
1852                 buildConfirmMessageBox( PROPERTY_CONFIRM_REMOVE_PORTLET_MESSAGE, url.getUrl( ), getViewFullUrl( VIEW_MANAGE_PORTLETS ) ) );
1853     }
1854 
1855     /**
1856      * Remove Portlet Action
1857      *
1858      * @param request
1859      *            The Http Request
1860      * @return The XPage
1861      */
1862     @Action( ACTION_REMOVE_PORTLET )
1863     public XPage doRemovePluginPortlet( HttpServletRequest request )
1864     {
1865         int nPluginPortletId = Integer.parseInt( request.getParameter( PARAM_PORTLET_ID ) );
1866         ModelService.removePortlet( _nPluginId, nPluginPortletId );
1867         addInfo( INFO_PORTLET_DELETED, getLocale( request ) );
1868 
1869         return redirectView( request, VIEW_MANAGE_PORTLETS );
1870     }
1871 
1872     /**
1873      * Add error duplicate portlet messages to request
1874      * 
1875      * @param request
1876      *            The Http Request
1877      */
1878 
1879     private void addDupplicatePortletErrorMessages( HttpServletRequest request )
1880     {
1881 
1882         if ( !QualityService.bValideUniquePortletClassName )
1883         {
1884             addError( ERROR_PORTLET_CLASS_NAME_DUPLICATE, getLocale( request ) );
1885         }
1886 
1887         if ( !QualityService.bValideUniquePortletType )
1888         {
1889             addError( ERROR_PORTLET_TYPE_DUPLICATE, getLocale( request ) );
1890         }
1891         if ( !QualityService.bValideUniquePortletJspName )
1892         {
1893             addError( ERROR_PORTLET_JSP_NAME_DUPLICATE, getLocale( request ) );
1894         }
1895 
1896     }
1897 
1898     /**
1899      * The get page of the plugin recapitulation
1900      *
1901      * @param request
1902      *            The Http Request
1903      * @return The XPage
1904      */
1905     @View( VIEW_RECAPITULATE )
1906     public XPage getPluginRecapitulate( HttpServletRequest request )
1907     {
1908         PluginModel pm = ModelService.getPluginModel( _nPluginId );
1909 
1910         Map<String, Object> model = getPluginModel( );
1911         model.put( MARK_PLUGIN_ID, Integer.toString( _nPluginId ) );
1912         model.put( MARK_PLUGIN_APPLICATIONS, pm.getApplications( ) ); // FIXME can be found in the _model
1913         model.put( MARK_ADMIN_FEATURES, pm.getFeatures( ) );
1914         model.put( MARK_PLUGIN_PORTLETS, pm.getPortlets( ) );
1915         model.put( MARK_PLUGIN_REST, pm.getRest( ) );
1916         model.put( MARK_BUSINESS_CLASSES, pm.getBusinessClasses( ) );
1917         model.put( MARK_WORKFLOW_CONFIGURATION, pm.getConfiguration( ) );
1918         model.put( MARK_SCHEMES_COMBO, GeneratorService.getGenerationSchemes( StringUtils.equalsIgnoreCase( _strProjectType, PROJECT_TYPE_WORKFLOW_TASK ) ) );
1919         model.put( MARK_PROJECT_TYPE, _strProjectType );
1920 
1921         return getXPage( TEMPLATE_GET_RECAPITULATE, getLocale( request ), model );
1922     }
1923 
1924     /**
1925      * Get a default _model for template with the plugin object inside
1926      *
1927      * @return A default _model for template
1928      */
1929     private Map<String, Object> getPluginModel( )
1930     {
1931         Map<String, Object> model = getModel( );
1932         model.put( MARK_PLUGIN_MODEL, ModelService.getPluginModel( _nPluginId ) );
1933 
1934         return model;
1935     }
1936 
1937     /**
1938      * Build a message box object
1939      *
1940      * @param request
1941      *            The request
1942      * @param strMessageKey
1943      *            The message key
1944      * @param strUrlConfirm
1945      *            The Url to process confirmation
1946      * @param strUrlCancel
1947      *            The Url to cancel
1948      * @return
1949      */
1950     private MVCMessageBox buildConfirmMessageBox( String strMessageKey, String strUrlConfirm, String strUrlBack )
1951     {
1952         MVCMessageBox box = new MVCMessageBox( );
1953         box.setTemplate( TEMPLATE_MESSAGE_BOX_CONFIRMATION );
1954         box.setMessageKey( strMessageKey );
1955         box.setStyle( MVCMessageBox.QUESTION );
1956         box.setUrlButton1( strUrlConfirm );
1957         box.setUrlButton2( strUrlBack );
1958 
1959         return box;
1960     }
1961 
1962     /**
1963      * Build plugin exists message box
1964      * 
1965      * @return The message box object
1966      */
1967     private MVCMessageBox buildExistsMessageBox( )
1968     {
1969         MVCMessageBox box = new MVCMessageBox( );
1970         box.setTemplate( TEMPLATE_MESSAGE_BOX_EXISTS );
1971         box.setMessage( _strPluginName );
1972 
1973         return box;
1974     }
1975 
1976     /**
1977      * Returns the list of BusinessClasses
1978      * 
1979      * @param request
1980      *            The request
1981      * @return the collection of IdBusinessClasses
1982      */
1983     private List<Integer> getBusinessClasses( HttpServletRequest request )
1984     {
1985         List<Integer> list = new ArrayList<>( );
1986         Enumeration e = request.getParameterNames( );
1987 
1988         while ( e.hasMoreElements( ) )
1989         {
1990             String strParameter = (String) e.nextElement( );
1991 
1992             if ( strParameter.startsWith( PARAM_ID_BUSINESS_CLASS ) )
1993             {
1994                 String strId = strParameter.substring( PARAM_ID_BUSINESS_CLASS.length( ) );
1995                 list.add( Integer.parseInt( strId ) );
1996             }
1997         }
1998 
1999         return list;
2000     }
2001 
2002     // //////////////////////////////////////////////////////////////////////////
2003     // REST
2004 
2005     /**
2006      * The management of the plugin applications associated to the generated plugin
2007      *
2008      * @param request
2009      *            The Http Request
2010      * @return The XPage of the rest
2011      */
2012     @View( VIEW_MANAGE_REST )
2013     public XPage getManageRest( HttpServletRequest request )
2014     {
2015         Map<String, Object> model = getModel( );
2016 
2017         if ( ModelService.getRest( _nPluginId ) == null )
2018         {
2019             _rest = new Rest( );
2020             _rest.setIdBusinessClasses( new ArrayList<Integer>( ) );
2021             _rest.setId( 1 );
2022             ModelService.addRest( _nPluginId, _rest );
2023         }
2024         else
2025         {
2026             _rest = ModelService.getRest( _nPluginId );
2027         }
2028 
2029         model.put( MARK_PLUGIN_ID, Integer.toString( _nPluginId ) );
2030         model.put( MARK_BUSINESS_CLASSES_COMBO, ModelService.getComboBusinessClasses( _nPluginId ) );
2031         model.put( MARK_PLUGIN_REST, ModelService.getRest( _nPluginId ) );
2032         model.put( MARK_PROJECT_TYPE, _strProjectType );
2033 
2034         return getXPage( TEMPLATE_MANAGE_REST, getLocale( request ), model );
2035     }
2036 
2037     /**
2038      * The modification action of the plugin application
2039      *
2040      * @param request
2041      *            The Http Request
2042      * @return The XPage of the portlets
2043      */
2044     @Action( ACTION_MODIFY_REST_BACK )
2045     public XPage doModifyRestBack( HttpServletRequest request )
2046     {
2047         populate( _rest, request );
2048 
2049         List<Integer> listBusinessClasses = getBusinessClasses( request );
2050         _rest.setIdBusinessClasses( listBusinessClasses );
2051 
2052         if ( !validateBean( _rest, getLocale( request ) ) )
2053         {
2054             return redirect( request, VIEW_MANAGE_REST );
2055         }
2056 
2057         ModelService.updateRest( _nPluginId, _rest );
2058 
2059         return redirectView( request, VIEW_MANAGE_PORTLETS );
2060     }
2061 
2062     /**
2063      * The modification action of the plugin application
2064      *
2065      * @param request
2066      *            The Http Request
2067      * @return The XPage of the recapitulation
2068      */
2069     @Action( ACTION_MODIFY_REST_NEXT )
2070     public XPage doModifyRestNext( HttpServletRequest request )
2071     {
2072         populate( _rest, request );
2073 
2074         List<Integer> listBusinessClasses = getBusinessClasses( request );
2075         _rest.setIdBusinessClasses( listBusinessClasses );
2076 
2077         if ( !validateBean( _rest, getLocale( request ) ) )
2078         {
2079             return redirect( request, VIEW_MANAGE_REST );
2080         }
2081 
2082         ModelService.updateRest( _nPluginId, _rest );
2083 
2084         return redirectView( request, VIEW_RECAPITULATE );
2085     }
2086 
2087 }