2012-03-23 16 views
1

私は始める方法を少し失っているので、あまりコードはありません。NetbeansプラットフォームベースのJavaアプリケーションで自動バックアップ機能を作成するにはどうすればよいですか?

私はDerbyデータベースをバックアップし、ユーザーデータを格納するアプリケーションを作成しようとしています。手動で実行できるバックアップ自体のコードがあります。私は、設定ファイルをチェックし、適切なスケジュール(毎日、毎週、毎月)でバックアップを実行する機能を作成したい。私は起動確認をすることができると思うが、アプリケーションが起動していれば問題がある。定期的に時刻を確認したい。このアプリケーションは何日間も実行される可能性があります。

また、スケジュールされた時間が来た場合に、ユーザーが数時間、バックアップを「スリープ」できるようにしたいとします。

ブートアップ時にThread.Sleep()を呼び出して、X分/時間ごとにチェックすることができます。同様に、バックアップをスリープ状態にする場合もあります。それが最善の方法であるかどうかは分かりません。私は任意のAPI呼び出しはおそらく同じを行うだろうと仮定しますが、私はそのようなスレッドを処理する何かが欠けているのだろうかと思っています。

Netbeans IDEには何らかの機能/ライブラリがありますか&私が利用しているプラ​​ットフォームですが、この機能を構築するのに役立つでしょうか?

おかげ

+0

NetBeansプラットフォームを使用してアプリケーションを開発しているのですか、それとも単にIDEとして使用していますか? – Marcelo

+0

私はプラットフォームだけでなくIDEを開発しています。 – kevingreen

+0

ネットビーンズのサービスはここにありますか?私は自動更新サービスがあることを知っていますが、私はそれが起動時に実行されると思います。そのためにLayout.xmlにいくつかの関係があります。 – kevingreen

答えて

0

は、ここで私はそれを実装する方法です。私は実装の方法を少し変えました。だから、この答えは正確に質問の言葉になっていません。私は "スリープ"機能を削除しましたが、私が提供しているコードを使用すれば簡単に実装できます。私はそれを部分的に実装しました、そして、私は以下のコードを示します。基本的には、Runnableを実装するいくつかのクラスを作成する必要があります。バックアップを実行する実際のコードは表示されません。とにかくプラットフォーム特有のものなので、あなたのように扱います。私たちはDerbyを使用しています。そのため、バックアップがどのように処理されるのでしょうか。

私はクラス&機能によってそれを打破するでしょう:

DatabaseBackupReminder。このクラスは、前回のバックアップからの経過時間を通知するプロンプトをユーザに処理し、X個の時間だけリマインダをスリープさせる。それはスレッドそのものなので、別の場所で呼び出せて寝ることができるので、最後にバックアップが実行された日時を確認するためにDBにpingを実行しているわけではありません。

public class DatabaseBackupReminder extends Thread 

/*****************Variables ****************/ 
String backupFrequency; //How often to backup? Daily, Monthly, Weekly, or Never 
String backupTimeOfDay; //I don't use this, but the idea was to autobackup morning, 
         //day, or night 
boolean backupIsSet = false; //Have they set a schedule? 
Timestamp lastBackupRunTime; //Pulled from our Derby database to see when the backup was run 
Timestamp backupScheduleSetTime; //Pulled from the DB to see when the user set the schedule 
           //This is so, if they set it to daily, we will check 24hrs from the set date for 
           //backup validity 
Period periodSinceLastBackup; //Using the Joda library, we use this to calculate 
boolean backupEverRan; //We check to see if they've ever backed up 
            //Useful logic for clear dialog purposes. 
public enum enumBackupFrequencies {DAILY, WEEKLY, MONTHLY, NEVER} //use a valueOf with the backupFrequency. 
//We're using java 1.7, no Switch on strings, this is a workaround 
    Herd herd;//Herd is a custom datatype we use, it's basically a wrapper around a Derby table. 
