/** * Copyright 2008 The University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package edu.unc.lib.dl.search.solr.model; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import edu.unc.lib.dl.search.solr.exception.InvalidHierarchicalFacetException; public class MultivaluedHierarchicalFacetNode implements HierarchicalFacetNode { public static Pattern extractFacetParts = Pattern.compile("[\\^/]"); private String displayValue; private String searchKey; private String facetValue; private String searchValue; private String pivotValue; private String limitValue; private List<String> tiers; /** * Initializes from an array of tier values, using the first tierNumber values. * * @param tierValues * @param tierNumber */ public MultivaluedHierarchicalFacetNode(String[] facetParts, int tierNumber) { if (facetParts.length == 0) throw new InvalidHierarchicalFacetException("Invalid facet format, no values were provided"); StringBuilder facetBuilder = new StringBuilder(); this.tiers = new ArrayList<String>(); for (int i = "".equals(facetParts[0])? 1 : 0; i < facetParts.length && i <= tierNumber; i++) { this.populateNode(facetParts[i], i, tierNumber); if (i > 0) facetBuilder.append('/'); facetBuilder.append(facetParts[i]); } this.facetValue = facetBuilder.toString(); } public MultivaluedHierarchicalFacetNode(String facetValue) { this.facetValue = facetValue.replaceAll("\"", ""); this.tiers = new ArrayList<String>(); try { String[] facetParts = extractFacetParts.split(facetValue); if (facetParts.length == 0 ) throw new InvalidHierarchicalFacetException("Incorrect facet format for value " + facetValue); for (int i = "".equals(facetParts[0])? 1 : 0; i < facetParts.length; i++) { this.populateNode(facetParts[i], i, facetParts.length - 1); } } catch (NullPointerException e) { throw new InvalidHierarchicalFacetException("Facet value did not match expected format: " + facetValue, e); } catch (IndexOutOfBoundsException e) { throw new InvalidHierarchicalFacetException("Facet value did not match expected format: " + facetValue, e); } } private void populateNode(String facetPart, int index, int lastIndex) { if (index == lastIndex) { String[] facetPair = facetPart.split(",", 2); // Query values will not have the display value part of the pair if (facetPair.length == 2) displayValue = facetPair[1]; else displayValue = null; searchKey = facetPair[0]; tiers.add(facetPair[0]); } else { tiers.add(facetPart); } } public MultivaluedHierarchicalFacetNode(String displayValue, String searchKey, String facetValue, List<String> tiers) { this.displayValue = displayValue; this.searchKey = searchKey; this.facetValue = facetValue; this.tiers = tiers; } public MultivaluedHierarchicalFacetNode(MultivaluedHierarchicalFacetNode node) { this.displayValue = node.displayValue; this.searchKey = node.searchKey; this.facetValue = node.facetValue; this.searchValue = node.searchValue; this.pivotValue = node.pivotValue; this.limitValue = node.limitValue; this.tiers = new ArrayList<String>(node.tiers); } @Override public String getDisplayValue() { return displayValue; } public void setDisplayValue(String displayValue) { this.displayValue = displayValue; } @Override public String getSearchKey() { return searchKey; } @Override public String getFacetValue() { return facetValue; } public List<String> getTiers() { return tiers; } public String joinTiers(boolean designateLastNode) { StringBuilder joined = new StringBuilder(); int i = 0; for (String tier : tiers) { if (designateLastNode && i++ == tiers.size() - 1) { joined.append('^'); } else { joined.append('/'); } joined.append(tier); } return joined.toString(); } public void setSearchValue(String searchValue) { } /** * Returns index query syntax for an exact value, with leading and trailing node designators * format: /tier1/tier2^tier3 */ @Override public String getSearchValue() { if (searchValue == null) this.searchValue = joinTiers(true); return this.searchValue; } /** * Returns index query syntax for getting the next tier of values, with trailing last node designator * * Format: /tier1/tier2^ */ @Override public String getPivotValue() { if (pivotValue == null) this.pivotValue = joinTiers(false) + "^"; return this.pivotValue; } /** * Returns expected search query syntax, with no first or last tier designation * * Formated: tier1/tier2/tier3 */ @Override public String getLimitToValue() { if (this.limitValue == null) { StringBuilder joined = new StringBuilder(); for (String tier : tiers) { if (joined.length() > 0) joined.append('/'); joined.append(tier); } this.limitValue = joined.toString(); } return this.limitValue; } @Override public Object clone() { return new MultivaluedHierarchicalFacetNode(this); } }