package com.qxueyou.scc.exercise.service.impl;
|
|
import java.util.List;
|
import java.util.regex.Matcher;
|
import java.util.regex.Pattern;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import com.qxueyou.scc.exercise.model.ExerciseParse;
|
import com.qxueyou.scc.exercise.service.impl.node.Doc;
|
import com.qxueyou.scc.exercise.service.impl.node.Item;
|
import com.qxueyou.scc.exercise.service.impl.node.ItemType;
|
import com.qxueyou.scc.exercise.service.impl.node.Option;
|
import com.qxueyou.scc.exercise.service.impl.parser.ItemParser;
|
import com.qxueyou.scc.exercise.service.impl.parser.OptionParser;
|
|
public class Handler {
|
|
private Doc doc;
|
|
private Node currentNode;
|
|
/** 失败 */
|
public static final Integer HANDLER_RESULT_FAIL = 1 ;
|
|
/** 上一类型 */
|
public static final Integer HANDLER_RESULT_CONTINUE = 2;
|
|
/** 成功*/
|
public static final Integer HANDLER_RESULT_SUCCESS = 3;
|
|
/** 校验是否有中文 */
|
private static String regEx = "[\u4e00-\u9fa5]";
|
private static Pattern pat = Pattern.compile(regEx);
|
|
public Handler(){
|
doc = new Doc();
|
currentNode = doc;
|
}
|
|
/**
|
* 解析文本,每次读取一个段落
|
* @param content 段落文本内容
|
*/
|
public ExerciseParse parse(String content){
|
|
ParseResult result = null;
|
|
content = content.replace((char)12288, (char)32);
|
content = content.replace((char)160, (char)32);
|
|
//将得到的文本全角转半角
|
//content = formatFullToHalf(content);
|
content = content.replace('(', '(');
|
content = content.replace(')', ')');
|
|
// 非全部英文题 非全部空格, 需要将空格替换掉
|
if(isContentContainsChinese(content) || content.trim().isEmpty()){
|
content = content.replace(" ", "");
|
}
|
|
content = content.replace("\t", "");
|
|
if(StringUtils.isEmpty(content)||content.equals("\r")){
|
return new ExerciseParse(HANDLER_RESULT_SUCCESS,content);
|
}
|
|
//是否需要人为去掉回车
|
content = content.replace("\r", "");
|
|
int count = 0;
|
|
do{
|
result = currentNode.getParser().parse(currentNode, content);
|
|
if(result.isSuccess()){
|
if(ParseResult.STEP_CUR.equals(result.getNextStep())){
|
//成功后,取得当前parser
|
generateLastSuccessType(doc,currentNode,result.getNextNode());
|
return new ExerciseParse(HANDLER_RESULT_SUCCESS,content);
|
}
|
if(ParseResult.STEP_PRE.equals(result.getNextStep())){
|
currentNode = currentNode.getParent();
|
return new ExerciseParse(HANDLER_RESULT_SUCCESS,content);
|
}
|
if(ParseResult.STEP_NEXT.equals(result.getNextStep())){
|
currentNode = result.getNextNode();
|
return new ExerciseParse(HANDLER_RESULT_SUCCESS,content);
|
}
|
}else{
|
if(ParseResult.STEP_CUR.equals(result.getNextStep())){
|
//20150907 修改;抛到最上层doc解析器仍然无法定位,直接将文本内容添加到上一个解析成功的位置
|
appendTextToLastPosition(doc,content);
|
return new ExerciseParse(HANDLER_RESULT_CONTINUE,doc.getLastSuccessType(),content);
|
}
|
if(ParseResult.STEP_PRE.equals(result.getNextStep())){
|
if(currentNode.getParent()==null){
|
return new ExerciseParse(HANDLER_RESULT_FAIL,content);
|
}
|
currentNode = currentNode.getParent();
|
}
|
if(ParseResult.STEP_NEXT.equals(result.getNextStep())){
|
if(result.getNextNode()==null){
|
return new ExerciseParse(HANDLER_RESULT_FAIL,content);
|
}
|
currentNode = result.getNextNode();
|
}
|
}
|
|
}while( count++ < 15);
|
|
return new ExerciseParse(HANDLER_RESULT_FAIL,content);
|
|
}
|
|
public Doc result(){
|
return doc;
|
}
|
|
|
/**
|
* 得到最新成功的解析类型
|
*
|
* @param doc doc
|
* @param currNode 当前节点
|
* @param analysisNode 如果是解析 部分的解析器,返回非空数据,用于获取解析器类型
|
*/
|
private void generateLastSuccessType(Doc doc,Node currNode,Node analysisNode){
|
Parser currParser = currNode.getParser();
|
if(null != analysisNode){
|
doc.setLastSuccessType(Doc.CURR_SUCCESS_ANALYSIS);
|
return ;
|
}
|
if(currParser instanceof OptionParser){
|
doc.setLastSuccessType(Doc.CURR_SUCCESS_OPTION);
|
return ;
|
}
|
if(currParser instanceof ItemParser){
|
doc.setLastSuccessType(Doc.CURR_SUCCESS_CONTENT);
|
return ;
|
}
|
}
|
|
/**
|
* 得到当前解析成功的最新位置:如果是题目的:题干、选项或者解析,将他们组装对应位置
|
*
|
* @param doc
|
* @param content
|
*/
|
private void appendTextToLastPosition(Doc doc,String content){
|
String currSuccessType = doc.getLastSuccessType();
|
|
//第一层 ItemType
|
List<Node> lstItemType = doc.getChildren();
|
if(null == lstItemType || lstItemType.isEmpty()){
|
return ;
|
}
|
|
//第二层Item
|
ItemType objItemType = (ItemType)lstItemType.get(lstItemType.size() - 1);
|
List<Node> lstItem = objItemType.getChildren();
|
if(null == lstItem || lstItem.isEmpty()){
|
return ;
|
}
|
|
//取到最新位置的Item
|
Item objItem = (Item)lstItem.get(lstItem.size() - 1);
|
if(null != objItem){
|
appendTextToCurrPosition(objItem,currSuccessType,content);
|
}
|
}
|
|
/**
|
* 将当前没有归档的内容加入到对应的位置
|
*
|
* @param objItem
|
* @param currSuccessType
|
* @param content
|
*/
|
private void appendTextToCurrPosition(Item objItem,String currSuccessType,String content){
|
if(Doc.CURR_SUCCESS_CONTENT == currSuccessType){
|
objItem.setTitle(objItem.getTitle()+ content);
|
currentNode = objItem;
|
|
}else if(Doc.CURR_SUCCESS_ANALYSIS == currSuccessType){
|
objItem.setAnalysis(objItem.getAnalysis() + content);
|
currentNode = objItem;
|
|
}else if(Doc.CURR_SUCCESS_OPTION == currSuccessType){
|
|
List<Option> lstOptions = objItem.getOptions();
|
if(null == lstOptions || lstOptions.isEmpty()){
|
return ;
|
}
|
|
Option opt = null ;
|
for(int i = lstOptions.size() -1 ; i>=0 ; i --){
|
opt = lstOptions.get(i);
|
if(null == opt){
|
return ;
|
}
|
//将选项添加到最新位置
|
if(StringUtils.isNotBlank(opt.getNo())){
|
opt.setContent(opt.getContent() + content);
|
currentNode = objItem;
|
return ;
|
}
|
}
|
}
|
}
|
|
/**
|
* 字符串是否包含中文
|
* @param content
|
* @return
|
*/
|
private boolean isContentContainsChinese( String content ){
|
|
Matcher matcher = pat.matcher(content);
|
boolean flg = false;
|
if (matcher.find()) {
|
flg = true;
|
}
|
return flg;
|
}
|
|
}
|