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.services.context; 018 019import org.forgerock.json.JsonValue; 020 021/** 022 * Type-safe contextual information associated with the processing of a request in an application. 023 * Contexts are linked together in a stack with a {@link RootContext} at the bottom of the stack. Each context 024 * maintains a reference to its parent context which can be accessed using the {@link #getParent()}} method. 025 * Context implementations may provide information about the client, the end-user, auditing information, routing 026 * decisions, etc. While contexts are arranged in a stack, application code will usually access contexts using the 027 * {@link #asContext(Class)} method: 028 * 029 * <pre> 030 * Context context = ...; // Opaque reference to the context stack 031 * 032 * String remoteHost = context.asContext(ClientContext.class).getRemoteHost(); 033 * context.asContext(AttributesContext.class).getAttributes().put("key", "value"); 034 * </pre> 035 * 036 * Alternatively, scripted applications will usually access contexts by name: 037 * 038 * <pre> 039 * var remoteHost = context.client.remoteHost; 040 * context.attributes.key = "value"; 041 * </pre> 042 * 043 * Context implementations should inherit from {@link AbstractContext} and ensure that they can be serialized to and 044 * from JSON. 045 */ 046public interface Context { 047 048 /** 049 * Get this Context's name. 050 * 051 * @return this object's name 052 */ 053 String getContextName(); 054 055 /** 056 * Returns the first context in the chain whose type is a sub-type of the 057 * provided {@code Context} class. The method first checks this context to 058 * see if it has the required type, before proceeding to the parent context, 059 * and then continuing up the chain of parents until the root context is 060 * reached. 061 * 062 * @param <T> 063 * The context type. 064 * @param clazz 065 * The class of context to be returned. 066 * @return The first context in the chain whose type is a sub-type of the 067 * provided {@code Context} class. 068 * @throws IllegalArgumentException 069 * If no matching context was found in this context's parent 070 * chain. 071 */ 072 <T extends Context> T asContext(Class<T> clazz); 073 074 /** 075 * Returns the first context in the chain whose context name matches the 076 * provided name. 077 * 078 * @param contextName 079 * The name of the context to be returned. 080 * @return The first context in the chain whose name matches the 081 * provided context name. 082 * @throws IllegalArgumentException 083 * If no matching context was found in this context's parent 084 * chain. 085 */ 086 Context getContext(String contextName); 087 088 /** 089 * Returns {@code true} if there is a context in the chain whose type is a 090 * sub-type of the provided {@code Context} class. The method first checks 091 * this context to see if it has the required type, before proceeding to the 092 * parent context, and then continuing up the chain of parents until the 093 * root context is reached. 094 * 095 * @param clazz 096 * The class of context to be checked. 097 * @return {@code true} if there is a context in the chain whose type is a 098 * sub-type of the provided {@code Context} class. 099 */ 100 boolean containsContext(Class<? extends Context> clazz); 101 102 /** 103 * Returns {@code true} if there is a context in the chain whose name 104 * matches the provided context name. 105 * 106 * @param contextName 107 * The name of the context to locate. 108 * @return {@code true} if there is a context in the chain whose context name 109 * matches {@code contextName}. 110 */ 111 boolean containsContext(String contextName); 112 113 /** 114 * Returns the unique ID identifying this context, usually a UUID. 115 * 116 * @return The unique ID identifying this context. 117 */ 118 String getId(); 119 120 /** 121 * Returns the parent of this context. 122 * 123 * @return The parent of this context, or {@code null} if this context is a 124 * root context. 125 */ 126 Context getParent(); 127 128 /** 129 * Returns {@code true} if this context is a root context. 130 * 131 * @return {@code true} if this context is a root context. 132 */ 133 boolean isRootContext(); 134 135 /** 136 * Return this Context as a JsonValue (for persistence). 137 * 138 * @return the Context data as a JsonValue. 139 */ 140 JsonValue toJsonValue(); 141}