All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.leancloud.im.v2.messages.AVIMFileMessage Maven / Gradle / Ivy

package cn.leancloud.im.v2.messages;


import cn.leancloud.AVException;
import cn.leancloud.AVFile;
import cn.leancloud.AVLogger;
import cn.leancloud.callback.ProgressCallback;
import cn.leancloud.callback.SaveCallback;
import cn.leancloud.convertor.ObserverBuilder;
import cn.leancloud.core.PaasClient;
import cn.leancloud.im.v2.AVIMTypedMessage;
import cn.leancloud.im.v2.annotation.AVIMMessageField;
import cn.leancloud.im.v2.annotation.AVIMMessageType;
import cn.leancloud.utils.LogUtil;
import cn.leancloud.utils.StringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.reactivex.schedulers.Schedulers;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@AVIMMessageType(type = AVIMMessageType.FILE_MESSAGE_TYPE)
public class AVIMFileMessage extends AVIMTypedMessage {
  private static final AVLogger LOGGER = LogUtil.getLogger(AVIMFileMessage.class);

  static final String OBJECT_ID = "objId";
  static final String FILE_URL = "url";
  static final String FILE_META = "metaData";
  static final String FILE_SIZE = "size";
  public static final String FORMAT = "format";
  public static final String DURATION = "duration";
  private static final String LOCAL_PATH = "local_path";

  File localFile;
  AVFile actualFile;

  boolean hasAdditionalMetaAttr = false;

  @AVIMMessageField(name = "_lcfile")
  protected Map file;
  @AVIMMessageField(name = "_lctext")
  String text;
  @AVIMMessageField(name = "_lcattrs")
  Map attrs;

  ProgressCallback progressCallback;

  public AVIMFileMessage() {
  }

  public AVIMFileMessage(String localPath) throws IOException {
    this(new File(localPath));
  }

  public AVIMFileMessage(File localFile) throws IOException {
    this.localFile = localFile;
    actualFile = new AVFile(localFile.getName(), localFile);
    this.file = new HashMap();
    file.put(LOCAL_PATH, localFile.getPath());
  }

  public AVIMFileMessage(AVFile file) {
    this.actualFile = file;
  }

  public Map getFile() {
    return file;
  }

  /**
   * 获取本地文件地址,如果用户并未指定任何本地文件,则返回 null
   *
   * @return local file path.
   */
  public String getLocalFilePath() {
    return (null != localFile && localFile.exists() ? localFile.getPath() : null);
  }

  /**
   * 获取文件消息中得AVFile对象
   *
   * @return AVFile instance.
   */
  public AVFile getAVFile() {
    if (actualFile != null) {
      return actualFile;
    } else if (null != file && file.containsKey(FILE_URL)) {
      Map avfileMeta = null;
      if (file.containsKey(FILE_META)) {
        avfileMeta = (Map) file.get(FILE_META);
      }
      AVFile avfile = new AVFile(null, (String) file.get(FILE_URL), avfileMeta);
      if (file.containsKey(OBJECT_ID)) {
        avfile.setObjectId((String) file.get(OBJECT_ID));
      }
      return avfile;
    }
    return null;
  }

  public void attachAVFile(AVFile file) {
    this.actualFile = file;
  }

  protected void setFile(Map file) {
    this.file = file;
    Map metaData = (Map) file.get(FILE_META);
    actualFile = new AVFile(null, (String) file.get(FILE_URL), metaData);
    actualFile.setObjectId((String) file.get(OBJECT_ID));
    if (file.containsKey(LOCAL_PATH)) {
      this.localFile = new File((String) file.get(LOCAL_PATH));
    }
  }

  protected void setHasAdditionalMetaAttr(boolean hasAdditionalMetaAttr) {
    this.hasAdditionalMetaAttr = hasAdditionalMetaAttr;
  }

  /**
   * 获取文件地址
   *
   * @return file url.
   */
  public String getFileUrl() {
    if (file != null) {
      return (String) file.get(FILE_URL);
    } else {
      return null;
    }
  }

  /**
   * 获取文件的metaData
   *
   * @return meta data map.
   */
  public Map getFileMetaData() {
    if (file == null) {
      file = new HashMap();
    }
    Map meta;
    if (!file.containsKey(FILE_META)) {
      meta = new HashMap();
      meta.put(FILE_SIZE, actualFile.getSize());
      file.put(FILE_META, meta);
    } else {
      meta = (Map) file.get(FILE_META);
    }
    return meta;
  }

  /**
   * 获取文件大小
   *
   * @return file size.
   */
  public long getSize() {
    Map meta = getFileMetaData();
    if (meta != null && meta.containsKey(FILE_SIZE)) {
      return Long.parseLong(meta.get(FILE_SIZE).toString());
    }
    return 0;
  }

  protected void upload(final SaveCallback callback) {
    if (actualFile != null) {
      actualFile.saveInBackground().subscribeOn(Schedulers.io())
              .subscribe(ObserverBuilder.buildSingleObserver(new SaveCallback() {
        @Override
        public void done(AVException e) {
          if (e != null) {
            callback.internalDone(e);
          } else {
            fulFillFileInfo(callback);
          }
        }
      }));
    } else {
      callback.internalDone(new AVException(new RuntimeException("cannot find the file!")));
    }
  }

  /**
   * 设置文件上传进度回调
   *
   * @param callback callback function.
   */
  public void setProgressCallback(ProgressCallback callback) {
    this.progressCallback = callback;
  }

  public String getText() {
    return this.text;
  }

  public void setText(String text) {
    this.text = text;
  }

  public Map getAttrs() {
    return this.attrs;
  }

  public void setAttrs(Map attr) {
    this.attrs = attr;
  }

  protected void fulFillFileInfo(final SaveCallback callback) {
    // fulfill the file info map with AVFile
    if (actualFile != null) {
      file = getFile() == null ? new HashMap() : getFile();
      file.put(OBJECT_ID, actualFile.getObjectId());
      file.put(FILE_URL, actualFile.getUrl());
      file.remove(LOCAL_PATH);
      final Map metaData =
              getFileMetaData() == null ? new HashMap() : getFileMetaData();
      if (!metaData.containsKey(FILE_SIZE)) {
        metaData.put(FILE_SIZE, actualFile.getSize());
      }

      getAdditionalMetaData(metaData, new SaveCallback() {
        @Override
        public void done(AVException e) {
          file.put(FILE_META, metaData);
          if (callback != null) {
            callback.internalDone(e);
          }
        }
      });
    } else {
      callback.internalDone(new AVException(new RuntimeException("cannot find the file!")));
    }
  }

  /**
   * 判断是不是通过外部设置 url 来的 AVFile
   *
   * @param avFile AVFile instance.
   * @return flag indicating the parameter file is external or not.
   */
  static boolean isExternalAVFile(AVFile avFile) {
    return null != avFile
            && null != avFile.getMetaData()
            && avFile.getMetaData().containsKey("__source")
            && avFile.getMetaData().get("__source").equals("external");
  }

  protected String getQueryName() {
    return "";
  }

  protected void parseAdditionalMetaData(final Map meta, JSONObject response) {
    return;
  }

  protected void getAdditionalMetaData(final Map meta, final SaveCallback callback) {
    if (!this.hasAdditionalMetaAttr) {
      callback.internalDone(null);
    } else if (!StringUtil.isEmpty(actualFile.getUrl()) && localFile == null
              && !isExternalAVFile(actualFile)) {
      OkHttpClient client = PaasClient.getGlobalOkHttpClient();
      Request.Builder builder = new Request.Builder();
      final String url = actualFile.getUrl() + getQueryName();
      Call call = client.newCall(builder.url(url).get().build());
      call.enqueue(new Callback() {
        @Override
        public void onFailure(@NotNull Call call, @NotNull IOException e) {
          LOGGER.d("error encountered while accessing qiniu with url:" + url);
          callback.internalDone(null);
        }

        @Override
        public void onResponse(@NotNull Call call, @NotNull Response rawResponse) throws IOException {
          String content = rawResponse.body().string();
          com.alibaba.fastjson.JSONObject response = JSON.parseObject(content);
          parseAdditionalMetaData(meta, response);

          callback.internalDone(null);
        }
      });
    } else {
      callback.internalDone(null);
    }
  }

  public int hashCode() {
    return super.hashCode();
  }

  public boolean equals(Object other) {
    return super.equals(other);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy