public class ArticleService {

	private DefaultHttpClient httpClient;
	private String host;
	private String returnFormat;
	private String appkey;
	private String auth; 
	
	public ArticleService(DefaultHttpClient httpClient, String host,
			String returnFormat, String appkey, String auth){
		this.httpClient = httpClient;
		this.host = host;
		this.returnFormat = returnFormat;
		this.appkey = appkey;
		this.auth = auth;
	}
	
	/**
	 * 获取指定文章的信息
     * 可选参数：mode
	 * @param boardName 合法的版面名称
	 * @param id 文章或主题的id
	 * @return 文章元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Article getArticle(String boardName, int id, ParamOption params) throws JSONException,
            NForumException, IOException {
		String url = host + "article/" + boardName + "/"+ id + returnFormat + appkey
				+ params;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Article.parse(getMethod.getJSON());
	}
	
	/**
	 * 获取指定主题的信息
     * 可选参数 au, count, page
	 * @param boardName 合法的版面名称
	 * @param id 文章或主题的id
	 * @return 文章元数据，以及该元数据还包括以下两个属性：当前主题包含的文章元数据数组，和当前主题分页信息
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Threads getThreads(String boardName, int id, ParamOption params) throws 
	        JSONException, NForumException, IOException {
		String url = host + "threads/" + boardName + "/"+ id + returnFormat + appkey
				+ params;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Threads.parse(getMethod.getJSON());
	}
	
	/**
	 * 发布新文章/主题
     * 可选参数：reid, signature, email, anonymous, outgo
	 * @param boardName 合法的版面名称
	 * @param title 新文章的标题
	 * @param content 新文章的内容，可以为空
	 * @return 已发表的文章元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Article postArticle(String boardName, String title, String content, ParamOption params) throws
			JSONException, NForumException, IOException {
		String url = host + "article/" + boardName + "/post"  + returnFormat + appkey;
        params.addParams("title", title);
        if (null != content) {
            params.addParams("content", content);
        }
        PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return Article.parse(postMethod.postJSON());
	}

	/**
	 * 转寄指定文章/主题
     * 可选参数 threads, noref, noatt, noansi, big5
	 * @param boardName 合法的版面名称
	 * @param id 文章或主题id
	 * @param target 合法的用户id
	 * @return 所转寄的文章/主题元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Article forwardArticle(String boardName, int id, String target, ParamOption params)
            throws JSONException, NForumException, IOException {
		String url = host + "article/" + boardName + "/forward/" + id + returnFormat + appkey;
        params.addParams("target", target);
		PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return Article.parse(postMethod.postJSON());
	}

	/**
	 * 转载指定文章
	 * @param boardName 合法的版面名称
	 * @param id 文章或主题id
	 * @param target 文章转载至的版面的名称
	 * @return 所转载的文章元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Article crossArticle(String boardName, int id, String target) throws
		    JSONException, NForumException, IOException {
		String url = host + "article/" + boardName + "/cross/" + id + returnFormat + appkey;
        ParamOption params = new ParamOption().addParams("target", target);
		PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return Article.parse(postMethod.postJSON());
	}

	/**
	 * 更新指定文章
	 * @param boardName 合法的版面名称
	 * @param id 文章或主题id
	 * @param title 修改后的文章标题
	 * @param content 修改后的文章内容
	 * @return 已更新的文章元数据
	 * @throws NForumException
	 * @throws IOException
	 */
	public Article updateArticle(String boardName, int id, String title, String content) throws
		    JSONException, NForumException, IOException {
		String url = host + "article/" + boardName + "/update/" + id + returnFormat + appkey;
        ParamOption params = new ParamOption()
                .addParams("title", title)
                .addParams("content", content);
		PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return Article.parse(postMethod.postJSON());
	}

