001/* 002 * Copyright (c) 2010-2025 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.Objects; 030import java.util.Optional; 031 032import com.restfb.exception.FacebookJsonMappingException; 033 034/** 035 * Representation of a Facebook API request parameter. 036 * 037 * @author <a href="http://restfb.com">Mark Allen</a> 038 */ 039public final class Parameter { 040 /** 041 * Parameter name. 042 */ 043 public final String name; 044 045 /** 046 * Parameter value. 047 */ 048 public final String value; 049 050 /** 051 * Creates a new parameter with the given {@code name} and {@code value}. 052 * 053 * @param name 054 * The parameter name. 055 * @param value 056 * The parameter value. 057 * @param jsonMapper 058 * Mapper for converting the parameter value to JSON. 059 * @throws IllegalArgumentException 060 * If {@code name} is {@code null} or a blank string or either {@code value} or {@code jsonMapper} is 061 * {@code null}. 062 */ 063 private Parameter(String name, Object value, JsonMapper jsonMapper) { 064 if (isBlank(name) || value == null) { 065 throw new IllegalArgumentException(Parameter.class + " instances must have a non-blank name and non-null value." 066 + " Got instead name:" + name + ", value:" + value); 067 } 068 069 this.value = Optional.ofNullable(jsonMapper) 070 .orElseThrow(() -> new IllegalArgumentException("Provided " + JsonMapper.class + " must not be null.")) 071 .toJson(value, true); 072 this.name = trimToEmpty(name); 073 } 074 075 /** 076 * Factory method which provides an instance with the given {@code name} and {@code value}. 077 * <p> 078 * The {@code value} parameter is often a {@link String} or primitive type like {@link Integer}, but you may pass in a 079 * {@link java.util.List}, {@link java.util.Map}, or your own <tt>@Facebook</tt>-annotated Javabean, and it will be 080 * converted to JSON automatically. See the "attachment" section of 081 * <a href="http://wiki.developers.facebook.com/index.php/Stream.publish">the stream.publish API documentation</a> for 082 * an example of where this is useful. 083 * 084 * @param name 085 * The parameter name. 086 * @param value 087 * The parameter value. 088 * @return A {@code Parameter} instance with the given {@code name} and {@code value}. 089 * @throws IllegalArgumentException 090 * If {@code name} or {@code value} is {@code null} or a blank string. 091 * @throws FacebookJsonMappingException 092 * If an error occurs when converting {@code value} to JSON. 093 */ 094 public static Parameter with(String name, Object value) { 095 return Parameter.with(name, value, new DefaultJsonMapper()); 096 } 097 098 /** 099 * convenience factory method which needs a comma separated list of fields that the dev likes to fetch from the API 100 * 101 * @param fieldList 102 * comma separated list of fields 103 * @return Parameter object 104 */ 105 public static Parameter withFields(String fieldList) { 106 return Parameter.with("fields", fieldList); 107 } 108 109 /** 110 * Convenience factory method that creates a {@code Parameter} object to retrieve the metadata from the API. 111 * 112 * @return Parameter object 113 */ 114 public static Parameter withMetadata() { 115 return Parameter.with("metadata", "1"); 116 } 117 118 /** 119 * convenience factory method which creates a {@code Parameter} object to fetch data from API with given locale 120 * 121 * @param locale 122 * the locale that should be used to fetch the data 123 * 124 * @return Parameter object 125 */ 126 public static Parameter withLocale(Locale locale) { 127 return Parameter.with("locale", locale.getLanguage()); 128 } 129 130 /** 131 * convenience factory method which creates a {@code Parameter} object to fetch data from API with given limit 132 * 133 * @param limit 134 * the limit that should be used fetching data 135 * 136 * @return Parameter object 137 */ 138 public static Parameter withLimit(int limit) { 139 return Parameter.with("limit", limit); 140 } 141 142 /** 143 * convenience factory method which creates a {@code Parameter} object to post an object with a message parameter to 144 * the API 145 * 146 * @param obj 147 * The content of the message, should be a String, but maybe some JSON 148 * 149 * @return Parameter object 150 */ 151 public static Parameter withMessage(Object obj) { 152 return Parameter.with("message", obj); 153 } 154 155 /** 156 * convenience factory method which creates a {@code Parameter} object to query some information e.g. searching profiles 157 * the API 158 * 159 * @param queryString 160 * the String used in the query 161 * 162 * @return Parameter object 163 */ 164 public static Parameter withQuery(String queryString) { 165 return Parameter.with("q", queryString); 166 } 167 168 /** 169 * Factory method which provides an instance with the given {@code name} and {@code value}, using the provided 170 * {@code jsonMapper} to turn {@code value} into a JSON string. 171 * <p> 172 * The {@code value} parameter is often a {@link String} or primitive type like {@link Integer}, but you may pass in a 173 * {@link java.util.List}, {@link java.util.Map}, or your own <tt>@Facebook</tt>-annotated Javabean, and it will be 174 * converted to JSON automatically. See the "attachment" section of 175 * <a href="http://wiki.developers.facebook.com/index.php/Stream.publish">the stream.publish API documentation</a> for 176 * an example of where this is useful. 177 * 178 * @param name 179 * The parameter name. 180 * @param value 181 * The parameter value. 182 * @param jsonMapper 183 * The jsonMapper 184 * @return A {@code Parameter} instance with the given {@code name} and {@code value}. 185 * @throws IllegalArgumentException 186 * If {@code name} or {@code value} is {@code null} or a blank string. 187 * @throws FacebookJsonMappingException 188 * If an error occurs when converting {@code value} to JSON. 189 */ 190 public static Parameter with(String name, Object value, JsonMapper jsonMapper) { 191 return new Parameter(name, value, jsonMapper); 192 } 193 194 /** 195 * @see java.lang.Object#equals(java.lang.Object) 196 */ 197 @Override 198 public boolean equals(Object o) { 199 if (o == null || getClass() != o.getClass()) return false; 200 Parameter parameter = (Parameter) o; 201 return Objects.equals(name, parameter.name) && Objects.equals(value, parameter.value); 202 } 203 204 @Override 205 public int hashCode() { 206 int hash = 7; 207 hash = 37 * hash + this.name.hashCode(); 208 hash = 41 * hash + this.value.hashCode(); 209 return hash; 210 } 211 212 @Override 213 public String toString() { 214 return format("Parameter[%s=%s]", name, value); 215 } 216}