001/* 002 * Copyright 2017 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.join; 017 018import java.util.Objects; 019import java.util.Optional; 020 021import org.apache.solr.client.solrj.util.ClientUtils; 022 023import org.ametys.cms.search.query.JoinQuery; 024import org.ametys.cms.search.query.Query; 025import org.ametys.cms.search.query.QuerySyntaxException; 026 027/** 028 * Class representing a join key and its (optional) nested query for creating a {@link JoinQuery} 029 */ 030public class JoinKey 031{ 032 private String _key; 033 private Optional<String> _joinField; 034 private Optional<Query> _nestedQuery; 035 036 /** 037 * Creates a JoinKey 038 * @param key The key. Cannot be null 039 */ 040 public JoinKey(String key) 041 { 042 this(key, null, null); 043 } 044 045 /** 046 * Creates a JoinKey 047 * @param key The key. Cannot be null 048 * @param nestedQuery The nested query of the join key. Can be null 049 */ 050 public JoinKey(String key, Query nestedQuery) 051 { 052 this(key, null, nestedQuery); 053 } 054 055 /** 056 * Creates a JoinKey 057 * @param key The key. Cannot be null 058 * @param joinField the field to join on. Can be null in which case "id_dv" will be assumed on Solr side. 059 * @param nestedQuery The nested query of the join key. Can be null 060 */ 061 public JoinKey(String key, String joinField, Query nestedQuery) 062 { 063 if (key == null) 064 { 065 throw new IllegalArgumentException("The key of the JoinKey cannot be null"); 066 } 067 068 _key = key; 069 _joinField = Optional.ofNullable(joinField); 070 _nestedQuery = Optional.ofNullable(nestedQuery); 071 } 072 073 /** 074 * Gets the key of the JoinKey 075 * @return the key of the JoinKey 076 */ 077 public String getKey() 078 { 079 return _key; 080 } 081 082 /** 083 * Returns the join field, if any. 084 * @return the join field, if any. 085 */ 086 public Optional<String> getJoinField() 087 { 088 return _joinField; 089 } 090 091 /** 092 * Gets the optional nested query of the join key 093 * @return the optional nested query of the join key 094 */ 095 public Optional<Query> getNestedQuery() 096 { 097 return _nestedQuery; 098 } 099 100 /** 101 * Build the Solr {@link JoinQuery} part representing this {@link JoinKey}. 102 * @param escape if the nested query should be escaped 103 * @return a Solr query part 104 * @throws QuerySyntaxException if the query part can't be built because of a syntax error. 105 */ 106 public String build(boolean escape) throws QuerySyntaxException 107 { 108 StringBuilder queryString = new StringBuilder(); 109 110 queryString.append(_key); 111 112 if (_joinField.isPresent()) 113 { 114 queryString.append('%').append(_joinField.get()); 115 } 116 117 if (_nestedQuery.isPresent()) 118 { 119 String query = _nestedQuery.get().build(); 120 queryString.append('[') 121 .append(escape ? ClientUtils.escapeQueryChars(query) : query) 122 .append(']'); 123 } 124 125 return queryString.toString(); 126 } 127 128 @Override 129 public int hashCode() 130 { 131 return Objects.hash(_key, _joinField, _nestedQuery); 132 } 133 134 @Override 135 public boolean equals(Object obj) 136 { 137 if (!(obj instanceof JoinKey other)) 138 { 139 return false; 140 } 141 142 return Objects.equals(_key, other._key) 143 && Objects.equals(_joinField, other._joinField) 144 && Objects.equals(_nestedQuery, other._nestedQuery); 145 } 146 147 @Override 148 public String toString() 149 { 150 return "JoinKey(key=" + _key + ",joinField=" + _joinField.orElse("<none>") + ",nestedQuery=" + _nestedQuery.map(Query::toString).orElse("<none>") + ")"; 151 } 152}