001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2014-2015 ForgeRock AS. 015 */ 016 017package org.forgerock.openig.decoration.helper; 018 019import static org.forgerock.util.Reject.*; 020 021import org.forgerock.json.JsonValue; 022import org.forgerock.openig.heap.Heap; 023import org.forgerock.openig.heap.HeapException; 024 025/** 026 * Lazily resolve a {@link JsonValue} reference node against a provided {@link Heap} instance. 027 * Once the reference has been acquired, no other resolution is tried (except for optional references resolved 028 * to {@code null}). 029 * @param <T> expected type of the resolved reference object 030 */ 031public final class LazyReference<T> { 032 033 /** 034 * Builds a LazyReference dedicated to resolve the given (optional or not) {@code reference} of type {@code type} 035 * from the given {@code heap}. 036 * 037 * @param heap 038 * Heap instance that will try to resolve the reference 039 * @param reference 040 * Reference to be resolved (can be an inline declaration) 041 * @param type 042 * expected resolved type of the reference 043 * @param optional 044 * is this reference optional (return {@code null} if the given {@code reference} wraps a {@code null} 045 * value) 046 * @return a new LazyReference 047 * @param <R> expected resolved type of the reference 048 */ 049 public static <R> LazyReference<R> newReference(final Heap heap, 050 final JsonValue reference, 051 final Class<R> type, 052 final boolean optional) { 053 return new LazyReference<>(checkNotNull(heap), checkNotNull(reference), type, optional); 054 } 055 056 private final Heap heap; 057 private final JsonValue reference; 058 private final Class<T> type; 059 private final boolean optional; 060 061 private T resolved; 062 063 private LazyReference(final Heap heap, final JsonValue reference, final Class<T> type, final boolean optional) { 064 this.heap = heap; 065 this.reference = reference; 066 this.type = type; 067 this.optional = optional; 068 } 069 070 /** 071 * Resolves the encapsulated reference. 072 * Notice that synchronization is done in the Heap, so no need to cover that here. 073 * 074 * @return the resolved instance, or {@code null} if it was optional and not set. 075 * @throws HeapException 076 * if resolution failed, this error is the one thrown be the heap, untouched. 077 */ 078 public T get() throws HeapException { 079 if (resolved == null) { 080 resolved = heap.resolve(reference, type, optional); 081 } 082 return resolved; 083 } 084 085}