Package org.syncany.operations

Source Code of org.syncany.operations.ActionFileHandler

/*
* Syncany, www.syncany.org
* Copyright (C) 2011-2014 Philipp C. Heckel <philipp.heckel@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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.syncany.operations;

import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
import java.io.File;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.syncany.config.UserConfig;
import org.syncany.operations.cleanup.CleanupOperation;
import org.syncany.plugins.transfer.StorageException;
import org.syncany.plugins.transfer.TransferManager;
import org.syncany.plugins.transfer.files.ActionRemoteFile;

/**
* The action handler manages the {@link ActionRemoteFile}s written during an {@link Operation}.
*
* <p>In particular, it uploads an initial action file when the operation is started, deletes it
* when it is finished/terminated, and renews the operation's action file in a given interval.
*
* <p>The renewal is necessary to show other clients that the operation is still running. To ensure
* action file renewal, the {@link #start()} method starts a timer that uploads a new {@link ActionRemoteFile}
* every {@link #ACTION_RENEWAL_INTERVAL} milliseconds. The {@link #finish()} method stops this timer.
*
* @see CleanupOperation
* @author Philipp C. Heckel <philipp.heckel@gmail.com>
*/
public class ActionFileHandler
  private static final Logger logger = Logger.getLogger(ActionFileHandler.class.getSimpleName());

  /**
   * Defines the time that the action files updated while an operation is running.
   *
   * This time period must be (significantly) smaller than the ignore time defined in
   * {@link CleanupOperation#ACTION_FILE_DELETE_TIME}.
   */
  public static final int ACTION_RENEWAL_INTERVAL = 2*60*1000; // Minutes

  private TransferManager transferManager;
  private ActionRemoteFile actionFile;
  private Timer actionRenewalTimer;

  public ActionFileHandler(TransferManager transferManager, String operationName, String machineName) {   
    try {
      this.transferManager = transferManager;
      this.actionFile = new ActionRemoteFile(operationName, machineName, System.currentTimeMillis());
      this.actionRenewalTimer = createNewActionRenewalTimer();     
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }   
  }

  private Timer createNewActionRenewalTimer() {
    return new Timer("ActRenewTim");
  }

  public void start() throws Exception {
    logger.log(Level.INFO, "Starting action for " + actionFile + " ...");
   
    uploadActionFile(actionFile);
    scheduleActionRenewalTask();
  }

  public void finish() throws StorageException {
    logger.log(Level.INFO, "Finishing action for " + actionFile + " ...");
   
    cancelActionRenewalTask();
    deleteActionFile(actionFile);
  }

  private void deleteActionFile(ActionRemoteFile actionFile) throws StorageException {
    logger.log(Level.INFO, "Deleting action file: " + actionFile);
    transferManager.delete(actionFile);
  }

  private void uploadActionFile(ActionRemoteFile actionFile) throws Exception {
    logger.log(Level.INFO, "Uploading action file: " + actionFile);

    File tempActionFile = File.createTempFile("syncany-action-", ".tmp");
    tempActionFile.deleteOnExit();
   
    transferManager.upload(tempActionFile, actionFile);
   
    tempActionFile.delete();
  }
 
  private void scheduleActionRenewalTask() {
    logger.log(Level.INFO, "Scheduling action renewal task for every " + (ACTION_RENEWAL_INTERVAL/60/1000) + " minutes, for " + actionFile + " ...");
   
    actionRenewalTimer.schedule(new TimerTask() {     
      @Override
      public void run() {
        renewActionFile()
       
        if (UserConfig.preventStandbyEnabled()) {
          preventStandby();
        }
      }
    }, ACTION_RENEWAL_INTERVAL, ACTION_RENEWAL_INTERVAL);
  }

  private void cancelActionRenewalTask() {
    actionRenewalTimer.cancel();
    actionRenewalTimer = createNewActionRenewalTimer();
  }
 
  private synchronized void renewActionFile() {
    try {
      logger.log(Level.INFO, "Scheduling action renewal task for every " + (ACTION_RENEWAL_INTERVAL/60/1000) + " minutes, for " + actionFile + " ...");

      ActionRemoteFile oldActionFile = actionFile;     
      ActionRemoteFile newActionFile = new ActionRemoteFile(oldActionFile.getOperationName(), oldActionFile.getClientName(), System.currentTimeMillis());
     
      uploadActionFile(newActionFile);
      deleteActionFile(oldActionFile);
     
      actionFile = newActionFile;
    }
    catch (Exception e) {
      logger.log(Level.SEVERE, "ERROR: Cannot renew action file!", e);
    }
  }
 
  private void preventStandby() {
    try {
      Robot robot = new Robot();

      Point currentMousePosition = MouseInfo.getPointerInfo().getLocation();
      Point tempMousePosition = (currentMousePosition.x > 0) ? new Point(currentMousePosition.x - 10, currentMousePosition.y) : new Point(
          currentMousePosition.x + 10, currentMousePosition.y);

      logger.log(Level.INFO, "Standby prevention: Moving mouse 1px (and back): " + currentMousePosition);

      robot.mouseMove(tempMousePosition.x, tempMousePosition.y);
      robot.mouseMove(currentMousePosition.x, currentMousePosition.y);
    }   
    catch (Exception e) {
      if (e.getMessage() != null && e.getMessage().contains("headless")) {
        logger.log(Level.INFO, "Cannot prevent standby, because headless mode is enabled (no GUI environment)");
      }
      else {
        logger.log(Level.WARNING, "Standby prevention failed (headless mode?).", e)
      }     
    }
  }
}
TOP

Related Classes of org.syncany.operations.ActionFileHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.