com.aliyun.android.oss.task.GetObjectTask.java Source code

Java tutorial

Introduction

Here is the source code for com.aliyun.android.oss.task.GetObjectTask.java

Source

/**
 * Copyright (c) 2012 The Wiseserc. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

package com.aliyun.android.oss.task;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.text.ParseException;
import java.util.Date;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;

import com.aliyun.android.oss.OSSErrorCode;
import com.aliyun.android.oss.OSSException;
import com.aliyun.android.oss.http.HttpMethod;
import com.aliyun.android.oss.http.OSSHttpTool;
import com.aliyun.android.oss.model.OSSObject;
import com.aliyun.android.oss.model.Range;
import com.aliyun.android.util.Helper;
import com.cloud.client.CloudUtil;
import com.cloud.client.file.MissionListener;
import com.cloud.client.file.MissionObject;
import com.cloud.client.file.database.DatabaseAccessManager;
import com.cloud.util.log.LogMission;

/**
 * @author Michael
 */
public class GetObjectTask extends Task {
    private static final String TAG = "GetObjectTask";

    /**
     * Object??
     */
    private String objectKey;

    /**
     * 
     */
    private Range range;

    /**
     * ?
     */
    private Date modifiedSince;

    /**
     * ?
     */
    private Date unModifiedSince;

    /**
     * ETag
     */
    private String expectedETag;

    /**
     * ?ETag
     */
    private String unexpectedETag;

    private String filePath;

    /**
     * OSSheader
     */
    private String responseContentType = null;

    private String responseContentLanguage = null;

    private String responseExpires = null;

    private String responseCacheControl = null;

    private String responseContentDisposition = null;

    private String responseContentEncoding = null;

    private MissionListener listener = null;

    private MissionObject missionObject = null;

    private DatabaseAccessManager mDatabaseAccessManager = null;

    private LogMission mLogMission;
    /**
     * 
     */
    private byte[] decryptKey;

    public GetObjectTask(String bucketName, String objectKey, String filePath, MissionObject missionObject) {
        this(bucketName, objectKey);
        this.filePath = filePath;
        this.missionObject = missionObject;
    }

    /**
     * 
     */
    public GetObjectTask(String bucketName, String objectKey) {
        super(HttpMethod.GET, bucketName);
        this.objectKey = objectKey;
        this.mLogMission = new LogMission(TAG);
    }

    /**
     * ???
     */
    @Override
    protected void checkArguments() {
        if (Helper.isEmptyString(bucketName) || Helper.isEmptyString(objectKey)) {
            throw new IllegalArgumentException("bucketName or objectKey not properly set");
        }
    }

    /**
     * HttpGet
     */
    protected HttpUriRequest generateHttpRequest() {
        // ?Http
        String requestUri = this.getOSSEndPoint()
                + httpTool.generateCanonicalizedResource("/" + OSSHttpTool.encodeUri(objectKey));
        HttpGet httpGet = new HttpGet(requestUri);

        // Http
        String resource = httpTool.generateCanonicalizedResource("/" + bucketName + "/" + objectKey);
        String dateStr = Helper.getGMTDate();
        String authorization = OSSHttpTool.generateAuthorization(accessId, accessKey, httpMethod.toString(), "", "",
                dateStr, "", resource);

        httpGet.setHeader(AUTHORIZATION, authorization);
        httpGet.setHeader(DATE, dateStr);

        if (range != null) {
            OSSHttpTool.addHttpRequestHeader(httpGet, RANGE, "bytes=" + range.toString());
        }
        OSSHttpTool.addHttpRequestHeader(httpGet, IF_MODIFIED_SINCE, Helper.getGMTDate(modifiedSince));
        OSSHttpTool.addHttpRequestHeader(httpGet, IF_UNMODIFIED_SINCE, Helper.getGMTDate(unModifiedSince));
        OSSHttpTool.addHttpRequestHeader(httpGet, IF_MATCH, expectedETag);
        OSSHttpTool.addHttpRequestHeader(httpGet, IF_NONE_MATCH, unexpectedETag);

        return httpGet;
    }

    public String getBucketName() {
        return bucketName;
    }

