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.service.generator;
35  
36  import fr.paris.lutece.plugins.pluginwizard.business.model.Application;
37  import fr.paris.lutece.plugins.pluginwizard.business.model.Attribute;
38  import fr.paris.lutece.plugins.pluginwizard.business.model.BusinessClass;
39  import fr.paris.lutece.plugins.pluginwizard.business.model.Feature;
40  import fr.paris.lutece.plugins.pluginwizard.business.model.PluginModel;
41  import fr.paris.lutece.plugins.pluginwizard.business.model.Portlet;
42  import fr.paris.lutece.plugins.pluginwizard.util.Utils;
43  import fr.paris.lutece.portal.service.util.AppPropertiesService;
44  
45  import java.text.MessageFormat;
46  
47  import java.util.HashMap;
48  import java.util.Map;
49  
50  /**
51   *
52   * Class generated needed resource files for i18n implementation
53   *
54   */
55  public class ResourcesGenerator extends AbstractGenerator
56  {
57      private static final String PATH_JAVA = "src/java/fr/paris/lutece/plugins/{plugin_name}/resources/";
58      private static final String PATH_JAVA_WORKFLOW = "src/java/fr/paris/lutece/plugins/workflow/modules/{plugin_name}/resources/";
59      private static final String PATH_KOTLIN = "src/kotlin/fr/paris/lutece/plugins/{plugin_name}/resources/";
60      private static String [ ] _languages = {
61              "", "fr"
62      };
63      private static String [ ] _prefix = {
64              ""
65      };
66      private static String [ ] _suffix = {
67              "created", "updated", "removed"
68      };
69      private static String [ ] _titlePrefix = {
70              "create", "modify"
71      };
72  
73      /**
74       * {@inheritDoc }
75       */
76      @Override
77      public Map generate( PluginModel pm, String generationSchemeName )
78      {
79          HashMap map = new HashMap( );
80  
81          String prefixFileName = pm.getPluginNameForRessource( );
82  
83          for ( String strLanguage : _languages )
84          {
85              String strFilesPath = ( isKotlin( ) ) ? PATH_KOTLIN : ( pm.isWorkflowTask( ) ? PATH_JAVA_WORKFLOW.replace( "{plugin_name}",pm.getPluginNameForRessource( ) ) : PATH_JAVA );
86              String strPath = getFilePath( pm, strFilesPath,
87                      prefixFileName + "_messages" + ( strLanguage.length( ) > 0 ? "_" : "" ) + strLanguage + ".properties" );
88  
89              String strSourceCode = getCode( pm, strLanguage );
90              map.put( strPath, strSourceCode );
91          }
92  
93          return map;
94      }
95  
96      /**
97       * Build the code
98       *
99       * @param pm
100      *            The Plugin Model
101      * @param strLanguage
102      *            The language
103      * @return The code
104      */
105     private String getCode( PluginModel pm, String strLanguage )
106     {
107         StringBuilder sb = new StringBuilder( );
108         
109         if( pm.isWorkflowTask( ) )
110         {
111         	generatePluginKeys( sb, pm );
112             generateConfigurationClassKeys( sb, pm, strLanguage );
113             generateTaskServiceKeys( sb, pm, strLanguage ); 
114             generateTaskMessageKeys( sb, pm, strLanguage );
115         }
116         else
117         {
118         	generatePluginKeys( sb, pm );
119             generateFeaturesKeys( sb, pm );
120             generateXPagesKeys( sb, pm );
121             generateBusinessClassKeys( sb, pm, strLanguage );
122             generatePortletsKeys( sb, pm );
123             generateInfosKeys( sb, pm, strLanguage );
124         }
125         
126 
127         return sb.toString( );
128     }
129 
130     /**
131      * Writes in the buffer resources keys for the plugin
132      *
133      * @param sb
134      *            The buffer
135      * @param pm
136      *            The plugin model
137      */
138     private void generatePluginKeys( StringBuilder sb, PluginModel pm )
139     {
140         
141         if ( pm.isModule( ) )
142         {
143         	sb.append( "# Module's keys\n" );
144             sb.append( "module.provider=" ).append( pm.getPluginProvider( ) ).append( "\n" );
145             sb.append( "module.description=" ).append( pm.getPluginDescription( ) ).append( "\n" );
146         }
147         else
148         	if ( pm.isWorkflowTask( ) )
149         {
150             	sb.append( "# Workflow module's keys\n" );
151                 sb.append( "module.provider=" ).append( pm.getPluginProvider( ) ).append( "\n" );
152                 sb.append( "module.description=" ).append( pm.getPluginDescription( ) ).append( "\n" );    
153                 sb.append( "task." ).append( pm.getConfiguration( ).getWorkflowTaskName( ).toLowerCase( ) ).append(".title=").append( pm.getConfiguration( ).getWorkflowTaskName( ).toLowerCase( ) ).append( "\n" );
154         }
155         else
156         {
157         	sb.append( "# Plugin's keys\n" );
158             sb.append( "plugin.provider=" ).append( pm.getPluginProvider( ) ).append( "\n" );
159             sb.append( "plugin.description=" ).append( pm.getPluginDescription( ) ).append( "\n" );
160         }
161 
162         sb.append( "\n" );
163     }
164 
165     /**
166      * Writes in the buffer resources keys for features
167      *
168      * @param sb
169      *            The buffer
170      * @param pm
171      *            The plugin model
172      */
173     private void generateFeaturesKeys( StringBuilder sb, PluginModel pm )
174     {
175         if ( !pm.getFeatures( ).isEmpty( ) )
176         {
177             sb.append( "\n# Admin features keys\n\n" );
178 
179             for ( Feature feature : pm.getFeatures( ) )
180             {
181                 sb.append( "adminFeature." ).append( feature.getFeatureName( ) ).append( ".name=" ).append( feature.getFeatureName( ) ).append( "\n" );
182                 sb.append( "adminFeature." ).append( feature.getFeatureName( ) ).append( ".description=" ).append( feature.getFeatureDescription( ) )
183                         .append( "\n" );
184             }
185 
186             sb.append( "\n" );
187         }
188     }
189 
190     private void generateXPagesKeys( StringBuilder sb, PluginModel pm )
191     {
192         if ( !pm.getApplications( ).isEmpty( ) )
193         {
194             sb.append( "\n# XPages keys\n\n" );
195         }
196 
197         for ( Application application : pm.getApplications( ) )
198         {
199             if ( application.getIdBusinessClasses( ).isEmpty( ) )
200             {
201                 sb.append( "xpage." ).append( application.getApplicationName( ) ).append( ".pageTitle=" ).append( application.getApplicationName( ) )
202                         .append( "\n" );
203                 sb.append( "xpage." ).append( application.getApplicationName( ) ).append( ".pagePathLabel=" ).append( application.getApplicationName( ) )
204                         .append( "\n" );
205             }
206             else
207             {
208                 for ( int id : application.getIdBusinessClasses( ) )
209                 {
210                     for ( BusinessClass bc : pm.getBusinessClasses( ) )
211                     {
212                         if ( bc.getId( ) == id )
213                         {
214                             sb.append( "xpage." ).append( bc.getBusinessClass( ).toLowerCase( ) ).append( ".pageTitle=" )
215                                     .append( bc.getBusinessClass( ).toLowerCase( ) ).append( "\n" );
216                             sb.append( "xpage." ).append( bc.getBusinessClass( ).toLowerCase( ) ).append( ".pagePathLabel=" )
217                                     .append( bc.getBusinessClass( ).toLowerCase( ) ).append( "\n" );
218                         }
219                     }
220                 }
221             }
222         }
223     }
224 
225     /**
226      * Writes in the buffer resources keys for business classes
227      *
228      * @param sb
229      *            The buffer
230      * @param pm
231      *            The plugin model
232      * @param strLanguage
233      *            The language
234      */
235     private void generateBusinessClassKeys( StringBuilder sb, PluginModel pm, String strLanguage )
236     {
237         if ( !pm.getBusinessClasses( ).isEmpty( ) )
238         {
239             sb.append( "\n# Business classes keys\n\n" );
240         }
241 
242         for ( BusinessClass bc : pm.getBusinessClasses( ) )
243         {
244             sb.append( "\n# keys for business classes keys : " ).append( bc.getBusinessClass( ) ).append( "\n" );
245 
246             String strPrefix = "manage_" + bc.getPluralBusinessClass( ).toLowerCase( ) + ".";
247             sb.append( strPrefix ).append( "pageTitle=" ).append( bc.getBusinessClass( ) ).append( "\n" );
248             sb.append( strPrefix ).append( "title=" ).append( getLabel( "title.manage", strLanguage, bc.getPluralBusinessClass( ) ) ).append( "\n" );
249             sb.append( strPrefix ).append( "buttonAdd=" ).append( getLabel( "buttonAdd", strLanguage, bc.getBusinessClass( ) ) ).append( "\n" );
250 
251             for ( Attribute attribute : bc.getAttributes( ) )
252             {
253                 sb.append( strPrefix ).append( "column" ).append( attribute.getName( ) ).append( "=" ).append( attribute.getLabelName( ) ).append( "\n" );
254             }
255 
256             for ( String strTitlePrefix : _titlePrefix )
257             {
258                 strPrefix = strTitlePrefix + "_" + bc.getBusinessClass( ).toLowerCase( ) + ".";
259                 sb.append( strPrefix ).append( "pageTitle=" ).append( bc.getBusinessClass( ) ).append( "\n" );
260                 sb.append( strPrefix ).append( "title=" ).append( getLabel( "title." + strTitlePrefix, strLanguage, bc.getBusinessClass( ) ) ).append( "\n" );
261             }
262 
263             for ( String strBasePrefix : _prefix )
264             {
265                 strPrefix = strBasePrefix + ( strBasePrefix.isEmpty( ) ? "" : "_" ) + bc.getBusinessClass( ).toLowerCase( ) + ".";
266                 sb.append( strPrefix ).append( "pageTitle=" ).append( bc.getBusinessClass( ) ).append( "\n" );
267 
268                 for ( Attribute attribute : bc.getAttributes( ) )
269                 {
270                     sb.append( strPrefix ).append( "label" ).append( attribute.getName( ) ).append( "=" ).append( attribute.getLabelName( ) ).append( "\n" );
271                     sb.append( strPrefix ).append( "label" ).append( attribute.getName( ) ).append( ".help=" ).append( attribute.getLabelName( ) )
272                             .append( " (" ).append( getLabel( "helpText", strLanguage ) ).append( ")\n" );
273                 }
274             }
275 
276             sb.append( "\nmessage.confirmRemove" ).append( bc.getBusinessClass( ) ).append( "=" )
277                     .append( getLabel( "confirmRemove", strLanguage, bc.getBusinessClass( ) ) ).append( "\n" );
278 
279             // Constraints messages
280             sb.append( "\n# JSR 303 constraint validator messages\n" );
281 
282             strPrefix = "validation." + bc.getBusinessClass( ).toLowerCase( ) + ".";
283 
284             for ( Attribute attribute : bc.getAttributes( ) )
285             {
286                 if ( !attribute.getType( ).equals( "int" ) )
287                 {
288                     if ( attribute.getNotNull( ) )
289                     {
290                         sb.append( strPrefix ).append( attribute.getName( ) ).append( ".notEmpty=" )
291                                 .append( getLabel( "validation.notEmpty", strLanguage, attribute.getLabelName( ) ) ).append( "\n" );
292                     }
293 
294                     if ( attribute.getMaxLength( ) > 0 )
295                     {
296                         sb.append( strPrefix ).append( attribute.getName( ) ).append( ".size=" )
297                                 .append( getLabel( "validation.size", strLanguage, attribute.getLabelName( ), "" + attribute.getMaxLength( ) ) ).append( "\n" );
298                     }
299                 }
300             }
301 
302             sb.append( "\n# model attributes for validation messages\n" );
303             strPrefix = "model.entity." + bc.getBusinessClass( ).toLowerCase( ) + ".attribute.";
304 
305             for ( Attribute attribute : bc.getAttributes( ) )
306             {
307                 sb.append( strPrefix ).append( Utils.firstLowerCase( attribute.getName( ) ) ).append( "=" ).append( attribute.getLabelName( ) ).append( "\n" );
308             }
309         }
310     }
311     
312     /**
313      * Writes in the buffer resources keys for configuration classes
314      *
315      * @param sb
316      *            The buffer
317      * @param pm
318      *            The plugin model
319      * @param strLanguage
320      *            The language
321      */
322     private void generateConfigurationClassKeys( StringBuilder sb, PluginModel pm, String strLanguage )
323     {
324         if ( !pm.getBusinessClasses( ).isEmpty( ) )
325         {
326         	
327         	BusinessClass bc = pm.getBusinessClasses( ).get( 0 );
328         	
329         	if( !bc.getAttributes().isEmpty( ) )
330 	        {
331 	        	String strPrefixTask = "task.config.";
332 	        	String strPrefix = strPrefixTask;
333 	        	
334 	        	sb.append( "\n# Business classes keys (" ).append( bc.getBusinessClass( ) ).append( ")\n" );
335 	        	sb.append( "\n# Keys for config form" ).append( "\n" );
336 	        	
337 	            //Config forms labels and helper's label 
338 	            for ( Attribute attribute : bc.getAttributes( ) )
339 	            {
340 	                sb.append( strPrefix ).append( "label" ).append( attribute.getName( ) ).append( "=" ).append( attribute.getLabelName( ) ).append( "\n" );
341 	                sb.append( strPrefix ).append( "label" ).append( attribute.getName( ) ).append( ".help=" ).append( attribute.getLabelName( ) )
342 	                        .append( " (" ).append( getLabel( "helpText", strLanguage ) ).append( ")\n" );
343 	            }
344 	         
345 	            // Constraints messages from Business classes
346 	            sb.append( "\n#JSR 303 constraint validator messages\n" );
347 	            strPrefix = "validation." + strPrefixTask;
348 	
349 	            for ( Attribute attribute : bc.getAttributes( ) )
350 	            {
351 	                if ( !attribute.getType( ).equals( "int" ) )
352 	                {
353 	                    if ( attribute.getNotNull( ) )
354 	                    {
355 	                        sb.append( strPrefix ).append( attribute.getName( ) ).append( ".notEmpty=" )
356 	                                .append( getLabel( "validation.notEmpty", strLanguage, attribute.getLabelName( ) ) ).append( "\n" );
357 	                    }
358 	
359 	                    if ( attribute.getMaxLength( ) > 0 )
360 	                    {
361 	                        sb.append( strPrefix ).append( attribute.getName( ) ).append( ".size=" )
362 	                                .append( getLabel( "validation.size", strLanguage, attribute.getLabelName( ), "" + attribute.getMaxLength( ) ) ).append( "\n" );
363 	                    }
364 	                }
365 	            }
366 	            
367 	            //Model entity
368 	            sb.append( "\n#Model attributes for validation messages\n" );
369 	            strPrefix = "model.entity." + strPrefixTask + "attribute.";
370 	
371 	            for ( Attribute attribute : bc.getAttributes( ) )
372 	            {
373 	                sb.append( strPrefix ).append( Utils.firstLowerCase( attribute.getName( ) ) ).append( "=" ).append( attribute.getLabelName( ) ).append( "\n" );
374 	            }
375 	        }
376         }
377     }
378 
379     /**
380      * Writes in the buffer resources keys for TaskServiceKeys
381      *
382      * @param sb
383      *            The buffer
384      * @param pm
385      *            The plugin model
386      * @param strLanguage
387      *            The language
388      */
389     private void generateTaskServiceKeys( StringBuilder sb, PluginModel pm , String strLanguage )
390     {
391     	sb.append( "\n# keys for task service class keys : " ).append( "\n" );
392     	
393     	String strPrefix = pm.getWorkflowNameWithPrefix( );
394         sb.append( "service.taskTitle=" ).append(pm.getConfiguration().getWorkflowTaskName().replace( "([a-z])([A-Z])", "$1 $2" ) ).append( "\n" );
395     }
396 
397         /**
398      * Writes in the buffer resources keys for TaskServiceKeys
399      *
400      * @param sb
401      *            The buffer
402      * @param pm
403      *            The plugin model
404      * @param strLanguage
405      *            The language
406      */
407     private void generateTaskMessageKeys( StringBuilder sb, PluginModel pm , String strLanguage )
408     {
409         sb.append( "\n# Messages : " ).append( "\n" );
410         sb.append( "message" ).append( "." ).append( "task.information=TODO add message information" ).append( "\n" );
411     }
412 
413     /**
414      * Writes in the buffer resources keys for portlets
415      *
416      * @param sb
417      *            The buffer
418      * @param pm
419      *            The plugin model
420      */
421     private void generatePortletsKeys( StringBuilder sb, PluginModel pm )
422     {
423         if ( !pm.getPortlets( ).isEmpty( ) )
424         {
425             sb.append( "\n# Portlets keys\n\n" );
426 
427             for ( Portlet portlet : pm.getPortlets( ) )
428             {
429                 sb.append( "portlet." ).append( pm.getPluginName( ).toLowerCase( ) ).append( portlet.getPortletClass( ) ).append( ".name=" )
430                         .append( portlet.getJspBaseName( ) ).append( "\n" );
431             }
432 
433             sb.append( "\n" );
434         }
435     }
436 
437     /**
438      * Writes in the buffer resources keys for info notifications
439      *
440      * @param sb
441      *            The buffer
442      * @param pm
443      *            The plugin model
444      */
445     private void generateInfosKeys( StringBuilder sb, PluginModel pm, String strLanguage )
446     {
447         if ( !pm.getBusinessClasses( ).isEmpty( ) )
448         {
449             sb.append( "\n# Infos keys\n\n" );
450 
451             for ( BusinessClass bc : pm.getBusinessClasses( ) )
452             {
453                 for ( String strSuffix : _suffix )
454                 {
455                     sb.append( "info." ).append( bc.getBusinessClass( ).toLowerCase( ) ).append( "." ).append( strSuffix ).append( "=" )
456                             .append( bc.getBusinessClass( ) ).append( " " ).append( getLabel( "infoKey." + strSuffix, strLanguage ) ).append( "\n" );
457                 }
458             }
459 
460             sb.append( "\n" );
461         }
462     }
463 
464     /**
465      * Gets a label for a given language from the pluginwizard.properties file
466      *
467      * @param strKey
468      *            The key of the label
469      * @param strLanguage
470      *            The language
471      * @param arguments
472      *            arguments of the label
473      * @return The value of the label
474      */
475     private String getLabel( String strKey, String strLanguage, String... arguments )
476     {
477         String strFullKey = "pluginwizard.label." + strKey + "." + strLanguage;
478         String strLabel = AppPropertiesService.getProperty( strFullKey, "Label not found for key " + strFullKey );
479 
480         return MessageFormat.format( strLabel, (Object [ ]) arguments );
481     }
482 }