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