FileDocCategorySizeDatePackage
DownloadManagerDefaultPaths.javaAPI DocAzureus 3.0.3.419193Thu Sep 27 16:24:44 BST 2007org.gudy.azureus2.core3.download.impl

DownloadManagerDefaultPaths

public class DownloadManagerDefaultPaths extends Object

Fields Summary
private static final MovementInformation[]
COMPLETION_DETAILS
private static final MovementInformation[]
REMOVAL_DETAILS
private static final MovementInformation[]
UPDATE_FOR_MOVE_DETAILS
private static final MovementInformation[]
UPDATE_FOR_LOGIC_DETAILS
private static final TargetSpecification[]
DEFAULT_DIRS
private static final String
STATE_INCOMPLETE
private static final String
STATE_COMPLETE_DND
private static final String
STATE_COMPLETE
private static final String
SUBDIR_PARAM
Constructors Summary
Methods Summary
private static java.lang.Stringdescribe(org.gudy.azureus2.core3.download.DownloadManager dm, org.gudy.azureus2.core3.download.impl.DownloadManagerDefaultPaths$ContextDescriptor cs)

		if (cs == null) {
			if (dm == null) {return "";}
			return "\"" + dm.getDisplayName() + "\"";
		}
		if (dm == null) {
			return "\"" + cs.getContext() + "\"";
		}
		return "\"" + dm.getDisplayName() + "\" with regard to \"" + cs.getContext() + "\"";
	
private static org.gudy.azureus2.core3.download.impl.DownloadManagerDefaultPaths$TransferDetailsdeterminePaths(org.gudy.azureus2.core3.download.DownloadManager dm, org.gudy.azureus2.core3.download.impl.DownloadManagerDefaultPaths$MovementInformation mi)
This does the guts of determining appropriate file paths.

		LogRelation lr = (dm instanceof LogRelation) ? (LogRelation)dm : null;
		boolean proceed = mi.source.matchesDownload(dm, lr, mi);
		if (!proceed) {
			logInfo("Cannot consider " + describe(dm, mi) +
			    " - does not match source criteria.", lr);
			return null;
		}

		File target_path = mi.target.getTarget(dm, lr, mi);
		if (target_path == null) {
			logInfo("Unable to determine an appropriate target for " +
			    describe(dm, mi) + ".", lr);
			return null;
		}

        logInfo("Determined path for " + describe(dm, mi) + ".", lr);
		return mi.transfer.getTransferDetails(dm, lr, mi, target_path);
	
private static org.gudy.azureus2.core3.download.impl.DownloadManagerDefaultPaths$TransferDetailsdeterminePaths(org.gudy.azureus2.core3.download.DownloadManager dm, org.gudy.azureus2.core3.download.impl.DownloadManagerDefaultPaths$MovementInformation[] mis)

	    TransferDetails result = null;
		for (int i=0; i<mis.length; i++) {
			result = determinePaths(dm, mis[i]);
			if (result != null) {return result;}
		}
		return null;
	
public static java.io.FilegetCompletionDirectory(org.gudy.azureus2.core3.download.DownloadManager dm)

		return COMPLETION_DETAILS[0].target.getTarget(dm, null, null);
	
private static java.io.File[]getDefaultDirs(LogRelation lr)

		List results = new ArrayList();
		File location = null;
		TargetSpecification ts = null;
		for (int i=0; i<DEFAULT_DIRS.length; i++) {
			ts = (TargetSpecification)DEFAULT_DIRS[i];
			location = ts.getTarget(null, lr, ts);
			if (location != null) {
				results.add(location);
			}
		}
		return (File[])results.toArray(new File[results.size()]);
	
public static java.io.File[]getDefaultSavePaths(org.gudy.azureus2.core3.download.DownloadManager dm, boolean for_moving)

		MovementInformation[] mi = (for_moving) ? UPDATE_FOR_MOVE_DETAILS : UPDATE_FOR_LOGIC_DETAILS;
		TransferDetails details = determinePaths(dm, mi);

		// Always return an array of size two.
		File[] result = new File[2];

		// Set default values first.
		if (!for_moving) {
			result[0] = dm.getSaveLocation();
			result[1] = new File(dm.getTorrentFileName()).getParentFile();
		}

		if (details != null) {
			result[0] = details.transfer_destination;
			if (details.move_torrent) {
				result[1] = result[0];
			}
		}

		return result;

	
private static java.lang.StringgetStateDescriptor(org.gudy.azureus2.core3.download.DownloadManager dm)

		if (dm.isDownloadComplete(true)) {return STATE_COMPLETE;}
		else if (dm.isDownloadComplete(false)) {return STATE_COMPLETE_DND;}
		else {return STATE_INCOMPLETE;}
	
