001package arez.component; 002 003import arez.Arez; 004import arez.Disposable; 005import javax.annotation.Nonnull; 006import javax.annotation.Nullable; 007import static org.realityforge.braincheck.Guards.*; 008 009/** 010 * Interface implemented by components so that the underlying identifier can be exposed. 011 * The <code>ArezId</code> is used by Arez classes when manipulating the component. As long as 012 * {@link Disposable#dispose()} has not been invoked on the component then the <code>ArezId</code> 013 * value should be unique within the scope of the {@link arez.ArezContext}. 014 * 015 * @param <K> the type of the id. 016 */ 017@SuppressWarnings( "unchecked" ) 018public interface Identifiable<K> 019{ 020 /** 021 * Return the unique id of the component. 022 * As long as {@link Disposable#dispose()} has not been invoked on the component, 023 * the return value should be unique within the scope of the {@link arez.ArezContext}. 024 * 025 * @return the unique id of the component. 026 */ 027 @Nonnull 028 K getArezId(); 029 030 /** 031 * Return the unique id of the object if it is Identifiable, else return null. 032 * 033 * @param <K> the type of the id. 034 * @param object the object to dispose. 035 * @return the arez id if the object is Identifiable, otherwise null. 036 */ 037 @Nullable 038 static <K> K getArezId( @Nullable final Object object ) 039 { 040 if ( object instanceof Identifiable ) 041 { 042 return ( (Identifiable<K>) object ).getArezId(); 043 } 044 else 045 { 046 return null; 047 } 048 } 049 050 /** 051 * Cast specified object to instance of Identifiable. 052 * Invariant checks will verify that the cast is valid before proceeding. 053 * 054 * @param <K> the type parameter for Identifiable. 055 * @param object the object. 056 * @return the object cast to Identifiable. 057 */ 058 @Nonnull 059 static <K> Identifiable<K> asIdentifiable( @Nonnull final Object object ) 060 { 061 if ( Arez.shouldCheckApiInvariants() ) 062 { 063 apiInvariant( () -> object instanceof Identifiable, 064 () -> "Arez-0158: Object passed to asIdentifiable does not implement " + 065 "Identifiable. Object: " + object ); 066 } 067 return (Identifiable<K>) object; 068 } 069}