Copyright (c) 2004, 2015 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2004, 2015 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.core.commands.common; import java.util.Objects;

An object that can exist in one of two states: defined and undefined. This is used by APIs that want to give a handle to an object, even though the object does not fully exist yet. This way, users can attach listeners to objects before they come into existence. It also protects the API from users that do not release references when they should.

To enforce good coding practice, all handle objects must implement equals and toString. Please use string to cache the result for toString once calculated.

All handle objects are referred to using a single identifier. This identifier is a instance of String. It is important that this identifier remain unique within whatever context that handle object is being used. For example, there should only ever be one instance of Command with a given identifier.

Since:3.1
/** * <p> * An object that can exist in one of two states: defined and undefined. This is * used by APIs that want to give a handle to an object, even though the object * does not fully exist yet. This way, users can attach listeners to objects * before they come into existence. It also protects the API from users that do * not release references when they should. * </p> * <p> * To enforce good coding practice, all handle objects must implement * <code>equals</code> and <code>toString</code>. Please use * <code>string</code> to cache the result for <code>toString</code> once * calculated. * </p> * <p> * All handle objects are referred to using a single identifier. This identifier * is a instance of <code>String</code>. It is important that this identifier * remain unique within whatever context that handle object is being used. For * example, there should only ever be one instance of <code>Command</code> * with a given identifier. * </p> * * @since 3.1 */
public abstract class HandleObject extends EventManager implements IIdentifiable {
The constant integer hash code value meaning the hash code has not yet been computed.
/** * The constant integer hash code value meaning the hash code has not yet * been computed. */
private static final int HASH_CODE_NOT_COMPUTED = -1;
A factor for computing the hash code for all schemes.
/** * A factor for computing the hash code for all schemes. */
private static final int HASH_FACTOR = 89;
The seed for the hash code for all schemes.
/** * The seed for the hash code for all schemes. */
private static final int HASH_INITIAL = HandleObject.class.getName() .hashCode();
Whether this object is defined. A defined object is one that has been fully initialized. By default, all objects start as undefined.
/** * Whether this object is defined. A defined object is one that has been * fully initialized. By default, all objects start as undefined. */
protected transient boolean defined = false;
The hash code for this object. This value is computed lazily, and marked as invalid when one of the values on which it is based changes.
/** * The hash code for this object. This value is computed lazily, and marked * as invalid when one of the values on which it is based changes. */
private transient int hashCode = HASH_CODE_NOT_COMPUTED;
The identifier for this object. This identifier should be unique across all objects of the same type and should never change. This value will never be null.
/** * The identifier for this object. This identifier should be unique across * all objects of the same type and should never change. This value will * never be <code>null</code>. */
protected final String id;
The string representation of this object. This string is for debugging purposes only, and is not meant to be displayed to the user. This value is computed lazily, and is cleared if one of its dependent values changes.
/** * The string representation of this object. This string is for debugging * purposes only, and is not meant to be displayed to the user. This value * is computed lazily, and is cleared if one of its dependent values * changes. */
protected transient String string = null;
Constructs a new instance of HandleObject.
Params:
  • id – The id of this handle; must not be null.
/** * Constructs a new instance of <code>HandleObject</code>. * * @param id * The id of this handle; must not be <code>null</code>. */
protected HandleObject(final String id) { if (id == null) { throw new NullPointerException( "Cannot create a handle with a null id"); //$NON-NLS-1$ } this.id = id; }
Tests whether this object is equal to another object. A handle object is only equal to another handle object with the same id and the same class.
Params:
  • object – The object with which to compare; may be null.
Returns:true if the objects are equal; false otherwise.
/** * Tests whether this object is equal to another object. A handle object is * only equal to another handle object with the same id and the same class. * * @param object * The object with which to compare; may be <code>null</code>. * @return <code>true</code> if the objects are equal; <code>false</code> * otherwise. */
@Override public boolean equals(final Object object) { // Check if they're the same. if (object == this) { return true; } // Check if they're the same type. if (!(object instanceof HandleObject)) { return false; } // Check each property in turn. final HandleObject handle= (HandleObject) object; return Objects.equals(id, handle.id) && (this.getClass() == handle.getClass()); } @Override public final String getId() { return id; }
Computes the hash code for this object based on the id.
Returns:The hash code for this object.
/** * Computes the hash code for this object based on the id. * * @return The hash code for this object. */
@Override public final int hashCode() { if (hashCode == HASH_CODE_NOT_COMPUTED) { hashCode = HASH_INITIAL * HASH_FACTOR + Objects.hashCode(id); if (hashCode == HASH_CODE_NOT_COMPUTED) { hashCode++; } } return hashCode; }
Whether this instance is defined. A defined instance is one that has been fully initialized. This allows objects to effectively disappear even though other objects may still have references to them.
Returns:true if this object is defined; false otherwise.
/** * Whether this instance is defined. A defined instance is one that has been * fully initialized. This allows objects to effectively disappear even * though other objects may still have references to them. * * @return <code>true</code> if this object is defined; <code>false</code> * otherwise. */
public final boolean isDefined() { return defined; }
The string representation of this object -- for debugging purposes only. This string should not be shown to an end user.
Returns:The string representation; never null.
/** * The string representation of this object -- for debugging purposes only. * This string should not be shown to an end user. * * @return The string representation; never <code>null</code>. */
@Override public abstract String toString();
Makes this object becomes undefined. This method should make any defined properties null. It should also send notification to any listeners that these properties have changed.
/** * Makes this object becomes undefined. This method should make any defined * properties <code>null</code>. It should also send notification to any * listeners that these properties have changed. */
public abstract void undefine(); }