public static booleanisInDefaultDownloadDir(org.gudy.azureus2.core3.download.DownloadManager dm)

		// We don't create this object properly, but just enough to get it
		// to be usable.
		SourceSpecification source = new SourceSpecification();
		source.setBoolean("default subdir", SUBDIR_PARAM);
		return source.checkDefaultDir(dm.getSaveLocation().getParentFile(), getDefaultDirs(null));
	
private static voidlogInfo(java.lang.String message, LogRelation lr)

		if (lr == null) {return;}
		if (!Logger.isEnabled()) {return;}
		Logger.log(new LogEvent(lr, LogIDs.CORE, LogEvent.LT_INFORMATION, message));
	
private static voidlogWarn(java.lang.String message, LogRelation lr)

		if (lr == null) {return;}
		if (!Logger.isEnabled()) {return;}
		Logger.log(new LogEvent(lr, LogIDs.CORE, LogEvent.LT_WARNING, message));
	
public static java.io.FilenormaliseRelativePath(java.io.File path)

    	if (path.isAbsolute()) {return null;}
    	
    	File parent = path.getParentFile();
    	String child_name = normaliseRelativePathPart(path.getName());
    	if (child_name == null) {
    		return null;
    	}
    	
    	//  Simple one-level path.
    	if (parent == null) {
    		return new File(child_name);
    	}
    	
    	ArrayList parts = new ArrayList();
    	parts.add(child_name);
    	
    	String filepart = null;
    	while (parent != null) {
    		filepart = normaliseRelativePathPart(parent.getName());
    		if (filepart == null) {return null;}
    		else if (filepart.length()==0) {/* continue */}
    		else {parts.add(0, filepart);} 
    		parent = parent.getParentFile();
    	}
    	
    	StringBuffer sb = new StringBuffer((String)parts.get(0));
    	for (int i=1; i<parts.size(); i++) {
    		sb.append(File.separatorChar);
    		sb.append(parts.get(i));
    	}
    	
    	return new File(sb.toString());
    
