001/*
002 * (C) Copyright 2015-2018 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Benoit Delbosc
018 */
019
020package org.nuxeo.ecm.core.query.sql.model;
021
022import java.util.Arrays;
023import java.util.Collections;
024import java.util.List;
025import java.util.stream.Collectors;
026
027import org.apache.commons.lang3.StringUtils;
028
029public class EsHint implements Operand {
030
031    private static final long serialVersionUID = 4590329982296853715L;
032
033    public final String index;
034
035    public final String analyzer;
036
037    public final String operator;
038
039    public EsHint(EsIdentifierList index, String analyzer, String operator) {
040        this.index = (index == null) ? null : index.toString();
041        this.analyzer = analyzer;
042        this.operator = operator;
043    }
044
045    @Override
046    public void accept(IVisitor visitor) {
047    }
048
049    @Override
050    public String toString() {
051        StringBuilder sb = new StringBuilder();
052        sb.append("/*+ES: ");
053        if (index != null) {
054            sb.append(String.format("INDEX(%s) ", index));
055        }
056        if (analyzer != null) {
057            sb.append(String.format("ANALYZER(%s) ", analyzer));
058        }
059        if (operator != null) {
060            sb.append(String.format("OPERATOR(%s) ", operator));
061        }
062        sb.append("*/");
063        return sb.toString();
064    }
065
066    @Override
067    public boolean equals(Object obj) {
068        if (obj == this) {
069            return true;
070        }
071        if (!(obj instanceof EsHint)) {
072            return false;
073        }
074        return equals((EsHint) obj);
075    }
076
077    private boolean equals(EsHint other) {
078        return StringUtils.equals(index, other.index) && StringUtils.equals(analyzer, other.analyzer)
079                && StringUtils.equals(operator, other.operator);
080    }
081
082    /**
083     * Get Index field hints
084     */
085    public List<FieldHint> getIndex() {
086        if (index == null) {
087            return Collections.emptyList();
088        }
089        String[] fields = index.split(",");
090        return Arrays.stream(fields).map(FieldHint::new).collect(Collectors.toList());
091    }
092
093    /**
094     * Get Index field names (without boost)
095     */
096    public String[] getIndexFieldNames() {
097        return getIndex().stream().map(FieldHint::getField).toArray(String[]::new);
098    }
099
100    /**
101     * A field specified using a hint, with optional boost value
102     */
103    public static class FieldHint {
104        public static final float DEFAULT_BOOST = 1.0F;
105
106        protected final String field;
107
108        protected final float boost;
109
110        public FieldHint(String indexField) {
111            String[] parsed = indexField.split("\\^");
112            this.field = parsed[0];
113            if (parsed.length > 1) {
114                this.boost = Float.parseFloat(parsed[1]);
115            } else {
116                this.boost = DEFAULT_BOOST;
117            }
118        }
119
120        public FieldHint(String field, Float boost) {
121            this.field = field;
122            this.boost = boost == null ? DEFAULT_BOOST : boost;
123        }
124
125        public String getField() {
126            return field;
127        }
128
129        public float getBoost() {
130            return boost;
131        }
132    }
133}