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 * @author Laurence Gonsalves
031 * @since 2 (imported from Google Collections Library)
032 */
033@GwtCompatible
034public final class Objects {
035  private Objects() {}
036
037  /**
038   * Determines whether two possibly-null objects are equal. Returns:
039   *
040   * <ul>
041   * <li>{@code true} if {@code a} and {@code b} are both null.
042   * <li>{@code true} if {@code a} and {@code b} are both non-null and they are
043   *     equal according to {@link Object#equals(Object)}.
044   * <li>{@code false} in all other situations.
045   * </ul>
046   *
047   * <p>This assumes that any non-null objects passed to this function conform
048   * to the {@code equals()} contract.
049   */
050  public static boolean equal(@Nullable Object a, @Nullable Object b) {
051    return a == b || (a != null && a.equals(b));
052  }
053
054  /**
055   * Generates a hash code for multiple values. The hash code is generated by
056   * calling {@link Arrays#hashCode(Object[])}.
057   *
058   * <p>This is useful for implementing {@link Object#hashCode()}. For example,
059   * in an object that has three properties, {@code x}, {@code y}, and
060   * {@code z}, one could write:
061   * <pre>
062   * public int hashCode() {
063   *   return Objects.hashCode(getX(), getY(), getZ());
064   * }</pre>
065   *
066   * <b>Warning</b>: When a single object is supplied, the returned hash code
067   * does not equal the hash code of that object.
068   */
069  public static int hashCode(@Nullable Object... objects) {
070    return Arrays.hashCode(objects);
071  }
072
073  /**
074   * Creates an instance of {@link ToStringHelper}.
075   *
076   * <p>This is helpful for implementing {@link Object#toString()}.
077   * Specification by example: <pre>   {@code
078   *   // Returns "ClassName{}"
079   *   Objects.toStringHelper(this)
080   *       .toString();
081   *
082   *   // Returns "ClassName{x=1}"
083   *   Objects.toStringHelper(this)
084   *       .add("x", 1)
085   *       .toString();
086   *
087   *   // Returns "MyObject{x=1}"
088   *   Objects.toStringHelper("MyObject")
089   *       .add("x", 1)
090   *       .toString();
091   *
092   *   // Returns "ClassName{x=1, y=foo}"
093   *   Objects.toStringHelper(this)
094   *       .add("x", 1)
095   *       .add("y", "foo")
096   *       .toString();
097   *   }}</pre>
098   *
099   * @param self the object to generate the string for (typically {@code this}),
100   *        used only for its class name
101   * @since 2
102   */
103  public static ToStringHelper toStringHelper(Object self) {
104    return new ToStringHelper(simpleName(self.getClass()));
105  }
106
107  /**
108   * Creates an instance of {@link ToStringHelper} in the same manner as
109   * {@link Objects#toStringHelper(Object)}, but using the name of {@code clazz}
110   * instead of using an instance's {@link Object#getClass()}.
111   *
112   * @param clazz the {@link Class} of the instance
113   * @since 7 (source-compatible since 2)
114   */
115  public static ToStringHelper toStringHelper(Class<?> clazz) {
116    return new ToStringHelper(simpleName(clazz));
117  }
118
119  /**
120   * Creates an instance of {@link ToStringHelper} in the same manner as
121   * {@link Objects#toStringHelper(Object)}, but using {@code className} instead
122   * of using an instance's {@link Object#getClass()}.
123   *
124   * @param className the name of the instance type
125   * @since 7 (source-compatible since 2)
126   */
127  public static ToStringHelper toStringHelper(String className) {
128    return new ToStringHelper(className);
129  }
130
131  /**
132   * {@link Class#getSimpleName()} is not GWT compatible yet, so we
133   * provide our own implementation.
134   */
135  private static String simpleName(Class<?> clazz) {
136    String name = clazz.getName();
137
138    // we want the name of the inner class all by its lonesome
139    int start = name.lastIndexOf('$');
140
141    // if this isn't an inner class, just find the start of the
142    // top level class name.
143    if (start == -1) {
144      start = name.lastIndexOf('.');
145    }
146    return name.substring(start + 1);
147  }
148
149  /**
150   * Returns the first of two given parameters that is not {@code null}, if
151   * either is, or otherwise throws a {@link NullPointerException}.
152   *
153   * @return {@code first} if {@code first} is not {@code null}, or
154   *     {@code second} if {@code first} is {@code null} and {@code second} is
155   *     not {@code null}
156   * @throws NullPointerException if both {@code first} and {@code second} were
157   *     {@code null}
158   * @since 3
159   */
160  public static <T> T firstNonNull(@Nullable T first, @Nullable T second) {
161    return first != null ? first : checkNotNull(second);
162  }
163
164  /**
165   * Support class for {@link Objects#toStringHelper}.
166   *
167   * @author Jason Lee
168   * @since 2
169   */
170  public static final class ToStringHelper {
171    private final StringBuilder builder;
172    private String separator = "";
173
174    /**
175     * Use {@link Objects#toStringHelper(Object)} to create an instance.
176     */
177    private ToStringHelper(String className) {
178      this.builder = new StringBuilder(32)
179          .append(checkNotNull(className))
180          .append('{');
181    }
182
183    /**
184     * Adds a name/value pair to the formatted output in {@code name=value}
185     * format. If {@code value} is {@code null}, the string {@code "null"}
186     * is used.
187     */
188    public ToStringHelper add(String name, @Nullable Object value) {
189      builder.append(separator)
190          .append(checkNotNull(name))
191          .append('=')
192          .append(value);
193      separator = ", ";
194      return this;
195    }
196
197    /**
198     * Adds a value to the formatted output in {@code value} format.
199     *
200     * <p>It is strongly encouraged to use {@link #add(String, Object)} instead
201     * and give value a readable name.
202     */
203    public ToStringHelper addValue(@Nullable Object value) {
204      builder.append(separator).append(value);
205      separator = ", ";
206      return this;
207    }
208
209    /**
210     * Returns a string in the format specified by {@link
211     * Objects#toStringHelper(Object)}.
212     */
213    @Override public String toString() {
214      return builder.append('}').toString();
215    }
216  }
217}