	/**
	 * 删除指定文章
	 * @param boardName 合法的版面名称
	 * @param id 文章或主题id
	 * @return 已删除文章元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Article deleteArticle(String boardName, int id) throws JSONException,
            NForumException, IOException {
		String url = host + "article/" + boardName + "/delete/" + id + returnFormat + appkey;
		PostMethod postMethod = new PostMethod(httpClient, auth, url, new ParamOption());
		return Article.parse(postMethod.postJSON());
	}
}
 public class AttachmentService {
	
	private DefaultHttpClient httpClient;
	private String host;
	private String returnFormat;
	private String appkey;
	private String auth; 
	
	public AttachmentService(DefaultHttpClient httpClient, String host,
			String returnFormat, String appkey, String auth){
		this.httpClient = httpClient;
		this.host = host;
		this.returnFormat = returnFormat;
		this.appkey = appkey;
		this.auth = auth;
	}
	
	/**
	 * 获取附件信息
     * 可选参数：id，如果指定文章id则返回该文章的附件列表，
     * 否则(id=-1)返回当前用户上传文件的列表，当前用户的附件列表在下一次发文时会附加至新文章中
     * @param name 合法的版面名称
     * @return 返回指定文章的附件列表
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Attachment getAttachment(String name, ParamOption params) throws
		JSONException, NForumException, IOException {
        String url = host + "attachment/" + name;
        if (params.getParams().containsKey("id")) {
            url = url + "/" + params.getParams().get("id") + returnFormat + appkey;
        } else {
            url = url + returnFormat + appkey;
        }
        GetMethod getMethod = new GetMethod(httpClient, auth, url);
        return Attachment.parse(getMethod.getJSON());
    }

    /**
     * 添加新附件
	 * 可选参数：id，如果指定id则向该文章添加新附加，否则向当前用户的附件列表添加新附件
	 * @param boardName 合法的版面名称
	 * @param file 需上传的附件
	 * @return 用户空间/文章附件元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Attachment addAttachment(String boardName, File file, ParamOption params) throws JSONException,
		NForumException, IOException {
        String url = host + "attachment/" + boardName + "/add";
        if (params.getParams().containsKey("id")) {
            url = url + "/" + params.getParams().get("id") + returnFormat + appkey;
        } else {
            url = url + returnFormat + appkey;
        }
		FileBody fileBody = new FileBody(file);
		MultipartEntity mEntity = new MultipartEntity();
		mEntity.addPart("file", fileBody);
		PostMethod postMethod = new PostMethod(httpClient, auth, url, mEntity);
		return Attachment.parse(postMethod.postJSON());
	}
	
	/**
     * 删除附件
     * 可选参数：id，如果指定文章id则从该文章中删除附加，否则从当前用户的附件列表删除附件
	 * @param boardName 合法的版面名称
	 * @param file 需删除附件名
	 * @return 用户空间/文章附件元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Attachment delAttachment(String boardName, String file, ParamOption params) throws JSONException,
		NForumException, IOException {
		String url = host + "attachment/" + boardName + "/delete";
        if (params.getParams().containsKey("id")) {
            url = url + "/" + params.getParams().get("id") + returnFormat + appkey;
        } else {
            url = url + returnFormat + appkey;
        }
        params.addParams("file", file);
        PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return Attachment.parse(postMethod.postJSON());
	}
	
}
 public class BlacklistService {

	private DefaultHttpClient httpClient;
	private String host;
	private String returnFormat;
	private String appkey;
	private String auth; 
	
	public BlacklistService(DefaultHttpClient httpClient, String host,
			String returnFormat, String appkey, String auth){
		this.httpClient = httpClient;
		this.host = host;
		this.returnFormat = returnFormat;
		this.appkey = appkey;
		this.auth = auth;
	}
	
	/**
	 * 用户黑名单列表
     * 可选参数：count, page
	 * @return 黑名单结构体
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Blacklist getBlacklist(ParamOption params) throws JSONException,
		NForumException, IOException {
        String url = host + "blacklist/list" + returnFormat + appkey + params;
        GetMethod getMethod = new GetMethod(httpClient, auth, url);
        return Blacklist.parse(getMethod.getJSON());
    }

    /**
	 * 黑名单添加用户
	 * @param id 所要添加的用户ID
	 * @return 成功为true，不成功则抛出nForumException异常
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public boolean addBlacklist(String id) throws JSONException,
		NForumException, IOException {
		String url = host + "blacklist/add" + returnFormat + appkey;
        ParamOption params = new ParamOption().addParams("id", id);
		PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return postMethod.postJSON().getBoolean("status");
	}
	
	/**
	 * 黑名单删除用户
	 * @param id 所要删除的用户ID
	 * @return 成功为true，不成功则抛出nForumException异常
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public boolean delBlacklist(String id) throws JSONException,
	NForumException, IOException {
		String url = host + "blacklist/delete" + returnFormat + appkey;
        ParamOption params = new ParamOption().addParams("id", id);
		PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return postMethod.postJSON().getBoolean("status");
	}
	
}
 public class BoardService {
	
	private DefaultHttpClient httpClient;
	private String host;
	private String returnFormat;
	private String appkey;
	private String auth; 
	
	public BoardService(DefaultHttpClient httpClient, String host,
			String returnFormat, String appkey, String auth){
		this.httpClient = httpClient;
		this.host = host;
		this.returnFormat = returnFormat;
		this.appkey = appkey;
		this.auth = auth;
	}
	
	/**
	 * 获取指定版面的信息
     * 可选参数：mode, count, page
	 * @param name 合法的版面名称
	 * @return 版面元数据，以及在元数据含有以下两个属性：当前版面模式所包含的文章元数组，和当前版面模式分页信息
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Board getBoard(String name, ParamOption params) throws
		JSONException, NForumException, IOException {
		String url = host + "board/" + name + returnFormat + appkey + params;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Board.parse(getMethod.getJSON());
	}
}
 public class FavouriteService {

	private DefaultHttpClient httpClient;
	private String host;
	private String returnFormat;
	private String appkey;
	private String auth; 
	
	public FavouriteService(DefaultHttpClient httpClient, String host,
			String returnFormat, String appkey, String auth){
		this.httpClient = httpClient;
		this.host = host;
		this.returnFormat = returnFormat;
		this.appkey = appkey;
		this.auth = auth;
	}
	
	/**
	 * 获取收藏夹信息
	 * @param level 收藏夹层数，顶层为0
	 * @return 收藏夹结构体
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Favorite getFavourite(int level) throws JSONException,
		NForumException, IOException {
		String url = host + "favorite/" + level + returnFormat + appkey;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Favorite.parse(getMethod.getJSON());
	}
	
	/**
	 * 向收藏夹删除版面/目录
	 * @param level 收藏夹层数，顶层为0,
	 * @param name 新的版面或自定义目录，版面为版面name，如Flash；
	 * @param dir 是否为自定义目录 0不是，1是
	 * @return 收藏夹结构体
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Favorite addFavourite(int level, String name, int dir) throws
			JSONException, NForumException, IOException {
		String url = host + "favorite/add" + level + returnFormat + appkey;
        ParamOption params = new ParamOption()
                .addParams("name", name)
                .addParams("dir", dir);
		PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return Favorite.parse(postMethod.postJSON());
	}
	
	/**
	 * 从收藏夹删除版面/目录
	 * @param level 收藏夹层数，顶层为0,
	 * @param name 要删除的版面或自定义目录，版面为版面name，如Flash；
	 * @param dir 是否为自定义目录 0不是，1是
	 * @return 收藏夹结构体
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Favorite delFavourite(int level, String name, int dir) throws
            JSONException, NForumException, IOException {
		String url = host + "favorite/delete" + level + returnFormat + appkey;
        ParamOption params = new ParamOption()
                .addParams("name", name)
                .addParams("dir", dir);
		PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return Favorite.parse(postMethod.postJSON());
	}
}
 public class MailService {

    public static final String MAILBOX_INBOX = "inbox";
    public static final String MAILBOX_OUTBOX = "outbox";
    public static final String MAILBOX_RECYCLE = "deleted";

	private DefaultHttpClient httpClient;
	private String host;
	private String returnFormat;
	private String appkey;
	private String auth; 
	
	public MailService(DefaultHttpClient httpClient, String host,
			String returnFormat, String appkey, String auth){
		this.httpClient = httpClient;
		this.host = host;
		this.returnFormat = returnFormat;
		this.appkey = appkey;
		this.auth = auth;
	}
	
	/**
	 * 获取指定信箱信息
     * 可选参数：count, page
	 * @param boxName 只能为inbox|outbox|deleted中的一个，分别是收件箱|发件箱|回收站，
	 * 		建议使用MailService.MAILBOX_*常量
	 * @return 信箱元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Mailbox getMailbox(String boxName, ParamOption params) throws
		JSONException, NForumException, IOException {
		String url = host + "mail/"+ boxName + returnFormat + appkey + params;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Mailbox.parse(getMethod.getJSON());
	}
	
	/**
	 * 信箱属性信息，包括是否有新邮件
	 * @return 信箱元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Mailbox getMailboxInfo() throws
		JSONException, NForumException, IOException {
		String url = host + "mail/info" + returnFormat + appkey;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Mailbox.parse(getMethod.getJSON());
	}
	
	/**
	 * 获取指定信件信息
	 * @param boxName 只能为inbox|outbox|deleted中的一个，分别是收件箱|发件箱|回收站
	 * 			建议使用MailService.MAILBOX_*常量
	 * @param num 信件在信箱的索引,为信箱信息的信件列表中每个信件对象的index值
	 * @return 信件元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Mail getMail(String boxName, int num) throws
		JSONException, NForumException, IOException {
        String url = host + "mail/" + boxName + "/" + num + returnFormat + appkey;
        GetMethod getMethod = new GetMethod(httpClient, auth, url);
        return Mail.parse(getMethod.getJSON());
    }

    /**
	 * 发送新信件
     * 可选参数：title, content, signature, backup
	 * @param id 合法的用户id
	 * @return 发送成功返回true，失败则会报NForumException错误，包含错误的具体信息
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public boolean sendMail(String id, ParamOption params)
            throws JSONException, NForumException, IOException {
		String url = host + "mail/send" + returnFormat + appkey;
        params.addParams("id", id);
		PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return postMethod.postJSON().getBoolean("status");
	}
	
	/**
	 * 转寄指定邮箱的邮件
     * 可选参数：noansi, big5
	 * @param boxName 只能为inbox|outbox|deleted中的一个，分别是收件箱|发件箱|回收站，
	 * 			建议使用MailService.MAILBOX_*常量
	 * @param num 信件在信箱的索引,为信箱信息的信件列表中每个信件对象的index值
	 * @param target 合法的用户id
	 * @return 所转寄的邮件元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Mail forwardMail(String boxName, int num, String target, ParamOption params)
            throws JSONException, NForumException, IOException {
		String url = host + "mail/" + boxName + "/forward/" + num + returnFormat + appkey;
        params.addParams("target", target);
		PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return Mail.parse(postMethod.postJSON());
	}
	
	/**
	 * 回复指定信箱中的邮件
     * 可选参数：title, content, signature, backup
	 * @param boxName 只能为inbox|outbox|deleted中的一个，分别是收件箱|发件箱|回收站，
	 * 			建议使用MailService.MAILBOX_*常量
	 * @param num 信件在信箱的索引,为信箱信息的信件列表中每个信件对象的index值
	 * @return 所回复的邮件元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Mail replyMail(String boxName, int num, ParamOption params) throws JSONException,
            NForumException,IOException {
		String url = host + "mail/" + boxName + "/reply/" + num + returnFormat + appkey;
        params.addParams("boxName", boxName)
                .addParams("num", num);
		PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return Mail.parse(postMethod.postJSON());
	}
	
	/**
	 * 删除指定信件
	 * @param boxName 只能为inbox|outbox|deleted中的一个，分别是收件箱|发件箱|回收站，
	 * 			建议使用MailService.MAILBOX_*常量
	 * @param num 信件在信箱的索引,为信箱信息的信件列表中每个信件对象的index值
	 * @return 已删除的信件元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Mail deleteMail(String boxName, int num) throws
		JSONException, NForumException,IOException {
		String url = host + "mail/" + boxName + "/delete/" + num + returnFormat + appkey;
        ParamOption params = new ParamOption()
                .addParams("boxName", boxName)
                .addParams("num", num);
		PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return Mail.parse(postMethod.postJSON());
	}
}
 public class ReferService {

    public static final String TYPE_AT = "at";
    public static final String TYPE_REPLY = "reply";

	private DefaultHttpClient httpClient;
	private String host;
	private String returnFormat;
	private String appkey;
	private String auth; 
	
	public ReferService(DefaultHttpClient httpClient, String host,
			String returnFormat, String appkey, String auth){
		this.httpClient = httpClient;
		this.host = host;
		this.returnFormat = returnFormat;
		this.appkey = appkey;
		this.auth = auth;
	}
	
	/**
	 * 获取指定提醒类型列表
     * 可选参数：count, page
	 * @param type 只能为at|reply中的一个，分别是@我的文章和回复我的文章，
	 * 				ReferService.TYPE_*常量
	 * @return 提醒结构体
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Refer getRefer(String type, ParamOption params) throws JSONException,
		NForumException, IOException {
        String url = host + "refer/" + type + returnFormat + appkey + params;
        GetMethod getMethod = new GetMethod(httpClient, auth, url);
        return Refer.parse(getMethod.getJSON());
    }

    /**
	 * 获取指定类型提醒的属性信息
	 * @param type 只能为at|reply中的一个，分别是@我的文章和回复我的文章，
	 * 			ReferService.TYPE_*常量
	 * @return 提醒结构体
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Refer getReferInfo(String type) throws JSONException,
	NForumException, IOException {
		String url = host + "refer/" + type + "/info" +returnFormat + appkey;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Refer.parse(getMethod.getJSON());
	}
	
	/**
	 * 设置指定提醒为已读
     * 可选参数：index
	 * @param type 只能为at|reply中的一个，分别是@我的文章和回复我的文章，
	 * 			ReferService.TYPE_*常量
	 * @return 已读的提醒元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Refer setReferRead(String type, ParamOption params) throws JSONException,
	NForumException, IOException {
        String url = host + "refer/" + type + "/setRead";
        if (params.getParams().containsKey("index")) {
            url = url + "/" + params.getParams().get("index");
        }
        url = url + returnFormat + appkey;
        PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
        return Refer.parse(postMethod.postJSON());
    }
	
	/**
	 * 删除指定提醒
     * 可选参数：index
	 * @param type 只能为at|reply中的一个，分别是@我的文章和回复我的文章，
	 * 			ReferService.TYPE_*常量
	 * @return 已读的提醒元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Refer deleteRefer(String type, ParamOption params) throws JSONException,
	NForumException, IOException {
        String url = host + "refer/" + type + "/delete";
        if (params.getParams().containsKey("index")) {
            url = url + "/" + params.getParams().get("index");
        }
		PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
		return Refer.parse(postMethod.postJSON());
	}
	
}
 public class SearchService {

	private DefaultHttpClient httpClient;
	private String host;
	private String returnFormat;
	private String appkey;
	private String auth; 
	
	public SearchService(DefaultHttpClient httpClient, String host,
			String returnFormat, String appkey, String auth){
		this.httpClient = httpClient;
		this.host = host;
		this.returnFormat = returnFormat;
		this.appkey = appkey;
		this.auth = auth;
	}
	
	/** 
	 * 搜索版面和目录，
	 * 支持中文关键词，参数编码请使用utf-8
	 * @param keyword 版面或目录的关键词或描述
	 * @return 搜索结果结构体
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Search searchBoard(String keyword) throws JSONException,
		NForumException, IOException {
		String board = URLEncoder.encode(keyword, "GBK");
        ParamOption params = new ParamOption().addParams("board", board);
        String url = host + "search/board" + returnFormat + appkey +params;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Search.parse(getMethod.getJSON());
	}
	
	/**
	 * 搜索单个版面的文章，
	 * 搜索结果为时间顺序，o参数为1显示所有非回复文章，如果主题帖被删则结果中不会有此主题，
	 * 但是在/search/threads中会显示此主题，搜索版面主题请尽量使用/search/threads，
     * 可选参数：title1, title2, titlen, author, day, m, a, o, count, page
	 * @param board 单个合法版面
	 * @return 搜索结果结构体
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Search searchArticle(String board, ParamOption params) throws
		JSONException,NForumException, IOException {
        params.addParams("board", board);
        String url = host + "search/article" + returnFormat + appkey + params;
        GetMethod getMethod = new GetMethod(httpClient, auth, url);
        return Search.parse(getMethod.getJSON());
    }

    /**
	 * 搜索单个版面的主题，
	 * 搜索结果为时间倒序，如果主题帖被删除则会显示回复文章，
	 * 搜索结果会受到搜索最大返回结果值的限制，
     * 可选参数：title1, title2, titlen, author, day, m, a, count, page
	 * @param board 单个合法版面
	 * @return 搜索结果结构体
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Search searchThreads(String board, ParamOption params) throws
			JSONException,NForumException, IOException {
        params.addParams("board", board);
		String url = host + "search/threads" + returnFormat + appkey + params;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Search.parse(getMethod.getJSON());
	}
	
}
 public class SectionService {
	
	private DefaultHttpClient httpClient;
	private String host;
	private String returnFormat;
	private String appkey;
	private String auth; 
	
	public SectionService(DefaultHttpClient httpClient, String host,
			String returnFormat, String appkey, String auth){
		this.httpClient = httpClient;
		this.host = host;
		this.returnFormat = returnFormat;
		this.appkey = appkey;
		this.auth = auth;
	}
	
	/**
	 * 获取所有根分区信息
	 * @return 根分区数量，和所有根分区元数据所组成的数组
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Section getSection() throws JSONException,
		NForumException, IOException {
		String url = host + "section" + returnFormat + appkey;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Section.parse(getMethod.getJSON());
	}
	
	/**
	 * 获取指定分区的信息
	 * @param name 合法的分区名称
	 * @return 当前分区包含的分区目录名数，和当前分区包含的版面元数据数组
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Section getSection(String name) throws JSONException,
		NForumException, IOException {
		String url = host + "section/"+ name + returnFormat + appkey;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Section.parse(getMethod.getJSON());
	}
	
}
 public class UserService {

	private DefaultHttpClient httpClient;
	private String host;
	private String returnFormat;
	private String appkey;
	private String auth; 
	
	public UserService(DefaultHttpClient httpClient, String host,
			String returnFormat, String appkey, String auth){
		this.httpClient = httpClient;
		this.host = host;
		this.returnFormat = returnFormat;
		this.appkey = appkey;
		this.auth = auth;
	}
	
	/**
	 * 获取指定用户的信息
	 * @param id 合法的用户id
	 * @throws IOException 
	 * @throws NForumException 
	 * @throws JSONException 
	 * */
	public User queryById(String id) throws JSONException,
		NForumException, IOException {
		String url = host + "user/query/" + id + returnFormat + appkey;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return User.parse(getMethod.getJSON());
	}
	
