View Javadoc
1   /*
2    * Copyright (c) 2002-2017, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.deployment.util;
35  
36  import fr.paris.lutece.plugins.deployment.business.jaxb.maven.Model;
37  import fr.paris.lutece.plugins.deployment.business.jaxb.maven.ObjectFactory;
38  import fr.paris.lutece.plugins.deployment.util.vcs.ReleaseSVNCommitClient;
39  
40  import org.apache.commons.lang.StringUtils;
41  
42  import org.tmatesoft.svn.core.SVNException;
43  import org.tmatesoft.svn.core.wc.SVNCommitClient;
44  import org.tmatesoft.svn.core.wc.SVNCommitPacket;
45  
46  import org.w3c.dom.Document;
47  import org.w3c.dom.Node;
48  import org.w3c.dom.NodeList;
49  
50  import org.xml.sax.SAXException;
51  
52  import java.io.File;
53  import java.io.FileInputStream;
54  import java.io.FileNotFoundException;
55  import java.io.FileOutputStream;
56  import java.io.FileWriter;
57  import java.io.IOException;
58  import java.io.InputStream;
59  import java.io.OutputStream;
60  import java.io.StringWriter;
61  
62  import java.util.ArrayList;
63  import java.util.List;
64  
65  import javax.xml.bind.JAXBContext;
66  import javax.xml.bind.JAXBElement;
67  import javax.xml.bind.JAXBException;
68  import javax.xml.bind.Marshaller;
69  import javax.xml.bind.Unmarshaller;
70  import javax.xml.parsers.DocumentBuilder;
71  import javax.xml.parsers.DocumentBuilderFactory;
72  import javax.xml.parsers.ParserConfigurationException;
73  import javax.xml.transform.Transformer;
74  import javax.xml.transform.TransformerException;
75  import javax.xml.transform.TransformerFactory;
76  import javax.xml.transform.dom.DOMSource;
77  import javax.xml.transform.stream.StreamResult;
78  
79  public final class ReleaseUtils
80  {
81      public static final String CONSTANTE_EMPTY_STRING = "";
82      public static final String CONSTANTE_SNAPSHOT = "-SNAPSHOT";
83      public static final String CONSTANT_CORE = "core";
84      public static final String CONSTANT_CORE_PREFIX = "lutece-";
85      public static final String CONSTANT_POM_PARENT = "lutece-parent-pom";
86      public static final String CONSTANT_POM_PLUGIN = "lutece-plugins-pom";
87  
88      /**
89       * Safe split (no empty value)
90       * 
91       * @param strToSplit
92       * @param strSeparator
93       * @return
94       */
95      public static List<String> split( String strToSplit, String strSeparator )
96      {
97          List<String> listSplit = new ArrayList<String>( );
98          String [ ] splitted = strToSplit.split( strSeparator );
99  
100         if ( splitted != null )
101         {
102             for ( String strValue : splitted )
103             {
104                 if ( !StringUtils.isBlank( strValue ) )
105                 {
106                     // add to list
107                     listSplit.add( strValue );
108                 }
109             }
110         }
111 
112         return listSplit;
113     }
114 
115     public static String getReleaseName( final String strPluginName, String strVersion )
116     {
117         if ( CONSTANT_CORE.equals( strPluginName ) )
118         {
119             return CONSTANT_CORE_PREFIX + strPluginName + "-" + strVersion;
120         }
121 
122         return strPluginName + "-" + strVersion;
123     }
124 
125     public static <T> T unmarshal( Class<T> docClass, InputStream inputStream ) throws JAXBException
126     {
127         String packageName = docClass.getPackage( ).getName( );
128         JAXBContext jc = JAXBContext.newInstance( packageName );
129         Unmarshaller u = jc.createUnmarshaller( );
130         JAXBElement<T> doc = (JAXBElement<T>) u.unmarshal( inputStream );
131 
132         return doc.getValue( );
133     }
134 
135     public static void save( Model model, OutputStream outputStream ) throws JAXBException
136     {
137         String packageName = model.getClass( ).getPackage( ).getName( );
138         ObjectFactory factory = new ObjectFactory( );
139         JAXBElement<Model> element = factory.createProject( model );
140 
141         JAXBContext jc = JAXBContext.newInstance( packageName );
142         Marshaller m = jc.createMarshaller( );
143         m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
144         m.setProperty( Marshaller.JAXB_SCHEMA_LOCATION, "http://maven.apache.org/maven-v4_0_0.xsd" );
145         m.marshal( element, outputStream );
146     }
147 
148     public static String getNextVersion( String strVersion )
149     {
150         String strNextVersion = CONSTANTE_EMPTY_STRING;
151 
152         if ( strVersion.contains( CONSTANTE_SNAPSHOT ) )
153         {
154             strVersion = strVersion.substring( 0, strVersion.indexOf( CONSTANTE_SNAPSHOT ) );
155         }
156 
157         int nLastIndex = strVersion.lastIndexOf( "." );
158 
159         try
160         {
161             int nMinorVersion = Integer.parseInt( strVersion.substring( nLastIndex + 1, strVersion.length( ) ) );
162             nMinorVersion++;
163 
164             strNextVersion += strVersion.substring( 0, nLastIndex + 1 );
165             strNextVersion += nMinorVersion;
166             strNextVersion += CONSTANTE_SNAPSHOT;
167         }
168         catch( NumberFormatException nfe )
169         {
170             nfe.printStackTrace( );
171         }
172 
173         return strNextVersion;
174     }
175 
176     /**
177      * Retourne la version [stable] courante (sans -SNAPSHOT si present dans le pom)
178      * 
179      * @return
180      * @throws JAXBException
181      * @throws FileNotFoundException
182      */
183     public static String getReleaseVersion( String strPathLocalSiteName ) throws JAXBException, FileNotFoundException
184     {
185         InputStream is = new FileInputStream( DeploymentUtils.getPathPomFile( strPathLocalSiteName ) );
186 
187         Model model = unmarshal( Model.class, is );
188 
189         String strVersion = model.getVersion( );
190 
191         if ( strVersion.contains( "-SNAPSHOT" ) )
192         {
193             strVersion = strVersion.substring( 0, strVersion.indexOf( "-SNAPSHOT" ) );
194         }
195 
196         return strVersion;
197     }
198 
199     /**
200      * Retourne la version dans le pom)
201      * 
202      * @return
203      * @throws JAXBException
204      * @throws FileNotFoundException
205      */
206     public static String getSiteVersion( String strPathLocalSiteName ) throws JAXBException, FileNotFoundException
207     {
208         InputStream is = new FileInputStream( DeploymentUtils.getPathPomFile( strPathLocalSiteName ) );
209 
210         Model model = unmarshal( Model.class, is );
211 
212         String strVersion = model.getVersion( );
213         return strVersion;
214     }
215 
216     /**
217      * Retourne la version dans le pom)
218      * 
219      * @return
220      * @throws JAXBException
221      * @throws FileNotFoundException
222      */
223     public static String getSiteArtifactId( String strPathLocalSiteName ) throws JAXBException, FileNotFoundException
224     {
225         InputStream is = new FileInputStream( DeploymentUtils.getPathPomFile( strPathLocalSiteName ) );
226 
227         Model model = unmarshal( Model.class, is );
228 
229         String strVersion = model.getArtifactId( );
230         return strVersion;
231     }
232 
233     public static String updateReleaseVersion( String strPathLocalSiteName, String strNewVersion, String commitMessage, SVNCommitClient svnCommitClient )
234             throws ParserConfigurationException, SAXException, IOException, TransformerException, SVNException, JAXBException
235     {
236         String strPomFile = DeploymentUtils.getPathPomFile( strPathLocalSiteName );
237         InputStream inputStream = null;
238         OutputStream outputStream = null;
239 
240         try
241         {
242             inputStream = new FileInputStream( strPomFile );
243 
244             Model model = unmarshal( Model.class, inputStream );
245 
246             if ( !model.getVersion( ).equals( strNewVersion ) )
247             {
248                 model.setVersion( strNewVersion );
249 
250                 outputStream = new FileOutputStream( strPomFile );
251 
252                 save( model, outputStream );
253 
254                 // COMMIT
255                 /*
256                  * paths - an array of local items which should be traversed to collect information on every changed item (one SVNCommitItem per each modified
257                  * local item) keepLocks - if true and there are local items that were locked then these items will be left locked after traversing all of them,
258                  * otherwise the items will be unlocked force - forces collecting commit items for a non-recursive commit recursive - relevant only for
259                  * directory items: if true then the entire directory tree will be traversed including all child directories, otherwise only items located in
260                  * the directory itself will be processed
261                  */
262                 SVNCommitPacket commitPacket = svnCommitClient.doCollectCommitItems( new File [ ] {
263                     new File( strPomFile )
264                 }, false, false, false );
265 
266                 if ( !SVNCommitPacket.EMPTY.equals( commitPacket ) )
267                 {
268                     svnCommitClient.doCommit( commitPacket, false, commitMessage );
269                 }
270             }
271             else
272             {
273                 return "Pom already up to date\n";
274             }
275         }
276         finally
277         {
278             if ( outputStream != null )
279             {
280                 try
281                 {
282                     outputStream.close( );
283                 }
284                 catch( IOException ex )
285                 {
286                     // nothing...
287                     ex.printStackTrace( );
288                 }
289             }
290         }
291 
292         return "";
293     }
294 }