/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 com.orangelabs.rcs.provider;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.util.Date;
import javax2.sip.InvalidArgumentException;
import android.os.Environment;
import android.text.TextUtils;
import com.orangelabs.rcs.utils.FileUtils;
import com.orangelabs.rcs.utils.logger.Logger;
/**
* Backup and restore databases
*
* @author YPLO6403
*
*/
public class BackupRestoreDb {
/**
* The location of the database
*/
public static final String DATABASE_LOCATION = "/data/com.orangelabs.rcs/databases/";;
/**
* The maximum number of saved accounts
*/
private static final int MAX_SAVED_ACCOUNT = 3;
/**
* The logger
*/
private static final Logger logger = Logger.getLogger(BackupRestoreDb.class.getSimpleName());
/**
* Filter to get database files
*/
private static final FilenameFilter filenameDbFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
return (filename.endsWith(".db"));
}
};
/**
* Get list of RCS accounts saved under the database directory
*
* @param databasesDir
* the database directory
* @return the array of RCS saved accounts (may be empty) or null
* @throws InvalidArgumentException
*/
public static File[] listOfSavedAccounts(final File databasesDir) throws InvalidArgumentException {
if (databasesDir == null) {
throw new InvalidArgumentException();
}
if (databasesDir.isDirectory() == false) {
throw new InvalidArgumentException("Argument '" + databasesDir + "' is not a directory");
}
FileFilter directoryFilter = new FileFilter() {
@Override
public boolean accept(File file) {
if (file.isDirectory()) {
// There must be at least 3 digits
return file.getName().matches("^\\d{3,}$");
}
return false;
}
};
return databasesDir.listFiles(directoryFilter);
}
/**
* Check the arguments of backup or restore methods
*
* @param databasesDir
* the database directory
* @param account
* the account
* @return true is arguments are OK
*/
private static boolean checkBackupRestoreArguments(final File databasesDir, final String account) {
if (TextUtils.isEmpty(account)) {
return false;
}
// There must be at least 3 digits
if (account.matches("^\\d{3,}$") == false) {
return false;
}
if (databasesDir == null || databasesDir.isDirectory() == false) {
return false;
}
return true;
}
/**
* Save databases under account directory
*
* @param databasesDir
* the database directory
* @param account
* the account
* @return true if save succeeded
*/
private static boolean saveAccountDatabases(final File databasesDir, final String account) {
if (logger.isActivated()) {
logger.info("saveAccountDatabases account=" + account);
}
if (checkBackupRestoreArguments(databasesDir, account) == false) {
if (logger.isActivated()) {
logger.error("Cannot save account " + account);
}
return false;
}
// Put the names of all files ending with .db in a String array
String[] listOfDbFiles = databasesDir.list(filenameDbFilter);
if (listOfDbFiles != null && listOfDbFiles.length > 0) {
File dstDir = new File(databasesDir, account);
// Iterate over the array of database file names
for (String dbFile : listOfDbFiles) {
// Create file to be saved
File srcFile = new File(databasesDir, dbFile);
try {
// Copy database file under account directory
FileUtils.copyFileToDirectory(srcFile, dstDir, true);
if (logger.isActivated()) {
logger.info("Save file" + srcFile + " to " + dstDir);
}
} catch (Exception e) {
if (logger.isActivated()) {
logger.error(e.getMessage(), e);
}
return false;
}
}
// update the saved account db directory date with the backup date
dstDir.setLastModified((new Date()).getTime());
return true;
}
return false;
}
/**
* Restore databases from account directory
*
* @param databasesDir
* the database directory
* @param account
* the account
* @return true if restore succeeded
*/
private static boolean restoreAccountDatabases(final File databasesDir, final String account) {
if (checkBackupRestoreArguments(databasesDir, account) == false) {
return false;
}
File srcDir = new File(databasesDir, account);
// Put the names of all files ending with .db in a String array
String[] listOfDbFiles = srcDir.list(filenameDbFilter);
if (listOfDbFiles != null && listOfDbFiles.length > 0) {
// Iterate over the array of database file names
for (String dbFile : listOfDbFiles) {
// Create file to be restored
File srcFile = new File(srcDir, dbFile);
try {
// Copy database file under database directory
FileUtils.copyFileToDirectory(srcFile, databasesDir, true);
} catch (Exception e) {
if (logger.isActivated()) {
logger.error(e.getMessage(), e);
}
return false;
}
}
return true;
}
return false;
}
/**
* Suppress oldest backup if more than MAX_SAVED_ACCOUNT
*
* @param databasesDir
* the database directory
* @param currentUserAccount
* the account
* @throws InvalidArgumentException
*/
private static void cleanBackups(final File databasesDir, final String currentUserAccount) throws InvalidArgumentException {
File[] files = listOfSavedAccounts(databasesDir);
if (files != null && files.length > MAX_SAVED_ACCOUNT) {
File file = FileUtils.getOldestFile(files);
if (file.getName().equals(currentUserAccount) == false) {
FileUtils.deleteDirectory(file);
if (logger.isActivated()) {
logger.debug("Clean oldest Backup : account=" + file.getName());
}
} else {
// Do not clean current account
File[] _files = new File[files.length - 1];
int i = 0;
for (File file2 : files) {
if (file2.getName().equals(currentUserAccount) == false) {
_files[i++] = file2;
}
}
file = FileUtils.getOldestFile(_files);
FileUtils.deleteDirectory(file);
if (logger.isActivated()) {
logger.debug("Clean oldest Backup : account=" + file.getName());
}
}
}
}
/**
* Suppress oldest backup
*
* @param currentUserAccount
* the current account must not be cleaned
*/
public static void cleanBackups(String currentUserAccount) {
String accountDBs = Environment.getDataDirectory() + DATABASE_LOCATION;
try {
File srcdir = new File(accountDBs);
cleanBackups(srcdir, currentUserAccount);
} catch (Exception e) {
if (logger.isActivated())
logger.error(e.getMessage(), e);
}
}
/**
* Backup account
*
* @param account
* the Account to backup
* @return true if backup is successful
*/
public static boolean backupAccount(String account) {
String accountDBs = Environment.getDataDirectory() + DATABASE_LOCATION;
try {
File fdir = new File(accountDBs);
return saveAccountDatabases(fdir, account);
} catch (Exception e) {
if (logger.isActivated())
logger.error(e.getMessage(), e);
}
return false;
}
/**
* Restore account
*
* @param account
* Account
* @return true if restore is successful
*/
public static boolean restoreAccount(String account) {
String accountDBs = Environment.getDataDirectory() + DATABASE_LOCATION;
try {
File fdir = new File(accountDBs);
return restoreAccountDatabases(fdir, account);
} catch (Exception e) {
if (logger.isActivated())
logger.error(e.getMessage(), e);
}
return false;
}
}