    public void setBucketName(String bucketName) {
        this.bucketName = bucketName;
    }

    public String getObjectKey() {
        return objectKey;
    }

    public void setObjectKey(String objectKey) {
        this.objectKey = objectKey;
    }

    public void setProgressListener(MissionListener listener) {
        this.listener = listener;
    }

    public MissionListener getProgressListener() {
        return this.listener;
    }

    /**
     * ?{@link Range}
     * 
     * @return 
     * @see Range
     */
    public Range getRange() {
        return range;
    }

    /**
     * {@link Range}
     * 
     * @param range
     *            
     * @see Range
     */
    public void setRange(Range range) {
        this.range = range;
    }

    /**
     * ???304 not modified
     * 
     * @return 
     */
    public Date getModifiedSince() {
        return modifiedSince;
    }

    /**
     * ??304 Not Modified
     * 
     * @param modifiedSince
     *            
     */
    public void setModifiedSince(Date modifiedSince) {
        this.modifiedSince = modifiedSince;
    }

    /**
     * ???412 Precondition Failed
     * 
     * @return ?
     */
    public Date getUnModifiedSince() {
        return unModifiedSince;
    }

    /**
     * ??412 Precondition Failed
     * 
     * @param unModifiedSince
     *            ?
     */
    public void setUnModifiedSince(Date unModifiedSince) {
        this.unModifiedSince = unModifiedSince;
    }

    /**
     * ?TagTagobjectETag??412 Precondition Failed
     * 
     * @return Tag
     */
    public String getExpectedETag() {
        return expectedETag;
    }

    /**
     * TagTagobjectETag??412 Precondition Failed
     * 
     * @param expectedETag
     */
    public void setExpectedETag(String expectedETag) {
        this.expectedETag = expectedETag;
    }

    /**
     * ?TagTagobjectETag???304 Not Modified
     * 
     * @return Tag
     */
    public String getUnexpectedETag() {
        return unexpectedETag;
    }

    /**
     * TagTagobjectETag???304 Not Modified
     * 
     * @return Tag
     */
    public void setUnexpectedETag(String unexpectedETag) {
        this.unexpectedETag = unexpectedETag;
    }

    public String getResponseContentType() {
        return responseContentType;
    }

    /**
     * OSSContent-Type header
     * 
     * @param responseContentType
     */
    public void setResponseContentType(String responseContentType) {
        httpTool.setContentType(responseContentType);
        this.responseContentType = responseContentType;
    }

    public String getResponseContentLanguage() {
        return responseContentLanguage;
    }

    /**
     * OSSContent-Language header
     * 
     * @param responseContentLanguage
     */
    public void setResponseContentLanguage(String responseContentLanguage) {
        httpTool.setContentLanguage(responseContentLanguage);
        this.responseContentLanguage = responseContentLanguage;
    }

    public String getResponseExpires() {
        return responseExpires;
    }

    /**
     * OSSExpires header
     * 
     * @param responseExpires
     */
    public void setResponseExpires(String responseExpires) {
        httpTool.setExpires(responseExpires);
        this.responseExpires = responseExpires;
    }

    public String getResponseCacheControl() {
        return responseCacheControl;
    }

    /**
     * OSSCache-Contorl header
     * 
     * @param responseCacheControl
     */
    public void setResponseCacheControl(String responseCacheControl) {
        httpTool.setCacheControl(responseCacheControl);
        this.responseCacheControl = responseCacheControl;
    }

    public String getResponseContentDisposition() {
        return responseContentDisposition;
    }

    /**
     * OSSContent-Disposition header
     * 
     * @param responseContentDisposition
     */
    public void setResponseContentDisposition(String responseContentDisposition) {
        httpTool.setContentDisposition(responseContentDisposition);
        this.responseContentDisposition = responseContentDisposition;
    }

    public String getResponseContentEncoding() {
        return responseContentEncoding;
    }

    /**
     * OSSContent-Encoding header
     * 
     * @param responseContentEncoding
     */
    public void setResponseContentEncoding(String responseContentEncoding) {
        httpTool.setContentEncoding(responseContentEncoding);
        this.responseContentEncoding = responseContentEncoding;
    }