/*******************methods***************************************/          
    public DatabaseBackupReminder(String backupFrequency, String backupTimeOfDay, Timestamp lastBackupRunTime, Timestamp backupScheduleSetTime, Herd herd) 
    //Constructor 
    //Herd is a custom datatype we use, it's basically a wrapper around a Derby table. 
    boolean getBackupStillValid() //Checks based on lastBackupRunTime, and backupEverRan to see 
    //if we have a valid backup 

    public void promptForBackup(Period duration, boolean backupEverRunx) 
     //Take's the duration & has it ever run and displays a message. 
     //Something like "It's been 2 weeks, 1 days since your last backup" 
     //Not fully implemented, this was scrapped, but I'll explain how I think it should have worked below 

    public void run() 
    //Main thread for this reminder 
    public String timeSinceLastBackupString() 
    //Calls it based on objects values, not specific values, see method below 
    public String timeSinceLastBackupString(Period duration, boolean backupEverRunx) 
    //Constructs the string used in promptForBackup 



/********full method code**********/ 
public DatabaseBackupReminder(String backupFrequency, String backupTimeOfDay, Timestamp lastBackupRunTime, Timestamp backupScheduleSetTime, Herd herd) { 
    this.herd = herd; 
    if (backupFrequency == null) { 
     backupFrequency = ""; 
    } 
    if (backupTimeOfDay == null) { 
     backupTimeOfDay = ""; 
    } 
    if (backupScheduleSetTime == null) { 
     this.backupScheduleSetTime = new Timestamp(0); 
    } else { 
     this.backupScheduleSetTime = backupScheduleSetTime; 
    } 
    this.backupFrequency = backupFrequency; 
    this.backupTimeOfDay = backupTimeOfDay; 
    if (lastBackupRunTime == null) { 
     this.lastBackupRunTime = new Timestamp(0); 
    } else { 
     this.lastBackupRunTime = lastBackupRunTime; 
    } 
    periodSinceLastBackup = new Period(this.lastBackupRunTime.getTime(), Calendar.getInstance().getTimeInMillis()); 
    if (backupFrequency.trim().length() > 1) { 
     backupIsSet = true; 
    } 
    backupEverRan = false; 
    if (this.lastBackupRunTime.getTime() != 0) { 
     backupEverRan = true; 
    } 
} 

boolean getBackupStillValid() { 
    if (lastBackupRunTime.getTime() > 0) { 
     backupEverRan = true; 

    } else { 
     return false; 
    } 
    if (backupFrequency.trim().length() > 1) { 
     backupIsSet = true; 

    } 


    if (backupIsSet) { 
     switch (enumBackupFrequencies.valueOf(backupFrequency.trim().toUpperCase())) { 
      case DAILY: 
       if (periodSinceLastBackup.getYears() > 1 || periodSinceLastBackup.getMonths() > 1 || periodSinceLastBackup.getWeeks() > 1 || periodSinceLastBackup.getDays() >= 1) { 

        return false; 
       } 
       break; 
      case WEEKLY: 
       if (periodSinceLastBackup.getYears() > 1 || periodSinceLastBackup.getMonths() > 1 || periodSinceLastBackup.getWeeks() >= 1) { 
        return false; 

       } 
       break; 
      case MONTHLY: 
       if (periodSinceLastBackup.getYears() > 1 || periodSinceLastBackup.getMonths() >= 1) { 
        return false; 

       } 
       break; 
      case NEVER: 
     } 
    } 
    if (backupEverRan) { 
     return true; 
    } else { 
     return false; 
    } 

} 

