package cn.jcenterhome.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import cn.jcenterhome.service.DataBaseService;
public class XmlRpc{
private DataBaseService dataBaseService = (DataBaseService) BeanFactory.getBean("dataBaseService");
private HashMap<String,String> callBack;
private HashMap<String,Object> xmlMessage;
private String charSet;
private Integer timestamp;
private Map<String,Object> member;
private Map<String, Object> sGlobal;
private HttpServletRequest request;
private HttpServletResponse response;
public XmlRpc(HttpServletRequest request,HttpServletResponse response){
this.callBack=this.xmlRpcApi();
this.xmlMessage=new HashMap<String,Object>();
this.charSet=JavaCenterHome.jchConfig.get("charset");
this.request=request;
this.response=response;
this.sGlobal = (Map<String, Object>) request.getAttribute("sGlobal");
this.timestamp=(Integer)sGlobal.get("timestamp");
}
public XmlRpc(){
}
public XmlRpc xmlRpcSet(HttpServletRequest request,HttpServletResponse response) {
return new XmlRpc(request,response);
}
public void xmlrpcServer() throws Exception{
String data=readRequestInputStream();
if(Common.empty(data)) {
sendFault(1, "Invalid Method Call");
} else {
data =Common.addSlashes(data);
}
xmlMessage.put("structTypes", new Vector());
xmlMessage.put("structs", new Vector());
xmlMessage.put("struct_name", new Vector());
if(xmlrpcParse(data)){
Vector params=(Vector)xmlMessage.get("params");
Object result=xmlrpcCall(xmlMessage.get("methodname").toString(), params.toArray());
Map rxml = xmlrpcValue(result,null);
String outXml = xmlrpcValueXML(rxml);
outXml = "<methodResponse><params><param><value>"+outXml+"</value></param></params></methodResponse>";
outXml=Common.siconv(outXml, "UTF-8", charSet, charSet).toString();
xmlrpcOutXML(outXml);
}
}
private String sendFault(int code, String str) throws Exception{
response.setContentType("text/xml");
throw new Exception("<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
"<methodResponse><fault><value><struct><member><name>faultCode</name><value><i4>"
+code+
"</i4></value></member><member><name>faultString</name><value><string>"
+str+
"</string></value></member></struct></value></fault></methodResponse>");
}
private String readRequestInputStream(){
StringBuilder data= new StringBuilder();
BufferedReader br=null;
InputStreamReader isr=null;
try {
isr=new InputStreamReader((ServletInputStream)request.getInputStream(),"UTF-8");
br = new BufferedReader(isr);
String line = null;
while((line = br.readLine())!=null){
data.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(isr!=null){
isr.close();
isr=null;
}
if(br!=null){
br.close();
br=null;
}
} catch (Exception e) {
}
}
return data.toString();
}
private void xmlrpcOutXML(String xml) throws IOException{
xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+xml;
response.setHeader("Connection", "close");
response.setContentLength(Common.strlen(xml,charSet));
response.setContentType("text/xml");
String dateFormat = "E, d MMM yyyy HH:mm:ss Z";
response.setHeader("Date", Common.sgmdate(request, dateFormat, timestamp));
PrintWriter out = response.getWriter();
out.write(xml);
out.flush();
return;
}
private Object xmlrpcCall(String methodName, Object[] args) throws Exception{
String method =callBack.get(methodName);
if(method==null){
sendFault(1, "Invalid Method Call");
}
Class parameterTypes=Object[].class;
Object[] params={args};
Method m= this.getClass().getDeclaredMethod(method, parameterTypes);
return m.invoke(this,params);
}
private Map xmlrpcValue(Object data,String type) throws Exception{
Map value=new HashMap();
value.put("data", data);
if (Common.empty(type)) {
type = xmlrpcType(value);
}
value.put("type", type);
if("struct".equals(type)){
Map dataMap=(Map)value.get("data");
for (Object key : dataMap.keySet()) {
dataMap.put(key, xmlrpcValue(dataMap.get(key), null));
}
}
if("array".equals(type)){
Object[] datas=null;
if(value.get("data") instanceof Collection){
Collection dataCollection=(Collection)value.get("data");
datas=dataCollection.toArray();
}else{
datas=(Object[])value.get("data");
}
for (int i = 0,j=datas.length; i < j; i++) {
datas[i]=xmlrpcValue(datas[i], null);
}
value.put("data", datas);
}
return value;
}
private String xmlrpcType(Map value) {
Object data=value.get("data");
if (data instanceof Boolean) {
return "boolean";
}
if (data instanceof Double) {
return "double";
}
if (data instanceof Integer) {
return "int";
}
if(data instanceof byte[]){
return "base64";
}
if(data instanceof Date){
return "date";
}
if(Common.isArray(data)){
if(Common.empty(data)){
return "array";
}
if(data instanceof Map){
value.put("data", data);
return "struct";
}else{
return "array";
}
}
return "string";
}
private String xmlrpcValueXML(Map data){
Object type=data.get("type");
type=type==null ? type : type.toString();
if("boolean".equals(type)){
return "<boolean>"+ ((Boolean)data.get("data") ? "1" : "0")+"</boolean>";
}else if("int".equals(type)){
return "<int>"+data.get("data")+"</int>";
}else if("double".equals(type)){
return "<double>"+data.get("data")+"</double>";
}else if("string".equals(type)){
return "<string>"+Common.htmlSpecialChars(data.get("data")+"")+"</string>";
}else if("array".equals(type)){
String returnStr= "<array><data>";
Object[] datas=null;
if(data.get("data") instanceof Collection){
Collection dataCollection=(Collection)data.get("data");
datas=dataCollection.toArray();
}else{
datas=(Object[])data.get("data");
}
for (int i = 0,j=datas.length; i < j; i++) {
returnStr+="<value>"+xmlrpcValueXML((Map)datas[i])+"</value>";
}
returnStr+= "</data></array>";
return returnStr;
}else if("struct".equals(type)){
String returnStr= "<struct>";
Map dataMap=(Map)data.get("data");
for (Object name : dataMap.keySet()) {
returnStr+= "<member><name>"+name+"</name>";
returnStr+= "<value>"+xmlrpcValueXML((Map)dataMap.get(name))+"</value></member>";
}
returnStr+= "</struct>";
return returnStr;
}else if("date".equals(type)){
return "<dateTime.iso8601>"+((Map)data.get("data")).get("date")+"</dateTime.iso8601>";
}else if("base64".equals(type)){
return "<base64>"+Base64.encode(data.get("data").toString(), charSet)+"</base64>";
}
return "";
}
private boolean xmlrpcParse(String data) throws Exception{
data=data.replaceAll("<\\?xml(.*)?\\?>", "");
xmlMessage.put("messages", data);
if("".equals(Common.trim(data))){
return false;
}
Document document=DocumentHelper.parseText(data);;
Element rootElement = document.getRootElement();
List<Element> list = rootElement.elements();
xmltag_open(rootElement.getName());
xml_parse(list);
xmltag_close(rootElement.getName());
rootElement.clearContent();
document.clearContent();
return true;
}
private void xml_parse(List<Element> list){
for (Element e : list) {
List<Element> listChildern = e.elements();
if(listChildern.size()>0){
xmltag_open(e.getName());
xml_parse(listChildern);
xmltag_close(e.getQName().getQualifiedName());
}else{
xmltag_open(e.getName());
xml_data(e.getText());
xmltag_close(e.getQName().getQualifiedName());
}
}
}
private void xmltag_open(String tag){
xmlMessage.put("tag_content", "");
xmlMessage.put("last_open", tag);
if("methodCall".equals(tag) || "methodResponse".equals(tag) || "fault".equals(tag)){
xmlMessage.put("messageType", tag);
}else if("data".equals(tag)){
Vector structTypes=(Vector)xmlMessage.get("structTypes");
structTypes.add("array");
Vector structs=(Vector)xmlMessage.get("structs");
structs.add(new Vector());
}else if("struct".equals(tag)){
Vector structTypes=(Vector)xmlMessage.get("structTypes");
structTypes.add("struct");
Vector structs=(Vector)xmlMessage.get("structs");
structs.add(new HashMap());
}
}
private void xmltag_close(String tag){
boolean flag = false;
Object value=null;
String tag_content=Common.trim(xmlMessage.get("tag_content").toString());
if("int".equals(tag) || "i4".equals(tag)){
value = Common.intval(tag_content);
flag = true;
}else if("double".equals(tag)){
value = Double.valueOf(tag_content);
flag = true;
}else if("string".equals(tag)){
value = tag_content;
flag = true;
}else if("dateTime.iso8601".equals(tag)){
value = Common.strToTime(tag_content, Common.getTimeOffset(sGlobal, (Map<String, Object>) request.getAttribute("sConfig")));
flag = true;
}else if("value".equals(tag)){
if (!"".equals(tag_content) || "value".equals(xmlMessage.get("last_open"))) {
value = tag_content;
flag = true;
}
}else if("boolean".equals(tag)){
value = Boolean.valueOf(tag_content);
flag = true;
}else if("base64".equals(tag)){
value = Common.sAddSlashes(Base64.decode(tag_content, charSet));
flag = true;
}else if("data".equals(tag) || "struct".equals(tag)){
Vector structs=(Vector)xmlMessage.get("structs");
structs.remove(structs.size()-1);
value=structs;
Vector structTypes=(Vector)xmlMessage.get("structTypes");
structTypes.remove(structTypes.size()-1);
flag = true;
}else if("member".equals(tag)){
Vector struct_name=(Vector)xmlMessage.get("struct_name");
struct_name.remove(struct_name.size()-1);
}else if("name".equals(tag)){
Vector struct_name=(Vector)xmlMessage.get("struct_name");
struct_name.add(tag_content);
}else if("methodName".equals(tag)){
xmlMessage.put("methodname", tag_content);
}
if (flag) {
Vector structs=(Vector)xmlMessage.get("structs");
if (structs.size() > 0) {
Vector structTypes=(Vector)xmlMessage.get("structTypes");
if ("struct".equals(structTypes.get(structTypes.size()-1))) {
Vector struct_name=(Vector)xmlMessage.get("struct_name");
HashMap map=(HashMap)structs.get(structs.size()-1);
map.put(struct_name.get(struct_name.size()-1), value);
}else{
Vector v=(Vector)structs.get(structs.size()-1);
if(v==null){
v=new Vector();
structs.add(v);
}
v.add(value);
}
} else {
Vector params=(Vector)xmlMessage.get("params");
if(params==null){
params=new Vector();
xmlMessage.put("params", params);
}
params.add(value);
}
}
if (!Common.in_array(new String[]{"data", "struct", "member"},tag)) {
xmlMessage.put("tag_content", "");
}
}
private void xml_data(String data){
xmlMessage.put("tag_content", xmlMessage.get("tag_content").toString()+data);
}
private boolean authUser(String userName, String passWord) throws Exception{
userName = Common.addSlashes(Common.siconv(userName, charSet, "UTF-8", charSet).toString());
passWord = Common.addSlashes(Common.siconv(passWord, charSet, "UTF-8", charSet).toString());
Map<String, Object> member=Common.getPassPort(userName, passWord);
if(member.isEmpty()){
sendFault(1, "Authoried Error.Please check your password.");
return false;
}else{
this.member=member;
sGlobal.put("supe_uid", member.get("uid"));
this.member.put("username", Common.addSlashes(this.member.get("username").toString()));
sGlobal.put("supe_username", this.member.get("username"));
sGlobal.put("timestamp", timestamp);
return true;
}
}
private HashMap<String,String> xmlRpcApi() {
HashMap<String,String> api=new HashMap<String,String>();
api.put("metaWeblog.newPost", "newPost");
api.put("metaWeblog.editPost", "editPost");
api.put("metaWeblog.getPost", "getPost");
api.put("metaWeblog.newMediaObject", "newMediaObject");
api.put("metaWeblog.getCategories", "getCategories");
api.put("metaWeblog.getRecentPosts", "getRecentPosts");
api.put("mt.getCategoryList", "getCategoryList");
api.put("mt.setPostCategories", "setPostCategories");
api.put("blogger.getUsersBlogs", "getUserBlog");
api.put("blogger.getUserInfo", "getUserInfo");
api.put("blogger.deletePost", "deletePost");
api.put("blogger.getPost", "getPost");
api.put("blogger.getRecentPosts", "getRecentPosts");
api.put("blogger.newPost", "newPost");
api.put("blogger.editPost", "editPost");
return api;
}
private Object getRecentPosts(Object...args) throws Exception{
int num=50;
if(args.length>3){
num=Common.intval(args[3].toString());
}
String type=args[0].toString();
String userName=args[1].toString();
String passWord=args[2].toString();
authUser(userName, passWord);
int uid = (Integer)member.get("uid");
num=num < 1 ? num = 1 : num;
List<Map<String,Object>> struct=new ArrayList<Map<String,Object>>();
List<Map<String, Object>> blogList=dataBaseService.executeQuery("SELECT bf.message, b.blogid, b.subject, b.dateline FROM "+JavaCenterHome.getTableName("blog")+" b LEFT JOIN "+JavaCenterHome.getTableName("blogfield")+" bf ON bf.blogid=b.blogid WHERE b.uid ='"+uid+"' ORDER BY b.dateline DESC LIMIT 0,"+num);
for (Map<String, Object> item : blogList) {
Map<String, Object> tempMap=new HashMap<String, Object>();
tempMap.put("postid", item.get("blogid"));
tempMap.put("userid", uid);
tempMap.put("dateCreated", Common.sgmdate(request, "yyyyMMdd'T'HH:mm:ss", (Integer)item.get("dateline")));
tempMap.put("title", item.get("subject"));
tempMap.put("categories", new Object[]{item.get("classname")});
tempMap.put("description", item.get("message"));
tempMap.put("content", item.get("message"));
struct.add(tempMap);
}
return struct;
}
}