001/*
002 * (C) Copyright 2006-2012 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 *     bstefanescu
018 *
019 */
020
021package org.nuxeo.ecm.webengine.model;
022
023import java.io.Writer;
024import java.security.Principal;
025import java.text.ParseException;
026import java.util.List;
027import java.util.Locale;
028import java.util.Map;
029
030import javax.servlet.http.HttpServletRequest;
031import javax.ws.rs.core.HttpHeaders;
032import javax.ws.rs.core.UriInfo;
033
034import org.apache.commons.logging.Log;
035import org.nuxeo.ecm.core.api.CoreSession;
036import org.nuxeo.ecm.core.api.DocumentModel;
037import org.nuxeo.ecm.webengine.WebEngine;
038import org.nuxeo.ecm.webengine.forms.FormData;
039import org.nuxeo.ecm.webengine.scripting.ScriptFile;
040import org.nuxeo.ecm.webengine.session.UserSession;
041import org.nuxeo.runtime.model.Adaptable;
042
043import com.sun.jersey.api.core.HttpContext;
044import com.sun.jersey.server.impl.inject.ServerInjectableProviderContext;
045
046/**
047 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
048 */
049public interface WebContext extends Adaptable {
050
051    /**
052     * <p>
053     * This variable is used in a proxy setting. The proxy should send a header with this name. Webengine will assume
054     * that the base path of the application is this value.
055     * <p>
056     * If your application is on server localhost:8080/nuxeo/site/myapp and you proxy it via mysite.com/myapp, then the
057     * header should have an empty string value.
058     */
059    String NUXEO_WEBENGINE_BASE_PATH = "nuxeo-webengine-base-path";
060
061    /**
062     * Gets the current web application.
063     *
064     * @return the web root. Cannot return null.
065     */
066    Module getModule();
067
068    /**
069     * Gets the jersey server injection context
070     *
071     * @since 9.1
072     */
073    ServerInjectableProviderContext getServerInjectableProviderContext();
074
075    /**
076     * Gets the jersey server http context
077     *
078     * @since 9.1
079     */
080    HttpContext getServerHttpContext();
081
082    /**
083     * Gets the root resource if any resource was defined as being the root
084     * <p>
085     * A root resource can be any resource from the resource chain.
086     *
087     * @return the root resource or null if no root was defined
088     */
089    Resource getRoot();
090
091    /**
092     * Set the root resource of this context
093     */
094    void setRoot(Resource root);
095
096    /**
097     * Gets the i18n message for the given key.
098     * <p>
099     * The current module i18n messages are queried first then if no message is found the global message pool is queried
100     * (the one living in WEB-INF/i18n). If no message is found the key surrounded by exclamation marks is returned.
101     *
102     * @param key the message key
103     * @return the message
104     */
105    String getMessage(String key);
106
107    /**
108     * The same as {@link #getMessage(String)} but with parameter support
109     */
110    String getMessage(String key, Object... args);
111
112    /**
113     * The same as {@link #getMessage(String)} but with parameter support
114     */
115    String getMessage(String key, List<Object> args);
116
117    /**
118     * Same as {@link #getMessage(String)} but uses the given locale.
119     *
120     * @param key the message key
121     * @param locale the locale to use
122     * @return the message
123     */
124    String getMessageL(String key, String locale);
125
126    /**
127     * The same as {@link #getMessage(String)} but uses the given locale, with parameter support
128     */
129    String getMessageL(String key, String locale, Object... args);
130
131    /**
132     * The same as {@link #getMessage(String)} but uses the given locale, with parameter support.
133     */
134    String getMessageL(String key, String locale, List<Object> args);
135
136    /**
137     * Gets the context locale.
138     * <p>
139     * If the locale has been set using {@link #setLocale(Locale)}, returns the last locale set. Otherwise, compute it
140     * from the Accept-Language language sent by the client, using {@link HttpServletRequest#getLocale()}.
141     *
142     * @return the context locale
143     */
144    Locale getLocale();
145
146    /**
147     * Sets the current locale, that will be kept in context.
148     */
149    void setLocale(Locale locale);
150
151    /**
152     * Gets the web engine instance.
153     *
154     * @return the web engine instance. Cannot return null
155     */
156    WebEngine getEngine();
157
158    /**
159     * Gets the current user session.
160     * <p>
161     * The user session is a WebEngine abstraction for the current user session and can be used to retrieve current
162     * login, core session, and to set or get user session variables.
163     *
164     * @return the user session. Never returns null.
165     */
166    UserSession getUserSession();
167
168    /**
169     * Gets the Core Session (or Repository Session) corresponding to that request.
170     *
171     * @return the core session. Cannot return null
172     */
173    CoreSession getCoreSession();
174
175    /**
176     * Gets the principal identifying the user that originated the request.
177     *
178     * @return the current principal. Can return null if the user has not been authenticated.
179     */
180    Principal getPrincipal();
181
182    /**
183     * Gets the JAX-RS UriInfo.
184     *
185     * @return the uri info
186     */
187    UriInfo getUriInfo();
188
189    /**
190     * Gets HTTP Headers as defined by JAX-RS.
191     *
192     * @return HTTP headers object
193     */
194    HttpHeaders getHttpHeaders();
195
196    /**
197     * Gets the underlying HTTP servlet request object.
198     *
199     * @return the HTTP Request object. Cannot return null
200     */
201    HttpServletRequest getRequest();
202
203    /**
204     * Get HTTP Method.
205     *
206     * @return the method
207     */
208    String getMethod();
209
210    /**
211     * Gets the representation of the data form submitted by the user.
212     * <p>
213     * This provides access to both POST and GET parameters, or to multipart form data requests.
214     *
215     * @return the request form data. Cannot return null
216     */
217    FormData getForm();
218
219    /**
220     * Gets the URL requested by the client. Same as {@link HttpServletRequest#getRequestURL()}.
221     *
222     * @return the request URL. Cannot return null.
223     */
224    String getURL();
225
226    /**
227     * Returns the part of this request's URL from the protocol name up to the query string in the first line of the
228     * HTTP request. This is the same as {@link HttpServletRequest#getRequestURI()}.
229     *
230     * @return the request URI. Cannot return null.
231     */
232    String getURI();
233
234    /**
235     * Gets the path portion of the request URL.
236     *
237     * @return the path portion of the request URL. Cannot return null.
238     */
239    String getUrlPath();
240
241    /**
242     * Gets the login path for the current context.
243     * <p>
244     * This is the path you can use as a login form action to perform a login or a logout. After the login/logout is
245     * done the current page in that context will be served.
246     */
247    String getLoginPath();
248
249    /**
250     * Get the path prefix that identify the current web application.
251     * <p>
252     * The application path will include the base path (context + servlet path).
253     *
254     * @return the application path. Cannot be null
255     */
256    String getModulePath();
257
258    /**
259     * Gets the path of the servlet. Same as servlet context path + servlet path.
260     *
261     * @return the site path
262     */
263    String getBasePath();
264
265    /**
266     * Gets the URL of the base path. This is the same as {@link #getURL()} after removing the path segments over the
267     * base path.
268     *
269     * @return the base URL
270     */
271    String getBaseURL();
272
273    /**
274     * Gets the server URL without any path or trailing /. The returned string builder can be used to build the wanted
275     * URL. If the server is behind a proxy, return the server url of the proxy so writing the url in a webpage is safe.
276     *
277     * @return a string builder
278     */
279    StringBuilder getServerURL();
280
281    /**
282     * Get a suitable URI path for the given Nuxeo document, that can be used to invoke this document. This method is
283     * working only for root objects that implement {@link ModuleResource}
284     *
285     * @param document the nuxeo document
286     * @return the path if any or null if no suitable path can be found XXX can this method return null?
287     * @throws ClassCastException if the module root does not implementing {@link ModuleResource}
288     */
289    // TODO: should we remove this method from the context and create a
290    // specialized service to resolve document models to paths?
291    String getUrlPath(DocumentModel document);
292
293    /**
294     * Sets a context variable.
295     *
296     * @param key the variable key
297     * @param value the variable value
298     * @see #getProperty(String)
299     */
300    void setProperty(String key, Object value);
301
302    /**
303     * Gets a context variable.
304     * <p>
305     * Context variables can be used to share data between the scripts that are called in that request (and between Java
306     * code too of course).
307     *
308     * @param key the variable key
309     * @return the variable value or null if none
310     */
311    Object getProperty(String key);
312
313    /**
314     * Gets a context variable.
315     * <p>
316     * Context variables can be used to share data between the scripts that are called in that request (and between java
317     * code too of course).
318     *
319     * @param key the variable key
320     * @param defaultValue the default value to use if the property doesn't exists
321     * @return the variable value or the given default value if none
322     */
323    Object getProperty(String key, Object defaultValue);
324
325    /**
326     * Convenience method to get a cookie value.
327     *
328     * @param name the cookie name
329     * @return the cookie value if any null otherwise
330     */
331    String getCookie(String name);
332
333    /**
334     * Convenience method to get a cookie value using a default value.
335     *
336     * @param name the cookie name
337     * @param defaultValue the value to return when cookie is not set
338     * @return the cookie value if any or the default if none
339     */
340    String getCookie(String name, String defaultValue);
341
342    /**
343     * Gets a logger to be used by scripts for logging.
344     *
345     * @return a logger
346     */
347    Log getLog();
348
349    Resource newObject(String typeName, Object... args);
350
351    Resource newObject(ResourceType type, Object... args);
352
353    AdapterResource newAdapter(Resource ctx, String adapterName, Object... args);
354
355    /* object stack API */
356
357    Resource push(Resource obj);
358
359    Resource pop();
360
361    Resource tail();
362
363    Resource head();
364
365    Resource getTargetObject();
366
367    AdapterResource getTargetAdapter();
368
369    /* template and script resolver */
370
371    /**
372     * Resolves the given path into a file.
373     * <p>
374     * The path is resolved as following:
375     * <ol>
376     * <li>if the path begin with a dot '.' then a local path is assumed and the path will be resolved relative to the
377     * current executed script if any. Note that the directory stack will be consulted as well. If there is no current
378     * executed script then the path will be transformed into an absolute path and next step is entered.
379     * <li>the resolving is delegated to the current {@link Module#getFile(String)} that will try to resolve the path
380     * relative to each directory in the directory stack
381     * </ol>
382     *
383     * @param path the path to resolve into a file
384     * @return the file or null if the path couldn't be resolved
385     */
386    ScriptFile getFile(String path);
387
388    /* running scripts and rendering templates */
389
390    /**
391     * Renders the given template using the rendering engine registered in that web engine.
392     * <p>
393     * This is similar to the {@link #render(String, Object, Writer)} method with a null value for the <i>args</i>
394     * argument.
395     *
396     * @param template the template to render. Can be a path absolute to the web directory or relative to the caller
397     *            script if any.
398     * @param writer the writer to use
399     * @see #render(String, Object, Writer)
400     */
401    void render(String template, Writer writer);
402
403    /**
404     * Renders the given template using the rendering engine registered in that web engine. The given arguments are
405     * passed to the rendering process as context variables
406     *
407     * @param template the template to render
408     * @param args the arguments to pass
409     * @param writer the writer to use
410     */
411    void render(String template, Object args, Writer writer);
412
413    /**
414     * Renders the given template using the rendering engine registered in that web engine.
415     * <p>
416     * The given arguments are passed to the rendering process as context variables.
417     *
418     * @param script the template to render
419     * @param args the arguments to pass
420     * @param writer the writer to use
421     */
422    void render(ScriptFile script, Object args, Writer writer);
423
424    /**
425     * Runs the given script.
426     *
427     * @param script the script path. Can be a path absolute to the web directory or relative to the caller script if
428     *            any.
429     * @param args the arguments to pass
430     */
431    Object runScript(String script, Map<String, Object> args);
432
433    /**
434     * Runs the given script.
435     * <p>
436     * This is similar to {@link #runScript(String, Map)} with a null value for the <i>args</i> argument
437     *
438     * @param script the script path. Can be a path absolute to the web directory or relative to the caller script if
439     *            any.
440     * @see #runScript(String, Map)
441     */
442    Object runScript(String script);
443
444    /**
445     * Runs the script using given arguments
446     * <p>
447     * This is similar to {@link #runScript(String, Map)} with a null value for the <i>args</i> argument
448     *
449     * @param script the script path. Can be a path absolute to the web directory or relative to the caller script if
450     *            any.
451     * @param args a map of arguments
452     * @see #runScript(String, Map)
453     */
454    Object runScript(ScriptFile script, Map<String, Object> args);
455
456    /**
457     * Check the given expression in this context and return true if the expression is verified or false otherwise. Any
458     * valid guard expression is accepted
459     *
460     * @see org.nuxeo.ecm.webengine.security.Guard
461     * @param guard the guard to check
462     */
463    boolean checkGuard(String guard) throws ParseException;
464
465    /**
466     * Sets the repository name that will be used by {@link #getCoreSession()}.
467     *
468     * @param repoName
469     * @throws IllegalArgumentException if the repository is not found.
470     * @since 5.7.3
471     */
472    void setRepositoryName(String repoName);
473
474}