package neu.integration.ctic.dao;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import neu.integration.base.dao.impl.BaseDaoImpl;
import neu.integration.ctic.vo.Cnvd;

import org.apache.commons.lang.ObjectUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.util.Version;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Repository;
import org.springframework.util.ReflectionUtils;


@Repository(value="cnvdDao")
public class CnvdDaoImpl extends BaseDaoImpl<Cnvd, Integer> implements CnvdDao {

	
	/**
	 * 为TUser表建立索引
	 */
	public void index(){  
		FullTextSession fullTextSession = Search.getFullTextSession(getSession());  
		//查出结果  
		List<Cnvd> cnvds = findAll();  
		//依次建立索引  
		for (Iterator iterator = cnvds.iterator(); iterator.hasNext();) {  
			Cnvd cnvd = (Cnvd) iterator.next();  
			fullTextSession.index(cnvd);  
		}  
		System.out.println("index over......");  
	}

	
	/**
	 * 通过漏洞title查询检索库，并将结果高亮显示
	 */
	public void searchByTitle(){ 
		FullTextSession fullTextSession = Search.getFullTextSession(getSession());  
		//在字段content中检索  
		QueryParser queryParser = new QueryParser(Version.LUCENE_36, "title", new SmartChineseAnalyzer(Version.LUCENE_36));  
		Query luceneQuery=null;  
		try {  
			//检索含有“test”的信息  
			luceneQuery = queryParser.parse("test"); 
		} catch (ParseException e) {  
			e.printStackTrace();  
		}  
		//执行检索，得到结果集  
		FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery, Cnvd.class);  
		List<Cnvd> cnvdList = fullTextQuery.list();  
		//查看结果做验证  
		for (Iterator iterator = cnvdList.iterator(); iterator.hasNext();) {  
			Cnvd cnvd = (Cnvd) iterator.next();  
			System.out.println(cnvd.getTitle());  
		} 
		SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<font color=red>", "</font>");
        QueryScorer queryScorer = new QueryScorer(luceneQuery);
        Highlighter highlighter = new Highlighter(formatter, queryScorer);
        Analyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_36);
        //fieldNames需要高亮显示的字段
        String[] fieldNames={"title"};
        for (Cnvd cnvd : cnvdList) {
            for (String fieldName : fieldNames) {
                //运用反射得到具体的标题内容
                Object fieldValue = ReflectionUtils.invokeMethod(BeanUtils.getPropertyDescriptor(Cnvd.class, fieldName).getReadMethod(), cnvd); //ReflectionUtils.getField(ReflectionUtils.findField(searchResultClass, fieldName), e);
                String hightLightFieldValue = null;
                if(fieldValue instanceof String){
                     
                    try {
                        //获得高亮关键字
                        hightLightFieldValue = highlighter.getBestFragment( analyzer, fieldName , ObjectUtils.toString(fieldValue, null));
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    } catch (InvalidTokenOffsetsException e1) {
                        e1.printStackTrace();
                    }
                    //这个判断很关键，否则如果标题或内容中没有关键字的话，就会出现不显示的问题。
                    if(hightLightFieldValue!=null){
                        //运用反射机制，将结果集中的关键字设置成高亮
                        ReflectionUtils.invokeMethod(BeanUtils.getPropertyDescriptor(Cnvd.class, fieldName).getWriteMethod(), cnvd, hightLightFieldValue); //setField(ReflectionUtils.findField(searchResultClass, fieldName), e, hightLightFieldValue);
                    }
                }
            }
        }
      //查看结果做验证  
        for (Iterator iterator = cnvdList.iterator(); iterator.hasNext();) {  
        	Cnvd cnvd = (Cnvd) iterator.next();  
        	System.out.println(cnvd.getTitle());  
        } 
	}  

}
