package com.bao.lc.site.s3; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.htmlparser.NodeFilter; import org.htmlparser.Parser; import org.htmlparser.tags.ScriptTag; import org.htmlparser.util.NodeList; import org.htmlparser.util.ParserException; import com.bao.lc.AppConfig; import com.bao.lc.common.ScriptCodeFilter; import com.bao.lc.site.s3.bean.GenericBean; import com.bao.lc.util.MiscUtils; public class TdUtils { private static Log log = LogFactory.getLog(TdUtils.class); public static final String DEFAULT_ENTRY_DELIM = ";"; public static final String DEFAULT_FIELD_DELIM = ","; private static Map<String, String> stationNameMap = new HashMap<String, String>(); private static List<GenericBean> cardTypeList = new ArrayList<GenericBean>(); private static List<GenericBean> ticketTypeList = new ArrayList<GenericBean>(); private static List<GenericBean> trainClassList = new ArrayList<GenericBean>(); private static List<GenericBean> seatClassList = new ArrayList<GenericBean>(); private static List<GenericBean> issaveList = new ArrayList<GenericBean>(); private static List<GenericBean> filterCatList = new ArrayList<GenericBean>(); private static final String JS_ERROR_MSG_REGEX = "var message = \"(.+?)\";"; static { initStationNames(); initPassengerInfoValues(); } private static boolean initStationNames() { //https://dynamic.12306.cn/otsweb/js/common/station_name.js?version=2.4 InputStream is = TdUtils.class.getResourceAsStream("station_name.js"); String content = null; try { content = IOUtils.toString(is, "UTF-8"); } catch(IOException e) { log.error("load station_name.js failed.", e); return false; } //Find the real content int fromIndex = content.indexOf('\''); if(fromIndex >= 0) { int toIndex = content.indexOf('\'', fromIndex + 1); if(toIndex >= 0) { content = content.substring(fromIndex + 1, toIndex); } } String[] stations = content.split("@"); for(String station : stations) { if(station == null || station.isEmpty()) { continue; } String fields[] = station.split("\\|"); if(fields.length < 4) { log.error("The station is not unexpected. station=" + station); continue; } stationNameMap.put(fields[1], fields[2]); } return true; } private static void initPassengerInfoValues() { String cardType = AppConfig.getInstance().getPropInternal("td.passenger.info.card.type"); initHelper(cardType, ";", ",", 2, cardTypeList); String ticketType = AppConfig.getInstance().getPropInternal("td.passenger.info.ticket.type"); initHelper(ticketType, ";", ",", 2, ticketTypeList); String trainClass = AppConfig.getInstance().getPropInternal("td.passenger.info.train.class"); initHelper(trainClass, ";", ",", 2, trainClassList); String seatClass = AppConfig.getInstance().getPropInternal("td.passenger.info.seat.class"); initHelper(seatClass, ";", ",", 3, seatClassList); String isSave = AppConfig.getInstance().getPropInternal("td.passenger.info.issave"); initHelper(isSave, ";", ",", 2, issaveList); String filterCat = AppConfig.getInstance().getPropInternal("td.filter.category"); initHelper(filterCat, ";", ",", 2, filterCatList); // String[] entries = seatClass.split(";"); // for(int i = 0; i < entries.length; i++) // { // String[] values = entries[i].split(","); // // if(values.length != 2) // { // log.error("Unexpected values. entry=" + entries[i]); // continue; // } // seatClassNameList.add(values[0]); // // seatClassNameMap.put(values[0], i); // seatClassIndexMap.put(i, values[1]); // } } private static void initHelper(String content, String entryDelim, String valueDelim, int expectedFieldCount, List<GenericBean> gbList) { String[] entries = content.split(entryDelim); for(String entry : entries) { String[] values = entry.trim().split(valueDelim); if(values.length != expectedFieldCount) { log.error("Unexpected values. entry=" + entry + ", expectedFieldCount=" + expectedFieldCount); continue; } GenericBean bean = new GenericBean(Arrays.asList(values)); gbList.add(bean); } } public static String getStationCode(String name) { return stationNameMap.get(name); } public static String getSeatClassValue(int seatType) { // if(!seatClassIndexMap.containsKey(seatType)) // { // log.error("The seatType [" + seatType + "] doesn't exist."); // seatType = TrainTicketInfo.NONE_SEAT; // } // // return seatClassIndexMap.get(seatType); return GenericBean.getField(String.valueOf(seatType), 0, 2, seatClassList); } public static String getSeatClassName(int seatType) { return GenericBean.getField(String.valueOf(seatType), 0, 1, seatClassList); } public static List<String> getSeatClassNameList() { return GenericBean.getFieldList(1, seatClassList); } public static List<GenericBean> getSeatClasses() { return seatClassList; } public static List<GenericBean> getTrainClasses() { return trainClassList; } public static List<GenericBean> getCardTypes() { return cardTypeList; } public static String getCardTypeValue(String cardType) { //0: name //1: value // return cardTypeMap.get(cardType); return GenericBean.getField(cardType, 0, 1, cardTypeList); } public static List<GenericBean> getTicketTypes() { return ticketTypeList; } public static String getTicketTypeValue(String ticketType) { // return ticketTypeMap.get(ticketType); //0: name //1: value return GenericBean.getField(ticketType, 0, 1, ticketTypeList); } public static String getTrainClassValue(String trainClass) { // return trainClassNameMap.get(trainClass); //0: name //1: value return GenericBean.getField(trainClass, 0, 1, trainClassList); } public static List<String> getTrainClassNameList() { return GenericBean.getFieldList(0, trainClassList); } public static List<GenericBean> getSaveList() { return issaveList; } public static String getFilterCatName(int category) { return GenericBean.getField(String.valueOf(category), 0, 1, filterCatList); } public static String toString(List list, String delim) { if(list == null || list.isEmpty()) { return ""; } StringBuilder sb = new StringBuilder(); for(int i = 0, size = list.size(); i < size; i++) { if(i > 0) { sb.append(delim); } sb.append(list.get(i)); } return sb.toString(); } public static List<String> toList(String content, String delim) { if(content == null || content.isEmpty()) { return new ArrayList<String>(0); } String[] values = content.split(delim); List<String> list = new ArrayList<String>(values.length); for(int i = 0; i < values.length; i++) { String value = values[i].trim(); list.add(value); } return list; } public static List<Integer> toIndexList(String content, String delim, List fullDataList) { List<String> dataList = toList(content, delim); List<Integer> indexList = new ArrayList<Integer>(); for(String data: dataList) { int index = indexOf(data, fullDataList); if(index != -1) { indexList.add(index); } } return indexList; } public static int indexOf(String data, List fullDataList) { if(fullDataList == null || fullDataList.isEmpty()) { return -1; } for(int i = 0, size = fullDataList.size(); i < size; i++) { String s = String.valueOf(fullDataList.get(i)); if(data.equals(s)) { return i; } } return -1; } public static String getJsErrorMsg(String content, String charset) { Parser parser = MiscUtils.createParser(content, charset, log); // error message from java script code NodeFilter scriptFilter = new ScriptCodeFilter(JS_ERROR_MSG_REGEX); // parse NodeList nodeList = null; try { nodeList = parser.parse(scriptFilter); } catch(ParserException e) { log.error("Failed to parse JS_ERROR_MSG_REGEX: " + JS_ERROR_MSG_REGEX, e); return null; } if(nodeList.size() <= 0) { log.info("Can't find matched error message: " + JS_ERROR_MSG_REGEX); return null; } ScriptTag scriptErrorMsg = (ScriptTag)nodeList.elementAt(0); String srcCode = scriptErrorMsg.getScriptCode(); List<String> valueList = new ArrayList<String>(); int matchCount = MiscUtils.getRegexValue(srcCode, JS_ERROR_MSG_REGEX, valueList, true, 0); if(matchCount <= 0) { log.error("matchCount <= 0 for " + JS_ERROR_MSG_REGEX); return null; } String errorMsg = valueList.get(1); log.info("getJsErrorMsg result: " + errorMsg); return errorMsg; } public static String getVersion() { return "1.1"; } }