/* * Copyright (C) 2003-2012 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see<http://www.gnu.org/licenses/>. */ package org.exoplatform.services.jcr.impl.core.query; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; /** * Created by The eXo Platform SAS * Author : eXoPlatform * exo@exoplatform.com * Feb 6, 2012 */ /** * Wrapper of native process calling RSYNC utility */ public class RSyncJob { private static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.RsyncJob"); private final static String RSYNC_USER_SYSTEM_PROPERTY = "USER"; private final static String RSYNC_PASSWORD_SYSTEM_PROPERTY = "RSYNC_PASSWORD"; private Process process; private final String src; private final String dst; private String userName; private String password; public RSyncJob(String src, String dst, String userName, String password) { this.src = src.endsWith(File.separator) ? src : src + File.separator; this.dst = dst; this.userName = userName; this.password = password; } /** * Executes RSYNC synchronization job * * @throws IOException */ public void execute() throws IOException { // Future todo: Use JNI and librsync library? Runtime run = Runtime.getRuntime(); try { String command = "rsync -rv --delete " + src + " " + dst; if (LOG.isDebugEnabled()) { LOG.debug("Rsync job started: " + command); } if (userName != null && password != null) { String[] envProperties = new String[]{RSYNC_USER_SYSTEM_PROPERTY + "=" + userName, RSYNC_PASSWORD_SYSTEM_PROPERTY + "=" + password}; process = run.exec(command, envProperties); } else { process = run.exec(command); } // Handle process Standard and Error output InputStream stderr = process.getErrorStream(); InputStreamReader isrErr = new InputStreamReader(stderr); BufferedReader brErr = new BufferedReader(isrErr); InputStream stdout = process.getInputStream(); InputStreamReader isrStd = new InputStreamReader(stdout); BufferedReader brStd = new BufferedReader(isrStd); String val = null; StringBuilder stringBuilderErr = new StringBuilder(); StringBuilder stringBuilderStd = new StringBuilder(); while ((val = brStd.readLine()) != null) { stringBuilderStd.append(val); stringBuilderStd.append('\n'); } while ((val = brErr.readLine()) != null) { stringBuilderErr.append(val); stringBuilderErr.append('\n'); } Integer returnCode = null; // wait for thread while (returnCode == null) { try { returnCode = process.waitFor(); } catch (InterruptedException e) { // oops, this can happen sometimes } } if (LOG.isDebugEnabled()) { LOG.debug("Rsync job finished: " + returnCode + ". Error stream output \n" + stringBuilderErr.toString() + " Standard stream output \n" + stringBuilderStd.toString()); } if (returnCode != 0) { throw new IOException("RSync job finished with exit code is " + returnCode + ". Error stream output: \n" + stringBuilderErr.toString()); } } finally { process = null; } } public void forceCancel() { if (process != null) { process.destroy(); } } }