diff options
Diffstat (limited to 'src/com/cyanogenmod/filemanager/commands/secure/FindCommand.java')
-rw-r--r-- | src/com/cyanogenmod/filemanager/commands/secure/FindCommand.java | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/src/com/cyanogenmod/filemanager/commands/secure/FindCommand.java b/src/com/cyanogenmod/filemanager/commands/secure/FindCommand.java new file mode 100644 index 00000000..33d0ace0 --- /dev/null +++ b/src/com/cyanogenmod/filemanager/commands/secure/FindCommand.java @@ -0,0 +1,271 @@ +/* + * 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.filemanager.commands.secure; + +import android.util.Log; + +import com.cyanogenmod.filemanager.commands.AsyncResultListener; +import com.cyanogenmod.filemanager.commands.ConcurrentAsyncResultListener; +import com.cyanogenmod.filemanager.commands.FindExecutable; +import com.cyanogenmod.filemanager.console.ExecutionException; +import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory; +import com.cyanogenmod.filemanager.console.secure.SecureConsole; +import com.cyanogenmod.filemanager.model.FileSystemObject; +import com.cyanogenmod.filemanager.model.Query; +import com.cyanogenmod.filemanager.util.FileHelper; +import com.cyanogenmod.filemanager.util.SearchHelper; + +import de.schlichtherle.truezip.file.TFile; + +import java.util.Arrays; + +/** + * A class for search files. + */ +public class FindCommand extends Program implements FindExecutable { + + private static final String TAG = "FindCommand"; //$NON-NLS-1$ + + private final String mDirectory; + private final String[] mQueryRegExp; + private final ConcurrentAsyncResultListener mAsyncResultListener; + + private boolean mCancelled; + private boolean mEnded; + private final Object mSync = new Object(); + + /** + * Constructor of <code>FindCommand</code>. + * + * @param console The secure console + * @param directory The absolute directory where start the search + * @param query The terms to be searched + * @param asyncResultListener The partial result listener + */ + public FindCommand(SecureConsole console, String directory, Query query, + ConcurrentAsyncResultListener asyncResultListener) { + super(console); + // This command should start the search in the root directory or in a descendent folder + if (!getConsole().isSecureStorageResource(directory)) { + this.mDirectory = getConsole().getVirtualMountPoint().getAbsolutePath(); + } else { + this.mDirectory = directory; + } + this.mQueryRegExp = createRegexp(directory, query); + this.mAsyncResultListener = asyncResultListener; + if (mAsyncResultListener instanceof ConcurrentAsyncResultListener) { + ((ConcurrentAsyncResultListener) mAsyncResultListener).onRegister(); + } + this.mCancelled = false; + this.mEnded = false; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isAsynchronous() { + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public void execute() throws NoSuchFileOrDirectory, ExecutionException { + if (isTrace()) { + Log.v(TAG, + String.format("Finding in %s the query %s", //$NON-NLS-1$ + this.mDirectory, Arrays.toString(this.mQueryRegExp))); + } + if (this.mAsyncResultListener != null) { + this.mAsyncResultListener.onAsyncStart(); + } + + TFile f = getConsole().buildRealFile(mDirectory); + if (!f.exists()) { + if (isTrace()) { + Log.v(TAG, "Result: FAIL. NoSuchFileOrDirectory"); //$NON-NLS-1$ + } + if (this.mAsyncResultListener != null) { + this.mAsyncResultListener.onException(new NoSuchFileOrDirectory(this.mDirectory)); + } + } + if (!f.isDirectory()) { + if (isTrace()) { + Log.v(TAG, "Result: FAIL. NoSuchFileOrDirectory"); //$NON-NLS-1$ + } + if (this.mAsyncResultListener != null) { + this.mAsyncResultListener.onException( + new ExecutionException("path exists but it's not a folder")); //$NON-NLS-1$ + } + } + + // Find the data + findRecursive(f); + + if (this.mAsyncResultListener != null) { + this.mAsyncResultListener.onAsyncEnd(this.mCancelled); + } + if (this.mAsyncResultListener != null) { + this.mAsyncResultListener.onAsyncExitCode(0); + } + + if (isTrace()) { + Log.v(TAG, "Result: OK"); //$NON-NLS-1$ + } + } + + /** + * Method that search files recursively + * + * @param folder The folder where to start the search + */ + private void findRecursive(TFile folder) { + // Obtains the files and folders of the folders + TFile[] files = folder.listFiles(); + if (files != null) { + int cc = files.length; + for (int i = 0; i < cc; i++) { + if (files[i].isDirectory()) { + findRecursive(files[i]); + } + + // Check if the file or folder matches the regexp + try { + int ccc = this.mQueryRegExp.length; + for (int j = 0; j < ccc; j++) { + if (files[i].getName().matches(this.mQueryRegExp[j])) { + FileSystemObject fso = FileHelper.createFileSystemObject(files[i]); + if (fso != null) { + // Convert to virtual + fso.setParent(getConsole().buildVirtualPath( + files[i].getParentFile())); + fso.setSecure(true); + + if (isTrace()) { + Log.v(TAG, String.valueOf(fso)); + } + if (this.mAsyncResultListener != null) { + this.mAsyncResultListener.onPartialResult(fso); + } + } + } + } + } catch (Exception e) {/**NON-BLOCK**/} + + // Check if the process was cancelled + try { + synchronized (this.mSync) { + if (this.mCancelled || this.mEnded || (mAsyncResultListener != null + && mAsyncResultListener.isCancelled())) { + this.mSync.notify(); + break; + } + } + } catch (Exception e) {/**NON BLOCK**/} + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isCancelled() { + synchronized (this.mSync) { + return this.mCancelled; + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean cancel() { + try { + synchronized (this.mSync) { + this.mCancelled = true; + this.mSync.wait(5000L); + } + } catch (Exception e) {/**NON BLOCK**/} + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean end() { + try { + synchronized (this.mSync) { + this.mEnded = true; + this.mSync.wait(5000L); + } + } catch (Exception e) {/**NON BLOCK**/} + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public void setOnEndListener(OnEndListener onEndListener) { + //Ignore. secure console don't use this + } + + /** + * {@inheritDoc} + */ + @Override + public void setOnCancelListener(OnCancelListener onCancelListener) { + //Ignore. secure console don't use this + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isCancellable() { + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public AsyncResultListener getAsyncResultListener() { + return this.mAsyncResultListener; + } + + /** + * Method that create the regexp of this command, using the directory and + * arguments and creating the regular expressions of the search. + * + * @param directory The directory where to search + * @param query The query make for user + * @return String[] The regexp for filtering files + */ + private static String[] createRegexp(String directory, Query query) { + String[] args = new String[query.getSlotsCount()]; + int cc = query.getSlotsCount(); + for (int i = 0; i < cc; i++) { + args[i] = SearchHelper.toIgnoreCaseRegExp(query.getSlot(i), true); + } + return args; + } +} |