This enables the server to verify that the widgetset version match the servlet versiontags/7.0.0.alpha3
package com.vaadin; | |||||
import java.io.Serializable; | |||||
public class Version implements Serializable { | |||||
/** | |||||
* The version number of this release. For example "6.2.0". Always in the | |||||
* format "major.minor.revision[.build]". The build part is optional. All of | |||||
* major, minor, revision must be integers. | |||||
*/ | |||||
private static final String VERSION; | |||||
/** | |||||
* Major version number. For example 6 in 6.2.0. | |||||
*/ | |||||
private static final int VERSION_MAJOR; | |||||
/** | |||||
* Minor version number. For example 2 in 6.2.0. | |||||
*/ | |||||
private static final int VERSION_MINOR; | |||||
/** | |||||
* Version revision number. For example 0 in 6.2.0. | |||||
*/ | |||||
private static final int VERSION_REVISION; | |||||
/** | |||||
* Build identifier. For example "nightly-20091123-c9963" in | |||||
* 6.2.0.nightly-20091123-c9963. | |||||
*/ | |||||
private static final String VERSION_BUILD; | |||||
/* Initialize version numbers from string replaced by build-script. */ | |||||
static { | |||||
if ("@VERSION@".equals("@" + "VERSION" + "@")) { | |||||
VERSION = "9.9.9.INTERNAL-DEBUG-BUILD"; | |||||
} else { | |||||
VERSION = "@VERSION@"; | |||||
} | |||||
final String[] digits = VERSION.split("\\.", 4); | |||||
VERSION_MAJOR = Integer.parseInt(digits[0]); | |||||
VERSION_MINOR = Integer.parseInt(digits[1]); | |||||
VERSION_REVISION = Integer.parseInt(digits[2]); | |||||
if (digits.length == 4) { | |||||
VERSION_BUILD = digits[3]; | |||||
} else { | |||||
VERSION_BUILD = ""; | |||||
} | |||||
} | |||||
public static String getFullVersion() { | |||||
return VERSION; | |||||
} | |||||
public static int getMajorVersion() { | |||||
return VERSION_MAJOR; | |||||
} | |||||
public static int getMinorVersion() { | |||||
return VERSION_MINOR; | |||||
} | |||||
public static int getRevision() { | |||||
return VERSION_REVISION; | |||||
} | |||||
public static String getBuildIdentifier() { | |||||
return VERSION_BUILD; | |||||
} | |||||
} |
private Class<? extends ComponentConnector>[] classes = new Class[1024]; | private Class<? extends ComponentConnector>[] classes = new Class[1024]; | ||||
private boolean browserDetailsSent = false; | private boolean browserDetailsSent = false; | ||||
private boolean widgetsetVersionSent = false; | |||||
static// TODO consider to make this hashmap per application | static// TODO consider to make this hashmap per application | ||||
LinkedList<Command> callbacks = new LinkedList<Command>(); | LinkedList<Command> callbacks = new LinkedList<Command>(); | ||||
browserDetailsSent = true; | browserDetailsSent = true; | ||||
} | } | ||||
/** | |||||
* Checks whether the widget set version has been sent to the server. It is | |||||
* sent in the first UIDL request. | |||||
* | |||||
* @return <code>true</code> if browser information has already been sent | |||||
* | |||||
* @see ApplicationConnection#getNativeBrowserDetailsParameters(String) | |||||
*/ | |||||
public boolean isWidgetsetVersionSent() { | |||||
return widgetsetVersionSent; | |||||
} | |||||
/** | |||||
* Registers that the widget set version has been sent to the server. | |||||
*/ | |||||
public void setWidgetsetVersionSent() { | |||||
widgetsetVersionSent = true; | |||||
} | |||||
} | } |
// initial uidl request | // initial uidl request | ||||
String nativeBootstrapParameters = getNativeBrowserDetailsParameters(getConfiguration() | String nativeBootstrapParameters = getNativeBrowserDetailsParameters(getConfiguration() | ||||
.getRootPanelId()); | .getRootPanelId()); | ||||
String widgetsetVersion = ApplicationConfiguration.VERSION; | |||||
// TODO figure out how client and view size could be used better on | // TODO figure out how client and view size could be used better on | ||||
// server. screen size can be accessed via Browser object, but other | // server. screen size can be accessed via Browser object, but other | ||||
// values currently only via transaction listener. | // values currently only via transaction listener. | ||||
String parameters = "repaintAll=1&" + nativeBootstrapParameters | |||||
+ "&wsver=" + widgetsetVersion; | |||||
String parameters = "repaintAll=1&" + nativeBootstrapParameters; | |||||
return parameters; | return parameters; | ||||
} | } | ||||
} else { | } else { | ||||
extraParams = ""; | extraParams = ""; | ||||
} | } | ||||
if (!getConfiguration().isWidgetsetVersionSent()) { | |||||
if (!extraParams.isEmpty()) { | |||||
extraParams += "&"; | |||||
} | |||||
String widgetsetVersion = ApplicationConfiguration.VERSION; | |||||
extraParams += "wsver=" + widgetsetVersion; | |||||
getConfiguration().setWidgetsetVersionSent(); | |||||
} | |||||
makeUidlRequest(req.toString(), extraParams, forceSync); | makeUidlRequest(req.toString(), extraParams, forceSync); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Checks that the version reported by the client (widgetset) matches that | |||||
* of the server. | |||||
* | |||||
* @param request | |||||
*/ | |||||
private void checkWidgetsetVersion(WrappedRequest request) { | |||||
if (!AbstractApplicationServlet.VERSION.equals(request | |||||
.getParameter("wsver"))) { | |||||
logger.warning(String.format(WIDGETSET_MISMATCH_INFO, | |||||
AbstractApplicationServlet.VERSION, | |||||
request.getParameter("wsver"))); | |||||
} | |||||
} | |||||
private void checkProductionMode() { | private void checkProductionMode() { | ||||
// TODO Identical code in AbstractApplicationServlet -> refactor | // TODO Identical code in AbstractApplicationServlet -> refactor | ||||
// Check if the application is in production mode. | // Check if the application is in production mode. | ||||
return; | return; | ||||
} else if (requestType == RequestType.UIDL) { | } else if (requestType == RequestType.UIDL) { | ||||
// Handles AJAX UIDL requests | // Handles AJAX UIDL requests | ||||
if (isRepaintAll(request)) { | |||||
// warn if versions do not match | |||||
checkWidgetsetVersion(wrappedRequest); | |||||
} | |||||
applicationManager.handleUidlRequest(wrappedRequest, | applicationManager.handleUidlRequest(wrappedRequest, | ||||
wrappedResponse, portletWrapper, root); | wrappedResponse, portletWrapper, root); | ||||
return; | return; |
private static final Logger logger = Logger | private static final Logger logger = Logger | ||||
.getLogger(AbstractApplicationServlet.class.getName()); | .getLogger(AbstractApplicationServlet.class.getName()); | ||||
/** | |||||
* The version number of this release. For example "6.2.0". Always in the | |||||
* format "major.minor.revision[.build]". The build part is optional. All of | |||||
* major, minor, revision must be integers. | |||||
*/ | |||||
public static final String VERSION; | |||||
/** | |||||
* Major version number. For example 6 in 6.2.0. | |||||
*/ | |||||
public static final int VERSION_MAJOR; | |||||
/** | |||||
* Minor version number. For example 2 in 6.2.0. | |||||
*/ | |||||
public static final int VERSION_MINOR; | |||||
/** | |||||
* Version revision number. For example 0 in 6.2.0. | |||||
*/ | |||||
public static final int VERSION_REVISION; | |||||
/** | |||||
* Build identifier. For example "nightly-20091123-c9963" in | |||||
* 6.2.0.nightly-20091123-c9963. | |||||
*/ | |||||
public static final String VERSION_BUILD; | |||||
/* Initialize version numbers from string replaced by build-script. */ | |||||
static { | |||||
if ("@VERSION@".equals("@" + "VERSION" + "@")) { | |||||
VERSION = "9.9.9.INTERNAL-DEBUG-BUILD"; | |||||
} else { | |||||
VERSION = "@VERSION@"; | |||||
} | |||||
final String[] digits = VERSION.split("\\.", 4); | |||||
VERSION_MAJOR = Integer.parseInt(digits[0]); | |||||
VERSION_MINOR = Integer.parseInt(digits[1]); | |||||
VERSION_REVISION = Integer.parseInt(digits[2]); | |||||
if (digits.length == 4) { | |||||
VERSION_BUILD = digits[3]; | |||||
} else { | |||||
VERSION_BUILD = ""; | |||||
} | |||||
} | |||||
private Properties applicationProperties; | private Properties applicationProperties; | ||||
private boolean productionMode = false; | private boolean productionMode = false; | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Checks that the version reported by the client (widgetset) matches that | |||||
* of the server. | |||||
* | |||||
* @param request | |||||
*/ | |||||
private void checkWidgetsetVersion(HttpServletRequest request) { | |||||
if (!VERSION.equals(request.getParameter("wsver"))) { | |||||
logger.warning(String.format(WIDGETSET_MISMATCH_INFO, VERSION, | |||||
request.getParameter("wsver"))); | |||||
} | |||||
} | |||||
private void checkProductionMode() { | private void checkProductionMode() { | ||||
// Check if the application is in production mode. | // Check if the application is in production mode. | ||||
// We are in production mode if productionMode=true | // We are in production mode if productionMode=true | ||||
return; | return; | ||||
} | } | ||||
if (isRepaintAll(request)) { | |||||
// warn if versions do not match | |||||
checkWidgetsetVersion(request); | |||||
} | |||||
Application application = null; | Application application = null; | ||||
boolean transactionStarted = false; | boolean transactionStarted = false; | ||||
boolean requestStarted = false; | boolean requestStarted = false; |
import com.vaadin.Application; | import com.vaadin.Application; | ||||
import com.vaadin.Application.SystemMessages; | import com.vaadin.Application.SystemMessages; | ||||
import com.vaadin.RootRequiresMoreInformationException; | import com.vaadin.RootRequiresMoreInformationException; | ||||
import com.vaadin.Version; | |||||
import com.vaadin.external.json.JSONArray; | import com.vaadin.external.json.JSONArray; | ||||
import com.vaadin.external.json.JSONException; | import com.vaadin.external.json.JSONException; | ||||
import com.vaadin.external.json.JSONObject; | import com.vaadin.external.json.JSONObject; | ||||
WrappedResponse response, Callback callback, Root root) | WrappedResponse response, Callback callback, Root root) | ||||
throws IOException, InvalidUIDLSecurityKeyException { | throws IOException, InvalidUIDLSecurityKeyException { | ||||
checkWidgetsetVersion(request); | |||||
requestThemeName = request.getParameter("theme"); | requestThemeName = request.getParameter("theme"); | ||||
maxInactiveInterval = request.getSessionMaxInactiveInterval(); | maxInactiveInterval = request.getSessionMaxInactiveInterval(); | ||||
// repaint requested or session has timed out and new one is created | // repaint requested or session has timed out and new one is created | ||||
requestThemeName = null; | requestThemeName = null; | ||||
} | } | ||||
/** | |||||
* Checks that the version reported by the client (widgetset) matches that | |||||
* of the server. | |||||
* | |||||
* @param request | |||||
*/ | |||||
private void checkWidgetsetVersion(WrappedRequest request) { | |||||
String widgetsetVersion = request.getParameter("wsver"); | |||||
if (widgetsetVersion == null) { | |||||
// Only check when the widgetset version is reported. It is reported | |||||
// in the first UIDL request (not the initial request as it is a | |||||
// plain GET /) | |||||
return; | |||||
} | |||||
if (!Version.getFullVersion().equals(widgetsetVersion)) { | |||||
logger.warning(String.format(Constants.WIDGETSET_MISMATCH_INFO, | |||||
Version.getFullVersion(), widgetsetVersion)); | |||||
} | |||||
} | |||||
/** | /** | ||||
* Method called after the paint phase while still being synchronized on the | * Method called after the paint phase while still being synchronized on the | ||||
* application | * application |
import com.vaadin.Application; | import com.vaadin.Application; | ||||
import com.vaadin.RootRequiresMoreInformationException; | import com.vaadin.RootRequiresMoreInformationException; | ||||
import com.vaadin.Version; | |||||
import com.vaadin.external.json.JSONException; | import com.vaadin.external.json.JSONException; | ||||
import com.vaadin.external.json.JSONObject; | import com.vaadin.external.json.JSONObject; | ||||
import com.vaadin.terminal.DeploymentConfiguration; | import com.vaadin.terminal.DeploymentConfiguration; | ||||
} | } | ||||
JSONObject versionInfo = new JSONObject(); | JSONObject versionInfo = new JSONObject(); | ||||
versionInfo.put("vaadinVersion", AbstractApplicationServlet.VERSION); | |||||
versionInfo.put("vaadinVersion", Version.getFullVersion()); | |||||
versionInfo.put("applicationVersion", application.getVersion()); | versionInfo.put("applicationVersion", application.getVersion()); | ||||
appConfig.put("versionInfo", versionInfo); | appConfig.put("versionInfo", versionInfo); | ||||
} | } | ||||
Root root = context.getRoot(); | Root root = context.getRoot(); | ||||
String title = ((root == null || root.getCaption() == null) ? "Vaadin " | |||||
+ AbstractApplicationServlet.VERSION_MAJOR : root.getCaption()); | |||||
String title = ((root == null || root.getCaption() == null) ? "" : root | |||||
.getCaption()); | |||||
page.write("<title>" | page.write("<title>" | ||||
+ AbstractApplicationServlet.safeEscapeForHtml(title) | + AbstractApplicationServlet.safeEscapeForHtml(title) |