org.alfresco.solr.component.RewriteFacetCountsComponent.java Source code

Java tutorial

Introduction

Here is the source code for org.alfresco.solr.component.RewriteFacetCountsComponent.java

Source

/*
 * Copyright (C) 2005-2014 Alfresco Software Limited.
 *
 * This file is part of Alfresco
 *
 * Alfresco 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.
 *
 * Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
 */
package org.alfresco.solr.component;

import java.io.IOException;
import java.util.Collection;
import java.util.Map;

import com.google.common.collect.BiMap;

import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.handler.component.ResponseBuilder;
import org.apache.solr.handler.component.SearchComponent;

/**
 * @author Andy
 *
 */
public class RewriteFacetCountsComponent extends SearchComponent {

    /* (non-Javadoc)
     * @see org.apache.solr.handler.component.SearchComponent#finishStage(org.apache.solr.handler.component.ResponseBuilder)
     */
    @Override
    public void finishStage(ResponseBuilder rb) {
        /// wait until after distributed faceting is done 
        if (!rb.doFacets || rb.stage != ResponseBuilder.STAGE_GET_FIELDS) {
            return;
        } else {
            process(rb);
        }
    }

    /* (non-Javadoc)
     * @see org.apache.solr.handler.component.SearchComponent#prepare(org.apache.solr.handler.component.ResponseBuilder)
     */
    @Override
    public void prepare(ResponseBuilder rb) throws IOException {
        // Nothing to do
    }

    /* (non-Javadoc)
     * @see org.apache.solr.handler.component.SearchComponent#process(org.apache.solr.handler.component.ResponseBuilder)
     */
    @Override
    public void process(ResponseBuilder rb) {
        // rewrite

        rewrite(rb, "_field_mappings_", "facet_counts", "facet_fields");
        rewrite(rb, "_date_mappings_", "facet_counts", "facet_dates");
        rewrite(rb, "_range_mappings_", "facet_counts", "facet_ranges");
        rewrite(rb, "_interval_mappings_", "facet_counts", "facet_intervals");

        rewrite(rb, "_pivot_mappings_", "facet_counts", "facet_pivot");
        rewritePivotFields(rb, "facet_counts", "facet_pivot");

        rewrite(rb, "_stats_field_mappings_", "stats", "stats_fields");

        copyAnalytics(rb, "facet_counts", "facet_fields");

        Map<String, String> mappings = (Map<String, String>) rb.rsp.getValues().get("_stats_field_mappings_");
        if (mappings != null) {
            for (String key : mappings.keySet()) {
                rewrite(rb, "_stats_facet_mappings_", "stats", "stats_fields", key, "facets");
            }
        }
    }

    /**
     * @param rb
     */
    private void copyAnalytics(ResponseBuilder rb, String... sections) {
        NamedList<Object> found = (NamedList<Object>) rb.rsp.getValues();
        for (String section : sections) {
            found = (NamedList<Object>) found.get(section);
            if (found == null) {
                return;
            }
        }

        NamedList<Object> analytics = (NamedList<Object>) rb.rsp.getValues();
        analytics = (NamedList<Object>) analytics.get("analytics");
        if (analytics != null) {
            for (int i = 0; i < analytics.size(); i++) {
                String name = analytics.getName(i);
                Object value = analytics.getVal(i);
                found.add(name, value);
            }
        }

    }

    /**
     * Update pivot fields in the response to reference ACS properties rather than Solr fields.
     *
     * @param rb The response builder.
     * @param sections The names of the sections in the response to update.
     */
    private void rewritePivotFields(ResponseBuilder rb, String... sections) {
        Map<String, String> mappings = (Map<String, String>) rb.rsp.getValues().get("_pivot_mappings_");
        if (mappings != null) {
            NamedList<Object> found = (NamedList<Object>) rb.rsp.getValues();
            for (String section : sections) {
                found = (NamedList<Object>) found.get(section);
                if (found == null) {
                    return;
                }
            }
            for (int i = 0; i < found.size(); i++) {
                String pivotName = found.getName(i);
                String[] fromParts = pivotName.split(",");
                String mapping = mappings.get(pivotName);
                String[] toParts = mapping != null ? mapping.split(",") : fromParts;
                Collection<NamedList<Object>> current = (Collection<NamedList<Object>>) found.getVal(i);
                processPivot(rb, fromParts, toParts, current, 0);
            }
        }

    }

    private void processPivot(ResponseBuilder rb, String[] fromParts, String[] toParts,
            Collection<NamedList<Object>> current, int level) {
        for (NamedList<Object> entry : current) {
            for (int i = 0; i < entry.size(); i++) {
                String name = entry.getName(i);
                if (name.equals("field")) {
                    entry.setVal(i, fromParts[level].trim());
                } else if (name.equals("pivot")) {
                    Collection<NamedList<Object>> pivot = (Collection<NamedList<Object>>) entry.getVal(i);
                    processPivot(rb, fromParts, toParts, pivot, level + 1);
                } else if (name.equals("ranges")) {
                    SimpleOrderedMap ranges = (SimpleOrderedMap) entry.getVal(i);
                    processRanges(rb, ranges);
                } else {
                    // leave alone
                }
            }
        }
    }

    /**
     * Update the returned ranges to reference ACS properties rather than Solr fields.
     *
     * @param rb The response builder.
     * @param ranges The ranges to update.
     */
    private void processRanges(ResponseBuilder rb, SimpleOrderedMap ranges) {

        BiMap<String, String> mappings = (BiMap<String, String>) rb.rsp.getValues().get("_range_mappings_");
        if (mappings != null) {
            updateToACSNaming(mappings, ranges);
        }
    }

    /**
      * Update the returned facet sections to reference ACS properties rather than Solr fields.
      *
      * @param rb the response builder.
      * @param mappingName The name of the mapping definition created in {@link RewriteFacetParametersComponent}.
      * @param sections The names of the sections to be updated.
      */
    private void rewrite(ResponseBuilder rb, String mappingName, String... sections) {
        BiMap<String, String> mappings = (BiMap<String, String>) rb.rsp.getValues().get(mappingName);
        if (mappings != null) {
            NamedList<Object> found = (NamedList<Object>) rb.rsp.getValues();
            for (String section : sections) {
                found = (NamedList<Object>) found.get(section);
                if (found == null) {
                    return;
                }
            }
            // This found already contains the private buckets
            updateToACSNaming(mappings, found);
        }
    }

    /**
     * Update entries in a list to reference ACS properties rather than Solr fields.
     *
     * @param mappings The mapping from ACS properties to Solr fields.
     * @param propertyList The list to update.
     */
    private void updateToACSNaming(BiMap<String, String> mappings, NamedList<Object> propertyList) {
        for (int i = 0; i < propertyList.size(); i++) {
            String name = propertyList.getName(i);
            String newName = mappings.inverse().get(name);
            if (newName != null) {
                propertyList.setName(i, newName);
            }
        }
    }

    /* (non-Javadoc)
     * @see org.apache.solr.handler.component.SearchComponent#getDescription()
     */
    @Override
    public String getDescription() {
        return "RewriteFacetCounts";
    }

    /* (non-Javadoc)
     * @see org.apache.solr.handler.component.SearchComponent#getSource()
     */
    @Override
    public String getSource() {
        return "";
    }

}