All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.wikitty.query.WikittyQueryResult Maven / Gradle / Ivy

The newest version!
/*
 * #%L
 * Wikitty :: api
 * %%
 * Copyright (C) 2012 CodeLutin, Benjamin Poussin
 * %%
 * This program 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.
 * 
 * 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 Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */
package org.nuiton.wikitty.query;

import java.io.Serializable;
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 org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.wikitty.WikittyClient;
import org.nuiton.wikitty.WikittyUtil;
import org.nuiton.wikitty.entities.BusinessEntity;
import org.nuiton.wikitty.entities.Element;

/**
 * Represente un resultat de requete {@link WikittyQuery}. Pour caster les
 * valeurs dans une autre representation vous pouvez utiliser la methode
 * {@link WikittyClient#castTo(java.lang.Class, org.nuiton.wikitty.query.WikittyQueryResult)}
 *
 * @author poussin
 * @version $Revision$
 * @since 3.3
 *
 * Last update: $Date$
 * by : $Author$
 */
public class WikittyQueryResult implements Serializable, Iterable {

    /** to use log facility, just put in your code: log.info(\"...\"); */
    static private Log log = LogFactory.getLog(WikittyQueryResult.class);

    private static final long serialVersionUID = 1L;

    /** nom du critere qui a ete uitilise (peut-etre null) si le critete n'avait pas de nom */
    protected String queryName;
    /** indice of offset result in global search result */
    protected int offset;
    /** total number of result if we call the query for all possible result */
    protected int totalResult;
    /** query really executed (internal representation depend of search engine used */
    protected String queryString;
    /** query used to produce initial WikittyQueryResult */
    protected WikittyQuery query;

    /** list of result in the wanted interval */
    protected List results;
    /** Wikitty ids resulting of where clause */
    protected List wikittyIdResult;
    /** if query contains select clause, contains select result */
    protected List> selectResult;
    /** facet asked or null if no facet */
    protected Map> facets;

    /** facet asked of null if no facet, FacetTopic are put in map with key topic name,
     * To use this variable, you must used getter, because, this variable is
     * lazy loaded from facets variable.
     */
    transient protected Map> facetsAsMap = null;

    /** temps (nanoseconde) mis pour faire la requete (calcul cote serveur)*/
    protected long timeQuery;
    /** temps (nanoseconde) de transformation des resultats bruts en un autre type(calcul cote client)*/
    protected long timeConvertion;


    /**
     * Init paged result.
     *
     * we don't initialize securityToken
     *
     * @param offset indice element in global search result
     * @param totalResult total number of result if we call the query for all possible result
     * @param queryString query really executed
     * @param facets facet asked or null if no facet
     * @param results list of result in the wanted interval
     */
    public WikittyQueryResult(String queryName,
            int offset, int totalResult, WikittyQuery query, String queryString,
            List results,
            List> selectResult,
            List wikittyIdResult,
            Map> facets, 
            long timeQuery, long timeConvertion) {
        this.queryName = queryName;
        this.offset = offset;
        this.totalResult = totalResult;
        this.query = query;
        this.queryString = queryString;
        this.results = Collections.unmodifiableList(results);
        this.selectResult = selectResult;
        this.wikittyIdResult = wikittyIdResult;
        this.facets = facets;
        this.timeQuery = timeQuery;
        this.timeConvertion = timeConvertion;
    }

    /**
     * if this WikittyQueryResult contains Map, and
     * each Map contains only one value, this methode return
     * new WikittyQueryResult with value only (no more map).
     *
     * If this WikittyQueryResult don't contains Map, then this is returned
     * 
     * @return 
     */
    public  WikittyQueryResult convertMapToSimple() {
         WikittyQueryResult result;

        if (results.isEmpty() || !(results.get(0) instanceof Map)) {
            result = (WikittyQueryResult)this;
        } else {
            List data = new ArrayList(results.size());

            for (Map map : (List)results) {
                if (map.size() != 1) {
                    throw new IllegalStateException(String.format(
                            "Map must have ONE element (currently %s", map.size()));
                }
                data.addAll(map.values());
            }

            result = new WikittyQueryResult(
                    queryName, offset, totalResult, query, queryString,
                    data, selectResult, wikittyIdResult, facets,
                    timeQuery, timeConvertion);
        }

        return result;
    }

    public WikittyQueryResult convertMapToSimpleString() {
         List dataObject = convertMapToSimple().getAll();

         List data = new ArrayList(dataObject.size());
         for (Object o : dataObject) {
             data.add(WikittyUtil.toString(o));
         }

         WikittyQueryResult result = new WikittyQueryResult(
                 queryName, offset, totalResult, query, queryString,
                 data, selectResult, wikittyIdResult, facets,
                 timeQuery, timeConvertion);

        return result;
    }

    /** nom du critere qui a ete uitilise (peut-etre null) si le critete n'avait pas de nom */
    public String getQueryName() {
        return queryName;
    }

    /**
     * 
     * @deprecated since 3.5 use {@link #getOffset()}
     */
    @Deprecated
    public int getFirst() {
        return offset;
    }

