View Javadoc
1   package org.apache.maven.plugin.cxx.utils.svn;
2   
3   /*
4    * Copyright (C) 2011-2016, Neticoa SAS France - Tous droits réservés.
5    * Author(s) : Franck Bonin, Neticoa SAS France
6    *
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   *
19   */
20   
21  import org.apache.maven.plugin.cxx.utils.Credential;
22  import org.apache.maven.plugin.cxx.utils.ExecutorService;
23  import org.apache.maven.plugin.logging.Log;
24  import org.apache.maven.plugin.MojoExecutionException;
25  
26  import java.io.OutputStream;
27  import java.io.File;
28  import java.io.IOException;
29  import java.io.ByteArrayInputStream;
30  import java.io.ByteArrayOutputStream;
31  import java.io.BufferedReader;
32  import java.io.StringReader;
33  import java.io.FileOutputStream;
34  
35  import java.util.Properties;
36  
37  import java.text.StringCharacterIterator;
38   
39  import org.apache.commons.exec.CommandLine;
40  
41  import org.codehaus.plexus.util.StringUtils;
42   
43  import org.apache.commons.exec.DefaultExecutor;
44  import org.apache.commons.exec.ExecuteException;
45  import org.apache.commons.exec.Executor;
46  
47  import javax.xml.parsers.SAXParserFactory;
48  import javax.xml.parsers.SAXParser;
49  import org.xml.sax.InputSource;
50  import org.xml.sax.XMLReader;
51  
52  import org.codehaus.plexus.util.IOUtil;
53  
54  /**
55   * TODO
56   * 
57   * @version 8 mars 2016
58   * @author fbonin
59   */
60  public class SvnService
61  {
62      public static void execSvnCommand( File basedir, Credential cred, String[] specificParams,
63          OutputStream out, Log log ) throws MojoExecutionException
64      {
65          Properties enviro = null;
66          try
67          {
68              enviro = ExecutorService.getSystemEnvVars();
69              enviro.put( "LC_MESSAGES", "C" );
70          }
71          catch ( IOException e )
72          {
73              log.error( "Could not assign default system environment variables.", e );
74          }
75          
76          CommandLine commandLine = ExecutorService.getExecutablePath( "svn", enviro, basedir );
77          
78          if ( cred != null && ! StringUtils.isEmpty( cred.getUsername() ) )
79          {
80              commandLine.addArguments( new String[] { "--username", cred.getUsername() } );
81          }
82          if ( cred != null && ! StringUtils.isEmpty( cred.getPassword() ) )
83          {
84              commandLine.addArguments( new String[] { "--password", cred.getPassword() } );
85          }
86          /* TODO later :
87          commandLine.addArguments( new String[] {"--config-dir", "todo" } );
88          commandLine.addArgument( "--no-auth-cache" ); 
89          commandLine.addArgument( "--non-interactive" );
90          commandLine.addArgument( "--trust-server-cert" );
91          */
92  
93          commandLine.addArguments( specificParams );
94          
95          Executor exec = new DefaultExecutor();
96          
97          try
98          {
99              log.debug( "Execute command '" + commandLine + "'" );
100             int resultCode = ExecutorService.executeCommandLine( exec, commandLine, enviro, out,
101                 System.err, System.in );
102         }
103         catch ( ExecuteException e )
104         {
105             throw new MojoExecutionException( "Command '" + commandLine + "' execution failed.", e );
106         }
107         catch ( IOException e )
108         {
109             throw new MojoExecutionException( "Command '" + commandLine + "' execution failed.", e );
110         }
111     }
112     
113     public static SvnInfo getSvnInfo( File basedir, Credential cred, String uri,
114         Log log, boolean noParsingFailure ) throws MojoExecutionException
115     {
116         ByteArrayOutputStream out = new ByteArrayOutputStream();
117         
118         execSvnCommand( basedir, cred, new String[] {"info", uri, "--xml"}, out, log );
119         
120         SvnInfo svnInfo = new SvnInfo();
121         try
122         {
123             SAXParserFactory sfactory = SAXParserFactory.newInstance();
124             SAXParser parser = sfactory.newSAXParser();
125             XMLReader xmlparser = parser.getXMLReader();
126             xmlparser.setContentHandler( svnInfo );
127             xmlparser.parse( new InputSource( new ByteArrayInputStream( out.toByteArray( ) ) ) );
128         }
129         catch ( Exception e )
130         {
131             if ( noParsingFailure )
132             {
133                 log.error( "svn info xml parsing failed : " + e );
134             }
135             else
136             {
137                 throw new MojoExecutionException( "svn info xml parsing failed.", e );
138             }
139         }        
140         return svnInfo;
141     }
142     
143     public static SvnExternalsEntries loadSvnExternals( File basedir, Credential cred, String uri, Log log )
144         throws MojoExecutionException
145     {
146         SvnExternalsEntries properties = new SvnExternalsEntries();
147       
148         ByteArrayOutputStream out = new ByteArrayOutputStream();
149         
150         SvnService.execSvnCommand( basedir, cred,
151             new String[] {"propget", "svn:externals", uri}, out, log );
152         
153         BufferedReader in = new BufferedReader( new StringReader( out.toString( ) ) );
154         
155         String line = null;
156         
157         try
158         {
159             /* old svn 1.4 :
160               third-party/sounds             http://svn.example.com/repos/sounds
161               third-party/skins -r148        http://svn.example.com/skinproj
162               third-party/skins/toolkit -r21 http://svn.example.com/skin-maker
163             */
164             /* svn 1.5 and above (operative rev):
165               http://svn.example.com/repos/sounds third-party/sounds
166               -r148 http://svn.example.com/skinproj third-party/skins
167               -r21  http://svn.example.com/skin-maker third-party/skins/toolkit
168               svn 1.5 and above (PEG rev):
169               http://svn.example.com/repos/sounds third-party/sounds
170               http://svn.example.com/skinproj@148 third-party/skins
171               http://svn.example.com/skin-maker@21 third-party/skins/toolkit
172             */
173             
174             // this parser only support svn:externals syntaxe 1.5 and above
175             // [revision] origin target_dir
176             while ( null != ( line = in.readLine() ) )
177             {
178                 StringCharacterIterator iter = new StringCharacterIterator( line );
179                 SvnExternalsTokenizer m = new SvnExternalsTokenizer( iter );
180                 SvnExternalEntry external = new SvnExternalEntry();
181 
182                 SvnExternalsTokenizer.Token tok = m.nextToken();
183                 if ( SvnExternalsTokenizer.TokenType.revision == tok.tokenType )
184                 {
185                     external.revision = tok.value.toString();
186                     
187                     tok = m.nextToken();
188                     external.origin = SvnExternalsTokenizer.TokenType.libelle == tok.tokenType
189                         ? tok.value.toString() : null; 
190                     
191                     tok = m.nextToken();
192                     external.targetDir = SvnExternalsTokenizer.TokenType.libelle == tok.tokenType
193                         ? tok.value.toString() : null; 
194                 }
195                 else if ( SvnExternalsTokenizer.TokenType.libelle == tok.tokenType )
196                 {
197                     external.origin = tok.value.toString();
198                     
199                     tok = m.nextToken();
200                     external.targetDir = SvnExternalsTokenizer.TokenType.libelle == tok.tokenType
201                         ? tok.value.toString() : null; 
202                 }
203                 else if ( SvnExternalsTokenizer.TokenType.comment == tok.tokenType )
204                 {
205                     external.comment = tok.value.toString();
206                 }
207                 else if ( SvnExternalsTokenizer.TokenType.empty == tok.tokenType )
208                 {
209                     // ignore empty lines
210                     continue;
211                 }
212                 
213                 if ( external.isValide() )
214                 {
215                     properties.put( external );
216                 }
217                 else
218                 {
219                     log.warn( "unrecognized svn:externals entry of " + uri + " line content : '" + line + "'" );
220                 }
221             }
222         }
223         catch ( Exception e )
224         {
225             log.warn( "Failed to parse svn:externals of " + uri + " : " + e );
226         }
227         
228         return properties;
229     }
230     
231     public static void writeSvnExternals( File basedir, Credential cred, String uri,
232         SvnExternalsEntries properties, String tempDir, Log log ) throws MojoExecutionException
233     {   
234         String targetDirectoryPath = tempDir;
235         new File( targetDirectoryPath ).mkdirs();
236         File file = new File( targetDirectoryPath, "svn.externals" );
237 
238         OutputStream outputStream = null;
239         try
240         {
241             outputStream = new FileOutputStream( file );
242 
243             for ( SvnExternalEntry entry : properties.values() )
244             {
245                 if ( entry.isValide() )
246                 {
247                     outputStream.write( ( entry.toString() + "\n" ).getBytes() );
248                 }
249             }
250         }
251         catch ( Exception e )
252         {
253             throw new MojoExecutionException( "Error writing intermediate properties file "
254                 + file.toString() + " : " + e );
255         }
256         finally
257         {
258             IOUtil.close( outputStream );
259         }
260         
261         ByteArrayOutputStream out = new ByteArrayOutputStream();
262         SvnService.execSvnCommand( basedir, cred,
263             new String[] {"propset", "svn:externals", "--file", file.getPath(), uri}, out, log );
264     }
265     
266 }