1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630 |
- /*
- @ITMillApache2LicenseForJavaFiles@
- */
-
- package com.itmill.toolkit.terminal.gwt.server;
-
- import java.io.BufferedWriter;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.OutputStreamWriter;
- import java.io.PrintWriter;
- import java.io.Writer;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.util.Collection;
- import java.util.Enumeration;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.Properties;
-
- import javax.servlet.ServletContext;
- import javax.servlet.ServletException;
- import javax.servlet.ServletOutputStream;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
-
- import org.xml.sax.SAXException;
-
- import com.itmill.toolkit.Application;
- import com.itmill.toolkit.Application.SystemMessages;
- import com.itmill.toolkit.external.org.apache.commons.fileupload.servlet.ServletFileUpload;
- import com.itmill.toolkit.service.FileTypeResolver;
- import com.itmill.toolkit.terminal.DownloadStream;
- import com.itmill.toolkit.terminal.ParameterHandler;
- import com.itmill.toolkit.terminal.ThemeResource;
- import com.itmill.toolkit.terminal.URIHandler;
- import com.itmill.toolkit.ui.Window;
-
- /**
- * This servlet connects IT Mill Toolkit Application to Web.
- *
- * @author IT Mill Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-
- public class ApplicationServlet extends HttpServlet {
-
- private static final long serialVersionUID = -4937882979845826574L;
-
- /**
- * Version number of this release. For example "5.0.0".
- */
- public static final String VERSION;
-
- /**
- * Major version number. For example 5 in 5.1.0.
- */
- public static final int VERSION_MAJOR;
-
- /**
- * Minor version number. For example 1 in 5.1.0.
- */
- public static final int VERSION_MINOR;
-
- /**
- * Builds number. For example 0-custom_tag in 5.0.0-custom_tag.
- */
- public static final String VERSION_BUILD;
-
- /* Initialize version numbers from string replaced by build-script. */
- static {
- if ("@VERSION@".equals("@" + "VERSION" + "@")) {
- VERSION = "5.9.9-INTERNAL-NONVERSIONED-DEBUG-BUILD";
- } else {
- VERSION = "@VERSION@";
- }
- final String[] digits = VERSION.split("\\.");
- VERSION_MAJOR = Integer.parseInt(digits[0]);
- VERSION_MINOR = Integer.parseInt(digits[1]);
- VERSION_BUILD = digits[2];
- }
-
- /**
- * If the attribute is present in the request, a html fragment will be
- * written instead of a whole page.
- */
- public static final String REQUEST_FRAGMENT = ApplicationServlet.class
- .getName()
- + ".fragment";
- /**
- * This request attribute forces widgetset used; e.g for portlets that can
- * not have different widgetsets.
- */
- public static final String REQUEST_WIDGETSET = ApplicationServlet.class
- .getName()
- + ".widgetset";
- /**
- * This request attribute is used to add styles to the main element. E.g
- * "height:500px" generates a style="height:500px" to the main element,
- * useful from some embedding situations (e.g portlet include.)
- */
- public static final String REQUEST_APPSTYLE = ApplicationServlet.class
- .getName()
- + ".style";
-
- // Configurable parameter names
- private static final String PARAMETER_DEBUG = "Debug";
-
- private static final String PARAMETER_ITMILL_RESOURCES = "Resources";
-
- private static final int DEFAULT_BUFFER_SIZE = 32 * 1024;
-
- private static final int MAX_BUFFER_SIZE = 64 * 1024;
-
- // TODO This is session specific not servlet wide data. No need to store
- // this here, move it to Session from where it can be queried when required
- protected static HashMap applicationToAjaxAppMgrMap = new HashMap();
-
- private static final String RESOURCE_URI = "/RES/";
-
- private static final String AJAX_UIDL_URI = "/UIDL";
-
- static final String THEME_DIRECTORY_PATH = "ITMILL/themes/";
-
- private static final int DEFAULT_THEME_CACHETIME = 1000 * 60 * 60 * 24;
-
- static final String WIDGETSET_DIRECTORY_PATH = "ITMILL/widgetsets/";
-
- // Name of the default widget set, used if not specified in web.xml
- private static final String DEFAULT_WIDGETSET = "com.itmill.toolkit.terminal.gwt.DefaultWidgetSet";
-
- // Widget set parameter name
- private static final String PARAMETER_WIDGETSET = "widgetset";
-
- // Private fields
- private Class applicationClass;
-
- private Properties applicationProperties;
-
- private String resourcePath = null;
-
- private String debugMode = "";
-
- // Is this servlet application runner
- private boolean isApplicationRunnerServlet = false;
-
- // If servlet is application runner, store request's classname
- private String applicationRunnerClassname = null;
-
- private ClassLoader classLoader;
-
- private boolean testingToolsActive = false;
-
- private String testingToolsServerUri = null;
-
- /**
- * Called by the servlet container to indicate to a servlet that the servlet
- * is being placed into service.
- *
- * @param servletConfig
- * the object containing the servlet's configuration and
- * initialization parameters
- * @throws javax.servlet.ServletException
- * if an exception has occurred that interferes with the
- * servlet's normal operation.
- */
- public void init(javax.servlet.ServletConfig servletConfig)
- throws javax.servlet.ServletException {
- super.init(servletConfig);
-
- // Get applicationRunner
- final String applicationRunner = servletConfig
- .getInitParameter("applicationRunner");
- if (applicationRunner != null) {
- if ("true".equals(applicationRunner)) {
- isApplicationRunnerServlet = true;
- } else if ("false".equals(applicationRunner)) {
- isApplicationRunnerServlet = false;
- } else {
- throw new ServletException(
- "If applicationRunner parameter is given for an application, it must be 'true' or 'false'");
- }
- }
-
- // Stores the application parameters into Properties object
- applicationProperties = new Properties();
- for (final Enumeration e = servletConfig.getInitParameterNames(); e
- .hasMoreElements();) {
- final String name = (String) e.nextElement();
- applicationProperties.setProperty(name, servletConfig
- .getInitParameter(name));
- }
-
- // Overrides with server.xml parameters
- final ServletContext context = servletConfig.getServletContext();
- for (final Enumeration e = context.getInitParameterNames(); e
- .hasMoreElements();) {
- final String name = (String) e.nextElement();
- applicationProperties.setProperty(name, context
- .getInitParameter(name));
- }
-
- // Gets the debug window parameter
- final String debug = getApplicationOrSystemProperty(PARAMETER_DEBUG, "")
- .toLowerCase();
-
- // Enables application specific debug
- if (!"".equals(debug) && !"true".equals(debug)
- && !"false".equals(debug)) {
- throw new ServletException(
- "If debug parameter is given for an application, it must be 'true' or 'false'");
- }
- debugMode = debug;
-
- // Gets Testing Tools parameters if feature is activated
- if (getApplicationOrSystemProperty("testingToolsActive", "false")
- .equals("true")) {
- testingToolsActive = true;
- testingToolsServerUri = getApplicationOrSystemProperty(
- "testingToolsServerUri", null);
- }
-
- // Gets custom class loader
- final String classLoaderName = getApplicationOrSystemProperty(
- "ClassLoader", null);
- ClassLoader classLoader;
- if (classLoaderName == null) {
- classLoader = getClass().getClassLoader();
- } else {
- try {
- final Class classLoaderClass = getClass().getClassLoader()
- .loadClass(classLoaderName);
- final Constructor c = classLoaderClass
- .getConstructor(new Class[] { ClassLoader.class });
- classLoader = (ClassLoader) c
- .newInstance(new Object[] { getClass().getClassLoader() });
- } catch (final Exception e) {
- throw new ServletException(
- "Could not find specified class loader: "
- + classLoaderName, e);
- }
- }
- this.classLoader = classLoader;
-
- // Loads the application class using the same class loader
- // as the servlet itself
- if (!isApplicationRunnerServlet) {
- // Gets the application class name
- final String applicationClassName = servletConfig
- .getInitParameter("application");
- if (applicationClassName == null) {
- throw new ServletException(
- "Application not specified in servlet parameters");
- }
- try {
- applicationClass = classLoader.loadClass(applicationClassName);
- } catch (final ClassNotFoundException e) {
- throw new ServletException("Failed to load application class: "
- + applicationClassName);
- }
- } else {
- // This servlet is in application runner mode, it uses classloader
- // later to create Applications based on URL
- }
-
- }
-
- /**
- * Gets an application or system property value.
- *
- * @param parameterName
- * the Name or the parameter.
- * @param defaultValue
- * the Default to be used.
- * @return String value or default if not found
- */
- private String getApplicationOrSystemProperty(String parameterName,
- String defaultValue) {
-
- // Try application properties
- String val = applicationProperties.getProperty(parameterName);
- if (val != null) {
- return val;
- }
-
- // Try lowercased application properties for backward compability with
- // 3.0.2 and earlier
- val = applicationProperties.getProperty(parameterName.toLowerCase());
- if (val != null) {
- return val;
- }
-
- // Try system properties
- String pkgName;
- final Package pkg = getClass().getPackage();
- if (pkg != null) {
- pkgName = pkg.getName();
- } else {
- final String className = getClass().getName();
- pkgName = new String(className.toCharArray(), 0, className
- .lastIndexOf('.'));
- }
- val = System.getProperty(pkgName + "." + parameterName);
- if (val != null) {
- return val;
- }
-
- // Try lowercased system properties
- val = System.getProperty(pkgName + "." + parameterName.toLowerCase());
- if (val != null) {
- return val;
- }
-
- return defaultValue;
- }
-
- /**
- * Receives standard HTTP requests from the public service method and
- * dispatches them.
- *
- * @param request
- * the object that contains the request the client made of the
- * servlet.
- * @param response
- * the object that contains the response the servlet returns to
- * the client.
- * @throws ServletException
- * if an input or output error occurs while the servlet is
- * handling the TRACE request.
- * @throws IOException
- * if the request for the TRACE cannot be handled.
- */
- protected void service(HttpServletRequest request,
- HttpServletResponse response) throws ServletException, IOException {
-
- // check if we should serve static files (widgetsets, themes)
- if ((request.getPathInfo() != null)
- && (request.getPathInfo().length() > 10)) {
- if ((request.getContextPath() != null)
- && (request.getRequestURI().startsWith("/ITMILL/"))) {
- serveStaticResourcesInITMILL(request.getRequestURI(), response);
- return;
- } else if (request.getRequestURI().startsWith(
- request.getContextPath() + "/ITMILL/")) {
- serveStaticResourcesInITMILL(request.getRequestURI().substring(
- request.getContextPath().length()), response);
- return;
- }
- }
-
- Application application = null;
- boolean UIDLrequest = false;
- try {
- // handle file upload if multipart request
- if (ServletFileUpload.isMultipartContent(request)) {
- application = getExistingApplication(request, response);
- if (application == null) {
- throw new SessionExpired();
- }
- // Invokes context transaction listeners
- // note: endTransaction is called on finalize below
- ((WebApplicationContext) application.getContext())
- .startTransaction(application, request);
- getApplicationManager(application).handleFileUpload(request,
- response);
- return;
- }
-
- // Update browser details
- final WebBrowser browser = WebApplicationContext
- .getApplicationContext(request.getSession()).getBrowser();
- browser.updateBrowserProperties(request);
- // TODO Add screen height and width to the GWT client
-
- // Handles AJAX UIDL requests
- if (request.getPathInfo() != null) {
-
- String compare = AJAX_UIDL_URI;
- if (isApplicationRunnerServlet) {
- final String[] URIparts = getApplicationRunnerURIs(request);
- applicationRunnerClassname = URIparts[4];
- compare = "/" + applicationRunnerClassname + AJAX_UIDL_URI;
- }
-
- if (request.getPathInfo().startsWith(compare + "/")
- || request.getPathInfo().endsWith(compare)) {
- UIDLrequest = true;
- application = getExistingApplication(request, response);
- if (application == null) {
- // No existing applications found
- final String repaintAll = request
- .getParameter("repaintAll");
- if ((repaintAll != null) && (repaintAll.equals("1"))) {
- // UIDL request contains valid repaintAll=1 event,
- // probably user wants to initiate new application
- // through custom index.html without writeAjaxPage
- application = getNewApplication(request, response);
- } else {
- // UIDL request refers to non-existing application
- throw new SessionExpired();
- }
- }
-
- // Invokes context transaction listeners
- // note: endTransaction is called on finalize below
- ((WebApplicationContext) application.getContext())
- .startTransaction(application, request);
-
- // Handle UIDL request
- getApplicationManager(application).handleUidlRequest(
- request, response, this);
- return;
- }
- }
-
- // Get existing application
- application = getExistingApplication(request, response);
- if (application == null
- || request.getParameter("restartApplication") != null
- || request.getParameter("closeApplication") != null) {
- if (application != null) {
- application.close();
- final HttpSession session = request.getSession(false);
- if (session != null) {
- ApplicationServlet.applicationToAjaxAppMgrMap
- .remove(application);
- WebApplicationContext.getApplicationContext(session)
- .removeApplication(application);
- }
- }
- if (request.getParameter("closeApplication") != null) {
- return;
- }
- // Not found, creating new application
- application = getNewApplication(request, response);
- }
-
- // Invokes context transaction listeners
- // note: endTransaction is called on finalize below
- ((WebApplicationContext) application.getContext())
- .startTransaction(application, request);
-
- // Removes application if it has stopped
- if (!application.isRunning()) {
- endApplication(request, response, application);
- return;
- }
-
- // Finds the window within the application
- Window window = null;
- window = getApplicationWindow(request, application);
- if (window == null) {
- throw new ServletException(
- "Application did not give any window, did you remember to setMainWindow()?");
- }
-
- // Handle parameters
- final Map parameters = request.getParameterMap();
- if (window != null && parameters != null) {
- window.handleParameters(parameters);
- }
-
- // Is this a download request from application
- DownloadStream download = null;
-
- // Handles the URI if the application is still running
- download = handleURI(application, request, response);
-
- // If this is not a download request
- if (download == null) {
-
- // Sets terminal type for the window, if not already set
- if (window.getTerminal() == null) {
- window.setTerminal(browser);
- }
-
- // Finds theme name
- String themeName = window.getTheme();
- if (request.getParameter("theme") != null) {
- themeName = request.getParameter("theme");
- }
-
- if (themeName == null) {
- themeName = "default";
- }
-
- // Handles resource requests
- if (handleResourceRequest(request, response, themeName)) {
- return;
- }
-
- // Send initial AJAX page that kickstarts Toolkit application
- writeAjaxPage(request, response, window, themeName, application);
-
- } else {
- // Client downloads an resource
- handleDownload(download, request, response);
- }
-
- } catch (final SessionExpired e) {
- // Session has expired, notify user
- try {
- Application.SystemMessages ci = getSystemMessages();
- if (!UIDLrequest) {
- // 'plain' http req - e.g. browser reload;
- // just go ahead redirect the browser
- response.sendRedirect(ci.getSessionExpiredURL());
- } else {
- // send uidl redirect
- criticalNotification(request, response, ci
- .getSessionExpiredCaption(), ci
- .getSessionExpiredMessage(), ci
- .getSessionExpiredURL());
- }
- } catch (SystemMessageException ee) {
- throw new ServletException(ee);
- }
-
- } catch (final Throwable e) {
- // if this was an UIDL request, response UIDL back to client
- if (UIDLrequest) {
- Application.SystemMessages ci = getSystemMessages();
- criticalNotification(request, response, ci
- .getInternalErrorCaption(), ci
- .getInternalErrorMessage(), ci.getInternalErrorURL());
- } else {
- // Re-throw other exceptions
- throw new ServletException(e);
- }
- } finally {
- // Notifies transaction end
- if (application != null) {
- ((WebApplicationContext) application.getContext())
- .endTransaction(application, request);
- }
- }
- }
-
- /** Get system messages from the current application class */
- private SystemMessages getSystemMessages() {
- try {
- Class appCls = applicationClass;
- if (isApplicationRunnerServlet) {
- appCls = getClass().getClassLoader().loadClass(
- applicationRunnerClassname);
- }
- Method m = appCls.getMethod("getSystemMessages", null);
- return (Application.SystemMessages) m.invoke(null, null);
- } catch (ClassNotFoundException e) {
- // This should never happen
- throw new SystemMessageException(e);
- } catch (SecurityException e) {
- throw new SystemMessageException(
- "Application.getSystemMessage() should be static public", e);
- } catch (NoSuchMethodException e) {
- // This is completely ok and should be silently ignored
- } catch (IllegalArgumentException e) {
- // This should never happen
- throw new SystemMessageException(e);
- } catch (IllegalAccessException e) {
- throw new SystemMessageException(
- "Application.getSystemMessage() should be static public", e);
- } catch (InvocationTargetException e) {
- // This should never happen
- throw new SystemMessageException(e);
- }
- return Application.getSystemMessages();
- }
-
- /**
- * Serve resources in ITMILL directory if requested.
- *
- * @param request
- * @param response
- * @throws IOException
- */
- private void serveStaticResourcesInITMILL(String filename,
- HttpServletResponse response) throws IOException {
-
- final ServletContext sc = getServletContext();
- InputStream is = sc.getResourceAsStream(filename);
- if (is == null) {
- // try if requested file is found from classloader
-
- // strip leading "/" otherwise stream from JAR wont work
- filename = filename.substring(1);
- is = classLoader.getResourceAsStream(filename);
-
- if (is == null) {
- // cannot serve requested file
- System.err
- .println("Requested resource ["
- + filename
- + "] not found from filesystem or through class loader."
- + " Add widgetset and/or theme JAR to your classpath or add files to WebContent/ITMILL folder.");
- response.setStatus(404);
- return;
- }
- }
- final String mimetype = sc.getMimeType(filename);
- if (mimetype != null) {
- response.setContentType(mimetype);
- }
- final OutputStream os = response.getOutputStream();
- final byte buffer[] = new byte[20000];
- int bytes;
- while ((bytes = is.read(buffer)) >= 0) {
- os.write(buffer, 0, bytes);
- }
- }
-
- /**
- * Send notification to client's application. Used to notify client of
- * critical errors and session expiration due to long inactivity. Server has
- * no knowledge of what application client refers to.
- *
- * @param request
- * the HTTP request instance.
- * @param response
- * the HTTP response to write to.
- * @param caption
- * for the notification
- * @param message
- * for the notification
- * @param url
- * url to load after message, null for current page
- * @throws IOException
- * if the writing failed due to input/output error.
- */
- void criticalNotification(HttpServletRequest request,
- HttpServletResponse response, String caption, String message,
- String url) throws IOException {
-
- // clients JS app is still running, but server application either
- // no longer exists or it might fail to perform reasonably.
- // send a notification to client's application and link how
- // to "restart" application.
-
- if (caption != null) {
- caption = "\"" + caption + "\"";
- }
- if (message != null) {
- message = "\"" + message + "\"";
- }
- if (url != null) {
- url = "\"" + url + "\"";
- }
-
- // Set the response type
- response.setContentType("application/json; charset=UTF-8");
- final ServletOutputStream out = response.getOutputStream();
- final PrintWriter outWriter = new PrintWriter(new BufferedWriter(
- new OutputStreamWriter(out, "UTF-8")));
- outWriter.print("for(;;);[{\"changes\":[], \"meta\" : {"
- + "\"appError\": {" + "\"caption\":" + caption + ","
- + "\"message\" : " + message + "," + "\"url\" : " + url
- + "}}, \"resources\": {}, \"locales\":[]}]");
- outWriter.flush();
- outWriter.close();
- out.flush();
- }
-
- /**
- * Resolve application URL and widgetset URL. Widgetset is not application
- * specific.
- *
- * @param request
- * @return string array consisting of application url first and then
- * widgetset url.
- * @throws MalformedURLException
- */
- private String[] getAppAndWidgetUrl(HttpServletRequest request)
- throws MalformedURLException {
- // don't use server and port in uri. It may cause problems with some
- // virtual server configurations which lose the server name
- String appUrl = null;
- String widgetsetUrl = null;
- if (isApplicationRunnerServlet) {
- final String[] URIparts = getApplicationRunnerURIs(request);
- widgetsetUrl = URIparts[0];
- if (widgetsetUrl.equals("/")) {
- widgetsetUrl = "";
- }
- appUrl = URIparts[1];
- } else {
- String[] urlParts;
- urlParts = getApplicationUrl(request).toString().split("\\/");
- appUrl = "";
- widgetsetUrl = "";
- // if context is specified add it to widgetsetUrl
- String ctxPath = request.getContextPath();
- if (ctxPath.length() == 0
- && request
- .getAttribute("javax.servlet.include.context_path") != null) {
- // include request (e.g portlet), get contex path from
- // attribute
- ctxPath = (String) request
- .getAttribute("javax.servlet.include.context_path");
- }
- if (urlParts.length > 3
- && urlParts[3].equals(ctxPath.replaceAll("\\/", ""))) {
- widgetsetUrl += "/" + urlParts[3];
- }
- for (int i = 3; i < urlParts.length; i++) {
- appUrl += "/" + urlParts[i];
- }
- if (appUrl.endsWith("/")) {
- appUrl = appUrl.substring(0, appUrl.length() - 1);
- }
-
- }
- return new String[] { appUrl, widgetsetUrl };
- }
-
- /**
- *
- * @param request
- * the HTTP request.
- * @param response
- * the HTTP response to write to.
- * @param out
- * @param unhandledParameters
- * @param window
- * @param terminalType
- * @param theme
- * @throws IOException
- * if the writing failed due to input/output error.
- * @throws MalformedURLException
- * if the application is denied access the persistent data store
- * represented by the given URL.
- */
- private void writeAjaxPage(HttpServletRequest request,
- HttpServletResponse response, Window window, String themeName,
- Application application) throws IOException, MalformedURLException {
-
- // e.g portlets only want a html fragment
- boolean fragment = (request.getAttribute(REQUEST_FRAGMENT) != null);
- if (fragment) {
- request.setAttribute(Application.class.getName(), application);
- }
-
- final BufferedWriter page = new BufferedWriter(new OutputStreamWriter(
- response.getOutputStream()));
- final String pathInfo = request.getPathInfo() == null ? "/" : request
- .getPathInfo();
- String title = ((window == null || window.getCaption() == null) ? "IT Mill Toolkit 5"
- : window.getCaption());
-
- String widgetset = null;
- // request widgetset takes precedence (e.g portlet include)
- Object reqParam = request.getAttribute(REQUEST_WIDGETSET);
- try {
- widgetset = (String) reqParam;
- } catch (Exception e) {
- // FIXME: Handle exception
- System.err.println("Warning: request param '" + REQUEST_WIDGETSET
- + "' could not be used (is not a String)" + e);
- }
- if (widgetset == null) {
- widgetset = applicationProperties.getProperty(PARAMETER_WIDGETSET);
- }
- if (widgetset == null) {
- widgetset = DEFAULT_WIDGETSET;
- }
- final String[] urls = getAppAndWidgetUrl(request);
- final String appUrl = urls[0];
- final String widgetsetUrl = urls[1];
-
- final String staticFilePath = getApplicationOrSystemProperty(
- PARAMETER_ITMILL_RESOURCES, widgetsetUrl);
-
- // Default theme does not use theme URI
- String themeUri = null;
- if (themeName != null) {
- // Using custom theme
- themeUri = staticFilePath + "/" + THEME_DIRECTORY_PATH + themeName;
- }
-
- boolean testingApplication = testingToolsActive
- && request.getParameter("TT") != null;
-
- if (!fragment) {
- // Window renders are not cacheable
- response.setCharacterEncoding("utf-8");
- response.setHeader("Cache-Control", "no-cache");
- response.setHeader("Pragma", "no-cache");
- response.setDateHeader("Expires", 0);
- response.setContentType("text/html");
-
- // write html header
- page.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD "
- + "XHTML 1.0 Transitional//EN\" "
- + "\"http://www.w3.org/TR/xhtml1/"
- + "DTD/xhtml1-transitional.dtd\">\n");
-
- page.write("<html xmlns=\"http://www.w3.org/1999/xhtml\""
- + ">\n<head>\n");
- page
- .write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n");
- page.write("<style type=\"text/css\">"
- + "html, body {height:100%;}</style>");
- page.write("<title>" + title + "</title>");
-
- if (testingApplication) {
- // TT script needs to be in head as it needs to be the first
- // to hook capturing event listeners
- writeTestingToolsScripts(page, request);
- }
-
- page
- .write("\n</head>\n<body scroll=\"auto\" class=\"i-generated-body\">\n");
- }
-
- String appId = appUrl;
- if ("".equals(appUrl)) {
- appId = "ROOT";
- }
- appId = appId.replaceAll("[^a-zA-Z0-9]", "");
-
- if (isGecko17(request)) {
- // special start page for gecko 1.7 versions. Firefox 1.0 is not
- // supported, but the hack is make it possible to use linux and
- // hosted mode browser for debugging. Note that due this hack,
- // debugging gwt code in portals with linux will be problematic if
- // there are multiple toolkit portlets visible at the same time.
- // TODO remove this when hosted mode on linux gets newer gecko
-
- page.write("<iframe id=\"__gwt_historyFrame\" "
- + "style=\"width:0;height:0;border:0;overflow:"
- + "hidden\" src=\"javascript:false\"></iframe>\n");
- page.write("<script language='javascript' src='" + staticFilePath
- + "/" + WIDGETSET_DIRECTORY_PATH + widgetset + "/"
- + widgetset + ".nocache.js'></script>\n");
- page.write("<script type=\"text/javascript\">\n");
- page.write("//<![CDATA[\n");
- page.write("if(!itmill || !itmill.toolkitConfigurations) {\n "
- + "if(!itmill) { var itmill = {}} \n"
- + "itmill.toolkitConfigurations = {};\n"
- + "itmill.themesLoaded = {}};\n");
-
- page.write("itmill.toolkitConfigurations[\"" + appId + "\"] = {");
- page.write("appUri:'" + appUrl + "', ");
- page.write("pathInfo: '" + pathInfo + "', ");
- page.write("themeUri:");
- page.write(themeUri != null ? "'" + themeUri + "'" : "null");
- page.write(", versionInfo : {toolkitVersion:\"");
- page.write(VERSION);
- page.write("\",applicationVersion:\"");
- page.write(application.getVersion());
- page.write("\"}");
- page.write("};\n//]]>\n</script>\n");
-
- if (themeName != null) {
- // Custom theme's stylesheet, load only once, in different
- // script
- // tag to be dominate styles injected by widget
- // set
- page.write("<script type=\"text/javascript\">\n");
- page.write("//<![CDATA[\n");
- page.write("if(!itmill.themesLoaded['" + themeName + "']) {\n");
- page
- .write("var stylesheet = document.createElement('link');\n");
- page.write("stylesheet.setAttribute('rel', 'stylesheet');\n");
- page.write("stylesheet.setAttribute('type', 'text/css');\n");
- page.write("stylesheet.setAttribute('href', '" + themeUri
- + "/styles.css');\n");
- page
- .write("document.getElementsByTagName('head')[0].appendChild(stylesheet);\n");
- page.write("itmill.themesLoaded['" + themeName
- + "'] = true;\n}\n");
- page.write("//]]>\n</script>\n");
- }
-
- } else {
- page.write("<script type=\"text/javascript\">\n");
- page.write("//<![CDATA[\n");
- page.write("if(!itmill || !itmill.toolkitConfigurations) {\n "
- + "if(!itmill) { var itmill = {}} \n"
- + "itmill.toolkitConfigurations = {};\n"
- + "itmill.themesLoaded = {};\n");
- page.write("document.write('<iframe id=\"__gwt_historyFrame\" "
- + "style=\"width:0;height:0;border:0;overflow:"
- + "hidden\" src=\"javascript:false\"></iframe>');\n");
- page.write("document.write(\"<script language='javascript' src='"
- + staticFilePath + "/" + WIDGETSET_DIRECTORY_PATH
- + widgetset + "/" + widgetset
- + ".nocache.js'><\\/script>\");\n}\n");
-
- page.write("itmill.toolkitConfigurations[\"" + appId + "\"] = {");
- page.write("appUri:'" + appUrl + "', ");
- page.write("pathInfo: '" + pathInfo + "', ");
- page.write("themeUri:");
- page.write(themeUri != null ? "'" + themeUri + "'" : "null");
- page.write(", versionInfo : {toolkitVersion:\"");
- page.write(VERSION);
- page.write("\",applicationVersion:\"");
- page.write(application.getVersion());
- page.write("\"}");
- page.write("};\n//]]>\n</script>\n");
-
- if (themeName != null) {
- // Custom theme's stylesheet, load only once, in different
- // script
- // tag to be dominate styles injected by widget
- // set
- page.write("<script type=\"text/javascript\">\n");
- page.write("//<![CDATA[\n");
- page.write("if(!itmill.themesLoaded['" + themeName + "']) {\n");
- page
- .write("var stylesheet = document.createElement('link');\n");
- page.write("stylesheet.setAttribute('rel', 'stylesheet');\n");
- page.write("stylesheet.setAttribute('type', 'text/css');\n");
- page.write("stylesheet.setAttribute('href', '" + themeUri
- + "/styles.css');\n");
- page
- .write("document.getElementsByTagName('head')[0].appendChild(stylesheet);\n");
- page.write("itmill.themesLoaded['" + themeName
- + "'] = true;\n}\n");
- page.write("//]]>\n</script>\n");
- }
- }
-
- String style = null;
- reqParam = request.getAttribute(REQUEST_APPSTYLE);
- if (reqParam != null) {
- style = "style=\"" + reqParam + "\"";
- }
- page.write("<div id=\"" + appId + "\" class=\"i-app\" "
- + (style != null ? style : "") + "></div>\n");
-
- if (!fragment) {
- page.write("</body>\n</html>\n");
- }
- page.close();
-
- }
-
- private boolean isGecko17(HttpServletRequest request) {
- final WebBrowser browser = WebApplicationContext.getApplicationContext(
- request.getSession()).getBrowser();
- if (browser != null && browser.getBrowserApplication() != null) {
- if (browser.getBrowserApplication().indexOf("rv:1.7.") > 0
- && browser.getBrowserApplication().indexOf("Gecko") > 0) {
- return true;
- }
- }
- return false;
- }
-
- private void writeTestingToolsScripts(Writer page,
- HttpServletRequest request) throws IOException {
- // Testing Tools script and CSS files are served from Testing Tools
- // Server
- String ext = getTestingToolsUri(request);
- ext = ext.substring(0, ext.lastIndexOf('/'));
- page.write("<script src=\"" + ext + "/ext/TT.js"
- + "\" type=\"text/javascript\"></script>\n");
- page.write("<link rel=\"stylesheet\" href=\"" + ext + "/ext/TT.css"
- + "\" type=\"text/css\" />\n");
-
- }
-
- private String getTestingToolsUri(HttpServletRequest request) {
- if (testingToolsServerUri == null) {
- // Default behavior is that Testing Tools Server application exists
- // on same host as current application does in port 8099.
- testingToolsServerUri = "http" + "://" + request.getServerName()
- + ":8099" + "/TestingToolsServer";
- }
- return testingToolsServerUri;
- }
-
- /**
- * Handles the requested URI. An application can add handlers to do special
- * processing, when a certain URI is requested. The handlers are invoked
- * before any windows URIs are processed and if a DownloadStream is returned
- * it is sent to the client.
- *
- * @param application
- * the Application owning the URI.
- * @param request
- * the HTTP request instance.
- * @param response
- * the HTTP response to write to.
- * @return boolean <code>true</code> if the request was handled and further
- * processing should be suppressed, <code>false</code> otherwise.
- * @see com.itmill.toolkit.terminal.URIHandler
- */
- private DownloadStream handleURI(Application application,
- HttpServletRequest request, HttpServletResponse response) {
-
- String uri = request.getPathInfo();
-
- // If no URI is available
- if (uri == null) {
- uri = "";
- }
-
- // Removes the leading /
- while (uri.startsWith("/") && uri.length() > 0) {
- uri = uri.substring(1);
- }
-
- // If using application runner, remove package and class name
- if (isApplicationRunnerServlet) {
- uri = uri.replaceFirst(applicationRunnerClassname + "/", "");
- }
-
- // Handles the uri
- DownloadStream stream = null;
- try {
- stream = application.handleURI(application.getURL(), uri);
- } catch (final Throwable t) {
- application.terminalError(new URIHandlerErrorImpl(application, t));
- }
-
- return stream;
- }
-
- /**
- * Handles the requested URI. An application can add handlers to do special
- * processing, when a certain URI is requested. The handlers are invoked
- * before any windows URIs are processed and if a DownloadStream is returned
- * it is sent to the client.
- *
- * @param stream
- * the download stream.
- *
- * @param request
- * the HTTP request instance.
- * @param response
- * the HTTP response to write to.
- * @throws IOException
- *
- * @see com.itmill.toolkit.terminal.URIHandler
- */
- private void handleDownload(DownloadStream stream,
- HttpServletRequest request, HttpServletResponse response)
- throws IOException {
-
- if (stream.getParameter("Location") != null) {
- response.setStatus(HttpServletResponse.SC_FOUND);
- response.addHeader("Location", stream.getParameter("Location"));
- return;
- }
-
- // Download from given stream
- final InputStream data = stream.getStream();
- if (data != null) {
-
- // Sets content type
- response.setContentType(stream.getContentType());
-
- // Sets cache headers
- final long cacheTime = stream.getCacheTime();
- if (cacheTime <= 0) {
- response.setHeader("Cache-Control", "no-cache");
- response.setHeader("Pragma", "no-cache");
- response.setDateHeader("Expires", 0);
- } else {
- response.setHeader("Cache-Control", "max-age=" + cacheTime
- / 1000);
- response.setDateHeader("Expires", System.currentTimeMillis()
- + cacheTime);
- response.setHeader("Pragma", "cache"); // Required to apply
- // caching in some
- // Tomcats
- }
-
- // Copy download stream parameters directly
- // to HTTP headers.
- final Iterator i = stream.getParameterNames();
- if (i != null) {
- while (i.hasNext()) {
- final String param = (String) i.next();
- response.setHeader(param, stream.getParameter(param));
- }
- }
-
- int bufferSize = stream.getBufferSize();
- if (bufferSize <= 0 || bufferSize > MAX_BUFFER_SIZE) {
- bufferSize = DEFAULT_BUFFER_SIZE;
- }
- final byte[] buffer = new byte[bufferSize];
- int bytesRead = 0;
-
- final OutputStream out = response.getOutputStream();
-
- while ((bytesRead = data.read(buffer)) > 0) {
- out.write(buffer, 0, bytesRead);
- out.flush();
- }
- out.close();
-
- }
-
- }
-
- /**
- * Handles theme resource file requests. Resources supplied with the themes
- * are provided by the WebAdapterServlet.
- *
- * @param request
- * the HTTP request.
- * @param response
- * the HTTP response.
- * @return boolean <code>true</code> if the request was handled and further
- * processing should be suppressed, <code>false</code> otherwise.
- * @throws ServletException
- * if an exception has occurred that interferes with the
- * servlet's normal operation.
- */
- private boolean handleResourceRequest(HttpServletRequest request,
- HttpServletResponse response, String themeName)
- throws ServletException {
-
- // If the resource path is unassigned, initialize it
- if (resourcePath == null) {
- resourcePath = request.getContextPath() + request.getServletPath()
- + RESOURCE_URI;
- // WebSphere Application Server related fix
- resourcePath = resourcePath.replaceAll("//", "/");
- }
-
- String resourceId = request.getPathInfo();
-
- // Checks if this really is a resource request
- if (resourceId == null || !resourceId.startsWith(RESOURCE_URI)) {
- return false;
- }
-
- // Checks the resource type
- resourceId = resourceId.substring(RESOURCE_URI.length());
- InputStream data = null;
-
- // Gets theme resources
- try {
- data = getServletContext().getResourceAsStream(
- THEME_DIRECTORY_PATH + themeName + "/" + resourceId);
- } catch (final Exception e) {
- // FIXME: Handle exception
- e.printStackTrace();
- data = null;
- }
-
- // Writes the response
- try {
- if (data != null) {
- response.setContentType(FileTypeResolver
- .getMIMEType(resourceId));
-
- // Use default cache time for theme resources
- response.setHeader("Cache-Control", "max-age="
- + DEFAULT_THEME_CACHETIME / 1000);
- response.setDateHeader("Expires", System.currentTimeMillis()
- + DEFAULT_THEME_CACHETIME);
- response.setHeader("Pragma", "cache"); // Required to apply
- // caching in some
- // Tomcats
-
- // Writes the data to client
- final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
- int bytesRead = 0;
- final OutputStream out = response.getOutputStream();
- while ((bytesRead = data.read(buffer)) > 0) {
- out.write(buffer, 0, bytesRead);
- }
- out.close();
- data.close();
- } else {
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- }
-
- } catch (final java.io.IOException e) {
- // FIXME: Handle exception
- System.err.println("Resource transfer failed: "
- + request.getRequestURI() + ". (" + e.getMessage() + ")");
- }
-
- return true;
- }
-
- /**
- * Gets the current application URL from request.
- *
- * @param request
- * the HTTP request.
- * @throws MalformedURLException
- * if the application is denied access to the persistent data
- * store represented by the given URL.
- */
- private URL getApplicationUrl(HttpServletRequest request)
- throws MalformedURLException {
-
- URL applicationUrl;
-
- final URL reqURL = new URL(
- (request.isSecure() ? "https://" : "http://")
- + request.getServerName()
- + ((request.isSecure() && request.getServerPort() == 443)
- || (!request.isSecure() && request
- .getServerPort() == 80) ? "" : ":"
- + request.getServerPort())
- + request.getRequestURI());
- String servletPath = "";
- if (request.getAttribute("javax.servlet.include.servlet_path") != null) {
- // this is an include request
- servletPath = request.getAttribute(
- "javax.servlet.include.context_path").toString()
- + request
- .getAttribute("javax.servlet.include.servlet_path");
-
- } else {
- servletPath = request.getContextPath() + request.getServletPath();
- }
- if (servletPath.length() == 0
- || servletPath.charAt(servletPath.length() - 1) != '/') {
- servletPath = servletPath + "/";
- }
- applicationUrl = new URL(reqURL, servletPath);
-
- return applicationUrl;
- }
-
- /**
- * Parses application runner URIs.
- *
- * If request URL is e.g.
- * http://localhost:8080/itmill/run/com.itmill.toolkit.demo.Calc then
- * <ul>
- * <li>context=itmill</li>
- * <li>Runner servlet=run</li>
- * <li>Toolkit application=com.itmill.toolkit.demo.Calc</li>
- * </ul>
- *
- * @param request
- * @return string array containing widgetset URI, application URI and
- * context, runner, application classname
- */
- private String[] getApplicationRunnerURIs(HttpServletRequest request) {
- final String[] urlParts = request.getRequestURI().toString().split(
- "\\/");
- String context = null;
- String runner = null;
- String applicationClassname = null;
- if (urlParts[1].equals(request.getContextPath().replaceAll("\\/", ""))) {
- // class name comes after web context and runner application
- context = urlParts[1];
- runner = urlParts[2];
- applicationClassname = urlParts[3];
- return new String[] { "/" + context,
- "/" + context + "/" + runner + "/" + applicationClassname,
- context, runner, applicationClassname };
- } else {
- // no context
- context = "";
- runner = urlParts[1];
- applicationClassname = urlParts[2];
- return new String[] { "/",
- "/" + runner + "/" + applicationClassname, context, runner,
- applicationClassname };
- }
- }
-
- /**
- * Gets the existing application for given request. Looks for application
- * instance for given request based on the requested URL.
- *
- * @param request
- * the HTTP request.
- * @param response
- * @return Application instance, or null if the URL does not map to valid
- * application.
- * @throws MalformedURLException
- * if the application is denied access to the persistent data
- * store represented by the given URL.
- * @throws SAXException
- * @throws IllegalAccessException
- * @throws InstantiationException
- */
- private Application getExistingApplication(HttpServletRequest request,
- HttpServletResponse response) throws MalformedURLException,
- SAXException, IllegalAccessException, InstantiationException {
-
- // Ensures that the session is still valid
- final HttpSession session = request.getSession(true);
-
- // Gets application list for the session.
- final Collection applications = WebApplicationContext
- .getApplicationContext(session).getApplications();
-
- // Search for the application (using the application URI) from the list
- for (final Iterator i = applications.iterator(); i.hasNext();) {
- final Application a = (Application) i.next();
- final String aPath = a.getURL().getPath();
- String servletPath = "";
- if (isApplicationRunnerServlet) {
- final String[] URIparts = getApplicationRunnerURIs(request);
- servletPath = URIparts[1] + "/";
- } else {
- servletPath = request.getContextPath()
- + request.getServletPath();
- if (servletPath.length() < aPath.length()) {
- servletPath += "/";
- }
- }
- if (servletPath.equals(aPath)) {
- // Found a running application
- if (a.isRunning()) {
- return a;
- }
- // Application has stopped, so remove it before creating a new
- // application
- WebApplicationContext.getApplicationContext(session)
- .removeApplication(a);
- break;
- }
- }
-
- // Existing application not found
- return null;
- }
-
- /**
- * Creates new application for given request.
- *
- * @param request
- * the HTTP request.
- * @param response
- * @return Application instance, or null if the URL does not map to valid
- * application.
- * @throws MalformedURLException
- * if the application is denied access to the persistent data
- * store represented by the given URL.
- * @throws SAXException
- * @throws IllegalAccessException
- * @throws InstantiationException
- */
- private Application getNewApplication(HttpServletRequest request,
- HttpServletResponse response) throws MalformedURLException,
- SAXException, IllegalAccessException, InstantiationException {
-
- // Create application
- final WebApplicationContext context = WebApplicationContext
- .getApplicationContext(request.getSession());
- final URL applicationUrl;
-
- if (isApplicationRunnerServlet) {
- final String[] URIparts = getApplicationRunnerURIs(request);
- final String applicationClassname = URIparts[4];
- applicationUrl = new URL(getApplicationUrl(request).toString()
- + applicationClassname + "/");
- try {
- applicationClass = classLoader.loadClass(applicationClassname);
- } catch (final ClassNotFoundException e) {
- throw new InstantiationException(
- "Failed to load application class: "
- + applicationClassname);
- }
- } else {
- applicationUrl = getApplicationUrl(request);
- }
-
- // Creates new application and start it
- try {
- final Application application = (Application) applicationClass
- .newInstance();
- context.addApplication(application);
-
- // Sets initial locale from the request
- application.setLocale(request.getLocale());
-
- // Starts application
- application.start(applicationUrl, applicationProperties, context);
-
- return application;
-
- } catch (final IllegalAccessException e) {
- throw e;
- } catch (final InstantiationException e) {
- throw e;
- }
- }
-
- /**
- * Ends the application.
- *
- * @param request
- * the HTTP request.
- * @param response
- * the HTTP response to write to.
- * @param application
- * the application to end.
- * @throws IOException
- * if the writing failed due to input/output error.
- */
- private void endApplication(HttpServletRequest request,
- HttpServletResponse response, Application application)
- throws IOException {
-
- String logoutUrl = application.getLogoutURL();
- if (logoutUrl == null) {
- logoutUrl = application.getURL().toString();
- }
-
- final HttpSession session = request.getSession();
- if (session != null) {
- WebApplicationContext.getApplicationContext(session)
- .removeApplication(application);
- }
-
- response.sendRedirect(response.encodeRedirectURL(logoutUrl));
- }
-
- /**
- * Gets the existing application or create a new one. Get a window within an
- * application based on the requested URI.
- *
- * @param request
- * the HTTP Request.
- * @param application
- * the Application to query for window.
- * @return Window matching the given URI or null if not found.
- * @throws ServletException
- * if an exception has occurred that interferes with the
- * servlet's normal operation.
- */
- private Window getApplicationWindow(HttpServletRequest request,
- Application application) throws ServletException {
-
- Window window = null;
-
- // Finds the window where the request is handled
- String path = request.getPathInfo();
-
- // Main window as the URI is empty
- if (path == null || path.length() == 0 || path.equals("/")) {
- window = application.getMainWindow();
- } else {
- String windowName = null;
- if (path.charAt(0) == '/') {
- path = path.substring(1);
- }
- final int index = path.indexOf('/');
- if (index < 0) {
- windowName = path;
- path = "";
- } else {
- windowName = path.substring(0, index);
- path = path.substring(index + 1);
- }
- window = application.getWindow(windowName);
-
- if (window == null) {
- // By default, we use main window
- window = application.getMainWindow();
- } else if (!window.isVisible()) {
- // Implicitly painting without actually invoking paint()
- window.requestRepaintRequests();
-
- // If the window is invisible send a blank page
- return null;
- }
- }
-
- return window;
- }
-
- /**
- * Gets relative location of a theme resource.
- *
- * @param theme
- * the Theme name.
- * @param resource
- * the Theme resource.
- * @return External URI specifying the resource
- */
- public String getResourceLocation(String theme, ThemeResource resource) {
-
- if (resourcePath == null) {
- return resource.getResourceId();
- }
- return resourcePath + theme + "/" + resource.getResourceId();
- }
-
- /**
- * Checks if web adapter is in debug mode. Extra output is generated to log
- * when debug mode is enabled.
- *
- * @param parameters
- * @return <code>true</code> if the web adapter is in debug mode. otherwise
- * <code>false</code>.
- */
- public boolean isDebugMode(Map parameters) {
- if (parameters != null) {
- final Object[] debug = (Object[]) parameters.get("debug");
- if (debug != null && !"false".equals(debug[0].toString())
- && !"false".equals(debugMode)) {
- return true;
- }
- }
- return "true".equals(debugMode);
- }
-
- /**
- * Implementation of ParameterHandler.ErrorEvent interface.
- */
- public class ParameterHandlerErrorImpl implements
- ParameterHandler.ErrorEvent {
-
- private ParameterHandler owner;
-
- private Throwable throwable;
-
- /**
- * Gets the contained throwable.
- *
- * @see com.itmill.toolkit.terminal.Terminal.ErrorEvent#getThrowable()
- */
- public Throwable getThrowable() {
- return throwable;
- }
-
- /**
- * Gets the source ParameterHandler.
- *
- * @see com.itmill.toolkit.terminal.ParameterHandler.ErrorEvent#getParameterHandler()
- */
- public ParameterHandler getParameterHandler() {
- return owner;
- }
-
- }
-
- /**
- * Implementation of URIHandler.ErrorEvent interface.
- */
- public class URIHandlerErrorImpl implements URIHandler.ErrorEvent {
-
- private final URIHandler owner;
-
- private final Throwable throwable;
-
- /**
- *
- * @param owner
- * @param throwable
- */
- private URIHandlerErrorImpl(URIHandler owner, Throwable throwable) {
- this.owner = owner;
- this.throwable = throwable;
- }
-
- /**
- * Gets the contained throwable.
- *
- * @see com.itmill.toolkit.terminal.Terminal.ErrorEvent#getThrowable()
- */
- public Throwable getThrowable() {
- return throwable;
- }
-
- /**
- * Gets the source URIHandler.
- *
- * @see com.itmill.toolkit.terminal.URIHandler.ErrorEvent#getURIHandler()
- */
- public URIHandler getURIHandler() {
- return owner;
- }
- }
-
- /**
- * Gets communication manager for an application.
- *
- * If this application has not been running before, new manager is created.
- *
- * @param application
- * @return CommunicationManager
- */
- private CommunicationManager getApplicationManager(Application application) {
- CommunicationManager mgr = (CommunicationManager) applicationToAjaxAppMgrMap
- .get(application);
-
- if (mgr == null) {
- // Creates new manager
- mgr = new CommunicationManager(application);
- applicationToAjaxAppMgrMap.put(application, mgr);
- }
- return mgr;
- }
-
- /**
- * Gets resource path using different implementations. Required to
- * supporting different servlet container implementations (application
- * servers).
- *
- * @param servletContext
- * @param path
- * the resource path.
- * @return the resource path.
- */
- protected static String getResourcePath(ServletContext servletContext,
- String path) {
- String resultPath = null;
- resultPath = servletContext.getRealPath(path);
- if (resultPath != null) {
- return resultPath;
- } else {
- try {
- final URL url = servletContext.getResource(path);
- resultPath = url.getFile();
- } catch (final Exception e) {
- // FIXME: Handle exception
- e.printStackTrace();
- }
- }
- return resultPath;
- }
-
- }
|