/* Copyright (2005-2012) Schibsted ASA * This file is part of Possom. * * Possom is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Possom is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Possom. If not, see <http://www.gnu.org/licenses/>. * * Jul 25, 2007 11:02:02 AM */ package no.sesat.search.view.navigation; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import no.sesat.search.datamodel.DataModel; import no.sesat.search.datamodel.generic.StringDataObject; import no.sesat.search.datamodel.generic.StringDataObjectSupport; import no.sesat.search.result.BasicNavigationItem; import no.sesat.search.result.NavigationItem; import no.sesat.search.result.ResultItem; import no.sesat.search.result.ResultList; import no.sesat.search.view.config.SearchTab; /** The ControllerFactory and Controller class for manually configuration navigators against a command. * The command itself need not be a faceted search command. * * * @version $Id$ */ public class OptionNavigationController implements NavigationController, NavigationControllerFactory<OptionsNavigationConfig> { private OptionsNavigationConfig config; private String commandName; public NavigationController get(final OptionsNavigationConfig navigationConfig) { this.config = navigationConfig; this.commandName = navigationConfig.getCommandName(); return this; } public NavigationItem getNavigationItems(Context context) { final DataModel dm = context.getDataModel(); final ResultList<ResultItem> searchResult = commandName != null && null != dm.getSearch(commandName) ? dm.getSearch(commandName).getResults() : null; if (!config.getOptionsToKeep().isEmpty()) { removeAllBut(config.getOptionsToKeep(), searchResult, dm); } removeAll(config.getOptionsToDelete(), dm); addAll(config.getOptionsToAdd(), dm, context); // Only modifies the result of the parent. Return null. return null; } private void removeAll(final Collection<OptionsNavigationConfig.Option> options, final DataModel dataModel) { final NavigationItem parentResult = dataModel.getNavigation().getNavigation(config.getParent().getId()); for (final Iterator<NavigationItem> iterator = parentResult.getResults().iterator(); iterator.hasNext();) { final NavigationItem item = iterator.next(); for (final OptionsNavigationConfig.Option option : options) { if (item.getTitle().equals(option.getValue())) { iterator.remove(); } } } } private void removeAllBut( final Collection<OptionsNavigationConfig.Option> optionsToKeep, final ResultList<ResultItem> searchResult, final DataModel dataModel) { final NavigationItem parentResult = dataModel.getNavigation().getNavigation(config.getParent().getId()); final List<NavigationItem> toRemove = new ArrayList<NavigationItem>(); StringDataObject selectedValue = dataModel.getParameters().getValue(config.getParent().getField()); // Navigators already collected. Options is override for (NavigationItem navigator : parentResult.getResults()) { boolean match = false; // Double loop to find match in two lists. Not nice, but it works. for (OptionsNavigationConfig.Option option : optionsToKeep) { final String value = option.getValue(); if (navigator.getTitle().equals(value)) { match = true; if ((selectedValue == null || "".equals(selectedValue.getString())) && isOptionDefaultSelected(searchResult, option)) { navigator.setSelected(true); selectedValue = new StringDataObjectSupport("dummy"); } if (option.getDisplayName() != null) { navigator.setTitle(option.getDisplayName()); } } } if (!match) { toRemove.add(navigator); } } for(NavigationItem item : toRemove){ parentResult.removeResult(item); } } private void addAll( final Collection<OptionsNavigationConfig.Option> optionsToAdd, final DataModel dataModel, final Context context) { final NavigationItem parentResult = dataModel.getNavigation().getNavigation(config.getParent().getId()); final StringDataObject optionSelectedValue = dataModel.getParameters().getValue(config.getParent().getField()); boolean selectionDone = false; for (final OptionsNavigationConfig.Option option : optionsToAdd) { final String cmdName = option.getCommandName(); final ResultList<ResultItem> searchResult = null != cmdName && null != dataModel.getSearch(cmdName) ? dataModel.getSearch(option.getCommandName()).getResults() : null; // value is an unencoded value. String value = option.getValue(); if (option.getValueRef() != null && searchResult != null) { final String tmp = searchResult.getField(option.getValueRef()); if (tmp != null && tmp.length() > 0) { value = tmp; } } if (value != null) { final NavigationItem navigator = new BasicNavigationItem( option.getDisplayName(), context.getUrlGenerator().getURL(value, config.getParent(), option.getStaticParameters()), -1); parentResult.addResult(navigator); if (!selectionDone && (optionSelectedValue == null || "".equals(optionSelectedValue.getString())) && isOptionDefaultSelected(searchResult, option)) { navigator.setSelected(true); selectionDone = true; } else if (optionSelectedValue != null && optionSelectedValue.getString().equals(value)) { navigator.setSelected(true); selectionDone = true; } if (option.isUseHitCount() && searchResult != null) { navigator.setHitCount(searchResult.getHitCount()); } } } } private boolean isOptionDefaultSelected( final ResultList<ResultItem> result, final OptionsNavigationConfig.Option option) { final String valueRef = option.getDefaultSelectValueRef(); return option.isDefaultSelect() || (result != null && valueRef != null && option.getValue().equals(result.getField(valueRef))); } }