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