aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/search/query/parser/Parsable.java
blob: 76c9778f8e814341f7e4a2033f87b59a913eb50a (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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.search.query.parser;

import com.yahoo.language.Language;
import com.yahoo.search.query.Model;
import com.yahoo.search.query.Select;

import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

/**
 * <p>This class encapsulates all the parameters required to call {@link Parser#parse(Parsable)}. Because all set-
 * methods return a reference to self, you can write very compact calls to the parser:</p>
 *
 * <pre>
 * parser.parse(new Parsable()
 *                  .setQuery("foo")
 *                  .setFilter("bar")
 *                  .setDefaultIndexName("default")
 *                  .setLanguage(Language.ENGLISH))
 * </pre>
 *
 * <p>In case you are parsing the content of a {@link Model}, you can use the {@link #fromQueryModel(Model)} factory for
 * convenience.</p>
 *
 * @author Simon Thoresen Hult
 */
public final class Parsable {

    private final Set<String> sourceList = new HashSet<>();
    private final Set<String> restrictList = new HashSet<>();
    private String query;
    private String filter;
    private String defaultIndexName;
    private Language language; // TODO: Initialize to UNKNOWN
    private Optional<Language> explicitLanguage = Optional.empty();
    private Select select;

    /** If this is set it will be used to determine the language, if not set explicitly */
    private Optional<Model> model = Optional.empty();

    public String getQuery() {
        return query;
    }

    public Parsable setQuery(String query) {
        this.query = query;
        return this;
    }

    public String getFilter() {
        return filter;
    }

    public Parsable setFilter(String filter) {
        this.filter = filter;
        return this;
    }

    public String getDefaultIndexName() {
        return defaultIndexName;
    }

    public Parsable setDefaultIndexName(String defaultIndexName) {
        this.defaultIndexName = defaultIndexName;
        return this;
    }

    /** 
     * Returns the language to use when parsing, or null to decide during parsing.
     */
    public Language getLanguage() {
        return language;
    }

    /**
     * Returns the language to use when parsing, with a text to use for detection if necessary.
     * if not decided by the item under parsing. This is never null or UNKNOWN 
     */
    public Language getOrDetectLanguage(String languageDetectionText) {
        if (language != null  && language != Language.UNKNOWN) return language;
        if (model.isPresent()) return model.get().getParsingLanguage(languageDetectionText);
        return Language.UNKNOWN; // against the promise in the JavaDoc, but it is not locally ensured
    }

    public Parsable setLanguage(Language language) {
        Objects.requireNonNull(language, "Language cannot be null");
        this.language = language;
        return this;
    }
    
    /** Returns the language explicitly set to be used when parsing, or empty if none is set. */
    public Optional<Language> getExplicitLanguage() { return explicitLanguage; }

    public Parsable setExplicitLanguage(Optional<Language> language) {
        Objects.requireNonNull(language, "Explicit language cannot be null");
        this.explicitLanguage = language;
        return this;
    }

    public Parsable setModel(Model model) {
        Objects.requireNonNull(model, "Model cannot be null");
        this.model = Optional.of(model);
        return this;
    }
    
    public Set<String> getSources() {
        return sourceList;
    }

    public Parsable addSource(String sourceName) {
        sourceList.add(sourceName);
        return this;
    }

    public Parsable addSources(Collection<String> sourceNames) {
        sourceList.addAll(sourceNames);
        return this;
    }

    public Set<String> getRestrict() {
        return restrictList;
    }

    public Parsable addRestrict(String restrictName) {
        restrictList.add(restrictName);
        return this;
    }

    public Parsable addRestricts(Collection<String> restrictNames) {
        restrictList.addAll(restrictNames);
        return this;
    }

    public Parsable setSelect(Select select){
        this.select = select;
        return this;
    }

    public Select getSelect(){
        return this.select;
    }

    public static Parsable fromQueryModel(Model model) {
        return new Parsable()
                .setModel(model)
                .setQuery(model.getQueryString())
                .setFilter(model.getFilter())
                .setExplicitLanguage(Optional.ofNullable(model.getLanguage()))
                .setDefaultIndexName(model.getDefaultIndex())
                .addSources(model.getSources())
                .addRestricts(model.getRestrict())
                .setSelect(model.getParent().getSelect());
    }




}