<commit_before>package com.civilizer.web.controller;

import java.io.File;
import java.io.IOException;
import java.util.*;

import javax.faces.application.FacesMessage;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.webflow.execution.RequestContext;

import com.civilizer.config.AppOptions;
import com.civilizer.dao.FileEntityDao;
import com.civilizer.dao.FragmentDao;
import com.civilizer.dao.TagDao;
import com.civilizer.domain.FileEntity;
import com.civilizer.domain.Fragment;
import com.civilizer.domain.FragmentOrder;
import com.civilizer.domain.SearchParams;
import com.civilizer.domain.Tag;
import com.civilizer.domain.TextDecorator;
import com.civilizer.security.UserDetailsService;
import com.civilizer.web.view.*;

@Controller
@Component("mainController")
public final class MainController {
	
	// [DEV]
	private static final String DEVELOPMENT_MESSAGE_CLIENT_ID = "fragment-group-form:development-messages";
	
	private static final int    MAX_FRAGMENT_PANELS = 3;
	private static final String REQUEST_PARAM_LOCALE = "locale";
    
	@Autowired
	private FragmentDao fragmentDao;

	@Autowired
	private TagDao tagDao;
	
	@Autowired
	private FileEntityDao fileEntityDao;
	
	private Tag getTrashcanTag() {
		return tagDao.findById((long) Tag.TRASH_TAG_ID);
	}

	private Tag getBookmarkTag() {
		return tagDao.findById((long) Tag.BOOKMARK_TAG_ID);
	}

	private Tag getUntaggedTag() {
	    return tagDao.findById((long) Tag.UNTAGGED_TAG_ID);
	}
	
	private Tag getSpecialTag(String name) {
		return tagDao.findById((long) Tag.getSpecialTagId(name));
	}
	
	private void removeTag(Fragment frg, Tag tag) {
	    frg.removeTag(tag);
	    if (frg.getTags().isEmpty()) {
	        // [NOTE] As a rule, untagged fragments are not allowed;
	        // So we encounter such a tag, get it tagged with the '#untagged' tag
	        frg.addTag(getUntaggedTag());
	    }
	}
	
	// [DEV]
	public void yetToBeDeveloped(Object ... param) {
		String params = "";
		for (Object p : param) {
			params += p.toString() + ", ";
		}
		ViewUtil.addMessage(DEVELOPMENT_MESSAGE_CLIENT_ID, "Yet to be developed", params, null);
	}
	
	public FragmentListBean[] newFragmentListBeans() {
		final FragmentListBean[] output =  { null, null, null };
		for (int i=0; i<MAX_FRAGMENT_PANELS; ++i) {
			final FragmentListBean flb = new FragmentListBean();
			final long tagId = (i == 0) ?
					PanelContextBean.ALL_VALID_TAGS : PanelContextBean.EMPTY_TAG;
			flb.setPanelContextBean(new PanelContextBean(i, tagId));
			output[i] = flb;
		}
		return output;
	}

	public void populateFragmentListBeans(List<FragmentListBean> flbs, PanelContextBean pcb, SearchContextBean scb, RequestContext rc) {
//		final ExternalContext ec = rc.getExternalContext();
//		final ParameterMap pm =  ec.getRequestParameterMap();
//		final String locale = pm.get(REQUEST_PARAM_LOCALE);
//		logger.info(locale);
		
		for (int i=0; i<MAX_FRAGMENT_PANELS; ++i) {
			final PanelContextBean pc = (pcb != null && pcb.getPanelId() == i) ?
					pcb : null;
			final SearchContextBean sc = (scb != null && scb.getPanelId() == i) ?
					scb : null;
			populateFragmentListBean(flbs.get(i), pc, sc, rc);
		}
	}

