public class Client {
	private String appKey;	//APP_KEY
	private String appSecret;	//APP_SECREET
	
	public Client(String appKey, String appSecret) {
		if(StringUtil.isEmpty(appKey) || StringUtil.isEmpty(appSecret)) {
			throw new IllegalArgumentException("APP_KEY and APP_Secret must be not null.");
		}
		this.appKey = appKey;
		this.appSecret = appSecret;
	}
	
	public String getAppKey() {
		return appKey;
	}
	public void setAppKey(String appKey) {
		this.appKey = appKey;
	}
	public String getAppSecret() {
		return appSecret;
	}
	public void setAppSecret(String appSecret) {
		this.appSecret = appSecret;
	}
	@Override
	public String toString() {
		return "Client [appKey=" + appKey + ", appSecret=" + appSecret + "]";
	}
} public class RespConfig {

	public final static int RESP_OK = 0;
	
	public final static int FACESET_MAX_FACE = 10000;
	
} public class UrlConfig {
	
	public static final String CHART_SET = "UTF-8";

	public static final String BASE_URL = "https://apicn.faceplusplus.com/v2";
	
	//Face
	public static final String PATH_DETECT = "/detection/detect";
	
	//Person
	public static final String PATH_PERSON_CREATE = "/person/create";
	
	public static final String PATH_PERSON_DELETE = "/person/delete";
	
	public static final String PATH_PERSON_ADD_FACE = "/person/add_face";
	
	public static final String PATH_PERSON_REMOVE_FACE = "/person/remove_face";
	
	public static final String PATH_PERSON_SET_INFO = "/person/set_info";
	
	public static final String PATH_PERSON_GET_INFO = "/person/get_info";
	
	//Group
	public static final String PATH_GROUP_CREATE = "/group/create";
	
	public static final String PATH_GROUP_DELETE = "/group/delete";
	
	public static final String PATH_GROUP_ADD_PERSON = "/group/add_person";
	
	public static final String PATH_GROUP_REMOVE_PERSON = "/group/remove_person";
	
	public static final String PATH_GROUP_SET_INFO = "/group/set_info";
	
	public static final String PATH_GROUP_GET_INFO = "/group/get_info";
	
	//Faceset
	public static final String PATH_FACESET_CREATE = "/faceset/create";

	public static final String PATH_FACESET_DELETE = "/faceset/delete";
	
	public static final String PATH_FACESET_ADD_FACE = "/faceset/add_face";
	
	public static final String PATH_FACESET_REMOVE_FACE = "/faceset/remove_face";
	
	public static final String PATH_FACESET_SET_INFO = "/faceset/set_info";
	
	public static final String PATH_FACESET_GET_INFO = "/faceset/get_info";

	//Grouping
	public static final String PATH_GROUPING = "/grouping/grouping";
	
	//Info
	public static final String PATH_INFO_GET_IMAGE = "/info/get_image";
	
	public static final String PATH_INFO_GET_FACE = "/info/get_face";
	
	public static final String PATH_INFO_GET_PERSON_LIST = "/info/get_person_list";
	
	public static final String PATH_INFO_GET_FACESET_LIST = "/info/get_faceset_list";
	
	public static final String PATH_INFO_GET_GROUP_LIST = "/info/get_group_list";
	
	public static final String PATH_INFO_GET_SESSION = "/info/get_session";
	
	public static final String PATH_INFO_GET_QUOTA = "/info/get_quota";
	
	public static final String PATH_INFO_GET_APP = "/info/get_app";
	
	//train
	public static final String PATH_TRAIN_VERIFY = "/train/verify";

	public static final String PATH_TRAIN_SEARCH = "/train/search";
	
	public static final String PATH_TRAIN_IDENTIFY = "/train/identify";
	
	//recognition
	public static final String PATH_RECOGNITION_COMPARE = "/recognition/compare";
	
	public static final String PATH_RECOGNITION_VERIFY = "/recognition/verify";
	
	public static final String PATH_RECOGNITION_SEARCH = "/recognition/search";
	
	public static final String PATH_RECOGNITION_IDENTIFY = "/recognition/identify";
	
} public class Face implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8603825983713166688L;
	// face array 被检测出的人脸的列表
	private String face_id; //被检测出的每一张人脸都在Face++系统中的标识符
	private String face_data; //人脸本地截图的路径，如果有的话，没有为空
	private String img_id; //人脸相关的图片id
	private String url;	//相关图片的url
	
	private float width; // 0~100之间的实数，表示检出的脸的宽度在图片中百分比
	private float height; // 0~100之间的实数，表示检出的脸的高度在图片中百分比
	private PointF center; // 检出的人脸框的中心点坐标, x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	private PointF eye_left; // 相应人脸的左眼坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	private PointF eye_right; // 相应人脸的右眼坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	private PointF mouth_left; // 相应人脸的左侧嘴角坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	private PointF mouth_right; // 相应人脸的右侧嘴角坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	private PointF nose; // 相应人脸的鼻尖坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比 (0~100之间的实数)
	
	// attribute object 包含一系列人脸的属性分析结果 gender object 包含性别分析结果，value的值为Male/Female, confidence表示置信度
	private Gender gender;
	// age object 包含年龄分析结果，value的值为一个非负整数表示估计的年龄, range表示估计年龄的正负区间
	private Age age;
	// race object 包含人种分析结果，value的值为Asian/White/Black, confidence表示置信度
	private Race race;
	
	private String tag;	//人脸描述
	
	/**
	 * 被检测出的每一张人脸都在Face++系统中的标识符
	 * @return
	 */
	public String getFace_id() {
		return face_id;
	}

	/**
	 * 被检测出的每一张人脸都在Face++系统中的标识符
	 * @param face_id
	 */
	public void setFace_id(String face_id) {
		this.face_id = face_id;
	}
	
	

	/**
	 * 人脸本地截图的路径，如果有的话，没有为空
	 * @return the face_data
	 */
	public String getFace_data() {
		return face_data;
	}

	/**
	 * 人脸本地截图的路径，如果有的话，没有为空
	 * @param face_data the face_data to set
	 */
	public void setFace_data(String face_data) {
		this.face_data = face_data;
	}

	/**
	 * 人脸相关的图片id
	 * @return
	 */
	public String getImg_id() {
		return img_id;
	}

	/**
	 * 人脸相关的图片id
	 * @param img_id
	 */
	public void setImg_id(String img_id) {
		this.img_id = img_id;
	}
	
	/**
	 * 图片url
	 * @return the url
	 */
	public String getUrl() {
		return url;
	}
	/**
	 * 图片url
	 * @param url the url to set
	 */
	public void setUrl(String url) {
		this.url = url;
	}
	
	/**
	 * 0~100之间的实数，表示检出的脸的宽度在图片中百分比
	 * @return
	 */
	public float getWidth() {
		return width;
	}
	
	/**
	 * 0~100之间的实数，表示检出的脸的宽度在图片中百分比
	 * @param width
	 */
	public void setWidth(float width) {
		this.width = width;
	}
	
	/**
	 * 0~100之间的实数，表示检出的脸的高度在图片中百分比
	 * @return
	 */
	public float getHeight() {
		return height;
	}
	
	/**
	 * 0~100之间的实数，表示检出的脸的高度在图片中百分比
	 * @param height
	 */
	public void setHeight(float height) {
		this.height = height;
	}
	
	/**
	 * 检出的人脸框的中心点坐标, x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @return
	 */
	public PointF getCenter() {
		return center;
	}
	
	/**
	 * 检出的人脸框的中心点坐标, x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @param center
	 */
	public void setCenter(PointF center) {
		this.center = center;
	}
	/**
	 *  相应人脸的左眼坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @return
	 */
	public PointF getEye_left() {
		return eye_left;
	}
	
	/**
	 *  相应人脸的左眼坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @param eye_left
	 */
	public void setEye_left(PointF eye_left) {
		this.eye_left = eye_left;
	}
	
	/**
	 * 相应人脸的右眼坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @return
	 */
	public PointF getEye_right() {
		return eye_right;
	}
	
	/**
	 * 相应人脸的右眼坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @param eye_right
	 */
	public void setEye_right(PointF eye_right) {
		this.eye_right = eye_right;
	}
	
	/**
	 * 相应人脸的左侧嘴角坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @return
	 */
	public PointF getMouth_left() {
		return mouth_left;
	}
	
	/**
	 * 相应人脸的左侧嘴角坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @param mouth_left
	 */
	public void setMouth_left(PointF mouth_left) {
		this.mouth_left = mouth_left;
	}
	
	/**
	 * 相应人脸的右侧嘴角坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @return
	 */
	public PointF getMouth_right() {
		return mouth_right;
	}
	
	/**
	 * 相应人脸的右侧嘴角坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @param mouth_right
	 */
	public void setMouth_right(PointF mouth_right) {
		this.mouth_right = mouth_right;
	}
	
	/**
	 * 相应人脸的鼻尖坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比 (0~100之间的实数)
	 * @return
	 */
	public PointF getNose() {
		return nose;
	}
	/**
	 * 相应人脸的鼻尖坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比 (0~100之间的实数)
	 * @param nose
	 */
	public void setNose(PointF nose) {
		this.nose = nose;
	}
	

	/**
	 * 性别分析结果
	 * @return
	 */
	public Gender getGender() {
		return gender;
	}
	
	/**
	 * 性别分析结果
	 * @param gender
	 */
	public void setGender(Gender gender) {
		this.gender = gender;
	}
	
	/**
	 * 年龄分析结果
	 * @return
	 */
	public Age getAge() {
		return age;
	}
	
	/**
	 * 年龄分析结果
	 * @param age
	 */
	public void setAge(Age age) {
		this.age = age;
	}
	
	/**
	 * 人种分析结果
	 * @return
	 */
	public Race getRace() {
		return race;
	}
	
	/**
	 * 人种分析结果
	 * @param race
	 */
	public void setRace(Race race) {
		this.race = race;
	}
	
	

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Face [face_id=" + face_id + ", face_data=" + face_data
				+ ", img_id=" + img_id + ", url=" + url + ", width=" + width
				+ ", height=" + height + ", center=" + center + ", eye_left="
				+ eye_left + ", eye_right=" + eye_right + ", mouth_left="
				+ mouth_left + ", mouth_right=" + mouth_right + ", nose="
				+ nose + ", gender=" + gender + ", age=" + age + ", race="
				+ race + ", tag=" + tag + "]";
	}

	/**
	 * 人脸描述
	 * @return
	 */
	public String getTag() {
		return tag;
	}

	/**
	 * 人脸描述
	 * @param tag
	 */
	public void setTag(String tag) {
		this.tag = tag;
	}

	/**
	 * 性别
	 * @author xiaoying
	 */
	public static class Gender implements Serializable {
		/**
		 * 
		 */
		private static final long serialVersionUID = 3604771785466469504L;
		// gender object 包含性别分析结果，value的值为Male/Female, confidence表示置信度
		public String value; //值为Male/Female
		public float confidence; //置信度
		public String getValue() {
			return value;
		}
		public void setValue(String value) {
			this.value = value;
		}
		public float getConfidence() {
			return confidence;
		}
		public void setConfidence(float confidence) {
			this.confidence = confidence;
		}
		@Override
		public String toString() {
			return "Gender [value=" + value + ", confidence=" + confidence
					+ "]";
		}

	}

	/**
	 * 年龄
	 * @author xiaoying
	 */
	public static class Age implements Serializable {
		/**
		 * 
		 */
		private static final long serialVersionUID = 221737413026253122L;
		// age object 包含年龄分析结果，value的值为一个非负整数表示估计的年龄, range表示估计年龄的正负区间
		public int value;	//一个非负整数表示估计的年龄
		public int range;	//估计年龄的正负区间
		public int getValue() {
			return value;
		}
		public void setValue(int value) {
			this.value = value;
		}
		public int getRange() {
			return range;
		}
		public void setRange(int range) {
			this.range = range;
		}
		@Override
		public String toString() {
			return "Age [value=" + value + ", range=" + range + "]";
		}
		
	}

	/**
	 * 种族
	 * @author xiaoying
	 */
	public static class Race implements Serializable {
		/**
		 * 
		 */
		private static final long serialVersionUID = 888019375173484388L;
		// race object 包含人种分析结果，value的值为Asian/White/Black, confidence表示置信度
		public String value; //值为Asian/White/Black
		public float confidence; //置信度
		public String getValue() {
			return value;
		}
		public void setValue(String value) {
			this.value = value;
		}
		public float getConfidence() {
			return confidence;
		}
		public void setConfidence(float confidence) {
			this.confidence = confidence;
		}
		@Override
		public String toString() {
			return "Race [value=" + value + ", confidence=" + confidence + "]";
		}
		
	}
} public class Faceset implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 2977773864016787357L;
	private String faceset_name;	//相应Faceset的name
	private String faceset_id;	//相应Faceset的id
	private String tag;	//Faceset相关的tag
	private int face_count;	//这个Faceset下包含的face个数
	private List<Face> face;	//属于该faceset的face信息
	/**
	 * 相应Faceset的name
	 * @return the faceset_name
	 */
	public String getFaceset_name() {
		return faceset_name;
	}
	/**
	 * 相应Faceset的name
	 * @param faceset_name the faceset_name to set
	 */
	public void setFaceset_name(String faceset_name) {
		this.faceset_name = faceset_name;
	}
	/**
	 * 相应Faceset的id
	 * @return the faceset_id
	 */
	public String getFaceset_id() {
		return faceset_id;
	}
	/**
	 * 相应Faceset的id
	 * @param faceset_id the faceset_id to set
	 */
	public void setFaceset_id(String faceset_id) {
		this.faceset_id = faceset_id;
	}
	/**
	 * Faceset相关的tag
	 * @return the tag
	 */
	public String getTag() {
		return tag;
	}
	/**
	 * Faceset相关的tag
	 * @param tag the tag to set
	 */
	public void setTag(String tag) {
		this.tag = tag;
	}
	
	/**
	 * 这个Faceset下包含的face个数
	 * @return the face_count
	 */
	public int getFace_count() {
		return face_count;
	}
	/**
	 * 这个Faceset下包含的face个数
	 * @param face_count the face_count to set
	 */
	public void setFace_count(int face_count) {
		this.face_count = face_count;
	}
	/**
	 * 属于该faceset的face信息
	 * @return the face
	 */
	public List<Face> getFace() {
		return face;
	}
	/**
	 * 属于该faceset的face信息
	 * @param face the face to set
	 */
	public void setFace(List<Face> face) {
		this.face = face;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Faceset [faceset_name=" + faceset_name + ", faceset_id="
				+ faceset_id + ", tag=" + tag + ", face_count=" + face_count
				+ ", face=" + face + "]";
	}
} public class Group implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -5604871764437501922L;
	private String group_id;	//相应group的id
	private String group_name;	//相应group的name
	private String tag;	//group相关的tag
	private int person_count;	//Group包含的Person个数
	private List<Person> person;	//属于该group的person信息
	
	/**
	 * 相应group的id
	 * @return
	 */
	public String getGroup_id() {
		return group_id;
	}
	
	/**
	 * 相应group的id
	 * @param group_id
	 */
	public void setGroup_id(String group_id) {
		this.group_id = group_id;
	}
	
	/**
	 * 相应group的name
	 * @return
	 */
	public String getGroup_name() {
		return group_name;
	}
	
	/**
	 * 相应group的name
	 * @param group_name
	 */
	public void setGroup_name(String group_name) {
		this.group_name = group_name;
	}
	
	/**
	 * group相关的tag
	 * @return
	 */
	public String getTag() {
		return tag;
	}
	
	/**
	 * group相关的tag
	 * @param tag
	 */
	public void setTag(String tag) {
		this.tag = tag;
	}
	
	/**
	 * 
	 * @return the person_count
	 */
	public int getPerson_count() {
		return person_count;
	}

	/**
	 * 
	 * @param person_count the person_count to set
	 */
	public void setPerson_count(int person_count) {
		this.person_count = person_count;
	}

	/**
	 * 属于该group的person信息
	 * @return
	 */
	public List<Person> getPerson() {
		return person;
	}
	
	/**
	 * 属于该group的person信息
	 * @param person
	 */
	public void setPerson(List<Person> person) {
		this.person = person;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Group [group_id=" + group_id + ", group_name=" + group_name
				+ ", tag=" + tag + ", person_count=" + person_count
				+ ", person=" + person + ", getClass()=" + getClass()
				+ ", hashCode()=" + hashCode() + ", toString()="
				+ super.toString() + "]";
	}
} public class Person implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -7808261630401601077L;
	private String person_name;	//相应person的name
	private String person_id;	//相应person的id
	private String tag;			//person相关的tag
	
	private List<Face> face;	//添加到Person的Face
	
	private List<Group> group;	//已加入的Group
	
	/**
	 * 相应person的name
	 * @return
	 */
	public String getPerson_name() {
		return person_name;
	}
	
	/**
	 * 相应person的name
	 * @param person_name
	 */
	public void setPerson_name(String person_name) {
		this.person_name = person_name;
	}
	
	/**
	 * 相应person的id
	 * @return
	 */
	public String getPerson_id() {
		return person_id;
	}
	
	/**
	 * 相应person的id
	 * @param person_id
	 */
	public void setPerson_id(String person_id) {
		this.person_id = person_id;
	}
	
	/**
	 * person相关的tag
	 * @return
	 */
	public String getTag() {
		return tag;
	}
	
	/**
	 * person相关的tag
	 * @param tag
	 */
	public void setTag(String tag) {
		this.tag = tag;
	}
	
	/**
	 * 添加到Person的Face
	 * 只返回Face的face_id,tag
	 * @return
	 */
	public List<Face> getFace() {
		return face;
	}

	/**
	 * 添加到Person的Face
	 * 只返回Face的face_id,tag
	 * @param face
	 */
	public void setFace(List<Face> face) {
		this.face = face;
	}

	/**
	 * 已加入的Group
	 * 只返回Group的group_id,group_name,tag
	 * @return
	 */
	public List<Group> getGroup() {
		return group;
	}

	/**
	 * 已加入的Group
	 * 只返回Group的group_id,group_name,tag
	 * @param group
	 */
	public void setGroup(List<Group> group) {
		this.group = group;
	}

	@Override
	public String toString() {
		return "PersonGetInfoResp [person_name=" + person_name + ", person_id="
				+ person_id + ", tag=" + tag + ", face=" + face + ", group="
				+ group + "]";
	}
} public class InfoGetFaceReq extends BaseRequest {
	private String face_id;	//一组用逗号分割的face_id
	
	public InfoGetFaceReq() {
		
	}
	
	public InfoGetFaceReq(String face_id) {
		setFace_id(face_id);
	}

	/**
	 * 一组用逗号分割的face_id
	 * @return the face_id
	 */
	public String getFace_id() {
		return face_id;
	}

	/**
	 * 一组用逗号分割的face_id
	 * @param face_id the face_id to set
	 */
	public void setFace_id(String face_id) {
		this.face_id = face_id;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "InfoGetFaceReq [face_id=" + face_id + "]";
	}
	
} public class InfoGetImageReq extends BaseRequest {
	private String img_id;	//目标图片的img_id
	
	public InfoGetImageReq() {
		
	}
	
	public InfoGetImageReq(String img_id) {
		this.img_id = img_id;
	}

	/**
	 * 目标图片的img_id
	 * @return the img_id
	 */
	public String getImg_id() {
		return img_id;
	}

	/**
	 * 目标图片的img_id
	 * @param img_id the img_id to set
	 */
	public void setImg_id(String img_id) {
		this.img_id = img_id;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "InfoGetImageReq [img_id=" + img_id + "]";
	}
} public class InfoGetAppResp extends BaseResponse {
	private String name;//App的名称信息
	private String description;//App的描述信息
	/**
	 * 
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * 
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	/**
	 * 
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}
	/**
	 * 
	 * @param description the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "InfoGetAppResp [name=" + name + ", description=" + description
				+ ", error=" + error + ", error_code=" + error_code + "]";
	}
} public class InfoGetFaceResp extends BaseResponse {

	private List<FaceInfo> face_info; //人脸相关信息
	
	/**
	 * 人脸相关信息
	 * @return the face_info
	 */
	public List<FaceInfo> getFace_info() {
		return face_info;
	}

	/**
	 * 人脸相关信息
	 * @param face_info the face_info to set
	 */
	public void setFace_info(List<FaceInfo> face_info) {
		this.face_info = face_info;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "InfoGetFaceResp [face_info=" + face_info + ", error=" + error
				+ ", error_code=" + error_code + "]";
	}

	public static class FaceInfo {
		private Face face;	//人脸信息
		private List<Person> person;	//包含该face的Person信息
		private List<Faceset> faceset;	//包含该face的faceset信息
		
		
		/**
		 * 人脸信息
		 * @return
		 */
		public Face getFace() {
			return face;
		}
		
		/**
		 * 人脸信息
		 * @param face
		 */
		public void setFace(Face face) {
			this.face = face;
		}

		/**
		 * 包含该face的Person信息
		 * @return the person
		 */
		public List<Person> getPerson() {
			return person;
		}
		/**
		 * 包含该face的Person信息
		 * @param person the person to set
		 */
		public void setPerson(List<Person> person) {
			this.person = person;
		}
		/**
		 * 包含该face的faceset信息
		 * @return the faceset
		 */
		public List<Faceset> getFaceset() {
			return faceset;
		}
		/**
		 * 包含该face的faceset信息
		 * @param faceset the faceset to set
		 */
		public void setFaceset(List<Faceset> faceset) {
			this.faceset = faceset;
		}

		@Override
		public String toString() {
			return "FaceInfo [face=" + face + ", person=" + person
					+ ", faceset=" + faceset + "]";
		}
		
	}
} public static class FaceInfo {
	private Face face;	//人脸信息
	private List<Person> person;	//包含该face的Person信息
	private List<Faceset> faceset;	//包含该face的faceset信息
		
		
	/**
	 * 人脸信息
	 * @return
	 */
	public Face getFace() {
		return face;
	}
		
	/**
	 * 人脸信息
	 * @param face
	 */
	public void setFace(Face face) {
		this.face = face;
	}

	/**
	 * 包含该face的Person信息
	 * @return the person
	 */
	public List<Person> getPerson() {
		return person;
	}
	/**
	 * 包含该face的Person信息
	 * @param person the person to set
	 */
	public void setPerson(List<Person> person) {
		this.person = person;
	}
	/**
	 * 包含该face的faceset信息
	 * @return the faceset
	 */
	public List<Faceset> getFaceset() {
		return faceset;
	}
	/**
	 * 包含该face的faceset信息
	 * @param faceset the faceset to set
	 */
	public void setFaceset(List<Faceset> faceset) {
		this.faceset = faceset;
	}

	@Override
	public String toString() {
		return "FaceInfo [face=" + face + ", person=" + person
				+ ", faceset=" + faceset + "]";
	}
		
} public class InfoGetFacesetListResp extends BaseResponse {

	private List<Faceset> faceset;	//faceset列表

	/**
	 * faceset列表
	 * @return the faceset
	 */
	public List<Faceset> getFaceset() {
		return faceset;
	}

	/**
	 * faceset列表
	 * @param faceset the faceset to set
	 */
	public void setFaceset(List<Faceset> faceset) {
		this.faceset = faceset;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "InfoGetFacesetListResp [faceset=" + faceset + ", error="
				+ error + ", error_code=" + error_code + "]";
	}
	
} public class InfoGetGroupListResp extends BaseResponse {

	private List<Group> group;	//Group列表

	/**
	 * Group列表
	 * @return the group
	 */
	public List<Group> getGroup() {
		return group;
	}

	/**
	 * Group列表
	 * @param group the group to set
	 */
	public void setGroup(List<Group> group) {
		this.group = group;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "InfoGetGroupListResp [group=" + group + ", error=" + error
				+ ", error_code=" + error_code + "]";
	}
} public class InfoGetImageResp extends BaseResponse {
	private String img_id; //Face++系统中的图片标识符，用于标识用户请求中的图片
	private String url; //请求中图片的url
	private List<Face> face; //被检测出的人脸的列表
	/**
	 * 
	 * @return the img_id
	 */
	public String getImg_id() {
		return img_id;
	}
	/**
	 * 
	 * @param img_id the img_id to set
	 */
	public void setImg_id(String img_id) {
		this.img_id = img_id;
	}
	/**
	 * 
	 * @return the url
	 */
	public String getUrl() {
		return url;
	}
	/**
	 * 
	 * @param url the url to set
	 */
	public void setUrl(String url) {
		this.url = url;
	}
	/**
	 * 
	 * @return the face
	 */
	public List<Face> getFace() {
		return face;
	}
	/**
	 * 
	 * @param face the face to set
	 */
	public void setFace(List<Face> face) {
		this.face = face;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "InfoGetImageResp [img_id=" + img_id + ", url=" + url
				+ ", face=" + face + ", error=" + error + ", error_code="
				+ error_code + "]";
	}
} public class InfoGetPersonListResp extends BaseResponse {
	
	private List<Person> person; 	//person列表

	/**
	 * person列表
	 * @return the person
	 */
	public List<Person> getPerson() {
		return person;
	}

	/**
	 * person列表
	 * @param person the person to set
	 */
	public void setPerson(List<Person> person) {
		this.person = person;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "InfoGetPersonListResp [person=" + person + ", error=" + error
				+ ", error_code=" + error_code + "]";
	}
	
} public class InfoGetQuotaResp extends BaseResponse {
	private int total;	//当月quota使用上限额度
	private int used;	//已用quota
	private int exceed;	//超额使用量
	
	
	/**
	 * 当月quota使用上限额度
	 * @return the total
	 */
	public int getTotal() {
		return total;
	}


	/**
	 * 当月quota使用上限额度
	 * @param total the total to set
	 */
	public void setTotal(int total) {
		this.total = total;
	}


	/**
	 * 已用quota
	 * @return the used
	 */
	public int getUsed() {
		return used;
	}


	/**
	 * 已用quota
	 * @param used the used to set
	 */
	public void setUsed(int used) {
		this.used = used;
	}


	/**
	 * 超额使用量
	 * @return the exceed
	 */
	public int getExceed() {
		return exceed;
	}


	/**
	 * 超额使用量
	 * @param exceed the exceed to set
	 */
	public void setExceed(int exceed) {
		this.exceed = exceed;
	}


	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "InfoGetQuotaResp [total=" + total + ", used=" + used
				+ ", exceed=" + exceed + ", error=" + error + ", error_code="
				+ error_code + "]";
	}
} public class InfoGetSessionResp extends BaseResponse {
	private String session_id;	///相应请求的session标识符，可用于结果查询
	private int create_time;	///任务开始时间，单位：秒
	private int finish_time;	///任务结束时间，单位：秒
	private JSONObject result;	///返回session_id对应的结果内容
	private String status;	///可能取值有：INQUEUE(队列中), SUCC(成功) 和FAILED(失败)
	
	
	/**
	 * 相应请求的session标识符，可用于结果查询
	 * @return the session_id
	 */
	public String getSession_id() {
		return session_id;
	}


	/**
	 * 相应请求的session标识符，可用于结果查询
	 * @param session_id the session_id to set
	 */
	public void setSession_id(String session_id) {
		this.session_id = session_id;
	}


	/**
	 * 任务开始时间，单位：秒
	 * @return the create_time
	 */
	public int getCreate_time() {
		return create_time;
	}


	/**
	 * 任务开始时间，单位：秒
	 * @param create_time the create_time to set
	 */
	public void setCreate_time(int create_time) {
		this.create_time = create_time;
	}


	/**
	 * 任务结束时间，单位：秒
	 * @return the finish_time
	 */
	public int getFinish_time() {
		return finish_time;
	}


	/**
	 * 任务结束时间，单位：秒
	 * @param finish_time the finish_time to set
	 */
	public void setFinish_time(int finish_time) {
		this.finish_time = finish_time;
	}


	/**
	 * 返回session_id对应的结果内容
	 * @return the result
	 */
	public JSONObject getResult() {
		return result;
	}


	/**
	 * 返回session_id对应的结果内容
	 * @param result the result to set
	 */
	public void setResult(JSONObject result) {
		this.result = result;
	}


	/**
	 * 可能取值有：INQUEUE(队列中), SUCC(成功) 和FAILED(失败)
	 * @return the status
	 */
	public String getStatus() {
		return status;
	}


	/**
	 * 可能取值有：INQUEUE(队列中), SUCC(成功) 和FAILED(失败)
	 * @param status the status to set
	 */
	public void setStatus(String status) {
		this.status = status;
	}


	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "InfoGetSessionResp [session_id=" + session_id
				+ ", create_time=" + create_time + ", finish_time="
				+ finish_time + ", result=" + result + ", status=" + status
				+ ", error=" + error + ", error_code=" + error_code + "]";
	}
} public class HttpUtil {
	
	
	public static HttpResponse doPost(String actionPath, Map<String, Object> params) throws ClientProtocolException, IOException {
		DefaultHttpClient client = new DefaultHttpClient();
		HttpPost post = new HttpPost(UrlConfig.BASE_URL + actionPath);
		MultipartEntity mulEntity = new MultipartEntity();
		Set<String> keys = params.keySet();
		for (String key : keys) {
			Object obj = params.get(key);
			if (obj instanceof File && obj != null) {
				mulEntity.addPart(key, new FileBody((File) obj));
			} else {
				if(obj != null && !StringUtil.isEmpty(obj.toString())) {
					mulEntity.addPart(key, new StringBody(obj.toString(), Charset.forName(UrlConfig.CHART_SET)));
				}
			}
		}
		post.setEntity(mulEntity);
		return client.execute(post);
	}
} public class Log {
	
	private static boolean isPrint = true;
	
	public static void e(String msg) {
		if(isPrint) {
			System.err.println(msg);
		}
	}
	
	public static void i(String msg) {
		if(isPrint) {
			System.out.println(msg);
		}
	}
} public class StringUtil {
	public static boolean isEmpty(String str) {
		return str == null || str.equals("");
	}
}
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.xiaoying.faceplusplus.api.cliet.Client;
import com.xiaoying.faceplusplus.api.config.RespConfig;
import com.xiaoying.faceplusplus.api.config.UrlConfig;
import com.xiaoying.faceplusplus.api.entity.Face;
import com.xiaoying.faceplusplus.api.entity.Faceset;
import com.xiaoying.faceplusplus.api.entity.Group;
import com.xiaoying.faceplusplus.api.entity.Person;
import com.xiaoying.faceplusplus.api.entity.request.info.InfoGetFaceReq;
import com.xiaoying.faceplusplus.api.entity.request.info.InfoGetImageReq;
import com.xiaoying.faceplusplus.api.entity.response.info.InfoGetAppResp;
import com.xiaoying.faceplusplus.api.entity.response.info.InfoGetFaceResp;
import com.xiaoying.faceplusplus.api.entity.response.info.InfoGetFaceResp.FaceInfo;
import com.xiaoying.faceplusplus.api.entity.response.info.InfoGetFacesetListResp;
import com.xiaoying.faceplusplus.api.entity.response.info.InfoGetGroupListResp;
import com.xiaoying.faceplusplus.api.entity.response.info.InfoGetImageResp;
import com.xiaoying.faceplusplus.api.entity.response.info.InfoGetPersonListResp;
import com.xiaoying.faceplusplus.api.entity.response.info.InfoGetQuotaResp;
import com.xiaoying.faceplusplus.api.entity.response.info.InfoGetSessionResp;
import com.xiaoying.faceplusplus.api.utils.HttpUtil;
import com.xiaoying.faceplusplus.api.utils.Log;
import com.xiaoying.faceplusplus.api.utils.StringUtil;
/*
 * 文件名：InfoService.java
 * 版权：<版权>
 * 描述：<描述>
 * 创建人：xiaoying
 * 创建时间：2013-5-14
 * 修改人：xiaoying
 * 修改时间：2013-5-14
 * 版本：v1.0
 */

