Skip to content

Instantly share code, notes, and snippets.

@karlkilden
Created January 27, 2015 21:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karlkilden/e378d369658542ab3837 to your computer and use it in GitHub Desktop.
Save karlkilden/e378d369658542ab3837 to your computer and use it in GitHub Desktop.
package se.raindance.mp.search;
import static com.google.common.base.Strings.nullToEmpty;
import static se.raindance.mp.search.query.FieldInfo.newInstance;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.commons.lang3.StringUtils;
import org.apache.deltaspike.jsf.api.message.JsfMessage;
import org.slf4j.Logger;
import se.raindance.LogManager;
import se.raindance.MethodLogger;
import se.raindance.mp.JsfRequestContext;
import se.raindance.mp.Messages;
import se.raindance.mp.search.query.FieldInfo;
import se.raindance.mp.search.query.SearchDashBoard;
import se.raindance.mp.search.query.SearchFilter;
import se.raindance.mp.search.query.SearchFilter.QueryParam;
import se.raindance.mp.search.query.SearchFilter.QueryType;
import se.raindance.mp.search.query.SearchPanel;
import se.raindance.mp.search.query.SolrQueryHandler;
import se.raindance.mp.shop.ItemGroup;
import se.raindance.mp.shop.ItemGroupService;
import se.raindance.mp.solr.ItemDTO;
import se.raindance.mp.systemconfig.Setting;
import se.raindance.mp.tree.ItemGroupTreeBuilder;
import se.raindance.mp.tree.ItemGroupWrapper;
import se.raindance.web.usercontext.BundleController;
import com.google.common.base.Strings;
@Named
@ViewScoped
@MethodLogger
public class SearchController implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private static final Logger LOG = LogManager.getLogger();
private SearchDashBoard SearchDashBoard = new SearchDashBoard();
private String query = "";
private boolean overviewMode = true;
private List<ItemGroup> groups;
private ItemGroup group;
private HashMap<ItemGroup, Long> hits = new HashMap<>();
private ItemGroupTreeBuilder builder = new ItemGroupTreeBuilder();
@Inject
BundleController bundleController;
@Inject
private SolrQueryHandler handler;
@Inject
private JsfMessage<Messages> msg;
@Inject
private JsfRequestContext jsfRequestContext;
@Inject
private ItemGroupService itemGroupService;
private SearchFilter itemFilter;
private SearchPanel itemPanel;
private String previousQuery;
private List<ItemGroupWrapper> rootGroups;
private HashMap<ItemGroup, List<ItemGroup>> quickMenuMap = new HashMap<>();
@PostConstruct
private void setup() {
rootGroups = builder.getSortedRootNodes(itemGroupService.fetchAll());
createItemPanel();
createAgreementPanel();
createGroupPanel();
createCategories();
}
public List<ItemGroup> getGroups() {
return groups;
}
public void setGroups(List<ItemGroup> roots) {
this.groups = roots;
}
private void createCategories() {
group = null;
updateGroups(itemGroupService.fetchRootGroups());
itemFilter.queryTypes(QueryType.GROUP);
doSearch();
createQuickMenu();
}
public void down(ItemGroup itemGroup) {
itemFilter.reset();
goDown(itemGroup);
categorySearch();
}
public void goDown(ItemGroup itemGroup) {
handleNav(itemGroup);
if (!group.isLeaf()) {
updateGroups(itemGroupService.fetchChildren(group));
}
}
private void categorySearch() {
if (group != null && group.isLeaf() || !Strings.isNullOrEmpty(query)) {
itemFilter.queryTypes(QueryType.NORMAL);
doSearch();
}
}
public void up(ItemGroup itemGroup) {
itemFilter.reset();
if (Strings.isNullOrEmpty(query)) {
itemPanel.clearHits();
}
overviewMode = true;
ItemGroup parent = itemGroup.getParent();
if (parent != null && parent.getParent() != null) {
parent = parent.getParent();
}
if (parent == null) {
resetItemFilter();
createCategories();
} else {
group = parent;
handleNav(group);
groups = itemGroupService.fetchChildren(parent);
}
categorySearch();
}
private void resetItemFilter() {
itemFilter.queryTemplate(handler.getQueryTemplate(Setting.SEARCH_QUERY_ITEM));
itemFilter.clearFq();
}
private void handleNav(ItemGroup itemGroup) {
group = itemGroup;
itemFilter.queryTemplate(handler.getQueryTemplate(Setting.SEARCH_QUERY_CATEGORY));
itemFilter.clearFq().fq(ItemDTO.ITEM_GROUPS, String.valueOf(group.getId()));
createQuickMenu();
}
public void createQuickMenu() {
for (ItemGroup g : groups) {
if (SearchDashBoard.displayGroup(g.getId())) {
ItemGroupWrapper wrapper = builder.getMapped().get(g);
List<ItemGroup> quickMenu = new ArrayList<>();
for (ItemGroupWrapper menuChild : wrapper.getChildren()) {
if (SearchDashBoard.displayGroup(menuChild.getItemGroup().getId())) {
quickMenu.add(menuChild.getItemGroup());
}
}
quickMenuMap.put(g, quickMenu);
}
}
}
public ItemGroup getGroup() {
return group;
}
public void setGroup(ItemGroup group) {
this.group = group;
}
public HashMap<ItemGroup, Long> getHits() {
return hits;
}
public void setHits(HashMap<ItemGroup, Long> hits) {
this.hits = hits;
}
private void updateGroups(List<ItemGroup> newGroups) {
this.groups = newGroups;
}
private void createItemPanel() {
itemFilter = new SearchFilter(handler.getQueryTemplate(Setting.SEARCH_QUERY_ITEM));
itemPanel = new SearchPanel("panelItems", itemFilter);
itemPanel.addFields(newInstance(ItemDTO.IMG_URL).lazyImg(), newInstance(ItemDTO.ITEM_NAME), newInstance(ItemDTO.CONTRACTED).img(),
newInstance("amount").style().action(), newInstance(ItemDTO.FORMATTED_PRICE).style().suffixKey("priceSEK"), newInstance("cart")
.style());
SearchDashBoard.setItemPanel(itemPanel);
}
private void createAgreementPanel() {
SearchPanel p = new SearchPanel("panelAgreements", new SearchFilter(handler.getQueryTemplate(Setting.SEARCH_QUERY_AGREEMENT)));
p.addFields(newInstance("supplier"), newInstance(ItemDTO.ITEM_NAME), newInstance("hits").prefix("(").suffix(")"));
// SearchDashBoard.addGenericPanel(p);
}
private void createGroupPanel() {
SearchPanel p = new SearchPanel("panelGroups", new SearchFilter(handler.getQueryTemplate(Setting.SEARCH_QUERY_PRODUCT_GROUP)));
p.addFields(newInstance(ItemDTO.ITEM_NAME), newInstance("hits").format("(%s)"));
// SearchDashBoard.addGenericPanel(p);
}
public void search() {
itemFilter.reset();
query = nullToEmpty(query);
previousQuery = query;
query = escapeQueryChars(query);
SearchDashBoard.backToNormalSearch();
if (query.isEmpty()) {
itemPanel.clearHits();
itemFilter.queryTypes(QueryType.GROUP);
} else {
itemFilter.queryTypes(QueryType.NORMAL, QueryType.GROUP);
}
doSearch();
spellCheck();
overviewMode = true;
// if (itemFilter.hasQueryType(QueryType.NORMAL)) { Add later
// groups = autoDrillDownAndFilter();
// }
}
public void moreRowsSearchForGroup(ItemGroup group) {
down(group);
setOverviewMode(false);
moreRowsSearch();
}
public List<ItemGroup> autoDrillDownAndFilter() {
if (groups != null) {
List<ItemGroup> foundGroups = new ArrayList<>();
ItemGroup possibleSingleton = null;
for (ItemGroup g : groups) {
if (SearchDashBoard.displayGroup(g.getId())) {
possibleSingleton = g;
foundGroups.add(g);
}
}
if (foundGroups.size() == 1) {
goDown(possibleSingleton);
return autoDrillDownAndFilter();
} else {
return groups;
}
}
return groups;
}
public void doSearch() {
LOG.info("Searching for {}", query);
handler.queryAndSetResult(query, SearchDashBoard);
}
public void home() {
overviewMode = true;
}
public void spellCheck() {
SearchDashBoard.setLatestQuery(query);
handler.spellCheck(SearchDashBoard);
SearchDashBoard.setTriedSpelling(true);
}
public void saveFilter() {
msg.addInfo().savedSuccesfully();
jsfRequestContext.onComplete("refreshSearch()");
}
public String getValue(String value, FieldInfo fieldInfo) {
StringBuilder sb = new StringBuilder();
appendIfNotNull(sb, fieldInfo.getPrefix());
appendFromBundleIfNotNull(sb, fieldInfo.getPrefixKey());
if (fieldInfo.isText()) {
sb.append(StringUtils.capitalize(value));
} else {
sb.append(value);
}
appendIfNotNull(sb, fieldInfo.getSuffix());
appendFromBundleIfNotNull(sb, fieldInfo.getSuffixKey());
String result = sb.toString();
if (fieldInfo.getFormat() != null) {
result = String.format(fieldInfo.getFormat(), result);
}
return result;
}
private void appendIfNotNull(StringBuilder sb, String string) {
if (string != null) {
sb.append(string);
}
}
private void appendFromBundleIfNotNull(StringBuilder sb, String string) {
if (string != null) {
sb.append(bundleController.getText(string));
}
}
public SearchDashBoard getSearchDashboard() {
return SearchDashBoard;
}
public void setSearchDashboard(final SearchDashBoard searchDashboard) {
this.SearchDashBoard = searchDashboard;
}
public String getQuery() {
return query;
}
public void setQuery(final String query) {
this.query = query;
}
public boolean isOverviewMode() {
return overviewMode;
}
public void setOverviewMode(boolean overviewMode) {
this.overviewMode = overviewMode;
}
public static String escapeQueryChars(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// These characters are part of the query syntax and must be escaped
if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':' || c == '^' || c == '[' || c == ']' || c == '\"'
|| c == '{' || c == '}' || c == '~' || c == '*' || c == '?' || c == '|' || c == '&' || c == ';' || c == '/') {
sb.append('\\');
}
sb.append(c);
}
return sb.toString();
}
public void moreRowsSearch() {
itemFilter.setRowCount(1000);
itemFilter.queryTypes(QueryType.NORMAL, QueryType.GROUP);
itemFilter.addParam(QueryParam.CONVERT);
doSearch();
}
public void clear() {
query = "";
itemFilter.clearFq();
itemPanel.clearHits();
createCategories();
}
public void reset() {
SearchDashBoard.reset();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment