/**
   * 短縮URLの取得
   *
   * @return
   * @throws Exception
   */
  public String getShortUrl(UserModel userModel, ActivityModel activityModel) throws Exception {

    // アプリ承認オブジェクトの生成
    GoogleCredential credential =
        new GoogleCredential.Builder()
            .setJsonFactory(JSON_FACTORY)
            .setTransport(TRANSPORT)
            .setClientSecrets(
                Constants.GOOGLE_PROJECT_CLIENT_ID, Constants.GOOGLE_PROJECT_CLIENT_SECRET)
            .build()
            .setRefreshToken(userModel.getRefreshToken());

    // Urlshortener オブジェクトの生成
    Urlshortener.Builder builder = new Urlshortener.Builder(TRANSPORT, JSON_FACTORY, credential);
    builder.setApplicationName(Constants.GOOGLE_APPLICATION_NAME);
    Urlshortener urlshortener = builder.build();

    // URLの設定
    Url url = new Url();
    url.setLongUrl(
        "http://plucial.com/u/"
            + userModel.getKey().getName()
            + "/a/"
            + activityModel.getKey().getName());

    // 短縮URLの発行
    url = urlshortener.url().insert(url).execute();

    return url.getId();
  }
  @Override
  protected Navigation execute(
      UserModel acsessUserModel, UserModel loginUserModel, boolean isLogin, boolean isSmartPhone)
      throws Exception {

    String activityId = asString("activityId");
    ActivityModel activityModel = ActivityService.getActivity(activityId);

    ArrayList<ActivityModel> activityList = new ArrayList<ActivityModel>();
    if (activityModel != null) {
      activityList.add(activityModel);
    }

    // リクエストスコープの設定
    requestScope("activityList", activityList);
    if (activityModel != null) {
      if (activityModel.getTitleString() != null) {
        requestScope(
            "pageTitle", activityModel.getTitleString() + " - " + acsessUserModel.getDisplayName());

      } else if (activityModel.isAttachmentsFlg()
          && activityModel.getAttachmentsDisplayNameString() != null) {
        requestScope(
            "pageTitle",
            activityModel.getAttachmentsDisplayNameString()
                + " - "
                + acsessUserModel.getDisplayName());

      } else {
        requestScope("pageTitle", "Google+での投稿 - " + acsessUserModel.getDisplayName());
      }
    }

    return forward("/responsive/activity_only.jsp");
  }
  @Override
  public Navigation run() throws Exception {

    UserModel userModel = null;

    try {
      userModel = getUser();
    } catch (Exception e) {
      return null;
    }
    ;

    // タスクは成功するまで実行されるため、失敗時は例外をキャッチして再実行をさせない
    try {
      // アクティビティの取得
      String activityId = asString("activityId");

      ActivityModel activityModel = ActivityService.getActivity(activityId);
      if (activityModel == null) return null;

      // 短縮URLの取得
      String shortUrl = getShortUrl(userModel, activityModel);

      // Twitter メッセージの作成
      String msg = getMessage(activityModel, shortUrl);

      // POST
      if (activityModel.getAttachmentsType() != null
          && (activityModel
                  .getAttachmentsType()
                  .getCategory()
                  .equals(Constants.GOOGLE_ACTIVITY_ATTACHMENTS_TYPE_PHOTO)
              || activityModel
                  .getAttachmentsType()
                  .getCategory()
                  .equals(Constants.GOOGLE_ACTIVITY_ATTACHMENTS_TYPE_ALBUM))
          && activityModel
              .getVerb()
              .getCategory()
              .equals(Constants.GOOGLE_ACTIVITY_VERB_TYPE_POST)) {

        // 自分が投稿した写真付きの場合もしくアルバム
        imageUpload(userModel, msg, activityModel.getAttachmentsImageUrlString());

      } else {
        postMessage(userModel, msg);
      }

    } catch (Exception e) {
      logger.severe(e.toString());
    }

    return null;
  }
  /**
   * Twitterの取得
   *
   * @throws IOException
   */
  private String getMessage(ActivityModel activityModel, String shortUrl) throws Exception {

    String twitterMessage = null;

    // 再共有の場合
    if (activityModel.getVerb().getCategory().equals(Constants.GOOGLE_ACTIVITY_VERB_TYPE_SHARE)) {
      // 追加コメントが存在しない場合
      if (activityModel.getAnnotationString() == null) {

        // タイトルが存在しない場合
        if (activityModel.getTitleString() == null) {
          return "[ #PluCial " + shortUrl + " ]";

          // タイトル存在する場合
        } else {
          twitterMessage = activityModel.getTitleString();
        }

        // 追加コメントが存在する場合
      } else {
        twitterMessage = activityModel.getAnnotationString();
      }

      // 通常投稿の場合
    } else {
      // タイトルが存在しない場合
      if (activityModel.getTitleString() == null) {

        // 添付コンテンツのタイトルが存在しない場合
        if (activityModel.getAttachmentsDisplayNameString() == null) {
          return "[ #PluCial " + shortUrl + " ]";

          // 添付コンテンツのタイトルが存在する場合
        } else {
          twitterMessage = activityModel.getAttachmentsDisplayNameString();
        }

        // タイトル存在する場合
      } else {
        twitterMessage = activityModel.getTitleString();
      }
    }

    if (twitterMessage == null) {
      return "[ #PluCial " + shortUrl + " ]";
    } else {
      // リンクタグを削除
      twitterMessage = Utils.removeLinkTags(twitterMessage);
      // 太文字を削除
      twitterMessage = Utils.removeBTags(twitterMessage);

      // 改行の変換
      twitterMessage = twitterMessage.replace("<br>", "\n");
      // spanタグを削除
      twitterMessage = Utils.removeSpanTags(twitterMessage);
    }

    String lastString = ("\n[ #PluCial " + shortUrl + " ]");
    int limit_num = 100;

    // 画像の場合はTwitterメディア分の23文字を減らす
    if (activityModel.getAttachmentsType() != null
        && (activityModel
                .getAttachmentsType()
                .getCategory()
                .equals(Constants.GOOGLE_ACTIVITY_ATTACHMENTS_TYPE_PHOTO)
            || activityModel
                .getAttachmentsType()
                .getCategory()
                .equals(Constants.GOOGLE_ACTIVITY_ATTACHMENTS_TYPE_ALBUM))
        && activityModel.getVerb().getCategory().equals(Constants.GOOGLE_ACTIVITY_VERB_TYPE_POST)) {
      limit_num = limit_num - 23;
    }

    // ドメイン分 の 23文字を削減
    int domainCount = getDomainCount(twitterMessage);
    limit_num = limit_num - (domainCount * 23);
    // URL複数含まれる投稿はマイナスになる可能性がある
    if (limit_num < 0) return "[ #PluCial " + shortUrl + " ]";

    // タイトルの文字数が問題ない場合
    if (twitterMessage.length() <= limit_num) return twitterMessage + lastString;

    // タイトルの文字数が制限オーバーの場合
    String message = twitterMessage.substring(0, limit_num - 3) + "...";
    return message + lastString;
  }