/** return HTML style weibo */
 @Override
 public String compositeWeibo(JcUser jcUser) {
   StringBuffer cs = new StringBuffer();
   URL url = null;
   String weibo = "";
   List<Status> statuses = weiboPersistenceService.getAllTop(jcUser);
   for (Status s : statuses) {
     LOG.debug("compositing weibo,status is:" + s.getId());
     String resource = "/templates/status.html";
     if (s.getRetweetedStatus() != null) {
       resource = "/templates/retweeted.html";
     }
     url = this.getClass().getResource(resource);
     try {
       cs.append(formatWeibo(url.toURI(), s));
     } catch (URISyntaxException e) {
       LOG.error(e.getMessage());
     }
   }
   url = this.getClass().getResource("/templates/weibo.html");
   try {
     weibo = DataUtil.readFlatFile(new File(url.toURI()));
   } catch (FileNotFoundException e) {
     LOG.error("not found file:/templates/weibo.html" + e);
   } catch (IOException e2) {
     LOG.error("occurred exception read file '/templates/weibo.html' \n" + e2);
   } catch (URISyntaxException e3) {
     LOG.error(e3.getMessage());
   }
   weibo = weibo.replaceAll("\\$\\{content\\}", cs.toString());
   return weibo;
 }
  public StatusWapper obtainWeibo(Timeline tm, JcUser jcUser, int page) {
    StatusWapper statusWapper = null;
    int i = 0;
    try {
      statusWapper = tm.getUserTimeline(COUNT_PER_PAGE, page, jcUser);
      LOG.debug(++callCount + "st call weibo api (now is userTimeline)");
    } catch (WeiboException e) {
      LOG.error("occured a exception when obtaining weibo use weibo api" + e);
      LOG.error(++callCount + "st call weibo api (now is comments) cause error");
      // outOfLimit = true;
      jcUser.setOutOfLimit(true);
      return null;
    }

    // download pictures and/or obtain comments
    List<Status> statuses = statusWapper.getStatuses();
    for (i = 0; i < statuses.size(); i++) {
      Status s = statuses.get(i);
      Place place = new Place();
      try {
        if (s.getLatitude() != -1 && s.getLongitude() != -1)
          s.setFormatedAddress(place.formattedAddress(s.getLatitude(), s.getLongitude()));
        else s.setFormatedAddress(null);
      } catch (Exception e) {
        LOG.error("occured a exception when format address " + e);
        LOG.error("try again");
        try {
          if (s.getLatitude() != -1 && s.getLongitude() != -1)
            s.setFormatedAddress(place.formattedAddress(s.getLatitude(), s.getLongitude()));
          else s.setFormatedAddress(null);
        } catch (Exception e2) {
          LOG.error("occured a exception when format address " + e2);
          s.setFormatedAddress(null);
        }
      }
      if (s.getCommentsCount() > 0) s.setComments(obtainComments(s));
      statuses.set(i, downloadImage(s));
      // if (callCount >= limit || outOfLimit == true)
      if (jcUser.isOutOfLimit()) break;
    }
    LOG.debug("this time get statues count is" + statuses.size());
    int index = 0;
    // if (callCount >= limit || outOfLimit == true)
    if (jcUser.isOutOfLimit()) index = i;
    else index = i + 1;
    int len = statuses.size();
    int times = len - index;
    for (int j = 0; j < times; j++) {
      Status s = statuses.remove(index);
      LOG.debug(
          "removing id:"
              + s.getId()
              + ", creatAt:"
              + StringUtil.formatDate(s.getCreatedAt(), "yyyy-MM-dd HH:mm"));
    }
    LOG.debug("after remove get statues count is" + statuses.size());
    LOG.debug("after remove get statusWapper.statues count is" + statusWapper.getStatuses().size());
    return statusWapper;
  }
 public List<Comment> obtainComments(Status s) {
   CommentWapper commentWapper = null;
   if (!jcUser.isBackupComment()) return null;
   try {
     commentWapper = c.getCommentById(s.getId());
     commentCount += commentWapper.getComments().size();
     LOG.debug(++callCount + "st call weibo api (now is comments)");
   } catch (WeiboException e) {
     LOG.error(
         "occured a exception when obtaining comments status'id="
             + s.getId()
             + ", Exception:"
             + e);
     LOG.error(++callCount + "st call weibo api (now is comments) cause error");
     // outOfLimit = true;
     jcUser.setOutOfLimit(true);
   }
   if (commentWapper != null) return commentWapper.getComments();
   else return null;
 }
    @Override
    public void run() {
      while (containUndeleted(statuses)) {
        LOG.debug("(Thread-" + Thread.currentThread().getName() + ")delete weibo");
        for (int i = 0; i < statuses.size(); i++) {
          Status s = statuses.get(i);
          if (s.isDeleted()) continue;
          Status ds = null;
          try {
            if (!outOfLimit) {
              LOG.debug("deleting " + (destroyedIndex + 1) + "st  weibos, status.id=:" + s.getId());
              ds = tm.Destroy(s.getId());
              s.setDeleted(true);
              statuses.set(
                  i, s); // in OOP(Object Oriented Programming), it will changes table(type of List)
              // which in repository(type of Map)
              // weiboPersistenceService.save(statues); in procedure oriented programming, it should
              // be save by PersistenceService;
              destroyedIndex++;
            } else {
              LOG.debug("not be deleted:status.id=" + s.getId());
            }

          } catch (WeiboException e) {
            String error = e.toString();
            if (error.indexOf("target weibo does not exist!") != -1)
              LOG.error(
                  "an error eccorred when delete weibo,status.id="
                      + s.getId()
                      + " this weibo does not exist");
            else if (error.indexOf("User requests out of rate limit!") != -1) {
              LOG.error(
                  "an error(\"User requests out of rate limit!\") eccorred when delete weibo,status.id="
                      + s.getId()
                      + "  "
                      + e);
              outOfLimit = true;
              //							ju.setOutOfLimit(true);
              //							jcUserPersistenceService.delete(ju);
              //							jcUserPersistenceService.save(ju);
              LOG.debug("follow ids are not be delete:");
            }
          }
        }
        if (outOfLimit == true) {
          //				if (!ju.isOutOfLimit()) {
          LOG.debug("take a break for a half hour,it has delete count=" + (destroyedIndex + 1));
          try {
            Thread.sleep(1800 * 1000);
            outOfLimit = false;
            //						ju.setOutOfLimit(true);
            //						jcUserPersistenceService.delete(ju);
            //						jcUserPersistenceService.save(ju);
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
        }
      }
      weiboPersistenceService.deleteStatuses(statuses);
      LOG.debug("(Thread-" + Thread.currentThread().getName() + ")delete completed.");
      LOG.debug("(Thread-" + Thread.currentThread().getName() + ")delete completed.");
    }
  public String formatWeibo(URI fileUri, Status status) {
    // String debugBeforeTemp = null;
    // String debugAfterTemp = null;
    String template = "";
    int begin;
    int end;

    try {
      template = DataUtil.readFlatFile(new File(fileUri));
    } catch (FileNotFoundException e) {
      LOG.debug("not found file:" + fileUri + "' \n" + e);
    } catch (IOException e2) {
      LOG.debug("occured exception read file '" + fileUri + "' \n" + e2);
    }

    begin = template.indexOf("${");
    end = template.indexOf("}", begin);
    while (begin != -1) {
      String name = template.substring(begin + 2, end);
      String value = "";
      try {
        LinkedList<String> names = new LinkedList<String>(Arrays.asList(name.split("\\.")));
        names.poll(); // remove string 'status'
        value = ReflectionUtil.getValue(status, names);
      } catch (NoSuchMethodException e1) {
        LOG.error("occured a exception status'id=" + status.getId() + ",:" + e1);
      } catch (IllegalAccessException e2) {
        LOG.error("occured a exception status'id=" + status.getId() + ",:" + e2);
      } catch (IllegalArgumentException e3) {
        LOG.error("occured a exception status'id=" + status.getId() + ",:" + e3);
      } catch (InvocationTargetException e4) {
        LOG.error("occured a exception status'id=" + status.getId() + ",:" + e4);
      } catch (NullPointerException e5) {
        LOG.error(
            "try to get value of '"
                + name
                + "' occured a exception status'id="
                + status.getId()
                + ",:"
                + e5);
      }
      name = name.replace(".", "\\u002E");
      // LOG.debug("regex:"+"\\$\\{"+name+"\\}");
      value = StringUtil.escapeChar(value);
      // debugBeforeTemp = temp;
      try {
        template = template.replaceFirst("\\u0024\\u007B" + name + "\\u007D", value);
        // debugAfterTemp = temp;
      } catch (IllegalArgumentException e) {
        // LOG.debug("temp which before replaced:"+debugBeforeTemp);
        // LOG.debug("replace value:"+value);
        // LOG.debug("temp which after replaced:"+debugAfterTemp);
        // throw e;
        LOG.error("occured exception when format weibo,status'id=" + status.getId() + ",:" + e);
        return "";
      }
      begin = template.indexOf("${");
      end = template.indexOf("}", begin);
    }
    return template;
  }