	private FragmentListBean populateFragmentListBean(FragmentListBean existingFlb, PanelContextBean pcb, SearchContextBean scb, RequestContext rc) {
        final FragmentListBean flb = existingFlb;
        final PanelContextBean oldPcb = flb.getPanelContextBean();
        final PanelContextBean paramPcb = pcb;
        final FragmentSelectionBean fsb = (FragmentSelectionBean) rc.getFlowScope().get("fragmentSelectionBean");
        
        if (pcb == null) {
        	pcb = oldPcb;
        }

        int curPage = pcb.getCurPage();
        if (paramPcb != null) {
        	// the current page has been updated by going forward or forward
        	curPage = Math.max(0,
        			oldPcb.isLastPage() ? (paramPcb.getCurPage() - 1) : paramPcb.getCurPage());
        }
        SearchParams sp = oldPcb.getSearchParams();                
        long tagId = pcb.getTagId();
        if (scb != null) {
        	// a new KEYWORD SEARCH has been kicked;
            sp = scb.buildSearchParams();
            // this branch has the highest priority of all so it forces to overwrite a few key variables like so:
            tagId = PanelContextBean.EMPTY_TAG;
            curPage = 0;
        }
        final int count = pcb.getItemsPerPage();
        final int first = curPage * count;
        final FragmentOrder frgOrder = FragmentOrder.values()[flb.getOrderOption()];
        final boolean asc = flb.isOrderAsc();
        
        List<Fragment> fragments = Collections.emptyList(); // resultant fragments
        long allCount = 0; // the number of fragments at maximum
        if (tagId == PanelContextBean.ALL_VALID_TAGS) {
            // Fetch all the fragments
            fragments = fragmentDao.findSomeNonTrashed(first, count + 1, frgOrder, asc);
            allCount = fragmentDao.countAll(false);
        }
        else if (tagId == Tag.TRASH_TAG_ID) {
            // Fetch the trashed fragments
            fragments = fragmentDao.findSomeByTagId(tagId, first, count + 1, frgOrder, asc);
            allCount = fragmentDao.countByTagAndItsDescendants(tagId, true, tagDao);
        }
        else if (tagId != PanelContextBean.EMPTY_TAG) {
        	// Fetch the fragments with the specified tag (non-trashed)
        	fragments = fragmentDao.findSomeNonTrashedByTagId(tagId, first, count + 1, frgOrder, asc, tagDao);
        	allCount = fragmentDao.countByTagAndItsDescendants(tagId, false, tagDao);
        }
        else if (sp != null) {
            // Fetch the fragments by the search parameters
            final TagListBean tagListBean = (TagListBean) rc.getFlowScope().get("tagListBean");
            fragments = fragmentDao.findBySearchParams(sp, tagListBean.getTags());
            allCount = fragments.size();
            if (allCount > 0) {
                fragments = Fragment.paginate(fragments, first, count + 1, frgOrder, asc);
            }
            tagId = PanelContextBean.EMPTY_TAG;
        }
        
        // [NOTE] The content of fragments should be IMMUTABLE form here!
        <commit_msg>[bug fix] previous search phrase used to appear at non-search contexts<commit_after>package com.civilizer.web.controller;

import java.io.File;
import java.io.IOException;
import java.util.*;

import javax.faces.application.FacesMessage;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.webflow.execution.RequestContext;

import com.civilizer.config.AppOptions;
import com.civilizer.dao.FileEntityDao;
import com.civilizer.dao.FragmentDao;
import com.civilizer.dao.TagDao;
import com.civilizer.domain.FileEntity;
import com.civilizer.domain.Fragment;
import com.civilizer.domain.FragmentOrder;
import com.civilizer.domain.SearchParams;
import com.civilizer.domain.Tag;
import com.civilizer.domain.TextDecorator;
import com.civilizer.security.UserDetailsService;
import com.civilizer.web.view.*;

@Controller
@Component("mainController")
public final class MainController {
	
	// [DEV]
	private static final String DEVELOPMENT_MESSAGE_CLIENT_ID = "fragment-group-form:development-messages";
	
	private static final int    MAX_FRAGMENT_PANELS = 3;
	private static final String REQUEST_PARAM_LOCALE = "locale";
    
	@Autowired
	private FragmentDao fragmentDao;

	@Autowired
	private TagDao tagDao;
	
	@Autowired
	private FileEntityDao fileEntityDao;
	
	private Tag getTrashcanTag() {
		return tagDao.findById((long) Tag.TRASH_TAG_ID);
	}

	private Tag getBookmarkTag() {
		return tagDao.findById((long) Tag.BOOKMARK_TAG_ID);
	}

	private Tag getUntaggedTag() {
	    return tagDao.findById((long) Tag.UNTAGGED_TAG_ID);
	}
	
	private Tag getSpecialTag(String name) {
		return tagDao.findById((long) Tag.getSpecialTagId(name));
	}
	
	private void removeTag(Fragment frg, Tag tag) {
	    frg.removeTag(tag);
	    if (frg.getTags().isEmpty()) {
	        // [NOTE] As a rule, untagged fragments are not allowed;
	        // So we encounter such a tag, get it tagged with the '#untagged' tag
	        frg.addTag(getUntaggedTag());
	    }
	}
	
	// [DEV]
	public void yetToBeDeveloped(Object ... param) {
		String params = "";
		for (Object p : param) {
			params += p.toString() + ", ";
		}
		ViewUtil.addMessage(DEVELOPMENT_MESSAGE_CLIENT_ID, "Yet to be developed", params, null);
	}
	
	public FragmentListBean[] newFragmentListBeans() {
		final FragmentListBean[] output =  { null, null, null };
		for (int i=0; i<MAX_FRAGMENT_PANELS; ++i) {
			final FragmentListBean flb = new FragmentListBean();
			final long tagId = (i == 0) ?
					PanelContextBean.ALL_VALID_TAGS : PanelContextBean.EMPTY_TAG;
			flb.setPanelContextBean(new PanelContextBean(i, tagId));
			output[i] = flb;
		}
		return output;
	}

	public void populateFragmentListBeans(List<FragmentListBean> flbs, PanelContextBean pcb, SearchContextBean scb, RequestContext rc) {
//		final ExternalContext ec = rc.getExternalContext();
//		final ParameterMap pm =  ec.getRequestParameterMap();
//		final String locale = pm.get(REQUEST_PARAM_LOCALE);
//		logger.info(locale);
		
		for (int i=0; i<MAX_FRAGMENT_PANELS; ++i) {
			final PanelContextBean pc = (pcb != null && pcb.getPanelId() == i) ?
					pcb : null;
			final SearchContextBean sc = (scb != null && scb.getPanelId() == i) ?
					scb : null;
			populateFragmentListBean(flbs.get(i), pc, sc, rc);
		}
	}

	private FragmentListBean populateFragmentListBean(FragmentListBean existingFlb, PanelContextBean pcb, SearchContextBean scb, RequestContext rc) {
        final FragmentListBean flb = existingFlb;
        final PanelContextBean oldPcb = flb.getPanelContextBean();
        final PanelContextBean paramPcb = pcb;
        final FragmentSelectionBean fsb = (FragmentSelectionBean) rc.getFlowScope().get("fragmentSelectionBean");
        
        if (pcb == null) {
        	pcb = oldPcb;
        }

        int curPage = pcb.getCurPage();
        if (paramPcb != null) {
        	// the current page has been updated by going forward or forward
        	curPage = Math.max(0,
        			oldPcb.isLastPage() ? (paramPcb.getCurPage() - 1) : paramPcb.getCurPage());
        }
        SearchParams sp = oldPcb.getSearchParams();                
        long tagId = pcb.getTagId();
        if (scb != null) {
        	// a new KEYWORD SEARCH has been kicked;
            sp = scb.buildSearchParams();
            // this branch has the highest priority of all so it forces to overwrite a few key variables like so:
            tagId = PanelContextBean.EMPTY_TAG;
            curPage = 0;
        }
        final int count = pcb.getItemsPerPage();
        final int first = curPage * count;
        final FragmentOrder frgOrder = FragmentOrder.values()[flb.getOrderOption()];
        final boolean asc = flb.isOrderAsc();
        
        List<Fragment> fragments = Collections.emptyList(); // resultant fragments
        long allCount = 0; // the number of fragments at maximum
        if (tagId == PanelContextBean.ALL_VALID_TAGS) {
            // Fetch all the fragments
            fragments = fragmentDao.findSomeNonTrashed(first, count + 1, frgOrder, asc);
            allCount = fragmentDao.countAll(false);
            sp = null;
        }
        else if (tagId == Tag.TRASH_TAG_ID) {
            // Fetch the trashed fragments
            fragments = fragmentDao.findSomeByTagId(tagId, first, count + 1, frgOrder, asc);
            allCount = fragmentDao.countByTagAndItsDescendants(tagId, true, tagDao);
            sp = null;
        }
        else if (tagId != PanelContextBean.EMPTY_TAG) {
        	// Fetch the fragments with the specified tag (non-trashed)
        	fragments = fragmentDao.findSomeNonTrashedByTagId(tagId, first, count + 1, frgOrder, asc, tagDao);
        	allCount = fragmentDao.countByTagAndItsDescendants(tagId, false, tagDao);
            sp = null;
        }
        else if (sp != null) {
            // Fetch the fragments by the search parameters
            final TagListBean tagListBean = (TagListBean) rc.getFlowScope().get("tagListBean");
            fragments = fragmentDao.findBySearchParams(sp, tagListBean.getTags());
            allCount = fragments.size();
            if (allCount > 0) {
                fragments = Fragment.paginate(fragments, first, count + 1, frgOrder, asc);
            }
            tagId = PanelContextBean.EMPTY_TAG;
        }
        
        // [NOTE] The content of fragments should be IMMUTABLE form here!
        
{'fraction_non_alphanumeric': 0.10333091962346126, 'fraction_numerical': 0.0024619840695148444, 'mean_word_length': 3.2508464142813174, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '980266', 'n_tokens_mistral': 4372, 'n_tokens_neox': 4191, 'n_words': 998}