public void run() { 

    if (backupIsSet) { 
     switch (enumBackupFrequencies.valueOf(backupFrequency.trim().toUpperCase())) { 
      case DAILY: 
       if (periodSinceLastBackup.getYears() > 1 || periodSinceLastBackup.getMonths() > 1 || periodSinceLastBackup.getWeeks() > 1 || periodSinceLastBackup.getDays() > 1) { 

        promptForBackup(periodSinceLastBackup, backupEverRan); 

       } 
       break; 
      case WEEKLY: 
       if (periodSinceLastBackup.getYears() > 1 || periodSinceLastBackup.getMonths() > 1 || periodSinceLastBackup.getWeeks() > 1) { 
        promptForBackup(periodSinceLastBackup, backupEverRan); 

       } 
       break; 
      case MONTHLY: 
       if (periodSinceLastBackup.getYears() > 1 || periodSinceLastBackup.getMonths() > 1) { 
        promptForBackup(periodSinceLastBackup, backupEverRan); 

       } 
       break; 
      case NEVER: 
     } 
    } 



} 
public void promptForBackup(Period duration, boolean backupEverRun) { 
    int response; 
    long delay = 0; 

    response = JOptionPane.showConfirmDialog(null, timeSinceLastBackupString(duration, backupEverRun)); 
    if (response == JOptionPane.NO_OPTION) { 
     //TODO: open "how long to remind" dialog 
     BackupSnoozePanel snoozePanel = new BackupSnoozePanel(); 

     JOptionPane.showMessageDialog(null, snoozePanel); 

     switch (snoozePanel.BackupDelayInterval.getSelectedIndex()) { 
      case 0: 
       delay = 5000; //5 seconds, for testing 
       //delay = 60 * 60 * 1000; // 1 hour 
       break; 
      case 1: 
       delay = 10000; //10 seconds, for testing 
       //delay = 4 * 60 * 60 * 1000; // 4 hours 
       break; 
      case 2: 
       delay = 15000; //15 seconds, for testing 
       //delay = 8 * 60 * 60 * 1000; // 8 hours 
       break; 
      case 3: 
       delay = 20000; //20 seconds, for testing 
       ///delay = 12 * 60 * 60 * 1000; // 12 hours 
       break; 
      case 4: 
       delay = 0; //next boot 
       break; 
     } 


    } else { 
     //TODO: run backup  
    } 
    try { 

     if (delay > 0) { 
     //TODO: Code to sleep this reminder. Thread.sleep(delay) probably 

     } 
    } catch (Exception ex) { 
     //TODO: something to handle exceptions 
    } 

}//end promptForBackup 

public String timeSinceLastBackupString(Period duration, boolean backupEverRunx) { 

    if (!backupEverRunx) { 
     return "The backup has never been run. Would you like to run one?"; 
    } 


    String durationString = "It has been "; 
    if (duration.getYears() >= 1) { 
     durationString += duration.getYears() + " years"; 
    } 
    if (duration.getMonths() >= 1) { 
     durationString += duration.getMonths() + " months"; 
    } 
    if (duration.getWeeks() >= 1) { 
     durationString += duration.getWeeks() + " weeks "; 
    } 
    if (duration.getDays() >= 1) { 
     durationString += duration.getDays() + " days"; 
    } 
    durationString += " since your last backup. Would you like to run one?"; 
    return durationString; 
} 

public String timeSinceLastBackupString() { 
    return timeSinceLastBackupString(periodSinceLastBackup, backupEverRan); 



} 

DatabaseBackupController。このクラスは名前のとおり、プロセス全体を制御します。リマインダから、実際のバックアップコードを実行するまで。

public class DatabaseBackupController 
/***********variables*************/ 
String scheduleText; //Daily, Weekly, Monthy, or Never. It's set in our options panel. 
String timeText; //Time of day to run the backup, morning, day, or night. As 04:00-12:00 etc… 
Timestamp lastBackupRun; //Timestamp from DB (Herd is our abstracted class) from when it was last run. 
Timestamp lastBackupRunScheduleSetTime; //Timestamp from DB when the backup was set. 
Herd herd; //Herd is a custom datatype we use, it's basically a wrapper around a Derby table. 

/***********Method Headers**********/ 
public DatabaseBackupController(Herd herd) //Constructor 
//Sets global variables, based on values in DB 
public void setupBackupReminder() 
//calls DatabaseBackupReminder, passes global variables. 
public boolean checkBackupReminder() 
//Checks to make sure the current backup is valid within the duration since last backup 
public void runBackupPrompt() 
//When we are in fact going to backup, calls BackupRunner instance. 


