package com.bao.lc.site.s2.commands; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.chain.Context; import org.apache.commons.collections.MapUtils; 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.methods.HttpUriRequest; import org.htmlparser.Node; import org.htmlparser.NodeFilter; import org.htmlparser.Parser; import org.htmlparser.filters.AndFilter; import org.htmlparser.filters.HasAttributeFilter; import org.htmlparser.filters.HasChildFilter; import org.htmlparser.filters.HasSiblingFilter; import org.htmlparser.filters.NodeClassFilter; import org.htmlparser.filters.OrFilter; import org.htmlparser.tags.FormTag; import org.htmlparser.tags.InputTag; import org.htmlparser.tags.OptionTag; import org.htmlparser.tags.SelectTag; import org.htmlparser.tags.TableColumn; import org.htmlparser.util.NodeList; import org.htmlparser.util.ParserException; import com.bao.lc.bean.IDValuePair; import com.bao.lc.bean.ResultCode; import com.bao.lc.client.RequestBuilder; import com.bao.lc.client.utils.HttpClientUtils; import com.bao.lc.httpcommand.BasicHttpCommand; import com.bao.lc.httpcommand.params.HttpCommandPNames; import com.bao.lc.httpcommand.params.HttpCommandParams; import com.bao.lc.site.s2.ZyConstants; import com.bao.lc.util.AppUtils; import com.bao.lc.util.MiscUtils; public class GetTicketDetail extends BasicHttpCommand { private static Log log = LogFactory.getLog(GetTicketDetail.class); private String targetConusmer = null; public GetTicketDetail(String consumerName) { targetConusmer = consumerName; log.info("targetConusmer=" + targetConusmer); } public GetTicketDetail() { this(null); } @Override protected IDValuePair postExecute(Context context) throws Exception { parse(context); return ResultCode.RC_OK; } private void parse(Context context) throws ParserException, IOException { HttpResponse rsp = HttpCommandParams.getResponse(context); String encoding = MapUtils.getString(context, ZyConstants.PARAM_RSP_ENCODING, "UTF-8"); String queryResult = HttpClientUtils.saveToString(rsp.getEntity(), encoding); Parser parser = MiscUtils.createParser(queryResult, encoding, log); // Set filters List<NodeFilter> predicates = new ArrayList<NodeFilter>(4); NodeFilter[] a = new NodeFilter[0]; // 1. Submit filters predicates.add(new HasAttributeFilter("id", "submitForm")); predicates.add(new HasAttributeFilter("name", "submitForm")); predicates.add(new NodeClassFilter(FormTag.class)); NodeFilter submitFormFilter = new AndFilter(predicates.toArray(a)); // 2. Diag time filters predicates.clear(); predicates.add(new HasAttributeFilter("id", "rdDiagtime")); predicates.add(new HasAttributeFilter("name", "rdDiagtime")); predicates.add(new HasAttributeFilter("type", "radio")); predicates.add(new NodeClassFilter(InputTag.class)); NodeFilter inputsFilter = new AndFilter(predicates.toArray(a)); NodeFilter uncleFilter = new AndFilter(new HasSiblingFilter( new HasChildFilter(inputsFilter)), new NodeClassFilter(TableColumn.class)); NodeFilter diagTimeFilter = new OrFilter(inputsFilter, uncleFilter); // 3. Consumer List filters predicates.clear(); predicates.add(new HasAttributeFilter("id", "ddlConsumerList")); predicates.add(new HasAttributeFilter("name", "ddlConsumerList")); predicates.add(new NodeClassFilter(SelectTag.class)); NodeFilter consumerListFilter = new AndFilter(predicates.toArray(a)); // Total filter predicates.clear(); predicates.add(submitFormFilter); predicates.add(diagTimeFilter); predicates.add(consumerListFilter); NodeFilter finalFilter = new OrFilter(predicates.toArray(a)); // Fire! NodeList nodeList = parser.parse(finalFilter); FormTag submitForm = null; SelectTag consumerList = null; Map<String, String> diagTimeMap = new HashMap<String, String>(); InputTag diagTimeInput = null; TableColumn diagTimeColumn = null; for(int i = 0, size = nodeList.size(); i < size; i++) { Node node = nodeList.elementAt(i); if(node instanceof FormTag) { submitForm = (FormTag) node; continue; } else if(node instanceof SelectTag) { consumerList = (SelectTag) node; continue; } else if(node instanceof InputTag) { diagTimeInput = (InputTag) node; } else if(node instanceof TableColumn) { if(i == 0) { throw new ParserException("Unexpected TableColumn at index(0)."); } Node prevNode = nodeList.elementAt(i - 1); if(prevNode == diagTimeInput) { diagTimeColumn = (TableColumn) node; String timeText = StringUtils.strip(diagTimeColumn.toPlainTextString(), " \t\r\n"); String timeValue = diagTimeInput.getAttribute("value"); timeText = MiscUtils.getTableColumnText(diagTimeColumn); timeValue = StringUtils.trim(timeValue); if(StringUtils.isEmpty(timeText)) { throw new ParserException("Unexpected empty diag time."); } diagTimeMap.put(timeText, timeValue); } } } if(submitForm == null || consumerList == null || diagTimeMap.isEmpty()) { throw new ParserException("The required filed does't exist."); } // 1. Diag Time String dayOfWeek = MapUtils.getString(context, ZyConstants.PARAM_DAY_OF_WEEK); String expectedDiagTime = AppUtils.getDayOfWeekTextCN1(dayOfWeek); String diagTimeValue = diagTimeMap.get(expectedDiagTime); log.debug("expectedDiagTime=" + expectedDiagTime + ", diagTimeValue=" + diagTimeValue); Map<String, ConsumerInfo> consumerMap = new HashMap<String, ConsumerInfo>(); OptionTag[] options = consumerList.getOptionTags(); for(int i = 0; i < options.length; i++) { String name = options[i].getAttribute("name"); if(name == null || name.isEmpty()) { continue; } ConsumerInfo consumer = new ConsumerInfo(); consumer.name = name; consumer.id = options[i].getAttribute("id"); consumer.value = options[i].getAttribute("value"); consumer.phone = options[i].getAttribute("phone"); consumer.medical = options[i].getAttribute("medical"); consumerMap.put(name, consumer); } String consumerName = this.targetConusmer; if(consumerName == null || targetConusmer.isEmpty()) { consumerName = MapUtils.getString(context, ZyConstants.PARAM_CONSUMER_NAME); } log.info("consumerName=" + consumerName); ConsumerInfo consumer = consumerMap.get(consumerName); if(consumer == null) { throw new IllegalArgumentException("The user doesn't exist. " + consumerName); } Map<String, String> paramMap = new HashMap<String, String>(); NodeList submitInputs = submitForm.getFormInputs(); for(int i = 0, size = submitInputs.size(); i < size; i++) { InputTag input = (InputTag) submitInputs.elementAt(i); String name = input.getAttribute("name"); if(name == null || name.isEmpty()) { log.debug("Empty name input: " + input); continue; } String value = null; // Time if(name.equals("diagtimeid")) { value = diagTimeValue; } // Consumer else if(name.equals("txtConsumerName")) { value = consumer.name; } else if(name.equals("txtConsumerIdNo")) { value = consumer.value; } else if(name.equals("txtConsumerId")) { value = consumer.id; } else if(name.equals("txtConsumerTel")) { value = consumer.phone; } // other fields else { value = input.getAttribute("value"); } paramMap.put(name, value); } if(log.isDebugEnabled()) { log.debug("ParamMap: " + MiscUtils.toString(paramMap)); } String method = submitForm.getFormMethod(); String location = submitForm.getFormLocation(); // Build the next URI URI requestURI = HttpCommandParams.getTargetRequestURI(context); // Next Request RequestBuilder rb = new RequestBuilder(); rb.method(method).reference(location).baseURI(requestURI); rb.paramMap(paramMap).encoding(encoding); HttpUriRequest nextRequest = rb.create(); context.put(HttpCommandPNames.TARGET_REQUEST, nextRequest); context.put(HttpCommandPNames.TARGET_REFERER, requestURI.toString()); } private static class ConsumerInfo { public String name; public String id; public String value; public String phone; public String medical; public String toString() { StringBuilder sb = new StringBuilder(); sb.append("name=").append(name); sb.append(",id=").append(id); sb.append(",value=").append(value); sb.append(",phone=").append(phone); sb.append(",medical=").append(medical); return sb.toString(); } } }