package model; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import com.cf.util.Regex; import model.audio.FolderAudioFile; import model.progressbar.interfaces.IProgressBar; import model.table.StructureTableModel; import model.util.Commons; import model.util.FileUtil; public class FolderCreatorModel { /** * the logger */ private final Logger logger = Logger.getLogger(this.getClass().getName()); /** * list with current loaded files */ private List<FolderAudioFile> audioFiles; /** * folders which needs to be generated (can already be generated too) */ private List<String> folders; /** * all paths of loaded files */ private Set<String> readPaths; /** * the stop flag, if set to true all operations should stop */ private boolean stopFlag; /** * Constructor */ public FolderCreatorModel() { this.audioFiles = new ArrayList<FolderAudioFile>(); this.folders = new ArrayList<String>(); this.readPaths = new HashSet<String>(); this.stopFlag = false; } /** * sets the stop flag and stops all operations * * @param set * ture if stop, else false */ public void setStopFlag(boolean set) { logger.log(Level.FINER, "set stop flag: " + set); this.stopFlag = set; } /** * clears all audio files */ public boolean clearAudioFiles() { this.audioFiles.clear(); this.readPaths.clear(); return true; } /** * returns the number of loaded files * * @return the number of files */ public int getListSize() { return this.audioFiles.size(); } /** * deletes the audio file at the given index * * @param index * given index * * @return true if deleted successfully, else false */ public boolean deleteAudioFile(int index) { logger.log(Level.FINER, "delete audio file with index " + index + " exists: " + (index < this.audioFiles.size())); if (index >= this.audioFiles.size()) return false; String path = this.audioFiles.get(index).getFilePath(); this.audioFiles.remove(index); boolean delP = this.readPaths.remove(path); logger.log(Level.FINER, "audio file deleted: " + delP); return true; } /** * deletes the audio files at the given indices * * @param indices * given indices * * @return true if deleted successfully, else false */ public boolean deleteAudioFiles(int[] indices) { Integer[] tmp = new Integer[indices.length]; for (int i = 0; i < indices.length; i++) tmp[i] = indices[i]; List<Integer> ints = Arrays.asList(tmp); Collections.sort(ints); int offset = 0; for (Integer i : ints) { deleteAudioFile(i - offset); offset++; } return true; } /** * reads one audio file and checks if it is already read * * @param path * path to audio file * @param sort * true if audio files should be sorted after adding * * @return true if it is added, else false */ public boolean addAudioFile(String path, boolean sort) { if (this.stopFlag) return false; if (this.readPaths.contains(path)) return false; if (!Commons.isValidExtension(FileUtil.getFileExtension(path))) return false; this.readPaths.add(path); this.audioFiles.add(new FolderAudioFile(path)); if (sort) sortAudioFiles(); return true; } /** * analyses the given folder and saves all found audio files * * @param folderPath * given folder * @param recursive * true if sub folders should be checked too, else false * * @return true if everything worked correctly */ public boolean addAudioFiles(String folderPath, boolean recursive) { logger.log(Level.FINER, "reading all audio files from: " + folderPath + " recursive: " + recursive); if (this.stopFlag) return false; List<String> files = FileUtil.getFilesFromFolder(folderPath, true); for (String file : files) { if (this.stopFlag) return false; logger.log(Level.FINER, "analyse file: " + file); if (Commons.isValidExtension(FileUtil.getFileExtension(file))) { addAudioFile(file, false); } // check if it is a folder, if so else if (recursive && new File(file).isDirectory()) { addAudioFiles(file, recursive); } } sortAudioFiles(); return true; } /** * sorts the audio files alphabetically not case sensitive */ public void sortAudioFiles() { logger.log(Level.FINER, "sort audio files."); Collections.sort(audioFiles, new Comparator<FolderAudioFile>() { @Override public int compare(FolderAudioFile arg0, FolderAudioFile arg1) { return FileUtil.getFileName(arg0.getFilePath()).compareToIgnoreCase(FileUtil.getFileName(arg1.getFilePath())); } }); } /** * gets the TableModel with all audio files * * @return the TableModel */ public StructureTableModel getTableModel() { return new StructureTableModel(this.audioFiles); } /** * creates the new Path from the filename * * @param strucRegex * regex for folder structure * @param nameRegex * regex for file name * @param target * target folder * @param pb * the given progressbar which will be updated after each audio * file */ public void createNewPath(String strucRegex, String nameRegex, String target, IProgressBar pb) { logger.log(Level.FINER, "create new Path from filename"); ID3TagRegex regex = null; if (!strucRegex.equals(".") && !nameRegex.equals(".")) regex = new ID3TagRegex(nameRegex, strucRegex); for (FolderAudioFile audioFile : this.audioFiles) { audioFile.createNewPath(regex, target); if (pb != null) pb.nextStep(); } } /** * creates the new Path from the ID3Tag * * @param structure * regex for folder structure * @param target * target folder * @param pb * the given progressbar which will be updated after each audio * file */ public void createNewPathID3(String structure, String target, IProgressBar pb) { logger.log(Level.FINER, "create new Path from ID3Tag"); for (FolderAudioFile audioFile : this.audioFiles) { audioFile.createNewPathFromID3Tag(structure, target); if (pb != null) pb.nextStep(); } } /** * creates the folder structure. and saves all subfolders. * generateFolderStructure will generate them. */ public void createFolderStructure() { logger.log(Level.FINER, "create folder structure."); Set<String> tmp = new HashSet<String>(); for (FolderAudioFile audioFile : this.audioFiles) { String[] folders = FileUtil.getFilePath(audioFile.getNewPathRel()).split(Regex.replaceRegexChars(FolderAudioFile.sep)); String f = ""; for (int i = 0; i < folders.length; i++) { f += folders[i].trim(); if (!f.equals("")) tmp.add(f); logger.log(Level.FINER, "adding " + f + " to folders to generate."); f += FolderAudioFile.sep; } } this.folders = new ArrayList<String>(tmp); logger.log(Level.FINER, "found " + this.folders.size() + " folders to generate."); Collections.sort(this.folders, new Comparator<String>() { @Override public int compare(String o1, String o2) { if (o1.length() > o2.length()) return 1; else if (o1.length() < o2.length()) return -1; else return 0; } }); } /** * generates the folder Structure on the HDD. Before createFolderStructure * needs to be called. */ public void generateFolderStructure(String target) { logger.log(Level.FINER, "generate folders on HDD"); boolean created; for (String str : this.folders) { created = new File(target + str).mkdir(); logger.log(Level.FINER, "generate folder: " + target + str + " created: " + created); } } /** * copies all audio files to the new destination on the folder Structure * * @param pb * the given progressbar which will be updated after each audio * file * * @throws IOException * thrown if a file couldn't be copied */ public void copyAudioFiles(IProgressBar pb) throws IOException { boolean copied; for (FolderAudioFile audioFile : this.audioFiles) { copied = FileUtil.copyFile(audioFile.getFilePath(), audioFile.getNewPath()); if (pb != null) pb.nextStep(); logger.log(Level.FINER, "copy audio file from " + audioFile.getFilePath() + " to " + audioFile.getNewPath() + " copied: " + copied); } } }