package cologne.eck.all_peas.control;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import cologne.eck.all_peas.data.Attachments;
import cologne.eck.all_peas.data.PeaProperties;
import cologne.eck.all_peas.gui.PeaDialog;
import cologne.eck.all_peas.gui.PswDialogView;
import cologne.eck.tools.ReadResources;
import cologne.eck.tools.WriteResources;
import settings.PeaSettings;
public class PathFileManager {
/**
* File name of the file containing previously opened files
*/
private final static String PATH_FILE_NAME = PeaSettings.getJarFileName() + ".path";
/**
* Checks the path file (file PEA's directory, name of PEA, with extension"path")
* for previously opened file names.
*
* @return the names of the previously opened files (as an array of String)
* or null if the file does not exist, is empty or not accessible
*/
public final static String[] accessPathFile() {
File file = new File(PATH_FILE_NAME);
if (! file.exists() ) {
//System.err.println("PeaControl: no path file specified");
return null;
}
if (! file.canRead() ) {
System.err.println("PeaControl: can not read path file " + file.getName() );
Object win = null;
if (PswDialogView.getView().isVisible()){
win = PswDialogView.getView();
} else {
win = PeaControl.getDialog().getLockFrame();
}
PeaDialog.showMessage(win,
PeaProperties.getBundle().getString("path_file_access_error")
//"There is are file containing names of potentially encrypted files,\n" +
//" but no access to it: \n"
+ PATH_FILE_NAME,
"Info", 1);
return null;
}
byte[] pathBytes = ReadResources.readExternFile( file.getName() );
if (pathBytes == null) {
System.err.println("PeaControl: path file does not contain any file name: " + file.getPath() );
return null;
}
String pathString = new String(pathBytes, PeaProperties.getCharset());
String[] pathNames = pathString.split("\n");
return pathNames;
}
/**
* Checks access to a file and the file identifier
*
* @param fileName the file to check
* @param addFileIfValid add file to the list of available files if it is valid or not,
* this list is for EditorPEA, ImagePEA, NotesPEA - FilePea manages
* its own list of files in FileComposer
* @return null if the file is valid, otherwise an error message
*/
public final static String checkFile(String fileName, boolean addFileIfValid) {
//System.out.println("PeaControl check: " + fileName);
fileName = fileName.trim(); // ignore whitespace from manually editing the path file
File file = new File( fileName );
if (file.exists() && file.isFile() && file.canRead() && file.canWrite() ) {
RandomAccessFile f = null;
try {
f = new RandomAccessFile(file, "rwd");
//System.out.println("PeaControl checkFile: " + fileName);
if ( Attachments.checkFileIdentifier(f, false) == true) {
f.close();
//============================
// - - - Success: - - - - - -
//============================
if (addFileIfValid == true) {
//System.out.println("PeaControl check file added: " + fileName);
PeaControl.addAvailableFileName(fileName);
}
return null;
} else {
f.close();
//System.out.println("file identifier failed : " + fileName );
return PeaProperties.getBundle().getString("not_encrypted_with_this_archive")
+ " " + fileName;
}
} catch (FileNotFoundException e) {
System.err.println(e.toString());
return fileName + ": " + e;
} catch (IOException e) {
System.err.println(e.toString());
return fileName + ": " + e;
} catch (Exception e) {
System.err.println(e.toString());
try {
f.close();
} catch (IOException e1) {
System.err.println(e1.toString());
}
return PeaProperties.getBundle().getString("unexpected_error") + fileName + ": " + e;
}
} else {
return PeaProperties.getBundle().getString("no_access") + ": " + fileName;
}
}
/**
* Add selected files to the path file
* (Checks if files already exists in path file).
*
* @param selectedFileNames the file names to add to the path file
* as an array of Strings
*/
public final static void addFilesToPathFile(String[] selectedFileNames) {
byte[] newPathBytes = null;
StringBuilder newPathNames = null;
File file = new File(PATH_FILE_NAME);
if (! file.exists() ) { // WriteResources creates new file
newPathNames = new StringBuilder();
for (int i = 0; i < selectedFileNames.length; i++) {
newPathNames.append(selectedFileNames[i]);
newPathNames.append("\n");
}
} else { // path file exists
if (! file.canRead() || ! file.canWrite() ) {
System.err.println("PeaControl: can not read and write path file " + file.getName() );
Object win = null;
if (PswDialogView.getView().isVisible()){
win = PswDialogView.getView();
} else {
win = PeaControl.getDialog().getLockFrame();
}
PeaDialog.showMessage(win,
PeaProperties.getBundle().getString("path_file_access_error")
//"There is are file containing names of potentially encrypted files,\n" +
//" but no access to it: \n"
+ PATH_FILE_NAME,
"Info", 1);
return;
}
// get file names from path file:
String[] oldPathNames = accessPathFile();
newPathNames = new StringBuilder();
if ( file.length() == 0) { // empty file
System.out.println("empty path file");
//append new file names:
for (int i = 0; i < selectedFileNames.length; i++) {
newPathNames.append(selectedFileNames[i]);
newPathNames.append("\n");
}
} else {
// append old file names:
for (int i = 0; i < oldPathNames.length; i++) {
newPathNames.append(oldPathNames[i]);
newPathNames.append("\n");
}
// check if file name already exists, if not append
for (int i = 0; i < selectedFileNames.length; i++) {
boolean append = true;
for (int j = 0; j < oldPathNames.length; j++) {
if (selectedFileNames[i].equals(oldPathNames[j] )){
append = false;
}
}
if (append == true) {
newPathNames.append(selectedFileNames[i]);
newPathNames.append("\n");
}
}
}
}
newPathBytes = new String(newPathNames).getBytes(PeaProperties.getCharset());
WriteResources.write(newPathBytes, PATH_FILE_NAME, null);
}
/**
* Checks if current encryptedFileName is in path file.
* If not: asks to remember the file and store in path file.
*
* @param newFileName the file name to check
* @return true if the path file was updated with
* new file name
*/
public final static boolean pathFileCheck(String newFileName) {
/* if (PeaProperties.isInsideJar() == true) {
return false;
} */
if (newFileName != null) {
// path stored inside the PEA
if (newFileName.equals(PeaSettings.getExternalFilePath() )) {
return false; // no need to remember
}
// default location
if (newFileName.equals("resources" + File.separator + "text.lock")){
return false; // no need to remember
}
}
String pathFileName = PeaSettings.getJarFileName() + ".path";
byte[] pathFileContent = ReadResources.readExternFile(pathFileName);
if (pathFileContent == null) {
int n = PeaDialog.showQuestion(PeaControl.getDialog().getLockFrame(),
PeaProperties.getBundle().getString("remember_files")
+ PeaProperties.getBundle().getString("path_file_storage_info")
+ pathFileName,
"?",
0, //JOptionPane.YES_NO_OPTION,
3 //QUESTION_MESSAGE
);
if (n == 2) { // cancel
return false;
} else if (n == 0){
if (PeaProperties.getFileType().equals("text file")
|| PeaProperties.getFileType().equals("image")){
// more than one file
int len = PeaControl.getAvailableFileNames().size();
String allFileNames = "";
for (int i = 0; i < len; i++) {
allFileNames += PeaControl.getAvailableFileNames().get(i) +"\n";
}
byte[] encryptedFileNameBytes = allFileNames.getBytes(PeaProperties.getCharset());
WriteResources.write(encryptedFileNameBytes, pathFileName, null);
} else {
byte[] encryptedFileNameBytes = newFileName.getBytes(PeaProperties.getCharset());
WriteResources.write(encryptedFileNameBytes, pathFileName, null);
}
}
return true;
} else {
String pathNamesString = new String(pathFileContent, PeaProperties.getCharset());
String[] pathNames = pathNamesString.split("\n");
// check if encryptedFileName is already included
for (int i = 0; i < pathNames.length; i++) {
if (pathNames[i].equals(newFileName)) {
//System.out.println("Already included: " + encryptedFileName);
return false;
}
}
// is not included:
Object win = null;
if (PswDialogView.getView().isVisible()){
win = PswDialogView.getView();
} else {
win = PeaControl.getDialog().getLockFrame();
}
int n = PeaDialog.showQuestion(win,
PeaProperties.getBundle().getString("remember_files")
+ PeaProperties.getBundle().getString("path_file_storage_info")
+ pathFileName,
"?",
0, //JOptionPane.YES_NO_OPTION,
3 //QUESTION_MESSAGE
);
if (n == 2) { // cancel
return false;
} else if (n == 0){ // ok
//store in path file:
byte[] encryptedFileNameBytes = ("\n" + newFileName).getBytes(PeaProperties.getCharset());
byte[] newContent = new byte[pathFileContent.length + encryptedFileNameBytes.length];
System.arraycopy(pathFileContent, 0, newContent, 0, pathFileContent.length);
System.arraycopy(encryptedFileNameBytes, 0, newContent, pathFileContent.length, encryptedFileNameBytes.length);
if (newContent != null) {
WriteResources.write(newContent, pathFileName, null);
}
return true;
} else {
return false;
}
}
}
/**
* Checks if file names are already stored in the path file.
* If not: asks to remember the files and store.
*
* @param newFileNames the file names to check
* @return the file names which were added to
* the path file or null if no file name was added
*/
public final static ArrayList<String> pathFileCheck(ArrayList <String> newFileNames) {
if (newFileNames == null) {
return null;
}
// return value and list of files to add to path file
ArrayList<String> updatedFileNames = null;
// the name of the path file where file names are stored to remember:
String pathFileName = PeaSettings.getJarFileName() + ".path";
// the current content of the path file:
byte[] pathFileContent = ReadResources.readExternFile(pathFileName);
if (pathFileContent == null) {
pathFileContent = " ".getBytes(PeaProperties.getCharset());
}
// the current content as String
String pathNamesString = new String(pathFileContent, PeaProperties.getCharset());
// file names are separated by \n: String array of current file names
// in path file
String[] pathNames = pathNamesString.split("\n");
int len = newFileNames.size();
// check each new file name:
for (int i = 0; i < len; i++) {
// path stored inside the PEA
if (newFileNames.get(i).equals(PeaSettings.getExternalFilePath() )) {
// no need to remember
} else if (newFileNames.get(i).equals("resources" + File.separator + "text.lock")){
// no need to remember
} else {
// check against every file name of path file
boolean inPathFile = false;
for (int j = 0; j < pathNames.length; j++) {
if (pathNames[j].equals(newFileNames.get(i))) {
//System.out.println("Already included: " + newFileNames.get(i));
inPathFile = true;
break;
} else {
//
}
}
if (inPathFile == false){ // no match found
// file name is not in path file:
if (updatedFileNames == null){
updatedFileNames = new ArrayList<String>();
}
// add to new list:
updatedFileNames.add(newFileNames.get(i));
}
}
}
if (updatedFileNames != null) { // at least one file was not in path file
Object win = null; // the owner of the JOptionPane
if (PswDialogView.getView().isVisible()){
win = PswDialogView.getView();
} else {
win = PeaControl.getDialog().getLockFrame();
}
int n = PeaDialog.showQuestion(win,
PeaProperties.getBundle().getString("remember_files")
+ PeaProperties.getBundle().getString("path_file_storage_info")
+ pathFileName,
"?",
0, //JOptionPane.YES_NO_OPTION,
3 //QUESTION_MESSAGE
);
if (n == 0){ // ok
//store in path file:
int updatedLen = updatedFileNames.size();
//String newContent = "";
for (int i = 0; i < updatedLen;i++) {
// separate by \n and add to current list
pathNamesString += "\n" + updatedFileNames.get(i);
}
if (pathNamesString.trim().length() > 1) { //
byte[] newContent = pathNamesString.getBytes(PeaProperties.getCharset());
WriteResources.write(newContent, pathFileName, null);
}
} else { // cancel,close
return null;
}
}
return updatedFileNames;
}
/**
* @return the pathFileName
*/
public static String getPathFileName() {
return PATH_FILE_NAME;
}
}