	/**
	 * 用户登录，
	 * 此API没有实际功能，可不需要调用
	 * @return 当前登录用户的元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public User login() throws JSONException,
		NForumException, IOException {
		String url = host + "user/login" + returnFormat + appkey;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return User.parse(getMethod.getJSON());
	}
	
	
	/**
	 * 用户退出
	 * @return 当前登录用户的元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public User logout() throws JSONException,
		NForumException, IOException {
		String url = host + "user/logout" + returnFormat + appkey;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return User.parse(getMethod.getJSON());
	}
} public class VoteService {

    public static final String CATEGORY_ME = "me";
    public static final String CATEGORY_JOIN = "join";
    public static final String CATEGORY_LIST = "list";
    public static final String CATEGORY_NEW = "new";
    public static final String CATEGORY_HOT = "hot";
    public static final String CATEGORY_ALL = "all";

	private DefaultHttpClient httpClient;
	private String host;
	private String returnFormat;
	private String appkey;
	private String auth; 
	
	public VoteService(DefaultHttpClient httpClient, String host,
			String returnFormat, String appkey, String auth){
		this.httpClient = httpClient;
		this.host = host;
		this.returnFormat = returnFormat;
		this.appkey = appkey;
		this.auth = auth;
	}
	
	/**
	 * 获取投票信息
	 * @param vid 投票vid
	 * @return 投票元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Vote getVote(int vid) throws JSONException,
		NForumException, IOException {
		String url = host + "vote/" + vid + returnFormat + appkey;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
        return Vote.parse(getMethod.getJSON());
	}


    /**
     * 投票操作（单选）
     *
     * @param vid  投票vid
     * @param viid 所提交的投票选项
     * @return 投票元数据
     * @throws JSONException
     * @throws NForumException
     * @throws IOException
     */
    public Vote vote(int vid, int viid) throws
            JSONException, NForumException, IOException {
        String url = host + "vote/" + vid + returnFormat + appkey;
        ParamOption params = new ParamOption()
                .addParams("vote", viid);
        PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
        return Vote.parse(postMethod.postJSON());
    }