    /** indice of offset result in global search result */
    public int getOffset() {
        return offset;
    }

    /** total number of result if we call the query for all possible result */
    public int getTotalResult() {
        return totalResult;
    }

    /** query really executed (internal representation depend of search engine used */
    public String getQueryString() {
        return queryString;
    }

    /**
     * Return query used to initialise the first WikittyQueryResult (before
     * some transformation with getSelect or getWikitties). This query is
     * query realy send to server after some modification by WikittyClient if
     * necessary
     * @return
     * @since 3.10
     */
    public WikittyQuery getQuery() {
        return query;
    }

    /**
     * retourne le nombre de wikitty actuellement disponible dans le resultat
     * @return
     * @since 3.10
     */
    public int getWikittyResultSize() {
        int result = 0;
        if (wikittyIdResult != null) {
            result = wikittyIdResult.size();
        }
        return result;
    }

    /**
     * Retourne un nouveau WikittyQueryResult avec comme resultat la liste
     * des ids des wikitties selectionnes par la Query initiale
     * @return
     * @since 3.10
     */
    public WikittyQueryResult getWikittyResult() {
        WikittyQueryResult result = new WikittyQueryResult(
                queryName, offset, totalResult, query, queryString,
                wikittyIdResult, selectResult, wikittyIdResult, facets,
                timeQuery, timeConvertion);
        return result;
    }

    /**
     * Retourne un nouveau WikittyQueryResult avec comme resultat une liste
     * de BusinessEntity du type de la class passee en parametre a partir
     * des ids des wikitties selectionnes par la Query initiale
     * @return
     * @since 3.10
     */
    public  WikittyQueryResult getWikittyResult(
            WikittyClient client, Class clazz) {
        WikittyQueryResult result = getWikittyResult().castTo(client, clazz);
        return result;
    }

    /**
     * Indique s'il y a des resultats de select on non
     * @return
     * @since 3.10
     */
    public boolean hasSelectResult() {
        boolean result = CollectionUtils.isNotEmpty(selectResult);
        return result;
    }

    /**
     * Le nombre de map contenu dans le resultat de select
     * @return
     * @since 3.10
     */
    public int selectResultSize() {
        int result = 0;
        if (hasSelectResult()) {
            result = selectResult.size();
        }
        return result;
    }

    /**
     * Retourne la liste liste des noms disponible comme resulat de select
     * @return
     * @since 3.10
     */
    public List getSelectResultName() {
        List result = null;
        if (hasSelectResult()) {
            Map first = selectResult.get(0);
            result = new ArrayList(first.keySet());
        }
        return result;
    }

    /**
     * Retourne les resultats de select
     * @return
     * @since 3.10
     */
    public WikittyQueryResult> getSelectResult() {
        WikittyQueryResult> result = null;
        if (hasSelectResult()) {
            result = new WikittyQueryResult>(
                    queryName, offset, totalResult, query, queryString,
                    selectResult, selectResult, wikittyIdResult, facets,
                    timeQuery, timeConvertion);
        }
        return result;
    }

    /**
     * Retourne les resultats de select transforme en objet de type clazz
     *
     * @param 
     * @param client
     * @param clazz
     * @return
     * @since 3.10
     */
    public  WikittyQueryResult> getSelectResult(
            WikittyClient client, Class clazz) {
        WikittyQueryResult> result = getSelectResult().castToMap(client, clazz);
        return result;
    }

    /**
     * Retourne les resultats de select pour le champs demande
     * 
     * @param resultName
     * @return 
     * @since 3.10
     */
    public WikittyQueryResult getSelectResult(String resultName) {
        List data = new ArrayList(selectResultSize());
        for (Map m : selectResult) {
            data.add(m.get(resultName));
        }
        WikittyQueryResult result = new WikittyQueryResult(
                queryName, offset, totalResult, query, queryString,
                data, selectResult, wikittyIdResult, facets,
                timeQuery, timeConvertion);
        return result;
    }

    /**
     * Retourne les resultats de select pour le champs demande et le transforme
     * en objet de type clazz
     *
     * @param resultName
     * @return
     * @since 3.10
     */
    public  WikittyQueryResult getSelectResult(
            WikittyClient client, Class clazz, String resultName) {
        WikittyQueryResult result = getSelectResult(resultName).castTo(client, clazz);
        return result;
    }


    /**
     * Return name of all facet used in query.
     *
     * @return result's facets names
     */
    public Collection getFacetNames() {
        Collection result = facets.keySet();
        return result;
    }

    /**
     * Return all topic for the specified facet.
     *
     * @param facetName name of the wanted facet
     * @return facet's topics
     */
    public List getTopic(String facetName) {
        List result = facets.get(facetName);
        return result;
    }

    /**
     * Return all topic for the specified facet.
     *
     * @param facetName name of the wanted facet
     * @return facet's topics
     * @since 3.4
     */
    public List getTopic(Element facetName) {
        List result = getTopic(facetName.getValue());
        return result;
    }

