/*
* Jajuk
* Copyright (C) The Jajuk Team
* http://jajuk.info
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package org.jajuk.ui.actions;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import org.jajuk.base.Directory;
import org.jajuk.base.DirectoryManager;
import org.jajuk.base.File;
import org.jajuk.base.Track;
import org.jajuk.events.JajukEvent;
import org.jajuk.events.JajukEvents;
import org.jajuk.events.ObservationManager;
import org.jajuk.ui.widgets.InformationJPanel;
import org.jajuk.util.Conf;
import org.jajuk.util.Const;
import org.jajuk.util.JajukFileFilter;
import org.jajuk.util.Messages;
import org.jajuk.util.UtilGUI;
import org.jajuk.util.UtilString;
import org.jajuk.util.error.JajukException;
import org.jajuk.util.filters.NotAudioFilter;
import org.jajuk.util.log.Log;
/**
* .
*/
public class RefactorAction {
private static boolean bStopAll = false;
private static String sFS = java.io.File.separator;
private final List<File> alFiles;
/** [PERF] Stores directory to be refreshed to avoid rescanning them twice. */
private final List<Directory> toBeRefreshed = new ArrayList<Directory>(1);
/**
* The Constructor.
*
* @param pFiles files to be reorganized (can be from different directories)
*/
public RefactorAction(final List<File> pFiles) {
this.alFiles = pFiles;
// check the directory user selected contains some files
if (pFiles.size() == 0) {
Messages.showErrorMessage(18);
return;
}
StringBuilder sFiles = new StringBuilder();
for (final File f : alFiles) {
sFiles.append(f.getName()).append('\n');
}
if (Conf.getBoolean(Const.CONF_CONFIRMATIONS_REFACTOR_FILES)) {
final int iResu = Messages.getChoice(Messages.getString("Confirmation_refactor_files")
+ " : \n" + sFiles, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
if (iResu != JOptionPane.YES_OPTION) {
// Cancel
if (iResu == JOptionPane.CANCEL_OPTION) {
RefactorAction.bStopAll = true;
}
UtilGUI.stopWaiting();
return;
}
}
new Thread("Refactor Thread") {
@Override
public void run() {
UtilGUI.waiting();
refactor();
ObservationManager.notify(new JajukEvent(JajukEvents.DEVICE_REFRESH));
}
}.start();
UtilGUI.stopWaiting();
}
/**
* Refactoring itself.
*/
public void refactor() {
boolean bOKToOverwrite = false;
String sErrors = "";
String filename;
for (final File fCurrent : alFiles) {
final Track tCurrent = fCurrent.getTrack();
try {
filename = UtilString.applyPattern(fCurrent, Conf.getString(Const.CONF_PATTERN_REFACTOR),
true, true);
} catch (final JajukException je) {
sErrors += je.getMessage() + '\n';
continue;
}
filename += "." + tCurrent.getType().getExtension();
filename = filename.replace("/", RefactorAction.sFS);
final java.io.File fOld = fCurrent.getFIO();
final String sPathname = fCurrent.getDevice().getFIO().getPath() + RefactorAction.sFS
+ filename;
java.io.File fNew = new java.io.File(sPathname);
// Confirm if destination dir already exist
if (fNew.getParentFile().exists() && !bOKToOverwrite) {
final int resu = Messages.getChoice(Messages.getString("Warning.5"),
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
if (resu == JOptionPane.NO_OPTION) {
continue;
} else if (resu == JOptionPane.CANCEL_OPTION) {
return;
}
}
// This flag is used to avoid displaying the confirmation at each
// file
bOKToOverwrite = true;
fNew.getParentFile().mkdirs();
// Move file and related cover but save old Directory pathname
// for future deletion
try {
final java.io.File fCover = tCurrent.getAlbum().findCover();
if (fCover != null) {
java.io.File destFile = new java.io.File(fNew.getParent() + RefactorAction.sFS
+ fCover.getName());
if (!fCover.renameTo(destFile)) {
throw new IOException("Cannot move item: " + fCover.getAbsolutePath() + " to "
+ destFile.getAbsolutePath());
}
}
} catch (Exception e) {
// This exception can be thrown by instance if default cover is not
// readable
Log.error(e);
}
// Rename audio files
boolean bRenameSuccess = false;
// Test if source and target files are equals
if (fNew.getAbsolutePath().equalsIgnoreCase(fOld.getAbsolutePath())) {
sErrors += fCurrent.getAbsolutePath() + " (" + Messages.getString("Error.160") + ")\n";
} else {
try {
bRenameSuccess = fOld.renameTo(fNew);
if (!bRenameSuccess) {
sErrors += fCurrent.getAbsolutePath() + " (" + Messages.getString("Error.154") + ")\n";
}
Log.debug("[Refactoring] {{" + fNew.getAbsolutePath() + "}} Success ? " + bRenameSuccess);
} catch (Exception e) {
Log.error(e);
sErrors += fCurrent.getAbsolutePath() + " (" + Messages.getString("Error.161") + ")\n";
}
}
// Register and scans new directories
String sFirstDir = null;
final String sTest[] = sPathname.split(fCurrent.getDevice().getFIO().getPath()
.replace("\\", "\\\\"));
sFirstDir = sTest[1].split("\\" + RefactorAction.sFS)[1];
final Directory dir = DirectoryManager.getInstance().registerDirectory(
sFirstDir,
DirectoryManager.getInstance().getDirectoryForIO(fCurrent.getDevice().getFIO(),
fCurrent.getDevice()), fCurrent.getDevice());
// Ask to refresh this directory afterward
if (!toBeRefreshed.contains(dir)) {
toBeRefreshed.add(dir);
}
// See if old directory contain other files and move them
final java.io.File dOld = fOld.getParentFile();
final java.io.File[] list = dOld.listFiles(new JajukFileFilter(NotAudioFilter.getInstance()));
if (list == null) {
DirectoryManager.getInstance().removeDirectory(fOld.getParent());
} else if (list.length != 0) {
for (final java.io.File f : list) {
fNew = new java.io.File(fNew.getParent() + RefactorAction.sFS + f.getName());
try {
bRenameSuccess = f.renameTo(fNew);
if (!bRenameSuccess) {
sErrors += f.getAbsolutePath() + " (" + Messages.getString("Error.154") + ")\n";
}
Log.debug("[Refactoring] {{" + fNew.getAbsolutePath() + "}} Success ? "
+ bRenameSuccess);
} catch (Exception e) {
Log.error(e);
sErrors += f.getAbsolutePath() + " (" + Messages.getString("Error.161") + ")\n";
}
}
}
// Only try to remove old directory, will work if actually empty,
// do not force deletion here
else if (list.length == 0 && dOld.delete()) {
DirectoryManager.getInstance().removeDirectory(fOld.getParent());
}
InformationJPanel.getInstance().setMessage(
Messages.getString("RefactorWizard.0") + sPathname,
InformationJPanel.MessageType.INFORMATIVE);
}
// Refresh and cleanup required directories
for (final Directory dir : toBeRefreshed) {
try {
dir.refresh(false);
} catch (Exception e) {
Log.error(e);
}
dir.getDevice().cleanRemovedFiles(null);
}
if (!sErrors.isEmpty()) {
Messages.showDetailedErrorMessage(147, "", sErrors);
} else {
InformationJPanel.getInstance().setMessage(Messages.getString("Success"),
InformationJPanel.MessageType.INFORMATIVE);
}
}
/**
* Checks if is stop all.
*
* @return true, if is stop all
*/
public static boolean isStopAll() {
return bStopAll;
}
/**
* Reset stop all.
*
*/
public static void resetStopAll() {
bStopAll = false;
}
}