001: /*
002: * Copyright 2004 Outerthought bvba and Schaubroeck nv
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package org.outerj.daisy.repository.serverimpl.query.facets;
017:
018: import java.util.Locale;
019: import java.util.Map;
020: import java.util.SortedMap;
021:
022: import org.apache.commons.logging.Log;
023: import org.outerj.daisy.query.model.ValueExpr;
024: import org.outerj.daisy.repository.query.FacetConf;
025: import org.outerj.daisy.repository.serverimpl.query.Formatter;
026:
027: class NumberFacetSampler extends AbstractFacetSampler {
028: private double spreadFactor;
029:
030: public NumberFacetSampler(FacetConf facetConf, Locale locale,
031: Log logger) {
032: super (facetConf, locale, logger);
033: Map<String, String> facetProperties = facetConf.getProperties();
034: if (facetProperties.containsKey("threshold"))
035: threshold = Integer.parseInt(facetProperties
036: .get("threshold"));
037: else {
038: logger
039: .warn("Could not find facet property with name 'threshold'. Falling back to default value MAX_VALUE");
040: threshold = Integer.MAX_VALUE;
041: }
042: if (facetProperties.containsKey("spreadFactor"))
043: spreadFactor = Double.parseDouble(facetProperties
044: .get("spreadFactor"));
045: else {
046: logger
047: .warn("Could not find facet property with name 'spreadFactor'. Falling back to default value '1'");
048: spreadFactor = 1;
049: }
050: }
051:
052: public String createUserFormat(CountGroup group,
053: ValueExpr valueExpr, Formatter valueFormatter) {
054: String s1 = valueFormatter.format(valueExpr, group.getMin());
055: String s2 = valueFormatter.format(valueExpr, group.getMax());
056: return s1 + " - " + s2;
057: }
058:
059: public void regroup(SortedMap<Object, CountGroup> groups) {
060: Map.Entry<Object, CountGroup>[] entries = (Map.Entry<Object, CountGroup>[]) groups
061: .entrySet().toArray(new Map.Entry[groups.size()]);
062:
063: Number min = (Number) (entries[0].getValue()).getMin();
064: Number max = (Number) (entries[entries.length - 1].getValue())
065: .getMin();
066: double diff = Math.abs(max.doubleValue() - min.doubleValue());
067: int ascFactor = facetConf.getSortAscending() ? 1 : -1;
068:
069: double z = Math.pow(diff, 1.0 / spreadFactor) / threshold;
070: int groupCount = 1;
071: Double absoluteThreshold = new Double(min.doubleValue()
072: + Math.pow(groupCount * z, spreadFactor) * ascFactor);
073:
074: CountGroup currentGroup = entries[0].getValue();
075: for (int i = 1; i < entries.length; i++) {
076: CountGroup group = entries[i].getValue();
077: boolean changedGroup = false;
078: while (comparator.compare(absoluteThreshold,
079: ((Number) group.getMin()).doubleValue()) < 0
080: || comparator.compare(absoluteThreshold,
081: ((Number) group.getMax()).doubleValue()) < 0) {
082: groupCount++;
083: absoluteThreshold = new Double(min.doubleValue()
084: + Math.pow(groupCount * z, spreadFactor)
085: * ascFactor);
086: changedGroup = true;
087: }
088: if (changedGroup) {
089: currentGroup = group;
090: } else {
091: currentGroup.merge(group);
092: groups.remove(entries[i].getKey());
093: }
094: }
095: }
096:
097: @Override
098: protected String createQueryFormat(CountGroup g,
099: ValueExpr valueExpr, Formatter formatter) {
100: if (g.getMin().equals(g.getMax())) {
101: return formatter.format(valueExpr, g.getMin());
102: } else {
103: Object realmin = g.getMin(), realmax = g.getMax();
104: if (!facetConf.getSortAscending()) {
105: realmin = g.getMax();
106: realmax = g.getMin();
107: }
108: return formatter.format(valueExpr, realmin) + " AND "
109: + formatter.format(valueExpr, realmax);
110: }
111: }
112: }
|