    /**
     * 投票操作（多选）
     *
     * @param vid   投票vid
     * @param viids 所有提交的投票选项项的viid集合
     * @return 投票元数据
     * @throws JSONException
     * @throws NForumException
     * @throws IOException
     */
    public Vote vote(int vid, int[] viids) throws
            JSONException, NForumException, IOException {
        String url = host + "vote/" + vid + returnFormat + appkey;
        ParamOption params = new ParamOption();
        for (int i = 0; i < viids.length; i++) {
            params.addParams("vote[" + i + "]", viids[i]);
        }
        PostMethod postMethod = new PostMethod(httpClient, auth, url, params);
        return Vote.parse(postMethod.postJSON());
    }

    /**
	 * 获取投票列表
	 * @param category 投票列表类型，取值为me|join|list|new|hot|all，
	 *		建议使用VoteService.CATEGORY_*常量
	 * @return 投票元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Vote getVoteList(String category, ParamOption params) throws JSONException,
		NForumException, IOException {
		String url = host + "vote/category/" + category + returnFormat + appkey + params;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Vote.parse(getMethod.getJSON());
	}
	
}
 public class WidgetService {

	private DefaultHttpClient httpClient;
	private String host;
	private String returnFormat;
	private String appkey;
	private String auth; 
	
	public WidgetService(DefaultHttpClient httpClient, String host,
			String returnFormat, String appkey, String auth){
		this.httpClient = httpClient;
		this.host = host;
		this.returnFormat = returnFormat;
		this.appkey = appkey;
		this.auth = auth;
	}
	
	/**
	 * 获取十大热门话题的信息
	 * @return widget元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Widget getWidgetTopten() throws JSONException,
		NForumException, IOException {
		String url = host + "widget/topten" + returnFormat + appkey;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Widget.parse(getMethod.getJSON());
	}
	
	/** 获取推荐文章的信息
	 * @return widget元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Widget getWidgetRecommend() throws JSONException,
		NForumException, IOException {
		String url = host + "widget/recommend" + returnFormat + appkey;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Widget.parse(getMethod.getJSON());
	}
	
	/**
	 * 获取分区热门话题的信息
	 * @param sectionName 合法的分区名称
	 * @return widget元数据
	 * @throws JSONException
	 * @throws NForumException
	 * @throws IOException
	 */
	public Widget getWidgetSection(int sectionName) throws
		JSONException, NForumException, IOException {
		String url = host + "widget/section-" + sectionName + returnFormat + appkey;
		GetMethod getMethod = new GetMethod(httpClient, auth, url);
		return Widget.parse(getMethod.getJSON());
	}
} public class Host {
	public static final String HOST_BYR = "http://api.byr.cn/";
	public static final String HOST_BYR_TEST = "http://nforum.byr.edu.cn/byr/api/";
	public static final String HOST_TDRD = "http://napi.tdrd.org/";
	
	public static final String GUEST_USERNAME = "guest";
	public static final String GUEST_PASSWORD = "";
	
	public static final String RETURN_FORMAT_JSON = ".json";

}

