/* * 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.java; import android.util.Log; import com.cyanogenmod.filemanager.commands.AsyncResultListener; import com.cyanogenmod.filemanager.commands.WriteExecutable; import com.cyanogenmod.filemanager.console.ExecutionException; import com.cyanogenmod.filemanager.console.InsufficientPermissionsException; import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; /** * A class for write data to disk.<br/> * <br/> * User MUST call the {@link #createOutputStream()} to get the output stream where * write the data.<br/>. When no more exist then user MUST call the onEnd method * of the asynchronous listener.<br/> */ public class WriteCommand extends Program implements WriteExecutable { private static final String TAG = "WriteCommand"; //$NON-NLS-1$ private final String mFile; private BufferedOutputStream mBuffer; private final AsyncResultListener mAsyncResultListener; private boolean mCancelled; private final Object mSync = new Object(); private static final long TIMEOUT = 1000L; private final Object mWriteSync = new Object(); private boolean mReady; /** * Constructor of <code>WriteCommand</code>. * * @param file The file where to write the data * @param asyncResultListener The partial result listener */ public WriteCommand( String file, AsyncResultListener asyncResultListener) { super(); this.mFile = file; this.mAsyncResultListener = asyncResultListener; this.mCancelled = false; this.mReady = false; } /** * {@inheritDoc} */ @Override public boolean isAsynchronous() { return true; } /** * {@inheritDoc} */ @Override public OutputStream createOutputStream() throws IOException { try { // Wait until command is ready synchronized (this.mWriteSync) { if (!this.mReady) { try { this.mWriteSync.wait(TIMEOUT); } catch (Exception e) {/**NON BLOCK**/} } } this.mBuffer = new BufferedOutputStream( new FileOutputStream( new File(this.mFile)), getBufferSize()); return this.mBuffer; } catch (IOException ioEx) { if (isTrace()) { Log.e(TAG, "Result: FAILED. IOException", ioEx); //$NON-NLS-1$ } throw ioEx; } } /** * {@inheritDoc} */ @Override public void execute() throws InsufficientPermissionsException, NoSuchFileOrDirectory, ExecutionException { synchronized (this.mSync) { this.mReady = true; this.mSync.notify(); } if (isTrace()) { Log.v(TAG, String.format("Writing file %s", this.mFile)); //$NON-NLS-1$ } if (this.mAsyncResultListener != null) { this.mAsyncResultListener.onAsyncStart(); } // Wait the finalization try { synchronized (this.mSync) { this.mSync.wait(); } } catch (Throwable _throw) {/**NON BLOCK**/} 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$ } } /** * {@inheritDoc} */ @Override public boolean isCancelled() { synchronized (this.mSync) { return this.mCancelled; } } /** * {@inheritDoc} */ @Override public boolean cancel() { closeBuffer(); this.mCancelled = true; try { synchronized (this.mSync) { this.mSync.notify(); } } catch (Throwable _throw) {/**NON BLOCK**/} return true; } /** * {@inheritDoc} */ @Override public boolean end() { closeBuffer(); try { synchronized (this.mSync) { this.mSync.notify(); } } catch (Throwable _throw) {/**NON BLOCK**/} return true; } /** * Method that close the buffer */ private void closeBuffer() { try { if (this.mBuffer != null) { this.mBuffer.close(); } } catch (Exception ex) {/**NON BLOCK**/} try { Thread.yield(); } catch (Exception ex) {/**NON BLOCK**/} } /** * {@inheritDoc} */ @Override public void setOnEndListener(OnEndListener onEndListener) { //Ignore. Java console don't use this } /** * {@inheritDoc} */ @Override public void setOnCancelListener(OnCancelListener onCancelListener) { //Ignore. Java console don't use this } /** * {@inheritDoc} */ @Override public boolean isCancellable() { return true; } /** * {@inheritDoc} */ @Override public AsyncResultListener getAsyncResultListener() { return this.mAsyncResultListener; } }