/**********full method code****************/ 
    public DatabaseBackupController(Herd herd) { 
    this.herd = herd; 
    scheduleText = herd.getBackupSchedule(); 
    timeText = herd.getBackupTime(); 
    lastBackupRun = herd.getBackupScheduledLastRun(); 
    lastBackupRunScheduleSetTime = herd.getBackupScheduledDatetime(); 
} 

public void setupBackupReminder() { 
    DatabaseBackupReminder dbReminder = new DatabaseBackupReminder(scheduleText, timeText, lastBackupRun, lastBackupRunScheduleSetTime, herd); 
    Thread dbBackupThread = new Thread(dbReminder); 

    dbBackupThread.start(); 
}//end setupBackupReminder 

public boolean checkBackupReminder() { 
    DatabaseBackupReminder dbReminder = new DatabaseBackupReminder(scheduleText, timeText, lastBackupRun, lastBackupRunScheduleSetTime, herd); 
    return dbReminder.getBackupStillValid(); 
} 

public void runBackupPrompt() { 
    DatabaseBackupReminder dbReminder = new DatabaseBackupReminder(scheduleText, timeText, lastBackupRun, lastBackupRunScheduleSetTime, herd); 
    int response = JOptionPane.showConfirmDialog(null, dbReminder.timeSinceLastBackupString()); 
    if (response == JOptionPane.YES_OPTION) { 
     //NbPreferences.forModule(BackupSettingsPanel.class).putLong("databaseschedullastrun", Calendar.getInstance().getTimeInMillis()); 
     LoadStatusDialog lsd; 
     lsd = null; 
     lsd = new LoadStatusDialog(WindowManager.getDefault().getMainWindow(), false, true); 
     lsd.setVisible(true); 
     Thread br = new Thread(new BackupRunner(herd,lsd)); 
     br.start(); 
    } 
} 
}//end class 

クラスDbBackupActionは、ローカルバックアップのアスペクトを処理します。ローカルでバックアップし、そのファイルを別のクラスのオフサイトに送信します。 これはrunnableを実装しているため、バックアップを非同期に処理し、プログラム全体がハングアップすることはありません。

class DbBackupAction implements Runnable { 

private boolean backupSuccess; 

public DbBackupAction() { 
    this.backupSuccess = false; 
} 

public void runBackup() { 
} 

@Override 
public void run() { 
    Connection connection = JDBCUtils.getConnection(); 
    String dbName = NbPreferences.forModule(DatabasePanel.class).get("dbName", ""); 
    try { 
     DerbyUtils.backUpDatabase(connection, dbName); 
    } catch (SQLException ex) { 
     Exceptions.printStackTrace(ex); 
    } 
    setBackupSuccess(true); 
} 

/** 
* @return the backupSuccess 
*/ 
public boolean isBackupSuccess() { 
    return backupSuccess; 
} 

/** 
* @param backupSuccess the backupSuccess to set 
*/ 
public void setBackupSuccess(boolean backupSuccess) { 
    this.backupSuccess = backupSuccess; 
} 
} 

BackupRunnerは、オンサイトバックアップとオフサイトバックアップの両方を処理します。

