1 // This may look like C code, but it's really -*- C++ -*-
2 /*
3  * Copyright (C) 2008 Emweb bv, Herent, Belgium.
4  *
5  * See the LICENSE file for terms of use.
6  */
7 #ifndef WAPPLICATION_
8 #define WAPPLICATION_
9 
10 #include <chrono>
11 #include <vector>
12 #include <string>
13 #include <set>
14 
15 // even boost/poolfwd.hpp includes <windows.h> ...
16 namespace boost {
17   struct default_user_allocator_new_delete;
18 
19   template <typename UserAllocator>
20   class pool;
21 }
22 
23 #include <Wt/WObject.h>
24 #include <Wt/WCssStyleSheet.h>
25 #include <Wt/WEvent.h>
26 #include <Wt/WJavaScriptPreamble.h>
27 #include <Wt/WJavaScriptSlot.h>
28 #include <Wt/WLocale.h>
29 #include <Wt/WMessageResourceBundle.h>
30 #include <Wt/WSignal.h>
31 #include <Wt/WString.h>
32 
33 namespace Wt {
34 
35 #ifndef WT_TARGET_JAVA
36 /*
37  * Symbols used to check that included version matches library version
38  * against which you link.
39  */
40 struct WtLibVersion { };
41 extern WT_API const WtLibVersion WT_INCLUDED_VERSION;
42 #endif
43 
44 class WApplication;
45 class WCombinedLocalizedStrings;
46 class WContainerWidget;
47 class WEnvironment;
48 class WEvent;
49 class WLoadingIndicator;
50 class WLogEntry;
51 class WResource;
52 class WText;
53 
54 class WebSession;
55 class RootContainer;
56 class UpdateLockImpl;
57 class SoundManager;
58 
59 /*! \brief Typedef for a function that creates WApplication objects.
60  *
61  * \sa WRun()
62  *
63  * \relates WApplication
64  */
65 typedef std::function<std::unique_ptr<WApplication> (const WEnvironment&)> ApplicationCreator;
66 
67 #ifdef WT_TARGET_JAVA
68 /*! \brief An HTML Meta Header
69  */
70 #endif // WT_TARGET_JAVA
71 class MetaHeader {
72 public:
73   /*! \brief Constructor
74    *
75    * Creates a meta header. The lang and user agents are optional, and should
76    * be an empty string if not used.
77    */
78   MetaHeader(MetaHeaderType type, const std::string& name,
79 	     const WString& content, const std::string& lang,
80 	     const std::string& userAgent);
81 
82   MetaHeaderType type;
83   std::string name, lang, userAgent;
84   WString content;
85 };
86 
87 /*! \class WApplication Wt/WApplication.h Wt/WApplication.h
88  *  \brief Represents an application instance for a single session.
89  *
90  * \if cpp
91  *
92  * Each user session of your application has a corresponding
93  * %WApplication instance. You need to create a new instance and return
94  * it as the result of the callback function passed to WRun(). The
95  * instance is the main entry point to session information, and holds
96  * a reference to the root() of the widget tree.
97  *
98  * \elseif java
99  *
100  * Each user session of your application has a corresponding
101  * %WApplication instance. You need to create a new instance and return
102  * it as the result of {javadoclink WtServlet#createApplication(WEnvironment)}.
103  * The instance is the main entry point to session information,
104  * and holds a reference to the root() of the widget tree.
105  *
106  * \endif
107  *
108  * The recipe for a %Wt web application, which allocates new
109  * WApplication instances for every user visiting the application is
110  * thus:
111  *
112  * \if cpp
113  * \code
114  * std::unique_ptr<WApplication> createApplication(const WEnvironment& env)
115  * {
116  *   //
117  *   // Optionally, check the environment and redirect to an error page.
118  *   //
119  *   bool valid = ...;
120  *
121  *   std::unique_ptr<WApplication> app;
122  *   if (!valid) {
123  *     app = std::make_unique<WApplication>(env);
124  *     app->redirect("error.html");
125  *     app->quit();
126  *   } else {
127  *     // usually you will specialize your application class
128  *     app = std::make_unique<WApplication>(env);
129  *
130  *     //
131  *     // Add widgets to app->root() and return the application object.
132  *     //
133  *   }
134  *
135  *   return app;
136  * }
137  * \endcode
138  * \elseif java
139  * \code
140  * public class HelloServlet extends WtServlet {
141  *  public HelloServlet() {
142  *      super();
143  *  }
144  *
145  *  public WApplication createApplication(WEnvironment env) {
146  *      // In practice, you will specialize WApplication and simply
147  *      // return a new instance.
148  *      WApplication app = new WApplication(env);
149  *      app.getRoot().addWidget(new WText("Hello world."));
150  *      return app;
151  *  }
152  * }
153  * \endcode
154  * \endif
155  *
156  * \if cpp
157  *
158  * Throughout the session, the instance is available through
159  * WApplication::instance() (or through #wApp). The application may be
160  * exited either using the method quit(), or because of a timeout
161  * after the user has closed the window, but not because the user does
162  * not interact: keep-alive messages in the background will keep the
163  * session around as long as the user has the page opened. In either
164  * case, the application object is deleted, allowing for cleanup of
165  * the entire widget tree, and any other resources.
166  *
167  * \elseif java
168  *
169  * Throughout the session, the instance is available through the
170  * static method WApplication::instance(), which uses thread-specific
171  * storage to keep track of the current session. The application may
172  * be exited either using the method quit(), or because of a timeout
173  * after the user has closed the window, but not because the user does
174  * not interact: keep-alive messages in the background will keep the
175  * session around as long as the user has the page opened.
176  *
177  * \endif
178  *
179  * The %WApplication object provides access to session-wide settings, including:
180  *
181  * - circumstantial information through environment(), which gives
182  *   details about the user, start-up arguments, and user agent
183  *   capabilities.
184  * - the application title with setTitle().
185  * - inline and external style sheets using styleSheet() and
186  *   useStyleSheet().
187  * - inline and external JavaScript using doJavaScript() and require().
188  * - the top-level widget in root(), representing the entire browser window,
189  *   or multiple top-level widgets using bindWidget() when deployed in
190  *   EntryPointType::WidgetSet mode to manage a number of widgets within a 3rd party page.
191  * - definition of cookies using setCookie() to persist information across
192  *   sessions, which may be read using WEnvironment::getCookie() in a future
193  *   session.
194  * - management of the internal path (that enables browser history and
195  *   bookmarks) using setInternalPath() and related methods.
196  * - support for server-initiated updates with enableUpdates()
197  * \if cpp
198  * - localization information and message resources bundles using setLocale()
199  *   and messageResourceBundle().
200  * \elseif java
201  * - localization information and message resources bundles, with
202  *   setLocale() and setLocalizedStrings()
203  * \endif
204  */
205 class WT_API WApplication : public WObject
206 {
207 public:
208   /*! \brief Typedef for a function that creates WApplication objects.
209    *
210    * \sa WRun()
211    */
212   typedef Wt::ApplicationCreator ApplicationCreator;
213 
214   /*! \brief Creates a new application instance.
215    *
216    * The \p environment provides information on the initial request,
217    * user agent, and deployment-related information.
218    */
219 #if defined(DOXYGEN_ONLY) || defined(WT_TARGET_JAVA)
220   WApplication(const WEnvironment& environment);
221 #else
222   WApplication(const WEnvironment& environment,
223 	       WtLibVersion version = WT_INCLUDED_VERSION);
224 #endif
225 
226 #ifndef WT_TARGET_JAVA
227   /*! \brief Destructor.
228    *
229    * The destructor deletes the root() container, and as a consequence
230    * the entire widget tree.
231    */
232   ~WApplication();
233 #endif // WT_TARGET_JAVA
234 
235   /*! \brief Returns the current application instance.
236    *
237    * \if cpp
238    * This is the same as the global define #wApp. In a multi-threaded server,
239    * this method uses thread-specific storage to fetch the current session.
240    * \elseif java
241    * This method uses thread-specific storage to fetch the current session.
242    * \endif
243    */
244   static WApplication *instance();
245 
246   /*! \brief Returns the environment information.
247    *
248    * This method returns the environment object that was used when
249    * constructing the application. The environment provides
250    * information on the initial request, user agent, and
251    * deployment-related information.
252    *
253    * \sa url(), sessionId()
254    */
255   const WEnvironment& environment() const;
256 
257   /*! \brief Returns the root container.
258    *
259    * This is the top-level widget container of the application, and
260    * corresponds to entire browser window. The user interface of your
261    * application is represented by the content of this container.
262    *
263    * \if cpp
264    *
265    * The %root() widget is only defined when the application manages
266    * the entire window. When deployed as a \link Wt::EntryPointType::WidgetSet
267    * EntryPointType::WidgetSet\endlink application, there is no %root() container, and
268    * \c 0 is returned.  Instead, use bindWidget() to bind one or more
269    * root widgets to existing HTML &lt;div&gt; (or other) elements on
270    * the page.
271    *
272    * \elseif java
273    *
274    * The root() widget is only defined when the application manages
275    * the entire window. When deployed as a \link Wt::EntryPointType::WidgetSet
276    * EntryPointType::WidgetSet\endlink application, there is no %root() container, and
277    * <code>null</code> is returned. Instead, use bindWidget() to bind
278    * one or more root widgets to existing HTML &lt;div&gt; (or other)
279    * elements on the page.
280    *
281    * \endif
282    */
root()283   WContainerWidget *root() const { return widgetRoot_; }
284 
285   /*! \brief Finds a widget by name.
286    *
287    * This finds a widget in the application's widget hierarchy. It
288    * does not only consider widgets in the root(), but also widgets
289    * that are placed outside this root, such as in dialogs, or other
290    * "roots" such as all the bound widgets in a widgetset application.
291    *
292    * \sa WWidget::setObjectName(), WWidget::find()
293    */
294   WWidget *findWidget(const std::string& name);
295 
296   /** @name Style sheets and CSS
297    */
298   //!@{
299   /*! \brief Returns a reference to the inline style sheet.
300    *
301    * Widgets may allow configuration of their look and feel through
302    * style classes. These may be defined in this inline stylesheet, or
303    * in external style sheets.
304    *
305    * It is usually preferable to use external stylesheets (and
306    * consider more accessible). Still, the internal stylesheet has as
307    * benefit that style rules may be dynamically updated, and it is
308    * easier to manage logistically.
309    *
310    * \sa useStyleSheet()
311    * \sa WWidget::setStyleClass()
312    */
styleSheet()313   WCssStyleSheet& styleSheet() { return styleSheet_; }
314 
315   /*! \brief Adds an external style sheet.
316    *
317    * The \p link is a link to a stylesheet.
318    *
319    * The \p media indicates the CSS media to which this stylesheet
320    * applies. This may be a comma separated list of media. The default
321    * value is "all" indicating all media.
322    *
323    * This is an overloaded method for convenience, equivalent to:
324    * \code
325    * useStyleSheet(Wt::WCssStyleSheet(link, media))
326    * \endcode
327    */
328   void useStyleSheet(const WLink& link, const std::string& media = "all");
329 
330   /*! \brief Conditionally adds an external style sheet.
331    *
332    * This is an overloaded method for convenience, equivalent to:
333    * \code
334    * useStyleSheet(Wt::WLinkedCssStyleSheet(link, media), condition)
335    * \endcode
336    */
337   void useStyleSheet(const WLink& link, const std::string& condition,
338 		     const std::string& media);
339 
340   /*! \brief Adds an external stylesheet.
341    *
342    * Widgets may allow configuration of their look and feel through
343    * style classes. These may be defined in an inline stylesheet,
344    * or in external style sheets.
345    *
346    * External stylesheets are inserted after the internal style sheet,
347    * and can therefore override default styles set by widgets in the
348    * internal style sheet.
349    * External stylesheets must have valid link.
350    *
351    * If not empty, \p condition is a string that is used to apply the
352    * stylesheet to specific versions of IE. Only a limited subset of
353    * the IE conditional comments syntax is supported (since these are
354    * in fact interpreted server-side instead of client-side). Examples
355    * are:
356    *
357    * - "IE gte 6": only for IE version 6 or later.
358    * - "!IE gte 6": only for IE versions prior to IE6.
359    * - "IE lte 7": only for IE versions prior to IE7.
360    *
361    * \sa styleSheet(), useStyleSheet(const std::string&, const std::string&),
362    *  removeStyleSheet(const WLink& link)
363    * \sa WWidget::setStyleClass()
364    */
365   void useStyleSheet(const WLinkedCssStyleSheet& styleSheet,
366 		     const std::string& condition = "");
367 
368   /*! \brief Removes an external stylesheet.
369    *
370    * \sa styleSheet(), useStyleSheet(const std::string&, const std::string&)
371    * \sa WWidget::setStyleClass()
372    */
373   void removeStyleSheet(const WLink& link);
374 
375   /*! \brief Sets the theme.
376    *
377    * The theme provides the look and feel of several built-in widgets,
378    * using CSS style rules. Rules for each theme are defined in the
379    * <tt>resources/themes/</tt><i>theme</i><tt>/</tt> folder.
380    *
381    * The default theme is "default" CSS theme.
382    */
383   void setTheme(const std::shared_ptr<WTheme>& theme);
384 
385   /*! \brief Returns the theme.
386    */
theme()387   std::shared_ptr<WTheme> theme() const { return theme_; }
388 
389   /*! \brief Sets a CSS theme.
390    *
391    * This sets a WCssTheme as theme.
392    *
393    * The theme provides the look and feel of several built-in widgets,
394    * using CSS style rules. Rules for each CSS theme are defined in
395    * the <tt>resources/themes/</tt><i>name</i><tt>/</tt> folder.
396    *
397    * The default theme is "default". Setting an empty theme "" will
398    * result in a stub CSS theme that does not load any stylesheets.
399    */
400   void setCssTheme(const std::string& name);
401 
402   /*! \brief Sets the layout direction.
403    *
404    * The default direction is LayoutDirection::LeftToRight.
405    *
406    * This sets the language text direction, which by itself sets the
407    * default text alignment and reverse the column orders of &lt;table&gt;
408    * elements.
409    *
410    * In addition, %Wt will take this setting into account in
411    * WTextEdit, WTableView and WTreeView (so that columns are
412    * reverted), and swap the behaviour of WWidget::setFloatSide() and
413    * WWidget::setOffsets() for LayoutDirection::RightToLeft
414    * languages. Note that CSS settings themselves are not affected by
415    * this setting, and thus for example <tt>"float: right"</tt> will
416    * move a box to the right, irrespective of the layout direction.
417    *
418    * The library sets <tt>"Wt-ltr"</tt> or <tt>"Wt-rtl"</tt> as style
419    * classes for the document body. You may use this if to override
420    * certain style rules for a Right-to-Left document.
421    *
422    * The only valid values are LayoutDirection::LeftToRight or
423    * LayoutDirection::RightToLeft.
424    *
425    * For example:
426    * \code
427    * body        .sidebar { float: right; }
428    * body.Wt-rtl .sidebar { float: left; }
429    * \endcode
430    *
431    * \note The layout direction can be set only at application startup
432    * and does not have the effect of rerendering the entire UI.
433    */
434   void setLayoutDirection(LayoutDirection direction);
435 
436   /*! \brief Returns the layout direction.
437    *
438    * \sa setLayoutDirection()
439    */
layoutDirection()440   LayoutDirection layoutDirection() const { return layoutDirection_; }
441 
442   /*! \brief Sets a style class to the entire page &lt;body&gt;.
443    *
444    * \sa setHtmlClass()
445    */
446   void setBodyClass(const std::string& styleClass);
447 
448   /*! \brief Returns the style class set for the entire page &lt;body&gt;.
449    *
450    * \sa setBodyClass()
451    */
bodyClass()452   std::string bodyClass() const { return bodyClass_; }
453 
454   /*! \brief Sets a style class to the entire page &lt;html&gt;.
455    *
456    * \sa setBodyClass()
457    */
458   void setHtmlClass(const std::string& styleClass);
459 
460   /*! \brief Returns the style class set for the entire page &lt;html&gt;.
461    *
462    * \sa setHtmlClass()
463    */
htmlClass()464   std::string htmlClass() const { return htmlClass_; }
465   //!@}
466 
467   /*! \brief Sets the window title.
468    *
469    * Sets the browser window title to \p title.
470    *
471    * The default title is "".
472    *
473    * \sa title()
474    */
475   void setTitle(const WString& title);
476 
477   /*! \brief Returns the window title.
478    *
479    * \sa setTitle(const WString&)
480    */
title()481   const WString& title() const { return title_; }
482 
483   /*! \brief Returns the close message.
484    *
485    * \sa setConfirmCloseMessage()
486    */
closeMessage()487   const WString& closeMessage() const { return closeMessage_; }
488 
489   /*! \brief Returns the resource object that provides localized strings.
490    *
491    * \if cpp
492    * The default value is a WMessageResourceBundle instance, which
493    * uses XML files to resolve localized strings, but you can set a
494    * custom class using setLocalizedStrings().
495    * \elseif java
496    * This returns the object previously set using setLocalizedStrings().
497    * \endif
498    *
499    * WString::tr() is used to create localized strings, whose
500    * localized translation is looked up through this object, using a
501    * key.
502    *
503    * \if cpp
504    * \sa WString::tr(), messageResourceBundle()
505    * \elseif java
506    * \sa WString::tr()
507    * \endif
508    */
509   std::shared_ptr<WLocalizedStrings> localizedStrings();
510 
511 #ifdef WT_TARGET_JAVA
512   /*! \brief Accesses the built-in resource bundle.
513    *
514    * This is an internal function and should not be called directly.
515    *
516    * \sa localizedStrings()
517    */
518 #endif // WT_TARGET_JAVA
519   WMessageResourceBundle& builtinLocalizedStrings();
520 
521   /*! \brief Sets the resource object that provides localized strings.
522    *
523    * The \p translator resolves localized strings within the current
524    * application locale.
525    *
526    * \sa localizedStrings(), WString::tr(const char *key)
527    */
528   void setLocalizedStrings(const std::shared_ptr<WLocalizedStrings>&
529 			   stringResolver);
530 
531 #ifndef WT_TARGET_JAVA
532   /*! \brief Returns the message resource bundle.
533    *
534    * The message resource bundle defines the list of external XML
535    * files that are used to lookup localized strings.
536    *
537    * The default localizedStrings() is a WMessageResourceBundle
538    * object, and this method returns localizedStrings() downcasted to
539    * this type.
540    *
541    * \throws WException when localizedStrings() is not a WMessageResourceBundle
542    *
543    * \sa WString::tr(const char *key)
544    */
545   WMessageResourceBundle& messageResourceBundle();
546 #endif // WT_TARGET_JAVA
547 
548   /*! \brief Changes the locale.
549    *
550    * The locale is used by the localized strings resource to resolve
551    * localized strings.
552    *
553    * By passing an empty \p locale, the default locale is
554    * chosen.
555    *
556    * When the locale is changed, refresh() is called, which will
557    * resolve the strings of the current user-interface in the new
558    * locale.
559    *
560    * At construction, the locale is copied from the environment
561    * (WEnvironment::locale()), and this is the locale that was
562    * configured by the user in his browser preferences, and passed
563    * using an HTTP request header.
564    *
565    * \sa localizedStrings(), WString::tr()
566    */
567   void setLocale(const WLocale& locale);
568 
569   /*! \brief Returns the current locale.
570    *
571    * \sa setLocale(const WLocale&)
572    */
locale()573   const WLocale& locale() const { return locale_; }
574 
575   /*! \brief Refreshes the application.
576    *
577    * This lets the application refresh its data, including strings
578    * from message resource bundles. This is done by propagating
579    * WWidget::refresh() through the widget hierarchy.
580    *
581    * This method is also called when the user hits the refresh (or
582    * reload) button, if this can be caught within the current session.
583    *
584    * \if cpp
585    *
586    * The reload button may only be caught when %Wt is configured so that
587    * reload should not spawn a new session. When URL rewriting is used for
588    * session tracking, this will cause an ugly session ID to be added to the
589    * URL. See \ref config_session for configuring the reload
590    * behavior ("<reload-is-new-session>").
591    *
592    * \elseif java
593    *
594    * The reload button may only be caught when cookies for session
595    * tracking are configured in the servlet container.
596    *
597    * \endif
598    *
599    * \sa WWidget::refresh()
600    */
601   virtual void refresh();
602 
603   /*! \brief Binds a top-level widget for a EntryPointType::WidgetSet deployment.
604    *
605    * This method binds a \p widget to an existing element with DOM id
606    * \p domId on the page. The element type should correspond with
607    * the widget type (e.g. it should be a &lt;div&gt; for a
608    * WContainerWidget, or a &lt;table&gt; for a WTable).
609    *
610    * \sa root()
611    * \sa Wt::EntryPointType::WidgetSet
612    */
613   void bindWidget(std::unique_ptr<WWidget> widget, const std::string& domId);
614 
615   /** @name URLs and internal paths
616    */
617   //!@{
618   /*! \brief Returns a URL for the current session
619    *
620    * Returns the (relative) URL for this application session
621    * (including the session ID if necessary). The URL includes the
622    * full application path, and is expanded by the browser into a full
623    * URL.
624    *
625    * For example, for an application deployed at \code
626    * http://www.mydomain.com/stuff/app.wt \endcode this method might
627    * return <tt>"/stuff/app.wt?wtd=AbCdEf"</tt>. Additional query
628    * parameters can be appended in the form of
629    * <tt>"&param1=value&param2=value"</tt>.
630    *
631    * To obtain a URL that is suitable for bookmarking the current
632    * application state, to be used across sessions, use bookmarkUrl()
633    * instead.
634    *
635    * \sa redirect(), WEnvironment::hostName(), WEnvironment::urlScheme()
636    * \sa bookmarkUrl()
637    */
638   std::string url(const std::string& internalPath = std::string()) const;
639 
640   /*! \brief Makes an absolute URL.
641    *
642    * Returns an absolute URL for a given (relative url) by including
643    * the schema, hostname, and deployment path.
644    *
645    * If \p url is "", then the absolute base URL is returned. This is
646    * the absolute URL at which the application is deployed, up to the
647    * last '/'.
648    *
649    * The default implementation is not complete: it does not handle relative
650    * URL path segments with '..'. It just handles the cases that are necessary for
651    * %Wt.
652    *
653    * This is not used in the library, except when a public URL is
654    * needed, e.g. for inclusion in an email.
655    *
656    * You may want to reimplement this method when the application is
657    * hosted behind a reverse proxy or in general the public URL of the
658    * application cannot be guessed correctly by the application.
659    */
660   virtual std::string makeAbsoluteUrl(const std::string& url) const;
661 
662   /*! \brief "Resolves" a relative URL taking into account internal paths.
663    *
664    * This resolves the relative URL against the base path of the application,
665    * so that it will point to the correct path regardless of the current internal
666    * path, e.g. if the application is deployed at <tt>%http://example.com/one</tt>
667    * and we're at the internal path <tt>/two/</tt>, so that the full URL is
668    * <tt>%http://example.com/one/two/</tt>, the output of the input URL <tt>three</tt>
669    * will point to <tt>%http://example.com/three</tt>, and not
670    * <tt>%http://example.com/one/two/three</tt>.
671    *
672    * If the given url is the empty string, the result will point to the base path
673    * of the application.
674    *
675    * See the table below for more examples.
676    *
677    * <h3>When you would want to use resolveRelativeUrl:</h3>
678    *
679    * Using HTML5 History API or in a plain HTML session (without ugly
680    * internal paths), the internal path is present as a full part of
681    * the URL. This has a consequence that relative URLs, if not dealt
682    * with, would be resolved against the last 'folder' name of the
683    * internal path, rather than against the application deployment
684    * path (which is what you probably want).
685    *
686    * When using a widgetset mode deployment, or when configuring a
687    * baseURL property in the configuration, this method will make an
688    * absolute URL so that the property is fetched from the right
689    * server.
690    *
691    * Otherwise, this method will fixup a relative URL so that it
692    * resolves correctly against the base path of an application. This
693    * does not necessarily mean that the URL is resolved into an
694    * absolute URL. In fact, %Wt will simply prepend a sequence of "../"
695    * path elements to correct for the internal path. When passed an
696    * absolute URL (i.e. starting with '/'), the url is returned
697    * unchanged.
698    *
699    * For URLs passed to the %Wt API (and of which the library knows it
700    * represents a URL) this method is called internally by the
701    * library. But it may be useful for URLs which are set e.g. inside
702    * a WTemplate.
703    *
704    * <h3>Examples</h3>
705    *
706    * Note that whether the deployment path and entry point ends with a slash is significant.
707    * Below are some examples with the
708    * <span style="color:red;">deployment path</span> in <span style="color:red;">red</span>
709    * and the <span style="color:blue;">internal path</span> in <span style="color:blue;">blue</span>.
710    *
711    * <table>
712    * <tr><th>Current full path</th><th>url argument</th><th>Result points to</th></tr>
713    * <tr><td rowspan="4"><tt>%http://example.com</tt><tt style="color:red;">/foo/bar</tt><tt style="color:blue;">/internal/path</tt><br />Deployment path: <tt style="color:red;">/foo/bar</tt> (no slash at the end)<br />Internal path: <tt style="color:blue;">/internal/path</tt></td>
714    * <td><i>(empty string)</i></td><td><tt>%http://example.com/foo/bar</tt></tr>
715    * <tr><td><tt>.</tt></td><td><tt>%http://example.com/foo/</tt></td></tr>
716    * <tr><td><tt>./</tt></td><td><tt>%http://example.com/foo/</tt></td></tr>
717    * <tr><td><tt>../</tt></td><td><tt>%http://example.com/</tt></td></tr>
718    * <tr><td rowspan="4"><tt>%http://example.com</tt><tt style="color:red;">/foo/bar</tt><tt style="color:magenta;font-weight:bold;">/</tt><tt style="color:blue;">internal/path</tt><br />Deployment path: <tt style="color:red;">/foo/bar/</tt> (with slash at the end)<br />Internal path: <tt style="color:blue;">/internal/path</tt><br />Note that the slash between the deployment path and the internal path is shared</td>
719    * <td><i>(empty string)</i></td><td><tt>%http://example.com/foo/bar/</tt></tr>
720    * <tr><td><tt>.</tt></td><td><tt>%http://example.com/foo/bar/</tt></td></tr>
721    * <tr><td><tt>./</tt></td><td><tt>%http://example.com/foo/bar/</tt></td></tr>
722    * <tr><td><tt>../</tt></td><td><tt>%http://example.com/foo/</tt></td></tr>
723    * </table>
724    */
725   std::string resolveRelativeUrl(const std::string& url) const;
726 
727   /*! \brief Returns a bookmarkable URL for the current internal path.
728    *
729    * Is equivalent to <tt>bookmarkUrl(internalPath())</tt>, see
730    * bookmarkUrl(const std::string&) const.
731    *
732    * To obtain a URL that is refers to the current session of the
733    * application, use url() instead.
734    *
735    * \sa url(), bookmarkUrl(const std::string&) const
736    */
737   std::string bookmarkUrl() const;
738 
739   /*! \brief Returns a bookmarkable URL for a given internal path.
740    *
741    * Returns the (relative) URL for this application that includes the
742    * internal path \p internalPath, usable across sessions.
743    *
744    * The returned URL concatenates the internal path to the application
745    * base URL, and when no JavaScript is available and URL rewriting is used
746    * for session-tracking, a session Id is appended to reuse an existing
747    * session if available.
748    *
749    * \if cpp
750    * See also \ref config_session for configuring the session-tracking
751    * method.
752    *
753    * For the built-in httpd, when the application is deployed at a folder
754    * (ending with '/'), only an exact matching path is routed to
755    * the application (this can be changed since Wt 3.1.9, see
756    * \ref wthttpd ), making clean URLs impossible. Returned URLs then
757    * include a <tt>"?_="</tt> encoding for the internal path.
758    * \endif
759    *
760    * You can use bookmarkUrl() as the destination for a WAnchor, and
761    * listen to a click event is attached to a slot that switches to
762    * the internal path \p internalPath (see
763    * WAnchor::setRefInternalPath()). In this way, an anchor can be
764    * used to switch between internal paths within an application
765    * regardless of the situation (browser with or without Ajax
766    * support, or a web spider bot), but still generates suitable URLs
767    * across sessions, which can be used for bookmarking, opening in a
768    * new window/tab, or indexing.
769    *
770    * To obtain a URL that refers to the current session of the
771    * application, use url() instead.
772    *
773    * \sa url(), bookmarkUrl()
774    *
775    * \if cpp
776    * \note the \p internalPath should be CharEncoding::UTF8 encoded (we may fix the API
777    *       to use WString in the future).
778    * \endif
779    */
780   std::string bookmarkUrl(const std::string& internalPath) const;
781 
782   /*! \brief Changes the internal path.
783    *
784    * A %Wt application may manage multiple virtual paths. The virtual
785    * path is appended to the application URL. Depending on the
786    * situation, the path is directly appended to the application URL
787    * or it is appended using a name anchor (#).
788    *
789    * For example, for an application deployed at:
790    * \code
791    * http://www.mydomain.com/stuff/app.wt
792    * \endcode
793    * for which an \p internalPath <tt>"/project/z3cbc/details/"</tt> is
794    * set, the two forms for the application URL are:
795    * <ul>
796    * <li> in an AJAX session (HTML5):
797    * \code
798    * http://www.mydomain.com/stuff/app.wt/project/z3cbc/details/
799    * \endcode
800    * </li><li> in an AJAX session (HTML4):
801    * \code
802    * http://www.mydomain.com/stuff/app.wt#/project/z3cbc/details/
803    * \endcode
804    * </li><li>
805    * in a plain HTML session:
806    * \code
807    * http://www.mydomain.com/stuff/app.wt/project/z3cbc/details/
808    * \endcode
809    * </li></ul>
810    *
811    * Note, since %Wt 3.1.9, the actual form of the URL no longer
812    * affects relative URL resolution, since now %Wt includes an HTML
813    * <tt>meta base</tt> tag which points to the deployment path,
814    * regardless of the current internal path. This does break
815    * deployments behind a reverse proxy which changes paths.
816    *
817    * \if cpp
818    * For the built-in httpd, when the application is deployed
819    * at a folder (ending with '/'), only an exact matching path is
820    * routed to the application (this can be changed since Wt 3.1.9,
821    * see \ref wthttpd ), making clean URLs impossible. Returned
822    * URLs then include a <tt>"?_="</tt> encoding for the internal
823    * path:
824    *
825    * \code
826    * http://www.mydomain.com/stuff/?_=/project/z3cbc/details/
827    * \endcode
828    * \endif
829    *
830    * When the internal path is changed, an entry is added to the
831    * browser history. When the user navigates back and forward through
832    * this history (using the browser back/forward buttons), an
833    * internalPathChanged() event is emitted. You should listen to this
834    * signal to switch the application to the corresponding state. When
835    * \p emitChange is \c true, this signal is also emitted by setting
836    * the path (but only if the path is actually changed).
837    *
838    * A url that includes the internal path may be obtained using
839    * bookmarkUrl().
840    *
841    * The \p internalPath must start with a '/'. In this way, you
842    * can still use normal anchors in your HTML. Internal path changes
843    * initiated in the browser to paths that do not start with a '/'
844    * are ignored.
845    *
846    * The \p emitChange parameter determines whether calling this
847    * method causes the internalPathChanged() signal to be emitted.
848    *
849    * \sa bookmarkUrl(), internalPath(), internalPathChanged()
850    *
851    * \if cpp
852    * \note the \p path should be CharEncoding::UTF8 encoded (we may fix the API
853    *       to use WString in the future).
854    * \endif
855    */
856   void setInternalPath(const std::string& path, bool emitChange = false);
857 
858   /*! \brief Sets whether an internal path is valid by default.
859    *
860    * This configures how you treat (invalid) internal paths. If an
861    * internal path is treated valid by default then you need to call
862    * setInternalPath(false) for an invalid path. If on the other hand
863    * you treat an internal path as invalid by default, then you need
864    * to call setInternalPath(true) for a valid path.
865    *
866    * A user which opens an invalid internal path will receive a HTTP
867    * 404-Not Found response code (if sent an HTML response).
868    *
869    * The default value is \c true.
870    */
871   void setInternalPathDefaultValid(bool valid);
872 
873   /*! \brief Returns whether an internal path is valid by default.
874    *
875    * \sa setInternalPathDefaultValid()
876    */
internalPathDefaultValid()877   bool internalPathDefaultValid() const { return internalPathDefaultValid_; }
878 
879   /*! \brief Sets whether the current internal path is valid.
880    *
881    * You can use this function in response to an internal path change
882    * event (or at application startup) to indicate whether the new (or
883    * initial) internal path is valid. This has only an effect on plain
884    * HTML sessions, or on the first response in an application
885    * deployed with progressive bootstrap settings, as this generates
886    * then a 404 Not-Found response.
887    *
888    * \sa internalPathChanged(), setInternalPathDefaultValid()
889    */
890   void setInternalPathValid(bool valid);
891 
892   /*! \brief Returns whether the current internal path is valid.
893    *
894    * \sa setInternalPathValid()
895    */
internalPathValid()896   bool internalPathValid() const { return internalPathValid_; }
897 
898   /*! \brief Returns the current internal path.
899    *
900    * When the application is just created, this is equal to
901    * WEnvironment::internalPath().
902    *
903    * \sa setInternalPath(), internalPathNextPart(), internalPathMatches()
904    *
905    * \if cpp
906    * \note the \p returned path is CharEncoding::UTF8 (we may fix the API
907    *       to use WString in the future).
908    * \endif
909    */
910   std::string internalPath() const;
911 
912   /*! \brief Returns a part of the current internal path.
913    *
914    * This is a convenience method which returns the next \p folder
915    * in the internal path, after the given \p path.
916    *
917    * For example, when the current internal path is
918    * <tt>"/project/z3cbc/details"</tt>, this method returns
919    * <tt>"details"</tt> when called with <tt>"/project/z3cbc/"</tt> as
920    * \p path argument.
921    *
922    * The \p path must start with a '/', and internalPathMatches()
923    * should evaluate to \c true for the given \p path. If not,
924    * an empty string is returned and an error message is logged.
925    *
926    * \sa internalPath(), internalPathChanged()
927    *
928    * \if cpp
929    * \note the \p internal path is CharEncoding::UTF8 encoded (we may fix the API
930    *       to use WString in the future).
931    * \endif
932    */
933   std::string internalPathNextPart(const std::string& path) const;
934 
935   std::string internalSubPath(const std::string& path) const;
936 
937   /*! \brief Checks if the internal path matches a given path.
938    *
939    * Returns whether the current internalPath() starts with
940    * \p path (or is equal to \p path). You will typically use
941    * this method within a slot conneted to the internalPathChanged()
942    * signal, to check that an internal path change affects the
943    * widget. It may also be useful before changing \p path using
944    * setInternalPath() if you do not intend to remove sub paths when
945    * the current internal path already matches \p path.
946    *
947    * The \p path must start with a '/'.
948    *
949    * \sa setInternalPath(), internalPath()
950    *
951    * \if cpp
952    * \note the \p internal path is CharEncoding::UTF8 encoded (we may fix the API
953    *       to use WString in the future).
954    * \endif
955    */
956   bool internalPathMatches(const std::string& path) const;
957 
958   /*! \brief %Signal which indicates that the user changes the internal path.
959    *
960    * This signal indicates a change to the internal path, which is
961    * usually triggered by the user using the browser back/forward
962    * buttons.
963    *
964    * The argument contains the new internal path.
965    *
966    * \sa setInternalPath()
967    *
968    * \if cpp
969    * \note the \p internal path is CharEncoding::UTF8 encoded (we may fix the API
970    *       to use WString in the future).
971    * \endif
972    */
973   Signal<std::string>& internalPathChanged();
974 
975   /*! \brief %Signal which indicates that an invalid internal path is navigated.
976    */
internalPathInvalid()977   Signal<std::string>& internalPathInvalid() { return internalPathInvalid_; }
978 
979   /*! \brief Redirects the application to another location.
980    *
981    * The client will be redirected to a new location identified by \p
982    * url. Use this in conjunction with quit() if you want the
983    * application to be terminated as well.
984    *
985    * Calling %redirect() does not imply %quit() since it may be useful
986    * to switch between a non-secure and secure (SSL) transport
987    * connection.
988    */
989   void redirect(const std::string& url);
990   //!@}
991 
992   /*! \brief Returns the URL at which the resources are deployed.
993    *
994    * Returns resolveRelativeUrl(relativeResourcesUrl())
995    */
996   static std::string resourcesUrl();
997 
998   /*! \brief Returns the URL at which the resources are deployed.
999    *
1000    * \if cpp
1001    * This returns the value of the 'resources' property set in the
1002    * configuration file, and may thus be a URL relative to the deployment
1003    * path.
1004    * \endif
1005    *
1006    * \sa resolveRelativeUrl()
1007    */
1008   static std::string relativeResourcesUrl();
1009 
1010 #ifndef WT_TARGET_JAVA
1011   /*! \brief Returns the appRoot special property
1012    *
1013    * This returns the "appRoot" property, with a trailing slash added
1014    * to the end if it was not yet present.
1015    *
1016    * The property "appRoot" was introduced as a generalization of the
1017    * working directory for the location of files that do not need to
1018    * be served over http to the client, but are required by the
1019    * program to run properly. Typically, these are message resource
1020    * bundles (xml), CSV files, database files (e.g. SQLite files for
1021    * Wt::Dbo), ...
1022    *
1023    * Some connectors do not allow you to control what the current
1024    * working directory (CWD) is set to (fcgi, isapi). Instead of
1025    * referring to files assuming a sensible CWD, it is therefore
1026    * better to refer to them relative to the application root.
1027    *
1028    * The appRoot property is special in the sense that it can be set
1029    * implicitly by the connector (see the connector documentation for
1030    * more info). If it was not set by the connector, it can be set as
1031    * a normal property in the configuration file (the default
1032    * wt_config.xml describes how to set properties). If the property
1033    * is not set at all, it is assumed that the appRoot is CWD and this
1034    * function will return an empty string.
1035    *
1036    * \if cpp
1037    * Usage example:
1038    * \code
1039    * messageResourceBundle().use(appRoot() + "text");
1040    * messageResourceBundle().use(appRoot() + "charts");
1041    *
1042    * auto sqlite3_ = std::make_unique<Wt::Dbo::backend::Sqlite3>(appRoot() + "planner.db");
1043    * \endcode
1044    * \endif
1045    *
1046    * \sa WServer::appRoot(), docRoot()
1047    */
1048   static std::string appRoot();
1049 
1050   /*! \brief Returns the server document root.
1051    *
1052    * This returns the filesystem path that corresponds to the document root
1053    * of the webserver.
1054    *
1055    * \note This does not work reliably for complex webserver configurations
1056    *       (e.g. using FastCGI with Apache and rewrite rules). See also the
1057    *       <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=26052">
1058    *       discussion here</a>.
1059    *
1060    * \sa appRoot()
1061    */
1062   std::string docRoot() const;
1063 
1064   /*! \brief Sets a client-side connection monitor
1065    *
1066    * This can be used to be notified, in the browser, of changes in
1067    * connection state between the browser and the server. The passed
1068    * \p jsObject should be an object that has the following prototype:
1069    * \code
1070    *  {
1071    *     onChange: function(type, oldValue, newValue) { ... }
1072    *  }
1073    * \endcode
1074    *
1075    * The 'onChange' function will be called on an connection status change
1076    * event. The following types are defined:
1077    *  - "connectionStatus": 0 = disconnected, 1 = connected
1078    *  - "websocket": true = websocket is used, false = websocket is not used
1079    *
1080    * The current state is also stored in a 'status' object inside the
1081    * connection monitor.
1082    *
1083    * Example usage:
1084    * \code
1085    * app.setConnectionMonitor("{ onChange: function(type, ov, nv) { console.log(type, ov, nv); } }");
1086    * \endcode
1087    */
1088   void setConnectionMonitor(const std::string& jsObject);
1089 
1090 #else
1091   static std::string appRoot();
1092 #endif // WT_TARGET_JAVA
1093 
1094   /*! \brief Returns the unique identifier for the current session.
1095    *
1096    * The session id is a string that uniquely identifies the current session.
1097    * Note that the actual contents has no particular meaning and client
1098    * applications should in no way try to interpret its value.
1099    */
1100   std::string sessionId() const;
1101 
1102 #ifndef WT_TARGET_JAVA
1103   /*! \brief Changes the session id.
1104    *
1105    * To mitigate session ID fixation attacks, you should use this
1106    * method to change the session ID to a new random value after a
1107    * user has authenticated himself.
1108    *
1109    * \sa sessionId()
1110    */
1111   void changeSessionId();
1112 #endif // WT_TARGET_JAVA
1113 
session()1114   WebSession *session() const { return session_; }
1115 
1116   /** @name Manipulation outside the main event loop
1117    */
1118   //!@{
1119   /*! \brief Enables server-initiated updates.
1120    *
1121    * By default, updates to the user interface are possible only at
1122    * startup, during any event (in a slot), or at regular time points
1123    * using WTimer. This is the normal %Wt event loop.
1124    *
1125    * In some cases, one may want to modify the user interface from a
1126    * second thread, outside the event loop. While this may be worked
1127    * around by the WTimer, in some cases, there are bandwidth and
1128    * processing overheads associated which may be unnecessary, and
1129    * which create a trade-off with time resolution of the updates.
1130    *
1131    * When \p enabled is \c true, this enables "server push" (what is
1132    * called 'comet' in AJAX terminology). Widgets may then be
1133    * modified, created or deleted outside of the event loop (e.g. in
1134    * response to execution of another thread), and these changes are
1135    * propagated by calling triggerUpdate().
1136    *
1137    * \if cpp
1138    * There are two ways for safely manipulating a session's UI, with
1139    * respect to thread-safety and application life-time (the library
1140    * can decide to terminate an application if it lost connectivity
1141    * with the browser).
1142    *
1143    * <h3>WServer::post()</h3>
1144    *
1145    * The easiest and less error-prone solution is to post an event,
1146    * represented by a function/method call, to a session using
1147    * WServer::post().
1148    *
1149    * The method is non-blocking: it returns immediately, avoiding
1150    * dead-lock scenarios. The function is called from within a thread
1151    * of the server's thread pool, and not if the session has been or
1152    * is being terminated. The function is called in the context of the
1153    * targeted application session, and with exclusive access to the
1154    * session.
1155    *
1156    * <h3>WApplication::UpdateLock</h3>
1157    *
1158    * A more direct approach is to grab the application's update lock and
1159    * manipulate the application's state directly from another thread.
1160    *
1161    * At any time, the application may be deleted (e.g. because of a
1162    * time out or because the user closes the application window). You
1163    * should thus make sure you do no longer reference an application
1164    * after it has been deleted. When %Wt decides to delete an
1165    * application, it first runs WApplication::finalize() and then
1166    * invokes the destructor. While doing this, any other thread trying
1167    * to grab the update lock will unblock, but the lock will return \c
1168    * false. You should therefore always check whether the lock is
1169    * valid.
1170    *
1171    * \elseif java
1172    *
1173    * Note that you need to grab the application's update lock to avoid
1174    * concurrency problems, whenever you modify the application's state
1175    * from another thread.
1176    *
1177    * \endif
1178    *
1179    * An example of how to modify the widget tree outside the event loop
1180    * and propagate changes is:
1181    * \if cpp
1182    * \code
1183    * // You need to have a reference to the application whose state
1184    * // you are about to manipulate.
1185    * // You should prevent the application from being deleted somehow,
1186    * // before you could grab the application lock.
1187    * Wt::WApplication *app = ...;
1188    *
1189    * {
1190    *   // Grab the application lock. It is a scoped lock.
1191    *   Wt::WApplication::UpdateLock lock(app);
1192    *
1193    *   if (lock) {
1194    *     // We now have exclusive access to the application: we can safely modify the widget tree for example.
1195    *     app->root()->addWidget(std::make_unique<Wt::WText>("Something happened!"));
1196    *
1197    *     // Push the changes to the browser
1198    *     app->triggerUpdate();
1199    *   }
1200    * }
1201    * \endcode
1202    * \elseif java
1203    * \code
1204    * // You need to have a reference to the application whose state
1205    * // you are about to manipulate.
1206    * WApplication app = ...;
1207    *
1208    * // Grab the application lock
1209    * WApplication.UpdateLock lock = app.getUpdateLock();
1210    *
1211    * try {
1212    *   // We now have exclusive access to the application:
1213    *   // we can safely modify the widget tree for example.
1214    *   app.getRoot().addWidget(new WText("Something happened!"));
1215    *
1216    *   // Push the changes to the browser
1217    *   app.triggerUpdate();
1218    * } finally {
1219    *   lock.release();
1220    * }
1221    * \endcode
1222    * \endif
1223    *
1224    * \if java
1225    * This works only if your servlet container supports the Servlet 3.0
1226    * API. If you try to invoke this function on a servlet container with
1227    * no such support, an exception will be thrown.
1228    * \endif
1229    *
1230    * \note This works only if JavaScript is available on the client.
1231    *
1232    * \sa triggerUpdate()
1233    */
1234   void enableUpdates(bool enabled = true);
1235 
1236   /*! \brief Returns whether server-initiated updates are enabled.
1237    *
1238    * \sa enableUpdates()
1239    */
updatesEnabled()1240   bool updatesEnabled() const { return serverPush_ > 0; }
1241 
1242   /*! \brief Propagates server-initiated updates.
1243    *
1244    * When the lock to the application is released, changes will
1245    * propagate to the user interface. This call only has an effect
1246    * after updates have been enabled from within the normal event loop
1247    * using enableUpdates().
1248    *
1249    * This is typically used only outside of the main event loop,
1250    * e.g. from another thread or from within a method posted to an
1251    * application using WServer::post(), since changes always propagate
1252    * within the event loop at the end of the event.
1253    *
1254    * The update is not immediate, and thus changes that happen after this
1255    * call will equally be pushed to the client.
1256    *
1257    * \sa enableUpdates()
1258    */
1259   void triggerUpdate();
1260 
1261 #ifndef WT_TARGET_JAVA
1262   /*! \brief A RAII lock for manipulating and updating the
1263    *         application and its widgets outside of the event loop.
1264    *
1265    * You can use this lock to manipulate widgets outside of the event
1266    * loop. Inside the event loop (including events posted using
1267    * WServer::post()), this lock is already held by the library itself.
1268    *
1269    * The lock is recursive, so trying to take a lock, while already
1270    * holding a lock, will not block.
1271    */
1272 #else
1273   /*! \brief A synchronization lock for manipulating and updating the
1274    *         application and its widgets outside of the event loop.
1275    *
1276    * You need to take this lock only when you want to manipulate
1277    * widgets outside of the event loop. LabelOption::Inside the event loop, this
1278    * lock is already held by the library itself.
1279    *
1280    * \sa getUpdateLock()
1281    */
1282 #endif // WT_TARGET_JAVA
1283   class WT_API UpdateLock
1284 #ifdef WT_TARGET_JAVA
1285     : public AutoCloseable
1286 #endif // WT_TARGET_JAVA
1287   {
1288   public:
1289 #ifndef WT_TARGET_JAVA
1290     /*! \brief Creates and locks the given application.
1291      *
1292      * The lock guarantees exclusive access to modify the
1293      * application's state.
1294      *
1295      * You should also consider WServer::post() for lock-free
1296      * communication between different application sessions.
1297      *
1298      * As soon as the library decides to destroy the application, the
1299      * lock will no longer succeed in taking the application lock. You
1300      * can need to detect this by checking that after the lock is taken,
1301      * the lock is taken:
1302      * \code
1303      * WApplication::UpdateLock lock(app);
1304      * if (lock) {
1305      *   // exclusive access to app state
1306      * }
1307      * \endcode
1308      */
1309     UpdateLock(WApplication *app);
1310 
1311     /*! \brief Tests whether the update lock was succesfully taken.
1312      *
1313      * This may return \c false when the library has already decided
1314      * to destroy the session (but before your application
1315      * finalizer/destructor has run to notify helper threads that the
1316      * application is destroyed).
1317      */
1318     explicit operator bool() const { return ok_; }
1319 
1320     /*! \brief Releases the lock.
1321      */
1322     ~UpdateLock();
1323 
1324 #else
1325     /*! \brief Releases the lock.
1326      */
1327     void release();
1328 #endif
1329 
1330 #ifdef WT_TARGET_JAVA
1331     /*! \brief Releases the lock.
1332      *
1333      * Calls release()
1334      *
1335      * Implemented in order to support the AutoCloseable interface.
1336      */
1337     virtual void close();
1338 #endif // WT_TARGET_JAVA
1339 
1340   private:
1341 #ifdef WT_TARGET_JAVA
1342     UpdateLock(WApplication *app);
1343     bool createdHandler_;
1344 #endif // WT_TARGET_JAVA
1345 
1346 #ifndef WT_TARGET_JAVA
1347     mutable std::unique_ptr<UpdateLockImpl> impl_;
1348     bool ok_;
1349 #endif // !WT_TARGET_JAVA
1350 
1351     friend class WApplication;
1352   };
1353 
1354 #ifdef WT_TARGET_JAVA
1355   /*! \brief Grabs and returns the lock for manipulating widgets outside
1356    *         the event loop.
1357    *
1358    * You need to keep this lock in scope while manipulating widgets
1359    * outside of the event loop. In normal cases, inside the %Wt event
1360    * loop, you do not need to care about it.
1361    *
1362    * \sa enableUpdates(), triggerUpdate()
1363    */
1364   UpdateLock getUpdateLock();
1365 #endif // WT_TARGET_JAVA
1366 
1367   /*! \brief Attach an auxiliary thread to this application.
1368    *
1369    * In a multi-threaded environment, WApplication::instance() uses
1370    * thread-local data to retrieve the application object that
1371    * corresponds to the session currently being handled by the
1372    * thread. This is set automatically by the library whenever an
1373    * event is delivered to the application, or when you use the
1374    * UpdateLock to modify the application from an auxiliary thread
1375    * outside the normal event loop.
1376    *
1377    * When you want to manipulate the widget tree inside the main event
1378    * loop, but from within an auxiliary thread, then you cannot use
1379    * the UpdateLock since this will create an immediate dead
1380    * lock. Instead, you may attach the auxiliary thread to the
1381    * application, by calling this method from the auxiliary thread,
1382    * and in this way you can modify the application from within that
1383    * thread without needing the update lock.
1384    *
1385    * Calling attachThread() with \p attach = \c false, detaches the
1386    * current thread.
1387    */
1388   void attachThread(bool attach = true);
1389   //!@}
1390 
1391   /** @name Invoking JavaScript or including scripts
1392    */
1393   //!@{
1394   /*! \brief Executes some JavaScript code.
1395    *
1396    * This method may be used to call some custom \p javaScript code as
1397    * part of an event response.
1398    *
1399    * This function does not wait until the JavaScript is run, but
1400    * returns immediately. The JavaScript will be run after the normal
1401    * event handling, unless \p afterLoaded is set to \c false.
1402    *
1403    * In most situations, it's more robust to use
1404    * WWidget::doJavaScript() however.
1405    *
1406    * \sa WWidget::doJavaScript(), declareJavaScriptFunction()
1407    */
1408   void doJavaScript(const std::string& javascript, bool afterLoaded = true);
1409 
1410   /*! \brief Adds JavaScript statements that should be run continuously.
1411    *
1412    * This is an internal method.
1413    *
1414    * It is used by for example layout managers to adjust the layout
1415    * whenever the DOM tree is manipulated.
1416    *
1417    * \sa doJavaScript()
1418    */
1419   void addAutoJavaScript(const std::string& javascript);
1420 
1421   /*! \brief Declares an application-wide JavaScript function.
1422    *
1423    * The function is stored in WApplication::javaScriptClass().
1424    *
1425    * The next code snippet declares and invokes function foo:
1426    * \if cpp
1427    * \code
1428    * app->declareJavaScriptFunction("foo",
1429    *                                "function(id) { ... }");
1430    * ...
1431    * std::string id("myId");
1432    * app->doJavaScript(app->javaScriptClass() + ".foo('" + id + "');");
1433    * \endcode
1434    * \endif
1435    */
1436   void declareJavaScriptFunction(const std::string& name,
1437 				 const std::string& function);
1438 
1439   /*! \brief Loads a JavaScript library.
1440    *
1441    * Loads a JavaScript library located at the URL \p url. %Wt keeps
1442    * track of libraries (with the same URL) that already have been
1443    * loaded, and will load a library only once. In addition, you may
1444    * provide a \p symbol which if already defined will also indicate
1445    * that the library was already loaded (possibly outside of %Wt when
1446    * in EntryPointType::WidgetSet mode).
1447    *
1448    * This method returns \c true only when the library is loaded
1449    * for the first time.
1450    *
1451    * JavaScript libraries may be loaded at any point in time. Any
1452    * JavaScript code is deferred until the library is loaded, except
1453    * for JavaScript that was defined to load before, passing \c false
1454    * as second parameter to doJavaScript().
1455    *
1456    * Although %Wt includes an off-the-shelf JQuery version (which can
1457    * also be used by your own JavaScript code), you can override the
1458    * one used by %Wt and load another JQuery version instead, but this
1459    * needs to be done using requireJQuery().
1460    */
1461   bool require(const std::string& url,
1462 	       const std::string& symbol = std::string());
1463 
1464   /*! \brief Loads a custom JQuery library.
1465    *
1466    * %Wt ships with a rather old version of JQuery (1.4.1) which is
1467    * sufficient for its needs and is many times smaller than more recent
1468    * JQuery releases (about 50% smaller).
1469    *
1470    * Using this function, you can replace Wt's JQuery version with another
1471    * version of JQuery.
1472    *
1473    * \code
1474    * requireJQuery("jquery/jquery-1.7.2.min.js");
1475    * \endcode
1476    */
1477   bool requireJQuery(const std::string& url);
1478 
1479   /*! \brief Returns whether a custom JQuery library is used.
1480    *
1481    * \sa requireJQuery(const std::string& url)
1482    */
customJQuery()1483   bool customJQuery() const { return customJQuery_; }
1484 
1485   /*! \brief Sets the name of the application JavaScript class.
1486    *
1487    * This should be called right after construction of the application, and
1488    * changing the JavaScript class is only supported for EntryPointType::WidgetSet mode
1489    * applications. The \p className should be a valid JavaScript identifier, and
1490    * should also be unique in a single page.
1491    */
1492   void setJavaScriptClass(const std::string& className);
1493 
1494   /*! \brief Returns the name of the application JavaScript class.
1495    *
1496    * This JavaScript class encapsulates all JavaScript methods
1497    * specific to this application instance. The method is foreseen to
1498    * allow multiple applications to run simultaneously on the same
1499    * page in Wt::WidgtSet mode, without interfering.
1500    */
javaScriptClass()1501   std::string javaScriptClass() { return javaScriptClass_; }
1502   //!@}
1503 
1504   /*! \brief Processes UI events.
1505    *
1506    * You may call this method during a long operation to:
1507    *   - propagate widget changes to the client.
1508    *   - process UI events.
1509    *
1510    * This method starts a recursive event loop, blocking the current
1511    * thread, and resumes when all pending user interface events have been
1512    * processed.
1513    *
1514    * Because a thread is blocked, this may affect your application
1515    * scalability.
1516    */
1517   void processEvents();
1518 
1519   /*! \brief Blocks the thread, waiting for an UI event.
1520    *
1521    * This function is used by functions like WDialog::exec() or
1522    * WPopupMenu::exec(), to block the current thread waiting for a new
1523    * event.
1524    *
1525    * This requires that at least one additional thread is available to
1526    * process incoming requests, and is not scalable when working with
1527    * a fixed size thread pools.
1528    */
1529   virtual void waitForEvent();
1530 
1531 #ifndef WT_TARGET_JAVA
1532   /*! \brief Reads a configuration property.
1533    *
1534    * Tries to read a configured value for the property
1535    * \p name. The method returns whether a value is defined for
1536    * the property, and sets it to \p value.
1537    *
1538    * \sa WServer::readConfigurationProperty()
1539    */
1540   static bool readConfigurationProperty(const std::string& name,
1541 					std::string& value);
1542 #else
1543   /*! \brief Reads a configuration property.
1544    *
1545    * Tries to read a configured value for the property
1546    * \p name. If no value was configured, the default \p value
1547    * is returned.
1548    */
1549   static std::string *readConfigurationProperty(const std::string& name,
1550 						const std::string& value);
1551 #endif // WT_TARGET_JAVA
1552 
1553   /*
1554    * The DOM root object. This contains not only the application root but
1555    * also other invisible objects (timers, dialog covers, ...).
1556    */
1557   WWebWidget *domRoot() const;
1558 
1559   /*
1560    * A phony DOM root object, used to logically contain all widgets bound
1561    * in widgetset mode.
1562    */
domRoot2()1563   WContainerWidget *domRoot2() const { return domRoot2_.get(); }
1564 
1565   /*
1566    * Encode an object to a string, to make it referencable from JavaScript.
1567    * Currently only used to encode the drag object in drag & drop.
1568    *
1569    * FIXME: provide a way to remove the encoding!
1570    *
1571    * \see decodeObject()
1572    */
1573   std::string encodeObject(WObject *object);
1574 
1575   /*
1576    * Decode an object.
1577    *
1578    * \see encodeObject()
1579    */
1580   WObject *decodeObject(const std::string& objectId) const;
1581 
1582 #ifndef WT_TARGET_JAVA
1583   /*! \brief Initializes the application, post-construction.
1584    *
1585    * This method is invoked by the %Wt library after construction of a
1586    * new application. You may reimplement this method to do additional
1587    * initialization that is not possible from the constructor
1588    * (e.g. which uses virtual methods).
1589    */
1590   virtual void initialize();
1591 
1592   /*! \brief Finalizes the application, pre-destruction.
1593    *
1594    * This method is invoked by the %Wt library before destruction of a
1595    * new application. You may reimplement this method to do additional
1596    * finalization that is not possible from the destructor (e.g. which
1597    * uses virtual methods).
1598    */
1599   virtual void finalize();
1600 #else
1601   /*! \brief Destroys the application session.
1602    *
1603    * The application is destroyed when the session is invalidated. You
1604    * should put here any logic which is needed to cleanup the
1605    * application session.
1606    *
1607    * The default implementation does nothing.
1608    */
1609   virtual void destroy();
1610 #endif //WT_TARGET_JAVA
1611 
1612   /*! \brief Changes the threshold for two-phase rendering.
1613    *
1614    * This changes the threshold for the \p size of a JavaScript
1615    * response (in bytes) to render invisible changes in one go. If the
1616    * bandwidth for rendering the invisible changes exceed the
1617    * threshold, they will be fetched in a second communication, after
1618    * the visible changes have been rendered.
1619    *
1620    * The value is a trade-off: setting it smaller will always use
1621    * two-phase rendering, increasing the total render time but
1622    * reducing the latency for the visible changes. Setting it too
1623    * large will increase the latency to render the visible changes,
1624    * since first also all invisible changes need to be computed and
1625    * received in the browser.
1626    *
1627    * \if cpp
1628    * The initial value is read from the configuration file, see \ref
1629    * config_general.
1630    * \endif
1631    */
1632   void setTwoPhaseRenderingThreshold(int size);
1633 
1634   /*! \brief Sets a new cookie.
1635    *
1636    * Use cookies to transfer information across different sessions
1637    * (e.g. a user name). In a subsequent session you will be able to
1638    * read this cookie using WEnvironment::getCookie(). You cannot use
1639    * a cookie to store information in the current session.
1640    *
1641    * The name must be a valid cookie name (of type 'token': no special
1642    * characters or separators, see RFC2616 page 16). The value may be
1643    * anything. Specify the maximum age (in seconds) after which the
1644    * client must discard the cookie. To delete a cookie, use a value of '0'.
1645    *
1646    * By default the cookie only applies to the application deployment
1647    * path (WEnvironment::deploymentPath()) in the current domain. To
1648    * set a proper value for domain, see also RFC2109.
1649    *
1650    * \if cpp
1651    * \note %Wt provides session tracking automatically, and may be configured
1652    *       to use a cookie for this. You only need to use cookies yourself
1653    *       if you want to remember some information (like a logged in identity)
1654    *       <i>across sessions</i>.
1655    * \endif
1656    *
1657    * \sa WEnvironment::supportsCookies(), WEnvironment::getCookie()
1658    */
1659   void setCookie(const std::string& name, const std::string& value,
1660 		 int maxAge, const std::string& domain = "",
1661 		 const std::string& path = "", bool secure = false);
1662 
1663 #ifndef WT_TARGET_JAVA
1664   void setCookie(const std::string& name, const std::string& value,
1665 		 const WDateTime& expires, const std::string& domain = "",
1666 		 const std::string& path = "", bool secure = false);
1667 #endif // WT_TARGET_JAVA
1668 
1669   /*! \brief Removes a cookie.
1670    *
1671    * \sa setCookie()
1672    */
1673   void removeCookie(const std::string& name, const std::string& domain = "",
1674 		    const std::string& path = "");
1675 
1676   /*! \brief Adds an HTML meta link.
1677    *
1678    * When a link was previously set for the same \p href, its contents
1679    * are replaced.
1680    * When an empty string is used for the arguments \p media, \p hreflang,
1681    * \p type or \p sizes, they will be ignored.
1682    *
1683    * \sa removeMetaLink()
1684    */
1685   void addMetaLink(const std::string &href,
1686 		   const std::string &rel,
1687 		   const std::string &media,
1688 		   const std::string &hreflang,
1689 		   const std::string &type,
1690 		   const std::string &sizes,
1691 		   bool disabled);
1692 
1693   /*! \brief Removes the HTML meta link.
1694    *
1695    * \sa addMetaLink()
1696    */
1697   void removeMetaLink(const std::string &href);
1698 
1699   /*! \brief Adds a "name" HTML meta header.
1700    *
1701    * \sa addMetaHeader(MetaHeaderType, const std::string&, const WString&, const std::string&)
1702    */
1703   void addMetaHeader(const std::string& name, const WString& content,
1704 		     const std::string& lang = "");
1705 
1706   /*! \brief Adds an HTML meta header.
1707    *
1708    * This method sets either a "name" meta headers, which configures a
1709    * document property, or a "http-equiv" meta headers, which defines
1710    * a HTTP headers (but these latter headers are being deprecated).
1711    *
1712    * A meta header can however only be added in the following situations:
1713    *
1714    * - when a plain HTML session is used (including when the user agent is a
1715    *   bot), you can add meta headers at any time.
1716    * - or, when \ref progressive_bootstrap "progressive bootstrap" is
1717    *   used, you can set meta headers for any type of session, from
1718    *   within the application constructor (which corresponds to the
1719    *   initial request).
1720    * - but never for a Wt::EntryPointType::WidgetSet mode application since then the
1721    *   application is hosted within a foreign HTML page.
1722    *
1723    * These situations coincide with WEnvironment::ajax() returning \c
1724    * false (see environment()). The reason that it other cases the
1725    * HTML page has already been rendered, and will not be rerendered
1726    * since all updates are done dynamically.
1727    *
1728    * As an alternative, you can use the &lt;meta-headers&gt;
1729    * configuration property in the configuration file, which will be
1730    * applied in all circumstances.
1731    *
1732    * \sa removeMetaHeader()
1733    */
1734   void addMetaHeader(MetaHeaderType type, const std::string& name,
1735 		     const WString& content, const std::string& lang = "");
1736 
1737   /*! \brief Returns a meta header value.
1738    *
1739    * \sa addMetaHeader()
1740    */
1741   WString metaHeader(MetaHeaderType type, const std::string& name) const;
1742 
1743   /*! \brief Removes one or all meta headers.
1744    *
1745    * Removes the meta header with given type and name (if it is present).
1746    * If name is empty, all meta headers of the given type are removed.
1747    *
1748    * \sa addMetaHeader()
1749    */
1750   void removeMetaHeader(MetaHeaderType type, const std::string& name = "");
1751 
1752 #ifndef WT_TARGET_JAVA
1753   /*! \brief Adds an entry to the application log.
1754    *
1755    * Starts a new log entry of the given \p type in the %Wt
1756    * application log file. This method returns a stream-like object to
1757    * which the message may be streamed.
1758    *
1759    * \if cpp
1760    * A typical usage would be:
1761    * \code
1762    *  wApp->log("notice") << "User " << userName << " logged in successfully.";
1763    * \endcode
1764    *
1765    * This would create a log entry that looks like:
1766    * \verbatim
1767 [2008-Jul-13 14:01:17.817348] 16879 [/app.wt Z2gCmSxIGjLHD73L] [notice] "User bart logged in successfully."
1768    * \endverbatim
1769    * \endif
1770    *
1771    * \if cpp
1772    * \sa \ref config_general
1773    * \endif
1774    */
1775   WLogEntry log(const std::string& type) const;
1776 #endif // WT_TARGET_JAVA
1777 
1778   /*! \brief Sets the loading indicator.
1779    *
1780    * The loading indicator is shown to indicate that a response from
1781    * the server is pending or JavaScript is being evaluated.
1782    *
1783    * The default loading indicator is a WDefaultLoadingIndicator.
1784    */
1785   void setLoadingIndicator(std::unique_ptr<WLoadingIndicator> indicator);
1786 
1787   /*! \brief Returns the loading indicator.
1788    *
1789    * \sa setLoadingIndicator()
1790    */
loadingIndicator()1791   WLoadingIndicator *loadingIndicator() const { return loadingIndicator_; }
1792 
1793   /*
1794    * A url to a resource that provides a one pixel gif. This is sometimes
1795    * useful for CSS hackery to make IE behave.
1796    */
1797   std::string onePixelGifUrl();
1798 
1799   /*
1800    * The doctype used to deliver the application.
1801    */
1802   std::string docType() const;
1803 
1804   /*! \brief Quits the application.
1805    *
1806    * This quits the application with a default restart message resolved
1807    * as WString::tr("Wt.QuittedMessage").
1808    *
1809    * \sa quit(const WString&)
1810    */
1811   void quit();
1812 
1813   /*! \brief Quits the application.
1814    *
1815    * The method returns immediately, but has as effect that the
1816    * application will be terminated after the current event is
1817    * completed.
1818    *
1819    * The current widget tree (including any modifications still
1820    * pending and applied during the current event handling) will still
1821    * be rendered, after which the application is terminated.
1822    *
1823    * If the restart message is not empty, then the user will be
1824    * offered to restart the application (using the provided message)
1825    * when further interacting with the application.
1826    *
1827    * \sa redirect()
1828    */
1829   void quit(const WString& restartMessage);
1830 
1831   /*! \brief Returns whether the application has quit.
1832    *
1833    * \sa quit()
1834    */
hasQuit()1835   bool hasQuit() const { return quitted_; }
1836 
1837   /*! \brief Returns the current maximum size of a request to the
1838    *         application.
1839    *
1840    * The returned value is the maximum request size in bytes.
1841    *
1842    * \if cpp
1843    * The maximum request size is configured in the configuration file,
1844    * see \ref config_general.
1845    * \endif
1846    *
1847    * \sa requestTooLarge()
1848    */
1849   ::int64_t maximumRequestSize() const;
1850 
1851   /*! \brief %Signal which indicates that too a large request was received.
1852    *
1853    * The integer parameter is the request size that was received in bytes.
1854    */
requestTooLarge()1855   Signal< ::int64_t>& requestTooLarge() { return requestTooLarge_; }
1856 
1857   /** @name Global keyboard and mouse events
1858    */
1859   //!@{
1860   /*! \brief Event signal emitted when a keyboard key is pushed down.
1861    *
1862    * The application receives key events when no widget currently
1863    * has focus. Otherwise, key events are handled by the widget in focus,
1864    * and its ancestors.
1865    *
1866    * \sa See WInteractWidget::keyWentDown()
1867    */
1868   EventSignal<WKeyEvent>& globalKeyWentDown();
1869 
1870   /*! \brief Event signal emitted when a "character" was entered.
1871    *
1872    * The application receives key events when no widget currently
1873    * has focus. Otherwise, key events are handled by the widget in focus,
1874    * and its ancestors.
1875    *
1876    * \sa See WInteractWidget::keyPressed()
1877    */
1878   EventSignal<WKeyEvent>& globalKeyPressed();
1879 
1880   /*! \brief Event signal emitted when a keyboard key is released.
1881    *
1882    * The application receives key events when no widget currently
1883    * has focus. Otherwise, key events are handled by the widget in focus,
1884    * and its ancestors.
1885    *
1886    * \sa See WInteractWidget::keyWentUp()
1887    */
1888   EventSignal<WKeyEvent>& globalKeyWentUp();
1889 
1890   /*! \brief Event signal emitted when enter was pressed.
1891    *
1892    * The application receives key events when no widget currently
1893    * has focus. Otherwise, key events are handled by the widget in focus,
1894    * and its ancestors.
1895    *
1896    * \sa See WInteractWidget::enterPressed()
1897    */
1898   EventSignal<>& globalEnterPressed();
1899 
1900   /*! \brief Event signal emitted when escape was pressed.
1901    *
1902    * The application receives key events when no widget currently
1903    * has focus. Otherwise, key events are handled by the widget in focus,
1904    * and its ancestors.
1905    *
1906    * \sa See WInteractWidget::escapePressed()
1907    */
1908   EventSignal<>& globalEscapePressed();
1909   //!@}
1910 
1911   /*
1912    * Returns whether debug was configured.
1913    * (should be public API ?)
1914    */
1915   bool debug() const;
1916 
1917   /*
1918    * Methods for client-side focus
1919    */
1920   void setFocus(const std::string& id, int selectionStart, int selectionEnd);
1921 
1922 #ifdef WT_DEBUG_JS
1923   void loadJavaScript(const char *jsFile);
1924 #else
1925 #ifdef WT_TARGET_JAVA
1926   /*! \brief Loads an internal JavaScript file.
1927    *
1928    * This is an internal function and should not be called directly.
1929    *
1930    * \sa require(), doJavaScript()
1931    */
1932 #endif
1933   void loadJavaScript(const char *jsFile, const WJavaScriptPreamble& preamble);
1934 #endif
1935 
1936   bool javaScriptLoaded(const char *jsFile) const;
1937 
1938   /*! \brief Sets the message for the user to confirm closing of the
1939    *         application window/tab.
1940    *
1941    * If the message is empty, then the user may navigate away from the page
1942    * without confirmation.
1943    *
1944    * Otherwise the user will be prompted with a browser-specific
1945    * dialog asking him to confirm leaving the page. This \p message is
1946    * added to the page.
1947    *
1948    * \sa unload()
1949    */
1950   void setConfirmCloseMessage(const WString& message);
1951 
1952   void enableInternalPaths();
1953 
1954   // should we move this into an InternalPaths utility class / namespace ?
1955 #ifdef WT_TARGET_JAVA
1956   /*! \brief Utility function to check if one path falls under another path.
1957    *
1958    * This returns whether the \p query path matches the given \p path,
1959    * meaning that it is equal to that path or it specifies a more
1960    * specific sub path of that path.
1961    */
1962 #endif // WT_TARGET_JAVA
1963   static bool pathMatches(const std::string& path, const std::string& query);
1964 
1965 #ifndef WT_TARGET_JAVA
1966   /*! \brief Defers rendering of the current event response.
1967    *
1968    * This method defers the rendering of the current event response
1969    * until resumeRendering() is called. This may be used if you do not
1970    * want to actively block the current thread while waiting for an
1971    * event which is needed to complete the current event
1972    * response. Note that this effectively freezes the user interface,
1973    * and thus you should only do this if you know that the event you
1974    * are waiting for will arrive shortly, or there is really nothing more
1975    * useful for the user to do than wait for the action to complete.
1976    *
1977    * A typical use case is in conjunction with the Http::Client, to
1978    * defer the rendering while waiting for the Http::Client to
1979    * complete.
1980    *
1981    * The function may be called multiple times and the number of deferral
1982    * requests is counted. The current response is deferred until as
1983    * many calls to resumeRendering() have been performed.
1984    *
1985    * \sa resumeRendering()
1986    */
1987   void deferRendering();
1988 
1989   /*! \brief Resumes rendering of a deferred event response.
1990    *
1991    * \sa deferRendering()
1992    */
1993   void resumeRendering();
1994 #endif
1995 
1996   /*! \brief Encodes an untrusted URL to prevent referer leaks.
1997    *
1998    * This encodes an URL so that in case the session ID is present
1999    * in the current URL, this session ID does not leak to the refenced
2000    * URL.
2001    *
2002    * %Wt will safely handle URLs in the API (in WImage and WAnchor) but
2003    * you may want to use this function to encode URLs which you use in
2004    * WTemplate texts.
2005    */
2006   std::string encodeUntrustedUrl(const std::string& url) const;
2007 
2008   /*! \brief Pushes a (modal) widget onto the expose stack.
2009    *
2010    * This defines a new context of widgets that are currently visible.
2011    */
2012   void pushExposedConstraint(WWidget *w);
2013   void popExposedConstraint(WWidget *w);
2014 
2015   void addGlobalWidget(WWidget *w); // from within constructor
2016   void removeGlobalWidget(WWidget *w); // from within destructor
2017 
2018   /*! \brief Suspend the application.
2019    *
2020    * Keep this application alive for a certain amount of time, while
2021    * allowing the user to navigate away from the page. This can be
2022    * useful when using 3rd party login or payment providers.
2023    * You can later return to the application with a url that includes
2024    * the session ID as query parameter (see WApplication::url()).
2025    */
2026   void suspend(std::chrono::seconds duration);
2027 
2028   /*! \brief Signal that is emitted when the application is no longer suspended.
2029    *
2030    * This can be used to apply changes which were difficult to do as a result of
2031    * the application not being rendered.
2032    * Eg. Wt uses this to trigger a login as a result of single sign-on.
2033    */
unsuspended()2034   Signal<>& unsuspended() { return unsuspended_; }
2035 
2036 protected:
2037   /*! \brief Notifies an event to the application.
2038    *
2039    * This method is called by the event loop for propagating an event
2040    * to the application. It provides a single point of entry for
2041    * events to the application, besides the application constructor.
2042    *
2043    * You may want to reimplement this method for two reasons:
2044    *
2045    * - for having a single point for exception handling: while you may want
2046    *   to catch recoverable exceptions in a more appropriate place, general
2047    *   (usually fatal) exceptions may be caught here. You will probably
2048    *   want to catch the same exceptions in the application constructor
2049    *   in the same way.
2050    * - you want to manage resource usage during requests. For example, at
2051    *   the end of request handling, you want to return a database session
2052    *   back to the pool. Since %notify() is also used for rendering right after
2053    *   the application is created, this will also clean up resources after
2054    *   application construction.
2055    *
2056    * In either case, you will need to call the base class
2057    * implementation of %notify(), as otherwise no events will be
2058    * delivered to your application.
2059    *
2060    * The following shows a generic template for reimplementhing this
2061    * method for both managing request resources and generic exception
2062    * handling.
2063    *
2064    * \if cpp
2065    * \code
2066    * MyApplication::notify(const WEvent& event)
2067    * {
2068    *    // Grab resources for during request handling
2069    *    try {
2070    *      WApplication::notify(event);
2071    *    } catch (MyException& exception) {
2072    *      // handle this exception in a central place
2073    *    }
2074    *    // Free resources used during request handling
2075    * }
2076    * \endcode
2077    * \elseif java
2078    * \code
2079    * void notify(WEvent event) {
2080    *     // Grab resources for during request handling
2081    *     try {
2082    *       super.notify(event);
2083    *     }  catch (MyException exception) {
2084    *       // handle this exception in a central place
2085    *     }
2086    *     // Free resources used during request handling
2087    * }
2088    * \endcode
2089    * \endif
2090    *
2091    * Note that any uncaught exception throw during event handling
2092    * terminates the session.
2093    */
2094   virtual void notify(const WEvent& e);
2095 
2096   /*! \brief Returns whether a widget is exposed in the interface.
2097    *
2098    * The default implementation simply returns \c true, unless a modal
2099    * dialog is active, in which case it returns \c true only for widgets
2100    * that are inside the dialog.
2101    *
2102    * You may want to reimplement this method if you wish to disallow
2103    * events from certain widgets even when they are inserted in the
2104    * widget hierachy.
2105    */
2106   virtual bool isExposed(WWidget *w) const;
2107 
2108   /*! \brief Progresses to an Ajax-enabled user interface.
2109    *
2110    * This method is called when the progressive bootstrap method is used, and
2111    * support for AJAX has been detected. The default behavior will propagate
2112    * the WWidget::enableAjax() method through the widget hierarchy.
2113    *
2114    * You may want to reimplement this method if you want to make
2115    * changes to the user-interface when AJAX is enabled. You should
2116    * always call the base implementation.
2117    *
2118    * \sa WWidget::enableAjax()
2119    */
2120   virtual void enableAjax();
2121 
2122   /*! \brief Handles a browser unload event.
2123    *
2124    * The browser unloads the application when the user navigates away or
2125    * when he closes the window or tab.
2126    *
2127    * When <tt>reload-is-new-session</tt> is set to \c true, then the
2128    * default implementation of this method terminates this session by
2129    * calling quit(), otherwise the session is scheduled to expire within
2130    * seconds (since it may be a refresh).
2131    *
2132    * You may want to reimplement this if you want to keep the
2133    * application running until it times out (as was the behaviour
2134    * before %Wt 3.1.6).
2135    */
2136   virtual void unload();
2137 
2138   /*! \brief Idle timeout handler
2139    *
2140    * \if cpp
2141    * If <tt>idle-timeout</tt> is set in the configuration, this method is called when
2142    * the user seems idle for the number of seconds set in <tt>idle-timeout</tt>.
2143    * \elseif java
2144    * If idle timeout is set in the configuration
2145    * ({@link Configuration#setIdleTimeout(int)}), this
2146    * method is called when the user seems idle for the number of seconds set as the
2147    * idle timeout.
2148    * \endif
2149    *
2150    * This feature can be useful in security sensitive applications
2151    * to prevent unauthorized users from taking over the session
2152    * of a user that has moved away from or left behind
2153    * the device from which they are accessing the %Wt application.
2154    *
2155    * The default implementation logs that a timeout has occurred,
2156    * and calls quit().
2157    *
2158    * This method can be overridden to specify different timeout behaviour,
2159    * e.g. to show a dialog that a user's session has expired, or that
2160    * the session is about to expire.
2161    *
2162    * \if cpp
2163    *
2164    * Example for an expiration dialog:
2165    *
2166    * \code
2167    * class MyApplication : public Wt::WApplication {
2168    * public:
2169    *   MyApplication(Wt::WEnvironment &env)
2170    *    : WApplication(env)
2171    *   { }
2172    *
2173    * protected:
2174    *   virtual void idleTimeout() override
2175    *   {
2176    *     if (idleTimeoutDialog_)
2177    *       return; // Prevent multiple dialogs
2178    *
2179    *     idleTimeoutDialog_ = addChild(std::make_unique<Wt::WDialog>("Idle timeout"));
2180    *     idleTimeoutDialog_->contents()->addNew<Wt::WText>("This session will automatically quit in 1 minute, "
2181    *                                                       "press 'abort' to continue using the application");
2182    *     auto btn = idleTimeoutDialog_->footer()->addNew<Wt::WPushButton>("abort");
2183    *     btn->clicked().connect([this]{
2184    *       removeChild(idleTimeoutDialog_.get());
2185    *     });
2186    *     auto timer = idleTimeoutDialog_->addChild(std::make_unique<Wt::WTimer>());
2187    *     timer->setInterval(std::chrono::seconds{60});
2188    *     timer->setSingleShot(true);
2189    *     timer->timeout().connect([this]{
2190    *       quit();
2191    *     });
2192    *     timer->start();
2193    *     idleTimeoutDialog_->show();
2194    *   }
2195    *
2196    * private:
2197    *   Wt::Core::observing_ptr<Wt::WDialog> idleTimeoutDialog_;
2198    * };
2199    * \endcode
2200    *
2201    * \endif
2202    *
2203    * \note The events currently counted as user activity are:
2204    *  - mousedown
2205    *  - mouseup
2206    *  - wheel
2207    *  - keydown
2208    *  - keyup
2209    *  - touchstart
2210    *  - touchend
2211    *  - pointerdown
2212    *  - pointerup
2213    */
2214   virtual void idleTimeout();
2215 
2216   /**
2217    * @brief handleJavaScriptError print javaScript errors to log file.
2218    * You may want to overwrite it to render error page for example.
2219    *
2220    * @param errorText the error will usually be in json format.
2221    */
2222   virtual void handleJavaScriptError(const std::string& errorText);
2223 private:
2224   Signal< ::int64_t > requestTooLarge_;
2225   Signal<> unsuspended_;
2226 
2227   struct ScriptLibrary {
2228     ScriptLibrary(const std::string& uri, const std::string& symbol);
2229 
2230     std::string uri, symbol, beforeLoadJS;
2231     bool operator< (const ScriptLibrary& other) const;
2232     bool operator== (const ScriptLibrary& other) const;
2233   };
2234 
2235   struct MetaLink {
2236     MetaLink(const std::string &href,
2237 	     const std::string &rel,
2238 	     const std::string &media,
2239 	     const std::string &hreflang,
2240 	     const std::string &type,
2241 	     const std::string &sizes,
2242 	     bool disabled);
2243 
2244     std::string href;
2245     std::string rel;
2246     std::string media;
2247     std::string hreflang;
2248     std::string type;
2249     std::string sizes;
2250     bool disabled;
2251   };
2252 
2253 #ifndef WT_TARGET_JAVA
2254   typedef std::map<std::string, EventSignalBase *> SignalMap;
2255   typedef std::map<std::string, WResource*> ResourceMap;
2256 #else
2257   typedef std::weak_value_map<std::string, EventSignalBase *> SignalMap;
2258   typedef std::weak_value_map<std::string, WResource*> ResourceMap;
2259 #endif
2260   typedef std::map<std::string, WObject *> ObjectMap;
2261 
2262   /*
2263    * Basic application stuff
2264    */
2265   WebSession *session_; // session owning this application
2266 #ifndef WT_CNOR
2267   std::weak_ptr<WebSession> weakSession_; // used to sense destruction
2268 #endif // WT_CNOR
2269   WString title_, closeMessage_;
2270   bool titleChanged_, closeMessageChanged_, localeChanged_;
2271   std::unique_ptr<WContainerWidget> domRoot_; // main DOM root
2272   WContainerWidget *widgetRoot_;  // widgets in main DOM root
2273   WContainerWidget *timerRoot_;   // timers in main DOM root
2274   std::unique_ptr<WContainerWidget> domRoot2_; // other virtual root
2275   WCssStyleSheet styleSheet_;  // internal stylesheet
2276   std::unique_ptr<WCombinedLocalizedStrings> localizedStrings_;
2277   WLocale locale_;
2278   std::string renderedInternalPath_, newInternalPath_;
2279   Signal<std::string> internalPathChanged_, internalPathInvalid_;
2280   bool internalPathIsChanged_, internalPathDefaultValid_, internalPathValid_;
2281   int serverPush_;
2282   bool serverPushChanged_;
2283 #ifndef WT_TARGET_JAVA
2284   boost::pool<boost::default_user_allocator_new_delete> *eventSignalPool_;
2285 #endif // WT_TARGET_JAVA
2286   std::string javaScriptClass_;
2287   bool quitted_;
2288   WString quittedMessage_;
2289   std::unique_ptr<WResource> onePixelGifR_;
2290   bool internalPathsEnabled_;
2291   WWidget *exposedOnly_;
2292   WLoadingIndicator *loadingIndicator_;
2293   std::string htmlClass_, bodyClass_;
2294   bool bodyHtmlClassChanged_, enableAjax_;
2295 #ifndef WT_TARGET_JAVA
2296   bool initialized_;
2297 #endif // WT_TARGET_JAVA
2298   std::string focusId_;
2299   int selectionStart_, selectionEnd_;
2300   LayoutDirection layoutDirection_;
2301 
2302   std::vector<ScriptLibrary> scriptLibraries_;
2303   int scriptLibrariesAdded_;
2304 
2305   std::shared_ptr<WTheme> theme_;
2306   std::vector<WLinkedCssStyleSheet> styleSheets_;
2307   std::vector<WLinkedCssStyleSheet> styleSheetsToRemove_;
2308 
2309   int styleSheetsAdded_;
2310 
2311   std::vector<MetaHeader> metaHeaders_;
2312   std::vector<MetaLink> metaLinks_;
2313 
2314   SignalMap exposedSignals_;   // signals that may be accessed
2315   ResourceMap exposedResources_; // resources that may be accessed
2316   ObjectMap encodedObjects_;   // objects encoded for internal purposes
2317                                  // like 'virtual pointers' (see D&D)
2318   std::set<std::string> justRemovedSignals_;
2319 
2320   bool exposeSignals_; // if we are currently exposing signals (see WViewWidget)
2321 
2322   std::string afterLoadJavaScript_, beforeLoadJavaScript_;
2323   int newBeforeLoadJavaScript_;
2324   std::string autoJavaScript_;
2325   bool autoJavaScriptChanged_;
2326 
2327 #ifndef WT_DEBUG_JS
2328   std::vector<WJavaScriptPreamble> javaScriptPreamble_;
2329   int newJavaScriptPreamble_;
2330 #else
2331   std::vector<const char *> newJavaScriptToLoad_;
2332 #endif // WT_DEBUG_JS
2333   std::set<const char *> javaScriptLoaded_;
2334   bool customJQuery_;
2335 
2336   EventSignal<> showLoadingIndicator_, hideLoadingIndicator_;
2337   JSignal<> unloaded_;
2338   JSignal<> idleTimeout_;
2339 
timerRoot()2340   WContainerWidget *timerRoot() const { return timerRoot_; }
2341   WEnvironment& env(); // short-hand for session_->env()
2342 
2343   /*
2344    * Functions for exposed signals, resources, and objects
2345    */
2346   void addExposedSignal(EventSignalBase* signal);
2347   void removeExposedSignal(EventSignalBase* signal);
2348   EventSignalBase  *decodeExposedSignal(const std::string& signalName) const;
2349   std::string encodeSignal(const std::string& objectId,
2350 			   const std::string& name) const;
2351 
exposedSignals()2352   SignalMap& exposedSignals() { return exposedSignals_; }
justRemovedSignals()2353   std::set<std::string>& justRemovedSignals() { return justRemovedSignals_; }
2354 
2355   std::string resourceMapKey(WResource *resource);
2356   std::string addExposedResource(WResource *resource);
2357   bool removeExposedResource(WResource *resource);
2358   WResource *decodeExposedResource(const std::string& resourceMapKey) const;
2359   WResource *decodeExposedResource(const std::string& resourceMapKey,
2360                                    unsigned long rand) const;
2361 
2362   /*
2363    * Methods for application state handling
2364    */
2365   bool changeInternalPath(const std::string& path);
2366   bool changedInternalPath(const std::string& path);
2367 
2368   /*
2369    * Methods for accessing javaScript, which may have erase-on-read
2370    * semantics
2371    */
2372   void streamAfterLoadJavaScript(WStringStream& out);
2373   void streamBeforeLoadJavaScript(WStringStream& out, bool all);
2374   void streamJavaScriptPreamble(WStringStream& out, bool all);
2375 #ifdef WT_DEBUG_JS
2376   void loadJavaScriptFile(WStringStream& out, const char *jsFile);
2377 #endif // WT_DEBUG_JS
2378 
2379   /*
2380    * Methods that control exposing of signals
2381    */
setExposeSignals(bool how)2382   void setExposeSignals(bool how) { exposeSignals_ = how; }
exposeSignals()2383   bool exposeSignals() const { return exposeSignals_; }
2384   void doUnload();
2385   void doIdleTimeout();
2386 
2387 #ifndef WT_TARGET_JAVA
2388   int startWaitingAtLock();
2389   void endWaitingAtLock(int id);
2390 #endif // WT_TARGET_JAVA
2391 
focus()2392   std::string focus() const { return focusId_; }
selectionStart()2393   int selectionStart() const { return selectionStart_; }
selectionEnd()2394   int selectionEnd() const { return selectionEnd_; }
2395 
2396   WLocalizedStrings *localizedStringsPack();
2397 
2398   /*
2399    * Methods for audio handling
2400    */
2401   SoundManager *getSoundManager();
2402   SoundManager *soundManager_;
2403 
2404   static const char *RESOURCES_URL;
2405 
2406 #ifdef WT_TARGET_JAVA
2407   JSlot showLoadJS;
2408   JSlot hideLoadJS;
2409 #endif
2410 
2411   friend class WCssStyleSheet;
2412   friend class WebRenderer;
2413   friend class WebSession;
2414   friend class WebController;
2415   friend class EventSignalBase;
2416   friend class JavaScriptEvent;
2417   friend class UpdateLockImpl;
2418   friend class WContainerWidget;
2419   friend class WDialog;
2420   friend class WFileUpload;
2421   friend class WInteractWidget;
2422   friend class WLineEdit;
2423   friend class WMenu;
2424   friend class WResource;
2425   friend class WSound;
2426   friend class WString;
2427   friend class WTextArea;
2428   friend class WTimer;
2429   friend class WViewWidget;
2430   friend class WWidget;
2431   friend class WWebWidget;
2432 };
2433 
2434 #ifndef WT_TARGET_JAVA
2435 #ifdef DOXYGEN_ONLY
2436 /*! \brief Runs the %Wt application server.
2437  *
2438  * This function runs the application server, and should be called
2439  * only once (e.g. from within your main function).
2440  *
2441  * The \p createApplication parameter is a <tt>std::function</tt>
2442  * object that should create a new application instance for a new user
2443  * visiting the application. It is of type:
2444  * <tt>std::function<Wt::WApplication* (const
2445  * Wt::WEnvironment&)></tt>, and thus you can pass to it a function
2446  * like:
2447  *
2448  * <pre>
2449  * Wt::WApplication *createApplication(const Wt::WEnvironment& env)
2450  * {
2451  *   // ...
2452  * }
2453  * </pre>
2454  *
2455  * When using the built-in httpd, the implementation listens for POSIX
2456  * termination signals (or console CTRL-C) event. You can use the
2457  * WServer class for more flexible control on starting and stopping
2458  * the server.
2459  *
2460  * \relates WServer
2461  * \sa WApplication
2462  */
2463 extern int WRun(int argc, char** argv,
2464 		ApplicationCreator createApplication = 0);
2465 #else // DOXYGEN_ONLY
2466 extern int WTCONNECTOR_API
2467 WRun(int argc, char** argv,
2468      ApplicationCreator createApplication = ApplicationCreator());
2469 
2470 #endif // DOXYGEN_ONLY
2471 
2472 #ifdef DOXYGEN_ONLY
2473 /*! \brief Runs the %Wt application server.
2474  *
2475  * This function runs the application server, and should be called
2476  * only once (e.g. from within your main function).
2477  *
2478  * The \p createApplication parameter is a <tt>std::function</tt>
2479  * object that should create a new application instance for a new user
2480  * visiting the application. It is of type:
2481  * <tt>std::function<Wt::WApplication* (const
2482  * Wt::WEnvironment&)></tt>, and thus you can pass to it a function
2483  * like:
2484  *
2485  * <pre>
2486  * Wt::WApplication *createApplication(const Wt::WEnvironment& env)
2487  * {
2488  *   // ...
2489  * }
2490  * </pre>
2491  *
2492  * When using the built-in httpd, the implementation listens for POSIX
2493  * termination signals (or console CTRL-C) event. You can use the
2494  * WServer class for more flexible control on starting and stopping
2495  * the server.
2496  *
2497  * This version of WRun() takes a std::string
2498  * for the application path, and a vector of arguments (not including
2499  * argv[0], the application path) instead of argc and argv,
2500  * for better convenience when arguments are not provided via
2501  * the command line.
2502  *
2503  * \relates WServer
2504  * \sa WApplication
2505  */
2506 extern int WRun(const std::string &applicationPath,
2507                 const std::vector<std::string> &args,
2508                 ApplicationCreator createApplication = 0);
2509 #else // DOXYGEN_ONLY
2510 extern int WTCONNECTOR_API
2511 WRun(const std::string &applicationPath,
2512      const std::vector<std::string> &args,
2513      ApplicationCreator createApplication = ApplicationCreator());
2514 
2515 #endif // DOXYGEN_ONLY
2516 #endif // WT_TARGET_JAVA
2517 
2518 /*! \def wApp
2519  *  \brief Global constant for accessing the application instance.
2520  *
2521  * This is equivalent to WApplication::instance()
2522  *
2523  * \relates WApplication
2524  */
2525 #define wApp Wt::WApplication::instance()
2526 
2527 }
2528 
2529 #endif // WAPPLICATION_
2530