/** * License Agreement for OpenSearchServer * * Copyright (C) 2008-2015 Emmanuel Keller / Jaeksoft * * http://www.open-search-server.com * * This file is part of OpenSearchServer. * * OpenSearchServer 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. * * OpenSearchServer 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 OpenSearchServer. * If not, see <http://www.gnu.org/licenses/>. **/ package com.jaeksoft.searchlib.result; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import com.jaeksoft.searchlib.SearchLibException; import com.jaeksoft.searchlib.collapse.CollapseFunctionField; import com.jaeksoft.searchlib.function.expression.SyntaxError; import com.jaeksoft.searchlib.index.ReaderAbstract; import com.jaeksoft.searchlib.index.ReaderInterface; import com.jaeksoft.searchlib.query.ParseException; import com.jaeksoft.searchlib.request.AbstractLocalSearchRequest; import com.jaeksoft.searchlib.request.ReturnField; import com.jaeksoft.searchlib.result.collector.CollapseDocInterface; import com.jaeksoft.searchlib.result.collector.DocIdInterface; import com.jaeksoft.searchlib.schema.AbstractField; import com.jaeksoft.searchlib.schema.FieldValue; import com.jaeksoft.searchlib.schema.FieldValueItem; import com.jaeksoft.searchlib.schema.FieldValueOriginEnum; import com.jaeksoft.searchlib.snippet.SnippetField; import com.jaeksoft.searchlib.snippet.SnippetFieldValue; import com.jaeksoft.searchlib.util.Timer; import com.jaeksoft.searchlib.webservice.query.document.DocumentResult.Position; import com.jaeksoft.searchlib.webservice.query.document.FunctionFieldValue; public class ResultDocument { final private LinkedHashMap<String, FieldValue> returnFields; final private LinkedHashMap<String, SnippetFieldValue> snippetFields; final private int docId; final private List<FunctionFieldValue> functionFieldValue; final private List<Position> positions; final private String joinParameter; final private List<ResultDocument> collapsedDocuments; final private float score; public ResultDocument(final AbstractLocalSearchRequest searchRequest, final LinkedHashSet<String> fieldSet, final int docId, final ReaderInterface reader, final float score, final String joinParameter, final int collapsedDocumentCount, final Timer timer) throws IOException, ParseException, SyntaxError, SearchLibException { this.docId = docId; returnFields = new LinkedHashMap<String, FieldValue>(); snippetFields = new LinkedHashMap<String, SnippetFieldValue>(); functionFieldValue = new ArrayList<FunctionFieldValue>(0); positions = new ArrayList<Position>(0); collapsedDocuments = collapsedDocumentCount == 0 ? null : new ArrayList<ResultDocument>(0); this.joinParameter = joinParameter; this.score = score; if (docId < 0) return; Timer mainTimer = new Timer(timer, "ResultDocument"); Timer t = new Timer(mainTimer, "returnField(s)"); Map<String, FieldValue> documentFields = reader.getDocumentFields(docId, fieldSet, t); for (ReturnField field : searchRequest.getReturnFieldList()) { String fieldName = field.getName(); FieldValue fieldValue = documentFields.get(fieldName); if (fieldValue != null) returnFields.put(fieldName, fieldValue); } t.end(null); t = new Timer(mainTimer, "snippetField(s)"); for (SnippetField field : searchRequest.getSnippetFieldList()) { String fieldName = field.getName(); field.initSearchTerms(searchRequest); List<FieldValueItem> snippets = new ArrayList<FieldValueItem>(); boolean isHighlighted = false; FieldValue fieldValue = documentFields.get(fieldName); if (fieldValue != null) isHighlighted = field.getSnippets(docId, reader, fieldValue.getValueList(), snippets, t); SnippetFieldValue snippetFieldValue = new SnippetFieldValue(fieldName, snippets, isHighlighted); snippetFields.put(fieldName, snippetFieldValue); } t.end(null); mainTimer.end(null); } public ResultDocument(LinkedHashSet<String> fieldSet, int docId, ReaderInterface reader, float score, String joinParameter, Timer timer) throws IOException, ParseException, SyntaxError, SearchLibException { this.docId = docId; returnFields = reader.getDocumentFields(docId, fieldSet, timer); snippetFields = new LinkedHashMap<String, SnippetFieldValue>(); collapsedDocuments = null; positions = new ArrayList<Position>(0); functionFieldValue = null; this.score = score; this.joinParameter = joinParameter; } public ResultDocument(Integer docId) { this.docId = docId; returnFields = new LinkedHashMap<String, FieldValue>(); snippetFields = new LinkedHashMap<String, SnippetFieldValue>(); collapsedDocuments = null; positions = new ArrayList<Position>(0); functionFieldValue = null; joinParameter = null; score = 0; } public static <T> List<T> toList(Map<String, T> map) { List<T> list = new ArrayList<T>(0); for (T fv : map.values()) list.add(fv); return list; } public Map<String, FieldValue> getReturnFields() { return returnFields; } public Map<String, SnippetFieldValue> getSnippetFields() { return snippetFields; } public List<FieldValueItem> getValues(AbstractField<?> field) { if (field == null) return null; return getValues(field.getName()); } public List<FieldValueItem> getValues(String fieldName) { if (fieldName == null) return null; FieldValue fieldValue = returnFields.get(fieldName); if (fieldValue == null) return null; return fieldValue.getValueList(); } public String getValueContent(AbstractField<?> field, int pos) { List<FieldValueItem> values = getValues(field); if (values == null) return null; if (pos >= values.size()) return null; return values.get(pos).getValue(); } public String getValueContent(String fieldName, int pos) { FieldValue field = returnFields.get(fieldName); if (field == null) return null; return getValueContent(field, pos); } final public List<FieldValueItem> getSnippetValues(SnippetField field) { if (field == null) return null; return getSnippetValues(field.getName()); } final public List<FieldValueItem> getSnippetValue(SnippetField field) { if (field == null) return null; return getSnippetValues(field.getName()); } final public List<FieldValueItem> getSnippetValues(String fieldName) { SnippetFieldValue fieldValue = snippetFields.get(fieldName); if (fieldValue == null) return null; return fieldValue.getValueList(); } public List<FieldValueItem> getSnippetList(String fieldName) { SnippetFieldValue snippetFieldValue = snippetFields.get(fieldName); if (snippetFieldValue == null) return null; return snippetFieldValue.getValueList(); } final public List<FieldValueItem> getSnippetList(AbstractField<?> field) { if (field == null) return null; return getSnippetList(field.getName()); } final public FieldValueItem getSnippet(String fieldName, int pos) { List<FieldValueItem> values = getSnippetValues(fieldName); if (values == null) return null; if (pos >= values.size()) return null; return values.get(pos); } final public String getSnippetContent(String fieldName, int pos) { FieldValueItem fieldValue = getSnippet(fieldName, pos); if (fieldValue == null) return null; return fieldValue.getValue(); } final public boolean isHighlighted(String fieldName) { return snippetFields.get(fieldName).isHighlighted(); } public void appendIfStringDoesNotExist(ResultDocument rd) { for (FieldValue newFieldValue : rd.returnFields.values()) { String fieldName = newFieldValue.getName(); FieldValue fieldValue = returnFields.get(fieldName); if (fieldValue == null) returnFields.put(fieldName, fieldValue); else fieldValue.addIfStringDoesNotExist(newFieldValue.getValueList()); } for (SnippetFieldValue newFieldValue : rd.snippetFields.values()) { String fieldName = newFieldValue.getName(); SnippetFieldValue fieldValue = snippetFields.get(fieldName); if (fieldValue == null) snippetFields.put(fieldName, fieldValue); else fieldValue.addIfStringDoesNotExist(newFieldValue.getValueList()); } } public void addReturnedField(FieldValueOriginEnum origin, String field, String value) { FieldValue fieldValue = returnFields.get(field); if (fieldValue == null) { fieldValue = new FieldValue(field); returnFields.put(field, fieldValue); } fieldValue.addValues(new FieldValueItem(origin, value)); } public void addReturnedFields(FieldValue newFieldValue) { if (newFieldValue == null) return; if (newFieldValue.getValuesCount() == 0) return; String field = newFieldValue.getName(); FieldValue fieldValue = returnFields.get(field); if (fieldValue == null) { fieldValue = new FieldValue(field); returnFields.put(field, fieldValue); } fieldValue.addValues(newFieldValue.getValueList()); } public void addPosition(Position position) { positions.add(position); } public void addCollapsedDocument(ResultDocument document) { collapsedDocuments.add(document); } public List<ResultDocument> getCollapsedDocuments() { return collapsedDocuments; } public void addFunctionField(CollapseFunctionField functionField, ReaderAbstract reader, int pos, Timer timer) throws IOException, java.text.ParseException, InstantiationException, IllegalAccessException { functionFieldValue.add(new FunctionFieldValue(functionField, functionField.executeByPos(pos))); } public List<FunctionFieldValue> getFunctionFieldValues() { return functionFieldValue; } final public static int[] getDocIds(DocIdInterface docs) { if (docs == null) return null; return docs.getIds(); } final public static int getCollapseCount(DocIdInterface docs, int pos) { if (docs == null) return 0; if (!(docs instanceof CollapseDocInterface)) return 0; return ((CollapseDocInterface) docs).getCollapseCounts()[pos]; } public int getDocId() { return docId; } public float getScore() { return score; } public String getJoinParameter() { return joinParameter; } public List<Position> getPositions() { return positions; } public void addPositions(Collection<Position> positions) { if (positions != null) this.positions.addAll(positions); } }