001/* 002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nicolas Chapurlat <nchapurlat@nuxeo.com> 018 */ 019 020package org.nuxeo.ecm.core.io.registry.context; 021 022import java.io.Closeable; 023import java.io.IOException; 024import java.util.List; 025import java.util.Locale; 026import java.util.Map; 027import java.util.Set; 028 029import org.nuxeo.ecm.core.api.CoreSession; 030import org.nuxeo.ecm.core.api.DocumentModel; 031import org.nuxeo.ecm.core.io.registry.MarshallingException; 032import org.nuxeo.ecm.core.io.registry.context.RenderingContextImpl.RenderingContextBuilder; 033 034/** 035 * A context used to deliver parameter to marshallers during a marshalling request. 036 * <p> 037 * Use {@link CtxBuilder} to create your context. 038 * <p> 039 * When a {@link RenderingContext} is automatically provided from an HttpServletRequest, it contains request parameters, 040 * headers and request attribute. 041 * <p> 042 * To get/set parameter values, use: 043 * <ul> 044 * <li>{@link RenderingContext#getParameter(String)}</li> 045 * <li>{@link RenderingContext#getParameters(String)}</li> 046 * <li>{@link RenderingContext#getBooleanParameter(String)}</li> 047 * <li>{@link RenderingContext#getAllParameters()}</li> 048 * <li>{@link RenderingContext#addParameterValues(String, Object...)}</li> 049 * <li>{@link RenderingContext#addParameterListValues(String, List)}</li> 050 * <li>{@link RenderingContext#setParameterValues(String, Object...)}</li> 051 * <li>{@link RenderingContext#setParameterListValues(String, List)}</li> 052 * </ul> 053 * <p> 054 * To manage document properties, entity enrichers or properties fetching, use: 055 * <ul> 056 * <li>{@link RenderingContext#getProperties()}</li> 057 * <li>{@link RenderingContext#getEnrichers(String)}</li> 058 * <li>{@link RenderingContext#getFetched(String)}</li> 059 * </ul> 060 * <p> 061 * To manage infinite loop when calling a marshaller from another marshaller, use: 062 * <ul> 063 * <li>{@link RenderingContext#wrap()} -> {@link WrappedContext#controlDepth()}</li> 064 * </ul> 065 * Example: 066 * 067 * <pre> 068 * // This will control infinite loop in this marshaller 069 * try (Closeable resource = ctx.wrap().controlDepth().open()) { 070 * // call another marshaller to fetch the desired property here 071 * } catch (MaxDepthReachedException mdre) { 072 * // do not call the other marshaller 073 * } 074 * </pre> 075 * 076 * @since 7.2. 077 */ 078public interface RenderingContext { 079 080 Locale DEFAULT_LOCALE = Locale.ENGLISH; 081 082 String DEFAULT_URL = "http://fake-url.nuxeo.com/"; 083 084 String RESPONSE_HEADER_ENTITY_TYPE_KEY = "ENTITY_TYPE"; 085 086 /** 087 * @since 10.2 088 */ 089 String REPOSITORY_NAME_REQUEST_HEADER = "X-NXRepository"; 090 091 /** 092 * @since 10.2 093 */ 094 String REPOSITORY_NAME_REQUEST_PARAMETER = "nxrepository"; 095 096 /** 097 * Gets the requested {@link Locale}. 098 * 099 * @since 7.2 100 */ 101 Locale getLocale(); 102 103 /** 104 * Gets the current base url. 105 * 106 * @since 7.2 107 */ 108 String getBaseUrl(); 109 110 /** 111 * Gets the current {@link CoreSession} or try to create one. 112 * 113 * @param document may be null, if present, this method search for a session in the document. 114 * @return The current {@link CoreSession} if it exists. null otherwise. 115 * @throws MarshallingException if no session could be created or found. 116 * @since 7.2 117 */ 118 SessionWrapper getSession(DocumentModel document) throws MarshallingException; 119 120 /** 121 * Provides a {@link CoreSession} to marshallers. 122 * <p> 123 * For example: a {@link CoreSession} from the request context. 124 * </p> 125 * 126 * @param session The existing {@link CoreSession} which lifecycle is managed outside the marshalling context. 127 * @since 7.2 128 */ 129 void setExistingSession(CoreSession session); 130 131 /** 132 * Get all document properties. This will aggregate all values from parameters "properties", "X-NXproperties" and 133 * "X-NXDocumentProperties". This supports value separated by comma. 134 * 135 * @return All document properties. 136 * @since 7.2 137 */ 138 Set<String> getProperties(); 139 140 /** 141 * Get all properties to fetch for a given entity type. This will aggregate all values from parameters 142 * "fetch.entity" and "X-NXfetch.entity". This supports value separated by comma. 143 * 144 * @param entity The type of the entity on which you want to fetch properties. 145 * @return All properties to fetch. 146 * @since 7.2 147 */ 148 Set<String> getFetched(String entity); 149 150 /** 151 * Get all properties to translate for a given entity type. This will aggregate all values from parameters 152 * "translate.entity" and "X-NXtranslate.entity". This supports value separated by comma. 153 * 154 * @param entity The type of the entity on which you want to fetch properties. 155 * @return All properties to fetch. 156 * @since 7.2 157 */ 158 Set<String> getTranslated(String entity); 159 160 /** 161 * Get all enrichers to activate on the given entity type. This will aggregate all values from parameters 162 * "enrichers.entity", "X-NXenrichers.entity" and "X-NXContext-Category". This supports value separated by comma. 163 * 164 * @param entity The type of the entity on which you want to activate enrichers. 165 * @return All enrichers to activate. 166 * @since 7.2 167 */ 168 Set<String> getEnrichers(String entity); 169 170 /** 171 * see {@link WrappedContext} 172 * 173 * @return A new {@link WrappedContext} 174 * @since 7.2 175 */ 176 WrappedContext wrap(); 177 178 /** 179 * Get the casted parameter value for a given name. If multiple are available, the first found is returned. 180 * 181 * @param name The parameter name. 182 * @return The first parameter value, null if no parameter are availble. 183 * @since 7.2 184 */ 185 <T> T getParameter(String name); 186 187 /** 188 * see {@link #getParameter(String)} 189 * 190 * @return true is the parameter exists and if it's Boolean.TRUE or "true", false otherwise. 191 */ 192 boolean getBooleanParameter(String name); 193 194 /** 195 * Get the casted parameter values for a given name. 196 * 197 * @param name The parameter name. 198 * @return The parameter values. 199 * @since 7.2 200 */ 201 <T> List<T> getParameters(String name); 202 203 /** 204 * Get all parameter in this context except wrapped parameters. 205 * 206 * @return All parameter's names and their values. 207 * @since 7.2 208 */ 209 Map<String, List<Object>> getAllParameters(); 210 211 /** 212 * @see #setParameterListValues(String, List) 213 * @since 7.2 214 */ 215 void setParameterValues(String name, Object... values); 216 217 /** 218 * Push values in the context with a given name. Please note that this method remove any value for the given name. 219 * 220 * @param name The parameter name. 221 * @param values The parameter values. 222 * @since 7.2 223 */ 224 void setParameterListValues(String name, List<Object> values); 225 226 /** 227 * @see #addParameterListValues(String, List) 228 * @since 7.2 229 */ 230 void addParameterValues(String name, Object... values); 231 232 /** 233 * Add values in the context with a given name. Please note that this method keep current values for the given name. 234 * 235 * @param name The parameter name. 236 * @param values The parameter values. 237 * @since 7.2 238 */ 239 void addParameterListValues(String name, List<?> values); 240 241 /** 242 * {@link RenderingContext} builder. 243 * <p> 244 * RenderingContext ctx = CtxBuilder.base("http://mine.nuxeo.com/nuxeo").locale(Locale.ENGLISH).param("name", 245 * "value1", "value2").get(); 246 * </p> 247 * 248 * @since 7.2 249 */ 250 public static final class CtxBuilder { 251 private CtxBuilder() { 252 } 253 254 public static RenderingContextBuilder builder() { 255 return new RenderingContextBuilder(); 256 } 257 258 public static RenderingContextBuilder base(String url) { 259 RenderingContextBuilder builder = new RenderingContextBuilder(); 260 return builder.base(url); 261 } 262 263 public static RenderingContextBuilder locale(Locale locale) { 264 RenderingContextBuilder builder = new RenderingContextBuilder(); 265 return builder.locale(locale); 266 } 267 268 public static RenderingContextBuilder session(CoreSession session) { 269 RenderingContextBuilder builder = new RenderingContextBuilder(); 270 return builder.session(session); 271 } 272 273 public static RenderingContextBuilder param(String name, Object value) { 274 RenderingContextBuilder builder = new RenderingContextBuilder(); 275 return builder.param(name, value); 276 } 277 278 public static RenderingContextBuilder paramValues(String name, Object... values) { 279 RenderingContextBuilder builder = new RenderingContextBuilder(); 280 return builder.paramValues(name, values); 281 } 282 283 public static RenderingContextBuilder paramList(String name, List<?> values) { 284 RenderingContextBuilder builder = new RenderingContextBuilder(); 285 return builder.paramList(name, values); 286 } 287 288 public static RenderingContextBuilder properties(String... schemaName) { 289 RenderingContextBuilder builder = new RenderingContextBuilder(); 290 return builder.properties(schemaName); 291 } 292 293 public static RenderingContextBuilder fetch(String entityType, String... propertyName) { 294 RenderingContextBuilder builder = new RenderingContextBuilder(); 295 return builder.fetch(entityType, propertyName); 296 } 297 298 public static RenderingContextBuilder fetchInDoc(String... propertyName) { 299 RenderingContextBuilder builder = new RenderingContextBuilder(); 300 return builder.fetchInDoc(propertyName); 301 } 302 303 public static RenderingContextBuilder translate(String entityType, String... propertyName) { 304 RenderingContextBuilder builder = new RenderingContextBuilder(); 305 return builder.translate(entityType, propertyName); 306 } 307 308 public static RenderingContextBuilder enrich(String entityType, String... enricherName) { 309 RenderingContextBuilder builder = new RenderingContextBuilder(); 310 return builder.enrich(entityType, enricherName); 311 } 312 313 public static RenderingContextBuilder enrichDoc(String... enricherName) { 314 RenderingContextBuilder builder = new RenderingContextBuilder(); 315 return builder.enrichDoc(enricherName); 316 } 317 318 public static RenderingContextBuilder depth(DepthValues value) { 319 RenderingContextBuilder builder = new RenderingContextBuilder(); 320 return builder.depth(value); 321 } 322 323 public static RenderingContext get() { 324 RenderingContextBuilder builder = new RenderingContextBuilder(); 325 return builder.get(); 326 } 327 } 328 329 /** 330 * Session wrapper. This used to be needed to close session, which isn't needed anymore. 331 * 332 * @since 7.2 333 */ 334 public class SessionWrapper implements Closeable { 335 336 private CoreSession session; 337 338 public SessionWrapper(CoreSession session) { 339 super(); 340 this.session = session; 341 } 342 343 public CoreSession getSession() { 344 return session; 345 } 346 347 @Override 348 public void close() throws IOException { 349 } 350 351 } 352 353}