OSDN Git Service

New uncompress command
authorjruesga <jorge@ruesga.com>
Wed, 17 Oct 2012 22:50:03 +0000 (00:50 +0200)
committerjruesga <jorge@ruesga.com>
Wed, 17 Oct 2012 22:50:03 +0000 (00:50 +0200)
res/xml/command_list.xml
src/com/cyanogenmod/explorer/commands/ExecutableCreator.java
src/com/cyanogenmod/explorer/commands/UncompressExecutable.java [new file with mode: 0644]
src/com/cyanogenmod/explorer/commands/shell/ShellExecutableCreator.java
src/com/cyanogenmod/explorer/commands/shell/UncompressCommand.java [new file with mode: 0644]
src/com/cyanogenmod/explorer/util/CommandHelper.java
src/com/cyanogenmod/explorer/util/FileHelper.java
tests/src/com/cyanogenmod/explorer/commands/shell/UncompressCommandTest.java [new file with mode: 0644]

index 44411fb..0309d9e 100644 (file)
   <command commandId="sendsignal" commandPath="/system/bin/kill" commandArgs="-%1$s %2$s" />
   <command commandId="terminate" commandPath="/system/bin/kill" commandArgs="%1$s" />
 
-  <!-- Compress commands -->
+  <!-- Compress -->
   <command commandId="compress" commandPath="/system/xbin/tar" commandArgs="%1$scvf %2$s [@]" />
   <command commandId="gzip" commandPath="/system/bin/gzip" commandArgs="%1$s" />
   <command commandId="bzip" commandPath="/system/xbin/bzip2" commandArgs="-f %1$s" />
 
+  <!-- Uncompress -->
+  <command commandId="untar" commandPath="/system/bin/mkdir" commandArgs="-p %2$s &amp;&amp; /system/xbin/tar -C %2$s %1$sxvf %3$s" />
+  <command commandId="unzip" commandPath="/system/bin/mkdir" commandArgs="-p %1$s &amp;&amp; /system/xbin/unzip -o %2$s -d %1$s" />
+  <command commandId="gunzip" commandPath="/system/xbin/gunzip" commandArgs="-f %1$s" />
+  <command commandId="bunzip" commandPath="/system/xbin/bunzip2" commandArgs="-f %1$s" />
+  <command commandId="unlzma" commandPath="/system/xbin/unlzma" commandArgs="-f %1$s" />
+  <command commandId="uncompress" commandPath="/system/xbin/uncompress" commandArgs="-f %1$s" />
+  <command commandId="unxz" commandPath="/system/xbin/unxz" commandArgs="-f %1$s" />
+
 </CommandList>
\ No newline at end of file
index 59b38b4..e54c7d5 100644 (file)
@@ -408,4 +408,16 @@ public interface ExecutableCreator {
             CompressionMode mode, String src, AsyncResultListener asyncResultListener)
             throws CommandNotFoundException;
 
+    /**
+     * Method that creates an executable for uncompress file system objects.
+     *
+     * @param src The compressed file
+     * @param asyncResultListener The listener where to return partial results
+     * @return UncompressExecutable A {@link UncompressExecutable} executable implementation reference
+     * @throws CommandNotFoundException If the executable can't be created
+     */
+    UncompressExecutable createUncompressExecutable(
+            String src, AsyncResultListener asyncResultListener)
+            throws CommandNotFoundException;
+
 }
diff --git a/src/com/cyanogenmod/explorer/commands/UncompressExecutable.java b/src/com/cyanogenmod/explorer/commands/UncompressExecutable.java
new file mode 100644 (file)
index 0000000..aa9358a
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod Project
+ *
+ * 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.cyanogenmod.explorer.commands;
+
+/**
+ * An interface that represents an executable for uncompress file system objects.
+ */
+public interface UncompressExecutable extends AsyncResultExecutable {
+
+    /**
+     * Method that returns the result of the operation
+     *
+     * @return Boolean The result of the operation
+     */
+    Boolean getResult();
+
+    /**
+     * Method that returns the path out uncompressed file or folder
+     *
+     * @return String The path of the uncompressed file or folder
+     */
+    String getOutUncompressedFile();
+
+    /**
+     * Method that returns if the uncompress process will create a file or a folder
+     *
+     * @return boolean If the uncompress process will create a file or a folder
+     */
+    boolean IsArchive();
+}
index be91a8d..3bf0587 100644 (file)
@@ -518,4 +518,19 @@ public class ShellExecutableCreator implements ExecutableCreator {
         }
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public UncompressCommand createUncompressExecutable(
+            String src,
+            AsyncResultListener asyncResultListener)
+            throws CommandNotFoundException {
+        try {
+            return new UncompressCommand(src, asyncResultListener);
+        } catch (InvalidCommandDefinitionException icdEx) {
+            throw new CommandNotFoundException("UncompressCommand", icdEx); //$NON-NLS-1$
+        }
+    }
+
 }