    /**
     * ???
     * @param {@link OSSObject}???
     * @return {@link OSSClientUtil}
     * @throws OSSException
     */
    public int getResult(OSSObject object) throws OSSException {
        int result = CloudUtil.CLOUDCLIENT_RESULT_OK;

        HttpResponse response = null;
        RandomAccessFile randomAccessFile = null;
        InputStream inputStream = null;
        object = new OSSObject(this.bucketName, this.objectKey);
        try {
            mLogMission.i("getResult", "before network request", missionObject);
            response = this.execute();
            mLogMission.i("getResult", "network response", missionObject);
            Header rangeHeader = response.getFirstHeader("Content-Range");
            if (rangeHeader != null) {
                String range = rangeHeader.getValue();
                mLogMission.i("getResult", "range:" + range.toString(), missionObject);
            }
            object.setObjectMetaData(OSSHttpTool.getObjectMetadataFromResponse(response));
            if (response.getEntity() != null) {
                mLogMission.i("getResult",
                        "the content length get from server:" + response.getEntity().getContentLength(),
                        missionObject);
                if (missionObject.getFileLength() <= 0L) {
                    missionObject.setFileLength(response.getEntity().getContentLength());
                    mLogMission.i("getResult",
                            "get content length and set file length. fileLength:" + missionObject.getFileLength(),
                            missionObject);
                }
                missionObject.setPaused(false);
                inputStream = response.getEntity().getContent();
                if (listener != null) {
                    listener.setTotalSize(missionObject.getFileLength());
                }
            }
            result = mDatabaseAccessManager.updateDownloadFile(missionObject);
            if (result != CloudUtil.CLOUDCLIENT_RESULT_OK) {
                return result;
            }

            randomAccessFile = new RandomAccessFile(filePath, "rwd");
            long offset = 0;
            if (range != null) {
                offset = range.getStart();
                mLogMission.i("getResult", "set offset before write file, offset:" + offset, missionObject);
            }
            randomAccessFile.seek(offset);
            mLogMission.i("getResult", "before write to local, file offset:" + offset, missionObject);
            byte[] buffer = new byte[1024 * 4];
            long readTotal = offset;
            int readLength = 0;
            while (true) {
                if (readTotal == missionObject.getFileLength()) {
                    missionObject.setFinished(true);
                    result = CloudUtil.CLOUDCLIENT_RESULT_OK;
                    mLogMission.i("getResult", "readTotal == missionObject's fileLength, readTotal:" + readTotal,
                            missionObject);
                    break;
                }
                if (listener != null && listener.isCancel()) {
                    missionObject.setPaused(true);
                    result = CloudUtil.CLOUD_FILE_MISSION_CANCEL;
                    mLogMission.i("getResult", "cancel download missionObject", missionObject);
                    break;
                }
                readLength = inputStream.read(buffer);
                mLogMission.i("getResult", "read buffer length:" + readLength, missionObject);
                if (readLength == -1) {
                    missionObject.setFinished(true);
                    result = CloudUtil.CLOUDCLIENT_RESULT_OK;
                    mLogMission.i("getResult", "buffer read finish, readLength:" + readLength, missionObject);
                    break;
                }

                mLogMission.i("getResult", "write to local, length:" + readLength, missionObject);
                randomAccessFile.write(buffer, 0, readLength);
                readTotal += readLength;
                mLogMission.i("getResult", "readTotal:" + readTotal, missionObject);
                missionObject.setTransferredLength(readTotal);
                missionObject.setLastTime(System.currentTimeMillis());
                //                result = mDatabaseAccessManager.updateDownloadFile(missionObject);
                //                if (result != CloudUtil.CLOUDCLIENT_RESULT_OK) {
                //                    break;
                //                }
                if (listener != null) {
                    listener.transferred(readTotal);
                }
            }
        } catch (OSSException osse) {
            throw osse;
        } catch (ParseException pe) {
            OSSException ossException = new OSSException(pe);
            ossException.setErrorCode(OSSErrorCode.PARSE_METADATA_ERROR);
            throw ossException;
        } catch (IOException ioe) {
            OSSException ossException = new OSSException(ioe);
            ossException.setErrorCode(OSSErrorCode.GET_ENTITY_CONTENT_ERROR);
            throw ossException;
        } finally {
            mDatabaseAccessManager.updateDownloadFile(missionObject);
            mLogMission.i("getResult", "finally, update db", missionObject);
            this.releaseHttpClient();
            if (randomAccessFile != null) {
                try {
                    inputStream.close();
                    randomAccessFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * ??? 
     * 
     * @return {@link OSSObject}???
     * @throws Exception
     * @see OSSObject
     */
    public OSSObject getResult() throws OSSException {
        HttpResponse r = null;
        OSSObject obj = new OSSObject(this.bucketName, this.objectKey);
        FileOutputStream fileOutputStream = null;
        InputStream inputStream;
        try {
            r = this.execute();

            obj.setObjectMetaData(OSSHttpTool.getObjectMetadataFromResponse(r));

            if (listener != null && r.getEntity() != null) {
                listener.setTotalSize(r.getEntity().getContentLength());
            }
            inputStream = r.getEntity().getContent();
            fileOutputStream = new FileOutputStream(filePath);
            byte[] buffer = new byte[1024 * 4];
            int readLength = 0;
            long readTotal = 0L;
            while ((readLength = inputStream.read(buffer)) != -1) {
                fileOutputStream.write(buffer, 0, readLength);
                readTotal += readLength;
                if (listener != null) {
                    listener.transferred(readTotal);
                }
            }
        } catch (OSSException osse) {
            throw osse;
        } catch (ParseException pe) {
            OSSException ossException = new OSSException(pe);
            ossException.setErrorCode(OSSErrorCode.PARSE_METADATA_ERROR);
            throw ossException;
        } catch (IOException ioe) {
            OSSException ossException = new OSSException(ioe);
            ossException.setErrorCode(OSSErrorCode.GET_ENTITY_CONTENT_ERROR);
            throw ossException;
        } finally {
            this.releaseHttpClient();
            if (fileOutputStream != null)
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }

        //        try {
        //            // 
        //            String algorithm = obj.getObjectMetaData().getAttrs()
        //                    .get(X_OSS_META_ENCRYPT);
        //            if (!Helper.isEmptyString(algorithm)) {
        //                if (Helper.isEmptyString(new String(decryptKey))) {
        //                    throw new IllegalArgumentException("decrypt should not be null");
        //                }
        //                data = CipherUtil.decrypt(data, decryptKey,
        //                        CipherAlgorithm.valueOf(algorithm));
        //            }
        //        } catch (IllegalArgumentException ie) {
        //            OSSException ossException = new OSSException(ie);
        //            ossException.setErrorCode(OSSErrorCode.DECRYPT_KEY_NOT_EMPTY);
        //            throw ossException;
        //        } catch (Exception e) {
        //            OSSException ossException = new OSSException(e);
        //            ossException.setErrorCode(OSSErrorCode.DECRYPT_ERROR);
        //            throw ossException;
        //        } finally {
        //            this.releaseHttpClient();
        //        }
        //
        //        try {
        //            // 
        //            String compressMethod = obj.getObjectMetaData().getAttrs()
        //                    .get(X_OSS_META_COMPRESS);
        //            if (!Helper.isEmptyString(compressMethod)
        //                    && compressMethod.equals("zip")) {
        //                data = CompressUtils.unzipBytes(data);
        //            }
        //            obj.setData(data);
        //        } catch (Exception e) {
        //            OSSException ossException = new OSSException(e);
        //            ossException.setErrorCode(OSSErrorCode.UNZIP_ERROR);
        //            throw ossException;
        //        } finally {
        //            this.releaseHttpClient();
        //        }

        return obj;
    }

    /** * @return the decryptKey */
    public byte[] getDecryptKey() {
        return decryptKey;
    }

    /** * @param decryptKey the decryptKey to set */
    public void setDecryptKey(byte[] decryptKey) {
        this.decryptKey = decryptKey;
    }

    public DatabaseAccessManager getDatabaseAccessManager() {
        return mDatabaseAccessManager;
    }

    public void setDatabaseAccessManager(DatabaseAccessManager mDatabaseAccessManager) {
        this.mDatabaseAccessManager = mDatabaseAccessManager;
    }
}