    /**
     * Return topic for the specified facet and topic name.
     *
     * @param facetName name of the wanted facet
     * @param topicName name of the wanted topic
     * @return topic
     */
    public FacetTopic getTopic(String facetName, String topicName) {
        FacetTopic result = getFacetsAsMap().get(facetName).get(topicName);
        return result;
    }

    /**
     * Return topic count for the specified facet and topic name. If facet or
     * topic don't exist, return 0.
     *
     * @param facetName name of the wanted facet
     * @param topicName name of the wanted topic
     * @return topic count or 0
     */
    public int getTopicCount(String facetName, String topicName) {
        int result = 0;
        if (getFacetsAsMap() != null) {
            Map topics = getFacetsAsMap().get(facetName);
            if (topics != null) {
                FacetTopic topic = topics.get(topicName);
                if (topic != null) {
                    result = topic.getCount();
                }
            }
        }
        return result;
    }

    /**
     * Get map represent facets.
     *
     * return map of list
     * 
  • key is facet name *
  • value is topic liste une this facet * * @return all facets */ public Map> getFacets() { return facets; } /** * Get map represent facets. * * return map of map *
  • primary key is facet name *
  • secondary key is topic name *
  • value is topic * * @return */ public Map> getFacetsAsMap() { if (facetsAsMap == null && facets != null) { // use local variable to prevent multi-thread problem (multiple add) Map> localFacetsAsMap = new HashMap>(); for (Map.Entry> e : getFacets().entrySet()) { Map topics = new HashMap(); localFacetsAsMap.put(e.getKey(), topics); for (FacetTopic t : e.getValue()) { topics.put(t.getTopicName(), t); } } facetsAsMap = localFacetsAsMap; } return facetsAsMap; } /** * Return the offset element in result * * Can throw an exception if no element available * @return offset element */ public T peek() { T result = get(0); return result; } /** * Return element at index. * * @param i index * @return element at index */ public T get(int i) { T result = results.get(i); return result; } /** * Return unmodifiable list of all result. * * @return all results */ public List getAll() { return results; } /** * Return the number of result in this object. * * @return result number */ public int size() { int result = results.size(); return result; } /** * temps (nanoseconde) mis pour faire la requete (calcul cote serveur) */ public long getTimeQuery() { return timeQuery; } /** * temps (nanoseconde) mis pour faire la requete (calcul cote serveur) */ public void setTimeQuery(long timeQuery) { this.timeQuery = timeQuery; } /** * temps (nanoseconde) de transformation des resultats bruts en un autre * type(calcul cote client) */ public long getTimeConvertion() { return timeConvertion; } /** * temps (nanoseconde) de transformation des resultats bruts en un autre * type(calcul cote client) */ public void setTimeConvertion(long timeConvertion) { this.timeConvertion = timeConvertion; } /** * Iterate on result, same as getAll().iterator(). * @return */ public Iterator iterator() { Iterator result = getAll().iterator(); return result; } @Override public String toString() { String result = getQueryString() + " results " + getAll(); if (!getFacetNames().isEmpty()) { result += "\nfacets " + getFacets(); } return result; } /** * Convert all result to the wanted type and return new WikittyQueryResult * with this new result list. For business object transformation, if some * result don't have the right extension (clazz) this extension is * automatically added. * * @param queryResult result to convert * @param target to cast into. * Can be Wikitty, BusinessEntity, String, Date, Number (returned is BigDecimal), Boolean, byte[] * @return new WikittyQueryResult with element in right class or Exception * if conversion is impossible * @since 3.10 */ public WikittyQueryResult castTo(WikittyClient client, Class target) { WikittyQueryResult result; if (target == null || Map.class.isAssignableFrom(target)) { result = (WikittyQueryResult)this; } else { long startTime = System.nanoTime(); WikittyQueryResult queryResultFlated = convertMapToSimple(); List castedResult = client.castTo(target, queryResultFlated.getAll()); long estimatedTime = System.nanoTime() - startTime; result = new WikittyQueryResult( queryName, offset, totalResult, query, queryString, castedResult, selectResult, wikittyIdResult, facets, timeQuery, estimatedTime); } return result; } /** * Convert all result to the wanted type and return new WikittyQueryResult * with this new result list. For business object transformation, if some * result don't have the right extension (clazz) this extension is * automatically added. * * @param queryResult result to convert * @param target to cast into. * Can be Wikitty, BusinessEntity, String, Date, Number (returned is BigDecimal), Boolean, byte[] * @return new WikittyQueryResult with element in right class or Exception * if conversion is impossible * @since 3.10 */ public WikittyQueryResult> castToMap( WikittyClient client, Class target) { WikittyQueryResult> result; long startTime = System.nanoTime(); List> castedResult = client.castToMap(target, (List>)this.getAll()); long estimatedTime = System.nanoTime() - startTime; result = new WikittyQueryResult>( queryName, offset, totalResult, query, queryString, castedResult, selectResult, wikittyIdResult, facets, timeQuery, estimatedTime); return result; } }