/* * Copyright 2014 Brian Rosenberger (Brutex Network) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.brutex.svn; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; /* Executes the svnadmin utility * * @author Brian Rosenberger bru(at)brutex.de * @since 0.1 */ public class SVNAdminExecutor { private Logger logger = Logger.getLogger(SVNAdminExecutor.class); private final File svnadmin; private final String repos; private String rev = null; private String message = null; private String locale = "de_DE.UTF-8"; private String encoding = "UTF-8"; private boolean useBypassHooks = true; /** * Instantiates a new SVN admin executor. * * @param svnadmin the svnadmin * @param repos the repos */ public SVNAdminExecutor(File svnadmin, String repos) { if(! svnadmin.exists() ) throw new IllegalArgumentException( String.format("The svnadmin executable at '%s' does not exist.", svnadmin.toString())); if(! svnadmin.isFile() ) throw new IllegalArgumentException( String.format("The svnadmin utility at'%s' is not a file.", svnadmin.toString())); logger.debug(String.format("Instantiating '%s' with svnadmin at '%s'.", this.getClass().getCanonicalName(), svnadmin.toString())); this.svnadmin = svnadmin; logger.debug(String.format("Working against svn repository at '%s'.", repos)); this.repos = repos; } /** * Execute svn admin. * * @param command the command * @return the string */ public String executeSVNAdmin(SVNAdminCommand command) { StringBuilder sb = new StringBuilder(); StringBuilder sberr = new StringBuilder(); if(rev==null) { logger.error("The revision can not be 'null' for the svnadmin command."); return null; } if(message==null) { logger.error("The new log message can not be 'null' for the svnadmin command."); return null; } File logfile = null; try { logfile = File.createTempFile("~msg"+rev+"_", ".tmp"); BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logfile), encoding)); out.write(message); out.flush(); out.close(); } catch (IOException e) { logger.error("Failed to write new log message to temporary file '"+logfile.getAbsolutePath()+"'.", e); return null; } try { List cmdline = new ArrayList(5); cmdline.add(svnadmin.toString()); cmdline.add(command.getValue()); cmdline.add(repos); if(useBypassHooks) { cmdline.add("--bypass-hooks"); } cmdline.add("-r"); cmdline.add(rev); cmdline.add(logfile.getAbsolutePath()); ProcessBuilder pf = new ProcessBuilder(cmdline); logger.debug(String.format("Executing svnadmin with commandline '%s'.", pf.command())); Map env = pf.environment(); env.put("LANG", locale); Process svnprocess = pf.start(); BufferedReader stdin = new BufferedReader(new InputStreamReader(svnprocess.getInputStream(), encoding)); BufferedReader stderr = new BufferedReader(new InputStreamReader(svnprocess.getErrorStream(), encoding)); String s; while( (s = stdin.readLine()) != null ) { sb.append(s + '\n'); } while( (s = stderr.readLine()) != null ) { sberr.append(s + '\n'); } stdin.close(); stderr.close(); } catch (IOException e) { logger.error( String.format( "Error calling the svnadmin utility: '%s'", e.getMessage())); e.printStackTrace(); } finally { logfile.deleteOnExit(); } String error = sberr.toString(); if( error.length()>0 ) { error = "Failed to call svnadmin. The STDERR was '"+error+"'"; logger.error(error); throw new IllegalArgumentException(error); } String output = sb.toString().trim(); logger.debug(String.format("Svnadmin output was '%s'", output)); return output; } public void setRev(String rev) { if(rev==null || rev.length()<=0) throw new IllegalArgumentException("Revision cannot be null or empty."); this.rev = rev; } public void setEncoding(String encoding) { this.encoding = encoding; } /** * Set the locale that will be pushed into * 'LANG' environment variable. * * @param locale i.e. de_DE.UTF-8 */ public void setLocale(String locale) { this.locale = locale; } /** * Set the new log message. * * @param message new message */ public void setMessage(String message) { this.message = message; } /** * Set this to true to bypass the pre-revprop-change and post-revprop-change * hooks. * * @param useBypassHooks defaults to true */ public void setUseBypassHooks(boolean useBypassHooks) { this.useBypassHooks = useBypassHooks; } }