diff --git a/src/com/cyanogenmod/explorer/commands/shell/UncompressCommand.java b/src/com/cyanogenmod/explorer/commands/shell/UncompressCommand.java
new file mode 100644 (file)
index 0000000..7a51f52
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod Project
+ *
+ * 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.cyanogenmod.explorer.commands.shell;
+
+import com.cyanogenmod.explorer.commands.AsyncResultListener;
+import com.cyanogenmod.explorer.commands.SIGNAL;
+import com.cyanogenmod.explorer.commands.UncompressExecutable;
+import com.cyanogenmod.explorer.console.CommandNotFoundException;
+import com.cyanogenmod.explorer.console.ExecutionException;
+import com.cyanogenmod.explorer.console.InsufficientPermissionsException;
+import com.cyanogenmod.explorer.util.FileHelper;
+
+import java.io.File;
+
+/**
+ * A class for uncompress file system objects.
+ *
+ * {@link "http://unixhelp.ed.ac.uk/CGI/man-cgi?tar"}
+ * {@link "http://unixhelp.ed.ac.uk/CGI/man-cgi?unzip"}
+ * {@link "http://unixhelp.ed.ac.uk/CGI/man-cgi?gunzip"}
+ * {@link "http://unixhelp.ed.ac.uk/CGI/man-cgi?bunzip2"}
+ * {@link "http://unixhelp.ed.ac.uk/CGI/man-cgi?xz"}
+ */
+public class UncompressCommand extends AsyncResultProgram implements UncompressExecutable {
+
+    /**
+     * An enumeration of implemented uncompression modes.
+     */
+    public enum UncompressionMode {
+        /**
+         * Uncompress using Tar algorithm
+         */
+        A_UNTAR(UNTAR_ID, "", "tar", true), //$NON-NLS-1$ //$NON-NLS-2$
+        /**
+         * Uncompress using Tar algorithm
+         */
+        A_UNZIP(UNZIP_ID, "", "zip", true), //$NON-NLS-1$ //$NON-NLS-2$
+        /**
+         * Uncompress using Gzip algorithm
+         */
+        AC_GUNZIP(GUNZIP_ID, "z", "tar.gz", true), //$NON-NLS-1$ //$NON-NLS-2$
+        /**
+         * Uncompress using Gzip algorithm
+         */
+        AC_GUNZIP2(GUNZIP_ID, "z", "tgz", true), //$NON-NLS-1$ //$NON-NLS-2$
+        /**
+         * Uncompress using Bzip algorithm
+         */
+        AC_BUNZIP(BUNZIP_ID, "j", "tar.bz2", true), //$NON-NLS-1$ //$NON-NLS-2$
+        /**
+         * Uncompress using Lzma algorithm
+         */
+        AC_UNLZMA(UNLZMA_ID, "a", "tar.lzma", true), //$NON-NLS-1$ //$NON-NLS-2$
+        /**
+         * Uncompress using Gzip algorithm
+         */
+        C_GUNZIP(GUNZIP_ID, "", "gz", false), //$NON-NLS-1$ //$NON-NLS-2$
+        /**
+         * Uncompress using Bzip algorithm
+         */
+        C_BUNZIP(BUNZIP_ID, "", "bz2", false), //$NON-NLS-1$ //$NON-NLS-2$
+        /**
+         * Uncompress using Lzma algorithm
+         */
+        C_UNLZMA(UNLZMA_ID, "", "lzma", false), //$NON-NLS-1$ //$NON-NLS-2$
+        /**
+         * Uncompress using Unix compress algorithm
+         */
+        C_UNCOMPRESS(UNCOMPRESS_ID, "", ".Z", false), //$NON-NLS-1$ //$NON-NLS-2$
+        /**
+         * Uncompress using Unix compress algorithm
+         */
+        C_UNXZ(UNXZ_ID, "", ".xz", false); //$NON-NLS-1$ //$NON-NLS-2$
+
+        String mId;
+        String mFlag;
+        String mExtension;
+        boolean mArchive;
+
+        /**
+         * Constructor of <code>UncompressionMode</code>
+         *
+         * @param id The command identifier
+         * @param flag The tar compression flag
+         * @param extension The file extension
+         * @param archive If the file is an archive or archive-compressed
+         */
+        private UncompressionMode(String id, String flag, String extension, boolean archive) {
+            this.mId = id;
+            this.mFlag = flag;
+            this.mExtension = extension;
+            this.mArchive = archive;
+        }
+    }
+
+    private static final String UNTAR_ID = "untar"; //$NON-NLS-1$
+    private static final String UNZIP_ID = "unzip"; //$NON-NLS-1$
+    private static final String GUNZIP_ID = "gunzip"; //$NON-NLS-1$
+    private static final String BUNZIP_ID = "bunzip"; //$NON-NLS-1$
+    private static final String UNLZMA_ID = "unlzma"; //$NON-NLS-1$
+    private static final String UNCOMPRESS_ID = "uncompress"; //$NON-NLS-1$
+    private static final String UNXZ_ID = "unxz"; //$NON-NLS-1$
+
+    private Boolean mResult;
+    private String mPartial;
+
+    private final String mOutFile;
+    private final boolean mIsArchive;
+
+    /**
+     * Constructor of <code>UncompressCommand</code>.<br/>
+     * <br/>
+     * <ul>
+     * <li>For archive and archive-compressed files, the file is extracted in a directory
+     * of the current location of the file with the name of the file without the extension.</li>
+     * <li>For compressed files, the file is extracted in the same directory in a file without
+     * the extension, and the source file is deleted.</li>
+     * </ul>
+     *
+     * @param src The archive-compressed file
+     * @param asyncResultListener The partial result listener
+     * @throws InvalidCommandDefinitionException If the command has an invalid definition
+     */
+    public UncompressCommand(
+            String src, AsyncResultListener asyncResultListener)
+            throws InvalidCommandDefinitionException {
+        super(resolveId(src), asyncResultListener, resolveArguments(src));
+
+        // Check that have a valid
+        UncompressionMode mode = getMode(src);
+        if (mode == null) {
+            throw new InvalidCommandDefinitionException(
+                            "Unsupported uncompress mode"); //$NON-NLS-1$
+        }
+
+        // Retrieve information about the uncompress process
+        this.mOutFile = resolveOutputFile(src);
+        this.mIsArchive = mode.mArchive;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onStartParsePartialResult() {
+        this.mResult = Boolean.FALSE;
+        this.mPartial = ""; //$NON-NLS-1$
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onEndParsePartialResult(boolean canceled) {
+        // Send the last partial data
+        if (this.mPartial != null && this.mPartial.length() > 0) {
+            if (getAsyncResultListener() != null) {
+                getAsyncResultListener().onPartialResult(this.mPartial);
+            }
+        }
+        this.mPartial = ""; //$NON-NLS-1$
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onParsePartialResult(final String partialIn) {
+        if (partialIn == null || partialIn.length() ==0) return;
+        boolean endsWithNewLine = partialIn.endsWith("\n"); //$NON-NLS-1$
+        String[] lines = partialIn.split("\n"); //$NON-NLS-1$
+
+        // Append the pending data to the first line
+        lines[0] = this.mPartial + lines[0];
+
+        // Return all the lines, except the last
+        for (int i = 0; i < lines.length-1; i++) {
+            if (getAsyncResultListener() != null) {
+                getAsyncResultListener().onPartialResult(lines[i]);
+            }
+        }
+
+        // Return the last line?
+        if (endsWithNewLine) {
+            if (getAsyncResultListener() != null) {
+                getAsyncResultListener().onPartialResult(lines[lines.length-1]);
+            }
+            this.mPartial = ""; //$NON-NLS-1$
+        } else {
+            // Save the partial for next calls
+            this.mPartial = lines[lines.length-1];
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onParseErrorPartialResult(String partialErr) {/**NON BLOCK**/}
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public SIGNAL onRequestEnd() {
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Boolean getResult() {
+        return this.mResult;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void checkExitCode(int exitCode)
+            throws InsufficientPermissionsException, CommandNotFoundException, ExecutionException {
+
+        //Ignore exit code 143 (canceled)
+        //Ignore exit code 137 (kill -9)
+        if (exitCode != 0 && exitCode != 143 && exitCode != 137) {
+            throw new ExecutionException(
+                        "exitcode != 0 && != 1 && != 143 && != 137"); //$NON-NLS-1$
+        }
+
+        // Correct
+        this.mResult = Boolean.TRUE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getOutUncompressedFile() {
+        return this.mOutFile;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean IsArchive() {
+        return this.mIsArchive;
+    }
+
+    /**
+     * Method that resolves the identifier to use as command
+     *
+     * @param src The compressed file
+     * @return String The identifier of the command
+     */
+    private static String resolveId(String src) {
+        UncompressionMode mode = getMode(src);
+        if (mode != null) {
+            return mode.mId;
+        }
+        return ""; //$NON-NLS-1$
+    }
+
+    /**
+     * Method that resolves the arguments for the uncompression
+     *
+     * @return String[] The arguments
+     */
+    private static String[] resolveArguments(String src) {
+        String name = FileHelper.getName(src);
+        File dst = new File(new File(src).getParent(), name);
+        UncompressionMode mode = getMode(src);
+        if (mode != null) {
+            switch (mode) {
+                case A_UNTAR:
+                case AC_GUNZIP:
+                case AC_GUNZIP2:
+                case AC_BUNZIP:
+                case AC_UNLZMA:
+                    return new String[]{mode.mFlag, dst.getAbsolutePath(), src};
+
+                case A_UNZIP:
+                    return new String[]{dst.getAbsolutePath(), src};
+
+                case C_GUNZIP:
+                case C_BUNZIP:
+                case C_UNLZMA:
+                case C_UNCOMPRESS:
+                case C_UNXZ:
+                    return new String[]{src};
+
+                default:
+                    break;
+            }
+        }
+        return new String[]{};
+    }
+
+    /**
+     * Method that resolves the output path of the uncompressed file
+     *
+     * @return String The output path of the uncompressed file
+     */
+    private static String resolveOutputFile(String src) {
+        String name = FileHelper.getName(src);
+        File dst = new File(new File(src).getParent(), name);
+        return dst.getAbsolutePath();
+    }
+
+    /**
+     * Method that returns the uncompression mode from the compressed file
+     *
+     * @param src The compressed file
+     * @return UncompressionMode The uncompression mode. <code>null</code> if no mode found
+     */
+    private static UncompressionMode getMode(String src) {
+        String extension = FileHelper.getExtension(src);
+        UncompressionMode[] modes = UncompressionMode.values();
+        for (int i = 0; i < modes.length; i++) {
+            UncompressionMode mode = modes[i];
+            if (mode.mExtension.compareTo(extension) == 0) {
+                return mode;
+            }
+        }
+        return null;
+    }
+}
index f303277..c094f18 100644 (file)
@@ -50,6 +50,7 @@ import com.cyanogenmod.explorer.commands.ResolveLinkExecutable;
 import com.cyanogenmod.explorer.commands.SIGNAL;
 import com.cyanogenmod.explorer.commands.SendSignalExecutable;
 import com.cyanogenmod.explorer.commands.SyncResultExecutable;
+import com.cyanogenmod.explorer.commands.UncompressExecutable;
 import com.cyanogenmod.explorer.commands.WritableExecutable;
 import com.cyanogenmod.explorer.commands.WriteExecutable;
 import com.cyanogenmod.explorer.commands.shell.CompressCommand.CompressionMode;
@@ -1287,7 +1288,69 @@ public final class CommandHelper {
             return executable1;
         }
         throw new ExecutionException(
-                String.format("Fail to create file %s", compressOutFile)); //$NON-NLS-1$
+                String.format("Fail to compress to file %s", compressOutFile)); //$NON-NLS-1$
+    }
+
+    /**
+     * Method that uncompress file system objects.
+     *
+     * @param context The current context (needed if console == null)
+     * @param src The file to compress
+     * @param asyncResultListener The partial result listener
+     * @param console The console in which execute the program.
+     * <code>null</code> to attach to the default console
+     * @return AsyncResultProgram The command executed in background
+     * @throws FileNotFoundException If the initial directory not exists
+     * @throws IOException If initial directory can't not be checked
+     * @throws InvalidCommandDefinitionException If the command has an invalid definition
+     * @throws NoSuchFileOrDirectory If the file or directory was not found
+     * @throws ConsoleAllocException If the console can't be allocated
+     * @throws InsufficientPermissionsException If an operation requires elevated permissions
+     * @throws CommandNotFoundException If the command was not found
+     * @throws OperationTimeoutException If the operation exceeded the maximum time of wait
+     * @throws ExecutionException If the operation returns a invalid exit code
+     * @throws ReadOnlyFilesystemException If the operation writes in a read-only filesystem
+     * @see CompressExecutable
+     */
+    public static UncompressExecutable uncompress(
+            Context context, String src,
+            AsyncResultListener asyncResultListener, Console console)
+            throws FileNotFoundException, IOException, ConsoleAllocException,
+            NoSuchFileOrDirectory, InsufficientPermissionsException,
+            CommandNotFoundException, OperationTimeoutException,
+            ExecutionException, InvalidCommandDefinitionException, ReadOnlyFilesystemException {
+        Console c = ensureConsole(context, console);
+
+        UncompressExecutable executable1 =
+                c.getExecutableFactory().newCreator().
+                    createUncompressExecutable(src, asyncResultListener);
+
+        // Prior to write to disk the data, ensure that can write to the disk using
+        // createFile or createFolder method
+
+        String compressOutFile = executable1.getOutUncompressedFile();
+        WritableExecutable executable2 = null;
+        if (executable1.IsArchive()) {
+            //- Create Folder
+            executable2 =
+                    c.getExecutableFactory().
+                        newCreator().
+                            createCreateDirectoryExecutable(compressOutFile);
+        } else {
+            //- Create File
+            executable2 =
+                    c.getExecutableFactory().
+                        newCreator().
+                            createCreateFileExecutable(compressOutFile);
+        }
+        writableExecute(context, executable2, c);
+        if (((Boolean)executable2.getResult()).booleanValue()) {
+            //- Compress
+            execute(context, executable1, c);
+            return executable1;
+        }
+        throw new ExecutionException(
+                String.format("Fail to uncompress to %s", compressOutFile)); //$NON-NLS-1$
     }
 
     /**
index 6f9f612..aa94ce9 100644 (file)
@@ -49,11 +49,12 @@ import java.util.List;
 public final class FileHelper {
 
     /**
-     * Constructor of <code>FileHelper</code>.
+     * Special extension for compressed tar files
      */
-    private FileHelper() {
-        super();
-    }
+    private static final String[] COMPRESSED_TAR =
+        {
+         "tar.gz", "tar.bz2", "tar.lzma" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        };
 
     /**
      * The root directory.
@@ -86,6 +87,13 @@ public final class FileHelper {
     public static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$
 
     /**
+     * Constructor of <code>FileHelper</code>.
+     */
+    private FileHelper() {
+        super();
+    }
+
+    /**
      * Method that check if a file is a symbolic link.
      *
      * @param file File to check
@@ -249,12 +257,14 @@ public final class FileHelper {
             return null;
         }
 
-        // 3 exceptions to the general form: tar.gz, tar.bz2 and tar.lzma
-        if (name.endsWith(".tar.gz")) return "tar.gz"; //$NON-NLS-1$ //$NON-NLS-2$
-        if (name.endsWith(".tar.bz2")) return "tar.bz2"; //$NON-NLS-1$ //$NON-NLS-2$
-        if (name.endsWith(".tar.lzma")) return "tar.lzma"; //$NON-NLS-1$ //$NON-NLS-2$
+        // Exceptions to the general extraction method
+        for (int i = 0; i < COMPRESSED_TAR.length; i++) {
+            if (name.endsWith("." + COMPRESSED_TAR[i])) { //$NON-NLS-1$
+                return COMPRESSED_TAR[i];
+            }
+        }
 
-        // General form
+        // General extraction method
         return name.substring(pos + 1);
     }
 
@@ -680,4 +690,33 @@ public final class FileHelper {
         }
         return false;
     }
+
+    /**
+     * Method that returns is a {@link FileSystemObject} can be handled by this application
+     * allowing the uncompression of the file
+     *
+     * @param fso The file system object to verify
+     * @return boolean If the file is supported
+     */
+    @SuppressWarnings("nls")
+    public static boolean isSupportedUnCompressedFile(FileSystemObject fso) {
+        // Valid uncompressed formats are:
+        final String[] VALID =
+                {
+                    "tar", "tgz", "tar.gz", "tar.bz2", "tar.lzma",
+                    "unzip", "gz", "bz2", "lzma", "xz", "Z"
+                };
+
+        //Only regular files
+        if (isDirectory(fso) || fso instanceof Symlink) {
+            return false;
+        }
+        String ext = getExtension(fso);
+        for (int i = 0; i < VALID.length; i++) {
+            if (VALID[i].compareTo(ext) == 0) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/tests/src/com/cyanogenmod/explorer/commands/shell/UncompressCommandTest.java b/tests/src/com/cyanogenmod/explorer/commands/shell/UncompressCommandTest.java
new file mode 100644 (file)
index 0000000..adcf06e
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod Project
+ *
+ * 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.cyanogenmod.explorer.commands.shell;
+
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import com.cyanogenmod.explorer.commands.AsyncResultListener;
+import com.cyanogenmod.explorer.commands.UncompressExecutable;
+import com.cyanogenmod.explorer.util.CommandHelper;
+
+/**
+ * A class for testing the uncompression of file system objects.
+ *
+ * @see UncompressCommand
+ */
+public class UncompressCommandTest extends AbstractConsoleTest {
+
+    private static final String TAG = "UncompressCommandTest"; //$NON-NLS-1$
+
+    /**
+     * @hide
+     */
+    final Object mSync = new Object();
+    /**
+     * @hide
+     */
+    boolean mNewPartialData;
+    /**
+     * @hide
+     */
+    boolean mNormalEnd;
+    /**
+     * @hide
+     */
+    boolean mResult;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isRootConsoleNeeded() {
+        return true;
+    }
+
+    /**
+     * Method that performs the test of uncompress data in TAR format.
+     *
+     * @throws Exception If test failed
+     */
+    @LargeTest
+    @SuppressWarnings("unused")
+    public void testArchiveUnTAR() throws Exception {
+        // Cann't not reproduce without sample compress file
+    }
+
+    /**
+     * Method that performs the test of uncompress data in ZIP format.
+     *
+     * @throws Exception If test failed
+     */
+    @LargeTest
+    @SuppressWarnings("unused")
+    public void testArchiveUnZIP() throws Exception {
+        // Cann't not reproduce without sample compress file
+    }
+
+    /**
+     * Method that performs the test of uncompress data in GZIP format.
+     *
+     * @throws Exception If test failed
+     */
+    @LargeTest
+    @SuppressWarnings("unused")
+    public void testArchiveUnTarGZIP() throws Exception {
+        // Cann't not reproduce without sample compress file
+    }
+
+    /**
+     * Method that performs the test of uncompress data in BZIP format.
+     *
+     * @throws Exception If test failed
+     */
+    @LargeTest
+    @SuppressWarnings("unused")
+    public void testArchiveUnTarBZIP() throws Exception {
+        // Cann't not reproduce without sample compress file
+    }
+
+    /**
+     * Method that performs the test of uncompress data in LZMA format.
+     *
+     * @throws Exception If test failed
+     */
+    @LargeTest
+    @SuppressWarnings("unused")
+    public void testArchiveUnTarLZMA() throws Exception {
+        // Cann't not reproduce without sample compress file
+    }
+
+    /**
+     * Method that performs the test of uncompress data in GZIP format.
+     *
+     * @throws Exception If test failed
+     */
+    @LargeTest
+    @SuppressWarnings("unused")
+    public void testArchiveUnGZIP() throws Exception {
+        // Cann't not reproduce without sample compress file
+    }
+
+    /**
+     * Method that performs the test of uncompress data in BZIP format.
+     *
+     * @throws Exception If test failed
+     */
+    @LargeTest
+    @SuppressWarnings("unused")
+    public void testArchiveUnBZIP() throws Exception {
+        // Cann't not reproduce without sample compress file
+    }
+
+    /**
+     * Method that performs the test of uncompress data in LZMA format.
+     *
+     * @throws Exception If test failed
+     */
+    @LargeTest
+    @SuppressWarnings("unused")
+    public void testArchiveUnLZMA() throws Exception {
+        // Cann't not reproduce without sample compress file
+    }
+
+    /**
+     * Method that performs the test of uncompress data in Unix compress format.
+     *
+     * @throws Exception If test failed
+     */
+    @LargeTest
+    @SuppressWarnings("unused")
+    public void testArchiveUnCompress() throws Exception {
+        // Cann't not reproduce without sample compress file
+    }
+
+    /**
+     * Method that performs the test of uncompress data in XZ format.
+     *
+     * @throws Exception If test failed
+     */
+    @LargeTest
+    @SuppressWarnings("unused")
+    public void testArchiveUnXZ() throws Exception {
+        // Cann't not reproduce without sample compress file
+    }
+
+
+    /**
+     * Method that uncompress data.
+     *
+     * @param src The compressed file
+     * @param expectOutput If the test need to expect output in the uncompress operation
+     * @throws Exception If test failed
+     */
+    @SuppressWarnings("unused")
+    private void testUncompress(String src, boolean expectOutput) throws Exception {
+        UncompressExecutable cmd = null;
+        try {
+            this.mNewPartialData = false;
+            this.mNormalEnd = false;
+            cmd =
+                CommandHelper.uncompress(
+                    getContext(), src, new AsyncResultListener() {
+                        public void onAsyncStart() {
+                            /**NON BLOCK**/
+                        }
+                        public void onAsyncEnd(boolean canceled) {
+                            synchronized (UncompressCommandTest.this.mSync) {
+                                UncompressCommandTest.this.mNormalEnd = true;
+                                UncompressCommandTest.this.mSync.notify();
+                            }
+                        }
+                        public void onAsyncExitCode(int exitCode) {
+                            /**NON BLOCK**/
+                        }
+                        public void onException(Exception cause) {
+                            fail(String.valueOf(cause));
+                        }
+                        public void onPartialResult(Object result) {
+                            UncompressCommandTest.this.mNewPartialData = true;
+                            Log.d(TAG, (String)result);
+                        }
+                   }, getConsole());
+            synchronized (UncompressCommandTest.this.mSync) {
+                UncompressCommandTest.this.mSync.wait(60000L);
+            }
+            try {
+                if (!this.mNormalEnd && cmd != null && cmd.isCancelable() && !cmd.isCanceled()) {
+                    cmd.cancel();
+                }
+            } catch (Exception e) {/**NON BLOCK**/}
+
+            // Wait for result
+            Thread.sleep(500L);
+
+            if (expectOutput) {
+                assertTrue("no new partial data", this.mNewPartialData); //$NON-NLS-1$
+            }
+            assertNotNull("cmd != null", cmd); //$NON-NLS-1$
+            if (cmd != null) {
+                assertTrue("return != true", cmd.getResult().booleanValue()); //$NON-NLS-1$
+            }
+        } finally {
+            try {
+                CommandHelper.deleteFile(getContext(), src, getConsole());
+            } catch (Exception e) {/**NON BLOCK**/}
+            try {
+                if (cmd != null) {
+                    if (cmd.IsArchive()) {
+                        CommandHelper.deleteDirectory(
+                                getContext(), cmd.getOutUncompressedFile(), getConsole());
+                    } else {
+                        CommandHelper.deleteFile(
+                                getContext(), cmd.getOutUncompressedFile(), getConsole());
+                    }
+                }
+            } catch (Exception e) {/**NON BLOCK**/}
+        }
+    }
+
+}