class BackupRunner implements Runnable { 

Herd herd; 
LoadStatusDialog lsd; 

BackupRunner(Herd herd, LoadStatusDialog lsd) { 
    this.herd = herd; 
    this.lsd = lsd; 
} 

@Override 
public void run() { 



    DbBackupAction dba = new DbBackupAction(); 
    Thread dbaThread = new Thread(dba); 

    dbaThread.start(); 
    while (dbaThread.isAlive()) { 
     try { 
      dbaThread.join(); 
     } catch (InterruptedException ex) { 
      Exceptions.printStackTrace(ex); 
     } 
    } 


    if (dba.isBackupSuccess()) { 

     RemoteBackupAction rba = new RemoteBackupAction(); 
     lsd.setProgressBarIndeterminate(true); 
     Thread rbaThread = new Thread(rba); 
     rbaThread.start(); 
     while (rbaThread.isAlive()) { 
      try { 
       rbaThread.join(); 
      } catch (InterruptedException ex) { 
       Exceptions.printStackTrace(ex); 
      } 
     } 



     if (rba.isBackupSuccess()) { 


      herd.setBackupScheduledLastRun(new Timestamp(Calendar.getInstance().getTimeInMillis())); 
      HerdService hs = new HerdDaoService(); 
      hs.update(herd); 

      EventBus.publish(new RefreshStartScreenEvent()); 
     } 
    } 
} 
} 

RemoteBackupActionがバックアップオフサイトをFTPingを扱うDbBackupAction & & RemoteBackupActionを使用しています。

class RemoteBackupAction implements Runnable { 

Thread thread; 
LoadStatusDialog lsd; 
File backupFile; 
Pref pref; 
private boolean backupSuccess; 

public RemoteBackupAction() { 
    backupSuccess = false; 
} 

public void runThread() { 

       backupSuccess = true; 

       try { 
        DerbyUtils.remoteBackupDatabase(backupFile); 
       } catch (SQLException ex) { 
        JOptionPane.showMessageDialog(null, 
          "This option is not available when working offline."); 
        System.out.println("SQLExcption: " + ex); 
        backupSuccess = false; 
       } catch (Exception ex) { 
        JOptionPane.showMessageDialog(null, 
          "Unable to connection to ftp site for remote backup."); 
        System.out.println("IOExcption: " + ex); 
        backupSuccess = false; 
       } 



} 

public void startOffsiteBackup() { 
    pref = CentralLookup.getDefault().lookup(Pref.class); 
    System.out.println("pref.isOnline(): " + pref.isOnline()); 
    if (!pref.isOnline()) { 
     JOptionPane.showMessageDialog(null, 
       "This option is not available when working offline."); 
     return; 
    } 

    File[] files = DerbyUtils.getListOfBackups(); 
    if ((files == null) || (files.length < 1)) { 
     JOptionPane.showMessageDialog(null, 
       "There are no backup files available for upload. " 
       + "Please create a local backup."); 
     return; 
    } 
    Backup[] backups = new Backup[files.length]; 
    if (files.length > 0) { 
     Date[] dates = new Date[files.length]; 
     String[] herdCodes = new String[files.length]; 
     SimpleDateFormat inFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm"); 
     for (int i = 0; i < files.length; i++) { 
      try { 
       String[] splitFileName = files[i].getName().split("_"); 
       herdCodes[i] = splitFileName[0]; 
       dates[i] = inFormat.parse(splitFileName[1].split("//.")[0]); 
       backups[i] = new Backup(herdCodes[i], files[i], files[i].getName(), dates[i]); 
      } catch (ParseException ex) { 
       Exceptions.printStackTrace(ex); 
      } 
     } 
    } else { 
     System.out.println("no backup files yet"); 
    } 

    Arrays.sort(backups, Collections.reverseOrder()); 

    if (backups[0] != null) { 

     this.backupFile = backups[0].getFile(); 
    } else { 
     // Cancel button selected 
     return; 
    } 

    runThread(); 
} 

/** 
* @return the backupSuccess 
*/ 
public boolean isBackupSuccess() { 
    return backupSuccess; 
} 

@Override 
public void run() { 
    startOffsiteBackup(); 
} 
+0

自分の答えを受け入れるのは悪い形ですか?成功の定義を変えたので、これが適切に問題をカバーしてくれることを願っています。私はまだコードが元の問題を解決するために使用できると思います。 – kevingreen

+1

いいえ、あなた自身の答えを受け入れることは悪くないです。 –

+0

@JoachimRohde haha​​、cool。私はとにかくやった。これはかなり特定のreqのセットと思われます。 – kevingreen

関連する問題