org.craftercms.commerce.server.solr.AbstractSolrCRUDService.java Source code

Java tutorial

Introduction

Here is the source code for org.craftercms.commerce.server.solr.AbstractSolrCRUDService.java

Source

/*
 * Copyright (C) 2007-2013 Crafter Software Corporation.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.craftercms.commerce.server.solr;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.beans.DocumentObjectBinder;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.response.FacetField.Count;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.craftercms.commerce.api.BaseType;
import org.craftercms.commerce.api.CrafterCommerceConstants;
import org.craftercms.commerce.api.CrafterCommerceException;
import org.craftercms.commerce.api.facet.Facet;
import org.craftercms.commerce.api.facet.FacetValue;
import org.craftercms.commerce.api.service.ServiceResponse;
import org.craftercms.commerce.server.BaseCRUDService;
import org.craftercms.commerce.server.QueryConverter;
import org.craftercms.commerce.server.ReturnMessageProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

public abstract class AbstractSolrCRUDService<T extends BaseType> extends BaseCRUDService<T> {

    private static final Logger LOGGER = LoggerFactory
            .getLogger("org.craftercms.commerce.solr.AbstractSolrCRUDService");

    @Autowired
    private SolrServer solrServer;

    @Autowired
    private QueryConverter queryConverter;

    private DocumentBaseTypeBinder documentObjectBinder = new DocumentBaseTypeBinder();

    // ---------- Getters & setters ----------

    protected SolrServer getSolrServer() {
        return solrServer;
    }

    protected void setSolrServer(SolrServer solrServer) {
        this.solrServer = solrServer;
    }

    protected QueryConverter getQueryConverter() {
        return queryConverter;
    }

    protected void setQueryConverter(QueryConverter queryConverter) {
        this.queryConverter = queryConverter;
    }

    protected DocumentObjectBinder getDocumentObjectBinder() {
        return documentObjectBinder;
    }

    // ---------- Implementation ----------

    public ServiceResponse<T> save(@RequestBody T entity) throws CrafterCommerceException {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("About to save entity: " + entity.toString());
        }
        prepareEntityForSaving(entity);
        validate(entity);
        try {
            SolrInputDocument inputDoc = documentObjectBinder.toSolrInputDocument(entity);
            solrServer.add(inputDoc);
            solrServer.commit();
            return new ServiceResponse<T>(getTypeArgument(), true, entity,
                    ReturnMessageProvider.saveMessage(getTypeArgument()));
        } catch (Exception e) {
            LOGGER.error("Failed to save entity", e);
            return new ServiceResponse<T>(getTypeArgument(), false, e.getMessage());
        }
    }

    public ServiceResponse<T> saveAll(@RequestBody T[] entities) throws CrafterCommerceException {
        try {
            for (T entity : entities) {
                prepareEntityForSaving(entity);
                validate(entity);
            }
            List<SolrInputDocument> inputDocs = new ArrayList<SolrInputDocument>(entities.length);
            for (T _entity : entities) {
                inputDocs.add(documentObjectBinder.toSolrInputDocument(_entity));
            }
            solrServer.add(inputDocs);
            solrServer.commit();
            return new ServiceResponse<T>(getTypeArgument(), true, new HashSet<T>(Arrays.asList(entities)),
                    ReturnMessageProvider.saveAllMessage(getTypeArgument(), entities));
        } catch (Exception e) {
            LOGGER.error("Failed to save entities", e);
            return new ServiceResponse<T>(getTypeArgument(), false, e.getMessage());
        }
    }

    public ServiceResponse<T> findById(@PathVariable String id) throws CrafterCommerceException {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("About to find entity for id: " + id);
        }
        try {
            T entity = null;
            SolrQuery solrQuery = new SolrQuery(BaseType.SOLR_ID_FIELD + ":" + id);
            SolrDocumentList solrDocList = solrServer.query(solrQuery).getResults();
            if (solrDocList.size() > 0) {
                entity = documentObjectBinder.getBean(getTypeArgument(), solrDocList.get(0));
            }
            boolean found = (entity == null ? false : true);
            return new ServiceResponse<T>(getTypeArgument(), true, entity,
                    ReturnMessageProvider.findByIdMessage(getTypeArgument(), id, found));
        } catch (Exception e) {
            LOGGER.error("Failed to find entity by id for id = " + id, e);
            return new ServiceResponse<T>(getTypeArgument(), false, e.getMessage());
        }
    }

    public ServiceResponse<T> findByQuery(@PathVariable String query, @PathVariable int offset,
            @PathVariable int maxResults) throws CrafterCommerceException {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("About to find entities for query: " + query);
        }
        try {
            String solrQueryStr = queryConverter.toSolrQuery(query);
            SolrQuery solrQuery = new SolrQuery(solrQueryStr);
            solrQuery.setStart(offset);
            solrQuery.setRows(maxResults);
            QueryResponse qResponse = solrServer.query(solrQuery);
            Set<T> entities = toEntities(qResponse);
            ServiceResponse<T> sResponse = new ServiceResponse<T>();
            sResponse.setReturnedClass(getTypeArgument());
            sResponse.setSuccess(true);
            sResponse.setEntities(entities);
            sResponse.setCount(qResponse.getResults().getNumFound());
            String message = ReturnMessageProvider.findByQueryMessage(getTypeArgument(), query, entities.size());
            sResponse.setMessage(message);
            return sResponse;
        } catch (Exception e) {
            LOGGER.error("Failed to find entities by query for query = " + query, e);
            return new ServiceResponse<T>(getTypeArgument(), false, e.getMessage());
        }
    }

    public ServiceResponse<T> findByQuery(String query, int offset, int maxResults, String... facet)
            throws CrafterCommerceException {
        try {
            String solrQueryStr = queryConverter.toSolrQuery(query);
            SolrQuery solrQuery = new SolrQuery(solrQueryStr);
            solrQuery.setStart(offset);
            solrQuery.setRows(maxResults);
            // construct facet parameters
            if (facet.length > 0) {
                solrQuery.setFacet(true);
                solrQuery.setFacetMinCount(2); // only get the facet if there are 2 or more values
                for (String _facet : facet) {
                    solrQuery.addFacetField(_facet);
                }
            }
            // execute Solr query
            QueryResponse response = solrServer.query(solrQuery);
            Set<T> entities = toEntities(response);
            Set<Facet> facets = toFacets(response);
            // create the service response
            ServiceResponse<T> serviceResponse = new ServiceResponse<T>();
            serviceResponse.setSuccess(true);
            serviceResponse.setEntities(entities);
            serviceResponse.setCount(response.getResults().getNumFound());
            serviceResponse.setFacets(facets);
            String msg = ReturnMessageProvider.findByQueryMessage(getTypeArgument(), query, entities.size());
            serviceResponse.setMessage(msg);
            // return the response
            return serviceResponse;
        } catch (Exception e) {
            LOGGER.error("Failed to find entities by query for query = " + query, e);
            return new ServiceResponse<T>(getTypeArgument(), false, e.getMessage());
        }
    }

    /**
     * A proxy method
     * 
     * @param query
     * @param offset
     * @param maxResults
     * @param facets A string with field names for creating facets, separated by a comma (,)
     * @return
     * @throws CrafterCommerceException
     */
    @RequestMapping(CrafterCommerceConstants.FIND_BY_QUERY_WITH_FACETS_ACTION_REST_MAPPING)
    public ServiceResponse<T> findByQueryWithFacets(@PathVariable String query, @PathVariable int offset,
            @PathVariable int maxResults, @PathVariable String facets) throws CrafterCommerceException {

        String[] facetsArray = facets.split(",");

        return findByQuery(query, offset, maxResults, facetsArray);
    }

    public ServiceResponse<T> findAll() throws CrafterCommerceException {
        try {
            String solrQueryStr = BaseType.SOLR_TYPE_FIELD + ":" + getTypeArgument().getName();
            SolrQuery solrQuery = new SolrQuery(solrQueryStr);
            solrQuery.setRows((int) count().getCount());

            SolrDocumentList solrDocList = solrServer.query(solrQuery).getResults();

            Set<T> entities = new LinkedHashSet<T>(solrDocList.size());
            for (SolrDocument _solrDoc : solrDocList) {
                entities.add(documentObjectBinder.getBean(getTypeArgument(), _solrDoc));
            }

            ServiceResponse<T> sResponse = new ServiceResponse<T>();
            sResponse.setSuccess(true);
            sResponse.setReturnedClass(getTypeArgument());
            sResponse.setEntities(entities);
            sResponse.setMessage(ReturnMessageProvider.findAllMessage(getTypeArgument(), entities));

            return sResponse;
        } catch (Exception e) {
            LOGGER.error("Failed to find all entities", e);
            return new ServiceResponse<T>(getTypeArgument(), false, e.getMessage());
        }
    }

    public ServiceResponse<T> count() throws CrafterCommerceException {
        try {
            String solrQueryStr = BaseType.SOLR_TYPE_FIELD + ":" + getTypeArgument().getName();
            SolrQuery solrQuery = new SolrQuery(solrQueryStr);
            solrQuery.setRows(0);

            long numfound = solrServer.query(solrQuery).getResults().getNumFound();

            ServiceResponse<T> sResponse = new ServiceResponse<T>();
            sResponse.setSuccess(true);
            sResponse.setReturnedClass(getTypeArgument());
            sResponse.setCount(numfound);
            sResponse.setMessage(ReturnMessageProvider.countMessage(getTypeArgument(), numfound));

            return sResponse;
        } catch (Exception e) {
            LOGGER.error("Failed to count all entities", e);
            return new ServiceResponse<T>(getTypeArgument(), false, e.getMessage());
        }
    }

    public ServiceResponse<T> delete(@RequestBody T entity) throws CrafterCommerceException {
        try {
            solrServer.deleteByQuery(BaseType.SOLR_ID_FIELD + ":" + entity.getId());
            solrServer.commit();
            return new ServiceResponse<T>(getTypeArgument(), true, ReturnMessageProvider.deleteMessage(entity));
        } catch (Exception e) {
            LOGGER.error("Failed to delete entity", e);
            return new ServiceResponse<T>(getTypeArgument(), false, e.getMessage());
        }
    }

    public ServiceResponse<T> deleteAll() throws CrafterCommerceException {
        try {
            solrServer.deleteByQuery(BaseType.SOLR_TYPE_FIELD + ":" + getTypeArgument().getName());
            solrServer.commit();
            return new ServiceResponse<T>(getTypeArgument(), true,
                    ReturnMessageProvider.deleteAllMessage(getTypeArgument()));
        } catch (Exception e) {
            LOGGER.error("Failed to delete all entities", e);
            return new ServiceResponse<T>(getTypeArgument(), false, e.getMessage());
        }
    }

    public ServiceResponse<T> exists(@PathVariable String id) throws CrafterCommerceException {
        try {
            SolrQuery solrQuery = new SolrQuery(BaseType.SOLR_ID_FIELD + ":" + id);
            solrQuery.setRows(0);
            long numfound = solrServer.query(solrQuery).getResults().getNumFound();
            boolean exists = (numfound != 0) ? true : false;
            return new ServiceResponse<T>(getTypeArgument(), true, exists,
                    ReturnMessageProvider.existsMessage(getTypeArgument(), id, exists));
        } catch (Exception e) {
            LOGGER.error("Failed check if entity exists for id = " + id, e);
            return new ServiceResponse<T>(getTypeArgument(), false, e.getMessage());
        }
    }

    // ---------- Utility methods ----------

    private Set<T> toEntities(QueryResponse response) {
        SolrDocumentList solrDocList = response.getResults();
        Set<T> entities = new LinkedHashSet<T>(solrDocList.size());
        for (SolrDocument _solrDoc : solrDocList) {
            entities.add(documentObjectBinder.getBean(getTypeArgument(), _solrDoc));
        }
        return entities;
    }

    private Set<Facet> toFacets(QueryResponse response) {
        List<FacetField> facetFields = response.getFacetFields();
        Set<Facet> facets = new LinkedHashSet<Facet>(facetFields.size());
        Facet newFacet;
        FacetValue newFacetValue;
        for (FacetField _facetField : facetFields) {
            newFacet = new Facet(_facetField.getName());
            for (Count _count : _facetField.getValues()) {
                newFacetValue = new FacetValue(_count.getName(), _count.getCount());
                newFacet.getFacetValues().add(newFacetValue);
            }
            facets.add(newFacet);
        }
        return facets;
    }

}