@Override
  public EFilterResult doFilter(final PageRequestResponse rRequest, final FilterChain filterChain)
      throws IOException {
    if (rRequest.isHttpRequest()) {
      final String dk = Convert.toDateString(new Date(), "yyyy-MM-dd-HH");
      synchronized (stats) {
        PVStat stat = stats.get(dk);
        if (stat == null) {
          updateStats();
          stats.put(dk, stat = new PVStat());
        }

        stat.pv++;
        stat.ip.add(rRequest.getRemoteAddr());
        Object userId;
        final String sessionId = rRequest.getSessionId();
        if ((userId = rRequest.getLoginId()) != null) {
          if (!stat.uv.contains(sessionId)) {
            stat.uv.add(Convert.toString(userId));
          }
        } else {
          stat.uv.add(sessionId);
        }

        final int pt = Convert.toInt(rRequest.getSessionAttr(MVCConst.PAGELOAD_TIME));
        stat.averageTime += pt;

        if (stat.minTime == 0 || pt < stat.minTime) {
          stat.minTime = pt;
        }
        if (stat.maxTime == 0 || pt > stat.maxTime) {
          stat.maxTime = pt;
        }
      }
    }
    return EFilterResult.SUCCESS;
  }
 public static Collection<TransitionNode> getTransitions(
     final PageRequestResponse rRequest, final WorkitemBean workitem) {
   final ArrayList<TransitionNode> al = new ArrayList<TransitionNode>();
   final String[] transitions = StringUtils.split(rRequest.getParameter("transitions"));
   final ActivityComplete activityComplete = WorkitemComplete.get(workitem).getActivityComplete();
   // 通过手动方式选取的路由
   if (transitions != null && transitions.length > 0) {
     for (final String id : transitions) {
       final TransitionNode transition = activityComplete.getTransitionById(id);
       if (TransitionUtils.isTransitionManual(transition)) {
         al.add(transition);
       }
     }
   } else {
     al.addAll(activityComplete.getTransitions());
   }
   return al;
 }