package com.bao.lc.site.sx;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.util.EntityUtils;
import com.bao.lc.AppConfig;
import com.bao.lc.bean.HttpResult;
import com.bao.lc.bean.IDValuePair;
import com.bao.lc.bean.ResultCode;
import com.bao.lc.client.BrowserClient;
import com.bao.lc.client.RequestBuilder;
import com.bao.lc.client.params.MiscParams;
import com.bao.lc.client.utils.HttpClientUtils;
import com.bao.lc.common.exception.ParseException;
import com.bao.lc.util.AppUtils;
import com.bao.lc.util.MiscUtils;
public class RjLogin
{
private static Log log = LogFactory.getLog(RjLogin.class);
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private static long MAX_TIME_DIFF = 1000 * 60 * 8;
private static int MAX_TRY_TIMES = 10;
private static final boolean isDebug = false;
private BrowserClient session = null;
private boolean isLogin = false;
private boolean isDestroyed = false;
private String user = null;
private String password = null;
private String department = null;
private String doc = null;
private int week = 5;
private int dayOfWeek = 5;
//System start time
private Calendar startTime = null;
//Expected register time
private Calendar registerTime = null;
//Expected time when we can start to register
private Calendar startRegTime = null;
//When we start
private Calendar ourStartRegTime = null;
public RjLogin(String user, String password, String department, String doc, int week, int dayOfWeek)
{
session = new BrowserClient();
isLogin = false;
isDestroyed = false;
this.user = user;
this.password = password;
this.department = department;
this.doc = doc;
this.week = week;
this.dayOfWeek = dayOfWeek;
Runtime.getRuntime().addShutdownHook(new ExitThread());
}
public IDValuePair get()
{
IDValuePair rc = ResultCode.RC_OK;
try
{
do
{
// 1. login
if(!login(user, password))
{
rc = ResultCode.RC_LOGIN_FAILED;
break;
}
// 2. query reglist
if(queryRegList(true) == ResultCode.RC_ALREADY_REGISTERED)
{
rc = ResultCode.RC_ALREADY_REGISTERED;
break;
}
updateTimes();
// Wait until we can start to work
waitToRegister();
//3.
int tryTime = 0, validTryTime = 0;
do
{
rc = register(department, doc, week, dayOfWeek);
if(rc == ResultCode.RC_OK || rc == ResultCode.RC_DOCTOR_REG_LIST_FULL)
{
break;
}
if(MiscUtils.diffWithNow(startRegTime) >= 0)
{
validTryTime++;
}
tryTime++;
String info = String.format("Try to register for %d, %d times. Result: %s.", tryTime, validTryTime, rc);
log.info(info);
if(MiscUtils.diffWithNow(startRegTime) >= MAX_TIME_DIFF)
{
rc = ResultCode.RC_TIMEOUT;
break;
}
if(validTryTime >= MAX_TRY_TIMES)
{
rc = ResultCode.RC_EXCEED_MAX_TRY_TIMES;
break;
}
}
while( true );
}
while(false);
}
catch(Exception e)
{
rc = ResultCode.RC_EXCEPTION_CAUGHT;
log.error(e.toString(), e);
}
finally
{
dispose();
}
log.info("Final Result: " + rc);
return rc;
}
public boolean login(String user, String password) throws ClientProtocolException, IOException,
ParseException
{
HttpResponse rsp = null;
Map<String, String> paramMap = new HashMap<String, String>();
String url = null;
// 1. main page
url = AppConfig.getInstance().getPropInternal("rjh.url.main");
rsp = session.execute(url);
// 2. login page
url = AppConfig.getInstance().getPropInternal("rjh.url.login");
rsp = session.execute(url);
String content = EntityUtils.toString(rsp.getEntity(), "GB2312");
parseLoginParameters(content, paramMap);
// 3. validation code
String validateToken = paramMap.get("ValidateToken");
url = AppConfig.getInstance().getPropInternal("rjh.url.validation_code") + validateToken;
rsp = session.execute(url);
String validationCodeImage = AppUtils.getTempFilePath("vcode.png");
HttpClientUtils.saveToFile(rsp.getEntity(), validationCodeImage);
// 4. show validation code
String validationCode = MiscUtils.getValidationCode(validationCodeImage);
if(validationCode == null)
{
return false;
}
// 5. post login
paramMap.put("TxtCode", validationCode);
paramMap.put("TxtLoginName", user);
paramMap.put("TxtPwd", password);
paramMap.remove("ValidateToken");
url = AppConfig.getInstance().getPropInternal("rjh.url.login");
MiscParams.setReferer(session.getParams(), url);
RequestBuilder rb = new RequestBuilder();
rb.method(HttpPost.METHOD_NAME).uriStr(url).paramMap(paramMap).encoding("GB2312");
rsp = session.execute(rb);
// Check login result
isLogin = (rsp.getStatusLine().getStatusCode() == 302);
log.info(String.format("User [%s] login %s.", user, (isLogin ? "succeeded" : "failed")));
HttpClientUtils.saveToFile(rsp.getEntity(), AppUtils.getTempFilePath("login_result.html"));
if(isLogin)
{
url = AppConfig.getInstance().getPropInternal("rjh.url.user_panel");
rsp = session.execute(url);
HttpClientUtils.saveToFile(rsp.getEntity(),
AppUtils.getTempFilePath("login_user_panel.html"));
}
else
{
String errorReason = parseLoginErrorReason(AppUtils
.getTempFilePath("login_result.html"));
log.info(errorReason);
}
return isLogin;
}
public IDValuePair queryRegList(boolean check) throws ClientProtocolException, IOException, ParseException
{
String url = null, content = null;
HttpResponse rsp = null;
IDValuePair rc = ResultCode.RC_OK;
do
{
// 1. open query page
url = AppConfig.getInstance().getPropInternal("rjh.url.query_reg_page");
MiscParams.setReferer(session.getParams(), AppConfig.getInstance().getPropInternal("rjh.url.user_panel"));
rsp = session.execute(url);
content = HttpClientUtils.saveToString(rsp.getEntity(), "GB2312");
if(rsp.getStatusLine().getStatusCode() != 200)
{
rc = new HttpResult(rsp.getStatusLine().getStatusCode(), url);
break;
}
// 2. do query
Map<String, String> paramMap = new HashMap<String, String>();
parseQueryRegListPage(content, paramMap);
RequestBuilder rb = new RequestBuilder();
rb.method(HttpPost.METHOD_NAME).uriStr(url).paramMap(paramMap).encoding("GB2312");
rsp = session.execute(rb);
HttpClientUtils.saveToFile(rsp.getEntity(), AppUtils.getTempFilePath("reg_result.html"));
if(rsp.getStatusLine().getStatusCode() != 200)
{
rc = new HttpResult(rsp.getStatusLine().getStatusCode(), url);
break;
}
List<RegInfo> regList = new ArrayList<RegInfo>();
parseRegListResult(AppUtils.getTempFilePath("reg_result.html"), regList);
log.info(regList);
if(check)
{
String mark = AppConfig.getInstance().getPropInternal("rjh.mark.reg_valid");
for(int i = 0, size = regList.size(); i < size; i++)
{
RegInfo regInfo = regList.get(i);
if(!regInfo.flagName.equals(mark))
{
continue;
}
if(!regInfo.department.contains(department))
{
continue;
}
if(!regInfo.doctorName.equals(doc))
{
continue;
}
Calendar regTime = MiscUtils.toCalendar(regInfo.regTime);
if(!MiscUtils.isSameDay(regTime, registerTime))
{
continue;
}
log.info("Successfully register: " + regInfo);
return ResultCode.RC_ALREADY_REGISTERED;
}
return ResultCode.RC_NO_MATCHED_RECORD;
}
}
while(false);
return rc;
}
public IDValuePair register(String department, String name, int week, int dayOfWeek) throws ClientProtocolException, IOException, ParseException
{
IDValuePair rc = ResultCode.RC_OK;
String url = null, content = null;
HttpResponse rsp = null;
Map<String, String> paramMap = new HashMap<String, String>();
do
{
//1. Get register page
url = AppConfig.getInstance().getPropInternal("rjh.url.reg_page");
MiscParams.setReferer(session.getParams(), AppConfig.getInstance().getPropInternal("rjh.url.user_panel"));
rsp = session.execute(url);
if(rsp.getStatusLine().getStatusCode() != 200)
{
rc = new HttpResult(rsp.getStatusLine().getStatusCode(), url);
break;
}
content = HttpClientUtils.saveToString(rsp.getEntity(), "GB2312");
//2. Query available register list
parseRegPageParameter(content, department, week, paramMap);
RequestBuilder rb = new RequestBuilder();
rb.method(HttpPost.METHOD_NAME).uriStr(url).paramMap(paramMap).encoding("GB2312");
rsp = session.execute(rb);
if(rsp.getStatusLine().getStatusCode() != 200)
{
rc = new HttpResult(rsp.getStatusLine().getStatusCode(), url,
HttpResult.HttpMethod.POST);
break;
}
content = HttpClientUtils.saveToString(rsp.getEntity(), "GB2312");
//3. Parse available register list
Map<Integer, List<RegDoctorInfo>> availMap = new HashMap<Integer, List<RegDoctorInfo>>();
parseAvailableRegList(content, availMap);
List<RegDoctorInfo> regDoctorInfoList = availMap.get(dayOfWeek);
if(regDoctorInfoList == null || regDoctorInfoList.isEmpty())
{
rc = ResultCode.RC_REG_LIST_EMPTY;
log.info("No available register doctors.");
break;
}
RegDoctorInfo regDoctorInfo = null;
for(int i = 0, size = regDoctorInfoList.size(); i < size; i++)
{
if(name.equals(regDoctorInfoList.get(i).name))
{
regDoctorInfo = regDoctorInfoList.get(i);
break;
}
}
if(regDoctorInfo == null)
{
rc = ResultCode.RC_DOCTOR_NOT_EXIST;
log.info("No specified doctor, doctor=" + name);
break;
}
url = regDoctorInfo.href.replaceAll(" ", "%20");
url = AppConfig.getInstance().getPropInternal("rjh.url.reg_doctor_root") + url;
rsp = session.execute(url);
if(rsp.getStatusLine().getStatusCode() != 200)
{
rc = new HttpResult(rsp.getStatusLine().getStatusCode(), url);
break;
}
content = HttpClientUtils.saveToString(rsp.getEntity(), "GB2312");
RegDoctorInfoDetailResult parseResult = new RegDoctorInfoDetailResult();
parseDoctorRegList(content, parseResult);
if(parseResult.viewState == null || parseResult.regDoctorInfoDetailList.isEmpty())
{
rc = ResultCode.RC_DOCTOR_DETAIL_LIST_EMPTY;
break;
}
RegDoctorInfoDetail regDetail = parseResult.regDoctorInfoDetailList.get(0);
boolean bHasAvailable = regDetail.isAvailable();
if(!bHasAvailable)
{
rc = ResultCode.RC_DOCTOR_REG_LIST_FULL;
break;
}
paramMap.clear();
paramMap.put("__VIEWSTATE", parseResult.viewState);
paramMap.put("__EVENTTARGET", regDetail.eventTarget);
paramMap.put("__EVENTARGUMENT", regDetail.eventArgument);
rb.method(HttpPost.METHOD_NAME).uriStr(url).paramMap(paramMap).encoding("GB2312");
rsp = session.execute(rb);
if(rsp.getStatusLine().getStatusCode() != 200)
{
rc = new HttpResult(rsp.getStatusLine().getStatusCode(), url,
HttpResult.HttpMethod.POST);
break;
}
content = HttpClientUtils.saveToString(rsp.getEntity(), "GB2312");
paramMap.clear();
parseDoRegisterParameters(content, paramMap);
rb.method(HttpPost.METHOD_NAME).uriStr(url).paramMap(paramMap).encoding("GB2312");
rsp = session.execute(rb);
if(rsp.getStatusLine().getStatusCode() != 200)
{
rc = new HttpResult(rsp.getStatusLine().getStatusCode(), url,
HttpResult.HttpMethod.POST);
break;
}
content = HttpClientUtils.saveToString(rsp.getEntity(), "GB2312");
String result = parseDoRegisterResult(content);
log.info("[RESULT]: " + result);
if(!result.contains(AppConfig.getInstance().getPropInternal("rjh.mark.reg_result_ok")))
{
rc = ResultCode.RC_REG_MESSAGE_FAIL;
break;
}
rc = queryRegList(true);
if(ResultCode.RC_ALREADY_REGISTERED == rc)
{
rc = ResultCode.RC_OK;
}
}
while(false);
if(rc.getID() == ResultCode.RC_HTTP_ERROR.getID())
{
String resultFile = AppUtils.getOutputFilePath("HttpResultError.html");
HttpClientUtils.saveToFile(rsp.getEntity(), resultFile);
String logInfo = String.format("[Fail] register: ResultFile=%s, %s", resultFile, rc.toString());
log.info(logInfo);
}
return rc;
}
public void logout() throws ClientProtocolException, IOException
{
if(!isLogin)
{
log.info("User [" + user + "] doesn't login yet.");
return;
}
String userPanel = AppConfig.getInstance().getPropInternal("rjh.url.user_panel");
MiscParams.setReferer(session.getParams(), userPanel);
String url = AppConfig.getInstance().getPropInternal("rjh.url.logout");
HttpResponse rsp = session.execute(url);
HttpClientUtils.saveToFile(rsp.getEntity(), AppUtils.getTempFilePath("logout.html"));
isLogin = false;
log.info("User [" + user + "] logout succeeded.");
}
public void dispose()
{
if(isDestroyed)
{
return;
}
try
{
logout();
}
catch(Exception e2)
{
log.error("failed to logout", e2);
}
session.getConnectionManager().shutdown();
isDestroyed = true;
}
private void updateTimes()
{
//1.
startTime = Calendar.getInstance();
//2.
registerTime = (Calendar)startTime.clone();
MiscUtils.updateCalendar(registerTime, week, dayOfWeek);
//3
startRegTime = (Calendar)registerTime.clone();
startRegTime.add(Calendar.WEEK_OF_YEAR, -4);
startRegTime.set(Calendar.HOUR_OF_DAY, 7);
startRegTime.set(Calendar.MINUTE, 30);
startRegTime.set(Calendar.SECOND, 0);
startRegTime.set(Calendar.MILLISECOND, 0);
//4.
ourStartRegTime = (Calendar)startRegTime.clone();
ourStartRegTime.add(Calendar.MINUTE, -4);
if(isDebug)
{
//3
startRegTime = (Calendar)startTime.clone();
startRegTime.add(Calendar.SECOND, 20);
//4.
ourStartRegTime = (Calendar)startRegTime.clone();
ourStartRegTime.add(Calendar.SECOND, -17);
MAX_TRY_TIMES = 3;
}
String timeInfo = String
.format("startTime=%s, registerTime=%s, startRegTime=%s, ourStartRegTime=%s.",
dateFormat.format(startTime.getTime()), dateFormat.format(registerTime.getTime()),
dateFormat.format(startRegTime.getTime()),
dateFormat.format(ourStartRegTime.getTime()));
log.info(timeInfo);
}
private void waitToRegister()
{
Calendar now = Calendar.getInstance();
long diff = ourStartRegTime.getTimeInMillis() - now.getTimeInMillis();
int minute = 17;
while( diff > 0 )
{
long sleepTime = (minute * 60 + 55) * 1000;
if(sleepTime > diff)
{
sleepTime = diff;
}
log.debug("Time is not reached yet, wait (" + sleepTime + ") ms. now="
+ dateFormat.format(now.getTime()) + ", ourStartRegTime="
+ dateFormat.format(ourStartRegTime.getTime()));
try
{
Thread.sleep(sleepTime);
}
catch(Exception e)
{
log.error("sleep exception.", e);
}
try
{
IDValuePair rc = queryRegList(false);
if(rc != ResultCode.RC_OK)
{
log.warn("Keep session failed. " + rc);
}
}
catch(Exception e)
{
log.error("queryRegList error.", e);
}
now = Calendar.getInstance();
diff = ourStartRegTime.getTimeInMillis() - now.getTimeInMillis();
}
log.info("Time up! Start to work now!");
}
private String parseLoginErrorReason(String fileName) throws IOException, ParseException
{
String content = IOUtils.toString(new FileInputStream(fileName), "GB2312");
String regex = "<span id=\"LblErr\" (.+?)>(.+?)</span>";
String result = MiscUtils.getRegexValueOnce(content, regex, 2);
return result;
}
private void parseRegListResult(String fileName, List<RegInfo> regList) throws ParseException
{
regList.clear();
try
{
String content = IOUtils.toString(new FileInputStream(fileName), "GB2312");
String tableRegex = "<table id=\"Table1\" (.+?)<table (.+?) id=\"DataGrid1\" style=\"(.+?)\">(.+?)</table>";
String result = MiscUtils.getRegexValueOnce(content, tableRegex, 4, Pattern.MULTILINE
| Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
log.trace(result);
String tableRowRegex = "<tr align=\"Right\" (.+?)</tr>(.+?)<tr align=\"Right\" (.+?)</tr>";
result = MiscUtils.getRegexValueOnce(result, tableRowRegex, 2, Pattern.MULTILINE
| Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
log.trace(result);
tableRowRegex = "<tr>(.+?)</tr>";
List<String> valueList = new ArrayList<String>();
int rc = MiscUtils.getRegexValue(result, tableRowRegex, valueList, true,
Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
log.info("Found regsiter record count: " + (rc - 1));
List<String> fieldList = new ArrayList<String>(8);
String recordRegex = "<td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td>";
String record = null;
for(int i = 3; i < valueList.size(); i += 2)
{
record = valueList.get(i).trim();
fieldList.clear();
MiscUtils.getRegexValueOnce(record, recordRegex, fieldList, true,
Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
RegInfo regInfo = new RegInfo(fieldList, 1);
regList.add(regInfo);
}
}
catch(Exception e)
{
log.error(e.toString(), e);
}
}
private void parseQueryRegListPage(String content, Map<String, String> paramMap)
throws ParseException
{
String result = null;
// 1. __VIEWSTATE
String viewStateRegex = "<input type=\"hidden\" name=\"__VIEWSTATE\" value=\"(.+)\" />";
result = MiscUtils.getRegexValueOnce(content, viewStateRegex, 1);
paramMap.put("__VIEWSTATE", result);
// 2. btn_search
String btnSearchRegex = "<input type=\"submit\" name=\"btn_search\" value=\"(.+)\" id=\"btn_search\" />";
result = MiscUtils.getRegexValueOnce(content, btnSearchRegex, 1);
paramMap.put("btn_search", result);
// 3. StartDate
String startDateRegex = "name=\"txt_StartDate\" type=\"text\" value=\"(.+)\" id=\"txt_StartDate\"";
result = MiscUtils.getRegexValueOnce(content, startDateRegex, 1);
paramMap.put("txt_StartDate", result);
// 4. EndDate
String endDateRegex = "name=\"txt_EndDate\" type=\"text\" value=\"(.+)\" id=\"txt_EndDate\"";
result = MiscUtils.getRegexValueOnce(content, endDateRegex, 1);
paramMap.put("txt_EndDate", result);
}
private void parseLoginParameters(String content, Map<String, String> paramMap)
throws ParseException
{
String result = null;
// 1. validationCodeRegex
String validationCodeRegex = "<img src=\"\\.\\./ValidateToken.aspx\\?yymm=(.+)\" id=\"IMG1\" />";
result = MiscUtils.getRegexValueOnce(content, validationCodeRegex, 1);
paramMap.put("ValidateToken", result);
// 2. __VIEWSTATE
String viewStateRegex = "<input type=\"hidden\" name=\"__VIEWSTATE\" value=\"(.+)\" />";
result = MiscUtils.getRegexValueOnce(content, viewStateRegex, 1);
paramMap.put("__VIEWSTATE", result);
// 3. _stv
String stvRegex = "<input name=\"_stv\" id=\"_stv\" type=\"hidden\" style=\"(.+)\" value=\"(.+)\" />";
result = MiscUtils.getRegexValueOnce(content, stvRegex, 2);
paramMap.put("_stv", result);
paramMap.put("BtnLogin.x", "38");
paramMap.put("BtnLogin.y", "5");
}
private void parseRegPageParameter(String content, String departmentName, int week,
Map<String, String> paramMap) throws ParseException
{
String result = null;
int flags = Pattern.DOTALL | Pattern.MULTILINE | Pattern.CASE_INSENSITIVE;
// 1. Get department list
String departmentRegex = "<select name=\"ddl_ks\" id=\"ddl_ks\">(.+?)</select>";
result = MiscUtils.getRegexValueOnce(content, departmentRegex, 1, flags);
// Then Get department id
String departmentIDListRegex = "<option value=\"(.+?)\">(.+?)</option>";
List<String> valueList = new ArrayList<String>();
int matchCount = MiscUtils.getRegexValue(result, departmentIDListRegex, valueList, true, flags);
if(valueList.size() != matchCount * 3)
{
throw new ParseException("Unexpected result. matchCount=" + matchCount + ", listSize="
+ valueList.size());
}
boolean bFound = false;
for(int i = 0; i < matchCount; i++)
{
String departmentFullName = valueList.get(i * 3 + 2);
if(departmentFullName.contains(departmentName))
{
bFound = true;
String departmentID = valueList.get(i * 3 + 1);
paramMap.put("ddl_ks", departmentID);
String logInfo = String.format(
"Found department [%s] with matched result: name=%s, id=%s.", departmentName,
departmentFullName, departmentID);
log.info(logInfo);
break;
}
}
if(!bFound)
{
throw new ParseException("Can't find matched department: " + departmentName);
}
// 2. Get ViewState
String viewStateRegex = "<input type=\"hidden\" name=\"__VIEWSTATE\" value=\"(.+?)\" />";
result = MiscUtils.getRegexValueOnce(content, viewStateRegex, 1, flags);
paramMap.put("__VIEWSTATE", result);
// 3. Get Button value
String okBtnRegex = "<input type=\"submit\" name=\"btn_OK\" value=\"(.+?)\" id=\"btn_OK\" />";
result = MiscUtils.getRegexValueOnce(content, okBtnRegex, 1, flags);
paramMap.put("btn_OK", result);
// ...
paramMap.put("ddl_lx", "ALL");
paramMap.put("ddl_yydm", "00");
paramMap.put("ddl_week", String.valueOf(week));
if(log.isDebugEnabled())
{
log.debug("parseRegPageParameter result: " + paramMap);
}
}
private void parseAvailableRegList(String content, Map<Integer, List<RegDoctorInfo>> availMap) throws ParseException
{
int flags = Pattern.DOTALL | Pattern.MULTILINE | Pattern.CASE_INSENSITIVE;
List<String> valueList = new ArrayList<String>();
int matchCount = 0;
String regex = null;
//1.
String columnRegex = "<table (.+?) id=\"dg_%d\" (.+?)\">(.+?)</table>";
List<String> tableContentList = new ArrayList<String>();
for(int i = 1; i <= 6; i++)
{
tableContentList.clear();
regex = String.format(columnRegex, i);
matchCount = MiscUtils.getRegexValue(content, regex, tableContentList, true, flags);
if(matchCount < 1)
{
log.debug("Can't find any matched available register list at day: [" + i + "]");
valueList.add("");
continue;
}
if(matchCount > 1)
{
log.warn("Found more than 1 matched available register list at day: [" + i + "], matchCount=" + matchCount);
}
valueList.add(tableContentList.get(3));
}
tableContentList.clear();
//2.
StringBuilder sb = new StringBuilder();
sb.append("<tr style=\"(.+?)\">");
sb.append("(\\s*?)<td style=\"(.+?)\">(.+?)</td>");
sb.append("(\\s*?)<td>(.+?)</td>");
sb.append("(\\s*?)<td>(\\s*?)<a href='(.+?)' target=\"_blank\">(\\s*?)(.+?)</a>(\\s*?)</td>");
sb.append("(\\s*?)</tr>");
regex = sb.toString();
int[] indexes = {14, 4, 6, 9};
List<String> rawRegInfoList = new ArrayList<String>();
List<String> validRegInfoList = new ArrayList<String>();
for(int i = 0, week = 1, size = valueList.size(); i < size; i++, week++)
{
rawRegInfoList.clear();
validRegInfoList.clear();
String availRawRegInfo = valueList.get(i).trim();
matchCount = MiscUtils.getRegexValue(availRawRegInfo, regex, rawRegInfoList, true, flags);
List<RegDoctorInfo> regDoctorInfoList = new ArrayList<RegDoctorInfo>();
for(int j = 0; j < matchCount; j++)
{
for(int k = 1; k < indexes.length; k++)
{
int index = j * indexes[0] + indexes[k];
validRegInfoList.add(rawRegInfoList.get(index));
}
RegDoctorInfo regDoctorInfo = new RegDoctorInfo(validRegInfoList, j * 3);
regDoctorInfoList.add(regDoctorInfo);
}
availMap.put(week, regDoctorInfoList);
}
rawRegInfoList.clear();
validRegInfoList.clear();
if(log.isDebugEnabled())
{
log.debug("parseAvailableRegList result: " + toString(availMap));
}
}
private void parseDoctorRegList(String content, RegDoctorInfoDetailResult parseResult) throws ParseException
{
int flags = Pattern.DOTALL | Pattern.MULTILINE | Pattern.CASE_INSENSITIVE;
//1.
String regex = "<table (.+?) id=\"dg_List\" (.+?)>(.+?)</table>";
String result = MiscUtils.getRegexValueOnce(content, regex, 3, flags);
//2.
StringBuilder sb = new StringBuilder();
sb.append("<tr style=\"(.+?)\">").append("(\\s*?)");
for(int i = 0; i < 6; i++)
{
sb.append("<td>(.+?)</td>");
}
sb.append("<td align=\"(.+?)\">(\\s*?)<a id=\"(.+?)\" NAME=\"(.+?)\" href=\"javascript:__doPostBack\\('(.+?)','(.*?)'\\)\">(.+?)</a>(\\s*?)</td>");
sb.append("(\\s*?)</tr>");
regex = sb.toString();
List<String> valueList = new ArrayList<String>();
int matchCount = MiscUtils.getRegexValue(result, regex, valueList, true, flags);
if(matchCount <= 0)
{
return;
}
int[] indexes = {18, 3, 4, 5, 6, 7, 8, 13, 14};
List<String> validRegInfoList = new ArrayList<String>();
for(int i = 0; i < matchCount; i++)
{
validRegInfoList.clear();
for(int j = 1; j < indexes.length; j++)
{
validRegInfoList.add(valueList.get(i * indexes[0] + indexes[j]));
}
RegDoctorInfoDetail regDoctorInfoDetail = new RegDoctorInfoDetail(validRegInfoList, 0);
parseResult.regDoctorInfoDetailList.add(regDoctorInfoDetail);
}
Collections.sort(parseResult.regDoctorInfoDetailList);
//get viewstate
regex = "<input type=\"hidden\" name=\"__VIEWSTATE\" value=\"(.+?)\"(\\s*?)/>";
result = MiscUtils.getRegexValueOnce(content, regex, 1);
parseResult.viewState = result;
}
private void parseDoRegisterParameters(String content, Map<String, String> paramMap) throws ParseException
{
String regex = null, result = null;
//1. btn_Submit
regex = "<input type=\"submit\" name=\"btn_Submit\" value=\"(.+?)\" id=\"btn_Submit\"(\\s*?)/>";
result = MiscUtils.getRegexValueOnce(content, regex, 1);
paramMap.put("btn_Submit", result);
//2.
regex = "<input type=\"hidden\" name=\"__EVENTTARGET\" value=\"(.*?)\"(\\s*?)/>";
result = MiscUtils.getRegexValueOnce(content, regex, 1);
paramMap.put("__EVENTTARGET", result);
//2.
regex = "<input type=\"hidden\" name=\"__EVENTARGUMENT\" value=\"(.*?)\"(\\s*?)/>";
result = MiscUtils.getRegexValueOnce(content, regex, 1);
paramMap.put("__EVENTARGUMENT", result);
//2.
regex = "<input type=\"hidden\" name=\"__VIEWSTATE\" value=\"(.*?)\"(\\s*?)/>";
result = MiscUtils.getRegexValueOnce(content, regex, 1);
paramMap.put("__VIEWSTATE", result);
}
private String parseDoRegisterResult(String content) throws ParseException
{
String regex = "<span id=\"lbl_Message\">(.*?)</span>";
return MiscUtils.getRegexValueOnce(content, regex, 1);
}
private class ExitThread extends Thread
{
public void run()
{
dispose();
log.info("ExitThread run over.");
}
}
private static class RegDoctorInfoDetailResult
{
public String viewState = null;
public List<RegDoctorInfoDetail> regDoctorInfoDetailList = null;
public RegDoctorInfoDetailResult()
{
this.viewState = null;
this.regDoctorInfoDetailList = new ArrayList<RegDoctorInfoDetail>();
}
}
private String toString(Map<Integer, List<RegDoctorInfo>> availMap)
{
String LF = "\r\n";
StringBuilder sb = new StringBuilder();
sb.append("Size=").append(availMap.size());
for(int week = 1; week <= 6; week++)
{
sb.append(LF);
sb.append("week[").append(week).append("]: ");
List<RegDoctorInfo> regDoctorInfoList = availMap.get(week);
if(regDoctorInfoList != null && !regDoctorInfoList.isEmpty())
{
sb.append(regDoctorInfoList);
}
}
return sb.toString();
}
private static class RegDoctorInfoDetail implements Comparable<RegDoctorInfoDetail>
{
public String name;
public String timeStart;
public String timeEnd;
public int total;
public int used;
public String eventTarget;
public String eventArgument;
public RegDoctorInfoDetail(List<String> fieldList, int fromIndex)
{
if(fromIndex < 0 || fromIndex > fieldList.size() - 8)
{
throw new IllegalArgumentException("invalid field list. fromIndex=" + fromIndex
+ ", size=" + fieldList.size());
}
timeStart = fieldList.get(fromIndex++);
timeEnd = fieldList.get(fromIndex++);
name = fieldList.get(fromIndex++);
String temp = fieldList.get(fromIndex++);
total = MiscUtils.toInt(temp);
temp = fieldList.get(fromIndex++);
used = MiscUtils.toInt(temp);
fromIndex++;
eventTarget = fieldList.get(fromIndex++);
eventArgument = fieldList.get(fromIndex++);
execJS();
}
public boolean isAvailable()
{
return (total > 0) && ((total - used) > 0);
}
public int compareTo(RegDoctorInfoDetail o)
{
if(!isAvailable() && !o.isAvailable())
{
return 0;
}
if(!isAvailable())
{
return 1;
}
if(!o.isAvailable())
{
return -1;
}
int result = this.timeStart.compareTo(o.timeStart);
if(result != 0)
{
return result;
}
return 0;
}
private void execJS()
{
if(eventTarget != null)
{
String[] a = eventTarget.split("\\$");
eventTarget = StringUtils.join(a, ':');
}
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("name=").append(name);
sb.append("; ").append("timeStart=").append(timeStart);
sb.append("; ").append("timeEnd=").append(timeEnd);
sb.append("; ").append("total=").append(total);
sb.append("; ").append("used=").append(used);
sb.append("; ").append("eventTarget=").append(eventTarget);
sb.append("; ").append("eventArgument=").append(eventArgument);
return sb.toString();
}
}
private static class RegDoctorInfo
{
public String name;
public String level;
public String href;
public RegDoctorInfo(List<String> fieldList, int fromIndex)
{
if(fromIndex < 0 || fromIndex > fieldList.size() - 3)
{
throw new IllegalArgumentException("invalid field list. fromIndex=" + fromIndex
+ ", size=" + fieldList.size());
}
name = fieldList.get(fromIndex++);
level = fieldList.get(fromIndex++);
href = fieldList.get(fromIndex++);
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("name=").append(name);
sb.append("; ").append("level=").append(level);
sb.append("; ").append("href=").append(href);
return sb.toString();
}
}
private static class RegInfo
{
public String hospitalName;
public String patientName;
public String regTime;
public String department;
public String doctorName;
public String flagName;
public RegInfo(List<String> fieldList, int fromIndex)
{
if(fromIndex < 0 || fromIndex > fieldList.size() - 6)
{
throw new IllegalArgumentException("invalid field list. fromIndex=" + fromIndex
+ ", size=" + fieldList.size());
}
hospitalName = fieldList.get(fromIndex++);
patientName = fieldList.get(fromIndex++);
regTime = fieldList.get(fromIndex++);
department = fieldList.get(fromIndex++);
doctorName = fieldList.get(fromIndex++);
flagName = fieldList.get(fromIndex++);
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("hospitalName=").append(hospitalName).append("; ");
sb.append("patientName=").append(patientName).append("; ");
sb.append("regTime=").append(regTime).append("; ");
sb.append("department=").append(department).append("; ");
sb.append("doctorName=").append(doctorName).append("; ");
sb.append("flagName=").append(flagName);
return sb.toString();
}
}
public static void main(String[] args) throws Exception
{
String user = AppConfig.getInstance().getPropInput("rjh.user");
String password = AppConfig.getInstance().getPropInput("rjh.password");
String department = AppConfig.getInstance().getPropInput("rjh.department");
String docName = AppConfig.getInstance().getPropInput("rjh.doctor");
String temp = AppConfig.getInstance().getPropInput("rjh.week");
int week = MiscUtils.toInt(temp);
if(week <= 0 || week > 5)
{
week = 5;
}
temp = AppConfig.getInstance().getPropInput("rjh.dayOfWeek");
int dayOfWeek = MiscUtils.toInt(temp);
if(dayOfWeek < 1 || dayOfWeek > 6)
{
dayOfWeek = 5;
}
for(int i = 0; args != null && i < args.length; i++)
{
if(args[i].startsWith("-user="))
{
user = args[i].substring("-user=".length());
}
else if(args[i].startsWith("-password="))
{
password = args[i].substring("-password=".length());
}
}
log.info(String.format(
"user=%s, password=%s, department=%s, docName=%s, week=%d, dayOfWeek=%d", user,
password, department, docName, week, dayOfWeek));
RjLogin rjlogin = new RjLogin(user, password, department, docName, week, dayOfWeek);
rjlogin.get();
System.exit(0);
}
}