package com.xiaoying.faceplusplus.api.service;




/**
 * 功能：查询信息的服务类
 * @author xiaoying
 * 
 */
public class InfoService extends BaseService {

	/**
	 * @param client
	 */
	public InfoService(Client client) {
		super(client);
	}
	
	/**
	 * 获取一张image的信息, 包括其中包含的face等信息
	 * @param body
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetImageResp getImage(InfoGetImageReq body) throws ClientProtocolException, IOException, ParseException, JSONException {
		if(StringUtil.isEmpty(body.getImg_id())) {
			throw new IllegalArgumentException("img_id should not be null");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("img_id", body.getImg_id());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_IMAGE, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetImageResp result = new InfoGetImageResp();
		result.setImg_id(json.optString("img_id"));
		result.setUrl(json.optString("url"));
		result.setFace(getFaces(json.optJSONArray("face")));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	/**
	 * 给定一组Face，返回相应的信息(包括源图片, 相关的person等等)。
	 * @param body
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetFaceResp getFace(InfoGetFaceReq body) throws ClientProtocolException, IOException, ParseException, JSONException {
		if(StringUtil.isEmpty(body.getFace_id())) {
			throw new IllegalArgumentException("img_id should not be null");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("face_id", body.getFace_id());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_FACE, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetFaceResp result = new InfoGetFaceResp();
		result.setFace_info(getFaceInfo(json.optJSONArray("face_info")));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	/**
	 * 返回该App中的所有Person
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetPersonListResp getPersonList() throws ClientProtocolException, IOException, ParseException, JSONException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_PERSON_LIST, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetPersonListResp result = new InfoGetPersonListResp();
		result.setPerson(getPersons(json.optJSONArray("person")));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	/**
	 * 返回该App中的所有faceset
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetFacesetListResp getFacsetList() throws ClientProtocolException, IOException, ParseException, JSONException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_FACESET_LIST, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetFacesetListResp result = new InfoGetFacesetListResp();
		result.setFaceset(getFacesets(json.optJSONArray("faceset")));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}
	
	/**
	 * 返回这个App中的所有Group
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetGroupListResp getGroupList() throws ClientProtocolException, IOException, ParseException, JSONException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_GROUP_LIST, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetGroupListResp result = new InfoGetGroupListResp();
		result.setGroup(getGroups(json.optJSONArray("group")));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	/**
	 * 查获取session相关状态和结果
	 *
	 * 可能的status：INQUEUE(队列中), SUCC(成功) 和FAILED(失败)
	 * 当status是SUCC时，返回结果中还包含session对应的结果
	 * 所有session都将在计算完成72小时之后过期，并被自动清除。
	 * status返回值为SUCC仅表示成功取得运行结果，实际任务成功与否请根据result内容判断
	 * @param sessionId
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetSessionResp getSesson(String sessionId) throws ClientProtocolException, IOException, ParseException, JSONException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("session_id", sessionId);
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_SESSION, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetSessionResp result = new InfoGetSessionResp();
		result.setSession_id(json.optString("session_id"));
		result.setCreate_time(json.optInt("create_time"));
		result.setFinish_time(json.optInt("finish_time"));
		result.setStatus(json.optString("status"));
		result.setResult(json.optJSONObject("result"));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	/**
	 * 查询Quota使用情况简报
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetQuotaResp getQuota() throws ClientProtocolException, IOException, ParseException, JSONException {