/*
* Copyright 2012 jMethods, Inc.
*
* 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.myjavaworld.jftp;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SealedObject;
import javax.crypto.spec.SecretKeySpec;
/**
* A Class used to serialize/deserialize favourite FTP sites. This is the
* central point that contains all the IO logic required to
* retrieve/store/add/edit/delete favouritre FTP sites.
*
* @author Sai Pullabhotla, psai [at] jMethods [dot] com
* @version 2.0
*/
public class FavoritesManager {
/**
* Serialized file that stores the favourite FTP sites.
*/
private static final File FAV_FILE = new File(JFTP.DATA_HOME,
"favorites.ser");
/**
* Returns the list of favourite FTP sites. The list is generated by reading
* the serialized file, <code>FAV_FILE</code>.
*
* @return List of favourite FTP sites.
* @exception IOException
* if an IO error occurs while reading the file
* @exception ClassNotFoundException
* We should never get this exception. If we get this, it
* means that the software is not installed correctly.
*/
public static List getFavorites() throws IOException,
ClassNotFoundException, IllegalBlockSizeException,
BadPaddingException {
List favorites = new ArrayList();
FileInputStream fin = null;
ObjectInputStream in = null;
try {
checkFavFile();
fin = new FileInputStream(FAV_FILE);
if (fin.available() > 0) {
in = new ObjectInputStream(fin);
Object obj = in.readObject();
if (obj instanceof List) {
favorites = (List) obj;
saveFavorites(favorites);
} else {
SealedObject so = (SealedObject) obj;
favorites = (List) so
.getObject(getCipher(Cipher.DECRYPT_MODE));
}
}
return favorites;
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException exp) {
}
try {
if (fin != null) {
fin.close();
}
} catch (IOException exp) {
}
in = null;
fin = null;
}
}
/**
* Saves the given list of favourite FTP sites to the favorite file.
*
* @param favorites
* List of favorites to be searialized
* @exception IOException
* if an IO error occurs
*/
public static void saveFavorites(List favorites) throws IOException,
IllegalBlockSizeException {
if (favorites == null) {
favorites = new ArrayList();
}
checkDataHome();
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(new FileOutputStream(FAV_FILE));
Cipher cipher = getCipher(Cipher.ENCRYPT_MODE);
if (cipher == null) {
// We do not have AES provider. so just save the favorites
// unencrypted.
out.writeObject(favorites);
} else {
SealedObject so = new SealedObject((Serializable) favorites,
cipher);
out.writeObject(so);
}
} finally {
if (out != null) {
out.close();
}
out = null;
}
}
/**
* Adds the given favourite to the list of previously stored favorites and
* saves them back to the favorites file.
*
* @param host
* Favorite FTP site
* @exception IOException
* if an IO error occurs
* @exception ClassNotFoundException
*/
public static void addFavorite(RemoteHost host) throws IOException,
ClassNotFoundException, IllegalBlockSizeException,
BadPaddingException {
List favorites = getFavorites();
favorites.add(host);
saveFavorites(favorites);
}
private static void checkDataHome() {
if (!JFTP.DATA_HOME.exists() || !JFTP.DATA_HOME.isDirectory()) {
JFTP.DATA_HOME.mkdirs();
}
}
private static void checkFavFile() throws IOException {
checkDataHome();
if (!FAV_FILE.exists() || !FAV_FILE.isFile()) {
FAV_FILE.createNewFile();
}
}
private static Cipher getCipher(int mode) {
final byte[] encodedKey = { 28, -9, -23, 35, -93, -47, -28, 55, -83,
-82, 101, -79, 36, 59, 77, -121 };
Cipher cipher = null;
try {
cipher = Cipher.getInstance("AES");
SecretKeySpec spec = new SecretKeySpec(encodedKey, "AES");
cipher.init(mode, spec);
return cipher;
} catch (InvalidKeyException exp) {
exp.printStackTrace();
} catch (NoSuchAlgorithmException exp) {
exp.printStackTrace();
} catch (NoSuchPaddingException exp) {
exp.printStackTrace();
}
return null;
}
}