001/* 002 * Copyright (c) 2010-2024 Mark Allen, Norbert Bartels. 003 * 004 * Permission is hereby granted, free of charge, to any person obtaining a copy 005 * of this software and associated documentation files (the "Software"), to deal 006 * in the Software without restriction, including without limitation the rights 007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 008 * copies of the Software, and to permit persons to whom the Software is 009 * furnished to do so, subject to the following conditions: 010 * 011 * The above copyright notice and this permission notice shall be included in 012 * all copies or substantial portions of the Software. 013 * 014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 020 * THE SOFTWARE. 021 */ 022package com.restfb; 023 024import static com.restfb.util.StringUtils.isBlank; 025import static com.restfb.util.StringUtils.trimToEmpty; 026import static java.lang.String.format; 027 028import java.util.Locale; 029import java.util.Optional; 030 031import com.restfb.exception.FacebookJsonMappingException; 032 033/** 034 * Representation of a Facebook API request parameter. 035 * 036 * @author <a href="http://restfb.com">Mark Allen</a> 037 */ 038public final class Parameter { 039 /** 040 * Parameter name. 041 */ 042 public final String name; 043 044 /** 045 * Parameter value. 046 */ 047 public final String value; 048 049 /** 050 * Creates a new parameter with the given {@code name} and {@code value}. 051 * 052 * @param name 053 * The parameter name. 054 * @param value 055 * The parameter value. 056 * @param jsonMapper 057 * Mapper for converting the parameter value to JSON. 058 * @throws IllegalArgumentException 059 * If {@code name} is {@code null} or a blank string or either {@code value} or {@code jsonMapper} is 060 * {@code null}. 061 */ 062 private Parameter(String name, Object value, JsonMapper jsonMapper) { 063 if (isBlank(name) || value == null) { 064 throw new IllegalArgumentException(Parameter.class + " instances must have a non-blank name and non-null value." 065 + " Got instead name:" + name + ", value:" + value); 066 } 067 068 this.value = Optional.ofNullable(jsonMapper) 069 .orElseThrow(() -> new IllegalArgumentException("Provided " + JsonMapper.class + " must not be null.")) 070 .toJson(value, true); 071 this.name = trimToEmpty(name); 072 } 073 074 /** 075 * Factory method which provides an instance with the given {@code name} and {@code value}. 076 * <p> 077 * The {@code value} parameter is often a {@link String} or primitive type like {@link Integer}, but you may pass in a 078 * {@link java.util.List}, {@link java.util.Map}, or your own <tt>@Facebook</tt>-annotated Javabean, and it will be 079 * converted to JSON automatically. See the "attachment" section of 080 * <a href="http://wiki.developers.facebook.com/index.php/Stream.publish">the stream.publish API documentation</a> for 081 * an example of where this is useful. 082 * 083 * @param name 084 * The parameter name. 085 * @param value 086 * The parameter value. 087 * @return A {@code Parameter} instance with the given {@code name} and {@code value}. 088 * @throws IllegalArgumentException 089 * If {@code name} or {@code value} is {@code null} or a blank string. 090 * @throws FacebookJsonMappingException 091 * If an error occurs when converting {@code value} to JSON. 092 */ 093 public static Parameter with(String name, Object value) { 094 return Parameter.with(name, value, new DefaultJsonMapper()); 095 } 096 097 /** 098 * convenience factory method which needs a comma separated list of fields that the dev likes to fetch from the API 099 * 100 * @param fieldList 101 * comma separated list of fields 102 * @return Parameter object 103 */ 104 public static Parameter withFields(String fieldList) { 105 return Parameter.with("fields", fieldList); 106 } 107 108 /** 109 * Convenience factory method that creates a {@code Parameter} object to retrieve the metadata from the API. 110 * 111 * @return Parameter object 112 */ 113 public static Parameter withMetadata() { 114 return Parameter.with("metadata", "1"); 115 } 116 117 /** 118 * convenience factory method which creates a {@code Parameter} object to fetch data from API with given locale 119 * 120 * @param locale 121 * the locale that should be used to fetch the data 122 * 123 * @return Parameter object 124 */ 125 public static Parameter withLocale(Locale locale) { 126 return Parameter.with("locale", locale.getLanguage()); 127 } 128 129 /** 130 * convenience factory method which creates a {@code Parameter} object to fetch data from API with given limit 131 * 132 * @param limit 133 * the limit that should be used fetching data 134 * 135 * @return Parameter object 136 */ 137 public static Parameter withLimit(int limit) { 138 return Parameter.with("limit", limit); 139 } 140 141 /** 142 * convenience factory method which creates a {@code Parameter} object to post an object with a message parameter to 143 * the API 144 * 145 * @param obj 146 * The content of the message, should be a String, but maybe some JSON 147 * 148 * @return Parameter object 149 */ 150 public static Parameter withMessage(Object obj) { 151 return Parameter.with("message", obj); 152 } 153 154 /** 155 * convenience factory method which creates a {@code Parameter} object to query some information e.g. searching profiles 156 * the API 157 * 158 * @param queryString 159 * the String used in the query 160 * 161 * @return Parameter object 162 */ 163 public static Parameter withQuery(String queryString) { 164 return Parameter.with("q", queryString); 165 } 166 167 /** 168 * Factory method which provides an instance with the given {@code name} and {@code value}, using the provided 169 * {@code jsonMapper} to turn {@code value} into a JSON string. 170 * <p> 171 * The {@code value} parameter is often a {@link String} or primitive type like {@link Integer}, but you may pass in a 172 * {@link java.util.List}, {@link java.util.Map}, or your own <tt>@Facebook</tt>-annotated Javabean, and it will be 173 * converted to JSON automatically. See the "attachment" section of 174 * <a href="http://wiki.developers.facebook.com/index.php/Stream.publish">the stream.publish API documentation</a> for 175 * an example of where this is useful. 176 * 177 * @param name 178 * The parameter name. 179 * @param value 180 * The parameter value. 181 * @param jsonMapper 182 * The jsonMapper 183 * @return A {@code Parameter} instance with the given {@code name} and {@code value}. 184 * @throws IllegalArgumentException 185 * If {@code name} or {@code value} is {@code null} or a blank string. 186 * @throws FacebookJsonMappingException 187 * If an error occurs when converting {@code value} to JSON. 188 */ 189 public static Parameter with(String name, Object value, JsonMapper jsonMapper) { 190 return new Parameter(name, value, jsonMapper); 191 } 192 193 /** 194 * @see java.lang.Object#equals(java.lang.Object) 195 */ 196 @Override 197 public boolean equals(Object obj) { 198 if (obj == null) { 199 return false; 200 } 201 if (!getClass().equals(obj.getClass())) { 202 return false; 203 } 204 205 Parameter other = (Parameter) obj; 206 207 if (this.name != other.name && !this.name.equals(other.name)) { 208 return false; 209 } 210 211 return !(this.value != other.value && !this.value.equals(other.value)); 212 } 213 214 @Override 215 public int hashCode() { 216 int hash = 7; 217 hash = 37 * hash + this.name.hashCode(); 218 hash = 41 * hash + this.value.hashCode(); 219 return hash; 220 } 221 222 @Override 223 public String toString() { 224 return format("Parameter[%s=%s]", name, value); 225 } 226}