001/*
002 *  Copyright 2019 Anyware Services
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 */
016package org.ametys.cms.search.query;
017
018import java.util.Objects;
019
020import org.apache.commons.lang3.StringUtils;
021import org.apache.solr.client.solrj.util.ClientUtils;
022
023/**
024 * <b>The use of this Query is discouraged. If possible (when from=id), use {@link JoinQuery} instead.</b>
025 * <br>Represents a Solr Join Query
026 */
027public class SolrNativeJoinQuery implements Query
028{
029    /** The "from" field of the join (the query is done on docs which hold this field) */
030    protected String _fromField;
031    /** The "to" field of the join (returned docs hold this field) */
032    protected String _toField;
033    /** The query to apply on joined docs */
034    protected Query _subQuery;
035    
036    /**
037     * <b>The use of this Query is discouraged. If possible (when from=id), use {@link JoinQuery} instead.</b>
038     * <br>Build a solr join query
039     * @param from The "from" field of the join (the query is done on docs which hold this field)
040     * @param to The "to" field of the join (returned docs holds this field)
041     * @param subQuery The sub query (query to apply on joined docs)
042     */
043    public SolrNativeJoinQuery(String from, String to, Query subQuery)
044    {
045        _fromField = from;
046        _toField = to;
047        _subQuery = subQuery;
048    }
049    
050    @Override
051    public String build() throws QuerySyntaxException
052    {
053        StringBuilder sb = new StringBuilder("{!join")
054                .append(" from=").append(_fromField)
055                .append(" to=").append(_toField)
056                .append(" v=\"").append(ClientUtils.escapeQueryChars(_subQuery.build())).append("\"")
057                .append("}");
058        return sb.toString();
059    }
060    
061    @Override
062    public String toString(int indent)
063    {
064        final String joinLineIndent = StringUtils.repeat(' ', indent);
065        final int subIndent = indent + 2;
066        final String subLineIndent = StringUtils.repeat(' ', subIndent);
067        final String from = subLineIndent + "[FROM]" + _fromField + "[/FROM]";
068        final String to = subLineIndent + "[TO]" + _toField + "[/TO]";
069        final String subq = subLineIndent + "[Q]" + (_subQuery == null ? String.valueOf(_subQuery) : ("\n" + _subQuery.toString(subIndent + 2) + "\n" + subLineIndent)) + "[/Q]";
070        return joinLineIndent + "[SOLRJOIN]\n" + from + "\n" + to + "\n" + subq + "\n" + joinLineIndent + "[/SOLRJOIN]";
071    }
072
073    @Override
074    public int hashCode()
075    {
076        return Objects.hash(_fromField, _subQuery, _toField);
077    }
078
079    @Override
080    public boolean equals(Object obj)
081    {
082        if (this == obj)
083        {
084            return true;
085        }
086        if (obj == null)
087        {
088            return false;
089        }
090        if (getClass() != obj.getClass())
091        {
092            return false;
093        }
094        SolrNativeJoinQuery other = (SolrNativeJoinQuery) obj;
095        return Objects.equals(_fromField, other._fromField) && Objects.equals(_subQuery, other._subQuery) && Objects.equals(_toField, other._toField);
096    }
097}