All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.bonita.util.Final Maven / Gradle / Ivy

package org.ow2.bonita.util;

import java.io.Serializable;
import java.util.concurrent.atomic.AtomicReference;

/**
 * This class provides an efficient way --- using hardware instructions if
 * available --- for holding a variable that can only be initialized once (aka:
 * final variables).
 * 
 * This class helps when it is not possible to declare a variable as
 * final but still, you need it to be initialized only once (e.g:
 * in a setter).
 * 
 * Note that you cannot initialize a variable to null using this
 * class.
 * 
 * This class is thread safe.
 * 
 * @author Pierre Vigneras
 * @param 
 */
public class Final implements Serializable {
  private static final long serialVersionUID = 48705032925395418L;

  private final AtomicReference atomicReference = new AtomicReference();

  public String toString() {
    return isInitialized() ? getValue().toString() : "";
  }

  /**
   * Return the current value of this variable. No check is performed. May
   * return null.
   * 
   * @return the current value of this variable. No check is performed. May
   *         return null.
   */
  protected T getValue() {
    return atomicReference.get();
  }

  /**
   * Set the value of this variable directly. No check is perform. Multiple set
   * is thus possible.
   * 
   * @param t
   *          the value to set this variable to.
   */
  protected void setValue(T t) {
    atomicReference.set(t);
  }

  /**
   * Initialize this variable to the given value.
   * 
   * The given value should not be null.
   * 
   * @param t
   *          the value
   * @throws IllegalArgumentException
   *           if the given value is null
   * @throws IllegalStateException
   *           if the variable has already been set.
   */
  public void init(final T t) {
    // Warning: do not remove this check as it guarantees the correct
    // semantic of this class. If you remove it, consequences are:
    // 1. initialized() is no more correct, you need a boolean to know if
    // the value has been set up.
    // 2. Multiple set(null) can be called and this class contract is
    // violated.
    // 3. You can set(null) and thereafter set(non-null-value) and this also
    // violate this class contract.
    Misc.checkArgsNotNull(t);
    if (!atomicReference.compareAndSet(null, t)) {
      String message = ExceptionManager.getInstance().getFullMessage("buc_F_1",
          t);
      throw new IllegalStateException(message);
    }
  }

  /**
   * Return the value of the initialized variable.
   * 
   * @return the value of the initialized variable, or null if it has not been
   *         initialized yet.
   */
  public T get() {
    return atomicReference.get();
  }

  /**
   * Check the initialized status of this final variable.
   * 
   * @return true if this final variable has been initialized,
   *         false otherwise.
   */
  public boolean isInitialized() {
    return atomicReference.get() != null;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy