/* * DrakkarKeel - An Enterprise Collaborative Search Platform * * The contents of this file are subject under the terms described in the * DRAKKARKEEL_LICENSE file included in this distribution; you may not use this * file except in compliance with the License. * * 2013-2014 DrakkarKeel Platform. */ package drakkar.mast.retrieval.improves; import drakkar.oar.DocumentMetaData; import drakkar.oar.ResultSetMetaData; import drakkar.oar.util.KeySearchable; import drakkar.mast.SearchException; import drakkar.mast.SearchableException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; /** * Esta clase maneja todos los métodos de búsqueda colaborativa con multiples * de buscadores que pueden ser invocados por los clientes * * */ public class CollaborativeMultiSearch extends SearchFactory { private DefaultMultiSearch defMultisearch; /** * Constructor de la clase * * @param searchers lista buscadores * @param defMultisearch objeto DefaultMultiSearch */ public CollaborativeMultiSearch(DefaultMultiSearch defMultisearch) { super(defMultisearch.getSearchersHash(), defMultisearch.getSearchableList()); this.defMultisearch = defMultisearch; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con todos los * buscadores activos en el servidor * * @param query consulta de la búsqueda * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda */ public List<ResultSetMetaData> search(String query, boolean caseSensitive, int members) throws SearchException { ResultSetMetaData results = this.defMultisearch.search(query, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con todos los * buscadores activos en el servidor * * @param query consulta de la búsqueda * @param field campo del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda */ public List<ResultSetMetaData> search(String query, int field, boolean caseSensitive, int members) throws SearchException { ResultSetMetaData results = this.defMultisearch.search(query, field, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con todos los * buscadores activos en el servidor * * @param query consulta de la búsqueda * @param fields campos del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda */ public List<ResultSetMetaData> search(String query, int[] fields, boolean caseSensitive, int members) throws SearchException { ResultSetMetaData results = this.defMultisearch.search(query, fields, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con todos los * buscadores activos en el servidor * * @param query consulta de la búsqueda * @param docType tipo del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda */ public List<ResultSetMetaData> search(String query, String docType, boolean caseSensitive, int members) throws SearchException { ResultSetMetaData results = this.defMultisearch.search(query, docType, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con todos los * buscadores activos en el servidor * * @param query consulta de la búsqueda * @param docTypes tipo del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda */ public List<ResultSetMetaData> search(String query, String[] docTypes, boolean caseSensitive, int members) throws SearchException { ResultSetMetaData results = this.defMultisearch.search(query, docTypes, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con todos los * buscadores activos en el servidor * * @param query consulta de la búsqueda * @param docType tipo del documento * @param field campo del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda */ public List<ResultSetMetaData> search(String query, String docType, int field, boolean caseSensitive, int members) throws SearchException { ResultSetMetaData results = this.defMultisearch.search(query, docType, field, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con todos los * buscadores activos en el servidor * * @param query consulta de la búsqueda * @param docType tipo del documento * @param fields campos del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda */ public List<ResultSetMetaData> search(String query, String docType, int[] fields, boolean caseSensitive, int members) throws SearchException { ResultSetMetaData results = this.defMultisearch.search(query, docType, fields, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con todos los * buscadores activos en el servidor * * @param query consulta de la búsqueda * @param docTypes tipo del documento * @param field campo ó campos del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda */ public List<ResultSetMetaData> search(String query, String[] docTypes, int field, boolean caseSensitive, int members) throws SearchException { ResultSetMetaData results = this.defMultisearch.search(query, docTypes, field, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con todos los * buscadores activos en el servidor * * @param query consulta de la búsqueda * @param docTypes tipo del documento * @param fields campos del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda */ public List<ResultSetMetaData> search(String query, String[] docTypes, int[] fields, boolean caseSensitive, int members) throws SearchException { ResultSetMetaData results = this.defMultisearch.search(query, docTypes, fields, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con los * buscadores selecionados * * @param searchers buscadores * @param query consulta de la búsqueda * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda * @throws SearchableException si el buscador no se encuentra disponible * * <br> * <br> * <b>Nota:</b> * <br> * Las constantes que representan los diferentes buscadores soportados, se encuentran * definidas en la clase <code>KeySearchable</code>, del paquete drakkar.oar.util * <br> * <br> * * @see KeySearchable * */ public List<ResultSetMetaData> search(int[] searchers, String query, boolean caseSensitive, int members) throws SearchException, SearchableException { ResultSetMetaData results = this.defMultisearch.search(searchers, query, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con los * buscadores selecionados * * @param searchers buscadores * @param query consulta de la búsqueda * @param field campo del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda * @throws SearchableException si el buscador no se encuentra disponible * * <br> * <br> * <b>Nota:</b> * <br> * Las constantes que representan los diferentes buscadores soportados, se encuentran * definidas en la clase <code>KeySearchable</code>, del paquete drakkar.oar.util * <br> * <br> * * @see KeySearchable * */ public List<ResultSetMetaData> search(int[] searchers, String query, int field, boolean caseSensitive, int members) throws SearchException, SearchableException { ResultSetMetaData results = this.defMultisearch.search(searchers, query, field, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con los * buscadores selecionados * * @param searchers buscadores * @param query consulta de la búsqueda * @param fields campos del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda * @throws SearchableException si el buscador no se encuentra disponible * * <br> * <br> * <b>Nota:</b> * <br> * Las constantes que representan los diferentes buscadores soportados, se encuentran * definidas en la clase <code>KeySearchable</code>, del paquete drakkar.oar.util * <br> * <br> * * @see KeySearchable * */ public List<ResultSetMetaData> search(int[] searchers, String query, int[] fields, boolean caseSensitive, int members) throws SearchException, SearchableException { ResultSetMetaData results = this.defMultisearch.search(searchers, query, fields, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con los * buscadores selecionados * * @param searchers buscadores * @param query consulta de la búsqueda * @param docType tipo del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda * @throws SearchableException si el buscador no se encuentra disponible * * <br> * <br> * <b>Nota:</b> * <br> * Las constantes que representan los diferentes buscadores soportados, se encuentran * definidas en la clase <code>KeySearchable</code>, del paquete drakkar.oar.util * <br> * <br> * * @see KeySearchable * */ public List<ResultSetMetaData> search(int[] searchers, String query, String docType, boolean caseSensitive, int members) throws SearchException, SearchableException { ResultSetMetaData results = this.defMultisearch.search(searchers, query, docType, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con los * buscadores selecionados * * @param searchers buscadores * @param query consulta de la búsqueda * @param docTypes tipo del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda * @throws SearchableException si el buscador no se encuentra disponible * * <br> * <br> * <b>Nota:</b> * <br> * Las constantes que representan los diferentes buscadores soportados, se encuentran * definidas en la clase <code>KeySearchable</code>, del paquete drakkar.oar.util * <br> * <br> * * @see KeySearchable * */ public List<ResultSetMetaData> search(int[] searchers, String query, String[] docTypes, boolean caseSensitive, int members) throws SearchException, SearchableException { ResultSetMetaData results = this.defMultisearch.search(searchers, query, docTypes, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con los * buscadores selecionados * * @param searchers buscadores * @param query consulta de la búsqueda * @param docType tipo del documento * @param field campo del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda * @throws SearchableException si el buscador no se encuentra disponible * * <br> * <br> * <b>Nota:</b> * <br> * Las constantes que representan los diferentes buscadores soportados, se encuentran * definidas en la clase <code>KeySearchable</code>, del paquete drakkar.oar.util * <br> * <br> * * @see KeySearchable * */ public List<ResultSetMetaData> search(int[] searchers, String query, String docType, int field, boolean caseSensitive, int members) throws SearchException, SearchableException { ResultSetMetaData results = this.defMultisearch.search(searchers, query, docType, field, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con los * buscadores selecionados * * @param searchers buscadores * @param query consulta de la búsqueda * @param docType tipo del documento * @param fields campos del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda * @throws SearchableException si el buscador no se encuentra disponible * * <br> * <br> * <b>Nota:</b> * <br> * Las constantes que representan los diferentes buscadores soportados, se encuentran * definidas en la clase <code>KeySearchable</code>, del paquete drakkar.oar.util * <br> * <br> * * @see KeySearchable * */ public List<ResultSetMetaData> search(int[] searchers, String query, String docType, int[] fields, boolean caseSensitive, int members) throws SearchException, SearchableException { ResultSetMetaData results = this.defMultisearch.search(searchers, query, docType, fields, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con los * buscadores selecionados * * @param searchers buscadores * @param query consulta de la búsqueda * @param docTypes tipo del documento * @param field campo ó campos del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda * @throws SearchableException si el buscador no se encuentra disponible * * <br> * <br> * <b>Nota:</b> * <br> * Las constantes que representan los diferentes buscadores soportados, se encuentran * definidas en la clase <code>KeySearchable</code>, del paquete drakkar.oar.util * <br> * <br> * * @see KeySearchable * */ public List<ResultSetMetaData> search(int[] searchers, String query, String[] docTypes, int field, boolean caseSensitive, int members) throws SearchException, SearchableException { ResultSetMetaData results = this.defMultisearch.search(searchers, query, docTypes, field, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } /** * Invoca una búsqueda a partir de los parámetros de entrada, aplicando el * principio MultiSearch y mecanismos de división del trabajo, con los * buscadores selecionados * * @param searchers buscadores * @param query consulta de la búsqueda * @param docTypes tipo del documento * @param fields campo ó campos del documento * @param caseSensitive tener en cuenta mayúsculas y minísculas * @param members número de miembros de la sesión * * @return lista de documentos encontrados * * @throws SearchException si ocurre alguna excepción durante el proceso de búsqueda * @throws SearchableException si el buscador no se encuentra disponible * * <br> * <br> * <b>Nota:</b> * <br> * Las constantes que representan los diferentes buscadores soportados, se encuentran * definidas en la clase <code>KeySearchable</code>, del paquete drakkar.oar.util * <br> * <br> * * @see KeySearchable * */ public List<ResultSetMetaData> search(int[] searchers, String query, String[] docTypes, int[] fields, boolean caseSensitive, int members) throws SearchException, SearchableException { ResultSetMetaData results = this.defMultisearch.search(searchers, query, docTypes, fields, caseSensitive); List<ResultSetMetaData> finalResults = this.multiSearch(results, members); return finalResults; } private List<ResultSetMetaData> multiSearch(ResultSetMetaData results, int members) { int searcherCount = results.getSearchersCount(); if (searcherCount == members) { Map<Integer, List<DocumentMetaData>> values = results.getResultsMap(); List<ResultSetMetaData> finalResults = new ArrayList<ResultSetMetaData>(); Set<Integer> keys = values.keySet(); for (Integer key : keys) { ResultSetMetaData item = new ResultSetMetaData(results.getQuery()); item.add(key, values.get(key)); finalResults.add(item); } return finalResults; } else { List<ResultSetMetaData> finalResults = this.divideSearchResults(results, members, searcherCount); return finalResults; } } /** * Este método es empleado internamente por los métodos de búsqueda que aplican * mecanismos de división del trabajo, para distribuir los resultados obtenidos * por cada buscador entre los miembros de la sesión * * @param ResultSetMetaData resultadosde la búsqueda * @param members número de miembros. * * @return lista con los resultados a enviar a cada miembro de la sesión */ private List<ResultSetMetaData> divideSearchResults(ResultSetMetaData searchResults, int members, int searchersCount) { List<ResultSetMetaData> finalResults = new ArrayList<ResultSetMetaData>(); Map<Integer, List<DocumentMetaData>> values = searchResults.getResultsMap(); String query = searchResults.getQuery(); if (members > searchersCount) { int x = members / searchersCount; int y = x * searchersCount; int z = members - y; List<ResultSetMetaData> temp; Set<Integer> keys = values.keySet(); int w = 0; for (Integer searcher : keys) { if (z > 0) { w = x + 1; temp = this.divideSearchResults(query, searcher, values.get(searcher), w); finalResults.addAll(temp); z--; } else { temp = this.divideSearchResults(query, searcher, values.get(searcher), x); finalResults.addAll(temp); } } } else { int x = searchersCount / members; int y = x * members; int z = searchersCount - y; List<ResultSetMetaData> results = new ArrayList<ResultSetMetaData>(); ResultSetMetaData temp; List<Integer> keyCollection = new ArrayList<Integer>(); Set<Integer> keyTemp = values.keySet(); for (Integer item : keyTemp) { keyCollection.add(item); } List<List<DocumentMetaData>> valueCollection = new ArrayList<List<DocumentMetaData>>(values.values()); int w = 0; int count; int j = 0; for (int i = 0; i < members; i++) { count = 0; if (z > 0) { w = x + 1; temp = new ResultSetMetaData(query); while (count < w) { temp.add(keyCollection.get(j), valueCollection.get(j)); j++; count++; } results.add(temp); z--; } else { temp = new ResultSetMetaData(query); while (count < x) { temp.add(keyCollection.get(j), valueCollection.get(j)); j++; count++; } results.add(temp); } }// end for return results; } return null; } private List<ResultSetMetaData> divideSearchResults(String query, int searcher, List<DocumentMetaData> values, int members) { List<ResultSetMetaData> list = this.getResultsList(query, searcher, members); DocumentMetaData doc = null; List<DocumentMetaData> valueTemp; ResultSetMetaData itemList; Map<Integer, List<DocumentMetaData>> itemHash; int size = values.size(); int x = size / members; int r = members * x; int a = size - r; int count = 0; for (int i = 0; i < r; i += members) { count = i; for (int j = 0; j < members; j++) { itemList = list.get(j); itemHash = itemList.getResultsMap(); valueTemp = itemHash.get(searcher); doc = values.get(count); valueTemp.add(doc); count++; } } for (int j = 0; j < a; j++) { itemList = list.get(j); itemHash = itemList.getResultsMap(); valueTemp = itemHash.get(searcher); doc = values.get(count); valueTemp.add(doc); count++; } return list; } /** * Este método es empleado internamente por el método * <code>divideSearchResults(ResultSetMetaData ResultSetMetaData, int members)</code> * para obtener una lista que almacenará la lista de documentos por cada usuario * de la sesión * * @param members número de miembros de la sesión * * @return lista de documentos. */ private List<ResultSetMetaData> getResultsList(String query, int searcher, int members) { List<ResultSetMetaData> list = new ArrayList<ResultSetMetaData>(members); for (int i = 0; i < members; i++) { list.add(new ResultSetMetaData(query, searcher)); } return list; } /** * * @return */ public DefaultMultiSearch getDefaultMultisearch() { return defMultisearch; } /** * * @param defMultisearch */ public void setDefaultMultisearch(DefaultMultiSearch defMultisearch) { this.defMultisearch = defMultisearch; } }