View Javadoc
1   /*
2    * Copyright (c) 2002-2021, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.releaser.util;
35  
36  import java.io.BufferedReader;
37  import java.io.File;
38  import java.io.FileReader;
39  import java.io.FileWriter;
40  import java.io.FilenameFilter;
41  import java.io.IOException;
42  import java.io.StringWriter;
43  import java.util.regex.Matcher;
44  import java.util.regex.Pattern;
45  
46  import javax.xml.parsers.DocumentBuilder;
47  import javax.xml.parsers.DocumentBuilderFactory;
48  import javax.xml.parsers.ParserConfigurationException;
49  import javax.xml.transform.Transformer;
50  import javax.xml.transform.TransformerException;
51  import javax.xml.transform.TransformerFactory;
52  import javax.xml.transform.dom.DOMSource;
53  import javax.xml.transform.stream.StreamResult;
54  
55  import org.eclipse.jgit.api.errors.NoFilepatternException;
56  import org.w3c.dom.Document;
57  import org.w3c.dom.Node;
58  import org.w3c.dom.NodeList;
59  import org.xml.sax.SAXException;
60  
61  // TODO: Auto-generated Javadoc
62  /**
63   * The Class PluginUtils.
64   */
65  public class PluginUtils
66  {
67  
68      /** The Constant CORE_PLUGIN_NAME1. */
69      public static final String CORE_PLUGIN_NAME1 = "core";
70  
71      /** The Constant CORE_PLUGIN_NAME2. */
72      public static final String CORE_PLUGIN_NAME2 = "lutece-core";
73  
74      /** The Constant SUFFIX_CONTEXT_FILE. */
75      private static final String SUFFIX_CONTEXT_FILE = ".xml";
76  
77      /** The Constant CONSTANTE_PLUGIN_PATH. */
78      private static final String CONSTANTE_PLUGIN_PATH = "webapp/WEB-INF/plugins/";
79  
80      /** The Constant CONSTANTE_CORE_CONF. */
81      private static final String CONSTANTE_CORE_CONF = "webapp/WEB-INF/conf/";
82  
83      /** The Constant CONSTANTE_CORE_APP_INFO. */
84      private static final String CONSTANTE_CORE_APP_INFO = "src/java/fr/paris/lutece/portal/service/init/AppInfo.java";
85  
86      /** The Constant REGEXP_VERSION_APP_INFO. */
87      private static final String REGEXP_VERSION_APP_INFO = "(.*)private static final String APP_VERSION = \"(.*)\";";
88  
89      /** The Constant PATTERN_VERSION_APP_INFO. */
90      private static final Pattern PATTERN_VERSION_APP_INFO = Pattern.compile( REGEXP_VERSION_APP_INFO );
91  
92      /**
93       * Checks if is core.
94       *
95       * @param strPluginName
96       *            plugin name
97       * @return <code>true</code> if core or lutece-core, <code>false</code> otherwise.
98       */
99      public static boolean isCore( String strPluginName )
100     {
101         return CORE_PLUGIN_NAME1.equals( strPluginName ) || CORE_PLUGIN_NAME2.equals( strPluginName );
102     }
103 
104     /**
105      * Gets the core XML file.
106      *
107      * @param strComponentPath
108      *            the str component path
109      * @return the core XML file
110      */
111     public static String getCoreXMLFile( String strComponentPath )
112     {
113         String strCodeXML = strComponentPath + ( strComponentPath.endsWith( File.separator ) ? "" : File.separator ) + CONSTANTE_CORE_CONF + "core.xml";
114         File fileCoreXML = new File( strCodeXML );
115 
116         if ( !fileCoreXML.exists( ) )
117         {
118             return "";
119         }
120 
121         return strCodeXML;
122     }
123 
124     /**
125      * Gets the plugin XML file.
126      *
127      * @param strComponentPath
128      *            the str component path
129      * @return the plugin XML file
130      */
131     public static String [ ] getPluginXMLFile( String strComponentPath )
132     {
133         String strDirConfPlugins = strComponentPath + ( strComponentPath.endsWith( File.separator ) ? "" : File.separator ) + CONSTANTE_PLUGIN_PATH;
134         File dirConfPlugins = new File( strDirConfPlugins );
135 
136         if ( !dirConfPlugins.exists( ) )
137         {
138             return new String [ 0];
139         }
140 
141         FilenameFilter filterContext = new ContextFileFilter( );
142         String [ ] filesName = dirConfPlugins.list( filterContext );
143         for ( int nIndex = 0; nIndex < filesName.length; nIndex++ )
144         {
145             if ( !filesName [nIndex].startsWith( strDirConfPlugins ) )
146             {
147                 filesName [nIndex] = strDirConfPlugins + filesName [nIndex];
148             }
149         }
150 
151         return filesName;
152     }
153 
154     /**
155      * Gets the app info file.
156      *
157      * @param strBasePath
158      *            the str base path
159      * @return the app info file
160      */
161     public static String getAppInfoFile( String strBasePath )
162     {
163         String strAppInfo = strBasePath + File.separator + CONSTANTE_CORE_APP_INFO;
164 
165         File fileAppInfo = new File( strAppInfo );
166         if ( !fileAppInfo.exists( ) )
167         {
168             return "";
169         }
170 
171         return strAppInfo;
172     }
173 
174     /**
175      * Update app info file.
176      *
177      * @param strFile
178      *            the str file
179      * @param strVersion
180      *            the str version
181      * @param commandResult
182      *            the command result
183      * @return true, if successful
184      */
185     public static boolean updateAppInfoFile( String strFile, String strVersion, CommandResult commandResult )
186     {
187         boolean bReplace = false;
188         BufferedReader br = null;
189         StringBuilder sbNewFileContent = null;
190         try
191         {
192             sbNewFileContent = new StringBuilder( );
193             br = new BufferedReader( new FileReader( strFile ) );
194             while ( br.ready( ) )
195             {
196                 String strNewLine = br.readLine( );
197                 Matcher matcher = PATTERN_VERSION_APP_INFO.matcher( strNewLine );
198                 if ( matcher.matches( ) )
199                 {
200                     if ( matcher.groupCount( ) >= 1 )
201                     {
202                         String strCurrentVersion = matcher.group( 2 );
203                         if ( !strCurrentVersion.equals( strVersion ) )
204                         {
205                             commandResult.getLog( ).append( "Updating core version from " + strCurrentVersion + " to " + strVersion );
206                             strNewLine = strNewLine.replace( strCurrentVersion, strVersion );
207                             bReplace = true;
208                         }
209                         else
210                         {
211                             commandResult.getLog( ).append( "Version is already " + strVersion );
212                         }
213                     }
214                 }
215 
216                 sbNewFileContent.append( strNewLine + "\n" );
217             }
218 
219         }
220         catch( Exception ex )
221         {
222             ReleaserUtils.addTechnicalError( commandResult, ex.getMessage( ), ex );
223         }
224         finally
225         {
226             if ( br != null )
227             {
228                 try
229                 {
230                     br.close( );
231                 }
232                 catch( IOException e1 )
233                 {
234                     ReleaserUtils.addTechnicalError( commandResult, e1.getMessage( ), e1 );
235                 }
236             }
237         }
238 
239         if ( !bReplace )
240         {
241             return false;
242         }
243 
244         FileWriter fw = null;
245         try
246         {
247             fw = new FileWriter( strFile );
248             fw.append( sbNewFileContent.toString( ) );
249         }
250         catch( Exception ex )
251         {
252             ReleaserUtils.addTechnicalError( commandResult, ex.getMessage( ), ex );
253         }
254         finally
255         {
256             if ( fw != null )
257             {
258                 try
259                 {
260                     fw.close( );
261                 }
262                 catch( IOException ex )
263                 {
264                     ReleaserUtils.addTechnicalError( commandResult, ex.getMessage( ), ex );
265                 }
266             }
267         }
268         return false;
269     }
270 
271     /**
272      * Update plugin XML version.
273      *
274      * @param strFile
275      *            the str file
276      * @param strNewVersion
277      *            the str new version
278      * @param commandResult
279      *            the command result
280      * @return the string
281      */
282     public static String updatePluginXMLVersion( String strFile, String strNewVersion, CommandResult commandResult )
283     {
284         FileWriter fw = null;
285         boolean bFileClosed = false;
286         try
287         {
288             DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance( );
289             DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder( );
290             Document doc = docBuilder.parse( strFile );
291 
292             doc.getDocumentElement( ).normalize( );
293 
294             NodeList versionList = doc.getElementsByTagName( "version" );
295             Node version = versionList.item( 0 );
296 
297             version.getFirstChild( ).setNodeValue( strNewVersion );
298 
299             DOMSource domSource = new DOMSource( doc );
300 
301             StringWriter sw = new StringWriter( );
302             StreamResult result = new StreamResult( sw );
303 
304             TransformerFactory tf = TransformerFactory.newInstance( );
305             Transformer transformer = tf.newTransformer( );
306             transformer.transform( domSource, result );
307 
308             fw = new FileWriter( new File( strFile ) );
309 
310             fw.append( sw.toString( ) );
311 
312             fw.flush( );
313 
314             fw.close( );
315 
316             bFileClosed = true;
317 
318         }
319         catch( Exception ex )
320         {
321             ReleaserUtils.addTechnicalError( commandResult, ex.getMessage( ), ex );
322         }
323 
324         finally
325         {
326             if ( fw != null && !bFileClosed )
327             {
328                 try
329                 {
330                     fw.close( );
331                 }
332                 catch( IOException e )
333                 {
334                     e.printStackTrace( );
335                 }
336             }
337         }
338 
339         return "";
340     }
341 
342     /**
343      * Utils filename filter to identify context files.
344      */
345     static class ContextFileFilter implements FilenameFilter
346     {
347 
348         /**
349          * Filter filename.
350          *
351          * @param file
352          *            The current file
353          * @param strName
354          *            The file name
355          * @return true if the file is a context file otherwise false
356          */
357         public boolean accept( File file, String strName )
358         {
359             return strName.endsWith( SUFFIX_CONTEXT_FILE );
360         }
361     }
362 
363 }