aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/search/result/DefaultErrorHit.java
blob: 54b83544b1a2547f510588bb016ab76b6db03772 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.search.result;

import com.yahoo.collections.ArraySet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * A hit which holds a list of error conditions in a result.
 *
 * @author bratseth
 * @author Steinar Knutsen
 */
public class DefaultErrorHit extends Hit implements ErrorHit, Cloneable {

    // TODO: Check that nobody implements ErrorHit, rename this to ErrorHit, and make an empty, deprecated subclass DefaultErrorHit
    
    /**
     * A list of unique error messages, where the first is considered the "main"
     * error. It should always contain at least one error.
     */
    private List<ErrorMessage> errors = new ArrayList<>();

    /**
     * Creates an error hit with one error
     *
     * @param source the name of the source or backend of this hit
     * @param error an initial error to add to this hit, cannot be null
     */
    public DefaultErrorHit(String source, ErrorMessage error) {
        super("error:" + source, new Relevance(Double.POSITIVE_INFINITY), source);
        addError(error);
    }

    /**
     * Creates an error hit with a list of errors
     *
     * @param source the name of the source or backend of this hit
     * @param errors a list of errors for this to hold. The list will not be modified or retained.
     */
    public DefaultErrorHit(String source, List<ErrorMessage> errors) {
        super("error:" + source, new Relevance(Double.POSITIVE_INFINITY), source);
        for (ErrorMessage error : errors)
            addError(error);
    }

    public void setSource(String source) {
        super.setSource(source);
        for (Iterator<ErrorMessage> i = errorIterator(); i.hasNext();) {
            ErrorMessage error = i.next();

            if (error.getSource() == null) {
                error.setSource(source);
            }
        }
    }

    /**
     * Returns the main error of this result, never null.
     *
     * @deprecated use {@link #errors()}
     */
    @Override
    @Deprecated // OK
    // TODO: Remove on Vespa 7
    public ErrorMessage getMainError() {
        return errors.get(0);
    }

    /**
     * This is basically a way of making a list simulate a set.
     */
    private void removeAndAdd(ErrorMessage error) {
        errors.remove(error);
        errors.add(error);
    }

    /** Adds an error to this */
    public void addError(ErrorMessage error) {
        if (error.getSource() == null)
            error.setSource(getSource());
        removeAndAdd(error);
    }


    /** Add all errors from another error hit to this */
    public void addErrors(ErrorHit errorHit) {
        for (Iterator<? extends ErrorMessage> i = errorHit.errorIterator(); i.hasNext();) {
            addError(i.next());
        }
    }

    /**
     * Returns all the detail errors of this error hit, not including the main error.
     * The iterator is modifiable.
     */
    public Iterator<ErrorMessage> errorIterator() {
        return errors.iterator();
    }

    /** Returns a read-only set containing all the error of this */
    public Set<ErrorMessage> errors() {
        Set<ErrorMessage> s = new ArraySet<>(errors.size());
        s.addAll(errors);
        return s;
    }

    @Override
    public String toString() {
        return "Error: " + errors.get(0).toString();
    }

    /** Returns true - this is a meta hit containing information on other hits */
    public boolean isMeta() {
        return true;
    }

    /**
     * Returns true if all errors in this have the given code
     */
    public boolean hasOnlyErrorCode(int code) {
        for (ErrorMessage error : errors) {
            if (error.getCode() != code)
                return false;
        }
        return true;
    }

    public DefaultErrorHit clone() {
        DefaultErrorHit clone = (DefaultErrorHit) super.clone();

        clone.errors = new ArrayList<>(this.errors);
        return clone;
    }

}