/**
* Tencent is pleased to support the open source community by making MSEC available.
*
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the GNU General Public 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
*
* https://opensource.org/licenses/GPL-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.
*/
//�����������̳߳���ִ�е�����
//��ں�����run()
package ngse.remote_shell;
import org.codehaus.jackson.map.ObjectMapper;
import org.json.JSONObject;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
/**
* Created by Administrator on 2016/2/4.
*/
public class Worker implements Runnable {
private Socket socket;//����ǰ�����ӵ�socket
public Worker(Socket s)
{
socket = s;
}
private void returnErrorMessage(String msg)
{
JsonRPCResponseBase r = new JsonRPCResponseBase();
ObjectMapper objectMapper = new ObjectMapper();
r.setMessage(msg);
r.setStatus(100);
try {
String s = objectMapper.writeValueAsString(r);
socket.getOutputStream().write(s.getBytes());
}
catch (Exception e)
{
e.printStackTrace();
return ;
}
}
//���÷�����ƣ�
// 1.��������json�ַ����е�handleClass�ֶΣ�ʵ����ʵ�ʵĴ�����
// 2. �Զ�������json�ַ���ʵ����Ϊjava�࣬�൱�ڲ������
// 3. �Զ�������ص�java��ʵ�������л�Ϊjson �ַ�������ΪӦ����ǰ��
private String handleRequest(String jsonStr, InputStream in, OutputStream out)
{
JSONObject jsonObject = new JSONObject(jsonStr);
String handleClassStr = jsonObject.getString("handleClass");
JSONObject requestBodyObj = jsonObject.getJSONObject("requestBody");
ObjectMapper objectMapper = new ObjectMapper();
try
{
Class<?> clazz = Class.forName(handleClassStr);
//ʵ����handle classָ������
JsonRPCHandler handler = (JsonRPCHandler) clazz.newInstance();
//��ø�������з������ҵ�exec����������
Method[] methods = clazz.getMethods();
boolean execFound = false;
for (int i = 0; i <methods.length ; i++) {
if (methods[i].getName().equals("exec")) {
execFound = true;
//exec�����IJ��������ͣ���json�����л�Ϊ�ò�����ʵ��
Class<?>[] paramTypes = methods[i].getParameterTypes();
if (paramTypes.length != 1)
{
returnErrorMessage("handle class's exec() method's param number is not 1!");
return "failed";
}
Object exec_request = objectMapper.readValue(requestBodyObj.toString(), paramTypes[0]);
//���exec�����ķ�������,Ҫ��̳���JsonRPCResponseBase
Class<?> returnType = methods[i].getReturnType();
String superClass = returnType.getSuperclass().getName();
if (superClass == null || !superClass.equals("ngse.remote_shell.JsonRPCResponseBase"))
{
returnErrorMessage("method exec() should return a class extending JsonRPCResponseBase.");
return "failed";
}
//����exec����,�������ص�java��ʵ�����л�Ϊjson�ַ�����Ӧ��ǰ��
try {
Object exec_result = methods[i].invoke(handler, exec_request);
if (exec_request != null) {
String s = objectMapper.writeValueAsString(exec_result);//???????bean???��??json?????
out.write(s.getBytes());
}
return "success";
} catch (InvocationTargetException e) {
e.printStackTrace();
return "failed";
}
}
}
if (!execFound)
{
return "exec method not found";
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
return "ClassNotFoundException:" + e.toString();
} catch (InstantiationException e)
{
e.printStackTrace();
return "InstantiationException:" + e.toString();
} catch (IllegalAccessException e)
{
e.printStackTrace();
return "IllegalAccessException:" + e.toString();
}
catch ( Exception e)
{
e.printStackTrace();
return "IllegalAccessException:" + e.toString();
}
return "failed";
}
//�������ж�ȡһ��������json�ַ���
private String readJsonString(StringBuffer jsonStr, InputStream in)
{
byte[] buf = new byte[10240];
try {
/*
//�ȶ�һ��json�ַ����ij��� 10�ֽڵ��ַ���
sum = 0;
while (sum < 10) {
len = in.read(buf, sum, 10-sum);
System.out.printf("read %d bytes\n", len);
if (len <= 0) {
return "read length failed!";
}
sum += len;
}
int jsonLen = new Integer(new String(buf, 0, 10).trim()).intValue();
//��json����
if (jsonLen > buf.length)
{
return "json string is too long";
}
sum = 0;
while (sum < jsonLen)
{
len = in.read(buf, sum, buf.length-sum);
System.out.printf("read %d bytes\n", len);
if (len == -1)
{
return "unexpected end of input";
}
sum += len;
}
jsonStr.append(new String(buf, 0, jsonLen));
*/
//����һֱ�����Զ˹ر�д
int offset = 0;
while (true)
{
if (offset >= buf.length)
{
return "buffer size is too small";
}
int len = in.read(buf, offset, buf.length-offset);
if (len < 0)
{
break;
}
offset += len;
}
jsonStr.append(new String(buf, 0, offset));
return "success";
}
catch (IOException e)
{
return e.toString();
}
}
@Override
public void run() {
try
{
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
StringBuffer jsonStr = new StringBuffer();
String resultStr = readJsonString(jsonStr, in);
if (!resultStr.equals("success"))
{
System.out.println(resultStr);
return;
}
System.out.println("json string:"+jsonStr.toString());
resultStr = handleRequest(jsonStr.toString(), in, out);
if (!resultStr.equals("success"))
{
System.out.println(resultStr);
return;
}
return;
}
catch (IOException e)
{
e.printStackTrace();
return;
}
finally {
System.out.println("close the socket.");
try { socket.close();} catch (Exception e){}
}
}
}