001/*
002 * Copyright (C) 2007 The Guava Authors
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
017package com.google.common.base;
018
019import static com.google.common.base.Preconditions.checkNotNull;
020
021import com.google.common.annotations.GwtCompatible;
022
023import java.util.Arrays;
024
025import javax.annotation.Nullable;
026
027/**
028 * Helper functions that can operate on any {@code Object}.
029 *
030 * <p>See the Guava User Guide on <a
031 * href="http://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained">writing
032 * {@code Object} methods with {@code Objects}</a>.
033 *
034 * @author Laurence Gonsalves
035 * @since 2.0 (imported from Google Collections Library)
036 */
037@GwtCompatible
038public final class Objects {
039  private Objects() {}
040
041  /**
042   * Determines whether two possibly-null objects are equal. Returns:
043   *
044   * <ul>
045   * <li>{@code true} if {@code a} and {@code b} are both null.
046   * <li>{@code true} if {@code a} and {@code b} are both non-null and they are
047   *     equal according to {@link Object#equals(Object)}.
048   * <li>{@code false} in all other situations.
049   * </ul>
050   *
051   * <p>This assumes that any non-null objects passed to this function conform
052   * to the {@code equals()} contract.
053   */
054  public static boolean equal(@Nullable Object a, @Nullable Object b) {
055    return a == b || (a != null && a.equals(b));
056  }
057
058  /**
059   * Generates a hash code for multiple values. The hash code is generated by
060   * calling {@link Arrays#hashCode(Object[])}.
061   *
062   * <p>This is useful for implementing {@link Object#hashCode()}. For example,
063   * in an object that has three properties, {@code x}, {@code y}, and
064   * {@code z}, one could write:
065   * <pre>
066   * public int hashCode() {
067   *   return Objects.hashCode(getX(), getY(), getZ());
068   * }</pre>
069   *
070   * <b>Warning</b>: When a single object is supplied, the returned hash code
071   * does not equal the hash code of that object.
072   */
073  public static int hashCode(@Nullable Object... objects) {
074    return Arrays.hashCode(objects);
075  }
076
077  /**
078   * Creates an instance of {@link ToStringHelper}.
079   *
080   * <p>This is helpful for implementing {@link Object#toString()}.
081   * Specification by example: <pre>   {@code
082   *   // Returns "ClassName{}"
083   *   Objects.toStringHelper(this)
084   *       .toString();
085   *
086   *   // Returns "ClassName{x=1}"
087   *   Objects.toStringHelper(this)
088   *       .add("x", 1)
089   *       .toString();
090   *
091   *   // Returns "MyObject{x=1}"
092   *   Objects.toStringHelper("MyObject")
093   *       .add("x", 1)
094   *       .toString();
095   *
096   *   // Returns "ClassName{x=1, y=foo}"
097   *   Objects.toStringHelper(this)
098   *       .add("x", 1)
099   *       .add("y", "foo")
100   *       .toString();
101   *   }}
102   *
103   *   // Returns "ClassName{x=1}"
104   *   Objects.toStringHelper(this)
105   *       .omitNullValues()
106   *       .add("x", 1)
107   *       .add("y", null)
108   *       .toString();
109   *   }}</pre>
110   *
111   * <p>Note that in GWT, class names are often obfuscated.
112   *
113   * @param self the object to generate the string for (typically {@code this}),
114   *        used only for its class name
115   * @since 2.0
116   */
117  public static ToStringHelper toStringHelper(Object self) {
118    return new ToStringHelper(simpleName(self.getClass()));
119  }
120
121  /**
122   * Creates an instance of {@link ToStringHelper} in the same manner as
123   * {@link Objects#toStringHelper(Object)}, but using the name of {@code clazz}
124   * instead of using an instance's {@link Object#getClass()}.
125   *
126   * <p>Note that in GWT, class names are often obfuscated.
127   *
128   * @param clazz the {@link Class} of the instance
129   * @since 7.0 (source-compatible since 2.0)
130   */
131  public static ToStringHelper toStringHelper(Class<?> clazz) {
132    return new ToStringHelper(simpleName(clazz));
133  }
134
135  /**
136   * Creates an instance of {@link ToStringHelper} in the same manner as
137   * {@link Objects#toStringHelper(Object)}, but using {@code className} instead
138   * of using an instance's {@link Object#getClass()}.
139   *
140   * @param className the name of the instance type
141   * @since 7.0 (source-compatible since 2.0)
142   */
143  public static ToStringHelper toStringHelper(String className) {
144    return new ToStringHelper(className);
145  }
146
147  /**
148   * {@link Class#getSimpleName()} is not GWT compatible yet, so we
149   * provide our own implementation.
150   */
151  private static String simpleName(Class<?> clazz) {
152    String name = clazz.getName();
153
154    // the nth anonymous class has a class name ending in "Outer$n"
155    // and local inner classes have names ending in "Outer.$1Inner"
156    name = name.replaceAll("\\$[0-9]+", "\\$");
157
158    // we want the name of the inner class all by its lonesome
159    int start = name.lastIndexOf('$');
160
161    // if this isn't an inner class, just find the start of the
162    // top level class name.
163    if (start == -1) {
164      start = name.lastIndexOf('.');
165    }
166    return name.substring(start + 1);
167  }
168
169  /**
170   * Returns the first of two given parameters that is not {@code null}, if
171   * either is, or otherwise throws a {@link NullPointerException}.
172   *
173   * <p><b>Note:</b> if {@code first} is represented as an {@code Optional<T>},
174   * this can be accomplished with {@code first.or(second)}. That approach also
175   * allows for lazy evaluation of the fallback instance, using
176   * {@code first.or(Supplier)}.
177   *
178   * @return {@code first} if {@code first} is not {@code null}, or
179   *     {@code second} if {@code first} is {@code null} and {@code second} is
180   *     not {@code null}
181   * @throws NullPointerException if both {@code first} and {@code second} were
182   *     {@code null}
183   * @since 3.0
184   */
185  public static <T> T firstNonNull(@Nullable T first, @Nullable T second) {
186    return first != null ? first : checkNotNull(second);
187  }
188
189  /**
190   * Support class for {@link Objects#toStringHelper}.
191   *
192   * @author Jason Lee
193   * @since 2.0
194   */
195  public static final class ToStringHelper {
196    private final String className;
197    private ValueHolder holderHead = new ValueHolder();
198    private ValueHolder holderTail = holderHead;
199    private boolean omitNullValues = false;
200
201    /**
202     * Use {@link Objects#toStringHelper(Object)} to create an instance.
203     */
204    private ToStringHelper(String className) {
205      this.className = checkNotNull(className);
206    }
207
208    /**
209     * Configures the {@link ToStringHelper} so {@link #toString()} will ignore
210     * properties with null value. The order of calling this method, relative
211     * to the {@code add()}/{@code addValue()} methods, is not significant.
212     *
213     * @since 12.0
214     */
215    public ToStringHelper omitNullValues() {
216      omitNullValues = true;
217      return this;
218    }
219
220    /**
221     * Adds a name/value pair to the formatted output in {@code name=value}
222     * format. If {@code value} is {@code null}, the string {@code "null"}
223     * is used, unless {@link #omitNullValues()} is called, in which case this
224     * name/value pair will not be added.
225     */
226    public ToStringHelper add(String name, @Nullable Object value) {
227      return addHolder(name, value);
228    }
229
230    /**
231     * Adds a name/value pair to the formatted output in {@code name=value}
232     * format.
233     *
234     * @since 11.0 (source-compatible since 2.0)
235     */
236    public ToStringHelper add(String name, boolean value) {
237      return addHolder(name, String.valueOf(value));
238    }
239
240    /**
241     * Adds a name/value pair to the formatted output in {@code name=value}
242     * format.
243     *
244     * @since 11.0 (source-compatible since 2.0)
245     */
246    public ToStringHelper add(String name, char value) {
247      return addHolder(name, String.valueOf(value));
248    }
249
250    /**
251     * Adds a name/value pair to the formatted output in {@code name=value}
252     * format.
253     *
254     * @since 11.0 (source-compatible since 2.0)
255     */
256    public ToStringHelper add(String name, double value) {
257      return addHolder(name, String.valueOf(value));
258    }
259
260    /**
261     * Adds a name/value pair to the formatted output in {@code name=value}
262     * format.
263     *
264     * @since 11.0 (source-compatible since 2.0)
265     */
266    public ToStringHelper add(String name, float value) {
267      return addHolder(name, String.valueOf(value));
268    }
269
270    /**
271     * Adds a name/value pair to the formatted output in {@code name=value}
272     * format.
273     *
274     * @since 11.0 (source-compatible since 2.0)
275     */
276    public ToStringHelper add(String name, int value) {
277      return addHolder(name, String.valueOf(value));
278    }
279
280    /**
281     * Adds a name/value pair to the formatted output in {@code name=value}
282     * format.
283     *
284     * @since 11.0 (source-compatible since 2.0)
285     */
286    public ToStringHelper add(String name, long value) {
287      return addHolder(name, String.valueOf(value));
288    }
289
290    /**
291     * Adds an unnamed value to the formatted output.
292     *
293     * <p>It is strongly encouraged to use {@link #add(String, Object)} instead
294     * and give value a readable name.
295     */
296    public ToStringHelper addValue(@Nullable Object value) {
297      return addHolder(value);
298    }
299
300    /**
301     * Adds an unnamed value to the formatted output.
302     *
303     * <p>It is strongly encouraged to use {@link #add(String, boolean)} instead
304     * and give value a readable name.
305     *
306     * @since 11.0 (source-compatible since 2.0)
307     */
308    public ToStringHelper addValue(boolean value) {
309      return addHolder(String.valueOf(value));
310    }
311
312    /**
313     * Adds an unnamed value to the formatted output.
314     *
315     * <p>It is strongly encouraged to use {@link #add(String, char)} instead
316     * and give value a readable name.
317     *
318     * @since 11.0 (source-compatible since 2.0)
319     */
320    public ToStringHelper addValue(char value) {
321      return addHolder(String.valueOf(value));
322    }
323
324    /**
325     * Adds an unnamed value to the formatted output.
326     *
327     * <p>It is strongly encouraged to use {@link #add(String, double)} instead
328     * and give value a readable name.
329     *
330     * @since 11.0 (source-compatible since 2.0)
331     */
332    public ToStringHelper addValue(double value) {
333      return addHolder(String.valueOf(value));
334    }
335
336    /**
337     * Adds an unnamed value to the formatted output.
338     *
339     * <p>It is strongly encouraged to use {@link #add(String, float)} instead
340     * and give value a readable name.
341     *
342     * @since 11.0 (source-compatible since 2.0)
343     */
344    public ToStringHelper addValue(float value) {
345      return addHolder(String.valueOf(value));
346    }
347
348    /**
349     * Adds an unnamed value to the formatted output.
350     *
351     * <p>It is strongly encouraged to use {@link #add(String, int)} instead
352     * and give value a readable name.
353     *
354     * @since 11.0 (source-compatible since 2.0)
355     */
356    public ToStringHelper addValue(int value) {
357      return addHolder(String.valueOf(value));
358    }
359
360    /**
361     * Adds an unnamed value to the formatted output.
362     *
363     * <p>It is strongly encouraged to use {@link #add(String, long)} instead
364     * and give value a readable name.
365     *
366     * @since 11.0 (source-compatible since 2.0)
367     */
368    public ToStringHelper addValue(long value) {
369      return addHolder(String.valueOf(value));
370    }
371
372    /**
373     * Returns a string in the format specified by {@link
374     * Objects#toStringHelper(Object)}.
375     *
376     * <p>After calling this method, you can keep adding more properties to later
377     * call toString() again and get a more complete representation of the
378     * same object; but properties cannot be removed, so this only allows
379     * limited reuse of the helper instance. The helper allows duplication of
380     * properties (multiple name/value pairs with the same name can be added).
381     */
382    @Override public String toString() {
383      // create a copy to keep it consistent in case value changes
384      boolean omitNullValuesSnapshot = omitNullValues;
385      String nextSeparator = "";
386      StringBuilder builder = new StringBuilder(32).append(className)
387          .append('{');
388      for (ValueHolder valueHolder = holderHead.next; valueHolder != null;
389          valueHolder = valueHolder.next) {
390        if (!omitNullValuesSnapshot || valueHolder.value != null) {
391          builder.append(nextSeparator);
392          nextSeparator = ", ";
393
394          if (valueHolder.name != null) {
395            builder.append(valueHolder.name).append('=');
396          }
397          builder.append(valueHolder.value);
398        }
399      }
400      return builder.append('}').toString();
401    }
402
403    private ValueHolder addHolder() {
404      ValueHolder valueHolder = new ValueHolder();
405      holderTail = holderTail.next = valueHolder;
406      return valueHolder;
407    }
408
409    private ToStringHelper addHolder(@Nullable Object value) {
410      ValueHolder valueHolder = addHolder();
411      valueHolder.value = value;
412      return this;
413    }
414
415    private ToStringHelper addHolder(String name, @Nullable Object value) {
416      ValueHolder valueHolder = addHolder();
417      valueHolder.value = value;
418      valueHolder.name = checkNotNull(name);
419      return this;
420    }
421
422    private static final class ValueHolder {
423      String name;
424      Object value;
425      ValueHolder next;
426    }
427  }
428}