package org.bigbluebutton.webminer.web.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import org.bigbluebutton.webminer.web.controller.SearchController;
public class SessionHitsOrganizer {
String sessionNum;
int firstHitSlideNum;
int lastHitSlideNum;
int range;
float releventRange;
Map<String, Float> hitsMap= new HashMap <String, Float>();
Map<String, Object> analyzedHitsMap;
Map<Integer, String> slideNumURLMap = new HashMap <Integer, String>();
Map<String, ArrayList> hitSlideGroup = new HashMap <String, ArrayList>();
private static Logger logger = Logger.getLogger(SessionHitsOrganizer.class);
public String getSessionNum() {
return sessionNum;
}
public void setSessionNum(String sessionNum) {
this.sessionNum = sessionNum;
}
public int getFirstHitSlideNum() {
return firstHitSlideNum;
}
public void setFirstHitSlideNum(int firstHitSlideNum) {
this.firstHitSlideNum = firstHitSlideNum;
}
public int getLastHitSlideNum() {
return lastHitSlideNum;
}
public void setLastHitSlideNum(int lastHitSlideNum) {
this.lastHitSlideNum = lastHitSlideNum;
}
public int getRange() {
return range;
}
public void setRange(int range) {
this.range = range;
}
public Map<String, Float> getHitsMap() {
return hitsMap;
}
public void setHitsMap(Map<String, Float> hitsMap) {
this.hitsMap = hitsMap;
}
public Map<String, Object> getAnalyzedHitsMap() {
return analyzedHitsMap;
}
public void setAnalyzedHitsMap(Map<String, Object> analyzedHitsMap) {
this.analyzedHitsMap = analyzedHitsMap;
}
public Map<Integer, String> getSlideNumURLMap() {
return slideNumURLMap;
}
public void setSlideNumURLMap(Map<Integer, String> slideURLNumMap) {
this.slideNumURLMap = slideURLNumMap;
}
public Map<String, ArrayList> getHitSlideGroup() {
return hitSlideGroup;
}
public void setHitSlideGroup(Map<String, ArrayList> hitSlideGroup) {
this.hitSlideGroup = hitSlideGroup;
}
public float getReleventRange() {
return releventRange;
}
public void setReleventRange(float releventRange) {
this.releventRange = releventRange;
}
public void addExactHits(String URL, float score){
this.hitsMap.put(URL, new Float(score));
//System.out.println("hello----------"+URL);
this.slideNumURLMap.put(getSlideNumFromFilePath(URL),URL);
}
public void generateResultGroup(){
//loop hitsMap, for each exact match, generate a group of slides.
Set<String> ksHitsMap = this.hitsMap.keySet();
if (ksHitsMap!=null){
Iterator it = this.hitsMap.keySet().iterator();
while (it.hasNext()){
String url = (String) it.next();
ArrayList <String> relevantSlidesURL = new ArrayList<String>();
int slideNum = getSlideNumFromFilePath(url);
float currentScore = this.hitsMap.get(url);
/* The code blow is to find the previous qualified slides*/
String prevHitURL = getPrevHitURL(slideNum);
int prevHitSlideNum = getPrevHitSlideNum(slideNum);
if (logger.isInfoEnabled()) {
logger.info("Current hit ("+slideNum+")="+url);
logger.info("PrevHitURL ("+prevHitSlideNum+")="+prevHitURL);
}
String lastQualifyURL=null;
int lastQualifySlideNum=-1;
float prevHitScore = -1;
while (prevHitURL != null){
//compare last previous hit score and current hit score
prevHitScore = this.hitsMap.get(prevHitURL);
if (logger.isInfoEnabled()) {
logger.info("Prev hit slide number="+prevHitSlideNum+"; Score="+prevHitScore+"current hit score="+currentScore);
}
if (Math.abs(currentScore-prevHitScore)<this.releventRange){
//find the first not qualified slide
lastQualifyURL=prevHitURL;
lastQualifySlideNum=prevHitSlideNum;
prevHitURL = getPrevHitURL(prevHitSlideNum);
if (prevHitURL==null){
//all the previous hits are relevant
for (int num=prevHitSlideNum; num<slideNum; num++){
relevantSlidesURL.add(getFilePathFromSlideNumber(num, url));
}
} else {
prevHitSlideNum = getPrevHitSlideNum(prevHitSlideNum);
}
}else{
if (lastQualifySlideNum<0){
//the first previous slide is not qualify already, there is no need to add prev slide
break;
} else if ((lastQualifySlideNum-prevHitSlideNum)<2){
//estimate score and determine which slide in between is qualify
//there is no slide in between two slides
for (int num=slideNum-1; num>=lastQualifySlideNum; num--){
relevantSlidesURL.add(getFilePathFromSlideNumber(num, url));
}
break;
} else {
//find the last qualify slide number with estimated score
if (lastQualifyURL!=null){
float lastQualifyScore = this.hitsMap.get(lastQualifyURL);
float factor = Math.abs((lastQualifyScore-prevHitScore)/(lastQualifySlideNum-prevHitSlideNum));
for (int k=1; k<(lastQualifySlideNum-prevHitSlideNum);k++){
float estimatedScore = factor*k+prevHitScore;
System.out.println("Score------------"+estimatedScore);
if (Math.abs(estimatedScore-lastQualifyScore)<this.releventRange){
for (int num=slideNum-1; num>=lastQualifySlideNum-k; num--){
relevantSlidesURL.add(getFilePathFromSlideNumber(num, url));
if (logger.isInfoEnabled()) {
logger.info("add relevant slide:"+getFilePathFromSlideNumber(num, url));
}
}
break;
}
}
}
}
break;
}
}
/* The code blow is to find the next qualified slides*/
//add relevant slide slide to exact match
if (logger.isInfoEnabled()) {
for (int x=0; x<relevantSlidesURL.size();x++){
logger.info("====Previous Hit form "+url+"===========");
logger.info((x + 1) + ": " + relevantSlidesURL.get(x));
logger.info("===============");
}
}
hitSlideGroup.put(url, relevantSlidesURL);
}
}
}
private int getPrevHitSlideNum(int slideNum) {
for (int i=slideNum-1; i>-1; i--){
if (this.slideNumURLMap.containsKey(i)){
return i;
}
}
return 0;
}
private String getPrevHitURL(int slideNum) {
for (int i=slideNum-1; i>-1; i--){
if (this.slideNumURLMap.containsKey(i)){
return (String) this.slideNumURLMap.get(i);
}
}
return null;
}
private int getSlideNumFromFilePath(String filePath){
Integer rtnValue = null;
String[] pathTokens = filePath.split("/");
String fileName = pathTokens[pathTokens.length - 1];
String[] nameTokens = fileName.split("-");
String slideNumPart = nameTokens[nameTokens.length-1];
if (slideNumPart!=null && slideNumPart.length()>0){
int index = slideNumPart.indexOf(".");
String number = slideNumPart.substring(0,index);
rtnValue = (new Integer(number)).intValue();
}
//System.out.println("===slide number===="+rtnValue);
return rtnValue;
}
private String getFilePathFromSlideNumber(int slideNum, String baseURL){
String rtnValue = "";
Pattern p = Pattern.compile("-slide-\\d{1,3}.swf");
Matcher matcher = p.matcher(baseURL);
rtnValue = matcher.replaceAll("-slide-"+(new Integer(slideNum)).toString()+".swf");
return rtnValue;
}
}