001/*
002 * JPPF.
003 * Copyright (C) 2005-2019 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.jppf.utils;
020
021import java.io.Serializable;
022
023/**
024 * Instances of this class hold a reference to an object than can be either of the specified parametrized type or an exception.
025 * They can be seen as a way to carry the result of a method invocation, even if this invocation raises an exception.
026 * @param <R> the non-exception type of the referenced object.
027 * @author Laurent Cohen
028 */
029public class InvocationResult<R> implements Serializable {
030  /**
031   * Explicit serialVersionUID.
032   */
033  private static final long serialVersionUID = 1L;
034  /**
035   * The referenced object.
036   */
037  private final Object ref;
038  
039  /**
040   * Initialize with the specified reference object.
041   * @param ref the referenced object with the expected type.
042   */
043  public InvocationResult(final R ref) {
044    this.ref = ref;
045  }
046  
047  /**
048   * Initialize with the specified reference object.
049   * @param ref the referenced object as an exception type.
050   */
051  public InvocationResult(final Exception ref) {
052    this.ref = ref;
053  }
054
055  /**
056   * Determine whether the referenced object is an exception.
057   * @return {@code true} if the referenced object is an exception, {@code false} otherwise.
058   */
059  public boolean isException() {
060    return ref instanceof Exception;
061  }
062
063  /**
064   * Get the referenced object as an exception.
065   * @return the referenced object as an {@link Exception}, or {@code null} if it is not an exception.
066   */
067  public Exception exception() {
068    return isException() ? (Exception) ref : null;
069  }
070
071  /**
072   * Get the invocation result.
073   * @return the result with the desired parametrized type, or {@code null} if the result is an exception.
074   */
075  @SuppressWarnings("unchecked")
076  public R result() {
077    return isException() ? null : (R) ref;
078  }
079
080  @Override
081  public String toString() {
082    return new StringBuilder(getClass().getSimpleName()).append('[')
083      .append("ref=").append(ref)
084      .append(']').toString();
085  }
086
087  @Override
088  public int hashCode() {
089    return 31 + ((ref == null) ? 0 : ref.hashCode());
090  }
091
092  @Override
093  public boolean equals(final Object obj) {
094    if (this == obj) return true;
095    if (obj == null) return false;
096    if (getClass() != obj.getClass()) return false;
097    final InvocationResult<?> other = (InvocationResult<?>) obj;
098    if (ref == null) return other.ref == null;
099    return ref.equals(other.ref);
100  }
101}