private static java.lang.StringnormaliseRelativePathPart(java.lang.String name)



     
        SourceSpecification source;
        TargetSpecification dest;
        TransferSpecification trans;
        MovementInformation mi_1, mi_2;

        /**
         * There are three sets of directories that we consider a "default"
         * directory (perhaps it should just be two):
         *
         * - default save dir
         * - completed save dir
         * - removed save dir
         */
        DEFAULT_DIRS = new TargetSpecification[3];
        dest = new TargetSpecification();
        dest.setBoolean("enabled", true);
        dest.setString("target", "Default save path");
        dest.setContext("default save dir");
        DEFAULT_DIRS[0] = dest;


        // First - download completion details.
		source = new SourceSpecification();
		source.setBoolean("default dir", "Move Only When In Default Save Dir");
		source.setBoolean("default subdir", SUBDIR_PARAM);
		source.setBoolean("persistent only", true);
		source.setBoolean("check exclusion flag", true);
		source.setBoolean("check completion flag", true);
		source.setBoolean(STATE_INCOMPLETE, false);
		source.setBoolean(STATE_COMPLETE_DND, true);
		source.setBoolean(STATE_COMPLETE, true); // Only handle fully complete downloads at moment.

		dest = new TargetSpecification();
		dest.setBoolean("enabled", "Move Completed When Done");
		dest.setString("target", "Completed Files Directory");
		dest.setContext("completed files dir");

		trans = new TransferSpecification();
		trans.setBoolean("torrent", "Move Torrent When Done");

		mi_1 = new MovementInformation(source, dest, trans, "Move on completion");
		COMPLETION_DETAILS = new MovementInformation[] {mi_1};
		DEFAULT_DIRS[1] = dest;

		// Next - download removal details.
		source = new SourceSpecification();
		source.setBoolean("default dir", "File.move.download.removed.only_in_default");
		source.setBoolean("default subdir", SUBDIR_PARAM);
		source.setBoolean("persistent only", true);
		source.setBoolean("check exclusion flag", true);
		source.setBoolean("check completion flag", false);
		source.setBoolean(STATE_INCOMPLETE, false);
		source.setBoolean(STATE_COMPLETE_DND, "File.move.download.removed.move_partial");
		source.setBoolean(STATE_COMPLETE, true);

		dest = new TargetSpecification();
		dest.setBoolean("enabled", "File.move.download.removed.enabled");
		dest.setString("target", "File.move.download.removed.path");
		dest.setContext("removed files dir");

		trans = new TransferSpecification();
		trans.setBoolean("torrent", "File.move.download.removed.move_torrent");

		mi_1 = new MovementInformation(source, dest, trans, "Move on removal");
		REMOVAL_DETAILS = new MovementInformation[] {mi_1};
		DEFAULT_DIRS[2] = dest;

	    /**
	     * Next - updating the current path (complete dl's first)
	     * 
	     * We instantiate the "update incomplete download" source first, and then
	     * we instantiate the "update complete download", but when we process, we
	     * will do the complete download bit first.
	     * 
	     * We do this, because in the "update incomplete download" section, completed
	     * downloads are enabled for it. And the reason it is, is because this will
	     * allow the code to behave properly if move on completion is not enabled.
	     *
	     * Complete downloads apply to this bit, just in case the "move on completion"
	     * section isn't active.
	     */
		source = new SourceSpecification();
		source.updateSettings(COMPLETION_DETAILS[0].source.getSettings());
		source.setBoolean("default dir", true);

		mi_1 = new MovementInformation(source, COMPLETION_DETAILS[0].target,
				COMPLETION_DETAILS[0].transfer, "Update completed download");
		
		// Now incomplete downloads. We have to define completely new settings for
		// it, since we've never defined it before.
		source = new SourceSpecification();
		source.setBoolean("default dir", true); // Must be in default directory to update.
		source.setBoolean("default subdir", SUBDIR_PARAM);
		source.setBoolean("persistent only", true);
		source.setBoolean("check exclusion flag", true);
		source.setBoolean("check completion flag", false);
		source.setBoolean(STATE_INCOMPLETE, true);
		source.setBoolean(STATE_COMPLETE_DND, true);
		source.setBoolean(STATE_COMPLETE, true);

		dest = new TargetSpecification();
		dest.setBoolean("enabled", true);
		dest.setString("target", "Default save path");

		trans = new TransferSpecification();
		trans.setBoolean("torrent", false);

        // Rest of the settings are the same.
		mi_2 = new MovementInformation(source, dest, trans, "Update incomplete download");
		UPDATE_FOR_MOVE_DETAILS = new MovementInformation[] {mi_1, mi_2};

		/**
		 * Now we have a copy of the exact same settings for updates, except we
		 * disable the logic regarding default directory requirements.
		 */
		UPDATE_FOR_LOGIC_DETAILS = new MovementInformation[UPDATE_FOR_MOVE_DETAILS.length];
		for (int i=0; i<UPDATE_FOR_MOVE_DETAILS.length; i++) {
			MovementInformation mi = UPDATE_FOR_MOVE_DETAILS[i];
		    source = new SourceSpecification();
		    source.updateSettings(mi.source.getSettings());
		    source.setBoolean("default dir", false);
		    source.setBoolean("persistent only", false);
		    source.setBoolean("check exclusion flag", false);
		    UPDATE_FOR_LOGIC_DETAILS[i] = new MovementInformation(source,
		        mi.target, mi.transfer, mi.title.replaceAll("Update", "Calculate path for"));
	    }

    
    	name = name.trim();
    	if (name.length() == 0) {return "";}
    	if (name.equals(".") || name.equals("..")) {
    		return null;
    	}
    	return FileUtil.convertOSSpecificChars(name).trim();
    
public static org.gudy.azureus2.core3.download.impl.DownloadManagerDefaultPaths$TransferDetailsonCompletion(org.gudy.azureus2.core3.download.DownloadManager dm, boolean set_on_completion_flag)

		TransferDetails td = determinePaths(dm, COMPLETION_DETAILS);
		
		// Not sure what we should do if we don't have any transfer details w.r.t the
		// completion flag. I think we probably should - we only want to consider the
		// settings once - when completion has actually occurred.
		if (set_on_completion_flag) {
			LogRelation lr = (dm instanceof LogRelation) ? (LogRelation)dm : null;
			logInfo("Setting completion flag on " + describe(dm, null) + ", may have been set before.", lr);
			dm.getDownloadState().setFlag(DownloadManagerState.FLAG_MOVE_ON_COMPLETION_DONE, true);
		}
		return td;
	
public static org.gudy.azureus2.core3.download.impl.DownloadManagerDefaultPaths$TransferDetailsonInitialisation(org.gudy.azureus2.core3.download.DownloadManager dm)

		return determinePaths(dm, UPDATE_FOR_MOVE_DETAILS[1]); // 1 - incomplete downloads
	
public static org.gudy.azureus2.core3.download.impl.DownloadManagerDefaultPaths$TransferDetailsonRemoval(org.gudy.azureus2.core3.download.DownloadManager dm)

		return determinePaths(dm, REMOVAL_DETAILS);