import com.dss886.nForumSDK.util.Host;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.impl.client.DefaultHttpClient;
import com.dss886.nForumSDK.service.ArticleService;
import com.dss886.nForumSDK.service.AttachmentService;
import com.dss886.nForumSDK.service.BlacklistService;
import com.dss886.nForumSDK.service.BoardService;
import com.dss886.nForumSDK.service.FavouriteService;
import com.dss886.nForumSDK.service.MailService;
import com.dss886.nForumSDK.service.ReferService;
import com.dss886.nForumSDK.service.SearchService;
import com.dss886.nForumSDK.service.SectionService;
import com.dss886.nForumSDK.service.UserService;
import com.dss886.nForumSDK.service.VoteService;
import com.dss886.nForumSDK.service.WidgetService;
/*
 * Copyright (C) 2010-2014 dss886
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.dss886.nForumSDK;



/**
 * SDK主类，封装了一些参数设置函数，
 * 并能返回用于调用接口的对象
 * @author dss886
 * @since 2014-9-7
 */
public class NForumSDK {
	
	private DefaultHttpClient httpClient;
	private String host;
	private String appkey;
	private String auth;
	
	private String returnFormat = Host.RETURN_FORMAT_JSON;

    private int timeout = 10000;

	/**
	 * 需要appkey的构造函数
	 * @param host 需要包括完整的协议和尾部的斜杠，例如：http://api.byr.cn/，
	 * 			或者使用 Host.HOST_* 常量。
	 * @param appkey 不包含参数名"?appkey="和尾部多余的"&"字符
	 * @param username 用户名
	 * @param password 密码
	 */
	public NForumSDK(String host, String appkey, String username, String password){
		httpClient = new DefaultHttpClient();
        HttpParams param = httpClient.getParams();
        HttpConnectionParams.setConnectionTimeout(param, timeout);
        HttpConnectionParams.setSoTimeout(param, timeout);
        httpClient = new DefaultHttpClient(param);

        auth = new String(Base64.encodeBase64((username + ":" + password).getBytes()));
		this.host = host;
		this.returnFormat = returnFormat + "?";
		this.appkey = "&appkey=" + appkey;
	}
	
	/**
	 * 不需要appkey的构造函数
	 * @param host 需要包括完整的协议和尾部的斜杠，例如：http://api.byr.cn/，
	 * 			或者使用 HOST.HOST_* 常量。
	 * @param username 用户名
	 * @param password 密码
	 */
	public NForumSDK(String host, String username, String password) {
        httpClient = new DefaultHttpClient();
        HttpParams param = httpClient.getParams();
        HttpConnectionParams.setConnectionTimeout(param, timeout);
        HttpConnectionParams.setSoTimeout(param, timeout);
        httpClient = new DefaultHttpClient(param);

        auth = new String(Base64.encodeBase64((username + ":" + password).getBytes()));
        this.host = host;
        this.returnFormat = returnFormat + "?";
        this.appkey = "";
    }

    public int getTimeout() {
        return timeout;
    }

    /**
     * @param timeout 网络超时毫秒数
     */
    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    /**
	 * @return 用户接口封装对象
	 */
	public UserService getUserService(){