Package com.skyline.common.tag

Source Code of com.skyline.common.tag.PageTag

package com.skyline.common.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.skyline.common.bean.Page;

/**
* 分页标签
*
* @author wuqh
*/
public class PageTag extends TagSupport {
  private static final long serialVersionUID = 6328083803585909955L;
  private static final Log LOGGER = LogFactory.getLog(PageTag.class);
  /** 分页对象 */
  private Page page;
  /** 当前页的class(例如<span class="currentPage">中的currentPage) */
  private String curClass;
  /** 当前页的style */
  private String curStyle;
  /** 非前页的style */
  private String normalClass;
  /** 当前页的style */
  private String normalStyle;
  /** 围在页数外面的字符串(写法XX%sYY,例如 第%s页,最后会变成 第2页 这样) */
  private String decStr;
  /** 页面url(xxx.html/xxx.html?a=x&b=y) */
  private String url;
  /** 当前页是否显示链接(true则当前页也是<a>标签,否则为<span>) */
  private Boolean arcCur;
  /** 显示的最多页数(例如5,则显示1,2,3,4,5或者2,3,4,5,6等等) */
  private Integer maxSize;
  /** url是否含有参数,有就在原有的基础上加&curpage=x,否侧加?curpage=x */
  private boolean hasParam;
  /** 显示最前的maxSize页,即第一页在显示范围之内,且最后一页在显示范围之外 */
  private static final int START = 1;
  /** 显示中间的maxSize页,即第一页和后一页都在显示范围之外 */
  private static final int MIDDLE = 2;
  /** 显示最后的maxSize页,即第一页在显示范围之外,且最后一页在显示范围之内 */
  private static final int END = 3;
  /** 只显示maxSize页 */
  private static final int NONE = 0;
  /** 当前显示属于START、MIDDLE、END、NONE中的哪种 */
  private int type = NONE;

  @Override
  public int doEndTag() throws JspException {
    // 多于一页才显示分页
    if (null == page || 1 == page.getTotalPage()) {
      return SKIP_BODY;
    }
    String linkStr = generateTotalStr();
    try {
      pageContext.getOut().println(linkStr);
    } catch (IOException e) {
      LOGGER.warn("调用page出错", e);
    }
    setToDefault();
    return EVAL_BODY_INCLUDE;
  }

  private void setToDefault() {
    page = null;
    curClass = null;;
    curStyle = null;
    normalClass = null;
    normalStyle = null;;
    decStr = null;
    url = null;;
    arcCur = false;
    maxSize = 5;
    hasParam = false;
    type = NONE;
  }
 
  /**
   * 组合所有的链接,产生最后需要显示的链接
   */
  private String generateTotalStr() {
    StringBuilder builder = new StringBuilder();
    // 必须放第一位,只有它调用getIndexAarry,刷新type
    String mainLink = generateMainLinkStr();
    String firstLink = generateFirstLinkStr();
    String preLink = generatePreLinkStr();
    String nextLink = generateNextLinkStr();
    String lastLink = generateLastLinkStr();
    // 超链接格式为 [上一页][ 1(同主体的第一页) ... ]主体(即 1 2 3 等等)[ ... X(同主体的最后一页)][下一页]
    builder.append(preLink);
    builder.append(' ');
    builder.append(firstLink);
    builder.append(' ');
    if (!firstLink.equals("")) {
      builder.append("... ");
    }
    builder.append(mainLink);
    builder.append(' ');
    if (!lastLink.equals("")) {
      builder.append("... ");
    }
    builder.append(lastLink);
    builder.append(' ');
    builder.append(nextLink);
    return builder.toString();
  }

  /**
   * 产生上一页的链接(当前页非第一页才会有链接,否则为空串)
   *
   */
  private String generatePreLinkStr() {
    if (page.isFirst()) {
      return "";
    } else {
      return generateLinkStr(true, normalClass, normalStyle, page
          .getCurpage() - 1, url, "上一页");
    }
  }

  /**
   * 产生下一页的链接(当前页非最后页才会有链接,否则为空串)
   *
   */
  private String generateNextLinkStr() {
    if (page.isLast()) {
      return "";
    } else {
      return generateLinkStr(true, normalClass, normalStyle, page
          .getCurpage() + 1, url, "下一页");
    }
  }

  /**
   * 产生第一页的链接(第一页不在显示返回之内才产生)
   *
   */
  private String generateFirstLinkStr() {
    if (type == START || type == NONE) {
      return "";
    } else {
      return generateLinkStr(true, normalClass, normalStyle, 1, url,
          decStr);
    }
  }

  /**
   * 产生最后页的链接(最后页不在显示返回之内才产生)
   *
   */
  private String generateLastLinkStr() {
    if (type == END || type == NONE) {
      return "";
    } else {
      return generateLinkStr(true, normalClass, normalStyle, page
          .getTotalPage(), url, decStr);
    }
  }

  /**
   * 产生maxSize页的超链接
   */
  private String generateMainLinkStr() {
    Integer[] index = getIndexAarry(page, maxSize);
    StringBuilder linkStr = new StringBuilder();
    int length = index.length;
    for (int i = 0; i < length; i++) {
      if (index[i] == page.getCurpage()) {
        linkStr.append(generateLinkStr(arcCur, curClass, curStyle, page
            .getCurpage(), url, decStr));
      } else {
        linkStr.append(generateLinkStr(true, normalClass, normalStyle,
            index[i], url, decStr));
      }
      linkStr.append(' ');
    }
    return linkStr.toString();
  }

  /**
   * 产生某一页的超链接
   *
   * @param arcCur
   *            该页是否是超链接,是就用&lt;a&gt;否则用&lt;span&gt;
   * @param curClass
   *            该页的class属性
   * @param curStyle
   *            该页的style属性
   * @param curpage
   *            该页是第几页
   * @param url
   *            该页的超链接
   * @param decStr
   *            围在页数外面的字符串(写法XX%sYY,例如 第%s页,最后会变成 第2页 这样)
   */
  private String generateLinkStr(Boolean arcCur, String curClass,
      String curStyle, Integer curpage, String url, String decStr) {
    if (arcCur == null) {
      arcCur = false;
    }
    // 把decStr结合页码后产生的串
    String dec = curpage.toString();
    decStr = StringUtils.trimToNull(decStr);
    if (null != decStr) {
      dec = decStr.replace("%s", dec);
    }
    StringBuilder cur = new StringBuilder();
    if (arcCur) {
      // url是否含有参数,有就在原有的基础上加&curpage=x,否侧加?curpage=x
      cur.append("<a href=\"").append(url);
      if (hasParam) {
        cur.append('&');
      } else {
        cur.append('?');
      }
      cur.append("curpage=").append(curpage).append('\"');
    } else {
      cur.append("<span");
    }
    if (null != StringUtils.trimToNull(curClass)) {
      cur.append(" class=\"").append(curClass.trim()).append('\"');
    }
    if (null != StringUtils.trimToNull(curStyle)) {
      cur.append(" style=\"").append(curStyle.trim()).append('\"');
    }
    cur.append('>').append(dec).append("</");
    if (arcCur) {
      cur.append("a>");
    } else {
      cur.append("span>");
    }
    return cur.toString();
  }

  /**
   * 获取需要的页的数组(同时刷新type),比如:一共10页,最多显示5页,当前页为第6也,那么显示[4,5,6,7,8]这几页,如果当前页为9,那么显示[6,7,8,9,10]
   *
   * @param page
   *            分页类,用于获取总页数和当前页数
   * @param maxSize
   *            最多显示多少页
   */
  private Integer[] getIndexAarry(Page page, Integer maxSize) {
    int total = page.getTotalPage();
    int current = page.getCurpage();
    // 如果总页数小于最多显示页数,则全部显示
    if (total <= maxSize) {
      type = NONE;
      Integer[] index = new Integer[total];
      for (int i = 0; i < total; i++) {
        index[i] = i + 1;
      }
      return index;
    }

    /**
     * <pre>
     * 分情况讨论:
     * (1)、何时永远显示1...maxSize:
     *     如果maxSize为偶数,则当前页在1...maxSize/2时;
     *     如果maxSize为奇数,则当前页为1...(maxSize/2 +1)时,
     *     故得当前页为(maxSize + 1) / 2
     * (2)、何时永远显示最后maxSize页:
     *     不论奇偶,当前页在(total-maxSize/2)...total时
     * (3)、中间时从哪页开始显示:
     *     如果maxSize为偶数,则从 当前页-maxSize/2+1 开始显示
     *     如果maxSize为奇数,则从 当前页-maxSize/2 开始显示
     *     故从 当前页-(maxSize+1)/2+1 开始显示
     * </pre>
     */
    // 当前页靠前则middle=(maxSize + 1) / 2;否则middle = maxSize / 2;
    // 前面几页不需要动
    int middle = (maxSize + 1) / 2;
    if (current <= middle) {
      type = START;
      Integer[] index = new Integer[maxSize];
      for (int i = 0; i < maxSize; i++) {
        index[i] = i + 1;
      }
      return index;
    }
    // 后面几页也不需要动
    middle = maxSize / 2;
    if ((current + middle) >= total) {
      type = END;
      Integer[] index = new Integer[maxSize];
      for (int i = 0, value = (total - maxSize + 1); i < maxSize; i++, value++) {
        index[i] = value;
      }
      return index;
    }
    // 中间的需要动
    type = MIDDLE;
    middle = (maxSize + 1) / 2;
    Integer[] index = new Integer[maxSize];
    int startIndex = current - middle + 1;
    for (int i = 0; i < maxSize; i++, startIndex++) {
      index[i] = startIndex;
    }
    return index;
  }

  public void setPage(Page page) {
    this.page = page;
  }

  public void setCurClass(String curClass) {
    this.curClass = curClass;
  }

  public void setCurStyle(String curStyle) {
    this.curStyle = curStyle;
  }

  public void setNormalClass(String normalClass) {
    this.normalClass = normalClass;
  }

  public void setNormalStyle(String normalStyle) {
    this.normalStyle = normalStyle;
  }

  public void setUrl(String url) {
    this.url = url;
    if (url.indexOf('?') != -1) {
      hasParam = true;
    } else {
      hasParam = false;
    }
  }

  public void setArcCur(Boolean arcCur) {
    this.arcCur = arcCur;
  }

  public void setMaxSize(Integer maxSize) {
    this.maxSize = maxSize;
  }

  public void setDecStr(String decStr) {
    this.decStr = decStr;
  }

  public static void main(String... args) {
    Page page = new Page();
    page.setCurpage(4);
    page.setSize(20);
    page.setTotal(200);
    PageTag tag = new PageTag();
    tag.setPage(page);
    tag.setMaxSize(5);
    tag.setUrl("*.do");
    System.out.println();
    System.out.println(page.getCurpage());
    System.out.println(tag.generateMainLinkStr());
    System.out.println(tag.generatePreLinkStr());
    System.out.println(tag.generateNextLinkStr());
    System.out.println(tag.generateFirstLinkStr());
    System.out.println(tag.generateLastLinkStr());
    System.out.println(tag.generateTotalStr());
  }
}
 
TOP

Related Classes of com.skyline.common.tag.PageTag

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.