/* * 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.shell; import android.util.Log; import com.cyanogenmod.filemanager.commands.AsyncResultListener; import com.cyanogenmod.filemanager.commands.FindExecutable; import com.cyanogenmod.filemanager.commands.SIGNAL; import com.cyanogenmod.filemanager.console.CommandNotFoundException; import com.cyanogenmod.filemanager.console.ExecutionException; import com.cyanogenmod.filemanager.console.InsufficientPermissionsException; import com.cyanogenmod.filemanager.model.FileSystemObject; import com.cyanogenmod.filemanager.model.Query; import com.cyanogenmod.filemanager.util.FileHelper; import com.cyanogenmod.filemanager.util.ParseHelper; import com.cyanogenmod.filemanager.util.SearchHelper; import java.io.BufferedReader; import java.io.File; import java.io.StringReader; import java.util.ArrayList; import java.util.List; /** * A class for search files. * * {@link "http://unixhelp.ed.ac.uk/CGI/man-cgi?find"} */ public class FindCommand extends AsyncResultProgram implements FindExecutable { private static final String TAG = "FindCommand"; //$NON-NLS-1$ private static final String ID = "find"; //$NON-NLS-1$ private final File mDirectory; /** * Constructor of <code>FindCommand</code>. * * @param directory The absolute path of the directory where do the search * @param query The terms to be searched * @param asyncResultListener The partial result listener * @throws InvalidCommandDefinitionException If the command has an invalid definition */ public FindCommand( String directory, Query query, AsyncResultListener asyncResultListener) throws InvalidCommandDefinitionException { super(ID, asyncResultListener, createArgs(FileHelper.addTrailingSlash(directory), query)); this.mDirectory = new File(directory); } /** * {@inheritDoc} */ @Override public void onStartParsePartialResult() { //$NON-NLS-1$ } /** * {@inheritDoc} */ @Override public void onEndParsePartialResult(boolean cancelled) { //$NON-NLS-1$ } /** * {@inheritDoc} */ @Override public void onParsePartialResult(final String partialIn) { // Check the in buffer to extract information final List<FileSystemObject> partialFiles = new ArrayList<FileSystemObject>(); BufferedReader br = null; try { //Read the partial + previous partial and clean partial br = new BufferedReader(new StringReader(partialIn)); //Add all lines to an array String line = null; while ((line = br.readLine()) != null) { //Checks that there is some text in the line. Otherwise ignore it if (line.trim().length() == 0) { break; } // Add to the list try { FileSystemObject fso = ParseHelper.parseStatOutput(line); // Search directory is not part of the search if (fso.getFullPath().compareTo(this.mDirectory.getAbsolutePath()) != 0) { partialFiles.add(fso); } } catch (Exception e) { // Log the parsing error if (isTrace()) { Log.w(TAG, String.format( "Failed to parse output: %s", //$NON-NLS-1$ String.valueOf(line))); } } } //If a listener is defined, then send the partial result if (getAsyncResultListener() != null) { getAsyncResultListener().onPartialResult(partialFiles); } } catch (Exception ex) { Log.w(TAG, "Partial result fails", ex); //$NON-NLS-1$ } finally { try { if (br != null) { br.close(); } } catch (Throwable ex) { /**NON BLOCK**/ } } } /** * {@inheritDoc} */ @Override public void onParseErrorPartialResult(String partialErr) {/**NON BLOCK**/} /** * {@inheritDoc} */ @Override public SIGNAL onRequestEnd() { return null; } /** * {@inheritDoc} */ @Override public boolean isIgnoreShellStdErrCheck() { return true; } /** * {@inheritDoc} */ @Override public void checkExitCode(int exitCode) throws InsufficientPermissionsException, CommandNotFoundException, ExecutionException { //Search in a subdirectory without permissions returns 1, but this //not must be treated as an error //Ignore exit code 143 (cancelled) //Ignore exit code 137 (kill -9) if (exitCode != 0 && exitCode != 1 && exitCode != 143 && exitCode != 137) { throw new ExecutionException( "exitcode != 0 && != 1 && != 143 && != 137"); //$NON-NLS-1$ } } /** * Method that create the arguments 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 arguments of the command */ private static String[] createArgs(String directory, Query query) { String[] args = new String[query.getSlotsCount() + 1]; args[0] = directory; int cc = query.getSlotsCount(); for (int i = 0; i < cc; i++) { args[i + 1] = SearchHelper.toIgnoreCaseRegExp(query.getSlot(i), false); } return args; } }