summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.classpath1
-rw-r--r--README.md16
-rw-r--r--WebContent/VAADIN/jquery.atmosphere.js553
-rw-r--r--WebContent/VAADIN/themes/base/base.scss5
-rw-r--r--WebContent/VAADIN/themes/base/debug/debug.scss11
-rw-r--r--WebContent/VAADIN/themes/chameleon/components/components.scss6
-rw-r--r--WebContent/VAADIN/themes/liferay/liferay.scss4
-rw-r--r--WebContent/VAADIN/themes/reindeer/reindeer.scss5
-rw-r--r--WebContent/VAADIN/themes/runo/runo.scss6
-rw-r--r--WebContent/VAADIN/themes/runo/window/img/dialog/maximize.pngbin0 -> 268 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/window/img/dialog/restore.pngbin0 -> 262 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/window/window.scss73
-rw-r--r--WebContent/VAADIN/vaadinPush.js.tpl6
-rw-r--r--WebContent/WEB-INF/liferay-display.xml2
-rw-r--r--WebContent/WEB-INF/liferay-portlet.xml6
-rw-r--r--WebContent/WEB-INF/portlet.xml116
-rw-r--r--WebContent/WEB-INF/web.xml232
-rw-r--r--all/build.xml249
-rw-r--r--all/ivy.xml17
-rw-r--r--build.xml131
-rw-r--r--build/common.xml80
-rwxr-xr-xbuild/ide.xml311
-rw-r--r--buildhelpers/build.xml93
-rw-r--r--buildhelpers/ivy.xml2
-rw-r--r--buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java9
-rw-r--r--client-compiled/build.xml280
-rw-r--r--client-compiled/ivy.xml4
-rw-r--r--client-compiler/build.xml108
-rw-r--r--client-compiler/ivy.xml106
-rw-r--r--client/build.xml117
-rwxr-xr-xclient/src/com/vaadin/DefaultWidgetSet.gwt.xml14
-rw-r--r--client/src/com/vaadin/Vaadin.gwt.xml28
-rw-r--r--client/src/com/vaadin/VaadinBrowserSpecificOverrides.gwt.xml101
-rw-r--r--client/src/com/vaadin/client/ApplicationConfiguration.java4
-rw-r--r--client/src/com/vaadin/client/ApplicationConnection.java111
-rw-r--r--client/src/com/vaadin/client/DateTimeService.java48
-rw-r--r--client/src/com/vaadin/client/LocaleService.java54
-rw-r--r--client/src/com/vaadin/client/Profiler.java245
-rw-r--r--client/src/com/vaadin/client/ResourceLoader.java6
-rw-r--r--client/src/com/vaadin/client/VConsole.java5
-rw-r--r--client/src/com/vaadin/client/VLoadingIndicator.java57
-rw-r--r--client/src/com/vaadin/client/communication/AtmospherePushConnection.java57
-rw-r--r--client/src/com/vaadin/client/communication/PushConnection.java6
-rw-r--r--client/src/com/vaadin/client/communication/StateChangeEvent.java25
-rw-r--r--client/src/com/vaadin/client/debug/internal/ProfilerSection.java336
-rw-r--r--client/src/com/vaadin/client/debug/internal/VDebugWindow.java13
-rw-r--r--client/src/com/vaadin/client/ui/AbstractComponentConnector.java6
-rw-r--r--client/src/com/vaadin/client/ui/VCalendar.java26
-rw-r--r--client/src/com/vaadin/client/ui/VCalendarPanel.java11
-rw-r--r--client/src/com/vaadin/client/ui/VOverlay.java18
-rw-r--r--client/src/com/vaadin/client/ui/VPopupView.java10
-rw-r--r--client/src/com/vaadin/client/ui/VProgressBar.java99
-rw-r--r--client/src/com/vaadin/client/ui/VProgressIndicator.java62
-rw-r--r--client/src/com/vaadin/client/ui/VRichTextArea.java165
-rw-r--r--client/src/com/vaadin/client/ui/VTabsheet.java82
-rw-r--r--client/src/com/vaadin/client/ui/VWindow.java20
-rw-r--r--client/src/com/vaadin/client/ui/calendar/CalendarConnector.java100
-rw-r--r--client/src/com/vaadin/client/ui/calendar/schedule/MonthEventLabel.java22
-rw-r--r--client/src/com/vaadin/client/ui/calendar/schedule/SimpleDayCell.java1
-rw-r--r--client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarDropHandler.java11
-rw-r--r--client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarMonthDropHandler.java5
-rw-r--r--client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarWeekDropHandler.java5
-rw-r--r--client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java7
-rw-r--r--client/src/com/vaadin/client/ui/progressindicator/ProgressBarConnector.java56
-rw-r--r--client/src/com/vaadin/client/ui/progressindicator/ProgressIndicatorConnector.java25
-rw-r--r--client/src/com/vaadin/client/ui/richtextarea/RichTextAreaConnector.java42
-rw-r--r--client/src/com/vaadin/client/ui/ui/UIConnector.java61
-rw-r--r--client/src/com/vaadin/client/ui/window/WindowConnector.java17
-rw-r--r--common.xml871
-rw-r--r--gwt-files.xml370
-rw-r--r--ivy-taskdefs.xml38
-rw-r--r--ivysettings.xml13
-rw-r--r--publish.xml127
-rw-r--r--push/build.xml136
-rw-r--r--push/ivy.xml18
-rw-r--r--push/src/org/atmosphere/cpr/AtmosphereFramework.java1779
-rw-r--r--server/build.xml112
-rw-r--r--server/ivy.xml12
-rw-r--r--server/src/com/vaadin/annotations/Push.java10
-rw-r--r--server/src/com/vaadin/annotations/VaadinServletConfiguration.java143
-rw-r--r--server/src/com/vaadin/data/util/LegacyPropertyHelper.java18
-rw-r--r--server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java120
-rw-r--r--server/src/com/vaadin/data/util/converter/Converter.java6
-rw-r--r--server/src/com/vaadin/data/util/converter/ConverterUtil.java50
-rw-r--r--server/src/com/vaadin/data/util/converter/DateToSqlDateConverter.java59
-rw-r--r--server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java2
-rw-r--r--server/src/com/vaadin/data/util/converter/StringToDoubleConverter.java67
-rw-r--r--server/src/com/vaadin/data/util/converter/StringToFloatConverter.java67
-rw-r--r--server/src/com/vaadin/data/util/converter/StringToIntegerConverter.java54
-rw-r--r--server/src/com/vaadin/data/util/converter/StringToNumberConverter.java69
-rw-r--r--server/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java2
-rw-r--r--server/src/com/vaadin/navigator/Navigator.java13
-rw-r--r--server/src/com/vaadin/server/AbstractClientConnector.java14
-rw-r--r--server/src/com/vaadin/server/ClientConnector.java26
-rw-r--r--server/src/com/vaadin/server/ComponentSizeValidator.java48
-rw-r--r--server/src/com/vaadin/server/ConnectorResourceHandler.java6
-rw-r--r--server/src/com/vaadin/server/Constants.java7
-rw-r--r--server/src/com/vaadin/server/DefaultDeploymentConfiguration.java56
-rw-r--r--server/src/com/vaadin/server/DragAndDropService.java10
-rw-r--r--server/src/com/vaadin/server/GlobalResourceHandler.java8
-rw-r--r--server/src/com/vaadin/server/JsonPaintTarget.java4
-rw-r--r--server/src/com/vaadin/server/LegacyApplication.java2
-rw-r--r--server/src/com/vaadin/server/LegacyCommunicationManager.java61
-rw-r--r--server/src/com/vaadin/server/LocaleService.java211
-rw-r--r--server/src/com/vaadin/server/Page.java111
-rw-r--r--server/src/com/vaadin/server/RequestHandler.java3
-rw-r--r--server/src/com/vaadin/server/UIProvider.java24
-rw-r--r--server/src/com/vaadin/server/VaadinPortlet.java35
-rw-r--r--server/src/com/vaadin/server/VaadinService.java114
-rw-r--r--server/src/com/vaadin/server/VaadinServlet.java83
-rw-r--r--server/src/com/vaadin/server/VaadinSession.java191
-rw-r--r--server/src/com/vaadin/server/communication/AtmospherePushConnection.java15
-rw-r--r--server/src/com/vaadin/server/communication/FileUploadHandler.java2
-rw-r--r--server/src/com/vaadin/server/communication/LocaleWriter.java204
-rw-r--r--server/src/com/vaadin/server/communication/MetadataWriter.java54
-rw-r--r--server/src/com/vaadin/server/communication/PushConnection.java4
-rw-r--r--server/src/com/vaadin/server/communication/PushHandler.java11
-rw-r--r--server/src/com/vaadin/server/communication/PushRequestHandler.java24
-rw-r--r--server/src/com/vaadin/server/communication/UIInitHandler.java10
-rw-r--r--server/src/com/vaadin/server/communication/UidlRequestHandler.java87
-rw-r--r--server/src/com/vaadin/server/communication/UidlWriter.java19
-rw-r--r--server/src/com/vaadin/ui/AbstractComponent.java9
-rw-r--r--server/src/com/vaadin/ui/AbstractField.java15
-rw-r--r--server/src/com/vaadin/ui/Calendar.java31
-rw-r--r--server/src/com/vaadin/ui/Label.java9
-rw-r--r--server/src/com/vaadin/ui/LegacyWindow.java2
-rw-r--r--server/src/com/vaadin/ui/LoginForm.java2
-rw-r--r--server/src/com/vaadin/ui/ProgressBar.java152
-rw-r--r--server/src/com/vaadin/ui/ProgressIndicator.java105
-rw-r--r--server/src/com/vaadin/ui/PushConfiguration.java282
-rw-r--r--server/src/com/vaadin/ui/UI.java238
-rw-r--r--server/src/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java2
-rw-r--r--server/src/com/vaadin/util/ConnectorHelper.java101
-rw-r--r--server/src/com/vaadin/util/CurrentInstance.java104
-rw-r--r--server/tests/src/com/vaadin/server/MockServletConfig.java86
-rw-r--r--server/tests/src/com/vaadin/server/MockServletContext.java304
-rw-r--r--server/tests/src/com/vaadin/server/VaadinServletConfigurationTest.java98
-rw-r--r--server/tests/src/com/vaadin/server/VaadinSessionTest.java23
-rw-r--r--server/tests/src/com/vaadin/tests/data/bean/AnotherTestEnum.java16
-rw-r--r--server/tests/src/com/vaadin/tests/data/bean/TestEnum.java16
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/TestAnyEnumToStringConverter.java130
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/TestSpecificEnumToStringConverter.java121
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java22
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValidators.java (renamed from server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValidators.java)2
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversions.java (renamed from server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java)2
-rw-r--r--server/tests/src/com/vaadin/ui/AbsFieldDataSourceLocaleChange.java (renamed from server/tests/src/com/vaadin/ui/AbstractFieldDataSourceLocaleChange.java)2
-rw-r--r--shared/build.xml106
-rw-r--r--shared/src/com/vaadin/shared/ApplicationConstants.java7
-rw-r--r--shared/src/com/vaadin/shared/communication/PushConstants.java46
-rw-r--r--shared/src/com/vaadin/shared/communication/SharedState.java6
-rw-r--r--shared/src/com/vaadin/shared/ui/calendar/CalendarEventId.java4
-rw-r--r--shared/src/com/vaadin/shared/ui/calendar/DateConstants.java4
-rw-r--r--shared/src/com/vaadin/shared/ui/progressindicator/ProgressBarState.java37
-rw-r--r--shared/src/com/vaadin/shared/ui/progressindicator/ProgressIndicatorState.java11
-rw-r--r--shared/src/com/vaadin/shared/ui/ui/DebugWindowClientRpc.java39
-rw-r--r--shared/src/com/vaadin/shared/ui/ui/DebugWindowServerRpc.java50
-rw-r--r--shared/src/com/vaadin/shared/ui/ui/Transport.java55
-rw-r--r--shared/src/com/vaadin/shared/ui/ui/UIState.java50
-rw-r--r--shared/src/com/vaadin/shared/ui/window/WindowServerRpc.java2
-rw-r--r--shared/src/com/vaadin/shared/util/SharedUtil.java4
-rw-r--r--theme-compiler/build.xml114
-rw-r--r--theme-compiler/ivy.xml8
-rw-r--r--theme-compiler/ivymodule/smartsprites-ivy-0.2.3-itmill.xml38
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java16
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj6
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/tree/ImportNode.java5
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java29
-rw-r--r--theme-compiler/tests/resources/automatic/css/nested-import.css5
-rw-r--r--theme-compiler/tests/resources/automatic/scss/nested-import.scss3
-rw-r--r--themes/build.xml214
-rw-r--r--themes/ivy.xml4
-rw-r--r--uitest/build.xml301
-rw-r--r--uitest/integration_base_files/base.xml253
-rw-r--r--uitest/integration_tests.xml1169
-rw-r--r--uitest/ivy.xml10
-rw-r--r--uitest/src/com/vaadin/tests/applicationcontext/CloseUI.java2
-rw-r--r--uitest/src/com/vaadin/tests/applicationcontext/UIRunSafelyThread.java2
-rw-r--r--uitest/src/com/vaadin/tests/components/AbstractComponentTestCase.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/CalendarDragAndDrop.html59
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/CalendarDragAndDrop.java123
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/CustomDateFormats.java1
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DateFieldLocale.java2
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DateFieldPrimaryStyleNames.html8
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.html121
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.java93
-rw-r--r--uitest/src/com/vaadin/tests/components/popupview/PopupViewAndFragment.html32
-rw-r--r--uitest/src/com/vaadin/tests/components/popupview/PopupViewAndFragment.java54
-rw-r--r--uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarGenericTest.java55
-rw-r--r--uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarPrimaryStyleName.html121
-rw-r--r--uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarTest.html62
-rw-r--r--uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarTest.java125
-rw-r--r--uitest/src/com/vaadin/tests/components/richtextarea/RichTextAreaUpdateWhileTyping.html42
-rw-r--r--uitest/src/com/vaadin/tests/components/richtextarea/RichTextAreaUpdateWhileTyping.java51
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableSqlContainer.html72
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableSqlContainer.java142
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/UiAccess.html166
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/UiAccess.java307
-rw-r--r--uitest/src/com/vaadin/tests/components/window/TooltipInWindow.html16
-rw-r--r--uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.html42
-rw-r--r--uitest/src/com/vaadin/tests/minitutorials/broadcastingmessages/Broadcaster.java33
-rw-r--r--uitest/src/com/vaadin/tests/minitutorials/broadcastingmessages/BroadcasterUI.java2
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPushStreaming.java12
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPushWebsocket.java8
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfiguration.html130
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfigurationTest.java102
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfigurator.java152
-rw-r--r--uitest/src/com/vaadin/tests/push/PushTransportAnnotation.html46
-rw-r--r--uitest/src/com/vaadin/tests/push/TogglePush.java13
-rw-r--r--uitest/src/com/vaadin/tests/themes/CSSInjectTest.html11
-rw-r--r--uitest/src/com/vaadin/tests/themes/CSSInjectTest.java24
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml15
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/TestingPushConnection.java8
-rw-r--r--uitest/test.xml412
-rw-r--r--uitest/vaadin-server.xml58
214 files changed, 10318 insertions, 6993 deletions
diff --git a/.classpath b/.classpath
index 381f0d280d..c6230a2c55 100644
--- a/.classpath
+++ b/.classpath
@@ -11,7 +11,6 @@
<classpathentry kind="src" path="uitest/src"/>
<classpathentry kind="src" path="buildhelpers/src"/>
<classpathentry kind="src" path="shared/src"/>
- <classpathentry kind="src" path="push/src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="owner.project.facets" value="java"/>
diff --git a/README.md b/README.md
index 5b56333cdb..808c1ef741 100644
--- a/README.md
+++ b/README.md
@@ -23,11 +23,12 @@ Start Eclipse
-------------
Start Eclipse and use the root checkout folder (the one containing the *vaadin*, *gwt* and *gwt-tools* folders) as the workspace folder
-Define Required Variables for the GWT Eclipse Projects
+Set up the Workspace and define required variables for projects
--------
-To be able to find all files, the GWT project requires you to define a couple of variables:
-
1. Open *Window* -> *Preferences* (Windows) or *Eclipse* -> *Preferences* (Mac)
+1. Go to *General* -> *Workspace*
+ 1. Set *Text file encoding* to *UTF-8*
+ 1. Set *New text file line delimiter* to *Unix*
1. Go to *General* -> *Workspace* -> *Linked Resources*
1. Add a new Path Variable **GWT_ROOT** referring to the gwt folder containing the gwt project
![GWT_ROOT](http://f.cl.ly/items/430q0H0z3t362Z1A1n3L/LinkedResources.png "Defining GWT_ROOT")
@@ -38,6 +39,15 @@ To be able to find all files, the GWT project requires you to define a couple of
![GWT_TOOLS](http://f.cl.ly/items/1k2Z1n2v0p0y3l0X0D1G/ClasspathVars.png "Defining GWT_TOOLS")
1. Go to Java -> Compiler
1. Check that the compliance level has been set to 1.6 (or higher)
+1. Go to XML -> XML Files -> Editor
+ 1. Ensure the settings are follows:
+<pre><code>Line width: 72
+Format comments: true
+Join lines: true
+Insert whitespace before closing empty end-tags: true
+Indent-using spaces: true
+Indentation size: 4
+</code></pre>
Import the Projects into the Workspace
------------
diff --git a/WebContent/VAADIN/jquery.atmosphere.js b/WebContent/VAADIN/jquery.atmosphere.js
index e9def6ae95..2b176668c1 100644
--- a/WebContent/VAADIN/jquery.atmosphere.js
+++ b/WebContent/VAADIN/jquery.atmosphere.js
@@ -49,7 +49,7 @@ jQuery.atmosphere = function() {
};
return {
- version : "1.0.12",
+ version : "1.0.13",
requests : [],
callbacks : [],
@@ -138,13 +138,16 @@ jQuery.atmosphere = function() {
*/
var _response = {
status: 200,
+ reasonPhrase : "OK",
responseBody : '',
+ messages : [],
headers : [],
state : "messageReceived",
transport : "polling",
error: null,
request : null,
partialMessage : "",
+ errorHandled: false,
id : 0
};
@@ -682,19 +685,21 @@ jQuery.atmosphere = function() {
_close();
};
- _response.request = request;
- var prevState = _response.state;
- _response.state = state;
- _response.status = 200;
- var prevTransport = _response.transport;
- _response.transport = transport;
+ if (_response.error == null) {
+ _response.request = request;
+ var prevState = _response.state;
+ _response.state = state;
+ _response.status = 200;
+ var prevTransport = _response.transport;
+ _response.transport = transport;
- var _body = _response.responseBody;
- _invokeCallback();
- _response.responseBody = _body;
+ var _body = _response.responseBody;
+ _invokeCallback();
+ _response.responseBody = _body;
- _response.state = prevState;
- _response.transport = prevTransport;
+ _response.state = prevState;
+ _response.transport = prevTransport;
+ }
}
/**
@@ -729,41 +734,43 @@ jQuery.atmosphere = function() {
type : rq.method,
dataType: "jsonp",
error : function(jqXHR, textStatus, errorThrown) {
- if (jqXHR.status < 300) {
+ _response.error = true;
+ if (jqXHR.status < 300 && rq.reconnect && _requestCount++ < rq.maxReconnectOnClose) {
_reconnect(_jqxhr, rq);
} else {
- _prepareCallback(textStatus, "error", jqXHR.status, rq.transport);
+ _onError(jqXHR.status, errorThrown);
}
},
jsonp : "jsonpTransport",
success: function(json) {
+ if (rq.reconnect) {
+ if (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest) {
+ _readHeaders(_jqxhr, rq);
- if (rq.reconnect && (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest)) {
- _readHeaders(_jqxhr, rq);
-
- if (!rq.executeCallbackBeforeReconnect) {
- _reconnect(_jqxhr, rq);
- }
+ if (!rq.executeCallbackBeforeReconnect) {
+ _reconnect(_jqxhr, rq);
+ }
- var msg = json.message;
- if (msg != null && typeof msg != 'string') {
- try {
- msg = jQuery.stringifyJSON(msg);
- } catch (err) {
- // The message was partial
+ var msg = json.message;
+ if (msg != null && typeof msg != 'string') {
+ try {
+ msg = jQuery.stringifyJSON(msg);
+ } catch (err) {
+ // The message was partial
+ }
}
- }
- if (_handleProtocol(rq, msg)) {
- _prepareCallback(msg, "messageReceived", 200, rq.transport);
- }
+ if (_handleProtocol(rq, msg)) {
+ _prepareCallback(msg, "messageReceived", 200, rq.transport);
+ }
- if (rq.executeCallbackBeforeReconnect) {
- _reconnect(_jqxhr, rq);
+ if (rq.executeCallbackBeforeReconnect) {
+ _reconnect(_jqxhr, rq);
+ }
+ } else {
+ jQuery.atmosphere.log(_request.logLevel, ["JSONP reconnect maximum try reached " + _request.requestCount]);
+ _onError(0, "maxRequest reached");
}
- } else {
- jQuery.atmosphere.log(_request.logLevel, ["JSONP reconnect maximum try reached " + _request.requestCount]);
- _onError();
}
},
data : rq.data,
@@ -802,29 +809,32 @@ jQuery.atmosphere = function() {
url : url,
type : rq.method,
error : function(jqXHR, textStatus, errorThrown) {
+ _response.error = true;
if (jqXHR.status < 300) {
_reconnect(_jqxhr, rq);
} else {
- _prepareCallback(textStatus, "error", jqXHR.status, rq.transport);
+ _onError(jqXHR.status, errorThrown);
}
},
success: function(data, textStatus, jqXHR) {
- if (rq.reconnect && (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest)) {
- if (!rq.executeCallbackBeforeReconnect) {
- _reconnect(_jqxhr, rq);
- }
+ if (rq.reconnect) {
+ if (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest) {
+ if (!rq.executeCallbackBeforeReconnect) {
+ _reconnect(_jqxhr, rq);
+ }
- if (_handleProtocol(rq, data)) {
- _prepareCallback(data, "messageReceived", 200, rq.transport);
- }
+ if (_handleProtocol(rq, data)) {
+ _prepareCallback(data, "messageReceived", 200, rq.transport);
+ }
- if (rq.executeCallbackBeforeReconnect) {
- _reconnect(_jqxhr, rq);
+ if (rq.executeCallbackBeforeReconnect) {
+ _reconnect(_jqxhr, rq);
+ }
+ } else {
+ jQuery.atmosphere.log(_request.logLevel, ["AJAX reconnect maximum try reached " + _request.requestCount]);
+ _onError(0, "maxRequest reached");
}
- } else {
- jQuery.atmosphere.log(_request.logLevel, ["AJAX reconnect maximum try reached " + _request.requestCount]);
- _onError();
}
},
beforeSend : function(jqXHR) {
@@ -912,7 +922,14 @@ jQuery.atmosphere = function() {
}
return;
}
- _sse = new EventSource(location, {withCredentials: _request.withCredentials});
+
+ try {
+ _sse = new EventSource(location, {withCredentials: _request.withCredentials});
+ } catch (e) {
+ _onError(0, e);
+ _reconnectWithFallbackTransport("SSE failed. Downgrading to fallback transport and resending");
+ return;
+ }
if (_request.connectTimeout > 0) {
_request.id = setTimeout(function() {
@@ -944,31 +961,25 @@ jQuery.atmosphere = function() {
return;
}
- if (!_handleProtocol(_request, message.data)) return;
+ var data = message.data;
+
+ if (!_handleProtocol(_request, data)) return;
_response.state = 'messageReceived';
_response.status = 200;
- var message = message.data;
- var skipCallbackInvocation = _trackMessageSize(message, _request, _response);
-
- if (jQuery.trim(message).length == 0) {
- skipCallbackInvocation = true;
- }
-
+ var skipCallbackInvocation = _trackMessageSize(data, _request, _response);
if (!skipCallbackInvocation) {
_invokeCallback();
_response.responseBody = '';
+ _response.messages = [];
}
};
_sse.onerror = function(message) {
clearTimeout(_request.id);
- _response.state = 'closed';
- _response.responseBody = "";
- _response.status = !sseOpened ? 501 : 200;
- _invokeCallback();
+ _invokeClose(sseOpened);
_clearState();
if (_abordingConnection) {
@@ -981,9 +992,10 @@ jQuery.atmosphere = function() {
_executeSSE(true);
}, _request.reconnectInterval);
_response.responseBody = "";
+ _response.messages = [];
} else {
jQuery.atmosphere.log(_request.logLevel, ["SSE reconnect maximum try reached " + _requestCount]);
- _onError();
+ _onError(0, "maxReconnectOnClose reached");
}
}
};
@@ -1025,7 +1037,6 @@ jQuery.atmosphere = function() {
}
_websocket = _getWebSocket(location);
-
if (_request.connectTimeout > 0) {
_request.id = setTimeout(function() {
if (!webSocketOpened) {
@@ -1062,6 +1073,7 @@ jQuery.atmosphere = function() {
}
webSocketOpened = true;
+ _websocket.webSocketOpened = webSocketOpened;
if (_request.method == 'POST') {
_response.state = "messageReceived";
@@ -1078,17 +1090,18 @@ jQuery.atmosphere = function() {
}, _request.reconnectInterval)
}, _request.timeout);
- if (!_handleProtocol(_request, message.data)) return;
+ var data = message.data;
+
+ if (!_handleProtocol(_request, data)) return;
_response.state = 'messageReceived';
_response.status = 200;
- var message = message.data;
- var skipCallbackInvocation = _trackMessageSize(message, _request, _response);
-
+ var skipCallbackInvocation = _trackMessageSize(data, _request, _response);
if (!skipCallbackInvocation) {
_invokeCallback();
_response.responseBody = '';
+ _response.messages = [];
}
};
@@ -1098,6 +1111,7 @@ jQuery.atmosphere = function() {
_websocket.onclose = function(message) {
if (closed) return
+ clearTimeout(_request.id);
var reason = message.reason;
if (reason === "") {
@@ -1133,12 +1147,7 @@ jQuery.atmosphere = function() {
jQuery.atmosphere.warn("Websocket closed, reason: " + reason);
jQuery.atmosphere.warn("Websocket closed, wasClean: " + message.wasClean);
- _response.state = 'closed';
- _response.responseBody = "";
- _response.status = !webSocketOpened ? 501 : 200;
- _invokeCallback();
- clearTimeout(_request.id);
-
+ _invokeClose(webSocketOpened);
closed = true;
if (_abordingConnection) {
@@ -1151,12 +1160,13 @@ jQuery.atmosphere = function() {
if (_request.reconnect && _requestCount++ < _request.maxReconnectOnClose) {
_request.id = setTimeout(function() {
_response.responseBody = "";
+ _response.messages = [];
_executeWebSocket(true);
}, _request.reconnectInterval);
} else {
jQuery.atmosphere.log(_request.logLevel, ["Websocket reconnect maximum try reached " + _requestCount]);
jQuery.atmosphere.warn("Websocket error, reason: " + message.reason);
- _onError();
+ _onError(0, "maxReconnectOnClose reached");
}
}
};
@@ -1164,22 +1174,25 @@ jQuery.atmosphere = function() {
function _handleProtocol(request, message) {
// The first messages is always the uuid.
- if (request.enableProtocol && request.firstMessage) {
+ if (jQuery.trim(message) != 0 && request.enableProtocol && request.firstMessage) {
request.firstMessage = false;
var messages = message.split(request.messageDelimiter);
- request.uuid = messages[0];
- request.stime = messages[1];
+ var pos = messages.length == 2 ? 0 : 1;
+ request.uuid = jQuery.trim(messages[pos]);
+ request.stime = jQuery.trim(messages[pos + 1]);
return false;
}
return true;
}
- function _onError() {
+ function _onError(code, reason) {
_clearState();
_response.state = 'error';
+ _response.reasonPhrase = reason;
_response.responseBody = "";
- _response.status = 500;
+ _response.messages = [];
+ _response.status = code;
_invokeCallback();
}
@@ -1203,7 +1216,7 @@ jQuery.atmosphere = function() {
var messageLength = 0;
var messageStart = message.indexOf(request.messageDelimiter);
while (messageStart != -1) {
- messageLength = message.substring(messageLength, messageStart);
+ messageLength = jQuery.trim(message.substring(messageLength, messageStart));
message = message.substring(messageStart + request.messageDelimiter.length, message.length);
if (message.length == 0 || message.length < messageLength) break;
@@ -1220,8 +1233,11 @@ jQuery.atmosphere = function() {
if (messages.length != 0) {
response.responseBody = messages.join(request.messageDelimiter);
+ response.messages = messages;
return false;
} else {
+ response.responseBody = "";
+ response.messages = [];
return true;
}
} else {
@@ -1246,15 +1262,16 @@ jQuery.atmosphere = function() {
}
_request.transport = _request.fallbackTransport;
- var reconnect = _request.reconnect && _requestCount++ < _request.maxReconnectOnClose;
- if (reconnect && _request.transport != 'none' || _request.transport == null) {
+ var reconnectInterval = _request.connectTimeout == -1 ? 0 : _request.connectTimeout;
+ if (_request.reconnect && _request.transport != 'none' || _request.transport == null) {
_request.method = _request.fallbackMethod;
_response.transport = _request.fallbackTransport;
+ _request.fallbackTransport = 'none';
_request.id = setTimeout(function() {
_execute();
- }, _request.reconnectInterval);
- } else if (!reconnect) {
- _onError();
+ }, reconnectInterval);
+ } else {
+ _onError(500, "Unable to reconnect with fallback transport");
}
}
@@ -1357,6 +1374,9 @@ jQuery.atmosphere = function() {
rq = request;
}
+ rq.lastIndex = 0;
+ rq.readyState = 0;
+
// CORS fake using JSONP
if ((rq.transport == 'jsonp') || ((rq.enableXDR) && (jQuery.atmosphere.checkCORSSupport()))) {
_jsonp(rq);
@@ -1380,6 +1400,14 @@ jQuery.atmosphere = function() {
}
}
+ var reconnectF = function() {
+ if (rq.reconnect && _requestCount++ < rq.maxReconnectOnClose) {
+ _reconnect(ajaxRequest, rq, true);
+ } else {
+ _onError(0, "maxReconnectOnClose reached");
+ }
+ };
+
if (rq.reconnect && ( rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest)) {
var ajaxRequest = _buildAjaxRequest();
_doRequest(ajaxRequest, rq, true);
@@ -1392,162 +1420,129 @@ jQuery.atmosphere = function() {
_response.transport = rq.transport;
}
- if (!jQuery.browser.msie) {
- ajaxRequest.onerror = function() {
- try {
- _response.status = XMLHttpRequest.status;
- } catch(e) {
- _response.status = 500;
- }
+ ajaxRequest.onabort = function () {
+ _invokeClose(true);
+ };
- if (!_response.status) {
- _response.status = 500;
- }
- _clearState();
+ ajaxRequest.onerror = function() {
+ _response.error = true;
+ try {
+ _response.status = XMLHttpRequest.status;
+ } catch(e) {
+ _response.status = 500;
+ }
- if (rq.reconnect) {
- _reconnect(ajaxRequest, rq, true);
- } else {
- _onError();
- }
- };
- }
+ if (!_response.status) {
+ _response.status = 500;
+ }
+ _clearState();
+ if (!_response.errorHandled) {
+ reconnectF();
+ }
+ };
ajaxRequest.onreadystatechange = function() {
if (_abordingConnection) {
return;
}
-
+ _response.error = null;
var skipCallbackInvocation = false;
var update = false;
- // Remote server disconnected us, reconnect.
- if (rq.transport == 'streaming'
+
+ // Opera doesn't call onerror if the server disconnect.
+ if (jQuery.browser.opera
+ && rq.transport == 'streaming'
&& rq.readyState > 2
&& ajaxRequest.readyState == 4) {
rq.readyState = 0;
rq.lastIndex = 0;
- _reconnect(ajaxRequest, rq, true);
+ reconnectF();
return;
}
rq.readyState = ajaxRequest.readyState;
- if (ajaxRequest.readyState == 4) {
- if (jQuery.browser.msie) {
- update = true;
- } else if (rq.transport == 'streaming') {
- update = true;
- } else if (rq.transport == 'long-polling') {
- update = true;
- clearTimeout(rq.id);
- }
- } else if (rq.transport == 'streaming' && jQuery.browser.msie && ajaxRequest.readyState >= 3) {
+ if (rq.transport == 'streaming' && ajaxRequest.readyState >= 3) {
update = true;
- } else if (!jQuery.browser.msie && ajaxRequest.readyState == 3 && ajaxRequest.status == 200 && rq.transport != 'long-polling') {
+ } else if (rq.transport == 'long-polling' && ajaxRequest.readyState === 4) {
update = true;
- } else {
- clearTimeout(rq.id);
}
+ clearTimeout(rq.id);
if (update) {
+ // MSIE 9 and lower status can be higher than 1000, Chrome can be 0
+ var status = 0;
+ if (ajaxRequest.readyState != 0) {
+ status = ajaxRequest.status > 1000 ? 0 : ajaxRequest.status;
+ }
+
+ if (status >= 300 || status == 0) {
+ // Prevent onerror callback to be called
+ _response.errorHandled = true;
+ _clearState();
+ reconnectF();
+ return;
+ }
var responseText = ajaxRequest.responseText;
- // MSIE status can be higher than 1000, Chrome can be 0
- if (ajaxRequest.status >= 500 || ajaxRequest.status == 0) {
- if (rq.reconnect) {
- _reconnect(ajaxRequest, rq, true);
- } else {
- _onError();
+ if (jQuery.trim(responseText.length) == 0 && rq.transport == 'long-polling') {
+ // For browser that aren't support onabort
+ if (!ajaxRequest.hasData) {
+ reconnectF();
+ } else {
+ ajaxRequest.hasData = false;
}
return;
}
+ ajaxRequest.hasData = true;
_readHeaders(ajaxRequest, _request);
if (rq.transport == 'streaming') {
- var text = responseText.substring(rq.lastIndex, responseText.length);
- _response.isJunkEnded = true;
-
- //fix junk is comming in parts
- if (!_response.junkFull && (text.indexOf("<!-- Welcome to the Atmosphere Framework.") == -1 || text.indexOf("<!-- EOD -->") == -1)) {
- return;
- }
- _response.junkFull = true;
-
- //if it's the start and we see the junk start
- //fix for reconnecting on chrome - junk is comming in parts
- if (rq.lastIndex == 0 && text.indexOf("<!-- Welcome to the Atmosphere Framework.") != -1 && text.indexOf("<!-- EOD -->") != -1) {
- _response.isJunkEnded = false;
- }
-
- if (!_response.isJunkEnded) {
- var endOfJunk = "<!-- EOD -->";
- var endOfJunkLength = endOfJunk.length;
- var junkEnd = text.indexOf(endOfJunk) + endOfJunkLength;
-
- if (junkEnd > endOfJunkLength && junkEnd != text.length) {
- _response.responseBody = text.substring(junkEnd);
- rq.lastIndex = responseText.length;
- if (!_handleProtocol( _request, _response.responseBody)) {
- return;
- }
- skipCallbackInvocation = _trackMessageSize(_response.responseBody, rq, _response);
- } else {
- skipCallbackInvocation = true;
- }
- } else {
+ if (!jQuery.browser.opera) {
var message = responseText.substring(rq.lastIndex, responseText.length);
rq.lastIndex = responseText.length;
- if (!_handleProtocol( _request, message)) {
+ if (!_handleProtocol(_request, message)) {
return;
}
skipCallbackInvocation = _trackMessageSize(message, rq, _response);
- }
- rq.lastIndex = responseText.length;
-
- if (jQuery.browser.opera) {
- jQuery.atmosphere.iterate(function() {
- if (ajaxRequest.responseText.length > rq.lastIndex) {
+ } else {
+ jQuery.atmosphere.iterate(function () {
+ if (_response.status != 500 && ajaxRequest.responseText.length > rq.lastIndex) {
try {
_response.status = ajaxRequest.status;
- _response.headers = parseHeaders(ajaxRequest.getAllResponseHeaders());
-
- _readHeaders(ajaxRequest, _request);
}
- catch(e) {
+ catch (e) {
_response.status = 404;
}
_response.state = "messageReceived";
- _response.responseBody = ajaxRequest.responseText.substring(rq.lastIndex);
+
+ var message = ajaxRequest.responseText.substring(rq.lastIndex);
rq.lastIndex = ajaxRequest.responseText.length;
+ if (_handleProtocol(_request, message)) {
+ skipCallbackInvocation = _trackMessageSize(message, rq, _response);
+ if (!skipCallbackInvocation) {
+ _invokeCallback();
+ }
- if (!_handleProtocol( _request, _response.responseBody)) {
- _reconnect(ajaxRequest, rq, false);
- return;
- }
- _invokeCallback();
- if ((rq.transport == 'streaming') && (ajaxRequest.responseText.length > rq.maxStreamingLength)) {
- // Close and reopen connection on large data received
- _clearState();
- _doRequest(_buildAjaxRequest(), rq, true);
+ _verifyStreamingLength(ajaxRequest, rq);
}
+ } else if (_response.status > 400){
+ rq.lastIndex = ajaxRequest.responseText.length;
+ return false;
}
}, 0);
}
-
- if (skipCallbackInvocation) {
- return;
- }
} else {
if (!_handleProtocol( _request, responseText)) {
_reconnect(ajaxRequest, rq, false);
return;
}
- _trackMessageSize(responseText, rq, _response);
+ skipCallbackInvocation = _trackMessageSize(responseText, rq, _response);
rq.lastIndex = responseText.length;
}
@@ -1575,17 +1570,15 @@ jQuery.atmosphere = function() {
jQuery.atmosphere.log(rq.logLevel, ["parent.callback no longer supported with 0.8 version and up. Please upgrade"]);
}
- _invokeCallback();
+ if (!skipCallbackInvocation) {
+ _invokeCallback();
+ }
if (rq.executeCallbackBeforeReconnect) {
_reconnect(ajaxRequest, rq, false);
}
- if ((rq.transport == 'streaming') && (responseText.length > rq.maxStreamingLength)) {
- // Close and reopen connection on large data received
- _clearState();
- _doRequest(_buildAjaxRequest(), rq, true);
- }
+ _verifyStreamingLength(ajaxRequest, rq);
}
};
ajaxRequest.send(rq.data);
@@ -1606,7 +1599,7 @@ jQuery.atmosphere = function() {
if (rq.logLevel == 'debug') {
jQuery.atmosphere.log(rq.logLevel, ["Max re-connection reached."]);
}
- _onError();
+ _onError(0, "maxRequest reached");
}
}
@@ -1651,13 +1644,13 @@ jQuery.atmosphere = function() {
if (request.trackMessageLength) {
ajaxRequest.setRequestHeader("X-Atmosphere-TrackMessageSize", "true")
}
-
- if (request.contentType != '') {
- ajaxRequest.setRequestHeader("Content-Type", request.contentType);
- }
ajaxRequest.setRequestHeader("X-Atmosphere-tracking-id", request.uuid);
}
+ if (request.contentType != '') {
+ ajaxRequest.setRequestHeader("Content-Type", request.contentType);
+ }
+
jQuery.each(request.headers, function(name, value) {
var h = jQuery.isFunction(value) ? value.call(this, ajaxRequest, request, create, _response) : value;
if (h != null) {
@@ -1667,17 +1660,26 @@ jQuery.atmosphere = function() {
}
function _reconnect(ajaxRequest, request, force) {
- var reconnect = request.reconnect && _requestCount++ < request.maxReconnectOnClose;
+ if (force || request.transport != 'streaming') {
+ if ( request.reconnect || (request.suspend && _subscribed)) {
+ var status = 0;
+ if (ajaxRequest.readyState != 0) {
+ status = ajaxRequest.status > 1000 ? 0 : ajaxRequest.status;
+ }
+ _response.status = status == 0 ? 204 : status;
+ _response.reason = status == 0 ? "Server resumed the connection or down." : "OK";
- if (reconnect && force || (request.suspend && ajaxRequest.status == 200 && request.transport != 'streaming' && _subscribed)) {
- if (request.reconnect) {
- _open('re-opening', request.transport, request);
- request.id = setTimeout(function() {
- _executeRequest();
- }, request.reconnectInterval);
+ var reconnectInterval = (request.connectTimeout == -1) ? 0 : request.connectTimeout;
+
+ // Reconnect immedialtely
+ if (!force) {
+ request.id = setTimeout(function () {
+ _executeRequest(request);
+ }, reconnectInterval);
+ } else {
+ _executeRequest(request);
+ }
}
- } else if (!reconnect) {
- _onError();
}
}
@@ -1702,21 +1704,6 @@ jQuery.atmosphere = function() {
var lastIndex = 0;
var xdrCallback = function (xdr) {
var responseBody = xdr.responseText;
- var isJunkEnded = false;
-
- if (responseBody.indexOf("<!-- Welcome to the Atmosphere Framework.") != -1) {
- isJunkEnded = true;
- }
-
- if (isJunkEnded) {
- var endOfJunk = "<!-- EOD -->";
- var endOfJunkLenght = endOfJunk.length;
- var junkEnd = responseBody.indexOf(endOfJunk);
- if (junkEnd !== -1) {
- responseBody = responseBody.substring(junkEnd + endOfJunkLenght + lastIndex);
- lastIndex += responseBody.length;
- }
- }
if (!_handleProtocol(request, responseBody)) return;
@@ -1747,10 +1734,8 @@ jQuery.atmosphere = function() {
xdr.onerror = function() {
// If the server doesn't send anything back to XDR will fail with polling
if (rq.transport != 'polling') {
- _prepareCallback(xdr.responseText, "error", 500, transport);
+ _reconnect(xdr, rq, false);
}
-
- _reconnect(xdr, rq, false);
};
// Handles close event
@@ -1873,23 +1858,7 @@ jQuery.atmosphere = function() {
clone.appendChild(cdoc.createTextNode("."));
var text = clone.innerText;
- var isJunkEnded = true;
-
- if (text.indexOf("<!-- Welcome to the Atmosphere Framework.") == -1) {
- isJunkEnded = false;
- }
-
- if (isJunkEnded) {
- var endOfJunk = "<!-- EOD -->";
- var endOfJunkLength = endOfJunk.length;
- var junkEnd = text.indexOf(endOfJunk) + endOfJunkLength;
-
- text = text.substring(junkEnd);
- }
-
text = text.substring(0, text.length - 1);
-
- _handleProtocol(rq, text);
return text;
};
@@ -1918,11 +1887,14 @@ jQuery.atmosphere = function() {
var text = readResponse();
if (text.length > rq.lastIndex) {
_response.status = 200;
+ _response.error = null;
- // Empties response every time that it is handled
- res.innerText = "";
- _prepareCallback(text, "messageReceived", 200, rq.transport);
-
+ var message = text;
+ if (message.length != 0 && _handleProtocol(rq, message)) {
+ // Empties response every time that it is handled
+ res.innerText = "";
+ _prepareCallback(message, "messageReceived", 200, rq.transport);
+ }
rq.lastIndex = 0;
}
@@ -1938,12 +1910,13 @@ jQuery.atmosphere = function() {
return false;
} catch (err) {
+ _response.error = true;
if (_requestCount++ < rq.maxReconnectOnClose) {
rq.id = setTimeout(function() {
_ieStreaming(rq);
}, rq.reconnectInterval);
} else {
- _onError();
+ _onError(0, "maxReconnectOnClose reached");
}
doc.execCommand("Stop");
doc.close();
@@ -2095,6 +2068,7 @@ jQuery.atmosphere = function() {
attachHeadersAsQueryString: true,
enableXDR: _request.enableXDR,
uuid : _request.uuid,
+ messageDelimiter : '|',
enableProtocol : false,
maxReconnectOnClose : _request.maxReconnectOnClose
};
@@ -2147,11 +2121,11 @@ jQuery.atmosphere = function() {
}
function _prepareCallback(messageBody, state, errorCode, transport) {
- _response.responseBody = messageBody;
+
if (state == "messageReceived") {
- if (_trackMessageSize(messageBody, _request, _response)) {
- return;
- }
+ if (_trackMessageSize(messageBody, _request, _response)) return;
+ } else {
+ _response.responseBody = messageBody;
}
_response.transport = transport;
@@ -2225,6 +2199,14 @@ jQuery.atmosphere = function() {
}
}
+ function _invokeClose(wasOpen) {
+ _response.state = 'closed';
+ _response.responseBody = "";
+ _response.messages = [];
+ _response.status = !wasOpen ? 501 : 200;
+ _invokeCallback();
+ }
+
/**
* Invoke request callbacks.
*
@@ -2242,7 +2224,7 @@ jQuery.atmosphere = function() {
_request.reconnect = _request.mrequest;
var messages = (typeof(_response.responseBody) == 'string' && _request.trackMessageLength) ?
- _response.responseBody.split(_request.messageDelimiter) : new Array(_response.responseBody);
+ (_response.messages.length>0 ? _response.messages : ['']) : new Array(_response.responseBody);
for (var i = 0; i < messages.length; i++) {
if (messages.length > 1 && messages[i].length == 0) {
@@ -2250,13 +2232,8 @@ jQuery.atmosphere = function() {
}
_response.responseBody = jQuery.trim(messages[i]);
- // Ugly see issue 400.
- if (_response.responseBody.length == 0 && _response.transport == 'streaming' && _response.state == "messageReceived") {
- var ua = navigator.userAgent.toLowerCase();
- var isAndroid = ua.indexOf("android") > -1;
- if (isAndroid) {
- continue;
- }
+ if (_response.responseBody.length == 0 && _response.state == "messageReceived") {
+ continue;
}
_invokeFunction(_response);
@@ -2289,16 +2266,52 @@ jQuery.atmosphere = function() {
}
/**
+ *
+ * @private
+ */
+ function _verifyStreamingLength(ajaxRequest, rq){
+ // Wait to be sure we have the full message before closing.
+ if (_response.partialMessage == "" &&
+ (rq.transport == 'streaming') &&
+ (ajaxRequest.responseText.length > rq.maxStreamingLength)) {
+ _response.messages = [];
+ _invokeClose(true);
+ _disconnect();
+ _clearState();
+ _reconnect(ajaxRequest, rq, true);
+ }
+ }
+
+ /**
+ * Disconnect
+ * @private
+ */
+ function _disconnect() {
+ if (_request.enableProtocol) {
+ var query = "X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=" + _request.uuid;
+ var url = _request.url.replace(/([?&])_=[^&]*/, query);
+ url = url + (url === _request.url ? (/\?/.test(_request.url) ? "&" : "?") + query : "");
+
+ if (_request.connectTimeout > -1) {
+ jQuery.ajax({url: url, async: false, timeout: _request.connectTimeout});
+ } else {
+ jQuery.ajax({url: url, async: false});
+ }
+ }
+ }
+
+ /**
* Close request.
*
* @private
*/
function _close() {
- _abordingConnection = true;
_request.reconnect = false;
+ _abordingConnection = true;
_response.request = _request;
_response.state = 'unsubscribe';
_response.responseBody = "";
+ _response.messages = [];
_response.status = 408;
_invokeCallback();
@@ -2319,7 +2332,9 @@ jQuery.atmosphere = function() {
_activeRequest = null;
}
if (_websocket != null) {
- _websocket.close();
+ if (_websocket.webSocketOpened) {
+ _websocket.close();
+ }
_websocket = null;
}
if (_sse != null) {
@@ -2343,7 +2358,7 @@ jQuery.atmosphere = function() {
if (_localStorageService != null) {
_localStorageService.close();
}
- }
+ };
this.subscribe = function(options) {
_subscribe(options);
@@ -2362,6 +2377,10 @@ jQuery.atmosphere = function() {
_close();
};
+ this.disconnect = function () {
+ _disconnect();
+ };
+
this.getUrl = function() {
return _request.url;
};
@@ -2421,10 +2440,8 @@ jQuery.atmosphere = function() {
var requestsClone = [].concat(jQuery.atmosphere.requests);
for (var i = 0; i < requestsClone.length; i++) {
var rq = requestsClone[i];
+ rq.disconnect();
rq.close();
- if (rq.enableProtocol()) {
- jQuery.ajax({url: this._closeUrl(rq), async:false});
- }
clearTimeout(rq.response.request.id);
}
}
@@ -2432,12 +2449,6 @@ jQuery.atmosphere = function() {
jQuery.atmosphere.callbacks = [];
},
- _closeUrl : function(rq) {
- var query = "X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=" + rq.getUUID();
- var url = rq.getUrl().replace(/([?&])_=[^&]*/, query);
- return url + (url === rq.getUrl() ? (/\?/.test(rq.getUrl()) ? "&" : "?") + query : "");
- },
-
unsubscribeUrl: function(url) {
var idx = -1;
if (jQuery.atmosphere.requests.length > 0) {
@@ -2446,10 +2457,8 @@ jQuery.atmosphere = function() {
// Suppose you can subscribe once to an url
if (rq.getUrl() == url) {
+ rq.disconnect();
rq.close();
- if (rq.enableProtocol()) {
- jQuery.ajax({url :this._closeUrl(rq), async:false});
- }
clearTimeout(rq.response.request.id);
idx = i;
break;
@@ -2643,8 +2652,8 @@ jQuery.atmosphere = function() {
/*
* jQuery stringifyJSON
* http://github.com/flowersinthesand/jquery-stringifyJSON
- *
- * Copyright 2011, Donghwan Kim
+ *
+ * Copyright 2011, Donghwan Kim
* Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0
*/
@@ -2728,4 +2737,4 @@ jQuery.atmosphere = function() {
return str("", {"": value});
};
-}(jQuery)); \ No newline at end of file
+}(jQuery));
diff --git a/WebContent/VAADIN/themes/base/base.scss b/WebContent/VAADIN/themes/base/base.scss
index 83e463fa00..514579830d 100644
--- a/WebContent/VAADIN/themes/base/base.scss
+++ b/WebContent/VAADIN/themes/base/base.scss
@@ -88,7 +88,10 @@ $line-height: normal;
@include base-orderedlayout;
@include base-panel;
@include base-popupview;
- @include base-progressindicator;
+ @include base-progressindicator(v-progressbar);
+ /* For legacy ProgressIndicator component */
+ @include base-progressindicator(v-progressindicator);
+
@include base-select;
@include base-shadow;
@include base-slider;
diff --git a/WebContent/VAADIN/themes/base/debug/debug.scss b/WebContent/VAADIN/themes/base/debug/debug.scss
index 687370270e..209c3e0469 100644
--- a/WebContent/VAADIN/themes/base/debug/debug.scss
+++ b/WebContent/VAADIN/themes/base/debug/debug.scss
@@ -207,13 +207,22 @@
.v-debugwindow-row:nth-child(odd) {
background-color: rgba(0, 61, 255, 0.11);
}
- .v-debugwindow-row.ERROR {
+ .v-debugwindow-row.SEVERE {
color: #550000;
background-color: #FFC5C5;
}
.v-debugwindow-row.WARNING {
background-color: #FFFF99;
}
+ .v-debugwindow-row.FINE {
+ color: lighten($maincolor, 5%);
+ }
+ .v-debugwindow-row.FINER {
+ color: lighten($maincolor, 10%);
+ }
+ .v-debugwindow-row.FINEST {
+ color: lighten($maincolor, 15%);
+ }
.v-debugwindow-row > span {
display: table-cell;
diff --git a/WebContent/VAADIN/themes/chameleon/components/components.scss b/WebContent/VAADIN/themes/chameleon/components/components.scss
index 9f29827de0..9c8a56b33d 100644
--- a/WebContent/VAADIN/themes/chameleon/components/components.scss
+++ b/WebContent/VAADIN/themes/chameleon/components/components.scss
@@ -29,7 +29,11 @@
@include chameleon-notification;
@include chameleon-panel;
@include chameleon-popupview;
- @include chameleon-progressindicator;
+
+ @include chameleon-progressindicator(v-progressbar);
+ /* For legacy ProgressIndicator component */
+ @include chameleon-progressindicator(v-progressindicator);
+
@include chameleon-slider;
@include chameleon-splitpanel;
@include chameleon-table;
diff --git a/WebContent/VAADIN/themes/liferay/liferay.scss b/WebContent/VAADIN/themes/liferay/liferay.scss
index 7d7665ad86..273c065772 100644
--- a/WebContent/VAADIN/themes/liferay/liferay.scss
+++ b/WebContent/VAADIN/themes/liferay/liferay.scss
@@ -42,7 +42,9 @@
@include liferay-notification;
@include liferay-panel;
@include liferay-popupview;
- @include liferay-progressindicator;
+ @include liferay-progressindicator(v-progressbar);
+ /* For legacy ProgressIndicator component */
+ @include liferay-progressindicator(v-progressindicator);
@include liferay-select;
@include liferay-slider;
@include liferay-splitpanel;
diff --git a/WebContent/VAADIN/themes/reindeer/reindeer.scss b/WebContent/VAADIN/themes/reindeer/reindeer.scss
index 3cf1c392e3..485839ecc7 100644
--- a/WebContent/VAADIN/themes/reindeer/reindeer.scss
+++ b/WebContent/VAADIN/themes/reindeer/reindeer.scss
@@ -56,7 +56,10 @@ $line-height: normal;
@include reindeer-notification;
@include reindeer-panel;
@include reindeer-popupview;
- @include reindeer-progressindicator;
+ @include reindeer-progressindicator(v-progressbar);
+ /* For legacy ProgressIndicator component */
+ @include reindeer-progressindicator(v-progressindicator);
+
@include reindeer-select;
@include reindeer-slider;
@include reindeer-splitpanel;
diff --git a/WebContent/VAADIN/themes/runo/runo.scss b/WebContent/VAADIN/themes/runo/runo.scss
index 6e88b14eb4..33ad35a8af 100644
--- a/WebContent/VAADIN/themes/runo/runo.scss
+++ b/WebContent/VAADIN/themes/runo/runo.scss
@@ -58,7 +58,11 @@ $line-height: 18px;
@include runo-orderedlayout;
@include runo-panel;
@include runo-popupview;
- @include runo-progressindicator;
+
+ @include runo-progressindicator(v-progressbar);
+ /* For legacy ProgressIndicator component */
+ @include runo-progressindicator(v-progressindicator);
+
@include runo-select;
@include runo-shadow;
@include runo-slider;
diff --git a/WebContent/VAADIN/themes/runo/window/img/dialog/maximize.png b/WebContent/VAADIN/themes/runo/window/img/dialog/maximize.png
new file mode 100644
index 0000000000..cbbc0f6691
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/window/img/dialog/maximize.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/window/img/dialog/restore.png b/WebContent/VAADIN/themes/runo/window/img/dialog/restore.png
new file mode 100644
index 0000000000..a4e9d257e1
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/window/img/dialog/restore.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/window/window.scss b/WebContent/VAADIN/themes/runo/window/window.scss
index d2048e027e..1a7cfd3b01 100644
--- a/WebContent/VAADIN/themes/runo/window/window.scss
+++ b/WebContent/VAADIN/themes/runo/window/window.scss
@@ -57,7 +57,6 @@
position: absolute;
top: 21px;
height: 12px;
- background: transparent url(img/close.png);
}
.#{$primaryStyleName}-closebox {
width: 12px;
@@ -99,30 +98,56 @@
/* Dialog style */
.#{$primaryStyleName}-dialog {
background-image: url(img/dialog/bottom-left.png);
+
+ .#{$primaryStyleName}-outerheader {
+ height: 32px;
+ padding: 13px 30px 5px 8px;
+ background: transparent url(img/top-right.png) no-repeat right top;
+ }
+ .#{$primaryStyleName}-header {
+ font-size: 12px;
+ line-height: normal;
+ font-weight: bold;
+ letter-spacing: 0;
+ text-shadow: 0 1px 0 #fff;
+ }
+ .#{$primaryStyleName}-contents > div {
+ background: #f1f3f3;
+ }
+ div.#{$primaryStyleName}-footer {
+ background-image: url(img/dialog/bottom-right.png);
+ }
+ .#{$primaryStyleName}-closebox {
+ top: 14px;
+ right: 16px;
+ background-image: url(img/dialog/close.png);
+ }
+
+ .#{$primaryStyleName}-restorebox {
+ width: 12px;
+ height: 12px;
+ top: 15px;
+ right: 32px;
+
+ background: transparent url(img/dialog/restore.png);
+ &:hover {
+ background-position: 0 -12px;
+ }
+ }
+
+ .#{$primaryStyleName}-maximizebox {
+ width: 11px;
+ height: 10px;
+ top: 15px;
+ right: 32px;
+
+ background: transparent url(img/dialog/maximize.png);
+ &:hover {
+ background-position: 0 -10px;
+ }
+ }
}
-.#{$primaryStyleName}-dialog .#{$primaryStyleName}-outerheader {
- height: 32px;
- padding: 13px 30px 5px 8px;
- background: transparent url(img/top-right.png) no-repeat right top;
-}
-.#{$primaryStyleName}-dialog .#{$primaryStyleName}-header {
- font-size: 12px;
- line-height: normal;
- font-weight: bold;
- letter-spacing: 0;
- text-shadow: 0 1px 0 #fff;
-}
-.#{$primaryStyleName}-dialog .#{$primaryStyleName}-contents > div {
- background: #f1f3f3;
-}
-.#{$primaryStyleName}-dialog div.#{$primaryStyleName}-footer {
- background-image: url(img/dialog/bottom-right.png);
-}
-.#{$primaryStyleName}-dialog .#{$primaryStyleName}-closebox {
- top: 14px;
- right: 16px;
- background-image: url(img/dialog/close.png);
-}
+
/* Shadow for window */
.v-shadow-window .top-left {
top: -13px; left: -20px;
diff --git a/WebContent/VAADIN/vaadinPush.js.tpl b/WebContent/VAADIN/vaadinPush.js.tpl
index 3928fba1b6..43dfd18b40 100644
--- a/WebContent/VAADIN/vaadinPush.js.tpl
+++ b/WebContent/VAADIN/vaadinPush.js.tpl
@@ -3,6 +3,6 @@ window.jQueryVaadin = window.jQuery.noConflict(true);
(function(jQuery, undefined) {
@jquery.atmosphere.js@
})(jQueryVaadin);
-if (console) {
- console.log("Vaadin push loaded");
-} \ No newline at end of file
+if (window.console) {
+ window.console.log("Vaadin push loaded");
+}
diff --git a/WebContent/WEB-INF/liferay-display.xml b/WebContent/WEB-INF/liferay-display.xml
index 12a8e4315b..014ed31b47 100644
--- a/WebContent/WEB-INF/liferay-display.xml
+++ b/WebContent/WEB-INF/liferay-display.xml
@@ -4,6 +4,6 @@
<display>
<category name="Vaadin">
<portlet id="JSR286TestPortlet" />
- <portlet id="Vaadin Liferay Theme Portlet"/>
+ <portlet id="Vaadin Liferay Theme Portlet" />
</category>
</display> \ No newline at end of file
diff --git a/WebContent/WEB-INF/liferay-portlet.xml b/WebContent/WEB-INF/liferay-portlet.xml
index 5a8d6fac8e..ea060ce44a 100644
--- a/WebContent/WEB-INF/liferay-portlet.xml
+++ b/WebContent/WEB-INF/liferay-portlet.xml
@@ -4,7 +4,7 @@
<liferay-portlet-app>
<portlet>
<portlet-name>JSR286TestPortlet</portlet-name>
- <instanceable>false</instanceable>
+ <instanceable>false</instanceable>
<ajaxable>false</ajaxable>
</portlet>
<portlet>
@@ -12,7 +12,7 @@
<instanceable>false</instanceable>
<ajaxable>false</ajaxable>
</portlet>
-
+
<role-mapper>
<role-name>administrator</role-name>
<role-link>Administrator</role-link>
@@ -29,5 +29,5 @@
<role-name>user</role-name>
<role-link>User</role-link>
</role-mapper>
-
+
</liferay-portlet-app> \ No newline at end of file
diff --git a/WebContent/WEB-INF/portlet.xml b/WebContent/WEB-INF/portlet.xml
index 45ce1eee83..3a603c43ae 100644
--- a/WebContent/WEB-INF/portlet.xml
+++ b/WebContent/WEB-INF/portlet.xml
@@ -1,85 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
- version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
+ version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
- <portlet>
- <portlet-name>JSR286TestPortlet</portlet-name>
- <display-name>Vaadin Portlet 2.0 Test</display-name>
- <portlet-class>com.vaadin.server.VaadinPortlet</portlet-class>
- <init-param>
- <name>ui</name>
- <value>com.vaadin.tests.integration.JSR286Portlet</value>
- </init-param>
- <init-param>
- <name>widgetset</name>
- <value>com.vaadin.DefaultWidgetSet</value>
- </init-param>
- <supports>
- <mime-type>text/html</mime-type>
- <portlet-mode>view</portlet-mode>
- <portlet-mode>edit</portlet-mode>
- <portlet-mode>help</portlet-mode>
- </supports>
- <portlet-info>
- <title>Vaadin Portlet 2.0 Test</title>
- <short-title>Vaadin Portlet 2.0 Test</short-title>
- </portlet-info>
+ <portlet>
+ <portlet-name>JSR286TestPortlet</portlet-name>
+ <display-name>Vaadin Portlet 2.0 Test</display-name>
+ <portlet-class>com.vaadin.server.VaadinPortlet</portlet-class>
+ <init-param>
+ <name>ui</name>
+ <value>com.vaadin.tests.integration.JSR286Portlet</value>
+ </init-param>
+ <init-param>
+ <name>widgetset</name>
+ <value>com.vaadin.DefaultWidgetSet</value>
+ </init-param>
+ <supports>
+ <mime-type>text/html</mime-type>
+ <portlet-mode>view</portlet-mode>
+ <portlet-mode>edit</portlet-mode>
+ <portlet-mode>help</portlet-mode>
+ </supports>
+ <portlet-info>
+ <title>Vaadin Portlet 2.0 Test</title>
+ <short-title>Vaadin Portlet 2.0 Test</short-title>
+ </portlet-info>
- <security-role-ref>
- <role-name>administrator</role-name>
- </security-role-ref>
- <security-role-ref>
- <role-name>guest</role-name>
- </security-role-ref>
- <security-role-ref>
- <role-name>power-user</role-name>
- </security-role-ref>
- <security-role-ref>
- <role-name>user</role-name>
- </security-role-ref>
- </portlet>
+ <security-role-ref>
+ <role-name>administrator</role-name>
+ </security-role-ref>
+ <security-role-ref>
+ <role-name>guest</role-name>
+ </security-role-ref>
+ <security-role-ref>
+ <role-name>power-user</role-name>
+ </security-role-ref>
+ <security-role-ref>
+ <role-name>user</role-name>
+ </security-role-ref>
+ </portlet>
- <portlet>
+ <portlet>
<portlet-name>Vaadin Liferay Theme Portlet</portlet-name>
<display-name>Vaadin Liferay Theme</display-name>
-
+
<portlet-class>com.vaadin.server.LegacyVaadinPortlet</portlet-class>
<init-param>
<name>application</name>
<value>com.vaadin.tests.integration.LiferayThemeDemo</value>
</init-param>
-
+
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
-
+
<portlet-info>
<title>Vaadin Liferay Theme</title>
<short-title>Vaadin Liferay Theme</short-title>
</portlet-info>
-
+
+ <security-role-ref>
+ <role-name>administrator</role-name>
+ </security-role-ref>
+ <security-role-ref>
+ <role-name>guest</role-name>
+ </security-role-ref>
<security-role-ref>
- <role-name>administrator</role-name>
- </security-role-ref>
- <security-role-ref>
- <role-name>guest</role-name>
- </security-role-ref>
- <security-role-ref>
- <role-name>power-user</role-name>
- </security-role-ref>
- <security-role-ref>
- <role-name>user</role-name>
- </security-role-ref>
+ <role-name>power-user</role-name>
+ </security-role-ref>
+ <security-role-ref>
+ <role-name>user</role-name>
+ </security-role-ref>
</portlet>
- <!--
- This can be used to work around an issue in liferay 5.0-5.1.1
-
- <container-runtime-option>
- <name>javax.portlet.escapeXml</name>
- <value>false</value>
- </container-runtime-option>
- -->
+ <!-- This can be used to work around an issue in liferay 5.0-5.1.1 <container-runtime-option>
+ <name>javax.portlet.escapeXml</name> <value>false</value> </container-runtime-option> -->
</portlet-app> \ No newline at end of file
diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml
index 848baea318..ba948968e2 100644
--- a/WebContent/WEB-INF/web.xml
+++ b/WebContent/WEB-INF/web.xml
@@ -1,134 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="vaadin-uitest" version="3.0"
- xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+ xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
- <!-- THIS IS A DEVELOPMENT AND TESTING web.xml . -->
+ <!-- THIS IS A DEVELOPMENT AND TESTING web.xml . -->
- <display-name>Vaadin</display-name>
- <description>Vaadin examples</description>
+ <display-name>Vaadin</display-name>
+ <description>Vaadin examples</description>
- <context-param>
- <param-name>productionMode</param-name>
- <param-value>false</param-value>
- </context-param>
+ <context-param>
+ <param-name>productionMode</param-name>
+ <param-value>false</param-value>
+ </context-param>
- <context-param>
- <param-name>resourceCacheTime</param-name>
- <param-value>3600</param-value>
- </context-param>
- <servlet>
- <servlet-name>Embed App 1</servlet-name>
- <servlet-class>com.vaadin.server.LegacyVaadinServlet</servlet-class>
- <init-param>
- <param-name>application</param-name>
- <param-value>com.vaadin.tests.components.button.Buttons</param-value>
- </init-param>
- </servlet>
- <servlet>
- <servlet-name>Embed App 2</servlet-name>
- <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
- <init-param>
- <param-name>UI</param-name>
- <param-value>com.vaadin.tests.components.label.MarginsInLabels</param-value>
- </init-param>
- </servlet>
- <servlet>
- <servlet-name>UI provider app</servlet-name>
- <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
- <init-param>
- <param-name>UIProvider</param-name>
- <param-value>com.vaadin.tests.applicationservlet.InitParamUIProvider</param-value>
- </init-param>
- <init-param>
- <param-name>UI</param-name>
- <param-value>com.vaadin.tests.VerifyAssertionsEnabled</param-value>
- </init-param>
- </servlet>
+ <context-param>
+ <param-name>resourceCacheTime</param-name>
+ <param-value>3600</param-value>
+ </context-param>
+ <servlet>
+ <servlet-name>Embed App 1</servlet-name>
+ <servlet-class>com.vaadin.server.LegacyVaadinServlet</servlet-class>
+ <init-param>
+ <param-name>application</param-name>
+ <param-value>com.vaadin.tests.components.button.Buttons</param-value>
+ </init-param>
+ </servlet>
+ <servlet>
+ <servlet-name>Embed App 2</servlet-name>
+ <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
+ <init-param>
+ <param-name>UI</param-name>
+ <param-value>com.vaadin.tests.components.label.MarginsInLabels</param-value>
+ </init-param>
+ </servlet>
+ <servlet>
+ <servlet-name>UI provider app</servlet-name>
+ <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
+ <init-param>
+ <param-name>UIProvider</param-name>
+ <param-value>com.vaadin.tests.applicationservlet.InitParamUIProvider</param-value>
+ </init-param>
+ <init-param>
+ <param-name>UI</param-name>
+ <param-value>com.vaadin.tests.VerifyAssertionsEnabled</param-value>
+ </init-param>
+ </servlet>
- <servlet>
- <servlet-name>VaadinApplicationRunner</servlet-name>
- <servlet-class>com.vaadin.launcher.ApplicationRunnerServlet</servlet-class>
- <!-- Non-default values for testing purposes -->
- <init-param>
- <param-name>legacyPropertyToString</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>heartbeatInterval</param-name>
- <param-value>301</param-value>
- </init-param>
- <init-param>
- <param-name>resourceCacheTime</param-name>
- <param-value>3601</param-value>
- </init-param>
- <init-param>
- <param-name>closeIdleSessions</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>testParam</param-name>
- <param-value>42</param-value>
- </init-param>
- </servlet>
+ <servlet>
+ <servlet-name>VaadinApplicationRunner</servlet-name>
+ <servlet-class>com.vaadin.launcher.ApplicationRunnerServlet</servlet-class>
+ <!-- Non-default values for testing purposes -->
+ <init-param>
+ <param-name>legacyPropertyToString</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <init-param>
+ <param-name>heartbeatInterval</param-name>
+ <param-value>301</param-value>
+ </init-param>
+ <init-param>
+ <param-name>resourceCacheTime</param-name>
+ <param-value>3601</param-value>
+ </init-param>
+ <init-param>
+ <param-name>closeIdleSessions</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ <init-param>
+ <param-name>testParam</param-name>
+ <param-value>42</param-value>
+ </init-param>
+ </servlet>
- <servlet>
- <servlet-name>VaadinApplicationRunnerWithPush</servlet-name>
- <servlet-class>com.vaadin.launcher.ApplicationRunnerServlet</servlet-class>
- <init-param>
- <param-name>pushmode</param-name>
- <param-value>automatic</param-value>
- </init-param>
- <async-supported>true</async-supported>
- </servlet>
+ <servlet>
+ <servlet-name>VaadinApplicationRunnerWithPush</servlet-name>
+ <servlet-class>com.vaadin.launcher.ApplicationRunnerServlet</servlet-class>
+ <init-param>
+ <param-name>pushmode</param-name>
+ <param-value>automatic</param-value>
+ </init-param>
+ <async-supported>true</async-supported>
+ </servlet>
- <!-- For testing GAE - the deployment script changes this to use GAEVaadinServlet -->
- <servlet>
- <servlet-name>IntegrationTest</servlet-name>
- <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
- <init-param>
- <param-name>UI</param-name>
- <param-value>com.vaadin.tests.integration.IntegrationTestUI</param-value>
- </init-param>
- <async-supported>true</async-supported>
- </servlet>
- <servlet-mapping>
- <servlet-name>Embed App 1</servlet-name>
- <url-pattern>/embed1/*</url-pattern>
- </servlet-mapping>
+ <!-- For testing GAE - the deployment script changes this to use GAEVaadinServlet -->
+ <servlet>
+ <servlet-name>IntegrationTest</servlet-name>
+ <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
+ <init-param>
+ <param-name>UI</param-name>
+ <param-value>com.vaadin.tests.integration.IntegrationTestUI</param-value>
+ </init-param>
+ <async-supported>true</async-supported>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>Embed App 1</servlet-name>
+ <url-pattern>/embed1/*</url-pattern>
+ </servlet-mapping>
- <servlet-mapping>
- <servlet-name>Embed App 2</servlet-name>
- <url-pattern>/embed2/*</url-pattern>
- </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>Embed App 2</servlet-name>
+ <url-pattern>/embed2/*</url-pattern>
+ </servlet-mapping>
- <servlet-mapping>
- <servlet-name>UI provider app</servlet-name>
- <url-pattern>/uiprovider/*</url-pattern>
- </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>UI provider app</servlet-name>
+ <url-pattern>/uiprovider/*</url-pattern>
+ </servlet-mapping>
- <servlet-mapping>
- <servlet-name>VaadinApplicationRunner</servlet-name>
- <url-pattern>/run/*</url-pattern>
- </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>VaadinApplicationRunner</servlet-name>
+ <url-pattern>/run/*</url-pattern>
+ </servlet-mapping>
- <servlet-mapping>
- <servlet-name>VaadinApplicationRunnerWithPush</servlet-name>
- <url-pattern>/run-push/*</url-pattern>
- </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>VaadinApplicationRunnerWithPush</servlet-name>
+ <url-pattern>/run-push/*</url-pattern>
+ </servlet-mapping>
- <servlet-mapping>
- <servlet-name>IntegrationTest</servlet-name>
- <url-pattern>/integration/*</url-pattern>
- </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>IntegrationTest</servlet-name>
+ <url-pattern>/integration/*</url-pattern>
+ </servlet-mapping>
- <servlet-mapping>
- <servlet-name>IntegrationTest</servlet-name>
- <url-pattern>/VAADIN/*</url-pattern>
- </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>IntegrationTest</servlet-name>
+ <url-pattern>/VAADIN/*</url-pattern>
+ </servlet-mapping>
- <welcome-file-list>
- <welcome-file>index.html</welcome-file>
- </welcome-file-list>
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ </welcome-file-list>
</web-app>
diff --git a/all/build.xml b/all/build.xml
index 4e1a557e53..a83d60b382 100644
--- a/all/build.xml
+++ b/all/build.xml
@@ -1,120 +1,137 @@
<?xml version="1.0"?>
-<project name="vaadin-all" basedir="." default="publish-local" xmlns:ivy="antlib:org.apache.ivy.ant" xmlns:antcontrib="antlib:net.sf.antcontrib">
- <description>
- Compiles a zip containing all jars + dependencies
- </description>
- <include file="../common.xml" as="common" />
- <include file="../build.xml" as="vaadin" />
-
- <!-- global properties -->
- <property name="module.name" value="vaadin-all" />
- <property name="result.dir" value="result" />
- <property name="javadoc.jar" location="${result.dir}/lib/vaadin-all-${vaadin.version}-javadoc.jar" />
- <property name="temp.dir" location="${result.dir}/temp" />
- <property name="temp.deps.dir" value="${temp.dir}/lib" />
- <property name="javadoc.temp.dir" location="${result.dir}/javadoc-temp" />
- <property name="zip.file" location="${result.dir}/lib/${module.name}-${vaadin.version}.zip" />
-
- <path id="classpath.javadoc">
- <fileset dir="${temp.deps.dir}" includes="*.jar">
- </fileset>
- </path>
- <target name="fetch.module.and.dependencies">
- <fail unless="module" message="No 'module' parameter given" />
-
- <ivy:cachepath pathid="module.and.deps" inline="true" organisation="com.vaadin" module="vaadin-${module}" revision="${vaadin.version}" />
- <copy todir="${temp.dir}" flatten="true">
- <path refid="module.and.deps" />
- </copy>
- </target>
-
- <target name="unzip.to.javadoctemp">
- <property name="file" location="${temp.dir}/vaadin-${module}-${vaadin.version}.jar" />
- <unzip src="${file}" dest="${javadoc.temp.dir}" />
- </target>
-
- <target name="javadoc" depends="copy-jars">
- <!-- Ensure filtered webcontent files are available -->
- <antcall target="common.filter.webcontent" />
-
- <!-- Unpack all source files to javadoc.temp.dir-->
- <antcontrib:foreach list="${modules.to.publish.to.maven}" target="unzip.to.javadoctemp" param="module" />
-
- <property name="javadoc.dir" location="${result.dir}/javadoc" />
- <property name="title" value="Vaadin ${vaadin.version} API" />
- <javadoc maxmemory="1024m" destdir="${javadoc.dir}" author="true" version="true" use="true" windowtitle="${title}" encoding="utf-8">
- <packageset dir="${javadoc.temp.dir}">
- <!-- TODO Javadoc throws ClassCastException if this is included (#9660)-->
- <exclude name="com/google/gwt/uibinder/elementparsers" />
- </packageset>
- <doctitle>&lt;h1>${title}&lt;/h1></doctitle>
- <!-- <header><![CDATA[<script type="text/javascript" src=".html-style/style.js"></script>]]></header> -->
- <bottom>${javadoc.bottom}</bottom>
- <link offline="true" href="http://docs.oracle.com/javase/6/docs/api/" packagelistLoc="build/javadoc/j2se-1.6.0" />
- <link offline="true" href="http://java.sun.com/j2ee/1.4/docs/api/" packagelistLoc="build/javadoc/j2ee-1.4" />
- <classpath refid="classpath.javadoc" />
- </javadoc>
-
- <!-- Create a javadoc jar -->
- <jar file="${javadoc.jar}" compress="true">
- <fileset dir="${javadoc.dir}" />
- <fileset refid="common.files.for.all.jars" />
- </jar>
-
-
- </target>
-
- <target name="copy-jars">
- <delete dir="${temp.dir}" />
- <antcontrib:foreach list="${modules.to.publish.to.maven}" target="fetch.module.and.dependencies" param="module" />
- <!-- All jars are now in temp.dir. Still need to separate vaadin and deps -->
- <move todir="${temp.deps.dir}">
- <fileset dir="${temp.dir}">
- <exclude name="vaadin-*-${vaadin.version}.*" />
- <exclude name="vaadin-*-${vaadin.version}-*.*" />
- </fileset>
- </move>
-
-
- </target>
- <target name="zip" depends="copy-jars, javadoc">
- <!-- Ensure filtered webcontent files are available -->
- <antcall target="common.filter.webcontent" />
-
- <zip destfile="${zip.file}">
- <fileset dir="${temp.dir}">
- <!-- Avoid conflicts with servlet and portlet API. They are provided by the container -->
- <exclude name="**/servlet-api*" />
- <exclude name="**/portlet-api*" />
- <!-- Buildhelpers should not even get here ... -->
- <exclude name="*buildhelpers*" />
- <!-- Zip users should not need javadoc, sources or pom files -->
- <exclude name="*.pom" />
- <exclude name="*-javadoc.jar" />
- <exclude name="*-sources.jar" />
-
- </fileset>
- <fileset refid="common.files.for.all.jars" />
- <fileset dir="${result.dir}/..">
- <include name="README.TXT" />
- </fileset>
- <!-- Do not include javadoc jar in zip as it is huge (> 40MB) and most people do not need it. -->
- </zip>
- </target>
-
- <target name="publish-local" depends="zip">
- <antcall target="common.publish-local" />
- </target>
-
- <target name="clean">
- <antcall target="common.clean" />
- </target>
- <target name="checkstyle">
- <!-- Checkstyle is handled by all separate modules -->
- </target>
- <target name="test" depends="checkstyle">
- <!-- No tests for this zip.. -->
- </target>
+<project name="vaadin-all" basedir="." default="publish-local"
+ xmlns:ivy="antlib:org.apache.ivy.ant" xmlns:antcontrib="antlib:net.sf.antcontrib">
+ <description>
+ Compiles a zip containing all jars + dependencies
+ </description>
+ <include file="../common.xml" as="common" />
+ <include file="../build.xml" as="vaadin" />
+
+ <!-- global properties -->
+ <property name="module.name" value="vaadin-all" />
+ <property name="result.dir" value="result" />
+ <property name="javadoc.jar"
+ location="${result.dir}/lib/vaadin-all-${vaadin.version}-javadoc.jar" />
+ <property name="temp.dir" location="${result.dir}/temp" />
+ <property name="temp.deps.dir" value="${temp.dir}/lib" />
+ <property name="javadoc.temp.dir" location="${result.dir}/javadoc-temp" />
+ <property name="zip.file"
+ location="${result.dir}/lib/${module.name}-${vaadin.version}.zip" />
+
+ <path id="classpath.javadoc">
+ <fileset dir="${temp.deps.dir}" includes="*.jar">
+ </fileset>
+ </path>
+ <target name="fetch.module.and.dependencies">
+ <fail unless="module" message="No 'module' parameter given" />
+
+ <ivy:cachepath pathid="module.and.deps" inline="true"
+ organisation="com.vaadin" module="vaadin-${module}"
+ revision="${vaadin.version}" />
+ <copy todir="${temp.dir}" flatten="true">
+ <path refid="module.and.deps" />
+ </copy>
+ </target>
+
+ <target name="unzip.to.javadoctemp">
+ <property name="file"
+ location="${temp.dir}/vaadin-${module}-${vaadin.version}.jar" />
+ <unzip src="${file}" dest="${javadoc.temp.dir}" />
+ </target>
+
+ <target name="javadoc" depends="copy-jars">
+ <!-- Ensure filtered webcontent files are available -->
+ <antcall target="common.filter.webcontent" />
+
+ <!-- Unpack all source files to javadoc.temp.dir -->
+ <antcontrib:foreach list="${modules.to.publish.to.maven}"
+ target="unzip.to.javadoctemp" param="module" />
+
+ <property name="javadoc.dir" location="${result.dir}/javadoc" />
+ <property name="title" value="Vaadin ${vaadin.version} API" />
+ <javadoc maxmemory="1024m" destdir="${javadoc.dir}"
+ author="true" version="true" use="true" windowtitle="${title}"
+ encoding="utf-8">
+ <packageset dir="${javadoc.temp.dir}">
+ <!-- TODO Javadoc throws ClassCastException if this is included
+ (#9660) -->
+ <exclude name="com/google/gwt/uibinder/elementparsers" />
+ </packageset>
+ <doctitle>&lt;h1>${title}&lt;/h1></doctitle>
+ <!-- <header><![CDATA[<script type="text/javascript" src=".html-style/style.js"></script>]]></header> -->
+ <bottom>${javadoc.bottom}</bottom>
+ <link offline="true"
+ href="http://docs.oracle.com/javase/6/docs/api/"
+ packagelistLoc="build/javadoc/j2se-1.6.0" />
+ <link offline="true" href="http://java.sun.com/j2ee/1.4/docs/api/"
+ packagelistLoc="build/javadoc/j2ee-1.4" />
+ <classpath refid="classpath.javadoc" />
+ </javadoc>
+
+ <!-- Create a javadoc jar -->
+ <jar file="${javadoc.jar}" compress="true">
+ <fileset dir="${javadoc.dir}" />
+ <fileset refid="common.files.for.all.jars" />
+ </jar>
+
+
+ </target>
+
+ <target name="copy-jars">
+ <delete dir="${temp.dir}" />
+ <antcontrib:foreach list="${modules.to.publish.to.maven}"
+ target="fetch.module.and.dependencies" param="module" />
+ <!-- All jars are now in temp.dir. Still need to separate vaadin
+ and deps -->
+ <move todir="${temp.deps.dir}">
+ <fileset dir="${temp.dir}">
+ <exclude name="vaadin-*-${vaadin.version}.*" />
+ <exclude name="vaadin-*-${vaadin.version}-*.*" />
+ </fileset>
+ </move>
+
+
+ </target>
+ <target name="zip" depends="copy-jars, javadoc">
+ <!-- Ensure filtered webcontent files are available -->
+ <antcall target="common.filter.webcontent" />
+
+ <zip destfile="${zip.file}">
+ <fileset dir="${temp.dir}">
+ <!-- Avoid conflicts with servlet and portlet API. They are
+ provided by the container -->
+ <exclude name="**/servlet-api*" />
+ <exclude name="**/portlet-api*" />
+ <!-- Buildhelpers should not even get here ... -->
+ <exclude name="*buildhelpers*" />
+ <!-- Zip users should not need javadoc, sources or pom files -->
+ <exclude name="*.pom" />
+ <exclude name="*-javadoc.jar" />
+ <exclude name="*-sources.jar" />
+
+ </fileset>
+ <fileset refid="common.files.for.all.jars" />
+ <fileset dir="${result.dir}/..">
+ <include name="README.TXT" />
+ </fileset>
+ <!-- Do not include javadoc jar in zip as it is huge (> 40MB)
+ and most people do not need it. -->
+ </zip>
+ </target>
+
+ <target name="publish-local" depends="zip">
+ <antcall target="common.publish-local" />
+ </target>
+
+ <target name="clean">
+ <antcall target="common.clean" />
+ </target>
+ <target name="checkstyle">
+ <!-- Checkstyle is handled by all separate modules -->
+ </target>
+ <target name="test" depends="checkstyle">
+ <!-- No tests for this zip.. -->
+ </target>
</project> \ No newline at end of file
diff --git a/all/ivy.xml b/all/ivy.xml
index 2b212f6675..3c49e9a884 100644
--- a/all/ivy.xml
+++ b/all/ivy.xml
@@ -19,21 +19,20 @@
<!-- LIBRARY DEPENDENCIES (compile time) -->
<!-- Project modules -->
<dependency org="com.vaadin" name="vaadin-shared"
- rev="${vaadin.version}"/>
+ rev="${vaadin.version}" />
<dependency org="com.vaadin" name="vaadin-server"
- rev="${vaadin.version}"/>
+ rev="${vaadin.version}" />
<dependency org="com.vaadin" name="vaadin-client"
- rev="${vaadin.version}"/>
+ rev="${vaadin.version}" />
<dependency org="com.vaadin" name="vaadin-client-compiler"
- rev="${vaadin.version}"/>
+ rev="${vaadin.version}" />
<dependency org="com.vaadin" name="vaadin-theme-compiler"
- rev="${vaadin.version}"/>
+ rev="${vaadin.version}" />
<dependency org="com.vaadin" name="vaadin-themes"
- rev="${vaadin.version}"/>
+ rev="${vaadin.version}" />
<dependency org="com.vaadin" name="vaadin-client-compiled"
- rev="${vaadin.version}"/>
- <dependency org="com.vaadin" name="vaadin-push"
- rev="${vaadin.version}"/>
+ rev="${vaadin.version}" />
+ <dependency org="com.vaadin" name="vaadin-push" rev="${vaadin.version}" />
</dependencies>
diff --git a/build.xml b/build.xml
index 37e4afd03b..192d034b9b 100644
--- a/build.xml
+++ b/build.xml
@@ -1,71 +1,78 @@
<?xml version="1.0"?>
-<project name="vaadin" basedir="." default="package" xmlns:ivy="antlib:org.apache.ivy.ant">
- <include file="common.xml" as="common" />
+<project name="vaadin" basedir="." default="package"
+ xmlns:ivy="antlib:org.apache.ivy.ant">
+ <include file="common.xml" as="common" />
- <path id="vaadin.buildhelpers.classpath" location="${vaadin.basedir}/buildhelpers/result/classes" />
+ <path id="vaadin.buildhelpers.classpath" location="${vaadin.basedir}/buildhelpers/result/classes" />
- <!-- =================================
- target: all
- ================================= -->
- <!--<target name="all" description="Compiles all parts of the project" depends="buildhelpers,theme-compiler,shared,server,client">-->
- <target name="package" description="Compiles and packages all modules in the project" depends="buildorder">
- <subant buildpathref="build-path" target="publish-local">
- </subant>
- </target>
+ <!-- ================================= target: all ================================= -->
+ <!--<target name="all" description="Compiles all parts of the project"
+ depends="buildhelpers,theme-compiler,shared,server,client"> -->
+ <target name="package"
+ description="Compiles and packages all modules in the project"
+ depends="buildorder">
+ <subant buildpathref="build-path" target="publish-local">
+ </subant>
+ </target>
- <target name="buildorder" depends="official.build.checks">
- <!-- Find out a good build order -->
- <ivy:buildlist reference="ivy.build.path">
- <fileset dir="." includes="**/build.xml">
- <exclude name="build.xml" />
- <exclude name="build/**" />
- <exclude name="buildhelpers/**" />
- </fileset>
- </ivy:buildlist>
- <path id="build-path">
- <path location="buildhelpers/build.xml"/>
- <path refid="ivy.build.path" />
- </path>
- </target>
- <target name="clean" depends="buildorder">
- <subant buildpathref="build-path" target="clean">
- </subant>
- <delete dir="result" />
- <!-- Clean IVY cache (~/.ivy2) so no old artifacts are fetched from there (leave everything but Vaadin artifacts) -->
- <delete dir="${ivy.cache.dir}/com.vaadin" />
- <delete dir="${ivy.cache.dir}/com.carrotsearch" />
+ <target name="buildorder" depends="official.build.checks">
+ <!-- Find out a good build order -->
+ <ivy:buildlist reference="ivy.build.path">
+ <fileset dir="." includes="**/build.xml">
+ <exclude name="build.xml" />
+ <exclude name="build/**" />
+ <exclude name="buildhelpers/**" />
+ </fileset>
+ </ivy:buildlist>
+ <path id="build-path">
+ <path location="buildhelpers/build.xml" />
+ <path refid="ivy.build.path" />
+ </path>
+ </target>
+ <target name="clean" depends="buildorder">
+ <subant buildpathref="build-path" target="clean">
+ </subant>
+ <delete dir="result" />
+ <!-- Clean IVY cache (~/.ivy2) so no old artifacts are fetched from
+ there (leave everything but Vaadin artifacts) -->
+ <delete dir="${ivy.cache.dir}/com.vaadin" />
+ <delete dir="${ivy.cache.dir}/com.carrotsearch" />
- </target>
- <target name="checkstyle" depends="buildorder">
- <subant buildpathref="build-path" target="checkstyle"/>
- </target>
- <target name="test" depends="buildorder">
- <subant buildpathref="build-path" target="test" />
- </target>
- <target name="test-all" depends="buildorder">
- <property name="war.file" location="result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" />
- <parallel>
- <sequential>
- <!-- Sleep before running integration tests so testbench tests have time to compile and start -->
- <sleep minutes="4" />
- <ant antfile="uitest/integration_tests.xml" target="integration-test-all" inheritall="false" inheritrefs="false">
- <property name="demo.war" value="${war.file}" />
- </ant>
- </sequential>
- <subant buildpathref="build-path" target="test" />
- <ant antfile="uitest/test.xml" target="test-package">
- <property name="war.file" location="${war.file}" />
- </ant>
- </parallel>
- </target>
+ </target>
+ <target name="checkstyle" depends="buildorder">
+ <subant buildpathref="build-path" target="checkstyle" />
+ </target>
+ <target name="test" depends="buildorder">
+ <subant buildpathref="build-path" target="test" />
+ </target>
+ <target name="test-all" depends="buildorder">
+ <property name="war.file"
+ location="result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" />
+ <parallel>
+ <sequential>
+ <!-- Sleep before running integration tests so testbench
+ tests have time to compile and start -->
+ <sleep minutes="4" />
+ <ant antfile="uitest/integration_tests.xml" target="integration-test-all"
+ inheritall="false" inheritrefs="false">
+ <property name="demo.war" value="${war.file}" />
+ </ant>
+ </sequential>
+ <subant buildpathref="build-path" target="test" />
+ <ant antfile="uitest/test.xml" target="test-package">
+ <property name="war.file" location="${war.file}" />
+ </ant>
+ </parallel>
+ </target>
- <target name="official.build.checks" if="build.release">
- <condition property="java.version.matches">
- <equals arg1="${ant.java.version}" arg2="${vaadin.java.version}" />
- </condition>
- <fail unless="java.version.matches" message="Java version is ${ant.java.version}, but Vaadin must be compiled with genuine Java ${vaadin.java.version} compiler." />
- <echo>Java version is ${ant.java.version} as required.</echo>
- </target>
+ <target name="official.build.checks" if="build.release">
+ <condition property="java.version.matches">
+ <equals arg1="${ant.java.version}" arg2="${vaadin.java.version}" />
+ </condition>
+ <fail unless="java.version.matches"
+ message="Java version is ${ant.java.version}, but Vaadin must be compiled with genuine Java ${vaadin.java.version} compiler." />
+ <echo>Java version is ${ant.java.version} as required.</echo>
+ </target>
</project>
diff --git a/build/common.xml b/build/common.xml
index 1fc6349a46..ee60c1ff42 100644
--- a/build/common.xml
+++ b/build/common.xml
@@ -1,59 +1,65 @@
<?xml version="1.0"?>
<project xmlns:antcontrib="antlib:net.sf.antcontrib"
- xmlns:artifact="antlib:org.apache.maven.artifact.ant"
- xmlns:ivy="antlib:org.apache.ivy.ant"
- name="common"
- basedir="../"
- default="init-deps" >
-
- <property name="ivy.install.version" value="2.2.0"/>
- <property name="ivy.jar.name" value="ivy-${ivy.install.version}.jar"/>
+ xmlns:artifact="antlib:org.apache.maven.artifact.ant" xmlns:ivy="antlib:org.apache.ivy.ant"
+ name="common" basedir="../" default="init-deps">
+
+ <property name="ivy.install.version" value="2.2.0" />
+ <property name="ivy.jar.name" value="ivy-${ivy.install.version}.jar" />
<property name="ivy.jar.dir" value="${user.home}/.ant/lib" />
<property name="ivy.jar.file" value="${ivy.jar.dir}/${ivy.jar.name}" />
-
- <target name="init-deps" description="Configure Ivy dependency management and load common task definitions"
- depends="init-taskdefs" unless="deps.initialized">
+
+ <target name="init-deps"
+ description="Configure Ivy dependency management and load common task definitions"
+ depends="init-taskdefs" unless="deps.initialized">
<property name="deps.initialized" value="1" />
</target>
-
+
<target name="check-ivy-installed">
- <available property="ivy.installed" file="${ivy.jar.file}"/>
- <available property="ivy.installed" classname="org.apache.ivy.ant.IvyConfigure" />
- <antcall target="common.ivy-download" />
- </target>
+ <available property="ivy.installed" file="${ivy.jar.file}" />
+ <available property="ivy.installed" classname="org.apache.ivy.ant.IvyConfigure" />
+ <antcall target="common.ivy-download" />
+ </target>
<target name="ivy-download" unless="ivy.installed">
- <mkdir dir="${ivy.jar.dir}"/>
- <get src="http://repo2.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar" dest="${ivy.jar.file}" usetimestamp="true"/>
+ <mkdir dir="${ivy.jar.dir}" />
+ <get
+ src="http://repo2.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar"
+ dest="${ivy.jar.file}" usetimestamp="true" />
+ </target>
+
+ <target name="ivy-configure" depends="check-ivy-installed"
+ unless="deps.initialized">
+ <!-- Ivy task definitions -->
+ <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant"
+ classpath="${ivy.jar.file}" />
+ <!-- Ivy settings -->
+ <property name="ivy.settings.file"
+ value="${project.root}/build/ivy/ivysettings.xml" />
+ <ivy:configure />
</target>
- <target name="ivy-configure" depends="check-ivy-installed" unless="deps.initialized">
- <!-- Ivy task definitions -->
- <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpath="${ivy.jar.file}" />
- <!-- Ivy settings -->
- <property name="ivy.settings.file" value="${project.root}/build/ivy/ivysettings.xml" />
- <ivy:configure/>
- </target>
-
<target name="init-taskdefs" depends="ivy-configure" unless="deps.initialized">
<echo>Loading Ant tasks</echo>
- <ivy:resolve file="${project.root}/build/ivy/ivy.xml" conf="taskdefs" />
+ <ivy:resolve file="${project.root}/build/ivy/ivy.xml"
+ conf="taskdefs" />
<ivy:cachepath pathid="taskdefs.classpath" conf="taskdefs" />
- <taskdef resource="emma_ant.properties" classpathref="taskdefs.classpath" />
-
- <!-- ant contrib required for flow control (for loop, if, property override) -->
- <!-- Note that we have to use a namespace to avoid clash when running sub-ant. -->
+ <taskdef resource="emma_ant.properties" classpathref="taskdefs.classpath" />
+
+ <!-- ant contrib required for flow control (for loop, if, property
+ override) -->
+ <!-- Note that we have to use a namespace to avoid clash when running
+ sub-ant. -->
<taskdef uri="antlib:net.sf.antcontrib" resource="net/sf/antcontrib/antlib.xml"
classpathref="taskdefs.classpath" />
-
- <!-- ant contrib for Maven integration -->
+
+ <!-- ant contrib for Maven integration -->
<taskdef resource="org/apache/maven/artifact/ant/antlib.xml"
- uri="antlib:org.apache.maven.artifact.ant" classpathref="taskdefs.classpath" />
-
- <!-- jarjar -->
+ uri="antlib:org.apache.maven.artifact.ant" classpathref="taskdefs.classpath" />
+
+ <!-- jarjar -->
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"
- classpathref="taskdefs.classpath"/>
+ classpathref="taskdefs.classpath" />
</target>
diff --git a/build/ide.xml b/build/ide.xml
index b1845020f3..5380536e2e 100755
--- a/build/ide.xml
+++ b/build/ide.xml
@@ -1,152 +1,165 @@
<?xml version="1.0"?>
-<project xmlns:antcontrib="antlib:net.sf.antcontrib" xmlns:artifact="antlib:org.apache.maven.artifact.ant" xmlns:ivy="antlib:org.apache.ivy.ant" name="Build script for IDE users" basedir=".." default="theme-and-default-widgetset">
- <include file="${basedir}/gwt-files.xml" />
-
- <property name="gwt.dev.classes" location="${gwt.eclipse.basedir}/dev/bin" />
- <property name="gwt.user.classes" location="${gwt.eclipse.basedir}/user/bin" />
- <property name="gwt.dev.src" location="${gwt.basedir}/dev/core/src" />
- <property name="gwt.dev.super.src" location="${gwt.basedir}/dev/core/super" />
- <property name="gwt.user.src" location="${gwt.basedir}/user/src" />
- <property name="gwt.user.super.src" location="${gwt.basedir}/user/super" />
-
- <property name="work.dir" location="work" />
- <property name="theme-version" location="9.9.9.INTERNAL-DEBUG-BUILD" />
- <echo>Using gwt files from ${gwt.user.classes} and ${gwt.dev.classes}</echo>
-
- <ivy:resolve file="client-compiler/ivy.xml" conf="ide" />
- <ivy:cachepath pathid="client-compiler.deps" conf="ide" />
- <ivy:resolve file="server/ivy.xml" conf="ide" />
- <ivy:cachepath pathid="server.deps" conf="ide" />
- <ivy:resolve file="client/ivy.xml" conf="ide" />
- <ivy:cachepath pathid="client.deps" conf="ide" />
- <ivy:resolve file="shared/ivy.xml" conf="ide" />
- <ivy:cachepath pathid="shared.deps" conf="ide" />
- <ivy:resolve file="uitest/ivy.xml" conf="ide" />
- <ivy:cachepath pathid="uitest.deps" conf="ide" />
- <ivy:resolve file="theme-compiler/ivy.xml" conf="ide" />
- <ivy:cachepath pathid="theme-compiler.deps" conf="ide" />
-
- <path id="classpath">
- <path location="bin" />
- <path location="build/classes" />
- <path location="${gwt.user.classes}" />
- <path location="${gwt.user.src}" />
- <path location="${gwt.user.super.src}" />
- <path location="${gwt.dev.classes}" />
- <path location="${gwt.dev.super.src}" />
- <path location="${gwt.dev.src}" />
- <path refid="client-compiler.deps" />
- <path refid="theme-compiler.deps" />
- <path refid="server.deps" />
- <path refid="shared.deps" />
- <path refid="uitest.deps" />
- <path refid="client.deps" />
- <path location="theme-compiler/src" />
- <path location="server/src" />
- <path location="shared/src" />
- <path location="uitest/src" />
- <path location="client/src" />
- </path>
-
- <target name="theme-and-default-widgetset" depends="default-widgetset, themes, vaadinPush.js">
- </target>
- <target name="themes">
- <antcall target="compile-theme">
- <param name="theme" value="base" />
- </antcall>
- <antcall target="compile-theme">
- <param name="theme" value="runo" />
- </antcall>
- <antcall target="compile-theme">
- <param name="theme" value="reindeer" />
- </antcall>
- <antcall target="compile-theme">
- <param name="theme" value="chameleon" />
- </antcall>
- <antcall target="compile-theme">
- <param name="theme" value="liferay" />
- </antcall>
- </target>
-
- <target name="compile-theme">
- <java classname="com.vaadin.buildhelpers.CompileTheme" failonerror="yes" fork="yes">
- <classpath refid="classpath" />
- <jvmarg value="-Djava.awt.headless=true" />
- <arg value="--theme" />
- <arg value="${theme}" />
- <arg value="--theme-version" />
- <arg value="${theme-version}" />
- <arg value="--theme-folder" />
- <arg value="WebContent/VAADIN/themes" />
- </java>
-
- </target>
-
-
- <target name="default-widgetset">
- <antcall target="compile-widgetset">
- <param name="widgetset" value="com.vaadin.DefaultWidgetSet" />
- </antcall>
- </target>
-
- <target name="testing-widgetset">
- <antcall target="compile-widgetset">
- <param name="widgetset" value="com.vaadin.tests.widgetset.TestingWidgetSet" />
- </antcall>
- </target>
-
- <target name="compile-widgetset">
- <property name="module" value="${widgetset}" />
- <property name="module.output.dir" location="WebContent/VAADIN/widgetsets" />
- <property name="style" value="PRETTY" />
- <property name="localWorkers" value="2" />
- <property name="extraParams" value="" />
-
- <mkdir dir="${module.output.dir}" />
-
- <echo>Compiling ${module} to ${module.output.dir} with parameters -logLevel TRACE -style ${style} -localWorkers ${localWorkers} -strict ${extraParams}</echo>
-
- <!--<ivy:resolve inline="true" organisation="javax.validation" module="validation-api" revision="1.0.0.GA"/>-->
-
- <!-- compile the module -->
- <java classname="com.google.gwt.dev.Compiler" classpathref="classpath" failonerror="yes" fork="yes" maxmemory="512m">
- <arg value="-workDir" />
- <arg value="${work.dir}" />
- <arg value="-logLevel" />
- <arg value="TRACE" />
- <arg value="-war" />
- <arg value="${module.output.dir}" />
- <arg value="-style" />
- <arg value="${style}" />
-
- <arg value="-localWorkers" />
- <arg value="${localWorkers}" />
- <arg value="-strict" />
- <arg line="${extraParams}" />
- <arg value="${module}" />
-
- <sysproperty key="vFailIfNotSerializable" value="true" />
-
- <jvmarg value="-Xss8M" />
- <jvmarg value="-XX:MaxPermSize=256M" />
- <jvmarg value="-Djava.awt.headless=true" />
- <jvmarg value="-Dgwt.usearchives=false" />
- </java>
- </target>
- <target name="vaadinPush.js">
- <property name="vaadinPush.js.output" location="WebContent/VAADIN/vaadinPush.js" />
-
- <loadfile srcfile="WebContent/VAADIN/jquery-1.7.2.js" property="jquery.js.contents" />
- <loadfile srcfile="WebContent/VAADIN/jquery.atmosphere.js" property="jquery.atmosphere.js.contents" />
- <loadfile srcfile="WebContent/VAADIN/vaadinPush.js.tpl" property="vaadinPush.js.contents">
- <filterchain>
- <replacetokens begintoken="@" endtoken="@">
- <token key="jquery.js" value="${jquery.js.contents}" />
- <token key="jquery.atmosphere.js" value="${jquery.atmosphere.js.contents}" />
- </replacetokens>
- </filterchain>
- </loadfile>
- <echo file="${vaadinPush.js.output}">${vaadinPush.js.contents}</echo>
- </target>
+<project xmlns:antcontrib="antlib:net.sf.antcontrib"
+ xmlns:artifact="antlib:org.apache.maven.artifact.ant" xmlns:ivy="antlib:org.apache.ivy.ant"
+ name="Build script for IDE users" basedir=".."
+ default="theme-and-default-widgetset">
+ <include file="${basedir}/gwt-files.xml" />
+
+ <property name="gwt.dev.classes" location="${gwt.eclipse.basedir}/dev/bin" />
+ <property name="gwt.user.classes" location="${gwt.eclipse.basedir}/user/bin" />
+ <property name="gwt.dev.src" location="${gwt.basedir}/dev/core/src" />
+ <property name="gwt.dev.super.src" location="${gwt.basedir}/dev/core/super" />
+ <property name="gwt.user.src" location="${gwt.basedir}/user/src" />
+ <property name="gwt.user.super.src" location="${gwt.basedir}/user/super" />
+
+ <property name="work.dir" location="work" />
+ <property name="theme-version" location="9.9.9.INTERNAL-DEBUG-BUILD" />
+ <echo>Using gwt files from ${gwt.user.classes} and
+ ${gwt.dev.classes}</echo>
+
+ <ivy:resolve file="client-compiler/ivy.xml" conf="ide" />
+ <ivy:cachepath pathid="client-compiler.deps" conf="ide" />
+ <ivy:resolve file="server/ivy.xml" conf="ide" />
+ <ivy:cachepath pathid="server.deps" conf="ide" />
+ <ivy:resolve file="client/ivy.xml" conf="ide" />
+ <ivy:cachepath pathid="client.deps" conf="ide" />
+ <ivy:resolve file="shared/ivy.xml" conf="ide" />
+ <ivy:cachepath pathid="shared.deps" conf="ide" />
+ <ivy:resolve file="uitest/ivy.xml" conf="ide" />
+ <ivy:cachepath pathid="uitest.deps" conf="ide" />
+ <ivy:resolve file="theme-compiler/ivy.xml" conf="ide" />
+ <ivy:cachepath pathid="theme-compiler.deps" conf="ide" />
+
+ <path id="classpath">
+ <path location="bin" />
+ <path location="build/classes" />
+ <path location="${gwt.user.classes}" />
+ <path location="${gwt.user.src}" />
+ <path location="${gwt.user.super.src}" />
+ <path location="${gwt.dev.classes}" />
+ <path location="${gwt.dev.super.src}" />
+ <path location="${gwt.dev.src}" />
+ <path refid="client-compiler.deps" />
+ <path refid="theme-compiler.deps" />
+ <path refid="server.deps" />
+ <path refid="shared.deps" />
+ <path refid="uitest.deps" />
+ <path refid="client.deps" />
+ <path location="theme-compiler/src" />
+ <path location="server/src" />
+ <path location="shared/src" />
+ <path location="uitest/src" />
+ <path location="client/src" />
+ </path>
+
+ <target name="theme-and-default-widgetset" depends="default-widgetset, themes, vaadinPush.js">
+ </target>
+ <target name="themes">
+ <antcall target="compile-theme">
+ <param name="theme" value="base" />
+ </antcall>
+ <antcall target="compile-theme">
+ <param name="theme" value="runo" />
+ </antcall>
+ <antcall target="compile-theme">
+ <param name="theme" value="reindeer" />
+ </antcall>
+ <antcall target="compile-theme">
+ <param name="theme" value="chameleon" />
+ </antcall>
+ <antcall target="compile-theme">
+ <param name="theme" value="liferay" />
+ </antcall>
+ </target>
+
+ <target name="compile-theme">
+ <java classname="com.vaadin.buildhelpers.CompileTheme"
+ failonerror="yes" fork="yes">
+ <classpath refid="classpath" />
+ <jvmarg value="-Djava.awt.headless=true" />
+ <arg value="--theme" />
+ <arg value="${theme}" />
+ <arg value="--theme-version" />
+ <arg value="${theme-version}" />
+ <arg value="--theme-folder" />
+ <arg value="WebContent/VAADIN/themes" />
+ </java>
+
+ </target>
+
+
+ <target name="default-widgetset">
+ <antcall target="compile-widgetset">
+ <param name="widgetset" value="com.vaadin.DefaultWidgetSet" />
+ </antcall>
+ </target>
+
+ <target name="testing-widgetset">
+ <antcall target="compile-widgetset">
+ <param name="widgetset"
+ value="com.vaadin.tests.widgetset.TestingWidgetSet" />
+ </antcall>
+ </target>
+
+ <target name="compile-widgetset">
+ <property name="module" value="${widgetset}" />
+ <property name="module.output.dir" location="WebContent/VAADIN/widgetsets" />
+ <property name="style" value="PRETTY" />
+ <property name="localWorkers" value="2" />
+ <property name="extraParams" value="" />
+
+ <mkdir dir="${module.output.dir}" />
+
+ <echo>Compiling ${module} to ${module.output.dir} with
+ parameters -logLevel TRACE -style ${style} -localWorkers
+ ${localWorkers} -strict ${extraParams}</echo>
+
+ <!--<ivy:resolve inline="true" organisation="javax.validation" module="validation-api"
+ revision="1.0.0.GA"/> -->
+
+ <!-- compile the module -->
+ <java classname="com.google.gwt.dev.Compiler" classpathref="classpath"
+ failonerror="yes" fork="yes" maxmemory="512m">
+ <arg value="-workDir" />
+ <arg value="${work.dir}" />
+ <arg value="-logLevel" />
+ <arg value="TRACE" />
+ <arg value="-war" />
+ <arg value="${module.output.dir}" />
+ <arg value="-style" />
+ <arg value="${style}" />
+
+ <arg value="-localWorkers" />
+ <arg value="${localWorkers}" />
+ <arg value="-strict" />
+ <arg line="${extraParams}" />
+ <arg value="${module}" />
+
+ <sysproperty key="vFailIfNotSerializable" value="true" />
+
+ <jvmarg value="-Xss8M" />
+ <jvmarg value="-XX:MaxPermSize=256M" />
+ <jvmarg value="-Djava.awt.headless=true" />
+ <jvmarg value="-Dgwt.usearchives=false" />
+ </java>
+ </target>
+ <target name="vaadinPush.js">
+ <property name="vaadinPush.js.output" location="WebContent/VAADIN/vaadinPush.js" />
+
+ <loadfile srcfile="WebContent/VAADIN/jquery-1.7.2.js"
+ property="jquery.js.contents" />
+ <loadfile srcfile="WebContent/VAADIN/jquery.atmosphere.js"
+ property="jquery.atmosphere.js.contents" />
+ <loadfile srcfile="WebContent/VAADIN/vaadinPush.js.tpl"
+ property="vaadinPush.js.contents">
+ <filterchain>
+ <replacetokens begintoken="@" endtoken="@">
+ <token key="jquery.js" value="${jquery.js.contents}" />
+ <token key="jquery.atmosphere.js" value="${jquery.atmosphere.js.contents}" />
+ </replacetokens>
+ </filterchain>
+ </loadfile>
+ <echo file="${vaadinPush.js.output}">${vaadinPush.js.contents}</echo>
+ </target>
</project> \ No newline at end of file
diff --git a/buildhelpers/build.xml b/buildhelpers/build.xml
index a101bff191..aa1eb8cb0d 100644
--- a/buildhelpers/build.xml
+++ b/buildhelpers/build.xml
@@ -1,50 +1,51 @@
<?xml version="1.0"?>
<project name="vaadin-buildhelpers" basedir="." default="publish-local">
- <description>
- Compiles build helpers used when building other modules.
- </description>
- <include file="../build.xml" as="vaadin" />
- <include file="../common.xml" as="common" />
-
- <property name="module.name" value="vaadin-buildhelpers" />
- <property name="module.symbolic" value="com.vaadin.buildhelpers" />
- <property name="result.dir" location="result" />
- <path id="classpath.compile.custom" />
-
- <target name="jar">
- <antcall target="common.jar">
- <reference torefid="extra.jar.includes" refid="empty.reference" />
- </antcall>
- </target>
-
- <target name="publish-local" depends="jar">
- <antcall target="common.sources.jar">
- <reference torefid="extra.jar.includes" refid="empty.reference" />
- </antcall>
- <antcall target="common.javadoc.jar" />
- <antcall target="common.publish-local" />
- </target>
-
- <target name="clean">
- <antcall target="common.clean" />
- </target>
-
- <target name="checkstyle">
- <antcall target="common.checkstyle">
- <param name="cs.src" location="src" />
- </antcall>
- </target>
-
- <target name="fetch-release-notes-tickets">
- <antcall target="common.exec-buildhelper">
- <param name="main.class" value="com.vaadin.buildhelpers.FetchReleaseNotesTickets" />
- <param name="output" value="${output}" />
- </antcall>
- </target>
-
- <target name="test" depends="checkstyle">
- <!--<antcall target="common.test.run" />-->
- <echo>WHAT? No JUnit tests for ${module.name}!</echo>
- </target>
+ <description>
+ Compiles build helpers used when building other modules.
+ </description>
+ <include file="../build.xml" as="vaadin" />
+ <include file="../common.xml" as="common" />
+
+ <property name="module.name" value="vaadin-buildhelpers" />
+ <property name="module.symbolic" value="com.vaadin.buildhelpers" />
+ <property name="result.dir" location="result" />
+ <path id="classpath.compile.custom" />
+
+ <target name="jar">
+ <antcall target="common.jar">
+ <reference torefid="extra.jar.includes" refid="empty.reference" />
+ </antcall>
+ </target>
+
+ <target name="publish-local" depends="jar">
+ <antcall target="common.sources.jar">
+ <reference torefid="extra.jar.includes" refid="empty.reference" />
+ </antcall>
+ <antcall target="common.javadoc.jar" />
+ <antcall target="common.publish-local" />
+ </target>
+
+ <target name="clean">
+ <antcall target="common.clean" />
+ </target>
+
+ <target name="checkstyle">
+ <antcall target="common.checkstyle">
+ <param name="cs.src" location="src" />
+ </antcall>
+ </target>
+
+ <target name="fetch-release-notes-tickets">
+ <antcall target="common.exec-buildhelper">
+ <param name="main.class"
+ value="com.vaadin.buildhelpers.FetchReleaseNotesTickets" />
+ <param name="output" value="${output}" />
+ </antcall>
+ </target>
+
+ <target name="test" depends="checkstyle">
+ <!--<antcall target="common.test.run" /> -->
+ <echo>WHAT? No JUnit tests for ${module.name}!</echo>
+ </target>
</project> \ No newline at end of file
diff --git a/buildhelpers/ivy.xml b/buildhelpers/ivy.xml
index 7c0a7b82a7..21c2a808cc 100644
--- a/buildhelpers/ivy.xml
+++ b/buildhelpers/ivy.xml
@@ -28,7 +28,7 @@
</publications>
<dependencies>
- <dependency org="commons-io" name="commons-io" rev="2.2" />
+ <dependency org="commons-io" name="commons-io" rev="2.2" />
</dependencies>
</ivy-module>
diff --git a/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java b/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java
index 588fe1aba1..5c3810099a 100644
--- a/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java
+++ b/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java
@@ -46,8 +46,15 @@ public class FetchReleaseNotesTickets {
// This is the header
continue;
}
+ String summary = fields[1];
+ if (summary.startsWith("\"") && summary.endsWith("\"")) {
+ // If a summary starts with " and ends with " then all quotes in
+ // the summary are encoded as double quotes
+ summary = summary.substring(1, summary.length() - 1);
+ summary = summary.replace("\"\"", "\"");
+ }
System.out.println(ticketTemplate.replace("@ticket@", fields[0])
- .replace("@description@", fields[1]));
+ .replace("@description@", summary));
}
urlStream.close();
}
diff --git a/client-compiled/build.xml b/client-compiled/build.xml
index c9c3244c0e..01bf2fa15e 100644
--- a/client-compiled/build.xml
+++ b/client-compiled/build.xml
@@ -1,139 +1,149 @@
<?xml version="1.0"?>
-<project name="vaadin-client-compiled" basedir="." default="publish-local" xmlns:ivy="antlib:org.apache.ivy.ant">
- <description>
- Compiled (JS+HTML) version of client side
- </description>
-
- <include file="../common.xml" as="common" />
- <include file="../build.xml" as="vaadin" />
- <include file="../gwt-files.xml" as="gwtfiles" />
-
- <!-- global properties -->
- <property name="module.name" value="vaadin-client-compiled" />
- <property name="module.symbolic" value="com.vaadin.client-compiled" />
- <property name="result.dir" value="result" />
- <property name="gwtar.dir" location="${result.dir}/gwtar" />
- <property name="work.dir" location="${result.dir}/work" />
- <property name="module.output.dir" location="${result.dir}/VAADIN/widgetsets" />
- <property name="compiled.jar" location="${result.dir}/lib/${module.name}-${vaadin.version}.jar" />
- <property name="compiled-cache.jar" location="${result.dir}/lib/${module.name}-cache-${vaadin.version}.jar" />
-
- <union id="jar.includes">
- <fileset dir="${result.dir}">
- <include name="VAADIN/widgetsets/com.vaadin*/**" />
- </fileset>
- </union>
-
- <target name="default-widgetset-cache">
- <antcall target="compile-module-cache">
- <param name="module" value="com.vaadin.DefaultWidgetSet" />
- </antcall>
- </target>
-
- <target name="default-widgetset">
- <antcall target="compile-module">
- <param name="module" value="com.vaadin.DefaultWidgetSet" />
- </antcall>
- </target>
-
-
- <target name="compile-module-cache">
- <fail unless="module" message="You must give the module to compile in the 'module' parameter" />
- <ivy:resolve resolveid="common" conf="compile-module" />
- <ivy:cachepath pathid="classpath.compile.widgetset" conf="compile-module" />
- <echo>Creating gwtar files for ${module} in ${gwtar.dir}</echo>
-
- <!-- Produce gwtar files for the separate JAR -->
- <java classname="com.google.gwt.dev.CompileModule" classpathref="classpath.compile.widgetset" failonerror="yes" fork="yes" maxmemory="512m">
- <arg value="-out" />
- <arg value="${gwtar.dir}" />
- <arg value="-strict" />
- <arg value="${module}" />
-
- <jvmarg value="-Xss8M" />
- <jvmarg value="-XX:MaxPermSize=256M" />
- <jvmarg value="-Djava.awt.headless=true" />
- </java>
- </target>
-
- <target name="compile-module">
- <fail unless="module" message="You must give the module to compile in the 'module' parameter" />
- <property name="style" value="OBF" />
- <property name="localWorkers" value="2" />
- <property name="extraParams" value="" />
-
- <ivy:resolve resolveid="common" conf="compile-module" />
- <ivy:cachepath pathid="classpath.compile.widgetset" conf="compile-module" />
-
- <mkdir dir="${module.output.dir}" />
-
- <echo>Compiling ${module} to ${module.output.dir}</echo>
-
- <!-- compile the module -->
- <java classname="com.google.gwt.dev.Compiler" classpathref="classpath.compile.widgetset" failonerror="yes" fork="yes" maxmemory="512m">
- <classpath location="${compiled-cache.jar}" />
- <arg value="-workDir" />
- <arg value="${work.dir}" />
- <arg value="-logLevel" />
- <arg value="TRACE" />
- <arg value="-war" />
- <arg value="${module.output.dir}" />
- <arg value="-style" />
- <arg value="${style}" />
-
- <arg value="-localWorkers" />
- <arg value="${localWorkers}" />
- <arg value="-strict" />
- <arg value="-XenableClosureCompiler" />
- <arg line="${extraParams}" />
- <arg value="${module}" />
-
- <sysproperty key="vFailIfNotSerializable" value="true" />
-
- <jvmarg value="-Xss8M" />
- <jvmarg value="-XX:MaxPermSize=256M" />
- <jvmarg value="-Djava.awt.headless=true" />
- </java>
-
- </target>
-
- <target name="client-compiled-cache.jar" depends="default-widgetset-cache">
- <!-- Ensure filtered webcontent files are available -->
- <antcall target="common.filter.webcontent" />
-
- <jar file="${compiled-cache.jar}" compress="true">
- <fileset dir="${gwtar.dir}">
- <include name="**/*.gwtar" />
- </fileset>
- <union refid="client-compiled-cache.gwt.includes" />
- <fileset refid="common.files.for.all.jars" />
- </jar>
- </target>
-
- <target name="jar" depends="default-widgetset">
- <antcall target="common.jar">
- <param name="osgi.extra.package.prefixes" value="VAADIN/widgetsets/" />
- <reference torefid="extra.jar.includes" refid="jar.includes" />
- </antcall>
- </target>
-
- <target name="publish-local" depends="jar">
- <antcall target="common.publish-local">
- <param name="conf" value="build" />
- </antcall>
- </target>
-
- <target name="clean">
- <antcall target="common.clean" />
- </target>
-
- <target name="checkstyle">
- <echo>No java files in module</echo>
- </target>
- <target name="test" depends="checkstyle">
- <!--<antcall target="common.test.run" />-->
- <echo>WHAT? No tests for ${module.name}!</echo>
- </target>
+<project name="vaadin-client-compiled" basedir="." default="publish-local"
+ xmlns:ivy="antlib:org.apache.ivy.ant">
+ <description>
+ Compiled (JS+HTML) version of client side
+ </description>
+
+ <include file="../common.xml" as="common" />
+ <include file="../build.xml" as="vaadin" />
+ <include file="../gwt-files.xml" as="gwtfiles" />
+
+ <!-- global properties -->
+ <property name="module.name" value="vaadin-client-compiled" />
+ <property name="module.symbolic" value="com.vaadin.client-compiled" />
+ <property name="result.dir" value="result" />
+ <property name="gwtar.dir" location="${result.dir}/gwtar" />
+ <property name="work.dir" location="${result.dir}/work" />
+ <property name="module.output.dir" location="${result.dir}/VAADIN/widgetsets" />
+ <property name="compiled.jar"
+ location="${result.dir}/lib/${module.name}-${vaadin.version}.jar" />
+ <property name="compiled-cache.jar"
+ location="${result.dir}/lib/${module.name}-cache-${vaadin.version}.jar" />
+
+ <union id="jar.includes">
+ <fileset dir="${result.dir}">
+ <include name="VAADIN/widgetsets/com.vaadin*/**" />
+ </fileset>
+ </union>
+
+ <target name="default-widgetset-cache">
+ <antcall target="compile-module-cache">
+ <param name="module" value="com.vaadin.DefaultWidgetSet" />
+ </antcall>
+ </target>
+
+ <target name="default-widgetset">
+ <antcall target="compile-module">
+ <param name="module" value="com.vaadin.DefaultWidgetSet" />
+ </antcall>
+ </target>
+
+
+ <target name="compile-module-cache">
+ <fail unless="module"
+ message="You must give the module to compile in the 'module' parameter" />
+ <ivy:resolve resolveid="common" conf="compile-module" />
+ <ivy:cachepath pathid="classpath.compile.widgetset"
+ conf="compile-module" />
+ <echo>Creating gwtar files for ${module} in ${gwtar.dir}</echo>
+
+ <!-- Produce gwtar files for the separate JAR -->
+ <java classname="com.google.gwt.dev.CompileModule"
+ classpathref="classpath.compile.widgetset" failonerror="yes"
+ fork="yes" maxmemory="512m">
+ <arg value="-out" />
+ <arg value="${gwtar.dir}" />
+ <arg value="-strict" />
+ <arg value="${module}" />
+
+ <jvmarg value="-Xss8M" />
+ <jvmarg value="-XX:MaxPermSize=256M" />
+ <jvmarg value="-Djava.awt.headless=true" />
+ </java>
+ </target>
+
+ <target name="compile-module">
+ <fail unless="module"
+ message="You must give the module to compile in the 'module' parameter" />
+ <property name="style" value="OBF" />
+ <property name="localWorkers" value="2" />
+ <property name="extraParams" value="" />
+
+ <ivy:resolve resolveid="common" conf="compile-module" />
+ <ivy:cachepath pathid="classpath.compile.widgetset"
+ conf="compile-module" />
+
+ <mkdir dir="${module.output.dir}" />
+
+ <echo>Compiling ${module} to ${module.output.dir}</echo>
+
+ <!-- compile the module -->
+ <java classname="com.google.gwt.dev.Compiler" classpathref="classpath.compile.widgetset"
+ failonerror="yes" fork="yes" maxmemory="512m">
+ <classpath location="${compiled-cache.jar}" />
+ <arg value="-workDir" />
+ <arg value="${work.dir}" />
+ <arg value="-logLevel" />
+ <arg value="TRACE" />
+ <arg value="-war" />
+ <arg value="${module.output.dir}" />
+ <arg value="-style" />
+ <arg value="${style}" />
+
+ <arg value="-localWorkers" />
+ <arg value="${localWorkers}" />
+ <arg value="-strict" />
+ <arg value="-XenableClosureCompiler" />
+ <arg line="${extraParams}" />
+ <arg value="${module}" />
+
+ <sysproperty key="vFailIfNotSerializable" value="true" />
+
+ <jvmarg value="-Xss8M" />
+ <jvmarg value="-XX:MaxPermSize=256M" />
+ <jvmarg value="-Djava.awt.headless=true" />
+ </java>
+
+ </target>
+
+ <target name="client-compiled-cache.jar" depends="default-widgetset-cache">
+ <!-- Ensure filtered webcontent files are available -->
+ <antcall target="common.filter.webcontent" />
+
+ <jar file="${compiled-cache.jar}" compress="true">
+ <fileset dir="${gwtar.dir}">
+ <include name="**/*.gwtar" />
+ </fileset>
+ <union refid="client-compiled-cache.gwt.includes" />
+ <fileset refid="common.files.for.all.jars" />
+ </jar>
+ </target>
+
+ <target name="jar" depends="default-widgetset">
+ <antcall target="common.jar">
+ <param name="osgi.extra.package.prefixes" value="VAADIN/widgetsets/" />
+ <reference torefid="extra.jar.includes" refid="jar.includes" />
+ </antcall>
+ </target>
+
+ <target name="publish-local" depends="jar">
+ <antcall target="common.publish-local">
+ <param name="conf" value="build" />
+ </antcall>
+ </target>
+
+ <target name="clean">
+ <antcall target="common.clean" />
+ </target>
+
+ <target name="checkstyle">
+ <echo>No java files in module</echo>
+ </target>
+ <target name="test" depends="checkstyle">
+ <!--<antcall target="common.test.run" /> -->
+ <echo>WHAT? No tests for ${module.name}!</echo>
+ </target>
</project>
diff --git a/client-compiled/ivy.xml b/client-compiled/ivy.xml
index 7802775f70..2f1dcfd22f 100644
--- a/client-compiled/ivy.xml
+++ b/client-compiled/ivy.xml
@@ -14,8 +14,8 @@
</configurations>
<publications>
<artifact type="jar" ext="jar" />
-<!-- <artifact type="source" ext="jar" m:classifier="sources" /> -->
-<!-- <artifact type="javadoc" ext="jar" m:classifier="javadoc" /> -->
+ <!-- <artifact type="source" ext="jar" m:classifier="sources" /> -->
+ <!-- <artifact type="javadoc" ext="jar" m:classifier="javadoc" /> -->
<artifact type="pom" ext="pom" />
<!-- cache must be a separate artifact, not within vaadin-client-compiled -->
<!-- <artifact type="jar" name="vaadin-client-compiled-cache"/> -->
diff --git a/client-compiler/build.xml b/client-compiler/build.xml
index cd8433f1cf..0ed4d7b0e3 100644
--- a/client-compiler/build.xml
+++ b/client-compiler/build.xml
@@ -1,68 +1,70 @@
<?xml version="1.0"?>
-<project name="vaadin-client-compiler" basedir="." default="publish-local" xmlns:ivy="antlib:org.apache.ivy.ant">
- <description>
- Compiles build helpers used when building other modules.
- </description>
- <include file="../common.xml" as="common" />
- <include file="../build.xml" as="vaadin" />
- <include file="../gwt-files.xml" as="gwtfiles" />
+<project name="vaadin-client-compiler" basedir="." default="publish-local"
+ xmlns:ivy="antlib:org.apache.ivy.ant">
+ <description>
+ Compiles build helpers used when building other modules.
+ </description>
+ <include file="../common.xml" as="common" />
+ <include file="../build.xml" as="vaadin" />
+ <include file="../gwt-files.xml" as="gwtfiles" />
- <!-- global properties -->
- <property name="module.name" value="vaadin-client-compiler" />
- <property name="module.symbolic" value="com.vaadin.client-compiler" />
- <property name="result.dir" value="result" />
- <path id="classpath.compile.custom">
- <fileset file="${gwt.dev.jar}" />
- </path>
+ <!-- global properties -->
+ <property name="module.name" value="vaadin-client-compiler" />
+ <property name="module.symbolic" value="com.vaadin.client-compiler" />
+ <property name="result.dir" value="result" />
+ <path id="classpath.compile.custom">
+ <fileset file="${gwt.dev.jar}" />
+ </path>
- <union id="compiler.includes">
- <union refid="client-compiler.gwt.includes" />
- <fileset dir="${result.dir}">
- <include name="com/google/gwt/dev/About.properties" />
- </fileset>
- </union>
+ <union id="compiler.includes">
+ <union refid="client-compiler.gwt.includes" />
+ <fileset dir="${result.dir}">
+ <include name="com/google/gwt/dev/About.properties" />
+ </fileset>
+ </union>
- <target name="jar">
- <!-- Get Git revision -->
- <exec executable="git" outputproperty="git.revision" failifexecutionfails="false" errorproperty="">
- <arg value="describe" />
- <arg value="--tags" />
- <arg value="--always" />
- <arg value="HEAD" />
- </exec>
+ <target name="jar">
+ <!-- Get Git revision -->
+ <exec executable="git" outputproperty="git.revision"
+ failifexecutionfails="false" errorproperty="">
+ <arg value="describe" />
+ <arg value="--tags" />
+ <arg value="--always" />
+ <arg value="HEAD" />
+ </exec>
- <echo file="${result.dir}/com/google/gwt/dev/About.properties">gwt.version=${vaadin.version}
-gwt.svnrev=${git.revision}</echo>
+ <echo file="${result.dir}/com/google/gwt/dev/About.properties">gwt.version=${vaadin.version}
+ gwt.svnrev=${git.revision}</echo>
- <antcall target="common.jar">
- <reference refid="compiler.includes" torefid="extra.jar.includes" />
- </antcall>
+ <antcall target="common.jar">
+ <reference refid="compiler.includes" torefid="extra.jar.includes" />
+ </antcall>
- </target>
+ </target>
- <target name="publish-local" depends="jar">
- <antcall target="common.sources.jar">
- <reference torefid="extra.jar.includes" refid="compiler.includes" />
- </antcall>
- <antcall target="common.javadoc.jar" />
+ <target name="publish-local" depends="jar">
+ <antcall target="common.sources.jar">
+ <reference torefid="extra.jar.includes" refid="compiler.includes" />
+ </antcall>
+ <antcall target="common.javadoc.jar" />
- <antcall target="common.publish-local" />
- </target>
+ <antcall target="common.publish-local" />
+ </target>
- <target name="clean">
- <antcall target="common.clean" />
- </target>
+ <target name="clean">
+ <antcall target="common.clean" />
+ </target>
- <target name="checkstyle">
- <antcall target="common.checkstyle">
- <param name="cs.src" location="src" />
- </antcall>
- </target>
+ <target name="checkstyle">
+ <antcall target="common.checkstyle">
+ <param name="cs.src" location="src" />
+ </antcall>
+ </target>
- <target name="test" depends="checkstyle">
- <!--<antcall target="common.test.run" />-->
- <echo>WHAT? No tests for ${module.name}!</echo>
- </target>
+ <target name="test" depends="checkstyle">
+ <!--<antcall target="common.test.run" /> -->
+ <echo>WHAT? No tests for ${module.name}!</echo>
+ </target>
</project> \ No newline at end of file
diff --git a/client-compiler/ivy.xml b/client-compiler/ivy.xml
index b26de51aca..f66a2e0255 100644
--- a/client-compiler/ivy.xml
+++ b/client-compiler/ivy.xml
@@ -1,62 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd"
- xmlns:m="http://ant.apache.org/ivy/maven">
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd"
+ xmlns:m="http://ant.apache.org/ivy/maven">
- <info organisation="com.vaadin" module="vaadin-client-compiler"
- revision="${vaadin.version}" />
+ <info organisation="com.vaadin" module="vaadin-client-compiler"
+ revision="${vaadin.version}" />
- <configurations>
- <conf name="build" />
- <conf name="build-provided" />
- <conf name="ide" visibility="private" />
- </configurations>
- <publications>
- <artifact type="jar" ext="jar" />
- <artifact type="source" ext="jar" m:classifier="sources" />
- <artifact type="javadoc" ext="jar" m:classifier="javadoc" />
- <artifact type="pom" ext="pom" />
- </publications>
- <dependencies>
- <dependency org="com.vaadin" name="vaadin-shared" rev="${vaadin.version}"
- conf="build" />
- <dependency org="com.vaadin" name="vaadin-server" rev="${vaadin.version}"
- conf="build" />
- <dependency org="com.vaadin" name="vaadin-client" rev="${vaadin.version}"
- conf="build" />
- <dependency org="com.vaadin" name="vaadin-theme-compiler"
- rev="${vaadin.version}" conf="build" />
+ <configurations>
+ <conf name="build" />
+ <conf name="build-provided" />
+ <conf name="ide" visibility="private" />
+ </configurations>
+ <publications>
+ <artifact type="jar" ext="jar" />
+ <artifact type="source" ext="jar" m:classifier="sources" />
+ <artifact type="javadoc" ext="jar" m:classifier="javadoc" />
+ <artifact type="pom" ext="pom" />
+ </publications>
+ <dependencies>
+ <dependency org="com.vaadin" name="vaadin-shared"
+ rev="${vaadin.version}" conf="build" />
+ <dependency org="com.vaadin" name="vaadin-server"
+ rev="${vaadin.version}" conf="build" />
+ <dependency org="com.vaadin" name="vaadin-client"
+ rev="${vaadin.version}" conf="build" />
+ <dependency org="com.vaadin" name="vaadin-theme-compiler"
+ rev="${vaadin.version}" conf="build" />
- <dependency org="commons-collections" name="commons-collections"
- rev="3.1" conf="build,ide -> default" />
- <dependency org="commons-logging" name="commons-logging"
- rev="1.1.1" conf="build,ide -> default" />
+ <dependency org="commons-collections" name="commons-collections"
+ rev="3.1" conf="build,ide -> default" />
+ <dependency org="commons-logging" name="commons-logging"
+ rev="1.1.1" conf="build,ide -> default" />
- <dependency org="ant" name="ant" rev="1.6.5" conf="build,ide -> default" />
- <dependency org="net.sourceforge.cssparser" name="cssparser"
- rev="0.9.5" conf="build,ide -> default" />
- <dependency org="ant" name="ant" rev="1.6.5" conf="build,ide -> default" />
- <dependency org="ant" name="ant-launcher" rev="1.6.5"
- conf="build,ide -> default" />
- <dependency org="org.mortbay.jetty" name="jetty" rev="6.1.11"
- conf="build,ide -> default" />
- <dependency org="org.mortbay.jetty" name="jetty-util" rev="6.1.11"
- conf="build,ide -> default" />
- <dependency org="org.jdesktop" name="swing-worker" rev="1.1"
- conf="build,ide -> default" />
- <dependency org="commons-codec" name="commons-codec" rev="1.3"
- conf="build,ide -> default" />
- <dependency org="commons-io" name="commons-io" rev="2.2"
- conf="build,ide -> default" />
- <dependency org="commons-lang" name="commons-lang" rev="2.6"
- conf="build,ide -> default" />
- <dependency org="org.apache.james" name="apache-mime4j"
- rev="0.6" conf="build,ide -> default" />
+ <dependency org="ant" name="ant" rev="1.6.5"
+ conf="build,ide -> default" />
+ <dependency org="net.sourceforge.cssparser" name="cssparser"
+ rev="0.9.5" conf="build,ide -> default" />
+ <dependency org="ant" name="ant" rev="1.6.5"
+ conf="build,ide -> default" />
+ <dependency org="ant" name="ant-launcher" rev="1.6.5"
+ conf="build,ide -> default" />
+ <dependency org="org.mortbay.jetty" name="jetty" rev="6.1.11"
+ conf="build,ide -> default" />
+ <dependency org="org.mortbay.jetty" name="jetty-util"
+ rev="6.1.11" conf="build,ide -> default" />
+ <dependency org="org.jdesktop" name="swing-worker"
+ rev="1.1" conf="build,ide -> default" />
+ <dependency org="commons-codec" name="commons-codec"
+ rev="1.3" conf="build,ide -> default" />
+ <dependency org="commons-io" name="commons-io" rev="2.2"
+ conf="build,ide -> default" />
+ <dependency org="commons-lang" name="commons-lang"
+ rev="2.6" conf="build,ide -> default" />
+ <dependency org="org.apache.james" name="apache-mime4j"
+ rev="0.6" conf="build,ide -> default" />
- <dependency org="com.vaadin" name="vaadin-client-compiler-deps"
- rev="1.0.1" conf="build,ide -> default" />
+ <dependency org="com.vaadin" name="vaadin-client-compiler-deps"
+ rev="1.0.2" conf="build,ide -> default" />
- </dependencies>
+ </dependencies>
</ivy-module>
diff --git a/client/build.xml b/client/build.xml
index a2262eed7d..a027d00f60 100644
--- a/client/build.xml
+++ b/client/build.xml
@@ -1,43 +1,46 @@
<?xml version="1.0"?>
-<project name="vaadin-client" basedir="." default="publish-local" xmlns:ivy="antlib:org.apache.ivy.ant">
- <description>
- Compiles build helpers used when building other modules.
- </description>
- <include file="../common.xml" as="common" />
- <include file="../build.xml" as="vaadin" />
- <include file="../gwt-files.xml" as="gwtfiles" />
+<project name="vaadin-client" basedir="." default="publish-local"
+ xmlns:ivy="antlib:org.apache.ivy.ant">
+ <description>
+ Compiles build helpers used when building other modules.
+ </description>
+ <include file="../common.xml" as="common" />
+ <include file="../build.xml" as="vaadin" />
+ <include file="../gwt-files.xml" as="gwtfiles" />
- <!-- global properties -->
- <property name="module.name" value="vaadin-client" />
- <property name="module.symbolic" value="com.vaadin.client" />
- <property name="result.dir" value="result" />
+ <!-- global properties -->
+ <property name="module.name" value="vaadin-client" />
+ <property name="module.symbolic" value="com.vaadin.client" />
+ <property name="result.dir" value="result" />
- <path id="classpath.compile.custom">
- <!-- Could possibly compile GWT files also here to verify that
- a) the same dependencies are used and
- b) all dependencies have been declared
- -->
- <fileset file="${gwt.user.jar}" />
- </path>
- <path id="classpath.test.custom" />
+ <path id="classpath.compile.custom">
+ <!-- Could possibly compile GWT files also here to verify that a)
+ the same dependencies are used and b) all dependencies have been declared -->
+ <fileset file="${gwt.user.jar}" />
+ </path>
+ <path id="classpath.test.custom" />
- <target name="jar">
- <property name="jar.file" location="${result.dir}/lib/${module.name}-${vaadin.version}.jar" />
- <antcall target="common.jar">
- <reference refid="client.gwt.includes" torefid="extra.jar.includes" />
- </antcall>
- <jar destfile="${jar.file}" update="true">
- <manifest>
- <attribute name="Vaadin-Package-Version" value="1" />
- <attribute name="Vaadin-Widgetsets" value="com.vaadin.DefaultWidgetSet" />
- </manifest>
- </jar>
- <!-- Hack to add validation dependency with source classifier -->
- <property name="pom.xml" location="${result.dir}/lib/${module.name}-${vaadin.version}.pom" />
- <copy file="${pom.xml}" tofile="${temp.pom}">
- <filterchain>
- <replacestring from=" &lt;/dependencies&gt;" to=" &lt;dependency&gt;
+ <target name="jar">
+ <property name="jar.file"
+ location="${result.dir}/lib/${module.name}-${vaadin.version}.jar" />
+ <antcall target="common.jar">
+ <reference refid="client.gwt.includes" torefid="extra.jar.includes" />
+ </antcall>
+ <jar destfile="${jar.file}" update="true">
+ <manifest>
+ <attribute name="Vaadin-Package-Version"
+ value="1" />
+ <attribute name="Vaadin-Widgetsets" value="com.vaadin.DefaultWidgetSet" />
+ </manifest>
+ </jar>
+ <!-- Hack to add validation dependency with source classifier -->
+ <property name="pom.xml"
+ location="${result.dir}/lib/${module.name}-${vaadin.version}.pom" />
+ <copy file="${pom.xml}" tofile="${temp.pom}">
+ <filterchain>
+ <replacestring from=" &lt;/dependencies&gt;"
+ to=" &lt;dependency&gt;
&lt;groupId&gt;javax.validation&lt;/groupId&gt;
&lt;artifactId&gt;validation-api&lt;/artifactId&gt;
&lt;version&gt;1.0.0.GA&lt;/version&gt;
@@ -45,32 +48,32 @@
&lt;classifier&gt;sources&lt;/classifier&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;" />
- </filterchain>
- </copy>
- <move file="${temp.pom}" tofile="${pom.xml}" />
- </target>
+ </filterchain>
+ </copy>
+ <move file="${temp.pom}" tofile="${pom.xml}" />
+ </target>
- <target name="publish-local" depends="jar">
- <antcall target="common.sources.jar">
- <reference torefid="extra.jar.includes" refid="client.gwt.includes" />
- </antcall>
- <antcall target="common.javadoc.jar" />
+ <target name="publish-local" depends="jar">
+ <antcall target="common.sources.jar">
+ <reference torefid="extra.jar.includes" refid="client.gwt.includes" />
+ </antcall>
+ <antcall target="common.javadoc.jar" />
- <antcall target="common.publish-local" />
- </target>
+ <antcall target="common.publish-local" />
+ </target>
- <target name="clean">
- <antcall target="common.clean" />
- </target>
+ <target name="clean">
+ <antcall target="common.clean" />
+ </target>
- <target name="checkstyle">
- <antcall target="common.checkstyle">
- <param name="cs.src" location="src" />
- </antcall>
- </target>
+ <target name="checkstyle">
+ <antcall target="common.checkstyle">
+ <param name="cs.src" location="src" />
+ </antcall>
+ </target>
- <target name="test" depends="checkstyle">
- <antcall target="common.test.run" />
- </target>
+ <target name="test" depends="checkstyle">
+ <antcall target="common.test.run" />
+ </target>
</project> \ No newline at end of file
diff --git a/client/src/com/vaadin/DefaultWidgetSet.gwt.xml b/client/src/com/vaadin/DefaultWidgetSet.gwt.xml
index 26ab7478e0..3aba1f6fee 100755
--- a/client/src/com/vaadin/DefaultWidgetSet.gwt.xml
+++ b/client/src/com/vaadin/DefaultWidgetSet.gwt.xml
@@ -1,13 +1,13 @@
<module>
- <!-- This GWT module defines the Vaadin DefaultWidgetSet. This is the module
- you want to extend when creating an extended widget set, or when creating
- a specialized widget set with a subset of the components. -->
+ <!-- This GWT module defines the Vaadin DefaultWidgetSet. This is the
+ module you want to extend when creating an extended widget set, or when creating
+ a specialized widget set with a subset of the components. -->
- <!-- Hint for WidgetSetBuilder not to automatically update the file -->
- <!-- WS Compiler: manually edited -->
+ <!-- Hint for WidgetSetBuilder not to automatically update the file -->
+ <!-- WS Compiler: manually edited -->
- <inherits name="com.vaadin.Vaadin" />
+ <inherits name="com.vaadin.Vaadin" />
- <entry-point class="com.vaadin.client.ApplicationConfiguration" />
+ <entry-point class="com.vaadin.client.ApplicationConfiguration" />
</module>
diff --git a/client/src/com/vaadin/Vaadin.gwt.xml b/client/src/com/vaadin/Vaadin.gwt.xml
index a4eb88d9b4..776886bb1b 100644
--- a/client/src/com/vaadin/Vaadin.gwt.xml
+++ b/client/src/com/vaadin/Vaadin.gwt.xml
@@ -12,13 +12,14 @@
<inherits name="com.google.gwt.http.HTTP" />
<inherits name="com.google.gwt.json.JSON" />
-
+
<inherits name="com.google.gwt.logging.Logging" />
- <!-- Firebug handler is deprecated but for some reason still enabled by default -->
+ <!-- Firebug handler is deprecated but for some reason still enabled
+ by default -->
<set-property name="gwt.logging.firebugHandler" value="DISABLED" />
<!-- Disable popup logging as we have our own popup logger -->
<set-property name="gwt.logging.popupHandler" value="DISABLED" />
-
+
<inherits name="com.vaadin.VaadinBrowserSpecificOverrides" />
<source path="client" />
@@ -40,21 +41,26 @@
<when-type-assignable
class="com.vaadin.client.metadata.ConnectorBundleLoader" />
</generate-with>
-
- <replace-with class="com.vaadin.client.communication.AtmospherePushConnection">
+
+ <replace-with
+ class="com.vaadin.client.communication.AtmospherePushConnection">
<when-type-is class="com.vaadin.client.communication.PushConnection" />
- </replace-with>
-
- <!-- Set vaadin.profiler to true to include profiling support in the module -->
+ </replace-with>
+
+ <!-- Set vaadin.profiler to true to include profiling support in the
+ module -->
<define-property name="vaadin.profiler" values="true,false" />
- <set-property name="vaadin.profiler" value="false" />
-
+ <set-property name="vaadin.profiler" value="false" />
+
<replace-with class="com.vaadin.client.Profiler.EnabledProfiler">
<when-type-is class="com.vaadin.client.Profiler" />
<when-property-is name="vaadin.profiler" value="true" />
- </replace-with>
+ </replace-with>
<!-- Use the new cross site linker to get a nocache.js without document.write -->
<add-linker name="xsiframe" />
+ <!-- Remove IE6/IE7 permutation as they are not supported -->
+ <set-property name="user.agent" value="ie8,ie9,gecko1_8,safari,opera" />
+
</module>
diff --git a/client/src/com/vaadin/VaadinBrowserSpecificOverrides.gwt.xml b/client/src/com/vaadin/VaadinBrowserSpecificOverrides.gwt.xml
index ba6c171a7d..45ede928f5 100644
--- a/client/src/com/vaadin/VaadinBrowserSpecificOverrides.gwt.xml
+++ b/client/src/com/vaadin/VaadinBrowserSpecificOverrides.gwt.xml
@@ -1,54 +1,55 @@
<module>
- <!-- This GWT module defines the browser specific overrides used by Vaadin -->
-
- <!-- Hint for WidgetSetBuilder not to automatically update the file -->
- <!-- WS Compiler: manually edited -->
-
- <!-- Fall through to this rule for everything but IE -->
- <replace-with
- class="com.vaadin.client.ui.upload.UploadIFrameOnloadStrategy">
- <when-type-is
- class="com.vaadin.client.ui.upload.UploadIFrameOnloadStrategy" />
- </replace-with>
-
- <replace-with
- class="com.vaadin.client.ui.upload.UploadIFrameOnloadStrategyIE">
- <when-type-is
- class="com.vaadin.client.ui.upload.UploadIFrameOnloadStrategy" />
- <any>
- <when-property-is name="user.agent" value="ie8" />
- </any>
- </replace-with>
-
- <!-- Fall through to this rule for everything but IE -->
- <replace-with class="com.vaadin.client.ui.VDragAndDropWrapper">
- <when-type-is class="com.vaadin.client.ui.VDragAndDropWrapper" />
- </replace-with>
-
- <replace-with class="com.vaadin.client.ui.VDragAndDropWrapperIE">
- <when-type-is class="com.vaadin.client.ui.VDragAndDropWrapper" />
- <any>
- <when-property-is name="user.agent" value="ie8" />
- </any>
- </replace-with>
-
- <!-- Fall through to this rule for everything but IE -->
- <replace-with class="com.vaadin.client.LayoutManager">
- <when-type-is class="com.vaadin.client.LayoutManager" />
- </replace-with>
-
- <replace-with class="com.vaadin.client.LayoutManagerIE8">
- <when-type-is class="com.vaadin.client.LayoutManager" />
- <any>
- <when-property-is name="user.agent" value="ie8" />
- </any>
- </replace-with>
-
- <replace-with class="com.vaadin.client.ui.VPopupImpl">
- <when-type-is class="com.google.gwt.user.client.ui.impl.PopupImplMozilla" />
- <when-property-is name="user.agent" value="gecko1_8"/>
- </replace-with>
-
+ <!-- This GWT module defines the browser specific overrides used by Vaadin -->
+
+ <!-- Hint for WidgetSetBuilder not to automatically update the file -->
+ <!-- WS Compiler: manually edited -->
+
+ <!-- Fall through to this rule for everything but IE -->
+ <replace-with
+ class="com.vaadin.client.ui.upload.UploadIFrameOnloadStrategy">
+ <when-type-is
+ class="com.vaadin.client.ui.upload.UploadIFrameOnloadStrategy" />
+ </replace-with>
+
+ <replace-with
+ class="com.vaadin.client.ui.upload.UploadIFrameOnloadStrategyIE">
+ <when-type-is
+ class="com.vaadin.client.ui.upload.UploadIFrameOnloadStrategy" />
+ <any>
+ <when-property-is name="user.agent" value="ie8" />
+ </any>
+ </replace-with>
+
+ <!-- Fall through to this rule for everything but IE -->
+ <replace-with class="com.vaadin.client.ui.VDragAndDropWrapper">
+ <when-type-is class="com.vaadin.client.ui.VDragAndDropWrapper" />
+ </replace-with>
+
+ <replace-with class="com.vaadin.client.ui.VDragAndDropWrapperIE">
+ <when-type-is class="com.vaadin.client.ui.VDragAndDropWrapper" />
+ <any>
+ <when-property-is name="user.agent" value="ie8" />
+ </any>
+ </replace-with>
+
+ <!-- Fall through to this rule for everything but IE -->
+ <replace-with class="com.vaadin.client.LayoutManager">
+ <when-type-is class="com.vaadin.client.LayoutManager" />
+ </replace-with>
+
+ <replace-with class="com.vaadin.client.LayoutManagerIE8">
+ <when-type-is class="com.vaadin.client.LayoutManager" />
+ <any>
+ <when-property-is name="user.agent" value="ie8" />
+ </any>
+ </replace-with>
+
+ <replace-with class="com.vaadin.client.ui.VPopupImpl">
+ <when-type-is
+ class="com.google.gwt.user.client.ui.impl.PopupImplMozilla" />
+ <when-property-is name="user.agent" value="gecko1_8" />
+ </replace-with>
+
<replace-with class="com.vaadin.client.ui.VPopupImpl">
<when-type-is class="com.google.gwt.user.client.ui.impl.PopupImpl" />
</replace-with>
diff --git a/client/src/com/vaadin/client/ApplicationConfiguration.java b/client/src/com/vaadin/client/ApplicationConfiguration.java
index adf5e1de9d..9152e5ab23 100644
--- a/client/src/com/vaadin/client/ApplicationConfiguration.java
+++ b/client/src/com/vaadin/client/ApplicationConfiguration.java
@@ -38,6 +38,7 @@ import com.vaadin.client.debug.internal.ErrorNotificationHandler;
import com.vaadin.client.debug.internal.HierarchySection;
import com.vaadin.client.debug.internal.LogSection;
import com.vaadin.client.debug.internal.NetworkSection;
+import com.vaadin.client.debug.internal.ProfilerSection;
import com.vaadin.client.debug.internal.Section;
import com.vaadin.client.debug.internal.VDebugWindow;
import com.vaadin.client.metadata.BundleLoadCallback;
@@ -578,6 +579,9 @@ public class ApplicationConfiguration implements EntryPoint {
}
window.addSection((Section) GWT.create(HierarchySection.class));
window.addSection((Section) GWT.create(NetworkSection.class));
+ if (Profiler.isEnabled()) {
+ window.addSection((Section) GWT.create(ProfilerSection.class));
+ }
if (isQuietDebugMode()) {
window.close();
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java
index 4141f9f2dc..ac058b5536 100644
--- a/client/src/com/vaadin/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/client/ApplicationConnection.java
@@ -95,6 +95,7 @@ import com.vaadin.shared.communication.LegacyChangeVariablesInvocation;
import com.vaadin.shared.communication.MethodInvocation;
import com.vaadin.shared.communication.SharedState;
import com.vaadin.shared.ui.ui.UIConstants;
+import com.vaadin.shared.ui.ui.UIState.PushConfigurationState;
/**
* This is the client side communication "engine", managing client-server
@@ -221,8 +222,6 @@ public class ApplicationConnection {
private Date requestStartTime;
- private boolean validatingLayouts = false;
-
private final LayoutManager layoutManager;
private final RpcManager rpcManager;
@@ -466,7 +465,8 @@ public class ApplicationConnection {
Element overlayContainer = VOverlay.getOverlayContainer(this);
Roles.getAlertRole().setAriaLiveProperty(overlayContainer,
LiveValue.ASSERTIVE);
- setOverlayContainerLabel(getUIConnector().getState().overlayContainerLabel);
+ VOverlay.setOverlayContainerLabel(this,
+ getUIConnector().getState().overlayContainerLabel);
Roles.getAlertRole().setAriaRelevantProperty(overlayContainer,
RelevantValue.ADDITIONS);
}
@@ -677,11 +677,12 @@ public class ApplicationConnection {
/**
* Requests an analyze of layouts, to find inconsistencies. Exclusively used
* for debugging during development.
+ *
+ * @deprecated as of 7.1. Replaced by {@link UIConnector#analyzeLayouts()}
*/
+ @Deprecated
public void analyzeLayouts() {
- String params = getRepaintAllParameters() + "&"
- + ApplicationConstants.PARAM_ANALYZE_LAYOUTS + "=1";
- makeUidlRequest("", params);
+ getUIConnector().analyzeLayouts();
}
/**
@@ -690,12 +691,12 @@ public class ApplicationConnection {
* source code.
*
* @param serverConnector
+ * @deprecated as of 7.1. Replaced by
+ * {@link UIConnector#showServerDebugInfo(ServerConnector)}
*/
+ @Deprecated
void highlightConnector(ServerConnector serverConnector) {
- String params = getRepaintAllParameters() + "&"
- + ApplicationConstants.PARAM_HIGHLIGHT_CONNECTOR + "="
- + serverConnector.getConnectorId();
- makeUidlRequest("", params);
+ getUIConnector().showServerDebugInfo(serverConnector);
}
/**
@@ -1350,16 +1351,6 @@ public class ApplicationConnection {
handleUIDLDuration.logDuration(" * Loading widgets completed",
10);
- Profiler.enter("Handling locales");
- if (json.containsKey("locales")) {
- VConsole.log(" * Handling locales");
- // Store locale data
- JsArray<ValueMap> valueMapArray = json
- .getJSValueMapArray("locales");
- LocaleService.addLocales(valueMapArray);
- }
- Profiler.leave("Handling locales");
-
Profiler.enter("Handling meta information");
ValueMap meta = null;
if (json.containsKey("meta")) {
@@ -1367,9 +1358,6 @@ public class ApplicationConnection {
meta = json.getValueMap("meta");
if (meta.containsKey("repaintAll")) {
prepareRepaintAll();
- if (meta.containsKey("invalidLayouts")) {
- validatingLayouts = true;
- }
}
if (meta.containsKey("timedRedirect")) {
final ValueMap timedRedirect = meta
@@ -1399,6 +1387,17 @@ public class ApplicationConnection {
JsArrayObject<StateChangeEvent> pendingStateChangeEvents = updateConnectorState(
json, createdConnectorIds);
+ /*
+ * Doing this here so that locales are available also to the
+ * connectors which get a state change event before the UI.
+ */
+ Profiler.enter("Handling locales");
+ VConsole.log(" * Handling locales");
+ // Store locale data
+ LocaleService
+ .addLocales(getUIConnector().getState().localeServiceState.localeData);
+ Profiler.leave("Handling locales");
+
// Update hierarchy, do not fire events
ConnectorHierarchyUpdateResult connectorHierarchyUpdateResult = updateConnectorHierarchy(json);
@@ -1459,17 +1458,6 @@ public class ApplicationConnection {
applicationRunning = false;
}
- if (validatingLayouts) {
- Set<ComponentConnector> zeroHeightComponents = new HashSet<ComponentConnector>();
- Set<ComponentConnector> zeroWidthComponents = new HashSet<ComponentConnector>();
- findZeroSizeComponents(zeroHeightComponents,
- zeroWidthComponents, getUIConnector());
- VConsole.printLayoutProblems(meta,
- ApplicationConnection.this,
- zeroHeightComponents, zeroWidthComponents);
- validatingLayouts = false;
-
- }
Profiler.leave("Error handling");
}
@@ -2224,28 +2212,6 @@ public class ApplicationConnection {
ApplicationConfiguration.runWhenDependenciesLoaded(c);
}
- private void findZeroSizeComponents(
- Set<ComponentConnector> zeroHeightComponents,
- Set<ComponentConnector> zeroWidthComponents,
- ComponentConnector connector) {
- Widget widget = connector.getWidget();
- ComputedStyle computedStyle = new ComputedStyle(widget.getElement());
- if (computedStyle.getIntProperty("height") == 0) {
- zeroHeightComponents.add(connector);
- }
- if (computedStyle.getIntProperty("width") == 0) {
- zeroWidthComponents.add(connector);
- }
- List<ServerConnector> children = connector.getChildren();
- for (ServerConnector serverConnector : children) {
- if (serverConnector instanceof ComponentConnector) {
- findZeroSizeComponents(zeroHeightComponents,
- zeroWidthComponents,
- (ComponentConnector) serverConnector);
- }
- }
- }
-
private void loadStyleDependencies(JsArrayString dependencies) {
// Assuming no reason to interpret in a defined order
ResourceLoadListener resourceLoadListener = new ResourceLoadListener() {
@@ -3276,14 +3242,6 @@ public class ApplicationConnection {
Timer forceHandleMessage = new Timer() {
@Override
public void run() {
- if (responseHandlingLocks.isEmpty()) {
- /*
- * Timer fired but there's nothing to clear. This can happen
- * with IE8 as Timer.cancel is not always effective (see GWT
- * issue 8101).
- */
- return;
- }
VConsole.log("WARNING: reponse handling was never resumed, forcibly removing locks...");
responseHandlingLocks.clear();
handlePendingMessages();
@@ -3402,9 +3360,17 @@ public class ApplicationConnection {
* <code>false</code> to disable the push connection.
*/
public void setPushEnabled(boolean enabled) {
+ final PushConfigurationState pushState = uIConnector.getState().pushConfiguration;
+
if (enabled && push == null) {
push = GWT.create(PushConnection.class);
- push.init(this);
+ push.init(this, pushState, new CommunicationErrorHandler() {
+ @Override
+ public boolean onError(String details, int statusCode) {
+ showCommunicationError(details, statusCode);
+ return true;
+ }
+ });
} else if (!enabled && push != null && push.isActive()) {
push.disconnect(new Command() {
@Override
@@ -3415,7 +3381,7 @@ public class ApplicationConnection {
* the old connection to disconnect, now is the right time
* to open a new connection
*/
- if (uIConnector.getState().pushMode.isEnabled()) {
+ if (pushState.mode.isEnabled()) {
setPushEnabled(true);
}
@@ -3434,17 +3400,4 @@ public class ApplicationConnection {
public void handlePushMessage(String message) {
handleJSONText(message, 200);
}
-
- /**
- * Set the label of the container element, where tooltip, notification and
- * dialgs are added to.
- *
- * @param overlayContainerLabel
- * label for the container
- */
- public void setOverlayContainerLabel(String overlayContainerLabel) {
- Roles.getAlertRole().setAriaLabelProperty(
- VOverlay.getOverlayContainer(this),
- getUIConnector().getState().overlayContainerLabel);
- }
}
diff --git a/client/src/com/vaadin/client/DateTimeService.java b/client/src/com/vaadin/client/DateTimeService.java
index 53e8f81a38..5fd0574d3e 100644
--- a/client/src/com/vaadin/client/DateTimeService.java
+++ b/client/src/com/vaadin/client/DateTimeService.java
@@ -308,10 +308,11 @@ public class DateTimeService {
*/
public String formatDate(Date date, String formatStr) {
/*
- * Format month names separately when locale for the DateTimeService is
- * not the same as the browser locale
+ * Format month and day names separately when locale for the
+ * DateTimeService is not the same as the browser locale
*/
formatStr = formatMonthNames(date, formatStr);
+ formatStr = formatDayNames(date, formatStr);
// Format uses the browser locale
DateTimeFormat format = DateTimeFormat.getFormat(formatStr);
@@ -321,6 +322,49 @@ public class DateTimeService {
return result;
}
+ private String formatDayNames(Date date, String formatStr) {
+ if (formatStr.contains("EEEE")) {
+ String dayName = getDay(date.getDay());
+
+ if (dayName != null) {
+ /*
+ * Replace 4 or more E:s with the quoted day name. Also
+ * concatenate generated string with any other string prepending
+ * or following the EEEE pattern, i.e. 'EEEE'ta ' becomes 'DAYta
+ * ' and not 'DAY''ta ', 'ab'EEEE becomes 'abDAY', 'x'EEEE'y'
+ * becomes 'xDAYy'.
+ */
+ formatStr = formatStr.replaceAll("'([E]{4,})'", dayName);
+ formatStr = formatStr.replaceAll("([E]{4,})'", "'" + dayName);
+ formatStr = formatStr.replaceAll("'([E]{4,})", dayName + "'");
+ formatStr = formatStr
+ .replaceAll("[E]{4,}", "'" + dayName + "'");
+ }
+ }
+
+ if (formatStr.contains("EEE")) {
+
+ String dayName = getShortDay(date.getMonth());
+
+ if (dayName != null) {
+ /*
+ * Replace 3 or more E:s with the quoted month name. Also
+ * concatenate generated string with any other string prepending
+ * or following the EEE pattern, i.e. 'EEE'ta ' becomes 'DAYta '
+ * and not 'DAY''ta ', 'ab'EEE becomes 'abDAY', 'x'EEE'y'
+ * becomes 'xDAYy'.
+ */
+ formatStr = formatStr.replaceAll("'([E]{3,})'", dayName);
+ formatStr = formatStr.replaceAll("([E]{3,})'", "'" + dayName);
+ formatStr = formatStr.replaceAll("'([E]{3,})", dayName + "'");
+ formatStr = formatStr
+ .replaceAll("[E]{3,}", "'" + dayName + "'");
+ }
+ }
+
+ return formatStr;
+ }
+
private String formatMonthNames(Date date, String formatStr) {
if (formatStr.contains("MMMM")) {
String monthName = getMonth(date.getMonth());
diff --git a/client/src/com/vaadin/client/LocaleService.java b/client/src/com/vaadin/client/LocaleService.java
index 4009c95531..69345d7174 100644
--- a/client/src/com/vaadin/client/LocaleService.java
+++ b/client/src/com/vaadin/client/LocaleService.java
@@ -17,10 +17,12 @@
package com.vaadin.client;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.logging.Logger;
-import com.google.gwt.core.client.JsArray;
+import com.vaadin.shared.ui.ui.UIState.LocaleData;
/**
* Date / time etc. localisation service for all widgets. Caches all loaded
@@ -31,16 +33,17 @@ import com.google.gwt.core.client.JsArray;
*/
public class LocaleService {
- private static Map<String, ValueMap> cache = new HashMap<String, ValueMap>();
- private static String defaultLocale;
+ private static Map<String, LocaleData> cache = new HashMap<String, LocaleData>();
- public static void addLocale(ValueMap valueMap) {
+ private static String defaultLocale;
- final String key = valueMap.getString("name");
+ public static void addLocale(LocaleData localeData) {
+ final String key = localeData.name;
if (cache.containsKey(key)) {
cache.remove(key);
}
- cache.put(key, valueMap);
+ getLogger().fine("Received locale data for " + localeData.name);
+ cache.put(key, localeData);
if (cache.size() == 1) {
setDefaultLocale(key);
}
@@ -61,8 +64,7 @@ public class LocaleService {
public static String[] getMonthNames(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("mn");
+ return cache.get(locale).monthNames;
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -71,8 +73,7 @@ public class LocaleService {
public static String[] getShortMonthNames(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("smn");
+ return cache.get(locale).shortMonthNames;
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -81,8 +82,7 @@ public class LocaleService {
public static String[] getDayNames(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("dn");
+ return cache.get(locale).dayNames;
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -91,8 +91,7 @@ public class LocaleService {
public static String[] getShortDayNames(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("sdn");
+ return cache.get(locale).shortDayNames;
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -101,8 +100,7 @@ public class LocaleService {
public static int getFirstDayOfWeek(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getInt("fdow");
+ return cache.get(locale).firstDayOfWeek;
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -111,8 +109,7 @@ public class LocaleService {
public static String getDateFormat(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getString("df");
+ return cache.get(locale).dateFormat;
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -121,8 +118,7 @@ public class LocaleService {
public static boolean isTwelveHourClock(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getBoolean("thc");
+ return cache.get(locale).twelveHourClock;
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -131,8 +127,7 @@ public class LocaleService {
public static String getClockDelimiter(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getString("hmd");
+ return cache.get(locale).hourMinuteDelimiter;
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -141,20 +136,19 @@ public class LocaleService {
public static String[] getAmPmStrings(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("ampm");
+ return new String[] { cache.get(locale).am, cache.get(locale).pm };
} else {
throw new LocaleNotLoadedException(locale);
}
-
}
- public static void addLocales(JsArray<ValueMap> valueMapArray) {
- for (int i = 0; i < valueMapArray.length(); i++) {
- addLocale(valueMapArray.get(i));
-
+ public static void addLocales(List<LocaleData> localeDatas) {
+ for (LocaleData localeData : localeDatas) {
+ addLocale(localeData);
}
-
}
+ private static Logger getLogger() {
+ return Logger.getLogger(LocaleService.class.getName());
+ }
}
diff --git a/client/src/com/vaadin/client/Profiler.java b/client/src/com/vaadin/client/Profiler.java
index 95b3232723..caa512b34e 100644
--- a/client/src/com/vaadin/client/Profiler.java
+++ b/client/src/com/vaadin/client/Profiler.java
@@ -23,13 +23,14 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
+import java.util.logging.Logger;
import com.google.gwt.core.client.Duration;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.shared.GWT;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.client.debug.internal.ProfilerSection.Node;
+import com.vaadin.client.debug.internal.ProfilerSection.ProfilerResultConsumer;
/**
* Lightweight profiling tool that can be used to collect profiling data with
@@ -96,137 +97,7 @@ public class Profiler {
}
}
- private static class Node {
-
- private final String name;
- private final LinkedHashMap<String, Node> children = new LinkedHashMap<String, Node>();
- private double time = 0;
- private int count = 0;
-
- public Node(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- private Node accessChild(String name, double time) {
- Node child = children.get(name);
- if (child == null) {
- child = new Node(name);
- children.put(name, child);
- }
- child.time -= time;
- child.count++;
- return child;
- }
-
- public double getTimeSpent() {
- return time;
- }
-
- public int getCount() {
- return count;
- }
-
- public double getOwnTime() {
- double time = getTimeSpent();
- for (Node node : children.values()) {
- time -= node.getTimeSpent();
- }
- return time;
- }
-
- public Widget buildTree() {
- String message = getStringRepresentation("");
-
- if (getName() == null || !children.isEmpty()) {
- SimpleTree tree = new SimpleTree(message);
- for (Node node : children.values()) {
- Widget child = node.buildTree();
- tree.add(child);
- }
- return tree;
- } else {
- return new Label(message);
- }
- }
-
- public void buildRecursiveString(StringBuilder builder, String prefix) {
- if (getName() != null) {
- String msg = getStringRepresentation(prefix);
- builder.append(msg + '\n');
- }
- String childPrefix = prefix + "*";
- for (Node node : children.values()) {
- node.buildRecursiveString(builder, childPrefix);
- }
- }
-
- @Override
- public String toString() {
- return getStringRepresentation("");
- }
-
- private String getStringRepresentation(String prefix) {
- if (getName() == null) {
- return "";
- }
- String msg = prefix + " " + getName() + " in " + getTimeSpent()
- + " ms.";
- if (getCount() > 1) {
- msg += " Invoked "
- + getCount()
- + " times ("
- + roundToSignificantFigures(getTimeSpent() / getCount())
- + " ms per time).";
- }
- if (!children.isEmpty()) {
- double ownTime = getOwnTime();
- msg += " " + ownTime + " ms spent in own code";
- if (getCount() > 1) {
- msg += " ("
- + roundToSignificantFigures(ownTime / getCount())
- + " ms per time)";
- }
- msg += '.';
- }
- return msg;
- }
-
- public static double roundToSignificantFigures(double num) {
- // Number of significant digits
- int n = 3;
- if (num == 0) {
- return 0;
- }
-
- final double d = Math.ceil(Math.log10(num < 0 ? -num : num));
- final int power = n - (int) d;
-
- final double magnitude = Math.pow(10, power);
- final long shifted = Math.round(num * magnitude);
- return shifted / magnitude;
- }
-
- public void sumUpTotals(Map<String, Node> totals) {
- String name = getName();
- if (name != null) {
- Node totalNode = totals.get(name);
- if (totalNode == null) {
- totalNode = new Node(name);
- totals.put(name, totalNode);
- }
-
- totalNode.time += getOwnTime();
- totalNode.count += getCount();
- }
- for (Node node : children.values()) {
- node.sumUpTotals(totals);
- }
- }
- }
+ private static ProfilerResultConsumer consumer;
/**
* Checks whether the profiling gathering is enabled.
@@ -323,7 +194,8 @@ public class Profiler {
*/
public static void logTimings() {
if (!isEnabled()) {
- VConsole.log("Profiler is not enabled, no data has been collected.");
+ getLogger().warning(
+ "Profiler is not enabled, no data has been collected.");
return;
}
@@ -332,7 +204,9 @@ public class Profiler {
stack.add(rootNode);
JsArray<GwtStatsEvent> gwtStatsEvents = getGwtStatsEvents();
if (gwtStatsEvents.length() == 0) {
- VConsole.log("No profiling events recorded, this might happen if another __gwtStatsEvent handler is installed.");
+ getLogger()
+ .warning(
+ "No profiling events recorded, this might happen if another __gwtStatsEvent handler is installed.");
return;
}
@@ -347,10 +221,10 @@ public class Profiler {
&& !isBeginEvent;
if (!inEvent && stack.size() >= 2
- && eventName.equals(stack.get(stack.size() - 2).name)
+ && eventName.equals(stack.get(stack.size() - 2).getName())
&& !isBeginEvent) {
// back out of sub event
- stackTop.time += gwtStatsEvent.getMillis();
+ stackTop.addTime(gwtStatsEvent.getMillis());
stack.removeLast();
stackTop = stack.getLast();
@@ -359,41 +233,35 @@ public class Profiler {
if (type.equals("end")) {
if (!inEvent) {
- VConsole.error("Got end event for " + eventName
- + " but is currently in " + stackTop.getName());
+ getLogger().severe(
+ "Got end event for " + eventName
+ + " but is currently in "
+ + stackTop.getName());
return;
}
Node previousStackTop = stack.removeLast();
- previousStackTop.time += gwtStatsEvent.getMillis();
+ previousStackTop.addTime(gwtStatsEvent.getMillis());
} else {
if (!inEvent) {
- stackTop = stackTop.accessChild(eventName,
+ stackTop = stackTop.enterChild(eventName,
gwtStatsEvent.getMillis());
stack.add(stackTop);
}
if (!isBeginEvent) {
// Create sub event
- stack.add(stackTop.accessChild(eventName + "." + type,
+ stack.add(stackTop.enterChild(eventName + "." + type,
gwtStatsEvent.getMillis()));
}
}
}
if (stack.size() != 1) {
- VConsole.log("Not all nodes are left, the last node is "
- + stack.getLast().getName());
+ getLogger().warning(
+ "Not all nodes are left, the last node is "
+ + stack.getLast().getName());
return;
}
- StringBuilder stringBuilder = new StringBuilder();
- rootNode.buildRecursiveString(stringBuilder, "");
-
- /*
- * Should really output to a separate section in the debug window, but
- * just dump it to the log for now.
- */
- VConsole.log(stringBuilder.toString());
-
Map<String, Node> totals = new HashMap<String, Node>();
rootNode.sumUpTotals(totals);
@@ -405,27 +273,7 @@ public class Profiler {
}
});
- double total = 0;
- double top20total = 0;
- for (int i = 0; i < totalList.size(); i++) {
- Node node = totalList.get(i);
- double timeSpent = node.getTimeSpent();
- total += timeSpent;
- if (i < 20) {
- top20total += timeSpent;
- }
- }
-
- VConsole.log("Largest individual contributors using " + top20total
- + " ms out of " + total + " ms");
- for (int i = 0; i < 20 && i < totalList.size(); i++) {
- Node node = totalList.get(i);
- double timeSpent = node.getTimeSpent();
- total += timeSpent;
- VConsole.log(" * " + node.getName() + ": " + timeSpent + " ms in "
- + node.getCount() + " invokations.");
- }
-
+ getConsumer().addProfilerData(stack.getFirst(), totalList);
}
/**
@@ -460,28 +308,24 @@ public class Profiler {
"domContentLoadedEventStart", "domContentLoadedEventEnd",
"domComplete", "loadEventStart", "loadEventEnd" };
+ LinkedHashMap<String, Double> timings = new LinkedHashMap<String, Double>();
+
for (String key : keys) {
double value = getPerformanceTiming(key);
if (value == 0) {
// Ignore missing value
continue;
}
- String text = key + ": " + (now - value);
- tree.add(new Label(text));
- stringBuilder.append("\n * ");
- stringBuilder.append(text);
+ timings.put(key, Double.valueOf(now - value));
}
- if (tree.getWidgetCount() == 0) {
- VConsole.log("Bootstrap timings not supported, please ensure your browser supports performance.timing");
+ if (timings.isEmpty()) {
+ getLogger()
+ .info("Bootstrap timings not supported, please ensure your browser supports performance.timing");
return;
}
- /*
- * Should really output to a separate section in the debug window,
- * but just dump it to the log for now.
- */
- VConsole.log(stringBuilder.toString());
+ getConsumer().addBootstrapData(timings);
}
}
@@ -535,4 +379,35 @@ public class Profiler {
$wnd.vaadin.gwtStatsEvents = [];
}-*/;
+ /**
+ * Sets the profiler result consumer that is used to output the profiler
+ * data to the user.
+ * <p>
+ * <b>Warning!</b> This is internal API and should not be used by
+ * applications or add-ons.
+ *
+ * @since 7.1
+ * @param profilerResultConsumer
+ * the consumer that gets profiler data
+ */
+ public static void setProfilerResultConsuer(
+ ProfilerResultConsumer profilerResultConsumer) {
+ if (consumer != null) {
+ throw new IllegalStateException("The consumer has already been set");
+ }
+ consumer = profilerResultConsumer;
+ }
+
+ private static ProfilerResultConsumer getConsumer() {
+ if (consumer == null) {
+ throw new IllegalStateException("No consumer has been registered");
+ } else {
+ return consumer;
+ }
+ }
+
+ private static Logger getLogger() {
+ return Logger.getLogger(Profiler.class.getName());
+ }
+
}
diff --git a/client/src/com/vaadin/client/ResourceLoader.java b/client/src/com/vaadin/client/ResourceLoader.java
index 7fc8b4f9f3..3d8eb739b1 100644
--- a/client/src/com/vaadin/client/ResourceLoader.java
+++ b/client/src/com/vaadin/client/ResourceLoader.java
@@ -323,7 +323,11 @@ public class ResourceLoader {
} else {
ObjectElement element = Document.get().createObjectElement();
element.setData(url);
- element.setType("text/plain");
+ if (BrowserInfo.get().isChrome()) {
+ element.setType("text/cache");
+ } else {
+ element.setType("text/plain");
+ }
element.setHeight("0px");
element.setWidth("0px");
return element;
diff --git a/client/src/com/vaadin/client/VConsole.java b/client/src/com/vaadin/client/VConsole.java
index f7a7554e34..37ed8e6370 100644
--- a/client/src/com/vaadin/client/VConsole.java
+++ b/client/src/com/vaadin/client/VConsole.java
@@ -15,7 +15,6 @@
*/
package com.vaadin.client;
-import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -81,9 +80,7 @@ public class VConsole {
}
public static void printLayoutProblems(ValueMap meta,
- ApplicationConnection applicationConnection,
- Set<ComponentConnector> zeroHeightComponents,
- Set<ComponentConnector> zeroWidthComponents) {
+ ApplicationConnection applicationConnection) {
if (impl != null) {
impl.meta(applicationConnection, meta);
}
diff --git a/client/src/com/vaadin/client/VLoadingIndicator.java b/client/src/com/vaadin/client/VLoadingIndicator.java
index fcce35781d..3b6cf2252c 100644
--- a/client/src/com/vaadin/client/VLoadingIndicator.java
+++ b/client/src/com/vaadin/client/VLoadingIndicator.java
@@ -42,75 +42,24 @@ public class VLoadingIndicator {
private int secondDelay = 1500;
private int thirdDelay = 5000;
- /**
- * Timer with method for checking if it has been cancelled. This class is a
- * workaround for a IE8 problem which causes a timer to be fired even if it
- * has been cancelled.
- *
- * @author Vaadin Ltd
- * @since 7.1
- */
- private abstract static class LoadingIndicatorTimer extends Timer {
- private boolean cancelled = false;
-
- @Override
- public void cancel() {
- super.cancel();
- cancelled = true;
- }
-
- @Override
- public void schedule(int delayMillis) {
- super.schedule(delayMillis);
- cancelled = false;
- }
-
- @Override
- public void scheduleRepeating(int periodMillis) {
- super.scheduleRepeating(periodMillis);
- cancelled = false;
- }
-
- /**
- * Checks if this timer has been cancelled.
- *
- * @return true if the timer has been cancelled, false otherwise
- */
- public boolean isCancelled() {
- return cancelled;
- }
- }
-
- private Timer firstTimer = new LoadingIndicatorTimer() {
+ private Timer firstTimer = new Timer() {
@Override
public void run() {
- if (isCancelled()) {
- // IE8 does not properly cancel the timer in all cases.
- return;
- }
show();
}
};
- private Timer secondTimer = new LoadingIndicatorTimer() {
+ private Timer secondTimer = new Timer() {
@Override
public void run() {
- if (isCancelled()) {
- // IE8 does not properly cancel the timer in all cases.
- return;
- }
getElement().setClassName(PRIMARY_STYLE_NAME);
getElement().addClassName("second");
// For backwards compatibility only
getElement().addClassName(PRIMARY_STYLE_NAME + "-delay");
}
};
- private Timer thirdTimer = new LoadingIndicatorTimer() {
+ private Timer thirdTimer = new Timer() {
@Override
public void run() {
- if (isCancelled()) {
- // IE8 does not properly cancel the timer in all cases.
- return;
- }
getElement().setClassName(PRIMARY_STYLE_NAME);
getElement().addClassName("third");
// For backwards compatibility only
diff --git a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java
index bc7e0b3fd2..f7936f8717 100644
--- a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java
+++ b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java
@@ -22,12 +22,15 @@ import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.user.client.Command;
import com.vaadin.client.ApplicationConnection;
+import com.vaadin.client.ApplicationConnection.CommunicationErrorHandler;
import com.vaadin.client.ResourceLoader;
import com.vaadin.client.ResourceLoader.ResourceLoadEvent;
import com.vaadin.client.ResourceLoader.ResourceLoadListener;
import com.vaadin.client.VConsole;
import com.vaadin.shared.ApplicationConstants;
+import com.vaadin.shared.communication.PushConstants;
import com.vaadin.shared.ui.ui.UIConstants;
+import com.vaadin.shared.ui.ui.UIState.PushConfigurationState;
/**
* The default {@link PushConnection} implementation that uses Atmosphere for
@@ -67,8 +70,7 @@ public class AtmospherePushConnection implements PushConnection {
*/
protected static class FragmentedMessage {
- // Jetty requires length less than buffer size
- private int FRAGMENT_LENGTH = ApplicationConstants.WEBSOCKET_BUFFER_SIZE - 1;
+ private static final int FRAGMENT_LENGTH = PushConstants.WEBSOCKET_FRAGMENT_SIZE;
private String message;
private int index = 0;
@@ -82,10 +84,12 @@ public class AtmospherePushConnection implements PushConnection {
}
public String getNextFragment() {
+ assert hasNextFragment();
+
String result;
if (index == 0) {
String header = "" + message.length()
- + ApplicationConstants.WEBSOCKET_MESSAGE_DELIMITER;
+ + PushConstants.MESSAGE_DELIMITER;
int fragmentLen = FRAGMENT_LENGTH - header.length();
result = header + getFragment(0, fragmentLen);
index += fragmentLen;
@@ -115,6 +119,8 @@ public class AtmospherePushConnection implements PushConnection {
private String transport;
+ private CommunicationErrorHandler errorHandler;
+
/**
* Keeps track of the disconnect confirmation command for cases where
* pending messages should be pushed before actually disconnecting.
@@ -128,12 +134,21 @@ public class AtmospherePushConnection implements PushConnection {
* (non-Javadoc)
*
* @see
- * com.vaadin.client.communication.PushConenction#init(com.vaadin.client
- * .ApplicationConnection)
+ * com.vaadin.client.communication.PushConnection#init(ApplicationConnection
+ * , Map<String, String>, CommunicationErrorHandler)
*/
@Override
- public void init(final ApplicationConnection connection) {
+ public void init(final ApplicationConnection connection,
+ final PushConfigurationState pushConfiguration,
+ CommunicationErrorHandler errorHandler) {
this.connection = connection;
+ this.errorHandler = errorHandler;
+
+ config = createConfig();
+ for (String param : pushConfiguration.parameters.keySet()) {
+ config.setStringValue(param,
+ pushConfiguration.parameters.get(param));
+ }
runWhenAtmosphereLoaded(new Command() {
@Override
@@ -209,9 +224,6 @@ public class AtmospherePushConnection implements PushConnection {
}
protected AtmosphereConfiguration getConfig() {
- if (config == null) {
- config = createConfig();
- }
return config;
}
@@ -384,7 +396,8 @@ public class AtmospherePushConnection implements PushConnection {
contentType: 'application/json; charset=UTF-8',
reconnectInterval: '5000',
maxReconnectOnClose: 10000000,
- trackMessageLength: true
+ trackMessageLength: true,
+ messageDelimiter: String.fromCharCode(@com.vaadin.shared.communication.PushConstants::MESSAGE_DELIMITER)
};
}-*/;
@@ -430,22 +443,30 @@ public class AtmospherePushConnection implements PushConnection {
if (isAtmosphereLoaded()) {
command.execute();
} else {
- VConsole.log("Loading " + ApplicationConstants.VAADIN_PUSH_JS);
+ final String pushJs = ApplicationConstants.VAADIN_PUSH_JS;
+ VConsole.log("Loading " + pushJs);
ResourceLoader.get().loadScript(
- connection.getConfiguration().getVaadinDirUrl()
- + ApplicationConstants.VAADIN_PUSH_JS,
+ connection.getConfiguration().getVaadinDirUrl() + pushJs,
new ResourceLoadListener() {
@Override
public void onLoad(ResourceLoadEvent event) {
- VConsole.log(ApplicationConstants.VAADIN_PUSH_JS
- + " loaded");
- command.execute();
+ if (isAtmosphereLoaded()) {
+ VConsole.log(pushJs + " loaded");
+ command.execute();
+ } else {
+ // If bootstrap tried to load vaadinPush.js,
+ // ResourceLoader assumes it succeeded even if
+ // it failed (#11673)
+ onError(event);
+ }
}
@Override
public void onError(ResourceLoadEvent event) {
- VConsole.error(event.getResourceUrl()
- + " could not be loaded. Push will not work.");
+ errorHandler.onError(
+ event.getResourceUrl()
+ + " could not be loaded. Push will not work.",
+ 0);
}
});
}
diff --git a/client/src/com/vaadin/client/communication/PushConnection.java b/client/src/com/vaadin/client/communication/PushConnection.java
index 61656242bd..bc2af98f1a 100644
--- a/client/src/com/vaadin/client/communication/PushConnection.java
+++ b/client/src/com/vaadin/client/communication/PushConnection.java
@@ -18,6 +18,8 @@ package com.vaadin.client.communication;
import com.google.gwt.user.client.Command;
import com.vaadin.client.ApplicationConnection;
+import com.vaadin.client.ApplicationConnection.CommunicationErrorHandler;
+import com.vaadin.shared.ui.ui.UIState.PushConfigurationState;
/**
* Represents the client-side endpoint of a bidirectional ("push") communication
@@ -37,7 +39,9 @@ public interface PushConnection {
* @param connection
* The ApplicationConnection
*/
- public void init(ApplicationConnection connection);
+ public void init(ApplicationConnection connection,
+ PushConfigurationState pushConfigurationState,
+ CommunicationErrorHandler errorHandler);
/**
* Pushes a message to the server. Will throw an exception if the connection
diff --git a/client/src/com/vaadin/client/communication/StateChangeEvent.java b/client/src/com/vaadin/client/communication/StateChangeEvent.java
index e17a56aa69..e8fd95e818 100644
--- a/client/src/com/vaadin/client/communication/StateChangeEvent.java
+++ b/client/src/com/vaadin/client/communication/StateChangeEvent.java
@@ -52,7 +52,7 @@ public class StateChangeEvent extends
@Deprecated
private Set<String> changedPropertiesSet;
- private boolean isNewConnector = false;
+ private boolean initialStateChange = false;
private JSONObject stateJson;
@@ -110,15 +110,15 @@ public class StateChangeEvent extends
* the event whose state has changed
* @param stateJson
* the JSON representation of the state change
- * @param isNewConnector
+ * @param initialStateChange
* <code>true</code> if the state change is for a new connector,
* otherwise <code>false</code>
*/
public StateChangeEvent(ServerConnector connector, JSONObject stateJson,
- boolean isNewConnector) {
+ boolean initialStateChange) {
setConnector(connector);
this.stateJson = stateJson;
- this.isNewConnector = isNewConnector;
+ this.initialStateChange = initialStateChange;
}
@Override
@@ -178,7 +178,7 @@ public class StateChangeEvent extends
changedProperties = FastStringSet.create();
addJsonFields(stateJson, changedProperties, "");
- if (isNewConnector) {
+ if (isInitialStateChange()) {
addAllStateFields(
AbstractConnector.getStateType(getConnector()),
changedProperties, "");
@@ -198,7 +198,7 @@ public class StateChangeEvent extends
* <code>false></code>
*/
public boolean hasPropertyChanged(String property) {
- if (isNewConnector) {
+ if (isInitialStateChange()) {
// Everything has changed for a new connector
return true;
} else if (stateJson != null) {
@@ -309,4 +309,17 @@ public class StateChangeEvent extends
}
}
}
+
+ /**
+ * Checks if the state change event is the first one for the given
+ * connector.
+ *
+ * @since 7.1
+ * @return true if this is the first state change event for the connector,
+ * false otherwise
+ */
+ public boolean isInitialStateChange() {
+ return initialStateChange;
+ }
+
}
diff --git a/client/src/com/vaadin/client/debug/internal/ProfilerSection.java b/client/src/com/vaadin/client/debug/internal/ProfilerSection.java
new file mode 100644
index 0000000000..f9d401de88
--- /dev/null
+++ b/client/src/com/vaadin/client/debug/internal/ProfilerSection.java
@@ -0,0 +1,336 @@
+package com.vaadin.client.debug.internal;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.client.ApplicationConnection;
+import com.vaadin.client.Profiler;
+import com.vaadin.client.SimpleTree;
+import com.vaadin.client.ValueMap;
+
+/**
+ * Debug window section for investigating {@link Profiler} data. This section is
+ * only visible if the profiler is enabled ({@link Profiler#isEnabled()}).
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ *
+ * @see Profiler
+ */
+public class ProfilerSection implements Section {
+ /**
+ * Interface for getting data from the {@link Profiler}.
+ * <p>
+ * <b>Warning!</b> This interface is most likely to change in the future and
+ * is therefore defined in this class in an internal package instead of
+ * Profiler where it might seem more logical.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+ public interface ProfilerResultConsumer {
+ public void addProfilerData(Node rootNode, List<Node> totals);
+
+ public void addBootstrapData(LinkedHashMap<String, Double> timings);
+ }
+
+ /**
+ * A hierarchical representation of the time spent running a named block of
+ * code.
+ * <p>
+ * <b>Warning!</b> This class is most likely to change in the future and is
+ * therefore defined in this class in an internal package instead of
+ * Profiler where it might seem more logical.
+ */
+ public static class Node {
+ private final String name;
+ private final LinkedHashMap<String, Node> children = new LinkedHashMap<String, Node>();
+ private double time = 0;
+ private int count = 0;
+
+ /**
+ * Create a new node with the given name.
+ *
+ * @param name
+ */
+ public Node(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Gets the name of the node
+ *
+ * @return the name of the node
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Creates a new child node or retrieves and existing child and updates
+ * its total time and hit count.
+ *
+ * @param name
+ * the name of the child
+ * @param time
+ * the timestamp for when the node is entered
+ * @return the child node object
+ */
+ public Node enterChild(String name, double time) {
+ Node child = children.get(name);
+ if (child == null) {
+ child = new Node(name);
+ children.put(name, child);
+ }
+ child.time -= time;
+ child.count++;
+ return child;
+ }
+
+ /**
+ * Gets the total time spent in this node, including time spent in sub
+ * nodes
+ *
+ * @return the total time spent, in milliseconds
+ */
+ public double getTimeSpent() {
+ return time;
+ }
+
+ /**
+ * Gets the number of times this node has been entered
+ *
+ * @return the number of times the node has been entered
+ */
+ public int getCount() {
+ return count;
+ }
+
+ /**
+ * Gets the total time spent in this node, excluding time spent in sub
+ * nodes
+ *
+ * @return the total time spent, in milliseconds
+ */
+ public double getOwnTime() {
+ double time = getTimeSpent();
+ for (Node node : children.values()) {
+ time -= node.getTimeSpent();
+ }
+ return time;
+ }
+
+ /**
+ * Gets the child nodes of this node
+ *
+ * @return a collection of child nodes
+ */
+ public Collection<Node> getChildren() {
+ return Collections.unmodifiableCollection(children.values());
+ }
+
+ private void buildRecursiveString(StringBuilder builder, String prefix) {
+ if (getName() != null) {
+ String msg = getStringRepresentation(prefix);
+ builder.append(msg + '\n');
+ }
+ String childPrefix = prefix + "*";
+ for (Node node : children.values()) {
+ node.buildRecursiveString(builder, childPrefix);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getStringRepresentation("");
+ }
+
+ public String getStringRepresentation(String prefix) {
+ if (getName() == null) {
+ return "";
+ }
+ String msg = prefix + " " + getName() + " in " + getTimeSpent()
+ + " ms.";
+ if (getCount() > 1) {
+ msg += " Invoked "
+ + getCount()
+ + " times ("
+ + roundToSignificantFigures(getTimeSpent() / getCount())
+ + " ms per time).";
+ }
+ if (!children.isEmpty()) {
+ double ownTime = getOwnTime();
+ msg += " " + ownTime + " ms spent in own code";
+ if (getCount() > 1) {
+ msg += " ("
+ + roundToSignificantFigures(ownTime / getCount())
+ + " ms per time)";
+ }
+ msg += '.';
+ }
+ return msg;
+ }
+
+ private static double roundToSignificantFigures(double num) {
+ // Number of significant digits
+ int n = 3;
+ if (num == 0) {
+ return 0;
+ }
+
+ final double d = Math.ceil(Math.log10(num < 0 ? -num : num));
+ final int power = n - (int) d;
+
+ final double magnitude = Math.pow(10, power);
+ final long shifted = Math.round(num * magnitude);
+ return shifted / magnitude;
+ }
+
+ public void sumUpTotals(Map<String, Node> totals) {
+ String name = getName();
+ if (name != null) {
+ Node totalNode = totals.get(name);
+ if (totalNode == null) {
+ totalNode = new Node(name);
+ totals.put(name, totalNode);
+ }
+
+ totalNode.time += getOwnTime();
+ totalNode.count += getCount();
+ }
+ for (Node node : children.values()) {
+ node.sumUpTotals(totals);
+ }
+ }
+
+ /**
+ * @since
+ * @param time
+ */
+ public void addTime(double time) {
+ this.time += time;
+ }
+ }
+
+ private static final int MAX_ROWS = 10;
+
+ private final DebugButton tabButton = new DebugButton(Icon.RESET_TIMER,
+ "Profiler");
+
+ private final HorizontalPanel controls = new HorizontalPanel();
+ private final FlowPanel content = new FlowPanel();
+
+ public ProfilerSection() {
+ Profiler.setProfilerResultConsuer(new ProfilerResultConsumer() {
+ @Override
+ public void addProfilerData(Node rootNode, List<Node> totals) {
+ double totalTime = 0;
+ int eventCount = 0;
+ for (Node node : totals) {
+ totalTime += node.getTimeSpent();
+ eventCount += node.getCount();
+ }
+
+ SimpleTree drillDownTree = (SimpleTree) buildTree(rootNode);
+ drillDownTree.setText("Drill down");
+
+ SimpleTree offendersTree = new SimpleTree("Longest events");
+ for (int i = 0; i < totals.size() && i < 20; i++) {
+ Node node = totals.get(i);
+ offendersTree.add(new Label(node
+ .getStringRepresentation("")));
+ }
+
+ SimpleTree root = new SimpleTree(eventCount
+ + " profiler events using " + totalTime + " ms");
+ root.add(drillDownTree);
+ root.add(offendersTree);
+ root.open(false);
+
+ content.add(root);
+ applyLimit();
+ }
+
+ @Override
+ public void addBootstrapData(LinkedHashMap<String, Double> timings) {
+ SimpleTree tree = new SimpleTree(
+ "Time since window.performance.timing events");
+ Set<Entry<String, Double>> entrySet = timings.entrySet();
+ for (Entry<String, Double> entry : entrySet) {
+ tree.add(new Label(entry.getValue() + " " + entry.getKey()));
+ }
+
+ tree.open(false);
+ content.add(tree);
+ applyLimit();
+ }
+ });
+ }
+
+ private Widget buildTree(Node node) {
+ String message = node.getStringRepresentation("");
+
+ Collection<Node> children = node.getChildren();
+ if (node.getName() == null || !children.isEmpty()) {
+ SimpleTree tree = new SimpleTree(message);
+ for (Node childNode : children) {
+ Widget child = buildTree(childNode);
+ tree.add(child);
+ }
+ return tree;
+ } else {
+ return new Label(message);
+ }
+ }
+
+ private void applyLimit() {
+ while (content.getWidgetCount() > MAX_ROWS) {
+ content.remove(0);
+ }
+ }
+
+ @Override
+ public DebugButton getTabButton() {
+ return tabButton;
+ }
+
+ @Override
+ public Widget getControls() {
+ return controls;
+ }
+
+ @Override
+ public Widget getContent() {
+ return content;
+ }
+
+ @Override
+ public void show() {
+ // Nothing to do
+ }
+
+ @Override
+ public void hide() {
+ // Nothing to do
+ }
+
+ @Override
+ public void meta(ApplicationConnection ac, ValueMap meta) {
+ // Nothing to do
+ }
+
+ @Override
+ public void uidl(ApplicationConnection ac, ValueMap uidl) {
+ // Nothing to do
+ }
+
+}
diff --git a/client/src/com/vaadin/client/debug/internal/VDebugWindow.java b/client/src/com/vaadin/client/debug/internal/VDebugWindow.java
index 5aab95616a..6c05658fe1 100644
--- a/client/src/com/vaadin/client/debug/internal/VDebugWindow.java
+++ b/client/src/com/vaadin/client/debug/internal/VDebugWindow.java
@@ -45,6 +45,7 @@ import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.Location;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConnection;
@@ -714,6 +715,18 @@ public final class VDebugWindow extends VOverlay {
}
}
+ /**
+ * Gets the container element for this window. The debug window is always
+ * global to the document and not related to any
+ * {@link ApplicationConnection} in particular.
+ *
+ * @return The global overlay container element.
+ */
+ @Override
+ public com.google.gwt.user.client.Element getOverlayContainer() {
+ return RootPanel.get().getElement();
+ }
+
/*
* Inner classes
*/
diff --git a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java
index 13d1e6d56c..ebc80c4728 100644
--- a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java
+++ b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java
@@ -51,8 +51,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector
private String lastKnownWidth = "";
private String lastKnownHeight = "";
- private boolean initialStateEvent = true;
-
private boolean tooltipListenersAttached = false;
/**
@@ -124,7 +122,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector
if (stateChangeEvent.hasPropertyChanged("id")) {
if (getState().id != null) {
getWidget().getElement().setId(getState().id);
- } else if (!initialStateEvent) {
+ } else if (!stateChangeEvent.isInitialStateChange()) {
getWidget().getElement().removeAttribute("id");
}
}
@@ -175,8 +173,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector
}
Profiler.leave("AbstractComponentContainer.onStateChanged check tooltip");
- initialStateEvent = false;
-
Profiler.leave("AbstractComponentConnector.onStateChanged");
}
diff --git a/client/src/com/vaadin/client/ui/VCalendar.java b/client/src/com/vaadin/client/ui/VCalendar.java
index c5c12f2d72..38bcc0b14f 100644
--- a/client/src/com/vaadin/client/ui/VCalendar.java
+++ b/client/src/com/vaadin/client/ui/VCalendar.java
@@ -39,6 +39,8 @@ import com.vaadin.client.ui.calendar.schedule.SimpleDayToolbar;
import com.vaadin.client.ui.calendar.schedule.SimpleWeekToolbar;
import com.vaadin.client.ui.calendar.schedule.WeekGrid;
import com.vaadin.client.ui.calendar.schedule.WeeklyLongEvents;
+import com.vaadin.client.ui.calendar.schedule.dd.CalendarDropHandler;
+import com.vaadin.client.ui.dd.VHasDropHandler;
import com.vaadin.shared.ui.calendar.DateConstants;
/**
@@ -47,7 +49,7 @@ import com.vaadin.shared.ui.calendar.DateConstants;
* @since 7.1
* @author Vaadin Ltd.
*/
-public class VCalendar extends Composite {
+public class VCalendar extends Composite implements VHasDropHandler {
public static final String ATTR_FIRSTDAYOFWEEK = "firstDay";
public static final String ATTR_LASTDAYOFWEEK = "lastDay";
@@ -96,6 +98,8 @@ public class VCalendar extends Composite {
private int firstHour;
private int lastHour;
+ private CalendarDropHandler dropHandler;
+
/**
* Listener interface for listening to event click events
*/
@@ -1443,4 +1447,24 @@ public class VCalendar extends Composite {
public void setForwardNavigationEnabled(boolean enabled) {
forwardNavigationEnabled = enabled;
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.client.ui.dd.VHasDropHandler#getDropHandler()
+ */
+ @Override
+ public CalendarDropHandler getDropHandler() {
+ return dropHandler;
+ }
+
+ /**
+ * Set the drop handler
+ *
+ * @param dropHandler
+ * The drophandler to use
+ */
+ public void setDropHandler(CalendarDropHandler dropHandler) {
+ this.dropHandler = dropHandler;
+ }
}
diff --git a/client/src/com/vaadin/client/ui/VCalendarPanel.java b/client/src/com/vaadin/client/ui/VCalendarPanel.java
index 311932b819..1f40298760 100644
--- a/client/src/com/vaadin/client/ui/VCalendarPanel.java
+++ b/client/src/com/vaadin/client/ui/VCalendarPanel.java
@@ -2216,6 +2216,11 @@ public class VCalendarPanel extends FocusableFlexTable implements
*/
public void setRangeStart(Date rangeStart) {
this.rangeStart = rangeStart;
+ if (initialRenderDone) {
+ // Dynamic updates to the range needs to render the calendar to
+ // update the element stylenames
+ renderCalendar();
+ }
}
@@ -2228,6 +2233,10 @@ public class VCalendarPanel extends FocusableFlexTable implements
*/
public void setRangeEnd(Date rangeEnd) {
this.rangeEnd = rangeEnd;
-
+ if (initialRenderDone) {
+ // Dynamic updates to the range needs to render the calendar to
+ // update the element stylenames
+ renderCalendar();
+ }
}
}
diff --git a/client/src/com/vaadin/client/ui/VOverlay.java b/client/src/com/vaadin/client/ui/VOverlay.java
index 9e809758ca..ced476f9dd 100644
--- a/client/src/com/vaadin/client/ui/VOverlay.java
+++ b/client/src/com/vaadin/client/ui/VOverlay.java
@@ -17,6 +17,7 @@
package com.vaadin.client.ui;
import com.google.gwt.animation.client.Animation;
+import com.google.gwt.aria.client.Roles;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.IFrameElement;
import com.google.gwt.dom.client.Style;
@@ -690,6 +691,23 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
return container;
}
+ /**
+ * Set the label of the container element, where tooltip, notification and
+ * dialgs are added to.
+ *
+ * @param applicationConnection
+ * the application connection for which to change the label
+ * @param overlayContainerLabel
+ * label for the container
+ */
+ public static void setOverlayContainerLabel(
+ ApplicationConnection applicationConnection,
+ String overlayContainerLabel) {
+ Roles.getAlertRole().setAriaLabelProperty(
+ VOverlay.getOverlayContainer(applicationConnection),
+ overlayContainerLabel);
+ }
+
@Override
public void center() {
super.center();
diff --git a/client/src/com/vaadin/client/ui/VPopupView.java b/client/src/com/vaadin/client/ui/VPopupView.java
index 05fbd2c073..dba4c8b092 100644
--- a/client/src/com/vaadin/client/ui/VPopupView.java
+++ b/client/src/com/vaadin/client/ui/VPopupView.java
@@ -40,6 +40,7 @@ import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.ComponentConnector;
+import com.vaadin.client.Util;
import com.vaadin.client.VCaptionWrapper;
import com.vaadin.client.VConsole;
import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
@@ -102,6 +103,8 @@ public class VPopupView extends HTML implements Iterable<Widget> {
});
popup.setAnimationEnabled(true);
+
+ popup.setAutoHideOnHistoryEventsEnabled(false);
}
/** For internal use only. May be removed or replaced in the future. */
@@ -313,8 +316,11 @@ public class VPopupView extends HTML implements Iterable<Widget> {
private void checkForRTE(Widget popupComponentWidget2) {
if (popupComponentWidget2 instanceof VRichTextArea) {
- ((VRichTextArea) popupComponentWidget2)
- .synchronizeContentToServer();
+ ComponentConnector rtaConnector = Util
+ .findConnectorFor(popupComponentWidget2);
+ if (rtaConnector != null) {
+ rtaConnector.flush();
+ }
} else if (popupComponentWidget2 instanceof HasWidgets) {
HasWidgets hw = (HasWidgets) popupComponentWidget2;
Iterator<Widget> iterator = hw.iterator();
diff --git a/client/src/com/vaadin/client/ui/VProgressBar.java b/client/src/com/vaadin/client/ui/VProgressBar.java
new file mode 100644
index 0000000000..8cfc28005c
--- /dev/null
+++ b/client/src/com/vaadin/client/ui/VProgressBar.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.client.ui;
+
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.HasEnabled;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.client.ApplicationConnection;
+import com.vaadin.shared.ui.progressindicator.ProgressBarState;
+
+/**
+ * Widget for showing the current progress of a long running task.
+ * <p>
+ * The default mode is to show the current progress internally represented by a
+ * floating point value between 0 and 1 (inclusive). The progress bar can also
+ * be in an indeterminate mode showing an animation indicating that the task is
+ * running but without providing any information about the current progress.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public class VProgressBar extends Widget implements HasEnabled {
+
+ Element wrapper = DOM.createDiv();
+ Element indicator = DOM.createDiv();
+
+ private boolean indeterminate = false;
+ private float state = 0.0f;
+ private boolean enabled;
+
+ public VProgressBar() {
+ setElement(DOM.createDiv());
+ getElement().appendChild(wrapper);
+ wrapper.appendChild(indicator);
+
+ setStylePrimaryName(ProgressBarState.PRIMARY_STYLE_NAME);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.user.client.ui.UIObject#setStylePrimaryName(java.lang.
+ * String)
+ */
+ @Override
+ public void setStylePrimaryName(String style) {
+ super.setStylePrimaryName(style);
+ indicator.setClassName(getStylePrimaryName() + "-indicator");
+ wrapper.setClassName(getStylePrimaryName() + "-wrapper");
+
+ }
+
+ public void setIndeterminate(boolean indeterminate) {
+ this.indeterminate = indeterminate;
+ setStyleName(getStylePrimaryName() + "-indeterminate", indeterminate);
+ }
+
+ public void setState(float state) {
+ final int size = Math.round(100 * state);
+ indicator.getStyle().setWidth(size, Unit.PCT);
+ }
+
+ public boolean isIndeterminate() {
+ return indeterminate;
+ }
+
+ public float getState() {
+ return state;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ setStyleName(ApplicationConnection.DISABLED_CLASSNAME, !enabled);
+ }
+
+}
diff --git a/client/src/com/vaadin/client/ui/VProgressIndicator.java b/client/src/com/vaadin/client/ui/VProgressIndicator.java
index d6b25cb016..c75113b5f4 100644
--- a/client/src/com/vaadin/client/ui/VProgressIndicator.java
+++ b/client/src/com/vaadin/client/ui/VProgressIndicator.java
@@ -16,59 +16,19 @@
package com.vaadin.client.ui;
-import com.google.gwt.dom.client.Style.Unit;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.ui.HasEnabled;
-import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.shared.ui.progressindicator.ProgressIndicatorState;
-public class VProgressIndicator extends Widget implements HasEnabled {
-
- public static final String CLASSNAME = "v-progressindicator";
- Element wrapper = DOM.createDiv();
- Element indicator = DOM.createDiv();
-
- protected boolean indeterminate = false;
- protected float state = 0.0f;
- private boolean enabled;
+/**
+ *
+ * @author Vaadin Ltd
+ *
+ * @deprecated as of 7.1, renamed to VProgressBar
+ */
+@Deprecated
+public class VProgressIndicator extends VProgressBar {
public VProgressIndicator() {
- setElement(DOM.createDiv());
- getElement().appendChild(wrapper);
- setStyleName(CLASSNAME);
- wrapper.appendChild(indicator);
- indicator.setClassName(CLASSNAME + "-indicator");
- wrapper.setClassName(CLASSNAME + "-wrapper");
+ super();
+ setStylePrimaryName(ProgressIndicatorState.PRIMARY_STYLE_NAME);
}
-
- public void setIndeterminate(boolean indeterminate) {
- this.indeterminate = indeterminate;
- setStyleName(CLASSNAME + "-indeterminate", indeterminate);
- }
-
- public void setState(float state) {
- final int size = Math.round(100 * state);
- indicator.getStyle().setWidth(size, Unit.PCT);
- }
-
- public boolean isIndeterminate() {
- return indeterminate;
- }
-
- public float getState() {
- return state;
- }
-
- @Override
- public boolean isEnabled() {
- return enabled;
- }
-
- @Override
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- setStyleName("v-disabled", !enabled);
-
- }
-
}
diff --git a/client/src/com/vaadin/client/ui/VRichTextArea.java b/client/src/com/vaadin/client/ui/VRichTextArea.java
index 1498c096ed..8a6ba3fc1e 100644
--- a/client/src/com/vaadin/client/ui/VRichTextArea.java
+++ b/client/src/com/vaadin/client/ui/VRichTextArea.java
@@ -16,11 +16,12 @@
package com.vaadin.client.ui;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
-import com.google.gwt.event.dom.client.ChangeEvent;
-import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
@@ -49,8 +50,8 @@ import com.vaadin.client.ui.richtextarea.VRichTextToolbar;
* @author Vaadin Ltd.
*
*/
-public class VRichTextArea extends Composite implements Field, ChangeHandler,
- BlurHandler, KeyPressHandler, KeyDownHandler, Focusable {
+public class VRichTextArea extends Composite implements Field, KeyPressHandler,
+ KeyDownHandler, Focusable {
/**
* The input node CSS classname.
@@ -91,11 +92,10 @@ public class VRichTextArea extends Composite implements Field, ChangeHandler,
private ShortcutActionHandlerOwner hasShortcutActionHandler;
- /** For internal use only. May be removed or replaced in the future. */
- public String currentValue = "";
-
private boolean readOnly = false;
+ private final Map<BlurHandler, HandlerRegistration> blurHandlers = new HashMap<BlurHandler, HandlerRegistration>();
+
public VRichTextArea() {
createRTAComponents();
fp.add(formatter);
@@ -110,9 +110,19 @@ public class VRichTextArea extends Composite implements Field, ChangeHandler,
private void createRTAComponents() {
rta = new RichTextArea();
rta.setWidth("100%");
- rta.addBlurHandler(this);
rta.addKeyDownHandler(this);
formatter = new VRichTextToolbar(rta);
+
+ // Add blur handlers
+ for (Entry<BlurHandler, HandlerRegistration> handler : blurHandlers
+ .entrySet()) {
+
+ // Remove old registration
+ handler.getValue().removeHandler();
+
+ // Add blur handlers
+ addBlurHandler(handler.getKey());
+ }
}
public void setEnabled(boolean enabled) {
@@ -127,6 +137,7 @@ public class VRichTextArea extends Composite implements Field, ChangeHandler,
* Swaps html to rta and visa versa.
*/
private void swapEditableArea() {
+ String value = getValue();
if (html.isAttached()) {
fp.remove(html);
if (BrowserInfo.get().isWebkit()) {
@@ -134,13 +145,12 @@ public class VRichTextArea extends Composite implements Field, ChangeHandler,
createRTAComponents(); // recreate new RTA to bypass #5379
fp.add(formatter);
}
- rta.setHTML(currentValue);
fp.add(rta);
} else {
- html.setHTML(currentValue);
fp.remove(rta);
fp.add(html);
}
+ setValue(value);
}
/** For internal use only. May be removed or replaced in the future. */
@@ -180,62 +190,6 @@ public class VRichTextArea extends Composite implements Field, ChangeHandler,
return readOnly;
}
- // TODO is this really used, or does everything go via onBlur() only?
- @Override
- public void onChange(ChangeEvent event) {
- synchronizeContentToServer();
- }
-
- /**
- * Method is public to let popupview force synchronization on close.
- */
- public void synchronizeContentToServer() {
- if (client != null && id != null) {
- final String html = sanitizeRichTextAreaValue(rta.getHTML());
- if (!html.equals(currentValue)) {
- client.updateVariable(id, "text", html, immediate);
- currentValue = html;
- }
- }
- }
-
- /**
- * Browsers differ in what they return as the content of a visually empty
- * rich text area. This method is used to normalize these to an empty
- * string. See #8004.
- *
- * @param html
- * @return cleaned html string
- */
- private String sanitizeRichTextAreaValue(String html) {
- BrowserInfo browser = BrowserInfo.get();
- String result = html;
- if (browser.isFirefox()) {
- if ("<br>".equals(html)) {
- result = "";
- }
- } else if (browser.isWebkit()) {
- if ("<div><br></div>".equals(html)) {
- result = "";
- }
- } else if (browser.isIE()) {
- if ("<P>&nbsp;</P>".equals(html)) {
- result = "";
- }
- } else if (browser.isOpera()) {
- if ("<br>".equals(html) || "<p><br></p>".equals(html)) {
- result = "";
- }
- }
- return result;
- }
-
- @Override
- public void onBlur(BlurEvent event) {
- synchronizeContentToServer();
- // TODO notify possible server side blur/focus listeners
- }
-
/**
* @return space used by components paddings and borders
*/
@@ -409,4 +363,81 @@ public class VRichTextArea extends Composite implements Field, ChangeHandler,
rta.setTabIndex(index);
}
+ /**
+ * Set the value of the text area
+ *
+ * @param value
+ * The text value. Can be html.
+ */
+ public void setValue(String value) {
+ if (rta.isAttached()) {
+ rta.setHTML(value);
+ } else {
+ html.setHTML(value);
+ }
+ }
+
+ /**
+ * Get the value the text area
+ */
+ public String getValue() {
+ if (rta.isAttached()) {
+ return rta.getHTML();
+ } else {
+ return html.getHTML();
+ }
+ }
+
+ /**
+ * Browsers differ in what they return as the content of a visually empty
+ * rich text area. This method is used to normalize these to an empty
+ * string. See #8004.
+ *
+ * @return cleaned html string
+ */
+ public String getSanitizedValue() {
+ BrowserInfo browser = BrowserInfo.get();
+ String result = getValue();
+ if (browser.isFirefox()) {
+ if ("<br>".equals(html)) {
+ result = "";
+ }
+ } else if (browser.isWebkit()) {
+ if ("<div><br></div>".equals(html)) {
+ result = "";
+ }
+ } else if (browser.isIE()) {
+ if ("<P>&nbsp;</P>".equals(html)) {
+ result = "";
+ }
+ } else if (browser.isOpera()) {
+ if ("<br>".equals(html) || "<p><br></p>".equals(html)) {
+ result = "";
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Adds a blur handler to the component.
+ *
+ * @param blurHandler
+ * the blur handler to add
+ */
+ public void addBlurHandler(BlurHandler blurHandler) {
+ blurHandlers.put(blurHandler, rta.addBlurHandler(blurHandler));
+ }
+
+ /**
+ * Removes a blur handler.
+ *
+ * @param blurHandler
+ * the handler to remove
+ */
+ public void removeBlurHandler(BlurHandler blurHandler) {
+ HandlerRegistration registration = blurHandlers.remove(blurHandler);
+ if (registration != null) {
+ registration.removeHandler();
+ }
+ }
}
diff --git a/client/src/com/vaadin/client/ui/VTabsheet.java b/client/src/com/vaadin/client/ui/VTabsheet.java
index ea1cb282a6..fe29e2ebc0 100644
--- a/client/src/com/vaadin/client/ui/VTabsheet.java
+++ b/client/src/com/vaadin/client/ui/VTabsheet.java
@@ -860,57 +860,17 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
*/
tab.recalculateCaptionWidth();
- UIDL tabContentUIDL = null;
- ComponentConnector tabContentPaintable = null;
- Widget tabContentWidget = null;
- if (tabUidl.getChildCount() > 0) {
- tabContentUIDL = tabUidl.getChildUIDL(0);
- tabContentPaintable = client.getPaintable(tabContentUIDL);
- tabContentWidget = tabContentPaintable.getWidget();
- }
-
- if (tabContentPaintable != null) {
- /* This is a tab with content information */
-
- int oldIndex = tp.getWidgetIndex(tabContentWidget);
- if (oldIndex != -1 && oldIndex != index) {
- /*
- * The tab has previously been rendered in another position so
- * we must move the cached content to correct position
- */
- tp.insert(tabContentWidget, index);
- }
- } else {
- /* A tab whose content has not yet been loaded */
-
- /*
- * Make sure there is a corresponding empty tab in tp. The same
- * operation as the moving above but for not-loaded tabs.
- */
- if (index < tp.getWidgetCount()) {
- Widget oldWidget = tp.getWidget(index);
- if (!(oldWidget instanceof PlaceHolder)) {
- tp.insert(new PlaceHolder(), index);
- }
- }
-
- }
-
if (selected) {
- renderContent(tabContentUIDL);
+ renderContent(tabUidl.getChildUIDL(0));
tb.selectTab(index);
- } else {
- if (tabContentUIDL != null) {
- // updating a drawn child on hidden tab
- if (tp.getWidgetIndex(tabContentWidget) < 0) {
- tp.insert(tabContentWidget, index);
- }
- } else if (tp.getWidgetCount() <= index) {
- tp.add(new PlaceHolder());
- }
}
}
+ /**
+ * @deprecated as of 7.1, VTabsheet only keeps the active tab in the DOM
+ * without any place holders.
+ */
+ @Deprecated
public class PlaceHolder extends VLabel {
public PlaceHolder() {
super("");
@@ -920,17 +880,20 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
private void renderContent(final UIDL contentUIDL) {
final ComponentConnector content = client.getPaintable(contentUIDL);
Widget newWidget = content.getWidget();
- if (tp.getWidgetCount() > activeTabIndex) {
- Widget old = tp.getWidget(activeTabIndex);
- if (old != newWidget) {
- tp.remove(activeTabIndex);
- tp.insert(content.getWidget(), activeTabIndex);
- }
- } else {
- tp.add(content.getWidget());
+
+ assert tp.getWidgetCount() <= 1;
+
+ if (tp.getWidgetCount() == 0) {
+ tp.add(newWidget);
+ } else if (tp.getWidget(0) != newWidget) {
+ tp.remove(0);
+ tp.add(newWidget);
}
- tp.showWidget(activeTabIndex);
+ assert tp.getWidgetCount() <= 1;
+
+ // There's never any other index than 0, but maintaining API for now
+ tp.showWidget(0);
VTabsheet.this.iLayout();
updateOpenTabSize();
@@ -1114,13 +1077,8 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
@Override
public void removeTab(int index) {
tb.removeTab(index);
- /*
- * This must be checked because renderTab automatically removes the
- * active tab content when it changes
- */
- if (tp.getWidgetCount() > index) {
- tp.remove(index);
- }
+
+ // Removing content from tp is handled by the connector
}
@Override
diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java
index 38dfdba1b8..1331eb106a 100644
--- a/client/src/com/vaadin/client/ui/VWindow.java
+++ b/client/src/com/vaadin/client/ui/VWindow.java
@@ -38,7 +38,6 @@ import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.BrowserInfo;
@@ -793,6 +792,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
int w = Util.getTouchOrMouseClientX(event) - startX + origW;
int h = Util.getTouchOrMouseClientY(event) - startY + origH;
+ w = Math.max(w, getMinWidth());
+ h = Math.max(h, getMinHeight());
+
setWidth(w + "px");
setHeight(h + "px");
@@ -811,6 +813,22 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
}
}
+ private int getMinHeight() {
+ return getPixelValue(getElement().getStyle().getProperty("minHeight"));
+ }
+
+ private int getMinWidth() {
+ return getPixelValue(getElement().getStyle().getProperty("minWidth"));
+ }
+
+ private static int getPixelValue(String size) {
+ if (size == null || !size.endsWith("px")) {
+ return -1;
+ } else {
+ return Integer.parseInt(size.substring(0, size.length() - 2));
+ }
+ }
+
public void updateContentsSize() {
LayoutManager layoutManager = getLayoutManager();
layoutManager.setNeedsMeasure(ConnectorMap.get(client).getConnector(
diff --git a/client/src/com/vaadin/client/ui/calendar/CalendarConnector.java b/client/src/com/vaadin/client/ui/calendar/CalendarConnector.java
index 285d15792b..5a83579d46 100644
--- a/client/src/com/vaadin/client/ui/calendar/CalendarConnector.java
+++ b/client/src/com/vaadin/client/ui/calendar/CalendarConnector.java
@@ -19,6 +19,7 @@ import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import com.google.gwt.core.shared.GWT;
@@ -30,6 +31,7 @@ import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConnection;
+import com.vaadin.client.Paintable;
import com.vaadin.client.TooltipInfo;
import com.vaadin.client.UIDL;
import com.vaadin.client.Util;
@@ -57,9 +59,11 @@ import com.vaadin.client.ui.calendar.schedule.DateCell.DateCellSlot;
import com.vaadin.client.ui.calendar.schedule.DateCellDayEvent;
import com.vaadin.client.ui.calendar.schedule.DateUtil;
import com.vaadin.client.ui.calendar.schedule.HasTooltipKey;
+import com.vaadin.client.ui.calendar.schedule.MonthEventLabel;
import com.vaadin.client.ui.calendar.schedule.SimpleDayCell;
import com.vaadin.client.ui.calendar.schedule.dd.CalendarDropHandler;
-import com.vaadin.client.ui.dd.VHasDropHandler;
+import com.vaadin.client.ui.calendar.schedule.dd.CalendarMonthDropHandler;
+import com.vaadin.client.ui.calendar.schedule.dd.CalendarWeekDropHandler;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.Connect.LoadStyle;
import com.vaadin.shared.ui.calendar.CalendarClientRpc;
@@ -78,16 +82,16 @@ import com.vaadin.ui.Calendar;
*/
@Connect(value = Calendar.class, loadStyle = LoadStyle.LAZY)
public class CalendarConnector extends AbstractComponentConnector implements
- VHasDropHandler, ActionOwner, SimpleManagedLayout {
+ ActionOwner, SimpleManagedLayout, Paintable {
private CalendarServerRpc rpc = RpcProxy.create(CalendarServerRpc.class,
this);
- private CalendarDropHandler dropHandler;
-
private final HashMap<String, String> actionMap = new HashMap<String, String>();
private HashMap<Object, String> tooltips = new HashMap<Object, String>();
+ private static final String DROPHANDLER_ACCEPT_CRITERIA_PAINT_TAG = "-ac";
+
/**
*
*/
@@ -287,7 +291,16 @@ public class CalendarConnector extends AbstractComponentConnector implements
((VCalendarAction) action).setEvent(event);
}
return actions;
-
+ } else if (widget instanceof MonthEventLabel) {
+ MonthEventLabel mel = (MonthEventLabel) widget;
+ CalendarEvent event = mel.getCalendarEvent();
+ Action[] actions = CalendarConnector.this
+ .getActionsBetween(event.getStartTime(),
+ event.getEndTime());
+ for (Action action : actions) {
+ ((VCalendarAction) action).setEvent(event);
+ }
+ return actions;
}
return null;
}
@@ -296,13 +309,16 @@ public class CalendarConnector extends AbstractComponentConnector implements
});
}
+ private boolean showingMonthView() {
+ return getState().days.size() > 7;
+ }
+
@Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
super.onStateChanged(stateChangeEvent);
CalendarState state = getState();
VCalendar widget = getWidget();
- boolean monthView = state.days.size() > 7;
// Enable or disable the forward and backward navigation buttons
widget.setForwardNavigationEnabled(hasEventListener(CalendarEventId.FORWARD));
@@ -326,10 +342,19 @@ public class CalendarConnector extends AbstractComponentConnector implements
List<CalendarState.Day> days = state.days;
List<CalendarState.Event> events = state.events;
- if (monthView) {
+ CalendarDropHandler dropHandler = getWidget().getDropHandler();
+ if (showingMonthView()) {
updateMonthView(days, events);
+ if (dropHandler != null
+ && !(dropHandler instanceof CalendarMonthDropHandler)) {
+ getWidget().setDropHandler(new CalendarMonthDropHandler(this));
+ }
} else {
updateWeekView(days, events);
+ if (dropHandler != null
+ && !(dropHandler instanceof CalendarWeekDropHandler)) {
+ getWidget().setDropHandler(new CalendarWeekDropHandler(this));
+ }
}
updateSizes();
@@ -345,32 +370,22 @@ public class CalendarConnector extends AbstractComponentConnector implements
* com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal
* .gwt.client.UIDL, com.vaadin.terminal.gwt.client.ApplicationConnection)
*/
+ @Override
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
- // check for DD -related access criteria
- // Iterator<Object> childIterator = uidl.getChildIterator();
- // while (childIterator.hasNext()) {
- // UIDL child = (UIDL) childIterator.next();
- //
- // // Drag&drop
- // if (ACCESSCRITERIA.equals(child.getTag())) {
- // if (monthView
- // && !(getDropHandler() instanceof CalendarMonthDropHandler)) {
- // setDropHandler(new CalendarMonthDropHandler());
- //
- // } else if (!monthView
- // && !(getDropHandler() instanceof CalendarWeekDropHandler)) {
- // setDropHandler(new CalendarWeekDropHandler());
- // }
- //
- // getDropHandler().setCalendarPaintable(this);
- // getDropHandler().updateAcceptRules(child);
- //
- // } else {
- // setDropHandler(null);
- // }
- //
- // }
+ Iterator<Object> childIterator = uidl.getChildIterator();
+ while (childIterator.hasNext()) {
+ UIDL child = (UIDL) childIterator.next();
+ if (DROPHANDLER_ACCEPT_CRITERIA_PAINT_TAG.equals(child.getTag())) {
+ if (getWidget().getDropHandler() == null) {
+ getWidget().setDropHandler(
+ showingMonthView() ? new CalendarMonthDropHandler(
+ this) : new CalendarWeekDropHandler(this));
+ }
+ getWidget().getDropHandler().updateAcceptRules(child);
+ } else {
+ getWidget().setDropHandler(null);
+ }
+ }
}
/**
@@ -439,27 +454,6 @@ public class CalendarConnector extends AbstractComponentConnector implements
calendarDayListOf(days));
}
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.terminal.gwt.client.ui.dd.VHasDropHandler#getDropHandler()
- */
- @Override
- public CalendarDropHandler getDropHandler() {
- return dropHandler;
- }
-
- /**
- * Set the drop handler
- *
- * @param dropHandler
- * The drophandler to use
- */
- public void setDropHandler(CalendarDropHandler dropHandler) {
- this.dropHandler = dropHandler;
- }
-
private Action[] getActionsBetween(Date start, Date end) {
List<Action> actions = new ArrayList<Action>();
for (int i = 0; i < actionKeys.size(); i++) {
diff --git a/client/src/com/vaadin/client/ui/calendar/schedule/MonthEventLabel.java b/client/src/com/vaadin/client/ui/calendar/schedule/MonthEventLabel.java
index b7f6ee7a3c..928ff85f18 100644
--- a/client/src/com/vaadin/client/ui/calendar/schedule/MonthEventLabel.java
+++ b/client/src/com/vaadin/client/ui/calendar/schedule/MonthEventLabel.java
@@ -17,6 +17,8 @@ package com.vaadin.client.ui.calendar.schedule;
import java.util.Date;
+import com.google.gwt.event.dom.client.ContextMenuEvent;
+import com.google.gwt.event.dom.client.ContextMenuHandler;
import com.google.gwt.user.client.ui.HTML;
import com.vaadin.client.ui.VCalendar;
@@ -35,11 +37,27 @@ public class MonthEventLabel extends HTML implements HasTooltipKey {
private String caption;
private Date time;
+ private CalendarEvent calendarEvent;
+
/**
* Default constructor
*/
public MonthEventLabel() {
setStylePrimaryName(STYLENAME);
+
+ addDomHandler(new ContextMenuHandler() {
+ @Override
+ public void onContextMenu(ContextMenuEvent event) {
+ calendar.getMouseEventListener().contextMenu(event,
+ MonthEventLabel.this);
+ event.stopPropagation();
+ event.preventDefault();
+ }
+ }, ContextMenuEvent.getType());
+ }
+
+ public void setCalendarEvent(CalendarEvent e) {
+ calendarEvent = e;
}
/**
@@ -139,4 +157,8 @@ public class MonthEventLabel extends HTML implements HasTooltipKey {
public Object getTooltipKey() {
return eventIndex;
}
+
+ public CalendarEvent getCalendarEvent() {
+ return calendarEvent;
+ }
} \ No newline at end of file
diff --git a/client/src/com/vaadin/client/ui/calendar/schedule/SimpleDayCell.java b/client/src/com/vaadin/client/ui/calendar/schedule/SimpleDayCell.java
index a2bd008d01..cf8006ef66 100644
--- a/client/src/com/vaadin/client/ui/calendar/schedule/SimpleDayCell.java
+++ b/client/src/com/vaadin/client/ui/calendar/schedule/SimpleDayCell.java
@@ -264,6 +264,7 @@ public class SimpleDayCell extends FocusableFlowPanel implements
eventDiv.addMouseUpHandler(this);
eventDiv.setCalendar(calendar);
eventDiv.setEventIndex(e.getIndex());
+ eventDiv.setCalendarEvent(e);
if (timeEvent) {
eventDiv.setTimeSpecificEvent(true);
diff --git a/client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarDropHandler.java b/client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarDropHandler.java
index aab9ca9c38..ab0c9f2e9a 100644
--- a/client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarDropHandler.java
+++ b/client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarDropHandler.java
@@ -28,15 +28,16 @@ import com.vaadin.client.ui.dd.VAbstractDropHandler;
*/
public abstract class CalendarDropHandler extends VAbstractDropHandler {
- protected CalendarConnector calendarConnector;
+ protected final CalendarConnector calendarConnector;
/**
- * Set the calendar instance
+ * Constructor
*
- * @param calendarPaintable
+ * @param connector
+ * The connector of the calendar
*/
- public void setConnector(CalendarConnector calendarConnector) {
- this.calendarConnector = calendarConnector;
+ public CalendarDropHandler(CalendarConnector connector) {
+ calendarConnector = connector;
}
/*
diff --git a/client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarMonthDropHandler.java b/client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarMonthDropHandler.java
index 913477ee14..fd0be4881e 100644
--- a/client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarMonthDropHandler.java
+++ b/client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarMonthDropHandler.java
@@ -18,6 +18,7 @@ package com.vaadin.client.ui.calendar.schedule.dd;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.vaadin.client.Util;
+import com.vaadin.client.ui.calendar.CalendarConnector;
import com.vaadin.client.ui.calendar.schedule.SimpleDayCell;
import com.vaadin.client.ui.dd.VAcceptCallback;
import com.vaadin.client.ui.dd.VDragEvent;
@@ -32,6 +33,10 @@ import com.vaadin.client.ui.dd.VDragEvent;
*/
public class CalendarMonthDropHandler extends CalendarDropHandler {
+ public CalendarMonthDropHandler(CalendarConnector connector) {
+ super(connector);
+ }
+
private Element currentTargetElement;
private SimpleDayCell currentTargetDay;
diff --git a/client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarWeekDropHandler.java b/client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarWeekDropHandler.java
index 0ea683dc3c..cede1827a2 100644
--- a/client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarWeekDropHandler.java
+++ b/client/src/com/vaadin/client/ui/calendar/schedule/dd/CalendarWeekDropHandler.java
@@ -18,6 +18,7 @@ package com.vaadin.client.ui.calendar.schedule.dd;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.vaadin.client.Util;
+import com.vaadin.client.ui.calendar.CalendarConnector;
import com.vaadin.client.ui.calendar.schedule.DateCell;
import com.vaadin.client.ui.calendar.schedule.DateCellDayEvent;
import com.vaadin.client.ui.dd.VAcceptCallback;
@@ -36,6 +37,10 @@ public class CalendarWeekDropHandler extends CalendarDropHandler {
private com.google.gwt.user.client.Element currentTargetElement;
private DateCell currentTargetDay;
+ public CalendarWeekDropHandler(CalendarConnector connector) {
+ super(connector);
+ }
+
/*
* (non-Javadoc)
*
diff --git a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java
index 345bdc0cbb..d9eac91e2b 100644
--- a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java
+++ b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java
@@ -252,8 +252,11 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
getWidget().setPromptingOn();
} else {
// we have focus in field, prompting can't be set on, instead
- // just clear the input
- getWidget().tb.setValue("");
+ // just clear the input if the value has changed from something
+ // else to null
+ if (getWidget().selectedOptionKey != null) {
+ getWidget().tb.setValue("");
+ }
}
getWidget().setSelectedItemIcon(null);
getWidget().selectedOptionKey = null;
diff --git a/client/src/com/vaadin/client/ui/progressindicator/ProgressBarConnector.java b/client/src/com/vaadin/client/ui/progressindicator/ProgressBarConnector.java
new file mode 100644
index 0000000000..91f3da5323
--- /dev/null
+++ b/client/src/com/vaadin/client/ui/progressindicator/ProgressBarConnector.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.client.ui.progressindicator;
+
+import com.vaadin.client.communication.StateChangeEvent;
+import com.vaadin.client.ui.AbstractFieldConnector;
+import com.vaadin.client.ui.VProgressBar;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.progressindicator.ProgressBarState;
+import com.vaadin.ui.ProgressBar;
+
+/**
+ * Connector for {@link VProgressBar}.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+@Connect(ProgressBar.class)
+public class ProgressBarConnector extends AbstractFieldConnector {
+
+ public ProgressBarConnector() {
+ super();
+ }
+
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
+ super.onStateChanged(stateChangeEvent);
+ getWidget().setIndeterminate(getState().indeterminate);
+ getWidget().setState(getState().state);
+ }
+
+ @Override
+ public ProgressBarState getState() {
+ return (ProgressBarState) super.getState();
+ }
+
+ @Override
+ public VProgressBar getWidget() {
+ return (VProgressBar) super.getWidget();
+ }
+
+} \ No newline at end of file
diff --git a/client/src/com/vaadin/client/ui/progressindicator/ProgressIndicatorConnector.java b/client/src/com/vaadin/client/ui/progressindicator/ProgressIndicatorConnector.java
index ac5c3f5f6b..23b71868e0 100644
--- a/client/src/com/vaadin/client/ui/progressindicator/ProgressIndicatorConnector.java
+++ b/client/src/com/vaadin/client/ui/progressindicator/ProgressIndicatorConnector.java
@@ -18,15 +18,24 @@ package com.vaadin.client.ui.progressindicator;
import com.google.gwt.user.client.Timer;
import com.vaadin.client.communication.StateChangeEvent;
-import com.vaadin.client.ui.AbstractFieldConnector;
+import com.vaadin.client.ui.VProgressBar;
import com.vaadin.client.ui.VProgressIndicator;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.progressindicator.ProgressIndicatorServerRpc;
import com.vaadin.shared.ui.progressindicator.ProgressIndicatorState;
import com.vaadin.ui.ProgressIndicator;
+/**
+ * Connector for {@link VProgressBar} with polling support.
+ *
+ * @since 7.0
+ * @author Vaadin Ltd
+ * @deprecated as of 7.1, use {@link ProgressBarConnector} combined with server
+ * push or UI polling.
+ */
@Connect(ProgressIndicator.class)
-public class ProgressIndicatorConnector extends AbstractFieldConnector {
+@Deprecated
+public class ProgressIndicatorConnector extends ProgressBarConnector {
@Override
public ProgressIndicatorState getState() {
@@ -45,8 +54,6 @@ public class ProgressIndicatorConnector extends AbstractFieldConnector {
@Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
super.onStateChanged(stateChangeEvent);
- getWidget().setIndeterminate(getState().indeterminate);
- getWidget().setState(getState().state);
if (isEnabled()) {
poller.scheduleRepeating(getState().pollingInterval);
@@ -56,13 +63,13 @@ public class ProgressIndicatorConnector extends AbstractFieldConnector {
}
@Override
- public void onUnregister() {
- super.onUnregister();
- poller.cancel();
+ public VProgressIndicator getWidget() {
+ return (VProgressIndicator) super.getWidget();
}
@Override
- public VProgressIndicator getWidget() {
- return (VProgressIndicator) super.getWidget();
+ public void onUnregister() {
+ super.onUnregister();
+ poller.cancel();
}
}
diff --git a/client/src/com/vaadin/client/ui/richtextarea/RichTextAreaConnector.java b/client/src/com/vaadin/client/ui/richtextarea/RichTextAreaConnector.java
index 36182464a3..20dfc74c69 100644
--- a/client/src/com/vaadin/client/ui/richtextarea/RichTextAreaConnector.java
+++ b/client/src/com/vaadin/client/ui/richtextarea/RichTextAreaConnector.java
@@ -15,6 +15,8 @@
*/
package com.vaadin.client.ui.richtextarea;
+import com.google.gwt.event.dom.client.BlurEvent;
+import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.user.client.Event;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.Paintable;
@@ -24,33 +26,47 @@ import com.vaadin.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
import com.vaadin.client.ui.VRichTextArea;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.Connect.LoadStyle;
+import com.vaadin.shared.util.SharedUtil;
import com.vaadin.ui.RichTextArea;
@Connect(value = RichTextArea.class, loadStyle = LoadStyle.LAZY)
public class RichTextAreaConnector extends AbstractFieldConnector implements
Paintable, BeforeShortcutActionListener {
+ /*
+ * Last value received from the server
+ */
+ private String cachedValue = "";
+
+ @Override
+ protected void init() {
+ getWidget().addBlurHandler(new BlurHandler() {
+
+ @Override
+ public void onBlur(BlurEvent event) {
+ flush();
+ }
+ });
+ }
+
@Override
public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
getWidget().client = client;
getWidget().id = uidl.getId();
if (uidl.hasVariable("text")) {
- getWidget().currentValue = uidl.getStringVariable("text");
- if (getWidget().rta.isAttached()) {
- getWidget().rta.setHTML(getWidget().currentValue);
- } else {
- getWidget().html.setHTML(getWidget().currentValue);
+ String newValue = uidl.getStringVariable("text");
+ if (!SharedUtil.equals(newValue, cachedValue)) {
+ getWidget().setValue(newValue);
+ cachedValue = newValue;
}
}
- if (isRealUpdate(uidl)) {
- getWidget().setEnabled(isEnabled());
- }
if (!isRealUpdate(uidl)) {
return;
}
+ getWidget().setEnabled(isEnabled());
getWidget().setReadOnly(isReadOnly());
getWidget().immediate = getState().immediate;
int newMaxLength = uidl.hasAttribute("maxLength") ? uidl
@@ -85,7 +101,13 @@ public class RichTextAreaConnector extends AbstractFieldConnector implements
@Override
public void flush() {
- getWidget().synchronizeContentToServer();
+ if (getConnection() != null && getConnectorId() != null) {
+ final String html = getWidget().getSanitizedValue();
+ if (!html.equals(cachedValue)) {
+ getConnection().updateVariable(getConnectorId(), "text", html,
+ getState().immediate);
+ getWidget().setValue(html);
+ }
+ }
};
-
}
diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java
index 643d687f1d..45b0a7ab9d 100644
--- a/client/src/com/vaadin/client/ui/ui/UIConnector.java
+++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java
@@ -50,14 +50,17 @@ import com.vaadin.client.ConnectorHierarchyChangeEvent;
import com.vaadin.client.ConnectorMap;
import com.vaadin.client.Focusable;
import com.vaadin.client.Paintable;
+import com.vaadin.client.ServerConnector;
import com.vaadin.client.UIDL;
import com.vaadin.client.VConsole;
+import com.vaadin.client.ValueMap;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler;
import com.vaadin.client.ui.AbstractSingleComponentContainerConnector;
import com.vaadin.client.ui.ClickEventHandler;
import com.vaadin.client.ui.ShortcutActionHandler;
import com.vaadin.client.ui.VNotification;
+import com.vaadin.client.ui.VOverlay;
import com.vaadin.client.ui.VUI;
import com.vaadin.client.ui.layout.MayScrollChildren;
import com.vaadin.client.ui.window.WindowConnector;
@@ -67,6 +70,8 @@ import com.vaadin.shared.communication.MethodInvocation;
import com.vaadin.shared.ui.ComponentStateUtil;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.Connect.LoadStyle;
+import com.vaadin.shared.ui.ui.DebugWindowClientRpc;
+import com.vaadin.shared.ui.ui.DebugWindowServerRpc;
import com.vaadin.shared.ui.ui.PageClientRpc;
import com.vaadin.shared.ui.ui.PageState;
import com.vaadin.shared.ui.ui.ScrollClientRpc;
@@ -133,6 +138,19 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
});
}
});
+ registerRpc(DebugWindowClientRpc.class, new DebugWindowClientRpc() {
+
+ @Override
+ public void reportLayoutProblems(String json) {
+ VConsole.printLayoutProblems(getValueMap(json), getConnection());
+ }
+
+ private native ValueMap getValueMap(String json)
+ /*-{
+ return JSON.parse(json);
+ }-*/;
+ });
+
getWidget().addResizeHandler(new ResizeHandler() {
@Override
public void onResize(ResizeEvent event) {
@@ -626,12 +644,13 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
configurePolling();
}
- if (stateChangeEvent.hasPropertyChanged("pushMode")) {
- getConnection().setPushEnabled(getState().pushMode.isEnabled());
+ if (stateChangeEvent.hasPropertyChanged("pushConfiguration")) {
+ getConnection().setPushEnabled(
+ getState().pushConfiguration.mode.isEnabled());
}
if (stateChangeEvent.hasPropertyChanged("overlayContainerLabel")) {
- getConnection().setOverlayContainerLabel(
+ VOverlay.setOverlayContainerLabel(getConnection(),
getState().overlayContainerLabel);
}
}
@@ -645,16 +664,9 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
pollTimer = new Timer() {
@Override
public void run() {
- /*
- * Verify that polling has not recently been canceled. This
- * is needed because Timer.cancel() does not always work
- * properly in IE 8 until GWT issue 8101 has been fixed.
- */
- if (pollTimer != null) {
- getRpcProxy(UIServerRpc.class).poll();
- // Send changes even though poll is @Delayed
- getConnection().sendPendingVariableChanges();
- }
+ getRpcProxy(UIServerRpc.class).poll();
+ // Send changes even though poll is @Delayed
+ getConnection().sendPendingVariableChanges();
}
};
pollTimer.scheduleRepeating(getState().pollInterval);
@@ -665,4 +677,27 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
.getName(), "poll"));
}
}
+
+ /**
+ * Invokes the layout analyzer on the server
+ *
+ * @since 7.1
+ */
+ public void analyzeLayouts() {
+ getRpcProxy(DebugWindowServerRpc.class).analyzeLayouts();
+ }
+
+ /**
+ * Sends a request to the server to print details to console that will help
+ * the developer to locate the corresponding server-side connector in the
+ * source code.
+ *
+ * @since 7.1
+ * @param serverConnector
+ * the connector to locate
+ */
+ public void showServerDebugInfo(ServerConnector serverConnector) {
+ getRpcProxy(DebugWindowServerRpc.class).showServerDebugInfo(
+ serverConnector);
+ }
}
diff --git a/client/src/com/vaadin/client/ui/window/WindowConnector.java b/client/src/com/vaadin/client/ui/window/WindowConnector.java
index 90311e30ad..4b839384a2 100644
--- a/client/src/com/vaadin/client/ui/window/WindowConnector.java
+++ b/client/src/com/vaadin/client/ui/window/WindowConnector.java
@@ -207,6 +207,14 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector
contentStyle.setPaddingBottom(footerHeight, Unit.PX);
contentStyle.setMarginBottom(-footerHeight, Unit.PX);
+ int minWidth = lm.getOuterWidth(window.header)
+ - lm.getInnerWidth(window.header);
+ int minHeight = footerHeight + headerHeight;
+
+ getWidget().getElement().getStyle().setPropertyPx("minWidth", minWidth);
+ getWidget().getElement().getStyle()
+ .setPropertyPx("minHeight", minHeight);
+
/*
* Must set absolute position if the child has relative height and
* there's a chance of horizontal scrolling as some browsers will
@@ -384,4 +392,13 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector
public void setWindowOrderAndPosition() {
getWidget().setWindowOrderAndPosition();
}
+
+ @Override
+ public boolean hasTooltip() {
+ /*
+ * Tooltip event handler always needed on the window widget to make sure
+ * tooltips are properly hidden. (#11448)
+ */
+ return true;
+ }
}
diff --git a/common.xml b/common.xml
index d673273a53..e46cefd895 100644
--- a/common.xml
+++ b/common.xml
@@ -1,403 +1,472 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project name="common" basedir="." default="" xmlns:ivy="antlib:org.apache.ivy.ant" xmlns:antcontrib="antlib:net.sf.antcontrib" xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
-
- <tstamp>
- <format property="build.date" pattern="yyyy-MM-dd" />
- </tstamp>
-
- <dirname property="vaadin.basedir" file="${ant.file.common}" />
- <property name="gwt.basedir" location="${vaadin.basedir}/../gwt" />
- <property file="${vaadin.basedir}/build.properties" />
-
- <property name="modules.to.publish.to.maven" value="shared,server,client,client-compiler,client-compiled,theme-compiler,themes,push" />
- <property name="modules.to.publish.to.download" value="${modules.to.publish.to.maven},all" />
-
- <ivy:settings file="${vaadin.basedir}/ivysettings.xml" />
- <ivy:settings file="${vaadin.basedir}/ivysettings.xml" id="ivysettings" />
- <ivy:resolve file="${vaadin.basedir}/ivy-taskdefs.xml" conf="taskdefs" log="quiet" />
- <ivy:cachepath pathid="taskdefs.classpath" conf="taskdefs" />
- <taskdef uri="antlib:net.sf.antcontrib" resource="net/sf/antcontrib/antlib.xml" classpathref="taskdefs.classpath" />
- <!-- ant contrib for Maven integration -->
- <taskdef resource="org/apache/maven/artifact/ant/antlib.xml" uri="antlib:org.apache.maven.artifact.ant" classpathref="taskdefs.classpath" />
-
- <!-- FIXME These are not available in other files -->
- <antcontrib:propertyregex property="vaadin.version.major" input="${vaadin.version}" regexp="([^\.]*)\.([^\.]*)\.([^\.]*)" select="\1" />
- <antcontrib:propertyregex property="vaadin.version.minor" input="${vaadin.version}" regexp="([^\.]*)\.([^\.]*)\.([^\.]*)" select="\2" />
- <antcontrib:propertyregex property="vaadin.version.revision" input="${vaadin.version}" regexp="([^\.]*)\.([^\.]*)\.([^\.]*)" select="\3" />
-
- <union id="empty.reference" />
-
- <property name="filtered.webcontent.dir" location="${vaadin.basedir}/result/filteredWebContent" />
- <property name="release-notes-tickets-file" location="${vaadin.basedir}/result/release-notes-tickets.html" />
-
- <target name="filter.webcontent" unless="webcontent.filtered" depends="fetch-release-notes-tickets">
- <property name="webcontent.filtered" value="true" />
- <!-- Running without build.release-notes will cause an error, which is ignored -->
- <loadfile property="release-notes-tickets" srcFile="${release-notes-tickets-file}" failonerror="false" />
-
- <delete dir="${filtered.webcontent.dir}" />
- <copy todir="${filtered.webcontent.dir}">
- <fileset dir="${vaadin.basedir}/WebContent">
- <include name="img/**" />
- </fileset>
- </copy>
- <copy todir="${filtered.webcontent.dir}">
- <fileset dir="${vaadin.basedir}/WebContent">
- <patternset>
- <include name="release-notes.html" />
- <include name="license.html" />
- <include name="licenses/**" />
- <include name="css/**" />
- </patternset>
- </fileset>
- <filterchain>
- <expandproperties />
- <replacetokens begintoken="@" endtoken="@">
- <token key="version" value="${vaadin.version}" />
- </replacetokens>
- <replacetokens begintoken="@" endtoken="@">
- <token key="version-minor" value="${vaadin.version.major}.${vaadin.version.minor}" />
- </replacetokens>
- <replacetokens begintoken="@" endtoken="@">
- <token key="builddate" value="${build.date}" />
- </replacetokens>
- <replacetokens begintoken="@" endtoken="@">
- <token key="release-notes-tickets" value="${release-notes-tickets}" />
- </replacetokens>
- </filterchain>
- </copy>
- </target>
-
- <target name="fetch-release-notes-tickets" unless="built.release-notes" if="build.release-notes">
- <mkdir dir="${vaadin.basedir}/result"/>
- <subant buildpath="${vaadin.basedir}/buildhelpers" target="fetch-release-notes-tickets" antfile="build.xml" inheritall="true">
- <property name="output" location="${release-notes-tickets-file}" />
- </subant>
- <property name="built.release-notes" value="1" />
- </target>
-
- <fileset dir="${filtered.webcontent.dir}" id="common.files.for.all.jars">
- <patternset>
- <include name="release-notes.html" />
- <include name="license.html" />
- <include name="licenses/**" />
- <include name="css/**" />
- <include name="img/**" />
- </patternset>
- </fileset>
-
-
- <target name="pom.xml" description="Generates a pom.xml based on the Ivy configuration. Either for a snapshot or a release version" depends="pom.xml.release,pom.xml.snapshot">
- </target>
-
- <target name="pom.xml.release" if="build.release">
- <fail unless="result.dir" message="No result.dir parameter given" />
- <property name="ivy.xml" location="${result.dir}/../ivy.xml" />
- <property name="pom.xml" location="${result.dir}/lib/${module.name}-${vaadin.version}.pom" />
- <property name="conf" value="build, build-provided" />
- <property name="vaadin.maven.version" value="${vaadin.version}" />
-
- <ivy:makepom templatefile="${vaadin.basedir}/pom-template.xml" ivyfile="${ivy.xml}" pomfile="${pom.xml}" conf="${conf}">
- <mapping conf="build" scope="compile" />
- <mapping conf="build-provided" scope="provided" />
- </ivy:makepom>
- </target>
-
- <target name="pom.xml.snapshot" unless="build.release">
- <fail unless="result.dir" message="No result.dir parameter given" />
- <property name="ivy.xml" location="${result.dir}/../ivy.xml" />
- <property name="pom.xml" location="${result.dir}/lib/${module.name}-${vaadin.version}.pom" />
- <property name="temp.pom.xml" location="${pom.xml}.temp" />
- <property name="conf" value="build, build-provided" />
- <property name="vaadin.maven.version" value="${vaadin.version.major}.${vaadin.version.minor}-SNAPSHOT" />
-
- <ivy:makepom templatefile="${vaadin.basedir}/pom-template.xml" ivyfile="${ivy.xml}" pomfile="${temp.pom.xml}" conf="${conf}">
- <mapping conf="build" scope="compile" />
- <mapping conf="build-provided" scope="provided" />
- </ivy:makepom>
- <copy file="${temp.pom.xml}" tofile="${pom.xml}">
- <filterchain>
- <replacestring from="${vaadin.version}" to="${vaadin.maven.version}" />
- </filterchain>
- </copy>
- <delete file="${temp.pom.xml}" />
- </target>
-
-
- <target name="sources.jar" depends="compile, filter.webcontent">
- <fail unless="result.dir" message="No result.dir parameter given" />
- <fail unless="module.name" message="No module.name parameter given" />
- <fail unless="src" message="No src directory parameter given" />
-
- <property name="sources.jar" location="${result.dir}/lib/${module.name}-${vaadin.version}-sources.jar" />
-
- <jar file="${sources.jar}" compress="true">
- <fileset dir="${src}">
- <patternset>
- <include name="**/*.java" />
- </patternset>
- </fileset>
- <fileset refid="common.files.for.all.jars" />
- <restrict>
- <union refid="extra.jar.includes" />
- <name name="*.java" />
- </restrict>
- </jar>
-
- </target>
-
- <target name="javadoc.jar" depends="dependencies, filter.webcontent">
- <fail unless="result.dir" message="No result.dir parameter given" />
- <fail unless="module.name" message="No module.name parameter given" />
- <property name="src" location="{$result.dir}/../src" />
- <property name="javadoc.dir" value="${result.dir}/javadoc" />
- <property name="javadoc.jar" location="${result.dir}/lib/${module.name}-${vaadin.version}-javadoc.jar" />
-
- <javadoc destdir="${javadoc.dir}" author="true" version="true" use="true" windowtitle="${module.name}">
- <packageset dir="${src}" excludes="${classes.exclude}" />
- <doctitle>&lt;h1>${module.name}&lt;/h1></doctitle>
- <!-- <header><![CDATA[<script type="text/javascript" src=".html-style/style.js"></script>]]></header> -->
- <bottom>${javadoc.bottom}</bottom>
- <link offline="true" href="http://docs.oracle.com/javase/6/docs/api/" packagelistLoc="build/javadoc/j2se-1.6.0" />
- <link offline="true" href="http://java.sun.com/j2ee/1.4/docs/api/" packagelistLoc="build/javadoc/j2ee-1.4" />
- <classpath refid="classpath.compile.dependencies" />
- </javadoc>
-
- <!-- Create a javadoc jar -->
- <jar file="${javadoc.jar}" compress="true">
- <fileset dir="${javadoc.dir}" />
- <fileset refid="common.files.for.all.jars" />
- </jar>
-
- </target>
-
- <target name="jar" depends="compile, pom.xml, filter.webcontent">
- <fail unless="result.dir" message="No result.dir parameter given" />
- <fail unless="module.name" message="No module.name parameter given" />
-
- <property name="result.jar" location="${result.dir}/lib/${module.name}-${vaadin.version}.jar" />
- <property name="classes" location="{$result.dir}/classes" />
- <property name="src" location="{$result.dir}/../src" />
-
- <union id="jar.files">
- <fileset dir="${classes}" excludes="${classes.exclude}" erroronmissingdir="false" />
- <fileset dir="${src}" excludes="${jar.exclude}" erroronmissingdir="false" />
- <fileset refid="common.files.for.all.jars" />
- <union refid="extra.jar.includes" />
- </union>
-
- <jar destfile="${result.jar}" duplicate="fail" index="true">
- <manifest>
- <attribute name="Implementation-Vendor" value="${vaadin.vendor}" />
- <attribute name="Implementation-URL" value="${vaadin.url}" />
- <attribute name="Implementation-Version" value="${vaadin.version}" />
- </manifest>
- <union refid="jar.files" />
- </jar>
-
- <antcall target="common.make-osgi-bundle">
- <param name="jar" value="${result.jar}" />
- <param name="bundle-version" value="${vaadin.version}" />
- <param name="bundle-name" value="${module.name}" />
- <param name="bundle-symbolic" value="${module.symbolic}" />
- <param name="bundle-vendor" value="${vaadin.vendor}" />
- </antcall>
-
- </target>
-
- <!-- Add OSGi attributes to the manifest of the given jar -->
- <target name="make-osgi-bundle">
- <fail unless="jar" message="No jar parameter given" />
- <fail unless="bundle-name" message="No bundle-name parameter given" />
- <fail unless="bundle-symbolic" message="No bundle-symbolic parameter given" />
- <fail unless="bundle-version" message="No bundle-version parameter given" />
- <fail unless="bundle-vendor" message="No bundle-vendor parameter given" />
-
- <property name="bundle-manifestversion" value="2" />
-
- <jar file="${jar}" update="true">
- <manifest>
- <attribute name="Bundle-Version" value="${bundle-version}" />
- <attribute name="Bundle-ManifestVersion" value="${bundle-manifestversion}" />
- <attribute name="Bundle-Name" value="${bundle-name}" />
- <attribute name="Bundle-SymbolicName" value="${bundle-symbolic}" />
- <attribute name="Bundle-Vendor" value="${bundle-vendor}" />
- <attribute name="Bundle-RequiredExecutionEnvironment" value="JavaSE-${vaadin.java.version}" />
- </manifest>
- </jar>
-
- <antcontrib:if>
- <isset property="import-package" />
- <then>
- <jar file="${result.jar}" update="true">
- <manifest>
- <attribute name="Import-Package" value="${import-package}" />
- </manifest>
- </jar>
- </then>
- </antcontrib:if>
- <antcontrib:if>
- <isset property="require-bundle" />
- <then>
- <jar file="${result.jar}" update="true">
- <manifest>
- <attribute name="Require-Bundle" value="${require-bundle}" />
- </manifest>
- </jar>
- </then>
- </antcontrib:if>
- <antcontrib:if>
- <isset property="export-package" />
- <then>
- <jar file="${result.jar}" update="true">
- <manifest>
- <attribute name="Export-Package" value="${export-package}" />
- </manifest>
- </jar>
- </then>
- </antcontrib:if>
-
- <!-- Generate the Export-Package attribute in the manifest -->
- <java classname="com.vaadin.buildhelpers.GeneratePackageExports" failonerror="true" fork="yes">
- <arg value="${jar}" />
- <arg line="com/vaadin com/google ${osgi.extra.package.prefixes}" />
- <classpath refid="vaadin.buildhelpers.classpath" />
- <jvmarg value="-Dvaadin.version=${vaadin.version}" />
- </java>
- </target>
-
- <target name="compile" description="Compiles the module" depends="dependencies, directories" if="src-exists">
- <fail unless="module.name" message="No module name given" />
-
- <javac srcdir="${src}" destdir="${classes}" source="${vaadin.java.version}" target="${vaadin.java.version}" debug="true" encoding="UTF-8" includeantruntime="false">
- <classpath refid="classpath.compile.dependencies" />
- <classpath refid="classpath.compile.custom" />
- </javac>
- </target>
-
- <target name="exec-buildhelper" depends="compile">
- <fail unless="main.class" message="No main class given in 'main.class'" />
- <fail unless="output" message="No output file given in 'output'" />
- <java classname="${main.class}" output="${output}" failonerror="true" fork="yes">
- <classpath refid="vaadin.buildhelpers.classpath" />
- <classpath refid="classpath.compile.dependencies" />
- <jvmarg value="-Dvaadin.version=${vaadin.version}" />
- </java>
- </target>
-
- <target name="directories">
- <property name="result.dir" location="result" />
- <property name="src" location="${result.dir}/../src" />
- <property name="classes" location="${result.dir}/classes" />
- <available file="${src}" type="dir" property="src-exists" />
- <mkdir dir="${classes}" />
- </target>
-
- <target name="test.run" depends="test.compile">
- <fail unless="module.name" message="No module name given" />
-
- <property name="result.dir" location="result" />
- <property name="classes" location="${result.dir}/classes" />
- <property name="test.src" location="${result.dir}/../tests/src" />
- <property name="test.classes" location="${result.dir}/tests/classes" />
-
-
- <junit printsummary="withOutAndErr" fork="yes">
- <formatter usefile="false" type="plain" />
- <jvmarg value="-ea" />
- <classpath location="${test.classes}" />
- <classpath location="${classes}" />
- <classpath refid="classpath.compile.custom" />
- <classpath refid="classpath.test.dependencies" />
-
- <batchtest fork="yes">
- <fileset dir="${test.src}">
- <exclude name="**/Abstract*" />
- <exclude name="com/vaadin/tests/data/bean/*" />
- <exclude name="com/vaadin/tests/util/*" />
- <exclude name="**/VaadinClasses.java" />
- <exclude name="**/*TestRunner.java" />
- <exclude name="**/SQLTestsConstants.java" />
- </fileset>
- </batchtest>
- </junit>
- </target>
-
- <target name="test.compile" description="Compiles tests" depends="compile, dependencies.test">
- <fail unless="module.name" message="No module name given" />
- <property name="result.dir" location="result" />
- <property name="base.dir" location="${result.dir}/.." />
- <property name="test.src" location="${base.dir}/tests/src" />
- <property name="test.resources" location="${base.dir}/tests/resources" />
- <property name="test.classes" location="${result.dir}/tests/classes" />
- <property name="classes" location="${result.dir}/classes" />
-
- <mkdir dir="${test.classes}" />
-
- <javac srcdir="${test.src}" destdir="${test.classes}" source="${vaadin.java.version}" target="${vaadin.java.version}" debug="true" encoding="UTF-8" includeantruntime="false">
- <classpath refid="classpath.test.dependencies" />
- <classpath location="${classes}" />
- <classpath refid="classpath.test.custom" />
- </javac>
-
- <!-- Copy resources -->
- <copy todir="${test.classes}" failonerror="false">
- <fileset dir="${test.resources}" />
- </copy>
- </target>
-
- <target name="dependencies" description="Resolves dependencies needed by this module">
- <property name='conf' value="build, build-provided" />
- <ivy:resolve resolveid="common" conf="${conf}" />
- <ivy:cachepath pathid="classpath.compile.dependencies" conf="${conf}" />
- </target>
-
- <target name="dependencies.test" description="Resolves dependencies needed by test">
- <ivy:resolve resolveid="common" conf="test" />
- <ivy:cachepath pathid="classpath.test.dependencies" conf="test" />
- </target>
-
- <target name="clean">
- <fail unless="result.dir" message="No result.dir parameter given" />
- <delete dir="${result.dir}" />
- </target>
-
- <target name="publish-local" description="Publishes the given module to the local repository">
- <fail unless="result.dir" message="No result.dir parameter given" />
- <property name="conf" value="*(public)" />
-
- <ivy:resolve conf="${conf}" />
- <ivy:publish settingsref="ivysettings" conf="${conf}" resolver="build-temp" overwrite="true" forcedeliver="true">
- <!-- <artifacts pattern="${result.dir}/[artifact]-[revision].[ext]" />-->
- <artifacts pattern="${result.dir}/lib/[artifact]-[revision](-[classifier]).[ext]" />
-
- </ivy:publish>
- </target>
-
- <target name="publish.to.local.maven">
- <property name="conf" value="*(public)" />
-
- <ivy:resolve conf="${conf}" />
- <ivy:publish conf="${conf}" resolver="local-maven" overwrite="true">
- </ivy:publish>
- </target>
-
- <!-- Checkstyle conf -->
- <property name="cs.dir" location="${vaadin.basedir}/checkstyle" />
- <property name="cs.xml" location="${cs.dir}/vaadin-checkstyle.xml" />
- <property name="cs.header-file" location="${cs.dir}/header" />
- <taskdef resource="checkstyletask.properties" uri="antlib:com.puppycrawl.tools.checkstyle" classpathref="taskdefs.classpath" />
-
- <target name="checkstyle">
- <fail unless="result.dir" message="No result.dir parameter given" />
- <fail unless="cs.src" message="No cs.src parameter given" />
- <property name="result.dir.full" location="${result.dir}"/>
- <mkdir dir="${result.dir}" />
- <echo>##teamcity[importData type='checkstyle' path='${result.dir.full}/checkstyle-errors.xml']</echo>
- <cs:checkstyle config="${cs.xml}" failOnViolation="false">
- <fileset dir="${cs.src}" includes="**/*.java" />
- <formatter type="xml" toFile="${result.dir}/checkstyle-errors.xml"/>
- <property key="checkstyle.header.file" file="${cs.header-file}" />
- </cs:checkstyle>
- </target>
+<project name="common" basedir="." default=""
+ xmlns:ivy="antlib:org.apache.ivy.ant" xmlns:antcontrib="antlib:net.sf.antcontrib"
+ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
+
+ <tstamp>
+ <format property="build.date" pattern="yyyy-MM-dd" />
+ </tstamp>
+
+ <dirname property="vaadin.basedir" file="${ant.file.common}" />
+ <property name="gwt.basedir" location="${vaadin.basedir}/../gwt" />
+ <property file="${vaadin.basedir}/build.properties" />
+
+ <property name="modules.to.publish.to.maven"
+ value="shared,server,client,client-compiler,client-compiled,theme-compiler,themes,push" />
+ <property name="modules.to.publish.to.download" value="${modules.to.publish.to.maven},all" />
+
+ <ivy:settings file="${vaadin.basedir}/ivysettings.xml" />
+ <ivy:settings file="${vaadin.basedir}/ivysettings.xml"
+ id="ivysettings" />
+ <ivy:resolve file="${vaadin.basedir}/ivy-taskdefs.xml"
+ conf="taskdefs" log="quiet" />
+ <ivy:cachepath pathid="taskdefs.classpath" conf="taskdefs" />
+ <taskdef uri="antlib:net.sf.antcontrib" resource="net/sf/antcontrib/antlib.xml"
+ classpathref="taskdefs.classpath" />
+ <!-- ant contrib for Maven integration -->
+ <taskdef resource="org/apache/maven/artifact/ant/antlib.xml"
+ uri="antlib:org.apache.maven.artifact.ant" classpathref="taskdefs.classpath" />
+
+ <!-- FIXME These are not available in other files -->
+ <antcontrib:propertyregex property="vaadin.version.major"
+ input="${vaadin.version}" regexp="([^\.]*)\.([^\.]*)\.([^\.]*)"
+ select="\1" />
+ <antcontrib:propertyregex property="vaadin.version.minor"
+ input="${vaadin.version}" regexp="([^\.]*)\.([^\.]*)\.([^\.]*)"
+ select="\2" />
+ <antcontrib:propertyregex property="vaadin.version.revision"
+ input="${vaadin.version}" regexp="([^\.]*)\.([^\.]*)\.([^\.]*)"
+ select="\3" />
+
+ <union id="empty.reference" />
+
+ <property name="filtered.webcontent.dir"
+ location="${vaadin.basedir}/result/filteredWebContent" />
+ <property name="release-notes-tickets-file"
+ location="${vaadin.basedir}/result/release-notes-tickets.html" />
+
+ <target name="filter.webcontent" unless="webcontent.filtered"
+ depends="fetch-release-notes-tickets">
+ <property name="webcontent.filtered" value="true" />
+ <!-- Running without build.release-notes will cause an error, which
+ is ignored -->
+ <loadfile property="release-notes-tickets" srcFile="${release-notes-tickets-file}"
+ failonerror="false" />
+
+ <delete dir="${filtered.webcontent.dir}" />
+ <copy todir="${filtered.webcontent.dir}">
+ <fileset dir="${vaadin.basedir}/WebContent">
+ <include name="img/**" />
+ </fileset>
+ </copy>
+ <copy todir="${filtered.webcontent.dir}">
+ <fileset dir="${vaadin.basedir}/WebContent">
+ <patternset>
+ <include name="release-notes.html" />
+ <include name="license.html" />
+ <include name="licenses/**" />
+ <include name="css/**" />
+ </patternset>
+ </fileset>
+ <filterchain>
+ <expandproperties />
+ <replacetokens begintoken="@" endtoken="@">
+ <token key="version" value="${vaadin.version}" />
+ </replacetokens>
+ <replacetokens begintoken="@" endtoken="@">
+ <token key="version-minor"
+ value="${vaadin.version.major}.${vaadin.version.minor}" />
+ </replacetokens>
+ <replacetokens begintoken="@" endtoken="@">
+ <token key="builddate" value="${build.date}" />
+ </replacetokens>
+ <replacetokens begintoken="@" endtoken="@">
+ <token key="release-notes-tickets" value="${release-notes-tickets}" />
+ </replacetokens>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="fetch-release-notes-tickets" unless="built.release-notes"
+ if="build.release-notes">
+ <mkdir dir="${vaadin.basedir}/result" />
+ <subant buildpath="${vaadin.basedir}/buildhelpers"
+ target="fetch-release-notes-tickets" antfile="build.xml"
+ inheritall="true">
+ <property name="output" location="${release-notes-tickets-file}" />
+ </subant>
+ <property name="built.release-notes" value="1" />
+ </target>
+
+ <fileset dir="${filtered.webcontent.dir}" id="common.files.for.all.jars">
+ <patternset>
+ <include name="release-notes.html" />
+ <include name="license.html" />
+ <include name="licenses/**" />
+ <include name="css/**" />
+ <include name="img/**" />
+ </patternset>
+ </fileset>
+
+
+ <target name="pom.xml"
+ description="Generates a pom.xml based on the Ivy configuration. Either for a snapshot or a release version"
+ depends="pom.xml.release,pom.xml.snapshot">
+ </target>
+
+ <target name="pom.xml.release" if="build.release">
+ <fail unless="result.dir" message="No result.dir parameter given" />
+ <property name="ivy.xml" location="${result.dir}/../ivy.xml" />
+ <property name="pom.xml"
+ location="${result.dir}/lib/${module.name}-${vaadin.version}.pom" />
+ <property name="conf" value="build, build-provided" />
+ <property name="vaadin.maven.version" value="${vaadin.version}" />
+
+ <ivy:makepom templatefile="${vaadin.basedir}/pom-template.xml"
+ ivyfile="${ivy.xml}" pomfile="${pom.xml}" conf="${conf}">
+ <mapping conf="build" scope="compile" />
+ <mapping conf="build-provided" scope="provided" />
+ </ivy:makepom>
+ </target>
+
+ <target name="pom.xml.snapshot" unless="build.release">
+ <fail unless="result.dir" message="No result.dir parameter given" />
+ <property name="ivy.xml" location="${result.dir}/../ivy.xml" />
+ <property name="pom.xml"
+ location="${result.dir}/lib/${module.name}-${vaadin.version}.pom" />
+ <property name="temp.pom.xml" location="${pom.xml}.temp" />
+ <property name="conf" value="build, build-provided" />
+ <property name="vaadin.maven.version"
+ value="${vaadin.version.major}.${vaadin.version.minor}-SNAPSHOT" />
+
+ <ivy:makepom templatefile="${vaadin.basedir}/pom-template.xml"
+ ivyfile="${ivy.xml}" pomfile="${temp.pom.xml}" conf="${conf}">
+ <mapping conf="build" scope="compile" />
+ <mapping conf="build-provided" scope="provided" />
+ </ivy:makepom>
+ <copy file="${temp.pom.xml}" tofile="${pom.xml}">
+ <filterchain>
+ <replacestring from="${vaadin.version}"
+ to="${vaadin.maven.version}" />
+ </filterchain>
+ </copy>
+ <delete file="${temp.pom.xml}" />
+ </target>
+
+
+ <target name="sources.jar" depends="compile, filter.webcontent">
+ <fail unless="result.dir" message="No result.dir parameter given" />
+ <fail unless="module.name" message="No module.name parameter given" />
+ <fail unless="src" message="No src directory parameter given" />
+
+ <property name="sources.jar"
+ location="${result.dir}/lib/${module.name}-${vaadin.version}-sources.jar" />
+
+ <jar file="${sources.jar}" compress="true">
+ <fileset dir="${src}">
+ <patternset>
+ <include name="**/*.java" />
+ </patternset>
+ </fileset>
+ <fileset refid="common.files.for.all.jars" />
+ <restrict>
+ <union refid="extra.jar.includes" />
+ <name name="*.java" />
+ </restrict>
+ </jar>
+
+ </target>
+
+ <target name="javadoc.jar" depends="dependencies, filter.webcontent">
+ <fail unless="result.dir" message="No result.dir parameter given" />
+ <fail unless="module.name" message="No module.name parameter given" />
+ <property name="src" location="{$result.dir}/../src" />
+ <property name="javadoc.dir" value="${result.dir}/javadoc" />
+ <property name="javadoc.jar"
+ location="${result.dir}/lib/${module.name}-${vaadin.version}-javadoc.jar" />
+
+ <javadoc destdir="${javadoc.dir}" author="true" version="true"
+ use="true" windowtitle="${module.name}">
+ <packageset dir="${src}" excludes="${classes.exclude}" />
+ <doctitle>&lt;h1>${module.name}&lt;/h1></doctitle>
+ <!-- <header><![CDATA[<script type="text/javascript" src=".html-style/style.js"></script>]]></header> -->
+ <bottom>${javadoc.bottom}</bottom>
+ <link offline="true"
+ href="http://docs.oracle.com/javase/6/docs/api/"
+ packagelistLoc="build/javadoc/j2se-1.6.0" />
+ <link offline="true" href="http://java.sun.com/j2ee/1.4/docs/api/"
+ packagelistLoc="build/javadoc/j2ee-1.4" />
+ <classpath refid="classpath.compile.dependencies" />
+ </javadoc>
+
+ <!-- Create a javadoc jar -->
+ <jar file="${javadoc.jar}" compress="true">
+ <fileset dir="${javadoc.dir}" />
+ <fileset refid="common.files.for.all.jars" />
+ </jar>
+
+ </target>
+
+ <target name="jar" depends="compile, pom.xml, filter.webcontent">
+ <fail unless="result.dir" message="No result.dir parameter given" />
+ <fail unless="module.name" message="No module.name parameter given" />
+
+ <property name="result.jar"
+ location="${result.dir}/lib/${module.name}-${vaadin.version}.jar" />
+ <property name="classes" location="{$result.dir}/classes" />
+ <property name="src" location="{$result.dir}/../src" />
+
+ <union id="jar.files">
+ <fileset dir="${classes}" excludes="${classes.exclude}"
+ erroronmissingdir="false" />
+ <fileset dir="${src}" excludes="${jar.exclude}"
+ erroronmissingdir="false" />
+ <fileset refid="common.files.for.all.jars" />
+ <union refid="extra.jar.includes" />
+ </union>
+
+ <jar destfile="${result.jar}" duplicate="fail" index="true">
+ <manifest>
+ <attribute name="Implementation-Vendor" value="${vaadin.vendor}" />
+ <attribute name="Implementation-URL" value="${vaadin.url}" />
+ <attribute name="Implementation-Version"
+ value="${vaadin.version}" />
+ </manifest>
+ <union refid="jar.files" />
+ </jar>
+
+ <antcall target="common.make-osgi-bundle">
+ <param name="jar" value="${result.jar}" />
+ <param name="bundle-version" value="${vaadin.version}" />
+ <param name="bundle-name" value="${module.name}" />
+ <param name="bundle-symbolic" value="${module.symbolic}" />
+ <param name="bundle-vendor" value="${vaadin.vendor}" />
+ </antcall>
+
+ </target>
+
+ <!-- Add OSGi attributes to the manifest of the given jar -->
+ <target name="make-osgi-bundle">
+ <fail unless="jar" message="No jar parameter given" />
+ <fail unless="bundle-name" message="No bundle-name parameter given" />
+ <fail unless="bundle-symbolic" message="No bundle-symbolic parameter given" />
+ <fail unless="bundle-version" message="No bundle-version parameter given" />
+ <fail unless="bundle-vendor" message="No bundle-vendor parameter given" />
+
+ <property name="bundle-manifestversion" value="2" />
+
+ <jar file="${jar}" update="true">
+ <manifest>
+ <attribute name="Bundle-Version" value="${bundle-version}" />
+ <attribute name="Bundle-ManifestVersion"
+ value="${bundle-manifestversion}" />
+ <attribute name="Bundle-Name" value="${bundle-name}" />
+ <attribute name="Bundle-SymbolicName" value="${bundle-symbolic}" />
+ <attribute name="Bundle-Vendor" value="${bundle-vendor}" />
+ <attribute name="Bundle-RequiredExecutionEnvironment"
+ value="JavaSE-${vaadin.java.version}" />
+ </manifest>
+ </jar>
+
+ <antcontrib:if>
+ <isset property="import-package" />
+ <then>
+ <jar file="${result.jar}" update="true">
+ <manifest>
+ <attribute name="Import-Package"
+ value="${import-package}" />
+ </manifest>
+ </jar>
+ </then>
+ </antcontrib:if>
+ <antcontrib:if>
+ <isset property="require-bundle" />
+ <then>
+ <jar file="${result.jar}" update="true">
+ <manifest>
+ <attribute name="Require-Bundle"
+ value="${require-bundle}" />
+ </manifest>
+ </jar>
+ </then>
+ </antcontrib:if>
+ <antcontrib:if>
+ <isset property="export-package" />
+ <then>
+ <jar file="${result.jar}" update="true">
+ <manifest>
+ <attribute name="Export-Package"
+ value="${export-package}" />
+ </manifest>
+ </jar>
+ </then>
+ </antcontrib:if>
+
+ <!-- Generate the Export-Package attribute in the manifest -->
+ <java classname="com.vaadin.buildhelpers.GeneratePackageExports"
+ failonerror="true" fork="yes">
+ <arg value="${jar}" />
+ <arg line="com/vaadin com/google ${osgi.extra.package.prefixes}" />
+ <classpath refid="vaadin.buildhelpers.classpath" />
+ <jvmarg value="-Dvaadin.version=${vaadin.version}" />
+ </java>
+ </target>
+
+ <target name="compile" description="Compiles the module"
+ depends="dependencies, directories" if="src-exists">
+ <fail unless="module.name" message="No module name given" />
+
+ <javac srcdir="${src}" destdir="${classes}" source="${vaadin.java.version}"
+ target="${vaadin.java.version}" debug="true" encoding="UTF-8"
+ includeantruntime="false">
+ <classpath refid="classpath.compile.dependencies" />
+ <classpath refid="classpath.compile.custom" />
+ </javac>
+ </target>
+
+ <target name="exec-buildhelper" depends="compile">
+ <fail unless="main.class" message="No main class given in 'main.class'" />
+ <fail unless="output" message="No output file given in 'output'" />
+ <java classname="${main.class}" output="${output}"
+ failonerror="true" fork="yes">
+ <classpath refid="vaadin.buildhelpers.classpath" />
+ <classpath refid="classpath.compile.dependencies" />
+ <jvmarg value="-Dvaadin.version=${vaadin.version}" />
+ </java>
+ </target>
+
+ <target name="directories">
+ <property name="result.dir" location="result" />
+ <property name="src" location="${result.dir}/../src" />
+ <property name="classes" location="${result.dir}/classes" />
+ <available file="${src}" type="dir" property="src-exists" />
+ <mkdir dir="${classes}" />
+ </target>
+
+ <target name="test.run" depends="test.compile">
+ <fail unless="module.name" message="No module name given" />
+
+ <property name="result.dir" location="result" />
+ <property name="classes" location="${result.dir}/classes" />
+ <property name="test.src" location="${result.dir}/../tests/src" />
+ <property name="test.classes" location="${result.dir}/tests/classes" />
+
+
+ <junit printsummary="withOutAndErr" fork="yes">
+ <formatter usefile="false" type="plain" />
+ <jvmarg value="-ea" />
+ <classpath location="${test.classes}" />
+ <classpath location="${classes}" />
+ <classpath refid="classpath.compile.custom" />
+ <classpath refid="classpath.test.dependencies" />
+
+ <batchtest fork="yes">
+ <fileset dir="${test.src}">
+ <exclude name="**/Abstract*" />
+ <exclude name="com/vaadin/tests/data/bean/*" />
+ <exclude name="com/vaadin/tests/util/*" />
+ <exclude name="**/VaadinClasses.java" />
+ <exclude name="**/*TestRunner.java" />
+ <exclude name="**/SQLTestsConstants.java" />
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ <target name="test.compile" description="Compiles tests"
+ depends="compile, dependencies.test">
+ <fail unless="module.name" message="No module name given" />
+ <property name="result.dir" location="result" />
+ <property name="base.dir" location="${result.dir}/.." />
+ <property name="test.src" location="${base.dir}/tests/src" />
+ <property name="test.resources" location="${base.dir}/tests/resources" />
+ <property name="test.classes" location="${result.dir}/tests/classes" />
+ <property name="classes" location="${result.dir}/classes" />
+
+ <mkdir dir="${test.classes}" />
+
+ <javac srcdir="${test.src}" destdir="${test.classes}"
+ source="${vaadin.java.version}" target="${vaadin.java.version}"
+ debug="true" encoding="UTF-8" includeantruntime="false">
+ <classpath refid="classpath.test.dependencies" />
+ <classpath location="${classes}" />
+ <classpath refid="classpath.test.custom" />
+ </javac>
+
+ <!-- Copy resources -->
+ <copy todir="${test.classes}" failonerror="false">
+ <fileset dir="${test.resources}" />
+ </copy>
+ </target>
+
+ <target name="dependencies" description="Resolves dependencies needed by this module">
+ <property name='conf' value="build, build-provided" />
+ <ivy:resolve resolveid="common" conf="${conf}" />
+ <ivy:cachepath pathid="classpath.compile.dependencies"
+ conf="${conf}" />
+ </target>
+
+ <target name="dependencies.test" description="Resolves dependencies needed by test">
+ <ivy:resolve resolveid="common" conf="test" />
+ <ivy:cachepath pathid="classpath.test.dependencies"
+ conf="test" />
+ </target>
+
+ <target name="clean">
+ <fail unless="result.dir" message="No result.dir parameter given" />
+ <delete dir="${result.dir}" />
+ </target>
+
+ <target name="publish-local"
+ description="Publishes the given module to the local repository">
+ <fail unless="result.dir" message="No result.dir parameter given" />
+ <property name="conf" value="*(public)" />
+
+ <ivy:resolve conf="${conf}" />
+ <ivy:publish settingsref="ivysettings" conf="${conf}"
+ resolver="build-temp" overwrite="true" forcedeliver="true">
+ <!-- <artifacts pattern="${result.dir}/[artifact]-[revision].[ext]"
+ /> -->
+ <artifacts
+ pattern="${result.dir}/lib/[artifact]-[revision](-[classifier]).[ext]" />
+
+ </ivy:publish>
+ </target>
+
+ <target name="publish.to.local.maven">
+ <property name="conf" value="*(public)" />
+
+ <ivy:resolve conf="${conf}" />
+ <ivy:publish conf="${conf}" resolver="local-maven"
+ overwrite="true">
+ </ivy:publish>
+ </target>
+
+ <!-- Checkstyle conf -->
+ <property name="cs.dir" location="${vaadin.basedir}/checkstyle" />
+ <property name="cs.xml" location="${cs.dir}/vaadin-checkstyle.xml" />
+ <property name="cs.header-file" location="${cs.dir}/header" />
+ <taskdef resource="checkstyletask.properties" uri="antlib:com.puppycrawl.tools.checkstyle"
+ classpathref="taskdefs.classpath" />
+
+ <target name="checkstyle">
+ <fail unless="result.dir" message="No result.dir parameter given" />
+ <fail unless="cs.src" message="No cs.src parameter given" />
+ <property name="result.dir.full" location="${result.dir}" />
+ <mkdir dir="${result.dir}" />
+ <echo>##teamcity[importData type='checkstyle'
+ path='${result.dir.full}/checkstyle-errors.xml']</echo>
+ <cs:checkstyle config="${cs.xml}" failOnViolation="false">
+ <fileset dir="${cs.src}" includes="**/*.java">
+ <exclude name="com/vaadin/sass/internal/parser/Parser.java" />
+ <exclude
+ name="com/vaadin/sass/internal/parser/ParserConstants.java" />
+ <exclude
+ name="com/vaadin/sass/internal/parser/ParserTokenManager.java" />
+ </fileset>
+ <formatter type="xml"
+ toFile="${result.dir}/checkstyle-errors.xml" />
+ <property key="checkstyle.header.file" file="${cs.header-file}" />
+ </cs:checkstyle>
+ </target>
</project>
diff --git a/gwt-files.xml b/gwt-files.xml
index cc4b4a1e96..4f9f746c99 100644
--- a/gwt-files.xml
+++ b/gwt-files.xml
@@ -1,189 +1,191 @@
<?xml version="1.0"?>
<project name="GWT files for Vaadin" basedir=".">
- <include file="common.xml" as="common" />
-
- <property name="gwt.lib.dir" location="${gwt.basedir}/build/lib" />
- <property name="gwt.eclipse.basedir" location="${gwt.basedir}/eclipse" />
-
- <property name="gwt.user.jar" location="${gwt.lib.dir}/gwt-user.jar" />
- <property name="gwt.dev.jar" location="${gwt.lib.dir}/gwt-dev.jar" />
- <property name="gwt.elemental.jar" location="${gwt.lib.dir}/gwt-elemental.jar" />
- <property name="gwt.codeserver.jar" location="${gwt.lib.dir}/gwt-codeserver.jar" />
-
- <available file="${gwt.dev.jar}" property="gwt.dev.jar.found" />
- <available file="${gwt.user.jar}" property="gwt.user.jar.found" />
- <available file="${gwt.elemental.jar}" property="gwt.elemental.jar.found" />
- <available file="${gwt.codeserver.jar}" property="gwt.codeserver.jar.found" />
-
- <property name="gwt.unpack.dir" location="${vaadin.basedir}/build/gwt" />
-
- <property name="gwt.user.jar.files" location="${gwt.unpack.dir}/gwt-user.jar" />
- <property name="gwt.dev.jar.files" location="${gwt.unpack.dir}/gwt-dev.jar" />
- <property name="gwt.elemental.jar.files" location="${gwt.unpack.dir}/gwt-elemental.jar" />
- <property name="gwt.codeserver.jar.files" location="${gwt.unpack.dir}/gwt-codeserver.jar" />
-
- <target name="unpack.gwt">
- <fail unless="gwt.dev.jar.found" message="Could not find gwt-dev.jar at ${gwt.dev.jar}" />
- <fail unless="gwt.user.jar.found" message="Could not find gwt-user.jar at ${gwt.user.jar}" />
- <fail unless="gwt.elemental.jar.found" message="Could not find gwt-elemental.jar at ${gwt.elemental.jar}" />
- <fail unless="gwt.codeserver.jar.found" message="Could not find gwt-codeserver.jar at ${gwt.codeserver.jar}" />
-
- <delete dir="${gwt.unpack.dir}" />
-
- <mkdir dir="${gwt.user.jar.files}" />
- <mkdir dir="${gwt.dev.jar.files}" />
- <mkdir dir="${gwt.elemental.jar.files}" />
- <mkdir dir="${gwt.codeserver.jar.files}" />
-
- <unzip dest="${gwt.user.jar.files}" src="${gwt.user.jar}" />
- <unzip dest="${gwt.dev.jar.files}" src="${gwt.dev.jar}" />
- <unzip dest="${gwt.elemental.jar.files}" src="${gwt.elemental.jar}" />
- <unzip dest="${gwt.codeserver.jar.files}" src="${gwt.codeserver.jar}" />
- </target>
-
- <union id="client-compiler.gwt.includes">
- <!-- GWT development JAR contents including many external dependencies
+ <include file="common.xml" as="common" />
+
+ <property name="gwt.lib.dir" location="${gwt.basedir}/build/lib" />
+ <property name="gwt.eclipse.basedir" location="${gwt.basedir}/eclipse" />
+
+ <property name="gwt.user.jar" location="${gwt.lib.dir}/gwt-user.jar" />
+ <property name="gwt.dev.jar" location="${gwt.lib.dir}/gwt-dev.jar" />
+ <property name="gwt.elemental.jar" location="${gwt.lib.dir}/gwt-elemental.jar" />
+ <property name="gwt.codeserver.jar" location="${gwt.lib.dir}/gwt-codeserver.jar" />
+
+ <available file="${gwt.dev.jar}" property="gwt.dev.jar.found" />
+ <available file="${gwt.user.jar}" property="gwt.user.jar.found" />
+ <available file="${gwt.elemental.jar}" property="gwt.elemental.jar.found" />
+ <available file="${gwt.codeserver.jar}" property="gwt.codeserver.jar.found" />
+
+ <property name="gwt.unpack.dir" location="${vaadin.basedir}/build/gwt" />
+
+ <property name="gwt.user.jar.files" location="${gwt.unpack.dir}/gwt-user.jar" />
+ <property name="gwt.dev.jar.files" location="${gwt.unpack.dir}/gwt-dev.jar" />
+ <property name="gwt.elemental.jar.files" location="${gwt.unpack.dir}/gwt-elemental.jar" />
+ <property name="gwt.codeserver.jar.files" location="${gwt.unpack.dir}/gwt-codeserver.jar" />
+
+ <target name="unpack.gwt">
+ <fail unless="gwt.dev.jar.found" message="Could not find gwt-dev.jar at ${gwt.dev.jar}" />
+ <fail unless="gwt.user.jar.found"
+ message="Could not find gwt-user.jar at ${gwt.user.jar}" />
+ <fail unless="gwt.elemental.jar.found"
+ message="Could not find gwt-elemental.jar at ${gwt.elemental.jar}" />
+ <fail unless="gwt.codeserver.jar.found"
+ message="Could not find gwt-codeserver.jar at ${gwt.codeserver.jar}" />
+
+ <delete dir="${gwt.unpack.dir}" />
+
+ <mkdir dir="${gwt.user.jar.files}" />
+ <mkdir dir="${gwt.dev.jar.files}" />
+ <mkdir dir="${gwt.elemental.jar.files}" />
+ <mkdir dir="${gwt.codeserver.jar.files}" />
+
+ <unzip dest="${gwt.user.jar.files}" src="${gwt.user.jar}" />
+ <unzip dest="${gwt.dev.jar.files}" src="${gwt.dev.jar}" />
+ <unzip dest="${gwt.elemental.jar.files}" src="${gwt.elemental.jar}" />
+ <unzip dest="${gwt.codeserver.jar.files}" src="${gwt.codeserver.jar}" />
+ </target>
+
+ <union id="client-compiler.gwt.includes">
+ <!-- GWT development JAR contents including many external dependencies
(for now) -->
- <fileset dir="${gwt.dev.jar.files}">
- <exclude name="META-INF/**" />
- <exclude name="license*" />
- <exclude name="LICENSE*" />
-
- <!-- Packages in vaadin-shared-deps.jar or declared
- as dependencies -->
- <exclude name="com/google/gwt/thirdparty/guava/**" />
- <exclude name="javax/servlet/**" />
- <exclude name="javax/xml/**" />
- <!-- cssparser -->
- <exclude name="com/steadystate/css/**" />
- <!-- Ant & AntLauncher -->
- <exclude name="org/apache/tools/**" />
- <!-- Jetty & jetty-util -->
- <exclude name="org/mortbay/**" />
- <!-- Swing Worker-->
- <exclude name="org/jdesktop/swingworker/**" />
- <!-- Apache commons codec & io & lang & collections & logging -->
- <exclude name="org/apache/commons/codec/**" />
- <exclude name="org/apache/commons/io/**" />
- <exclude name="org/apache/commons/lang/**" />
- <exclude name="org/apache/commons/collections/**" />
- <exclude name="org/apache/commons/logging/**" />
- <!-- apache mime4j -->
- <exclude name="org/apache/james/mime4j/**" />
-
- <!-- client-compiler-deps -->
- <exclude name="com/gargoylesoftware/" />
- <exclude name="com/google/common/" />
- <exclude name="com/google/debugging/" />
- <exclude name="com/google/gwt/dev/protobuf/" />
- <exclude name="com/google/gwt/thirdparty/debugging/" />
- <exclude name="com/google/gwt/thirdparty/javascript/" />
- <exclude name="com/google/gwt/thirdparty/mozilla/" />
- <exclude name="com/ibm/" />
- <exclude name="externs.zip" />
- <exclude name="java_cup/" />
- <exclude name="javax/annotation/" />
- <exclude name="net/sourceforge/htmlunit/" />
- <exclude name="org/apache/bcel/" />
- <exclude name="org/apache/html/" />
- <exclude name="org/apache/http/" />
- <exclude name="org/apache/NOTICE" />
- <exclude name="org/apache/regexp/" />
- <exclude name="org/apache/tapestry/" />
- <exclude name="org/apache/wml/" />
- <exclude name="org/apache/xalan/" />
- <exclude name="org/apache/xerces/" />
- <exclude name="org/apache/xml/" />
- <exclude name="org/apache/xmlcommons/" />
- <exclude name="org/apache/xpath/" />
- <exclude name="org/cyberneko/" />
- <exclude name="org/eclipse/" />
- <exclude name="org/kohsuke/" />
- <exclude name="org/w3c/" />
- <exclude name="org/xml/" />
- <exclude name="rhino_ast/" />
- <exclude name="rhinoDiff.txt" />
- <exclude name="trax/" />
- <exclude name="unicode-license.txt" />
- <exclude name="org/json" />
-
- <exclude name="license/NOTICE" />
- <exclude name="license/LICENSE.dom-documentation.txt" />
- <exclude name="license/LICENSE.dom-software.txt" />
- <exclude name="license/LICENSE" />
- <exclude name="license/README.dom.txt" />
- <exclude name="license/README.sax.txt" />
-
- <!-- Overridden in Vaadin -->
- <exclude name="com/google/gwt/dev/About.properties" />
-
- </fileset>
-
- <!-- GWT SuperDevMode -->
- <fileset dir="${gwt.codeserver.jar.files}">
- <exclude name="META-INF/**" />
- </fileset>
- </union>
-
- <union id="client-compiled-cache.gwt.includes">
- <!-- Precompiled GWT modules (.gwtar file) -->
- <fileset dir="${gwt.user.jar.files}">
- <exclude name="META-INF/**" />
-
- <!-- precompiled GWT modules (.gwtar) -->
- <include name="**/*.gwtar" />
- <!-- external dependencies -->
- <exclude name="javax/servlet/**" />
- <exclude name="org/w3c/css/sac/**" />
-
- </fileset>
- </union>
-
- <union id="client.gwt.includes">
- <fileset dir="${gwt.user.jar.files}">
- <exclude name="META-INF/**" />
- <!-- precompiled GWT modules (.gwtar) goes into client-compiled -->
- <exclude name="**/*.gwtar" />
- <!-- These go into server -->
- <exclude name="com/google/gwt/*/server/**" />
- <!-- These go into shared -->
- <exclude name="com/google/gwt/*/shared/**" />
- <exclude name="com/google/gwt/*/*/shared/**" />
- <exclude name="com/google/web/bindery/*/shared/**" />
-
- <!-- Used by the server, in wrong package in GWT -->
- <exclude name="com/google/gwt/user/client/rpc/IsSerializable.*" />
-
- <!-- These are in vaadin-shared-deps -->
- <exclude name="com/google/gwt/thirdparty/streamhtmlparser/**" />
- <exclude name="org/w3c/flute/**" />
-
- <!-- external dependencies -->
- <exclude name="javax/servlet/**" />
- <exclude name="org/w3c/css/sac/**" />
- </fileset>
- <!-- GWT Elemental -->
- <fileset dir="${gwt.elemental.jar.files}">
- <exclude name="META-INF/**" />
- </fileset>
- </union>
-
- <union id="shared.gwt.includes">
- <fileset dir="${gwt.user.jar.files}">
- <!-- Shared files from user -->
- <include name="com/google/gwt/*/shared/**" />
- <include name="com/google/gwt/*/*/shared/**" />
- <include name="com/google/web/bindery/*/shared/**" />
- <include name="com/google/gwt/user/client/rpc/IsSerializable.*" />
-
- </fileset>
- </union>
-
- <union id="server.gwt.includes">
- <fileset dir="${gwt.user.jar.files}">
- <!-- Server files from gwt-user -->
- <include name="com/google/gwt/*/server/**" />
- </fileset>
- </union>
+ <fileset dir="${gwt.dev.jar.files}">
+ <exclude name="META-INF/**" />
+ <exclude name="license*" />
+ <exclude name="LICENSE*" />
+
+ <!-- Packages in vaadin-shared-deps.jar or declared as dependencies -->
+ <exclude name="com/google/gwt/thirdparty/guava/**" />
+ <exclude name="javax/servlet/**" />
+ <exclude name="javax/xml/**" />
+ <!-- cssparser -->
+ <exclude name="com/steadystate/css/**" />
+ <!-- Ant & AntLauncher -->
+ <exclude name="org/apache/tools/**" />
+ <!-- Jetty & jetty-util -->
+ <exclude name="org/mortbay/**" />
+ <!-- Swing Worker -->
+ <exclude name="org/jdesktop/swingworker/**" />
+ <!-- Apache commons codec & io & lang & collections & logging -->
+ <exclude name="org/apache/commons/codec/**" />
+ <exclude name="org/apache/commons/io/**" />
+ <exclude name="org/apache/commons/lang/**" />
+ <exclude name="org/apache/commons/collections/**" />
+ <exclude name="org/apache/commons/logging/**" />
+ <!-- apache mime4j -->
+ <exclude name="org/apache/james/mime4j/**" />
+
+ <!-- client-compiler-deps -->
+ <exclude name="com/gargoylesoftware/" />
+ <exclude name="com/google/common/" />
+ <exclude name="com/google/debugging/" />
+ <exclude name="com/google/gwt/dev/protobuf/" />
+ <exclude name="com/google/gwt/thirdparty/debugging/" />
+ <exclude name="com/google/gwt/thirdparty/javascript/" />
+ <exclude name="com/google/gwt/thirdparty/mozilla/" />
+ <exclude name="com/ibm/" />
+ <exclude name="externs.zip" />
+ <exclude name="java_cup/" />
+ <exclude name="javax/annotation/" />
+ <exclude name="net/sourceforge/htmlunit/" />
+ <exclude name="org/apache/bcel/" />
+ <exclude name="org/apache/html/" />
+ <exclude name="org/apache/http/" />
+ <exclude name="org/apache/NOTICE" />
+ <exclude name="org/apache/regexp/" />
+ <exclude name="org/apache/tapestry/" />
+ <exclude name="org/apache/wml/" />
+ <exclude name="org/apache/xalan/" />
+ <exclude name="org/apache/xerces/" />
+ <exclude name="org/apache/xml/" />
+ <exclude name="org/apache/xmlcommons/" />
+ <exclude name="org/apache/xpath/" />
+ <exclude name="org/cyberneko/" />
+ <exclude name="org/eclipse/" />
+ <exclude name="org/kohsuke/" />
+ <exclude name="org/w3c/" />
+ <exclude name="org/xml/" />
+ <exclude name="rhino_ast/" />
+ <exclude name="rhinoDiff.txt" />
+ <exclude name="trax/" />
+ <exclude name="unicode-license.txt" />
+ <exclude name="org/json" />
+
+ <exclude name="license/NOTICE" />
+ <exclude name="license/LICENSE.dom-documentation.txt" />
+ <exclude name="license/LICENSE.dom-software.txt" />
+ <exclude name="license/LICENSE" />
+ <exclude name="license/README.dom.txt" />
+ <exclude name="license/README.sax.txt" />
+
+ <!-- Overridden in Vaadin -->
+ <exclude name="com/google/gwt/dev/About.properties" />
+
+ </fileset>
+
+ <!-- GWT SuperDevMode -->
+ <fileset dir="${gwt.codeserver.jar.files}">
+ <exclude name="META-INF/**" />
+ </fileset>
+ </union>
+
+ <union id="client-compiled-cache.gwt.includes">
+ <!-- Precompiled GWT modules (.gwtar file) -->
+ <fileset dir="${gwt.user.jar.files}">
+ <exclude name="META-INF/**" />
+
+ <!-- precompiled GWT modules (.gwtar) -->
+ <include name="**/*.gwtar" />
+ <!-- external dependencies -->
+ <exclude name="javax/servlet/**" />
+ <exclude name="org/w3c/css/sac/**" />
+
+ </fileset>
+ </union>
+
+ <union id="client.gwt.includes">
+ <fileset dir="${gwt.user.jar.files}">
+ <exclude name="META-INF/**" />
+ <!-- precompiled GWT modules (.gwtar) goes into client-compiled -->
+ <exclude name="**/*.gwtar" />
+ <!-- These go into server -->
+ <exclude name="com/google/gwt/*/server/**" />
+ <!-- These go into shared -->
+ <exclude name="com/google/gwt/*/shared/**" />
+ <exclude name="com/google/gwt/*/*/shared/**" />
+ <exclude name="com/google/web/bindery/*/shared/**" />
+
+ <!-- Used by the server, in wrong package in GWT -->
+ <exclude name="com/google/gwt/user/client/rpc/IsSerializable.*" />
+
+ <!-- These are in vaadin-shared-deps -->
+ <exclude name="com/google/gwt/thirdparty/streamhtmlparser/**" />
+ <exclude name="org/w3c/flute/**" />
+
+ <!-- external dependencies -->
+ <exclude name="javax/servlet/**" />
+ <exclude name="org/w3c/css/sac/**" />
+ </fileset>
+ <!-- GWT Elemental -->
+ <fileset dir="${gwt.elemental.jar.files}">
+ <exclude name="META-INF/**" />
+ </fileset>
+ </union>
+
+ <union id="shared.gwt.includes">
+ <fileset dir="${gwt.user.jar.files}">
+ <!-- Shared files from user -->
+ <include name="com/google/gwt/*/shared/**" />
+ <include name="com/google/gwt/*/*/shared/**" />
+ <include name="com/google/web/bindery/*/shared/**" />
+ <include name="com/google/gwt/user/client/rpc/IsSerializable.*" />
+
+ </fileset>
+ </union>
+
+ <union id="server.gwt.includes">
+ <fileset dir="${gwt.user.jar.files}">
+ <!-- Server files from gwt-user -->
+ <include name="com/google/gwt/*/server/**" />
+ </fileset>
+ </union>
</project>
diff --git a/ivy-taskdefs.xml b/ivy-taskdefs.xml
index 64d5ec1be1..3c04e5a051 100644
--- a/ivy-taskdefs.xml
+++ b/ivy-taskdefs.xml
@@ -1,24 +1,24 @@
<ivy-module version="2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
- <info organisation="com.vaadin" module="vaadin" />
- <configurations>
- <conf name="taskdefs" description="Ant task definitions"
- visibility="private" />
- </configurations>
- <publications />
- <dependencies>
- <!-- Ant tasks -->
- <dependency org="ant-contrib" name="ant-contrib" rev="1.0b3"
- conf="taskdefs ->master" />
- <dependency org="org.apache.maven" name="maven-ant-tasks"
- rev="2.0.10" conf="taskdefs ->master" />
- <dependency org="com.googlecode.jarjar" name="jarjar" rev="1.3"
- conf="taskdefs ->master" />
- <dependency org="com.puppycrawl.tools" name="checkstyle"
- rev="5.6" />
- </dependencies>
+ <info organisation="com.vaadin" module="vaadin" />
+ <configurations>
+ <conf name="taskdefs" description="Ant task definitions"
+ visibility="private" />
+ </configurations>
+ <publications />
+ <dependencies>
+ <!-- Ant tasks -->
+ <dependency org="ant-contrib" name="ant-contrib" rev="1.0b3"
+ conf="taskdefs ->master" />
+ <dependency org="org.apache.maven" name="maven-ant-tasks"
+ rev="2.0.10" conf="taskdefs ->master" />
+ <dependency org="com.googlecode.jarjar" name="jarjar"
+ rev="1.3" conf="taskdefs ->master" />
+ <dependency org="com.puppycrawl.tools" name="checkstyle"
+ rev="5.6" />
+ </dependencies>
</ivy-module>
diff --git a/ivysettings.xml b/ivysettings.xml
index 288eae9036..6c230b9fd8 100644
--- a/ivysettings.xml
+++ b/ivysettings.xml
@@ -16,12 +16,13 @@
pattern="${user.home}/.m2/repository/[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" />
</filesystem>
<dual name="custom-smartsprites">
- <filesystem name="smartsprites-ivy">
- <ivy pattern="${ivy.settings.dir}/theme-compiler/ivymodule/[module]-ivy-[revision].xml" />
- </filesystem>
+ <url name="smartsprites-ivy">
+ <ivy
+ pattern="http://vaadin.com/download/external/[module]-ivy-[revision].xml" />
+ </url>
<url name="smartsprites-artifact">
<artifact
- pattern="http://dev.vaadin.com/svn/versions/6.8/build/smartsprites/lib/[artifact](-[revision]).[ext]" />
+ pattern="http://vaadin.com/download/external/[artifact](-[revision]).[ext]" />
</url>
</dual>
<filesystem name="build-temp">
@@ -32,9 +33,9 @@
</filesystem>
</resolvers>
<modules>
- <!-- IT Mill patched SmartSprites -->
+ <!-- Custom SmartSprites until 0.2.10 is released -->
<module organisation="com.carrotsearch" name="smartsprites"
- revision="0.2.3-itmill" resolver="custom-smartsprites" />
+ revision="0.2.10-vaadin" resolver="custom-smartsprites" />
<module organisation="com.vaadin" name="vaadin-buildhelpers"
resolver="build-temp" />
<module organisation="com.vaadin" name="vaadin-shared"
diff --git a/publish.xml b/publish.xml
index 61638851cd..e979ec1ca9 100644
--- a/publish.xml
+++ b/publish.xml
@@ -1,74 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project name="publish" basedir="." default="" xmlns:ivy="antlib:org.apache.ivy.ant" xmlns:antcontrib="antlib:net.sf.antcontrib" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
- <include file="common.xml" as="common" />
- <include file="build.xml" as="vaadin" />
+<project name="publish" basedir="." default=""
+ xmlns:ivy="antlib:org.apache.ivy.ant" xmlns:antcontrib="antlib:net.sf.antcontrib"
+ xmlns:artifact="antlib:org.apache.maven.artifact.ant">
+ <include file="common.xml" as="common" />
+ <include file="build.xml" as="vaadin" />
- <!-- Dummy value as ivysettings-publish require a value -->
- <property name="publish.sftp.keyfile" value="/dummy" />
- <property name="publish.sftp.ivy.pattern" value="dummy" />
+ <!-- Dummy value as ivysettings-publish require a value -->
+ <property name="publish.sftp.keyfile" value="/dummy" />
+ <property name="publish.sftp.ivy.pattern" value="dummy" />
- <ivy:settings file="ivysettings.xml" />
- <ivy:settings file="ivysettings-publish.xml" id="publish.settings" />
- <property file="publish.properties" />
+ <ivy:settings file="ivysettings.xml" />
+ <ivy:settings file="ivysettings-publish.xml" id="publish.settings" />
+ <property file="publish.properties" />
- <available property="ant-jsch.present" file="${ant.home}/lib/ant-jsch.jar" />
- <available property="jsch.present" file="${ant.home}/lib/jsch-0.1.48.jar" />
- <fail unless="ant-jsch.present" message="Please install ant-jsch.jar into ANT_HOME/lib" />
- <fail unless="jsch.present" message="Please install jsch.jar into ANT_HOME/lib" />
+ <available property="ant-jsch.present" file="${ant.home}/lib/ant-jsch.jar" />
+ <available property="jsch.present" file="${ant.home}/lib/jsch-0.1.48.jar" />
+ <fail unless="ant-jsch.present" message="Please install ant-jsch.jar into ANT_HOME/lib" />
+ <fail unless="jsch.present" message="Please install jsch.jar into ANT_HOME/lib" />
- <target name="nightly.publish" depends="nightly.download.publish, nightly.maven.publish">
+ <target name="nightly.publish"
+ depends="nightly.download.publish, nightly.maven.publish">
- </target>
+ </target>
- <!-- Copies the nightly build artifacts to the download server. -->
- <target name="nightly.tests.publish" if="nightly.tests.publish">
- <property name="file.war" location="result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${version}.war" />
- <property name="target" value="${nightly.tests.publish}/${vaadin.version.major}.${vaadin.version.minor}-${build.tag}.war" />
+ <!-- Copies the nightly build artifacts to the download server. -->
+ <target name="nightly.tests.publish" if="nightly.tests.publish">
+ <property name="file.war"
+ location="result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${version}.war" />
+ <property name="target"
+ value="${nightly.tests.publish}/${vaadin.version.major}.${vaadin.version.minor}-${build.tag}.war" />
- <echo>Installing ${src} to ${target}</echo>
+ <echo>Installing ${src} to ${target}</echo>
- <scp todir="${nightly.tests.publish}" file="${file.war}">
- </scp>
- </target>
+ <scp todir="${nightly.tests.publish}" file="${file.war}">
+ </scp>
+ </target>
- <target name="nightly.download.publish">
- <antcontrib:foreach list="${modules.to.publish.to.download}" target="publish.module.to.download.site" param="module" />
- </target>
+ <target name="nightly.download.publish">
+ <antcontrib:foreach list="${modules.to.publish.to.download}"
+ target="publish.module.to.download.site" param="module" />
+ </target>
- <target name="nightly.maven.publish">
- <antcontrib:foreach list="${modules.to.publish.to.maven}" target="publish.module.to.maven" param="module" />
- </target>
+ <target name="nightly.maven.publish">
+ <antcontrib:foreach list="${modules.to.publish.to.maven}"
+ target="publish.module.to.maven" param="module" />
+ </target>
- <target name="publish.module.to.download.site">
- <fail unless="module" message="No module to publish defined" />
- <ivy:resolve file="${module}/ivy.xml" />
- <ivy:publish publishivy="false" settingsref="publish.settings" conf="*(public)" resolver="sftp-publish">
- <artifacts pattern="${ivy.settings.dir}/result/artifacts/[revision]/[module]/[artifact]-[revision](-[classifier]).[ext]" />
- </ivy:publish>
- </target>
+ <target name="publish.module.to.download.site">
+ <fail unless="module" message="No module to publish defined" />
+ <ivy:resolve file="${module}/ivy.xml" />
+ <ivy:publish publishivy="false" settingsref="publish.settings"
+ conf="*(public)" resolver="sftp-publish">
+ <artifacts
+ pattern="${ivy.settings.dir}/result/artifacts/[revision]/[module]/[artifact]-[revision](-[classifier]).[ext]" />
+ </ivy:publish>
+ </target>
- <target name="publish.module.to.maven">
- <fail unless="module" message="No module to publish defined" />
- <property file="${gpg.passphrase.file}" />
+ <target name="publish.module.to.maven">
+ <fail unless="module" message="No module to publish defined" />
+ <property file="${gpg.passphrase.file}" />
- <!-- Ivy should be able to handle this but this does not work at the moment
- <ivy:resolve file="${module}/ivy.xml" />
- <ivy:publish pubrevision="7.0-SNAPSHOT" publishivy="false" settingsref="publish.settings" conf="*(public)" resolver="sonatype">
- <artifacts pattern="${ivy.settings.dir}/result/artifacts/${vaadin.version}/[module]/[artifact]-${vaadin.version}(-[classifier]).[ext]" />
- </ivy:publish>
--->
- <property name="jar.file" location="result/artifacts/${vaadin.version}/vaadin-${module}/vaadin-${module}-${vaadin.version}.jar" />
- <property name="pom.file" location="result/artifacts/${vaadin.version}/vaadin-${module}/vaadin-${module}-${vaadin.version}.pom" />
+ <!-- Ivy should be able to handle this but this does not work at
+ the moment <ivy:resolve file="${module}/ivy.xml" /> <ivy:publish pubrevision="7.0-SNAPSHOT"
+ publishivy="false" settingsref="publish.settings" conf="*(public)" resolver="sonatype">
+ <artifacts pattern="${ivy.settings.dir}/result/artifacts/${vaadin.version}/[module]/[artifact]-${vaadin.version}(-[classifier]).[ext]"
+ /> </ivy:publish> -->
+ <property name="jar.file"
+ location="result/artifacts/${vaadin.version}/vaadin-${module}/vaadin-${module}-${vaadin.version}.jar" />
+ <property name="pom.file"
+ location="result/artifacts/${vaadin.version}/vaadin-${module}/vaadin-${module}-${vaadin.version}.pom" />
- <artifact:mvn failonerror="true">
- <arg value="gpg:sign-and-deploy-file" />
- <sysproperty key="file" value="${jar.file}" />
- <sysproperty key="pomFile" value="${pom.file}" />
- <sysproperty key="repositoryId" value="${maven.snapshot.repository.id}" />
- <sysproperty key="url" value="${maven.snapshot.repository.url}" />
- <sysproperty key="gpg.passphrase" value="${gpg.passphrase}" />
- <sysproperty key="retryFailedDeploymentCount" value="10" />
- </artifact:mvn>
- </target>
+ <artifact:mvn failonerror="true">
+ <arg value="gpg:sign-and-deploy-file" />
+ <sysproperty key="file" value="${jar.file}" />
+ <sysproperty key="pomFile" value="${pom.file}" />
+ <sysproperty key="repositoryId"
+ value="${maven.snapshot.repository.id}" />
+ <sysproperty key="url"
+ value="${maven.snapshot.repository.url}" />
+ <sysproperty key="gpg.passphrase" value="${gpg.passphrase}" />
+ <sysproperty key="retryFailedDeploymentCount"
+ value="10" />
+ </artifact:mvn>
+ </target>
</project> \ No newline at end of file
diff --git a/push/build.xml b/push/build.xml
index 95284e6e37..ad27599d36 100644
--- a/push/build.xml
+++ b/push/build.xml
@@ -1,74 +1,84 @@
<?xml version="1.0"?>
-<project name="vaadin-push" basedir="." default="publish-local" xmlns:ivy="antlib:org.apache.ivy.ant">
- <description>
- Meta package which defines dependencies needed for push
- </description>
- <include file="../build.xml" as="vaadin" />
- <include file="../common.xml" as="common" />
+<project name="vaadin-push" basedir="." default="publish-local"
+ xmlns:ivy="antlib:org.apache.ivy.ant">
+ <description>
+ Meta package which defines dependencies needed for push
+ </description>
+ <include file="../build.xml" as="vaadin" />
+ <include file="../common.xml" as="common" />
- <property name="module.name" value="vaadin-push" />
- <property name="module.symbolic" value="com.vaadin.push" />
- <property name="result.dir" location="result" />
- <property name="vaadinPush.js" location="${result.dir}/js/VAADIN/vaadinPush.js" />
- <path id="classpath.compile.custom" />
+ <property name="module.name" value="vaadin-push" />
+ <property name="module.symbolic" value="com.vaadin.push" />
+ <property name="result.dir" location="result" />
+ <property name="vaadinPush.js" location="${result.dir}/js/VAADIN/vaadinPush.js" />
- <union id="jar.includes">
- <fileset dir="${result.dir}/js">
- <include name="VAADIN/vaadinPush.js" />
- </fileset>
- </union>
+ <!-- Keep the version number in sync with ivy.xml -->
+ <property name="atmosphere.version" value="1.0.13" />
+ <property name="jquery.version" value="1.7.2" />
- <target name="vaadinPush.js">
- <mkdir dir="${result.dir}/js/VAADIN" />
- <property name="vaadinPush.js.output" location="${result.dir}/js/VAADIN/vaadinPush.js" />
- <property name="vaadinPush.js.combined.output" location="${result.dir}/js/VAADIN/push.combined.js" />
+ <path id="classpath.compile.custom" />
- <loadfile srcfile="${vaadin.basedir}/WebContent/VAADIN/jquery-1.7.2.js" property="jquery.js.contents" />
- <loadfile srcfile="${vaadin.basedir}/WebContent/VAADIN/jquery.atmosphere.js" property="jquery.atmosphere.js.contents" />
- <loadfile srcfile="${vaadin.basedir}/WebContent/VAADIN/vaadinPush.js.tpl" property="vaadinPush.js.contents">
- <filterchain>
- <replacetokens begintoken="@" endtoken="@">
- <token key="jquery.js" value="${jquery.js.contents}" />
- <token key="jquery.atmosphere.js" value="${jquery.atmosphere.js.contents}" />
- </replacetokens>
- </filterchain>
- </loadfile>
- <echo file="${vaadinPush.js.combined.output}">${vaadinPush.js.contents}</echo>
+ <union id="jar.includes">
+ <fileset dir="${result.dir}/js">
+ <include name="VAADIN/vaadinPush.js" />
+ </fileset>
+ </union>
- <!-- Minify -->
- <ivy:retrieve organisation="com.yahoo.platform.yui" module="yuicompressor" revision="2.4.7" inline="true" type="jar" pattern="${result.dir}/compressor.jar" />
- <java jar="${result.dir}/compressor.jar" fork="true">
- <arg value="-v"/>
- <arg value="-o"/>
- <arg file="${vaadinPush.js.output}"/>
- <arg file="${vaadinPush.js.combined.output}"/>
- </java>
- </target>
-
- <target name="jar" depends="vaadinPush.js">
- <property name="server.osgi.import" value="" />
- <antcall target="common.jar">
- <param name="require-bundle" value="" />
- <param name="import-package" value="${server.osgi.import}" />
- <reference torefid="extra.jar.includes" refid="jar.includes" />
- </antcall>
- </target>
+ <target name="vaadinPush.js">
+ <mkdir dir="${result.dir}/js/VAADIN" />
+ <property name="vaadinPush.js.output" location="${result.dir}/js/VAADIN/vaadinPush.js" />
+ <property name="vaadinPush.js.combined.output"
+ location="${result.dir}/js/VAADIN/push.combined.js" />
- <target name="publish-local" depends="jar">
- <antcall target="common.sources.jar">
- <reference torefid="extra.jar.includes" refid="jar.includes" />
- </antcall>
- <antcall target="common.javadoc.jar" />
- <antcall target="common.publish-local" />
- </target>
+ <loadfile
+ srcfile="${vaadin.basedir}/WebContent/VAADIN/jquery-${jquery.version}.js"
+ property="jquery.js.contents" />
+ <loadfile
+ srcfile="${vaadin.basedir}/WebContent/VAADIN/jquery.atmosphere.js"
+ property="jquery.atmosphere.js.contents" />
+ <loadfile
+ srcfile="${vaadin.basedir}/WebContent/VAADIN/vaadinPush.js.tpl"
+ property="vaadinPush.js.contents">
+ <filterchain>
+ <replacetokens begintoken="@" endtoken="@">
+ <token key="jquery.js" value="${jquery.js.contents}" />
+ <token key="jquery.atmosphere.js" value="${jquery.atmosphere.js.contents}" />
+ </replacetokens>
+ </filterchain>
+ </loadfile>
+ <echo file="${vaadinPush.js.combined.output}">${vaadinPush.js.contents}</echo>
- <target name="clean">
- <antcall target="common.clean" />
- </target>
- <target name="checkstyle">
- </target>
+ <!-- Minify -->
+ <ivy:retrieve organisation="com.yahoo.platform.yui"
+ module="yuicompressor" revision="2.4.7" inline="true" type="jar"
+ pattern="${result.dir}/compressor.jar" />
+ <java jar="${result.dir}/compressor.jar" fork="true">
+ <arg value="-v" />
+ <arg value="-o" />
+ <arg file="${vaadinPush.js.output}" />
+ <arg file="${vaadinPush.js.combined.output}" />
+ </java>
+ </target>
- <target name="test" depends="checkstyle">
- </target>
+ <target name="jar" depends="vaadinPush.js">
+ <antcall target="common.jar">
+ <param name="require-bundle"
+ value="org.atmosphere.atmosphere-runtime;bundle-version=&quot;${atmosphere.version}&quot;;visibility:=reexport" />
+ <reference torefid="extra.jar.includes" refid="jar.includes" />
+ </antcall>
+ </target>
+
+ <target name="publish-local" depends="jar">
+ <antcall target="common.publish-local" />
+ </target>
+
+ <target name="clean">
+ <antcall target="common.clean" />
+ </target>
+ <target name="checkstyle">
+ </target>
+
+ <target name="test" depends="checkstyle">
+ </target>
</project> \ No newline at end of file
diff --git a/push/ivy.xml b/push/ivy.xml
index 153c02e256..e2ba3a63f7 100644
--- a/push/ivy.xml
+++ b/push/ivy.xml
@@ -4,8 +4,7 @@
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd"
xmlns:m="http://ant.apache.org/ivy/maven">
- <info organisation="com.vaadin" module="vaadin-push"
- revision="${vaadin.version}" />
+ <info organisation="com.vaadin" module="vaadin-push" revision="${vaadin.version}" />
<configurations>
<conf name="build" />
@@ -15,22 +14,21 @@
</configurations>
<publications>
<artifact type="jar" ext="jar" />
- <artifact type="source" ext="jar" m:classifier="sources" />
- <artifact type="javadoc" ext="jar" m:classifier="javadoc" />
+ <!-- <artifact type="source" ext="jar" m:classifier="sources" />
+ <artifact type="javadoc" ext="jar" m:classifier="javadoc" /> -->
<artifact type="pom" ext="pom" />
</publications>
<dependencies>
-
-
<!-- API DEPENDENCIES -->
-
+
<!--Servlet API version 2.4 -->
<dependency org="javax.servlet" name="servlet-api"
rev="2.4" conf="build-provided,ide,test -> default" />
-
+
<!-- Atmosphere -->
- <dependency org="org.atmosphere" name="atmosphere-runtime" rev="1.0.12"
- conf="build,ide,test -> default">
+ <!-- Keep the version number in sync with build.xml -->
+ <dependency org="org.atmosphere" name="atmosphere-runtime"
+ rev="1.0.13" conf="build,ide,test -> default">
</dependency>
</dependencies>
diff --git a/push/src/org/atmosphere/cpr/AtmosphereFramework.java b/push/src/org/atmosphere/cpr/AtmosphereFramework.java
deleted file mode 100644
index 62f867fc94..0000000000
--- a/push/src/org/atmosphere/cpr/AtmosphereFramework.java
+++ /dev/null
@@ -1,1779 +0,0 @@
-/*
- * Copyright 2013 Jeanfrancois Arcand
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.atmosphere.cpr;
-
-import org.atmosphere.cache.UUIDBroadcasterCache;
-import org.atmosphere.config.ApplicationConfiguration;
-import org.atmosphere.config.AtmosphereHandlerConfig;
-import org.atmosphere.config.AtmosphereHandlerProperty;
-import org.atmosphere.config.FrameworkConfiguration;
-import org.atmosphere.container.BlockingIOCometSupport;
-import org.atmosphere.container.Tomcat7BIOSupportWithWebSocket;
-import org.atmosphere.di.InjectorProvider;
-import org.atmosphere.di.ServletContextHolder;
-import org.atmosphere.di.ServletContextProvider;
-import org.atmosphere.handler.AbstractReflectorAtmosphereHandler;
-import org.atmosphere.handler.ReflectorServletProcessor;
-import org.atmosphere.interceptor.AndroidAtmosphereInterceptor;
-import org.atmosphere.interceptor.JSONPAtmosphereInterceptor;
-import org.atmosphere.interceptor.JavaScriptProtocol;
-import org.atmosphere.interceptor.OnDisconnectInterceptor;
-import org.atmosphere.interceptor.SSEAtmosphereInterceptor;
-import org.atmosphere.util.AtmosphereConfigReader;
-import org.atmosphere.util.IntrospectionUtils;
-import org.atmosphere.util.Version;
-import org.atmosphere.websocket.DefaultWebSocketProcessor;
-import org.atmosphere.websocket.WebSocket;
-import org.atmosphere.websocket.WebSocketProtocol;
-import org.atmosphere.websocket.protocol.SimpleHttpProtocol;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.Servlet;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import static org.atmosphere.cpr.ApplicationConfig.ALLOW_QUERYSTRING_AS_REQUEST;
-import static org.atmosphere.cpr.ApplicationConfig.ATMOSPHERE_HANDLER;
-import static org.atmosphere.cpr.ApplicationConfig.ATMOSPHERE_HANDLER_MAPPING;
-import static org.atmosphere.cpr.ApplicationConfig.ATMOSPHERE_HANDLER_PATH;
-import static org.atmosphere.cpr.ApplicationConfig.BROADCASTER_CACHE;
-import static org.atmosphere.cpr.ApplicationConfig.BROADCASTER_CLASS;
-import static org.atmosphere.cpr.ApplicationConfig.BROADCASTER_FACTORY;
-import static org.atmosphere.cpr.ApplicationConfig.BROADCASTER_LIFECYCLE_POLICY;
-import static org.atmosphere.cpr.ApplicationConfig.BROADCAST_FILTER_CLASSES;
-import static org.atmosphere.cpr.ApplicationConfig.DISABLE_ONSTATE_EVENT;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_ATMOSPHERE_XML;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_BLOCKING_COMETSUPPORT;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_COMET_SUPPORT;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_NATIVE_COMETSUPPORT;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_SERVLET_MAPPING;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_SESSION_SUPPORT;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_USE_STREAM;
-import static org.atmosphere.cpr.ApplicationConfig.RESUME_AND_KEEPALIVE;
-import static org.atmosphere.cpr.ApplicationConfig.SUSPENDED_ATMOSPHERE_RESOURCE_UUID;
-import static org.atmosphere.cpr.ApplicationConfig.WEBSOCKET_PROCESSOR;
-import static org.atmosphere.cpr.ApplicationConfig.WEBSOCKET_PROTOCOL;
-import static org.atmosphere.cpr.ApplicationConfig.WEBSOCKET_SUPPORT;
-import static org.atmosphere.cpr.FrameworkConfig.ATMOSPHERE_CONFIG;
-import static org.atmosphere.cpr.FrameworkConfig.HAZELCAST_BROADCASTER;
-import static org.atmosphere.cpr.FrameworkConfig.JERSEY_BROADCASTER;
-import static org.atmosphere.cpr.FrameworkConfig.JERSEY_CONTAINER;
-import static org.atmosphere.cpr.FrameworkConfig.JGROUPS_BROADCASTER;
-import static org.atmosphere.cpr.FrameworkConfig.JMS_BROADCASTER;
-import static org.atmosphere.cpr.FrameworkConfig.REDIS_BROADCASTER;
-import static org.atmosphere.cpr.FrameworkConfig.WRITE_HEADERS;
-import static org.atmosphere.cpr.FrameworkConfig.XMPP_BROADCASTER;
-import static org.atmosphere.cpr.HeaderConfig.ATMOSPHERE_POST_BODY;
-import static org.atmosphere.cpr.HeaderConfig.X_ATMOSPHERE_TRACKING_ID;
-import static org.atmosphere.websocket.WebSocket.WEBSOCKET_SUSPEND;
-
-/**
- * The {@link AtmosphereFramework} is the entry point for the framework. This class can be used to from Servlet/filter
- * to dispatch {@link AtmosphereRequest} and {@link AtmosphereResponse}. The framework can also be configured using
- * the setXXX method. The life cycle of this class is
- * <blockquote><pre>
- * AtmosphereFramework f = new AtmosphereFramework();
- * f.init();
- * f.doCometSupport(AtmosphereRequest, AtmosphereResource);
- * f.destroy();
- * </pre></blockquote>
- *
- * @author Jeanfrancois Arcand
- */
-public class AtmosphereFramework implements ServletContextProvider {
- public static final String DEFAULT_ATMOSPHERE_CONFIG_PATH = "/META-INF/atmosphere.xml";
- public static final String DEFAULT_LIB_PATH = "/WEB-INF/lib/";
- public static final String MAPPING_REGEX = "[a-zA-Z0-9-&.*=@~;\\?]+";
-
- protected static final Logger logger = LoggerFactory.getLogger(AtmosphereFramework.class);
-
- protected final List<String> broadcasterFilters = new ArrayList<String>();
- protected final List<AsyncSupportListener> asyncSupportListeners = new ArrayList<AsyncSupportListener>();
- protected final ArrayList<String> possibleComponentsCandidate = new ArrayList<String>();
- protected final HashMap<String, String> initParams = new HashMap<String, String>();
- protected final AtmosphereConfig config;
- protected final AtomicBoolean isCometSupportConfigured = new AtomicBoolean(false);
- protected final boolean isFilter;
- protected final Map<String, AtmosphereHandlerWrapper> atmosphereHandlers = new ConcurrentHashMap<String, AtmosphereHandlerWrapper>();
- protected final ConcurrentLinkedQueue<String> broadcasterTypes = new ConcurrentLinkedQueue<String>();
-
- protected boolean useNativeImplementation = false;
- protected boolean useBlockingImplementation = false;
- protected boolean useStreamForFlushingComments = false;
- protected AsyncSupport asyncSupport;
- protected String broadcasterClassName = DefaultBroadcaster.class.getName();
- protected boolean isCometSupportSpecified = false;
- protected boolean isBroadcasterSpecified = false;
- protected boolean isSessionSupportSpecified = false;
- protected BroadcasterFactory broadcasterFactory;
- protected String broadcasterFactoryClassName;
- protected String broadcasterCacheClassName;
- protected boolean webSocketEnabled = true;
- protected String broadcasterLifeCyclePolicy = "NEVER";
- protected String webSocketProtocolClassName = SimpleHttpProtocol.class.getName();
- protected WebSocketProtocol webSocketProtocol;
- protected String handlersPath = "/WEB-INF/classes/";
- protected ServletConfig servletConfig;
- protected boolean autoDetectHandlers = true;
- private boolean hasNewWebSocketProtocol = false;
- protected String atmosphereDotXmlPath = DEFAULT_ATMOSPHERE_CONFIG_PATH;
- protected final LinkedList<AtmosphereInterceptor> interceptors = new LinkedList<AtmosphereInterceptor>();
- protected boolean scanDone = false;
- protected String annotationProcessorClassName = "org.atmosphere.cpr.DefaultAnnotationProcessor";
- protected final List<BroadcasterListener> broadcasterListeners = new ArrayList<BroadcasterListener>();
- protected String webSocketProcessorClassName = DefaultWebSocketProcessor.class.getName();
- protected String libPath = DEFAULT_LIB_PATH;
- protected boolean isInit;
- protected boolean sharedThreadPools = true;
-
- public static final class AtmosphereHandlerWrapper {
-
- public final AtmosphereHandler atmosphereHandler;
- public Broadcaster broadcaster;
- public String mapping;
- public List<AtmosphereInterceptor> interceptors = Collections.<AtmosphereInterceptor>emptyList();
-
- public AtmosphereHandlerWrapper(BroadcasterFactory broadcasterFactory, AtmosphereHandler atmosphereHandler, String mapping) {
- this.atmosphereHandler = atmosphereHandler;
- try {
- if (broadcasterFactory != null) {
- this.broadcaster = broadcasterFactory.lookup(mapping, true);
- } else {
- this.mapping = mapping;
- }
- } catch (Exception t) {
- throw new RuntimeException(t);
- }
- }
-
- public AtmosphereHandlerWrapper(AtmosphereHandler atmosphereHandler, Broadcaster broadcaster) {
- this.atmosphereHandler = atmosphereHandler;
- this.broadcaster = broadcaster;
- }
-
- @Override
- public String toString() {
- return "AtmosphereHandlerWrapper{ atmosphereHandler=" + atmosphereHandler + ", broadcaster=" +
- broadcaster + " }";
- }
- }
-
- /**
- * Create an AtmosphereFramework.
- */
- public AtmosphereFramework() {
- this(false, true);
- }
-
- /**
- * Create an AtmosphereFramework and initialize it via {@link AtmosphereFramework#init(javax.servlet.ServletConfig)}
- */
- public AtmosphereFramework(ServletConfig sc) throws ServletException {
- this(false, true);
- init(sc);
- }
-
- /**
- * Create an AtmosphereFramework.
- *
- * @param isFilter true if this instance is used as an {@link AtmosphereFilter}
- */
- public AtmosphereFramework(boolean isFilter, boolean autoDetectHandlers) {
- this.isFilter = isFilter;
- this.autoDetectHandlers = autoDetectHandlers;
- readSystemProperties();
- populateBroadcasterType();
- config = new AtmosphereConfig(this);
- }
-
- /**
- * The order of addition is quite important here.
- */
- private void populateBroadcasterType() {
- broadcasterTypes.add(HAZELCAST_BROADCASTER);
- broadcasterTypes.add(XMPP_BROADCASTER);
- broadcasterTypes.add(REDIS_BROADCASTER);
- broadcasterTypes.add(JGROUPS_BROADCASTER);
- broadcasterTypes.add(JMS_BROADCASTER);
- }
-
- /**
- * Add an {@link AtmosphereHandler} serviced by the {@link Servlet}
- * This API is exposed to allow embedding an Atmosphere application.
- *
- * @param mapping The servlet mapping (servlet path)
- * @param h implementation of an {@link AtmosphereHandler}
- * @param l An attay of {@link AtmosphereInterceptor}
- */
- public AtmosphereFramework addAtmosphereHandler(String mapping, AtmosphereHandler h, List<AtmosphereInterceptor> l) {
- if (!mapping.startsWith("/")) {
- mapping = "/" + mapping;
- }
-
- AtmosphereHandlerWrapper w = new AtmosphereHandlerWrapper(broadcasterFactory, h, mapping);
- w.interceptors = l;
- addMapping(mapping, w);
-
- logger.info("Installed AtmosphereHandler {} mapped to context-path: {}", h.getClass().getName(), mapping);
- if (l.size() > 0) {
- logger.info("Installed AtmosphereInterceptor {} mapped to AtmosphereHandler {}", l, h.getClass().getName());
- }
- return this;
- }
-
- /**
- * Add an {@link AtmosphereHandler} serviced by the {@link Servlet}
- * This API is exposed to allow embedding an Atmosphere application.
- *
- * @param mapping The servlet mapping (servlet path)
- * @param h implementation of an {@link AtmosphereHandler}
- */
- public AtmosphereFramework addAtmosphereHandler(String mapping, AtmosphereHandler h) {
- addAtmosphereHandler(mapping, h, Collections.<AtmosphereInterceptor>emptyList());
- return this;
- }
-
- private AtmosphereFramework addMapping(String path, AtmosphereHandlerWrapper w) {
- // We are using JAXRS mapping algorithm.
- if (path.contains("*")) {
- path = path.replace("*", MAPPING_REGEX);
- }
-
- if (path.endsWith("/")) {
- path = path + MAPPING_REGEX;
- }
-
- InjectorProvider.getInjector().inject(w.atmosphereHandler);
- atmosphereHandlers.put(path, w);
- return this;
- }
-
- /**
- * Add an {@link AtmosphereHandler} serviced by the {@link Servlet}
- * This API is exposed to allow embedding an Atmosphere application.
- *
- * @param mapping The servlet mapping (servlet path)
- * @param h implementation of an {@link AtmosphereHandler}
- * @param broadcasterId The {@link Broadcaster#getID} value.
- * @param l An attay of {@link AtmosphereInterceptor}
- */
- public AtmosphereFramework addAtmosphereHandler(String mapping, AtmosphereHandler h, String broadcasterId, List<AtmosphereInterceptor> l) {
- if (!mapping.startsWith("/")) {
- mapping = "/" + mapping;
- }
-
- AtmosphereHandlerWrapper w = new AtmosphereHandlerWrapper(broadcasterFactory, h, mapping);
- w.broadcaster.setID(broadcasterId);
- w.interceptors = l;
- addMapping(mapping, w);
- logger.info("Installed AtmosphereHandler {} mapped to context-path: {}", h.getClass().getName(), mapping);
- if (l.size() > 0) {
- logger.info("Installed AtmosphereInterceptor {} mapped to AtmosphereHandler {}", l, h.getClass().getName());
- }
- return this;
- }
-
- /**
- * Add an {@link AtmosphereHandler} serviced by the {@link Servlet}
- * This API is exposed to allow embedding an Atmosphere application.
- *
- * @param mapping The servlet mapping (servlet path)
- * @param h implementation of an {@link AtmosphereHandler}
- * @param broadcasterId The {@link Broadcaster#getID} value.
- */
- public AtmosphereFramework addAtmosphereHandler(String mapping, AtmosphereHandler h, String broadcasterId) {
- addAtmosphereHandler(mapping, h, broadcasterId, Collections.<AtmosphereInterceptor>emptyList());
- return this;
- }
-
- /**
- * Add an {@link AtmosphereHandler} serviced by the {@link Servlet}
- * This API is exposed to allow embedding an Atmosphere application.
- *
- * @param mapping The servlet mapping (servlet path)
- * @param h implementation of an {@link AtmosphereHandler}
- * @param broadcaster The {@link Broadcaster} associated with AtmosphereHandler.
- * @param l An attay of {@link AtmosphereInterceptor}
- */
- public AtmosphereFramework addAtmosphereHandler(String mapping, AtmosphereHandler h, Broadcaster broadcaster, List<AtmosphereInterceptor> l) {
- if (!mapping.startsWith("/")) {
- mapping = "/" + mapping;
- }
-
- AtmosphereHandlerWrapper w = new AtmosphereHandlerWrapper(h, broadcaster);
- w.interceptors = l;
-
- addMapping(mapping, w);
- logger.info("Installed AtmosphereHandler {} mapped to context-path: {}", h.getClass().getName(), mapping);
- if (l.size() > 0) {
- logger.info("Installed AtmosphereInterceptor {} mapped to AtmosphereHandler {}", l, h.getClass().getName());
- }
- return this;
- }
-
- /**
- * Add an {@link AtmosphereHandler} serviced by the {@link Servlet}
- * This API is exposed to allow embedding an Atmosphere application.
- *
- * @param mapping The servlet mapping (servlet path)
- * @param h implementation of an {@link AtmosphereHandler}
- * @param broadcaster The {@link Broadcaster} associated with AtmosphereHandler.
- */
- public AtmosphereFramework addAtmosphereHandler(String mapping, AtmosphereHandler h, Broadcaster broadcaster) {
- addAtmosphereHandler(mapping, h, broadcaster, Collections.<AtmosphereInterceptor>emptyList());
- return this;
- }
-
- /**
- * Remove an {@link AtmosphereHandler}
- *
- * @param mapping the mapping used when invoking {@link #addAtmosphereHandler(String, AtmosphereHandler)};
- * @return true if removed
- */
- public AtmosphereFramework removeAtmosphereHandler(String mapping) {
-
- if (mapping.endsWith("/")) {
- mapping += MAPPING_REGEX;
- }
-
- atmosphereHandlers.remove(mapping);
- return this;
- }
-
- /**
- * Remove all {@link AtmosphereHandler}
- */
- public AtmosphereFramework removeAllAtmosphereHandler() {
- atmosphereHandlers.clear();
- return this;
- }
-
- /**
- * Remove all init parameters.
- */
- public AtmosphereFramework removeAllInitParams() {
- initParams.clear();
- return this;
- }
-
- /**
- * Add init-param like if they were defined in web.xml
- *
- * @param name The name
- * @param value The value
- */
- public AtmosphereFramework addInitParameter(String name, String value) {
- initParams.put(name, value);
- return this;
- }
-
- protected void readSystemProperties() {
- if (System.getProperty(PROPERTY_NATIVE_COMETSUPPORT) != null) {
- useNativeImplementation = Boolean
- .parseBoolean(System.getProperty(PROPERTY_NATIVE_COMETSUPPORT));
- isCometSupportSpecified = true;
- }
-
- if (System.getProperty(PROPERTY_BLOCKING_COMETSUPPORT) != null) {
- useBlockingImplementation = Boolean
- .parseBoolean(System.getProperty(PROPERTY_BLOCKING_COMETSUPPORT));
- isCometSupportSpecified = true;
- }
- atmosphereDotXmlPath = System.getProperty(PROPERTY_ATMOSPHERE_XML, atmosphereDotXmlPath);
-
- if (System.getProperty(DISABLE_ONSTATE_EVENT) != null) {
- initParams.put(DISABLE_ONSTATE_EVENT, System.getProperty(DISABLE_ONSTATE_EVENT));
- }
- }
-
- /**
- * Path specific container using their own property.
- */
- public void patchContainer() {
- System.setProperty("org.apache.catalina.STRICT_SERVLET_COMPLIANCE", "false");
- }
-
- /**
- * Initialize the AtmosphereFramework. Invoke that method after having properly configured this class using the setter.
- */
- public AtmosphereFramework init() {
- try {
- init(new ServletConfig() {
-
- @Override
- public String getServletName() {
- return "AtmosphereFramework";
- }
-
- @Override
- public ServletContext getServletContext() {
- return (ServletContext) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{ServletContext.class},
- new InvocationHandler() {
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- logger.trace("Method {} not supported", method.getName());
- return null;
- }
- });
- }
-
- @Override
- public String getInitParameter(String name) {
- return initParams.get(name);
- }
-
- @Override
- public Enumeration<String> getInitParameterNames() {
- return Collections.enumeration(initParams.values());
- }
- });
- } catch (ServletException e) {
- logger.error("", e);
- }
- return this;
- }
-
- /**
- * Initialize the AtmosphereFramework using the {@link ServletContext}
- *
- * @param sc the {@link ServletContext}
- */
- public AtmosphereFramework init(final ServletConfig sc) throws ServletException {
-
- if (isInit) return this;
-
- try {
- ServletContextHolder.register(this);
-
- ServletConfig scFacade = new ServletConfig() {
-
- public String getServletName() {
- return sc.getServletName();
- }
-
- public ServletContext getServletContext() {
- return sc.getServletContext();
- }
-
- public String getInitParameter(String name) {
- String param = initParams.get(name);
- if (param == null) {
- return sc.getInitParameter(name);
- }
- return param;
- }
-
- public Enumeration<String> getInitParameterNames() {
- Enumeration en = sc.getInitParameterNames();
- while (en.hasMoreElements()) {
- String name = (String) en.nextElement();
- if (!initParams.containsKey(name)) {
- initParams.put(name, sc.getInitParameter(name));
- }
- }
- return Collections.enumeration(initParams.keySet());
- }
- };
- this.servletConfig = scFacade;
- asyncSupportListener(new AsyncSupportListenerAdapter());
-
- autoConfigureService(scFacade.getServletContext());
- patchContainer();
- doInitParams(scFacade);
- doInitParamsForWebSocket(scFacade);
- configureBroadcaster();
- loadConfiguration(scFacade);
- initWebSocket();
-
- autoDetectContainer();
- configureWebDotXmlAtmosphereHandler(sc);
- asyncSupport.init(scFacade);
- initAtmosphereHandler(scFacade);
- configureAtmosphereInterceptor(sc);
-
- if (broadcasterCacheClassName == null) {
- logger.warn("No BroadcasterCache configured. Broadcasted message between client reconnection will be LOST. " +
- "It is recommended to configure the {}", UUIDBroadcasterCache.class.getName());
- } else {
- logger.info("Using BroadcasterCache: {}", broadcasterCacheClassName);
- }
-
- // http://java.net/jira/browse/ATMOSPHERE-157
- if (sc.getServletContext() != null) {
- sc.getServletContext().setAttribute(BroadcasterFactory.class.getName(), broadcasterFactory);
- }
-
- for (String i : broadcasterFilters) {
- logger.info("Using BroadcastFilter: {}", i);
- }
-
- String s = config.getInitParameter(ApplicationConfig.BROADCASTER_SHARABLE_THREAD_POOLS);
- if (s != null) {
- sharedThreadPools = Boolean.parseBoolean(s);
- }
-
- logger.info("Shared ExecutorService supported: {}", sharedThreadPools);
- logger.info("HttpSession supported: {}", config.isSupportSession());
- logger.info("Using BroadcasterFactory: {}", broadcasterFactory.getClass().getName());
- logger.info("Using WebSocketProcessor: {}", webSocketProcessorClassName);
- logger.info("Using Broadcaster: {}", broadcasterClassName);
- logger.info("Atmosphere Framework {} started.", Version.getRawVersion());
-
- String showSupportMessage = config.getInitParameter("org.atmosphere.cpr.showSupportMessage");
- if (showSupportMessage == null || Boolean.parseBoolean(showSupportMessage)) {
- logger.info("\n\n\tFor Commercial Support, visit \n\t{} " +
- "or send an email to {}\n", "http://www.async-io.org/", "support@async-io.org");
- }
- } catch (Throwable t) {
- logger.error("Failed to initialize Atmosphere Framework", t);
-
- if (t instanceof ServletException) {
- throw (ServletException) t;
- }
-
- throw new ServletException(t);
- }
- isInit = true;
- return this;
- }
-
- /**
- * Configure the list of {@link AtmosphereInterceptor}.
- *
- * @param sc a ServletConfig
- */
- protected void configureAtmosphereInterceptor(ServletConfig sc) {
- String s = sc.getInitParameter(ApplicationConfig.ATMOSPHERE_INTERCEPTORS);
- if (s != null) {
- String[] list = s.split(",");
- for (String a : list) {
- try {
- AtmosphereInterceptor ai = (AtmosphereInterceptor) Thread.currentThread().getContextClassLoader()
- .loadClass(a.trim()).newInstance();
- ai.configure(config);
- interceptor(ai);
- } catch (InstantiationException e) {
- logger.warn("", e);
- } catch (IllegalAccessException e) {
- logger.warn("", e);
- } catch (ClassNotFoundException e) {
- logger.warn("", e);
- }
- }
- }
-
- s = sc.getInitParameter(ApplicationConfig.DISABLE_ATMOSPHEREINTERCEPTOR);
- if (s == null) {
- // OnDisconnect
- interceptors.addFirst(newAInterceptor(OnDisconnectInterceptor.class));
- // ADD Tracking ID Handshake
- interceptors.addFirst(newAInterceptor(JavaScriptProtocol.class));
- // ADD JSONP support
- interceptors.addFirst(newAInterceptor(JSONPAtmosphereInterceptor.class));
- // Add SSE support
- interceptors.addFirst(newAInterceptor(SSEAtmosphereInterceptor.class));
- // Android 2.3.x streaming support
- interceptors.addFirst(newAInterceptor(AndroidAtmosphereInterceptor.class));
- logger.info("Installed Default AtmosphereInterceptor {}. " +
- "Set org.atmosphere.cpr.AtmosphereInterceptor.disableDefaults in your xml to disable them.", interceptors);
- }
- }
-
- protected AtmosphereInterceptor newAInterceptor(Class<? extends AtmosphereInterceptor> a) {
- AtmosphereInterceptor ai = null;
- try {
- ai = (AtmosphereInterceptor) getClass().getClassLoader().loadClass(a.getName()).newInstance();
- ai.configure(config);
- } catch (Exception ex) {
- logger.warn("", ex);
- }
- return ai;
- }
-
- protected void configureWebDotXmlAtmosphereHandler(ServletConfig sc) {
- String s = sc.getInitParameter(ATMOSPHERE_HANDLER);
- if (s != null) {
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- try {
-
- String mapping = sc.getInitParameter(ATMOSPHERE_HANDLER_MAPPING);
- if (mapping == null) {
- mapping = "/*";
- }
- addAtmosphereHandler(mapping, (AtmosphereHandler) cl.loadClass(s).newInstance());
- } catch (Exception ex) {
- logger.warn("Unable to load WebSocketHandle instance", ex);
- }
- }
- }
-
- protected void configureBroadcaster() {
-
- try {
- // Check auto supported one
- if (isBroadcasterSpecified == false) {
- broadcasterClassName = lookupDefaultBroadcasterType(broadcasterClassName);
- }
-
- Class<? extends Broadcaster> bc =
- (Class<? extends Broadcaster>) Thread.currentThread().getContextClassLoader()
- .loadClass(broadcasterClassName);
- if (broadcasterFactoryClassName != null) {
- broadcasterFactory = (BroadcasterFactory) Thread.currentThread().getContextClassLoader()
- .loadClass(broadcasterFactoryClassName).newInstance();
- }
-
- if (broadcasterFactory == null) {
- broadcasterFactory = new DefaultBroadcasterFactory(bc, broadcasterLifeCyclePolicy, config);
- }
-
- for (BroadcasterListener b : broadcasterListeners) {
- broadcasterFactory.addBroadcasterListener(b);
- }
-
- BroadcasterFactory.setBroadcasterFactory(broadcasterFactory, config);
- InjectorProvider.getInjector().inject(broadcasterFactory);
-
- Iterator<Entry<String, AtmosphereHandlerWrapper>> i = atmosphereHandlers.entrySet().iterator();
- AtmosphereHandlerWrapper w;
- Entry<String, AtmosphereHandlerWrapper> e;
- while (i.hasNext()) {
- e = i.next();
- w = e.getValue();
-
- if (w.broadcaster == null) {
- w.broadcaster = broadcasterFactory.get(w.mapping);
- } else {
- if (broadcasterCacheClassName != null) {
- BroadcasterCache cache = (BroadcasterCache) Thread.currentThread().getContextClassLoader()
- .loadClass(broadcasterCacheClassName).newInstance();
- InjectorProvider.getInjector().inject(cache);
- w.broadcaster.getBroadcasterConfig().setBroadcasterCache(cache);
- }
- }
- }
- } catch (Exception ex) {
- logger.error("Unable to configure Broadcaster/Factory/Cache", ex);
- }
- }
-
- protected void doInitParamsForWebSocket(ServletConfig sc) {
- String s = sc.getInitParameter(WEBSOCKET_SUPPORT);
- if (s != null) {
- webSocketEnabled = Boolean.parseBoolean(s);
- sessionSupport(false);
- }
- s = sc.getInitParameter(WEBSOCKET_PROTOCOL);
- if (s != null) {
- webSocketProtocolClassName = s;
- }
-
- s = sc.getInitParameter(WEBSOCKET_PROCESSOR);
- if (s != null) {
- webSocketProcessorClassName = s;
- }
- }
-
- /**
- * Read init param from web.xml and apply them.
- *
- * @param sc {@link ServletConfig}
- */
- protected void doInitParams(ServletConfig sc) {
- String s = sc.getInitParameter(PROPERTY_NATIVE_COMETSUPPORT);
- if (s != null) {
- useNativeImplementation = Boolean.parseBoolean(s);
- if (useNativeImplementation) isCometSupportSpecified = true;
- }
- s = sc.getInitParameter(PROPERTY_BLOCKING_COMETSUPPORT);
- if (s != null) {
- useBlockingImplementation = Boolean.parseBoolean(s);
- if (useBlockingImplementation) isCometSupportSpecified = true;
- }
- s = sc.getInitParameter(PROPERTY_USE_STREAM);
- if (s != null) {
- useStreamForFlushingComments = Boolean.parseBoolean(s);
- }
- s = sc.getInitParameter(PROPERTY_COMET_SUPPORT);
- if (s != null) {
- asyncSupport = new DefaultAsyncSupportResolver(config).newCometSupport(s);
- isCometSupportSpecified = true;
- }
- s = sc.getInitParameter(BROADCASTER_CLASS);
- if (s != null) {
- broadcasterClassName = s;
- isBroadcasterSpecified = true;
- }
- s = sc.getInitParameter(BROADCASTER_CACHE);
- if (s != null) {
- broadcasterCacheClassName = s;
- }
- s = sc.getInitParameter(PROPERTY_SESSION_SUPPORT);
- if (s != null) {
- config.setSupportSession(Boolean.valueOf(s));
- isSessionSupportSpecified = true;
- }
- s = sc.getInitParameter(DISABLE_ONSTATE_EVENT);
- if (s != null) {
- initParams.put(DISABLE_ONSTATE_EVENT, s);
- } else {
- initParams.put(DISABLE_ONSTATE_EVENT, "false");
- }
- s = sc.getInitParameter(RESUME_AND_KEEPALIVE);
- if (s != null) {
- initParams.put(RESUME_AND_KEEPALIVE, s);
- }
- s = sc.getInitParameter(BROADCAST_FILTER_CLASSES);
- if (s != null) {
- broadcasterFilters.addAll(Arrays.asList(s.split(",")));
- logger.info("Installing BroadcastFilter class(es) {}", s);
- }
- s = sc.getInitParameter(BROADCASTER_LIFECYCLE_POLICY);
- if (s != null) {
- broadcasterLifeCyclePolicy = s;
- }
- s = sc.getInitParameter(BROADCASTER_FACTORY);
- if (s != null) {
- broadcasterFactoryClassName = s;
- }
- s = sc.getInitParameter(ATMOSPHERE_HANDLER_PATH);
- if (s != null) {
- handlersPath = s;
- }
- s = sc.getInitParameter(PROPERTY_ATMOSPHERE_XML);
- if (s != null) {
- atmosphereDotXmlPath = s;
- }
- }
-
- public void loadConfiguration(ServletConfig sc) throws ServletException {
-
- if (!autoDetectHandlers) return;
-
- try {
- URL url = sc.getServletContext().getResource(handlersPath);
- URLClassLoader urlC = new URLClassLoader(new URL[]{url},
- Thread.currentThread().getContextClassLoader());
- loadAtmosphereDotXml(sc.getServletContext().
- getResourceAsStream(atmosphereDotXmlPath), urlC);
-
- if (atmosphereHandlers.size() == 0) {
- autoDetectAtmosphereHandlers(sc.getServletContext(), urlC);
-
- if (atmosphereHandlers.size() == 0) {
- detectSupportedFramework(sc);
- }
- }
-
- autoDetectWebSocketHandler(sc.getServletContext(), urlC);
- } catch (Throwable t) {
- throw new ServletException(t);
- }
- }
-
- /**
- * Auto-detect Jersey when no atmosphere.xml file are specified.
- *
- * @param sc {@link ServletConfig}
- * @return true if Jersey classes are detected
- * @throws ClassNotFoundException
- */
- protected boolean detectSupportedFramework(ServletConfig sc) throws ClassNotFoundException, IllegalAccessException,
- InstantiationException, NoSuchMethodException, InvocationTargetException {
-
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- String broadcasterClassNameTmp = null;
-
- try {
- cl.loadClass(JERSEY_CONTAINER);
-
- if (!isBroadcasterSpecified) {
- broadcasterClassNameTmp = lookupDefaultBroadcasterType(JERSEY_BROADCASTER);
-
- cl.loadClass(broadcasterClassNameTmp);
- }
- useStreamForFlushingComments = true;
- } catch (Throwable t) {
- logger.trace("", t);
- return false;
- }
-
- logger.warn("Missing META-INF/atmosphere.xml but found the Jersey runtime. Starting Jersey");
-
- // Jersey will handle itself the headers.
- initParams.put(WRITE_HEADERS, "false");
-
- ReflectorServletProcessor rsp = new ReflectorServletProcessor();
- if (broadcasterClassNameTmp != null) broadcasterClassName = broadcasterClassNameTmp;
- rsp.setServletClassName(JERSEY_CONTAINER);
- sessionSupport(false);
- initParams.put(DISABLE_ONSTATE_EVENT, "true");
-
- String mapping = sc.getInitParameter(PROPERTY_SERVLET_MAPPING);
- if (mapping == null) {
- mapping = "/*";
- }
- Class<? extends Broadcaster> bc = (Class<? extends Broadcaster>) cl.loadClass(broadcasterClassName);
-
-
- if (broadcasterFactory != null) {
- broadcasterFactory.destroy();
- }
- broadcasterFactory = new DefaultBroadcasterFactory(bc, broadcasterLifeCyclePolicy, config);
- BroadcasterFactory.setBroadcasterFactory(broadcasterFactory, config);
-
- for (BroadcasterListener b : broadcasterListeners) {
- broadcasterFactory.addBroadcasterListener(b);
- }
-
- Broadcaster b;
-
- try {
- b = broadcasterFactory.get(bc, mapping);
- } catch (IllegalStateException ex) {
- logger.warn("Two Broadcaster's named {}. Renaming the second one to {}", mapping, sc.getServletName() + mapping);
- b = broadcasterFactory.get(bc, sc.getServletName() + mapping);
- }
-
- addAtmosphereHandler(mapping, rsp, b);
- return true;
- }
-
- protected String lookupDefaultBroadcasterType(String defaultB) {
- for (String b : broadcasterTypes) {
- try {
- Class.forName(b);
- return b;
- } catch (ClassNotFoundException e) {
- }
- }
- return defaultB;
- }
-
- protected void sessionSupport(boolean sessionSupport) {
- if (!isSessionSupportSpecified) {
- config.setSupportSession(sessionSupport);
- } else if (!config.isSupportSession()) {
- // Don't turn off session support. Once it's on, leave it on.
- config.setSupportSession(sessionSupport);
- }
- }
-
- /**
- * Initialize {@link AtmosphereServletProcessor}
- *
- * @param sc the {@link ServletConfig}
- * @throws javax.servlet.ServletException
- */
- public void initAtmosphereHandler(ServletConfig sc) throws ServletException {
- AtmosphereHandler a;
- AtmosphereHandlerWrapper w;
- for (Entry<String, AtmosphereHandlerWrapper> h : atmosphereHandlers.entrySet()) {
- w = h.getValue();
- a = w.atmosphereHandler;
- if (a instanceof AtmosphereServletProcessor) {
- ((AtmosphereServletProcessor) a).init(sc);
- }
- }
-
- if (atmosphereHandlers.size() == 0 && !SimpleHttpProtocol.class.isAssignableFrom(webSocketProtocol.getClass())) {
- logger.debug("Adding a void AtmosphereHandler mapped to /* to allow WebSocket application only");
- addAtmosphereHandler("/*", new AbstractReflectorAtmosphereHandler() {
- @Override
- public void onRequest(AtmosphereResource r) throws IOException {
- logger.debug("No AtmosphereHandler defined.");
- }
-
- @Override
- public void destroy() {
- }
- });
- }
- }
-
- protected void initWebSocket() {
- if (webSocketProtocol == null) {
- try {
- webSocketProtocol = (WebSocketProtocol) Thread.currentThread().getContextClassLoader()
- .loadClass(webSocketProtocolClassName).newInstance();
- logger.info("Installed WebSocketProtocol {} ", webSocketProtocolClassName);
- } catch (Exception ex) {
- try {
- webSocketProtocol = (WebSocketProtocol) AtmosphereFramework.class.getClassLoader()
- .loadClass(webSocketProtocolClassName).newInstance();
- logger.info("Installed WebSocketProtocol {} ", webSocketProtocolClassName);
- } catch (Exception ex2) {
- logger.error("Cannot load the WebSocketProtocol {}", getWebSocketProtocolClassName(), ex);
- webSocketProtocol = new SimpleHttpProtocol();
- }
- }
- }
- webSocketProtocol.configure(config);
- }
-
- public AtmosphereFramework destroy() {
- if (asyncSupport != null && AsynchronousProcessor.class.isAssignableFrom(asyncSupport.getClass())) {
- ((AsynchronousProcessor) asyncSupport).shutdown();
- }
-
- // We just need one bc to shutdown the shared thread pool
- for (Entry<String, AtmosphereHandlerWrapper> entry : atmosphereHandlers.entrySet()) {
- AtmosphereHandlerWrapper handlerWrapper = entry.getValue();
- handlerWrapper.atmosphereHandler.destroy();
- }
-
- BroadcasterFactory factory = broadcasterFactory;
- if (factory != null) {
- factory.destroy();
- BroadcasterFactory.factory = null;
- }
- WebSocketProcessorFactory.getDefault().destroy();
- return this;
- }
-
- /**
- * Load AtmosphereHandler defined under META-INF/atmosphere.xml
- *
- * @param stream The input stream we read from.
- * @param c The classloader
- */
- protected void loadAtmosphereDotXml(InputStream stream, URLClassLoader c)
- throws IOException, ServletException {
-
- if (stream == null) {
- return;
- }
-
- AtmosphereConfigReader.getInstance().parse(config, stream);
- for (AtmosphereHandlerConfig atmoHandler : config.getAtmosphereHandlerConfig()) {
- try {
- AtmosphereHandler handler;
-
- if (!ReflectorServletProcessor.class.getName().equals(atmoHandler.getClassName())) {
- handler = (AtmosphereHandler) c.loadClass(atmoHandler.getClassName()).newInstance();
- } else {
- handler = new ReflectorServletProcessor();
- }
-
- logger.info("Installed AtmosphereHandler {} mapped to context-path: {}", handler, atmoHandler.getContextRoot());
-
- for (ApplicationConfiguration a : atmoHandler.getApplicationConfig()) {
- initParams.put(a.getParamName(), a.getParamValue());
- }
-
- for (FrameworkConfiguration a : atmoHandler.getFrameworkConfig()) {
- initParams.put(a.getParamName(), a.getParamValue());
- }
-
- for (AtmosphereHandlerProperty handlerProperty : atmoHandler.getProperties()) {
-
- if (handlerProperty.getValue() != null && handlerProperty.getValue().indexOf("jersey") != -1) {
- initParams.put(DISABLE_ONSTATE_EVENT, "true");
- useStreamForFlushingComments = true;
- broadcasterClassName = lookupDefaultBroadcasterType(JERSEY_BROADCASTER);
- broadcasterFactory = null;
- configureBroadcaster();
- }
-
- IntrospectionUtils.setProperty(handler, handlerProperty.getName(), handlerProperty.getValue());
- IntrospectionUtils.addProperty(handler, handlerProperty.getName(), handlerProperty.getValue());
- }
-
- sessionSupport(Boolean.valueOf(atmoHandler.getSupportSession()));
-
- String broadcasterClass = atmoHandler.getBroadcaster();
- Broadcaster b;
- /**
- * If there is more than one AtmosphereHandler defined, their Broadcaster
- * may clash each other with the BroadcasterFactory. In that case we will use the
- * last one defined.
- */
- if (broadcasterClass != null) {
- broadcasterClassName = broadcasterClass;
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- Class<? extends Broadcaster> bc = (Class<? extends Broadcaster>) cl.loadClass(broadcasterClassName);
- broadcasterFactory = new DefaultBroadcasterFactory(bc, broadcasterLifeCyclePolicy, config);
- BroadcasterFactory.setBroadcasterFactory(broadcasterFactory, config);
- }
-
- b = broadcasterFactory.lookup(atmoHandler.getContextRoot(), true);
-
- AtmosphereHandlerWrapper wrapper = new AtmosphereHandlerWrapper(handler, b);
- addMapping(atmoHandler.getContextRoot(), wrapper);
-
- String bc = atmoHandler.getBroadcasterCache();
- if (bc != null) {
- broadcasterCacheClassName = bc;
- }
-
- if (atmoHandler.getCometSupport() != null) {
- asyncSupport = (AsyncSupport) c.loadClass(atmoHandler.getCometSupport())
- .getDeclaredConstructor(new Class[]{AtmosphereConfig.class})
- .newInstance(new Object[]{config});
- }
-
- if (atmoHandler.getBroadcastFilterClasses() != null) {
- broadcasterFilters.addAll(atmoHandler.getBroadcastFilterClasses());
- }
-
- List<AtmosphereInterceptor> l = new ArrayList<AtmosphereInterceptor>();
- if (atmoHandler.getAtmosphereInterceptorClasses() != null) {
- for (String a : atmoHandler.getAtmosphereInterceptorClasses()) {
- try {
- AtmosphereInterceptor ai = (AtmosphereInterceptor) c.loadClass(a).newInstance();
- ai.configure(config);
- l.add(ai);
- } catch (Throwable e) {
- logger.warn("", e);
- }
- }
- }
- wrapper.interceptors = l;
- if (l.size() > 0) {
- logger.info("Installed AtmosphereInterceptor {} mapped to AtmosphereHandler {}", l, atmoHandler.getClassName());
- }
- } catch (Throwable t) {
- logger.warn("Unable to load AtmosphereHandler class: " + atmoHandler.getClassName(), t);
- throw new ServletException(t);
- }
-
- }
- }
-
- /**
- * Set the {@link AsyncSupport} implementation. Make sure you don't set
- * an implementation that only works on some Container. See {@link BlockingIOCometSupport}
- * for an example.
- *
- * @param asyncSupport
- */
- public AtmosphereFramework setAsyncSupport(AsyncSupport asyncSupport) {
- this.asyncSupport = asyncSupport;
- return this;
- }
-
- /**
- * @param asyncSupport
- * @return
- * @Deprecated - Use {@link #setAsyncSupport(AsyncSupport)}
- */
- public AtmosphereFramework setCometSupport(AsyncSupport asyncSupport) {
- return setAsyncSupport(asyncSupport);
- }
-
- /**
- * Return the current {@link AsyncSupport}
- *
- * @return the current {@link AsyncSupport}
- */
- public AsyncSupport getAsyncSupport() {
- return asyncSupport;
- }
-
- /**
- * Return the current {@link AsyncSupport}
- *
- * @return the current {@link AsyncSupport}
- * @deprecated Use getAsyncSupport
- */
- public AsyncSupport getCometSupport() {
- return asyncSupport;
- }
-
- /**
- * Returns an instance of AsyncSupportResolver {@link AsyncSupportResolver}
- *
- * @return CometSupportResolver
- */
- protected AsyncSupportResolver createAsyncSupportResolver() {
- return new DefaultAsyncSupportResolver(config);
- }
-
-
- /**
- * Auto detect the underlying Servlet Container we are running on.
- */
- protected void autoDetectContainer() {
- // Was defined in atmosphere.xml
- if (getAsyncSupport() == null) {
- setAsyncSupport(createAsyncSupportResolver()
- .resolve(useNativeImplementation, useBlockingImplementation, webSocketEnabled));
- }
-
- logger.info("Atmosphere is using async support: {} running under container: {}",
- getAsyncSupport().getClass().getName(), asyncSupport.getContainerName());
- }
-
- /**
- * Auto detect instance of {@link AtmosphereHandler} in case META-INF/atmosphere.xml
- * is missing.
- *
- * @param servletContext {@link ServletContext}
- * @param classloader {@link URLClassLoader} to load the class.
- * @throws java.net.MalformedURLException
- * @throws java.net.URISyntaxException
- */
- public void autoDetectAtmosphereHandlers(ServletContext servletContext, URLClassLoader classloader)
- throws MalformedURLException, URISyntaxException {
-
- // If Handler has been added
- if (atmosphereHandlers.size() > 0) return;
-
- logger.info("Auto detecting atmosphere handlers {}", handlersPath);
-
- String realPath = servletContext.getRealPath(handlersPath);
-
- // Weblogic bug
- if (realPath == null) {
- URL u = servletContext.getResource(handlersPath);
- if (u == null) return;
- realPath = u.getPath();
- }
-
- loadAtmosphereHandlersFromPath(classloader, realPath);
- }
-
- public void loadAtmosphereHandlersFromPath(URLClassLoader classloader, String realPath) {
- File file = new File(realPath);
-
- if (file.isDirectory()) {
- getFiles(file);
- scanDone = true;
-
- for (String className : possibleComponentsCandidate) {
- try {
- className = className.replace('\\', '/');
- className = className.replaceFirst("^.*/(WEB-INF|target)(?:/scala-[^/]+)?/(test-)?classes/(.*)\\.class", "$3").replace("/", ".");
- Class<?> clazz = classloader.loadClass(className);
-
- if (AtmosphereHandler.class.isAssignableFrom(clazz)) {
- AtmosphereHandler handler = (AtmosphereHandler) clazz.newInstance();
- InjectorProvider.getInjector().inject(handler);
- addMapping("/" + handler.getClass().getSimpleName(),
- new AtmosphereHandlerWrapper(broadcasterFactory, handler, "/" + handler.getClass().getSimpleName()));
- logger.info("Installed AtmosphereHandler {} mapped to context-path: {}", handler, handler.getClass().getName());
- }
- } catch (Throwable t) {
- logger.trace("failed to load class as an AtmosphereHandler: " + className, t);
- }
- }
- }
- }
-
- /**
- * Auto detect instance of {@link org.atmosphere.websocket.WebSocketHandler} in case META-INF/atmosphere.xml
- * is missing.
- *
- * @param servletContext {@link ServletContext}
- * @param classloader {@link URLClassLoader} to load the class.
- * @throws java.net.MalformedURLException
- * @throws java.net.URISyntaxException
- */
- protected void autoDetectWebSocketHandler(ServletContext servletContext, URLClassLoader classloader)
- throws MalformedURLException, URISyntaxException {
-
- if (hasNewWebSocketProtocol) return;
-
- logger.info("Auto detecting WebSocketHandler in {}", handlersPath);
-
- String realPath = servletContext.getRealPath(handlersPath);
-
- // Weblogic bug
- if (realPath == null) {
- URL u = servletContext.getResource(handlersPath);
- if (u == null) return;
- realPath = u.getPath();
- }
-
- loadWebSocketFromPath(classloader, realPath);
- }
-
- protected void loadWebSocketFromPath(URLClassLoader classloader, String realPath) {
- File file = new File(realPath);
-
- if (file.isDirectory()) {
- getFiles(file);
- scanDone = true;
-
- for (String className : possibleComponentsCandidate) {
- try {
- className = className.replace('\\', '/');
- className = className.replaceFirst("^.*/(WEB-INF|target)(?:/scala-[^/]+)?/(test-)?classes/(.*)\\.class", "$3").replace("/", ".");
- Class<?> clazz = classloader.loadClass(className);
-
- if (WebSocketProtocol.class.isAssignableFrom(clazz)) {
- webSocketProtocol = (WebSocketProtocol) clazz.newInstance();
- InjectorProvider.getInjector().inject(webSocketProtocol);
- logger.info("Installed WebSocketProtocol {}", webSocketProtocol);
- }
- } catch (Throwable t) {
- logger.trace("failed to load class as an WebSocketProtocol: " + className, t);
- }
- }
- }
- }
-
-
- /**
- * Get the list of possible candidate to load as {@link AtmosphereHandler}
- *
- * @param f the real path {@link File}
- */
- private void getFiles(File f) {
- if (scanDone) return;
-
- File[] files = f.listFiles();
- for (File test : files) {
- if (test.isDirectory()) {
- getFiles(test);
- } else {
- String clazz = test.getAbsolutePath();
- if (clazz.endsWith(".class")) {
- possibleComponentsCandidate.add(clazz);
- }
- }
- }
- }
-
- /**
- * Invoke the proprietary {@link AsyncSupport}
- *
- * @param req
- * @param res
- * @return an {@link Action}
- * @throws IOException
- * @throws ServletException
- */
- public Action doCometSupport(AtmosphereRequest req, AtmosphereResponse res) throws IOException, ServletException {
- req.setAttribute(BROADCASTER_FACTORY, broadcasterFactory);
- req.setAttribute(PROPERTY_USE_STREAM, useStreamForFlushingComments);
- req.setAttribute(BROADCASTER_CLASS, broadcasterClassName);
- req.setAttribute(ATMOSPHERE_CONFIG, config);
-
- Action a = null;
- try {
- boolean skip = true;
- String s = config.getInitParameter(ALLOW_QUERYSTRING_AS_REQUEST);
- if (s != null) {
- skip = Boolean.valueOf(s);
- }
- if (!skip || req.getAttribute(WEBSOCKET_SUSPEND) == null) {
- Map<String, String> headers = configureQueryStringAsRequest(req);
- String body = headers.remove(ATMOSPHERE_POST_BODY);
- if (body != null && body.isEmpty()) {
- body = null;
- }
-
- req.headers(headers)
- .method(body != null && req.getMethod().equalsIgnoreCase("GET") ? "POST" : req.getMethod());
-
- if (body != null) {
- req.body(body);
- }
- }
-
- s = req.getHeader(X_ATMOSPHERE_TRACKING_ID);
-
- // Lookup for websocket
- if (s == null || s.equals("0")) {
- String unique = config.getInitParameter(ApplicationConfig.UNIQUE_UUID_WEBSOCKET);
- if (unique != null && Boolean.valueOf(unique)) {
- s = (String) req.getAttribute(SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
- }
- }
-
- if (s == null || s.equals("0")) {
- s = UUID.randomUUID().toString();
- res.setHeader(X_ATMOSPHERE_TRACKING_ID, s);
- } else {
- // This may breaks 1.0.0 application because the WebSocket's associated AtmosphereResource will
- // all have the same UUID, and retrieving the original one for WebSocket, so we don't set it at all.
- // Null means it is not an HTTP request.
- if (req.resource() == null) {
- res.setHeader(X_ATMOSPHERE_TRACKING_ID, s);
- } else if (req.getAttribute(WebSocket.WEBSOCKET_INITIATED) == null) {
- // WebSocket reconnect, in case an application manually set the header
- // (impossible to retrieve the headers normally with WebSocket or SSE)
- res.setHeader(X_ATMOSPHERE_TRACKING_ID, s);
- }
- }
-
- if (req.getAttribute(SUSPENDED_ATMOSPHERE_RESOURCE_UUID) == null) {
- req.setAttribute(SUSPENDED_ATMOSPHERE_RESOURCE_UUID, s);
- }
-
- a = asyncSupport.service(req, res);
- } catch (IllegalStateException ex) {
- if (ex.getMessage() != null && (ex.getMessage().startsWith("Tomcat failed") || ex.getMessage().startsWith("JBoss failed"))) {
- if (!isFilter) {
- logger.warn("Failed using comet support: {}, error: {} Is the Nio or Apr Connector enabled?", asyncSupport.getClass().getName(),
- ex.getMessage());
- }
- logger.trace(ex.getMessage(), ex);
-
- AsyncSupport current = asyncSupport;
- asyncSupport = asyncSupport.supportWebSocket() ? new Tomcat7BIOSupportWithWebSocket(config) : new BlockingIOCometSupport(config);
- if (current instanceof AsynchronousProcessor) {
- ((AsynchronousProcessor) current).shutdown();
- }
-
- asyncSupport.init(config.getServletConfig());
- logger.warn("Using " + asyncSupport.getClass().getName());
-
- a = asyncSupport.service(req, res);
- } else {
- logger.error("AtmosphereFramework exception", ex);
- throw ex;
- }
- } finally {
- if (a != null) {
- notify(a.type(), req, res);
- }
-
- if (req != null && a != null && a.type() != Action.TYPE.SUSPEND) {
- req.destroy();
- res.destroy();
- notify(Action.TYPE.DESTROYED, req, res);
- }
- }
- return a;
- }
-
- /**
- * Return the default {@link Broadcaster} class name.
- *
- * @return the broadcasterClassName
- */
- public String getDefaultBroadcasterClassName() {
- return broadcasterClassName;
- }
-
- /**
- * Set the default {@link Broadcaster} class name
- *
- * @param bccn the broadcasterClassName to set
- */
- public AtmosphereFramework setDefaultBroadcasterClassName(String bccn) {
- broadcasterClassName = bccn;
- return this;
- }
-
- /**
- * <tt>true</tt> if Atmosphere uses {@link AtmosphereResponse#getOutputStream()}
- * by default for write operation.
- *
- * @return the useStreamForFlushingComments
- */
- public boolean isUseStreamForFlushingComments() {
- return useStreamForFlushingComments;
- }
-
- /**
- * Set to <tt>true</tt> so Atmosphere uses {@link AtmosphereResponse#getOutputStream()}
- * by default for write operation. Default is false.
- *
- * @param useStreamForFlushingComments the useStreamForFlushingComments to set
- */
- public AtmosphereFramework setUseStreamForFlushingComments(boolean useStreamForFlushingComments) {
- this.useStreamForFlushingComments = useStreamForFlushingComments;
- return this;
- }
-
- /**
- * Get the {@link BroadcasterFactory} which is used by Atmosphere to construct
- * {@link Broadcaster}
- *
- * @return {@link BroadcasterFactory}
- */
- public BroadcasterFactory getBroadcasterFactory() {
- return broadcasterFactory;
- }
-
- /**
- * Set the {@link BroadcasterFactory} which is used by Atmosphere to construct
- * {@link Broadcaster}
- *
- * @return {@link BroadcasterFactory}
- */
- public AtmosphereFramework setBroadcasterFactory(final BroadcasterFactory broadcasterFactory) {
- this.broadcasterFactory = broadcasterFactory;
- configureBroadcaster();
- return this;
- }
-
- /**
- * Return the {@link org.atmosphere.cpr.BroadcasterCache} class name.
- *
- * @return the {@link org.atmosphere.cpr.BroadcasterCache} class name.
- */
- public String getBroadcasterCacheClassName() {
- return broadcasterCacheClassName;
- }
-
- /**
- * Set the {@link org.atmosphere.cpr.BroadcasterCache} class name.
- *
- * @param broadcasterCacheClassName
- */
- public void setBroadcasterCacheClassName(String broadcasterCacheClassName) {
- this.broadcasterCacheClassName = broadcasterCacheClassName;
- configureBroadcaster();
- }
-
- /**
- * Add a new Broadcaster class name AtmosphereServlet can use when initializing requests, and when
- * atmosphere.xml broadcaster element is unspecified.
- *
- * @param broadcasterTypeString
- */
- public AtmosphereFramework addBroadcasterType(String broadcasterTypeString) {
- broadcasterTypes.add(broadcasterTypeString);
- return this;
- }
-
- public String getWebSocketProtocolClassName() {
- return webSocketProtocolClassName;
- }
-
- public AtmosphereFramework setWebSocketProtocolClassName(String webSocketProtocolClassName) {
- hasNewWebSocketProtocol = true;
- this.webSocketProtocolClassName = webSocketProtocolClassName;
- return this;
- }
-
- public Map<String, AtmosphereHandlerWrapper> getAtmosphereHandlers() {
- return atmosphereHandlers;
- }
-
- protected Map<String, String> configureQueryStringAsRequest(AtmosphereRequest request) {
- Map<String, String> headers = new HashMap<String, String>();
-
- Enumeration<String> e = request.getParameterNames();
- String s;
- while (e.hasMoreElements()) {
- s = e.nextElement();
- if (s.equalsIgnoreCase("Content-Type")) {
- // Use the one set by the user first.
- if (request.getContentType() == null ||
- !request.getContentType().equalsIgnoreCase(request.getParameter(s))) {
- request.contentType(request.getParameter(s));
- }
- }
- headers.put(s, request.getParameter(s));
- }
- logger.trace("Query String translated to headers {}", headers);
- return headers;
- }
-
- protected boolean isIECandidate(AtmosphereRequest request) {
- String userAgent = request.getHeader("User-Agent");
- if (userAgent == null) return false;
-
- if (userAgent.contains("MSIE") || userAgent.contains(".NET")) {
- // Now check the header
- String transport = request.getHeader(HeaderConfig.X_ATMOSPHERE_TRANSPORT);
- if (transport != null) {
- return false;
- } else {
- return true;
- }
- }
- return false;
- }
-
- public WebSocketProtocol getWebSocketProtocol() {
- // TODO: Spagetthi code, needs to rework.
- // Make sure we initialized the WebSocketProtocol
- initWebSocket();
- return webSocketProtocol;
- }
-
- public boolean isUseNativeImplementation() {
- return useNativeImplementation;
- }
-
- public AtmosphereFramework setUseNativeImplementation(boolean useNativeImplementation) {
- this.useNativeImplementation = useNativeImplementation;
- return this;
- }
-
- public boolean isUseBlockingImplementation() {
- return useBlockingImplementation;
- }
-
- public AtmosphereFramework setUseBlockingImplementation(boolean useBlockingImplementation) {
- this.useBlockingImplementation = useBlockingImplementation;
- return this;
- }
-
- public String getAtmosphereDotXmlPath() {
- return atmosphereDotXmlPath;
- }
-
- public AtmosphereFramework setAtmosphereDotXmlPath(String atmosphereDotXmlPath) {
- this.atmosphereDotXmlPath = atmosphereDotXmlPath;
- return this;
- }
-
- public String getHandlersPath() {
- return handlersPath;
- }
-
- public AtmosphereFramework setHandlersPath(String handlersPath) {
- this.handlersPath = handlersPath;
- return this;
- }
-
- /**
- * Return the location of the jars containing the application classes. Default is WEB-INF/lib
- *
- * @return the location of the jars containing the application classes. Default is WEB-INF/lib
- */
- public String getLibPath() {
- return libPath;
- }
-
- /**
- * Set the location of the jars containing the application.
- *
- * @param libPath the location of the jars containing the application.
- * @return this
- */
- public AtmosphereFramework setLibPath(String libPath) {
- this.libPath = libPath;
- return this;
- }
-
- public String getWebSocketProcessorClassName() {
- return webSocketProcessorClassName;
- }
-
- public AtmosphereFramework setWebsocketProcessorClassName(String webSocketProcessorClassName) {
- this.webSocketProcessorClassName = webSocketProcessorClassName;
- return this;
- }
-
- /**
- * Add an {@link AtmosphereInterceptor} implementation. The adding order or {@link AtmosphereInterceptor} will be used, e.g
- * the first added {@link AtmosphereInterceptor} will always be called first.
- *
- * @param c {@link AtmosphereInterceptor}
- * @return this
- */
- public AtmosphereFramework interceptor(AtmosphereInterceptor c) {
- boolean found = false;
- for (AtmosphereInterceptor interceptor : interceptors) {
- if (interceptor.getClass().equals(c.getClass())) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- interceptors.addLast(c);
- logger.info("Installed AtmosphereInterceptor {}. ", c);
- }
- return this;
- }
-
- /**
- * Return the list of {@link AtmosphereInterceptor}
- *
- * @return the list of {@link AtmosphereInterceptor}
- */
- public LinkedList<AtmosphereInterceptor> interceptors() {
- return interceptors;
- }
-
- /**
- * Set the {@link AnnotationProcessor} class name.
- *
- * @param annotationProcessorClassName the {@link AnnotationProcessor} class name.
- * @return this
- */
- public AtmosphereFramework annotationProcessorClassName(String annotationProcessorClassName) {
- this.annotationProcessorClassName = annotationProcessorClassName;
- return this;
- }
-
- /**
- * Add an {@link AsyncSupportListener}
- *
- * @param asyncSupportListener an {@link AsyncSupportListener}
- * @return this;
- */
- public AtmosphereFramework asyncSupportListener(AsyncSupportListener asyncSupportListener) {
- asyncSupportListeners.add(asyncSupportListener);
- return this;
- }
-
- /**
- * Return the list of an {@link AsyncSupportListener}
- *
- * @return
- */
- public List<AsyncSupportListener> asyncSupportListeners() {
- return asyncSupportListeners;
- }
-
- /**
- * Add {@link BroadcasterListener} to all created {@link Broadcaster}
- */
- public AtmosphereFramework addBroadcasterListener(BroadcasterListener b) {
- if (isInit) {
- broadcasterFactory.addBroadcasterListener(b);
- } else {
- broadcasterListeners.add(b);
- }
- return this;
- }
-
- /**
- * Return a configured instance of {@link AtmosphereConfig}
- *
- * @return a configured instance of {@link AtmosphereConfig}
- */
- public AtmosphereConfig getAtmosphereConfig() {
- return config;
- }
-
- @Override
- public ServletContext getServletContext() {
- return servletConfig.getServletContext();
- }
-
- public ServletConfig getServletConfig() {
- return servletConfig;
- }
-
- /**
- * Return the list of {@link BroadcastFilter}
- *
- * @return the list of {@link BroadcastFilter
- */
- public List<String> broadcasterFilters() {
- return broadcasterFilters;
- }
-
- /**
- * Returns true if {@link java.util.concurrent.ExecutorService} shared amongst all components.
- *
- * @return true if {@link java.util.concurrent.ExecutorService} shared amongst all components.
- */
- public boolean isShareExecutorServices() {
- return sharedThreadPools;
- }
-
- /**
- * Set to true to have a {@link java.util.concurrent.ExecutorService} shared amongst all components.
- *
- * @param sharedThreadPools
- * @return this
- */
- public AtmosphereFramework shareExecutorServices(boolean sharedThreadPools) {
- this.sharedThreadPools = sharedThreadPools;
- return this;
- }
-
- protected void autoConfigureService(ServletContext sc) throws IOException {
- final ClassLoader cl = Thread.currentThread().getContextClassLoader();
-
- String path = libPath != DEFAULT_LIB_PATH ? libPath : sc.getRealPath(handlersPath);
- try {
- AnnotationProcessor p = (AnnotationProcessor) cl.loadClass(annotationProcessorClassName).newInstance();
- logger.info("Atmosphere is using {} for processing annotation", annotationProcessorClassName);
-
- p.configure(this);
- if (path != null) {
- p.scan(new File(path));
- }
-
- String pathLibs = sc.getRealPath(DEFAULT_LIB_PATH);
- if (pathLibs != null) {
- File libFolder = new File(pathLibs);
- File jars[] = libFolder.listFiles(new FilenameFilter() {
-
- @Override
- public boolean accept(File arg0, String arg1) {
- return arg1.endsWith(".jar");
- }
- });
-
- for (File file : jars) {
- p.scan(file);
- }
- }
- } catch (Throwable e) {
- logger.debug("Atmosphere's Service Annotation Not Supported. Please add https://github.com/rmuller/infomas-asl as dependencies or your own AnnotationProcessor to support @Service");
- logger.trace("", e);
- return;
- }
- }
-
- protected void notify(Action.TYPE type, AtmosphereRequest request, AtmosphereResponse response) {
- for (AsyncSupportListener l : asyncSupportListeners()) {
- try {
- switch (type) {
- case TIMEOUT:
- l.onTimeout(request, response);
- break;
- case CANCELLED:
- l.onClose(request, response);
- break;
- case SUSPEND:
- l.onSuspend(request, response);
- break;
- case RESUME:
- l.onSuspend(request, response);
- break;
- case DESTROYED:
- l.onDestroyed(request, response);
- break;
- }
- } catch (Throwable t) {
- logger.warn("", t);
- }
- }
- }
-} \ No newline at end of file
diff --git a/server/build.xml b/server/build.xml
index d61f412883..a812404862 100644
--- a/server/build.xml
+++ b/server/build.xml
@@ -1,59 +1,63 @@
<?xml version="1.0"?>
-<project name="vaadin-server" basedir="." default="publish-local" xmlns:ivy="antlib:org.apache.ivy.ant">
- <description>
- Compiles build helpers used when building other modules.
- </description>
- <include file="../common.xml" as="common" />
- <include file="../build.xml" as="vaadin" />
- <include file="../gwt-files.xml" as="gwtfiles" />
-
- <!-- global properties -->
- <property name="module.name" value="vaadin-server" />
- <property name="module.symbolic" value="com.vaadin.server" />
- <property name="result.dir" value="result" />
- <path id="classpath.compile.custom" />
- <path id="classpath.test.custom" />
-
- <union id="jar.includes">
- <union refid="server.gwt.includes" />
- <fileset dir="${vaadin.basedir}/WebContent">
- <include name="VAADIN/vaadinBootstrap.js" />
- </fileset>
- </union>
-
- <target name="jar">
- <property name="server.osgi.import" value="javax.servlet;version=&quot;2.4.0&quot;,javax.servlet.http;version=&quot;2.4.0&quot;,org.jsoup;version=&quot;1.6.3&quot;,org.jsoup.parser;version=&quot;1.6.3&quot;,org.jsoup.nodes;version=&quot;1.6.3&quot;,org.jsoup.helper;version=&quot;1.6.3&quot;,org.jsoup.safety;version=&quot;1.6.3&quot;,org.json;version=&quot;0.0.20080701&quot;" />
- <antcall target="common.jar">
- <param name="require-bundle" value="com.vaadin.shared;bundle-version=&quot;${vaadin.version}&quot;"/>
- <param name="import-package" value="${server.osgi.import}" />
- <param name="osgi.extra.package.prefixes" value="VAADIN" />
- <reference torefid="extra.jar.includes" refid="jar.includes" />
- </antcall>
- </target>
-
- <target name="publish-local" depends="jar">
- <antcall target="common.sources.jar">
- <reference torefid="extra.jar.includes" refid="server.gwt.includes" />
- </antcall>
- <antcall target="common.javadoc.jar" />
-
- <antcall target="common.publish-local" />
- </target>
-
- <target name="clean">
- <antcall target="common.clean" />
- </target>
-
- <target name="checkstyle">
- <antcall target="common.checkstyle">
- <param name="cs.src" location="src" />
- </antcall>
- </target>
-
- <target name="test" depends="checkstyle">
- <antcall target="common.test.run" />
- </target>
+<project name="vaadin-server" basedir="." default="publish-local"
+ xmlns:ivy="antlib:org.apache.ivy.ant">
+ <description>
+ Compiles build helpers used when building other modules.
+ </description>
+ <include file="../common.xml" as="common" />
+ <include file="../build.xml" as="vaadin" />
+ <include file="../gwt-files.xml" as="gwtfiles" />
+
+ <!-- global properties -->
+ <property name="module.name" value="vaadin-server" />
+ <property name="module.symbolic" value="com.vaadin.server" />
+ <property name="result.dir" value="result" />
+ <path id="classpath.compile.custom" />
+ <path id="classpath.test.custom" />
+
+ <union id="jar.includes">
+ <union refid="server.gwt.includes" />
+ <fileset dir="${vaadin.basedir}/WebContent">
+ <include name="VAADIN/vaadinBootstrap.js" />
+ </fileset>
+ </union>
+
+ <target name="jar">
+ <property name="server.osgi.import"
+ value="javax.servlet;version=&quot;2.4.0&quot;,javax.servlet.http;version=&quot;2.4.0&quot;,org.jsoup;version=&quot;1.6.3&quot;,org.jsoup.parser;version=&quot;1.6.3&quot;,org.jsoup.nodes;version=&quot;1.6.3&quot;,org.jsoup.helper;version=&quot;1.6.3&quot;,org.jsoup.safety;version=&quot;1.6.3&quot;,org.json;version=&quot;0.0.20080701&quot;" />
+ <property name="server.osgi.require"
+ value="com.vaadin.shared;bundle-version=&quot;${vaadin.version}&quot;,com.vaadin.push;bundle-version=&quot;${vaadin.version}&quot;;resolution:=optional" />
+ <antcall target="common.jar">
+ <param name="require-bundle" value="${server.osgi.require}" />
+ <param name="import-package" value="${server.osgi.import}" />
+ <param name="osgi.extra.package.prefixes" value="VAADIN" />
+ <reference torefid="extra.jar.includes" refid="jar.includes" />
+ </antcall>
+ </target>
+
+ <target name="publish-local" depends="jar">
+ <antcall target="common.sources.jar">
+ <reference torefid="extra.jar.includes" refid="server.gwt.includes" />
+ </antcall>
+ <antcall target="common.javadoc.jar" />
+
+ <antcall target="common.publish-local" />
+ </target>
+
+ <target name="clean">
+ <antcall target="common.clean" />
+ </target>
+
+ <target name="checkstyle">
+ <antcall target="common.checkstyle">
+ <param name="cs.src" location="src" />
+ </antcall>
+ </target>
+
+ <target name="test" depends="checkstyle">
+ <antcall target="common.test.run" />
+ </target>
</project>
diff --git a/server/ivy.xml b/server/ivy.xml
index 46d9e4c9f5..db7e953371 100644
--- a/server/ivy.xml
+++ b/server/ivy.xml
@@ -45,8 +45,8 @@
rev="${vaadin.version}" conf="build,test->build" />
<dependency org="com.vaadin" name="vaadin-theme-compiler"
rev="${vaadin.version}" conf="build,test->build" />
- <dependency org="com.vaadin" name="vaadin-push"
- rev="${vaadin.version}" conf="build-provided,test->build" />
+ <dependency org="com.vaadin" name="vaadin-push" rev="${vaadin.version}"
+ conf="build-provided,test->build" />
<!-- Jsoup for BootstrapHandler -->
<dependency org="org.jsoup" name="jsoup" rev="1.6.3"
@@ -70,12 +70,10 @@
conf="test -> default" />
<dependency org="org.hibernate" name="hibernate-validator"
rev="4.2.0.Final" conf="test -> default" />
-
+
<!-- For manual testing with PostgreSQL (see SQLTestConstants) -->
- <!--
- <dependency org="postgresql" name="postgresql"
- rev="9.1-901.jdbc3" conf="test,ide->default" />
- -->
+ <!-- <dependency org="postgresql" name="postgresql" rev="9.1-901.jdbc3"
+ conf="test,ide->default" /> -->
</dependencies>
diff --git a/server/src/com/vaadin/annotations/Push.java b/server/src/com/vaadin/annotations/Push.java
index 58e70acf21..d5e42d6f60 100644
--- a/server/src/com/vaadin/annotations/Push.java
+++ b/server/src/com/vaadin/annotations/Push.java
@@ -22,6 +22,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.vaadin.shared.communication.PushMode;
+import com.vaadin.shared.ui.ui.Transport;
import com.vaadin.ui.UI;
/**
@@ -46,4 +47,13 @@ public @interface Push {
*/
public PushMode value() default PushMode.AUTOMATIC;
+ /**
+ * Returns the transport type used for the push for the annotated UI. The
+ * default transport type when this annotation is present is
+ * {@link Transport#WEBSOCKET}.
+ *
+ * @return the transport type to use
+ */
+ public Transport transport() default Transport.DEFAULT;
+
}
diff --git a/server/src/com/vaadin/annotations/VaadinServletConfiguration.java b/server/src/com/vaadin/annotations/VaadinServletConfiguration.java
new file mode 100644
index 0000000000..38e3ff2ef0
--- /dev/null
+++ b/server/src/com/vaadin/annotations/VaadinServletConfiguration.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.vaadin.server.Constants;
+import com.vaadin.server.DefaultDeploymentConfiguration;
+import com.vaadin.server.DeploymentConfiguration;
+import com.vaadin.server.DeploymentConfiguration.LegacyProperyToStringMode;
+import com.vaadin.server.VaadinServlet;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.UI;
+
+/**
+ * Annotation for configuring subclasses of {@link VaadinServlet}. For a
+ * {@link VaadinServlet} class that has this annotation, the defined values are
+ * read during initialization and will be available using
+ * {@link DeploymentConfiguration#getApplicationOrSystemProperty(String, String)}
+ * as well as from specific methods in {@link DeploymentConfiguration}. Init
+ * params defined in <code>web.xml</code> or the <code>@WebServlet</code>
+ * annotation take precedence over values defined in this annotation.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface VaadinServletConfiguration {
+ /**
+ * Defines the init parameter name for methods in
+ * {@link VaadinServletConfiguration}.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ @Documented
+ public @interface InitParameterName {
+ /**
+ * The name of the init parameter that the annotated method controls.
+ *
+ * @return the parameter name
+ */
+ public String value();
+ }
+
+ /**
+ * Whether Vaadin is in production mode.
+ *
+ * @return true if in production mode, false otherwise.
+ *
+ * @see DeploymentConfiguration#isProductionMode()
+ */
+ @InitParameterName(Constants.SERVLET_PARAMETER_PRODUCTION_MODE)
+ public boolean productionMode();
+
+ /**
+ * Gets the default UI class to use for the servlet.
+ *
+ * @return the default UI class
+ */
+ @InitParameterName(VaadinSession.UI_PARAMETER)
+ public Class<? extends UI> ui();
+
+ /**
+ * The time resources can be cached in the browser, in seconds. The default
+ * value is
+ * {@value DefaultDeploymentConfiguration#DEFAULT_RESOURCE_CACHE_TIME}.
+ *
+ * @return the resource cache time
+ *
+ * @see DeploymentConfiguration#getResourceCacheTime()
+ */
+ @InitParameterName(Constants.SERVLET_PARAMETER_RESOURCE_CACHE_TIME)
+ public int resourceCacheTime() default DefaultDeploymentConfiguration.DEFAULT_RESOURCE_CACHE_TIME;
+
+ /**
+ * The number of seconds between heartbeat requests of a UI, or a
+ * non-positive number if heartbeat is disabled. The default value is
+ * {@value DefaultDeploymentConfiguration#DEFAULT_HEARTBEAT_INTERVAL}.
+ *
+ * @return the time between heartbeats
+ *
+ * @see DeploymentConfiguration#getHeartbeatInterval()
+ */
+ @InitParameterName(Constants.SERVLET_PARAMETER_HEARTBEAT_INTERVAL)
+ public int heartbeatInterval() default DefaultDeploymentConfiguration.DEFAULT_HEARTBEAT_INTERVAL;
+
+ /**
+ * Whether a session should be closed when all its open UIs have been idle
+ * for longer than its configured maximum inactivity time. The default value
+ * is {@value DefaultDeploymentConfiguration#DEFAULT_CLOSE_IDLE_SESSIONS}.
+ *
+ * @return true if UIs and sessions receiving only heartbeat requests are
+ * eventually closed; false if heartbeat requests extend UI and
+ * session lifetime indefinitely
+ *
+ * @see DeploymentConfiguration#isCloseIdleSessions()
+ */
+ @InitParameterName(Constants.SERVLET_PARAMETER_CLOSE_IDLE_SESSIONS)
+ public boolean closeIdleSessions() default DefaultDeploymentConfiguration.DEFAULT_CLOSE_IDLE_SESSIONS;
+
+ /**
+ * The default widgetset to use for the servlet. The default value is
+ * {@value VaadinServlet#DEFAULT_WIDGETSET}.
+ *
+ * @return the default widgetset name
+ */
+ @InitParameterName(VaadinServlet.PARAMETER_WIDGETSET)
+ public String widgetset() default VaadinServlet.DEFAULT_WIDGETSET;
+
+ /**
+ * The legacy Property.toString() mode used. The default value is
+ * {@link LegacyProperyToStringMode#DISABLED}
+ *
+ * @return The Property.toString() mode in use.
+ *
+ * @deprecated as of 7.1, should only be used to ease migration
+ */
+ @Deprecated
+ @InitParameterName(Constants.SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING)
+ public LegacyProperyToStringMode legacyPropertyToStringMode() default LegacyProperyToStringMode.DISABLED;
+}
diff --git a/server/src/com/vaadin/data/util/LegacyPropertyHelper.java b/server/src/com/vaadin/data/util/LegacyPropertyHelper.java
index 0276e35dbf..76bd57117d 100644
--- a/server/src/com/vaadin/data/util/LegacyPropertyHelper.java
+++ b/server/src/com/vaadin/data/util/LegacyPropertyHelper.java
@@ -15,6 +15,7 @@
*/
package com.vaadin.data.util;
+import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -32,7 +33,7 @@ import com.vaadin.server.VaadinService;
* @deprecated This is only used internally for backwards compatibility
*/
@Deprecated
-public class LegacyPropertyHelper {
+public class LegacyPropertyHelper implements Serializable {
/**
* Returns the property value converted to a String.
@@ -59,6 +60,11 @@ public class LegacyPropertyHelper {
getLogger().log(Level.WARNING,
Constants.WARNING_LEGACY_PROPERTY_TOSTRING,
p.getClass().getName());
+ if (getLogger().isLoggable(Level.FINE)) {
+ getLogger().log(Level.FINE,
+ "Strack trace for legacy toString to ease debugging",
+ new Throwable());
+ }
}
/**
@@ -76,8 +82,8 @@ public class LegacyPropertyHelper {
*/
public static boolean isLegacyToStringEnabled() {
if (VaadinService.getCurrent() == null) {
- // This should really not happen but we need to handle it somehow.
- // IF it happens it seems more safe to use the legacy mode and log.
+ // This will happen at least in JUnit tests. We do not what the real
+ // value should be but it seems more safe to use the legacy mode.
return true;
}
return VaadinService.getCurrent().getDeploymentConfiguration()
@@ -86,9 +92,9 @@ public class LegacyPropertyHelper {
private static boolean logLegacyToStringWarning() {
if (VaadinService.getCurrent() == null) {
- // This should really not happen but we need to handle it somehow.
- // IF it happens it seems more safe to use the legacy mode and log.
- return true;
+ // This will happen at least in JUnit tests. We do not want to spam
+ // the log with these messages in this case.
+ return false;
}
return VaadinService.getCurrent().getDeploymentConfiguration()
.getLegacyPropertyToStringMode() == LegacyProperyToStringMode.WARNING;
diff --git a/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java b/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java
new file mode 100644
index 0000000000..5999d850b4
--- /dev/null
+++ b/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+/**
+ * A converter that converts from the number type T to {@link String} and back.
+ * Uses the given locale and {@link NumberFormat} for formatting and parsing.
+ * Automatically trims the input string, removing any leading and trailing white
+ * space.
+ * <p>
+ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @since 7.1
+ */
+public abstract class AbstractStringToNumberConverter<T> implements
+ Converter<String, T> {
+
+ /**
+ * Returns the format used by {@link #convertToPresentation(Object, Locale)}
+ * and {@link #convertToModel(Object, Locale)}.
+ *
+ * @param locale
+ * The locale to use
+ * @return A NumberFormat instance
+ * @since 7.1
+ */
+ protected NumberFormat getFormat(Locale locale) {
+ if (locale == null) {
+ locale = Locale.getDefault();
+ }
+
+ return NumberFormat.getNumberInstance(locale);
+ }
+
+ /**
+ * Convert the value to a Number using the given locale and
+ * {@link #getFormat(Locale)}.
+ *
+ * @param value
+ * The value to convert
+ * @param locale
+ * The locale to use for conversion
+ * @return The converted value
+ * @throws ConversionException
+ * If there was a problem converting the value
+ * @since 7.1
+ */
+ protected Number convertToNumber(String value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ // Remove leading and trailing white space
+ value = value.trim();
+
+ // Parse and detect errors. If the full string was not used, it is
+ // an error.
+ ParsePosition parsePosition = new ParsePosition(0);
+ Number parsedValue = getFormat(locale).parse(value, parsePosition);
+ if (parsePosition.getIndex() != value.length()) {
+ throw new ConversionException("Could not convert '" + value
+ + "' to " + getModelType().getName());
+ }
+
+ if (parsedValue == null) {
+ // Convert "" to null
+ return null;
+ }
+ return parsedValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ @Override
+ public String convertToPresentation(T value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return getFormat(locale).format(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
+ */
+ @Override
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+}
diff --git a/server/src/com/vaadin/data/util/converter/Converter.java b/server/src/com/vaadin/data/util/converter/Converter.java
index be9bb32413..ded7da7fb5 100644
--- a/server/src/com/vaadin/data/util/converter/Converter.java
+++ b/server/src/com/vaadin/data/util/converter/Converter.java
@@ -38,12 +38,12 @@ import java.util.Locale;
* If conversion of a value fails, a {@link ConversionException} is thrown.
* </p>
*
- * @param <MODEL>
- * The model type. Must be compatible with what
- * {@link #getModelType()} returns.
* @param <PRESENTATION>
* The presentation type. Must be compatible with what
* {@link #getPresentationType()} returns.
+ * @param <MODEL>
+ * The model type. Must be compatible with what
+ * {@link #getModelType()} returns.
* @author Vaadin Ltd.
* @since 7.0
*/
diff --git a/server/src/com/vaadin/data/util/converter/ConverterUtil.java b/server/src/com/vaadin/data/util/converter/ConverterUtil.java
index 61d155bc9a..08d7363084 100644
--- a/server/src/com/vaadin/data/util/converter/ConverterUtil.java
+++ b/server/src/com/vaadin/data/util/converter/ConverterUtil.java
@@ -151,10 +151,14 @@ public class ConverterUtil implements Serializable {
/**
* Checks if the given converter can handle conversion between the given
- * presentation and model type
+ * presentation and model type. Does strict type checking and only returns
+ * true if the converter claims it can handle exactly the given types.
+ *
+ * @see #canConverterPossiblyHandle(Converter, Class, Class)
*
* @param converter
- * The converter to check
+ * The converter to check. If this is null the result is always
+ * false.
* @param presentationType
* The presentation type
* @param modelType
@@ -168,10 +172,48 @@ public class ConverterUtil implements Serializable {
return false;
}
- if (!modelType.isAssignableFrom(converter.getModelType())) {
+ if (modelType != converter.getModelType()) {
+ return false;
+ }
+ if (presentationType != converter.getPresentationType()) {
return false;
}
- if (!presentationType.isAssignableFrom(converter.getPresentationType())) {
+
+ return true;
+ }
+
+ /**
+ * Checks if it possible that the given converter can handle conversion
+ * between the given presentation and model type somehow.
+ *
+ * @param converter
+ * The converter to check. If this is null the result is always
+ * false.
+ * @param presentationType
+ * The presentation type
+ * @param modelType
+ * The model type
+ * @return true if the converter possibly support conversion between the
+ * given presentation and model type, false otherwise
+ */
+ public static boolean canConverterPossiblyHandle(Converter<?, ?> converter,
+ Class<?> presentationType, Class<?> modelType) {
+ if (converter == null) {
+ return false;
+ }
+ Class<?> converterModelType = converter.getModelType();
+
+ if (!modelType.isAssignableFrom(converterModelType)
+ && !converterModelType.isAssignableFrom(modelType)) {
+ // model types are not compatible in any way
+ return false;
+ }
+
+ Class<?> converterPresentationType = converter.getPresentationType();
+ if (!presentationType.isAssignableFrom(converterPresentationType)
+ && !converterPresentationType
+ .isAssignableFrom(presentationType)) {
+ // presentation types are not compatible in any way
return false;
}
diff --git a/server/src/com/vaadin/data/util/converter/DateToSqlDateConverter.java b/server/src/com/vaadin/data/util/converter/DateToSqlDateConverter.java
new file mode 100644
index 0000000000..97027cc05b
--- /dev/null
+++ b/server/src/com/vaadin/data/util/converter/DateToSqlDateConverter.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ *
+ */
+package com.vaadin.data.util.converter;
+
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * Converter for handling conversion between {@link java.util.Date} and
+ * {@link java.sql.Date}. This is used when a PopupDateField or InlineDateField
+ * is connected to a java.sql.Date property, typically through a JPAContainer or
+ * SQLContainer. Note that information (time information) is lost when
+ * converting from {@link java.util.Date} to {@link java.sql.Date}.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public class DateToSqlDateConverter implements Converter<Date, java.sql.Date> {
+
+ @Override
+ public java.sql.Date convertToModel(Date value, Locale locale)
+ throws ConversionException {
+ return new java.sql.Date(value.getTime());
+ }
+
+ @Override
+ public Date convertToPresentation(java.sql.Date value, Locale locale)
+ throws ConversionException {
+ return new Date(value.getTime());
+ }
+
+ @Override
+ public Class<java.sql.Date> getModelType() {
+ return java.sql.Date.class;
+ }
+
+ @Override
+ public Class<Date> getPresentationType() {
+ return Date.class;
+ }
+
+}
diff --git a/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java b/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
index de183dd342..bbd3945a37 100644
--- a/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
+++ b/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
@@ -87,6 +87,8 @@ public class DefaultConverterFactory implements ConverterFactory {
protected Converter<Date, ?> createDateConverter(Class<?> sourceType) {
if (Long.class.isAssignableFrom(sourceType)) {
return new DateToLongConverter();
+ } else if (java.sql.Date.class.isAssignableFrom(sourceType)) {
+ return new DateToSqlDateConverter();
} else {
return null;
}
diff --git a/server/src/com/vaadin/data/util/converter/StringToDoubleConverter.java b/server/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
index 69a0faf8f4..8bb82498b9 100644
--- a/server/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
+++ b/server/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
@@ -17,7 +17,6 @@
package com.vaadin.data.util.converter;
import java.text.NumberFormat;
-import java.text.ParsePosition;
import java.util.Locale;
/**
@@ -34,23 +33,8 @@ import java.util.Locale;
* @author Vaadin Ltd
* @since 7.0
*/
-public class StringToDoubleConverter implements Converter<String, Double> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Double, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- return NumberFormat.getNumberInstance(locale);
- }
+public class StringToDoubleConverter extends
+ AbstractStringToNumberConverter<Double> {
/*
* (non-Javadoc)
@@ -62,42 +46,8 @@ public class StringToDoubleConverter implements Converter<String, Double> {
@Override
public Double convertToModel(String value, Locale locale)
throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
- if (parsedValue == null) {
- // Convert "" to null
- return null;
- }
-
- return parsedValue.doubleValue();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- @Override
- public String convertToPresentation(Double value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
+ Number n = convertToNumber(value, locale);
+ return n == null ? null : n.doubleValue();
}
/*
@@ -110,13 +60,4 @@ public class StringToDoubleConverter implements Converter<String, Double> {
return Double.class;
}
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- @Override
- public Class<String> getPresentationType() {
- return String.class;
- }
}
diff --git a/server/src/com/vaadin/data/util/converter/StringToFloatConverter.java b/server/src/com/vaadin/data/util/converter/StringToFloatConverter.java
index 1adfd87565..a207654358 100644
--- a/server/src/com/vaadin/data/util/converter/StringToFloatConverter.java
+++ b/server/src/com/vaadin/data/util/converter/StringToFloatConverter.java
@@ -17,7 +17,6 @@
package com.vaadin.data.util.converter;
import java.text.NumberFormat;
-import java.text.ParsePosition;
import java.util.Locale;
/**
@@ -34,23 +33,8 @@ import java.util.Locale;
* @author Vaadin Ltd
* @since 7.0
*/
-public class StringToFloatConverter implements Converter<String, Float> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Float, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- return NumberFormat.getNumberInstance(locale);
- }
+public class StringToFloatConverter extends
+ AbstractStringToNumberConverter<Float> {
/*
* (non-Javadoc)
@@ -62,42 +46,8 @@ public class StringToFloatConverter implements Converter<String, Float> {
@Override
public Float convertToModel(String value, Locale locale)
throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
- if (parsedValue == null) {
- // Convert "" to null
- return null;
- }
-
- return parsedValue.floatValue();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- @Override
- public String convertToPresentation(Float value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
+ Number n = convertToNumber(value, locale);
+ return n == null ? null : n.floatValue();
}
/*
@@ -110,13 +60,4 @@ public class StringToFloatConverter implements Converter<String, Float> {
return Float.class;
}
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- @Override
- public Class<String> getPresentationType() {
- return String.class;
- }
}
diff --git a/server/src/com/vaadin/data/util/converter/StringToIntegerConverter.java b/server/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
index 4bb933bcc8..4f34cf1cd3 100644
--- a/server/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
+++ b/server/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
@@ -17,7 +17,6 @@
package com.vaadin.data.util.converter;
import java.text.NumberFormat;
-import java.text.ParsePosition;
import java.util.Locale;
/**
@@ -31,7 +30,8 @@ import java.util.Locale;
* @author Vaadin Ltd
* @since 7.0
*/
-public class StringToIntegerConverter implements Converter<String, Integer> {
+public class StringToIntegerConverter extends
+ AbstractStringToNumberConverter<Integer> {
/**
* Returns the format used by
@@ -42,6 +42,7 @@ public class StringToIntegerConverter implements Converter<String, Integer> {
* The locale to use
* @return A NumberFormat instance
*/
+ @Override
protected NumberFormat getFormat(Locale locale) {
if (locale == null) {
locale = Locale.getDefault();
@@ -49,50 +50,29 @@ public class StringToIntegerConverter implements Converter<String, Integer> {
return NumberFormat.getIntegerInstance(locale);
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
+ * java.util.Locale)
+ */
@Override
public Integer convertToModel(String value, Locale locale)
throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
+ Number n = convertToNumber(value, locale);
+ return n == null ? null : n.intValue();
- // Parse and detect errors. If the full string was not used, it is
- // an error.
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- if (parsedValue == null) {
- // Convert "" to null
- return null;
- }
- return parsedValue.intValue();
- }
-
- @Override
- public String convertToPresentation(Integer value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getModelType()
+ */
@Override
public Class<Integer> getModelType() {
return Integer.class;
}
- @Override
- public Class<String> getPresentationType() {
- return String.class;
- }
-
}
diff --git a/server/src/com/vaadin/data/util/converter/StringToNumberConverter.java b/server/src/com/vaadin/data/util/converter/StringToNumberConverter.java
index 99ff7007ad..eae73e4cfa 100644
--- a/server/src/com/vaadin/data/util/converter/StringToNumberConverter.java
+++ b/server/src/com/vaadin/data/util/converter/StringToNumberConverter.java
@@ -17,7 +17,6 @@
package com.vaadin.data.util.converter;
import java.text.NumberFormat;
-import java.text.ParsePosition;
import java.util.Locale;
/**
@@ -30,23 +29,8 @@ import java.util.Locale;
* @author Vaadin Ltd
* @since 7.0
*/
-public class StringToNumberConverter implements Converter<String, Number> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Number, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- return NumberFormat.getNumberInstance(locale);
- }
+public class StringToNumberConverter extends
+ AbstractStringToNumberConverter<Number> {
/*
* (non-Javadoc)
@@ -58,44 +42,7 @@ public class StringToNumberConverter implements Converter<String, Number> {
@Override
public Number convertToModel(String value, Locale locale)
throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- // Parse and detect errors. If the full string was not used, it is
- // an error.
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- if (parsedValue == null) {
- // Convert "" to null
- return null;
- }
- return parsedValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- @Override
- public String convertToPresentation(Number value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
+ return convertToNumber(value, locale);
}
/*
@@ -108,14 +55,4 @@ public class StringToNumberConverter implements Converter<String, Number> {
return Number.class;
}
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- @Override
- public Class<String> getPresentationType() {
- return String.class;
- }
-
}
diff --git a/server/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java b/server/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java
index 65c1050fb0..0cc2f0a1a5 100644
--- a/server/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java
+++ b/server/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java
@@ -48,7 +48,7 @@ public class SourceIs extends ClientSideCriterion {
int paintedComponents = 0;
for (int i = 0; i < components.length; i++) {
Component c = components[i];
- if (c.getUI() != null && c.getUI().getSession() != null) {
+ if (c.isAttached()) {
target.addAttribute("component" + paintedComponents++, c);
} else {
Logger.getLogger(SourceIs.class.getName())
diff --git a/server/src/com/vaadin/navigator/Navigator.java b/server/src/com/vaadin/navigator/Navigator.java
index df05a9fbce..540a3ee302 100644
--- a/server/src/com/vaadin/navigator/Navigator.java
+++ b/server/src/com/vaadin/navigator/Navigator.java
@@ -497,19 +497,22 @@ public class Navigator implements Serializable {
*/
public void navigateTo(String navigationState) {
String longestViewName = null;
+ ViewProvider longestViewNameProvider = null;
View viewWithLongestName = null;
for (ViewProvider provider : providers) {
String viewName = provider.getViewName(navigationState);
if (null != viewName
&& (longestViewName == null || viewName.length() > longestViewName
.length())) {
- View view = provider.getView(viewName);
- if (null != view) {
- longestViewName = viewName;
- viewWithLongestName = view;
- }
+ longestViewName = viewName;
+ longestViewNameProvider = provider;
}
}
+ if (longestViewName != null) {
+ viewWithLongestName = longestViewNameProvider
+ .getView(longestViewName);
+ }
+
if (viewWithLongestName == null && errorProvider != null) {
longestViewName = errorProvider.getViewName(navigationState);
viewWithLongestName = errorProvider.getView(longestViewName);
diff --git a/server/src/com/vaadin/server/AbstractClientConnector.java b/server/src/com/vaadin/server/AbstractClientConnector.java
index e998b8ed55..01f7d9af42 100644
--- a/server/src/com/vaadin/server/AbstractClientConnector.java
+++ b/server/src/com/vaadin/server/AbstractClientConnector.java
@@ -577,7 +577,7 @@ public abstract class AbstractClientConnector implements ClientConnector,
}
// Send detach event if the component have been connected to a window
- if (getSession() != null) {
+ if (isAttached()) {
detach();
}
@@ -585,7 +585,7 @@ public abstract class AbstractClientConnector implements ClientConnector,
this.parent = parent;
// Send attach event if connected to an application
- if (getSession() != null) {
+ if (isAttached()) {
attach();
}
}
@@ -595,6 +595,16 @@ public abstract class AbstractClientConnector implements ClientConnector,
return parent;
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.server.ClientConnector#isAttached()
+ */
+ @Override
+ public boolean isAttached() {
+ return getSession() != null;
+ }
+
@Override
public void attach() {
markAsDirty();
diff --git a/server/src/com/vaadin/server/ClientConnector.java b/server/src/com/vaadin/server/ClientConnector.java
index 3b52fbc730..9e328bb6ef 100644
--- a/server/src/com/vaadin/server/ClientConnector.java
+++ b/server/src/com/vaadin/server/ClientConnector.java
@@ -226,14 +226,22 @@ public interface ClientConnector extends Connector {
public void setParent(ClientConnector parent);
/**
- * Notifies the connector that it is connected to an application.
+ * Checks if the connector is attached to a VaadinSession.
*
+ * @since 7.1
+ * @return true if the connector is attached to a session, false otherwise
+ */
+ public boolean isAttached();
+
+ /**
+ * Notifies the connector that it is connected to a VaadinSession (and
+ * therefore also to a UI).
* <p>
* The caller of this method is {@link #setParent(ClientConnector)} if the
- * parent is itself already attached to the application. If not, the parent
- * will call the {@link #attach()} for all its children when it is attached
- * to the application. This method is always called before the connector's
- * data is sent to the client-side for the first time.
+ * parent is itself already attached to the session. If not, the parent will
+ * call the {@link #attach()} for all its children when it is attached to
+ * the session. This method is always called before the connector's data is
+ * sent to the client-side for the first time.
* </p>
*
* <p>
@@ -243,13 +251,13 @@ public interface ClientConnector extends Connector {
public void attach();
/**
- * Notifies the connector that it is detached from the application.
+ * Notifies the connector that it is detached from its VaadinSession.
*
* <p>
* The caller of this method is {@link #setParent(ClientConnector)} if the
- * parent is in the application. When the parent is detached from the
- * application it is its responsibility to call {@link #detach()} for each
- * of its children.
+ * parent is in the session. When the parent is detached from the session it
+ * is its responsibility to call {@link #detach()} for each of its children.
+ *
* </p>
*/
public void detach();
diff --git a/server/src/com/vaadin/server/ComponentSizeValidator.java b/server/src/com/vaadin/server/ComponentSizeValidator.java
index 27d087a2b2..07c195a1c1 100644
--- a/server/src/com/vaadin/server/ComponentSizeValidator.java
+++ b/server/src/com/vaadin/server/ComponentSizeValidator.java
@@ -16,8 +16,8 @@
package com.vaadin.server;
import java.io.PrintStream;
-import java.io.PrintWriter;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
@@ -40,6 +40,7 @@ import com.vaadin.ui.GridLayout.Area;
import com.vaadin.ui.Layout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
@@ -190,14 +191,14 @@ public class ComponentSizeValidator implements Serializable {
subErrors.add(error);
}
- public void reportErrors(PrintWriter clientJSON,
+ public void reportErrors(StringBuilder clientJSON,
PrintStream serverErrorStream) {
- clientJSON.write("{");
+ clientJSON.append("{");
Component parent = component.getParent();
String paintableId = component.getConnectorId();
- clientJSON.print("id:\"" + paintableId + "\"");
+ clientJSON.append("\"id\":\"" + paintableId + "\"");
if (invalidHeight) {
Stack<ComponentInfo> attributes = null;
@@ -227,7 +228,7 @@ public class ComponentSizeValidator implements Serializable {
attributes = getHeightAttributes(component);
}
printServerError(msg, attributes, false, serverErrorStream);
- clientJSON.print(",\"heightMsg\":\"" + msg + "\"");
+ clientJSON.append(",\"heightMsg\":\"" + msg + "\"");
}
if (invalidWidth) {
Stack<ComponentInfo> attributes = null;
@@ -255,25 +256,25 @@ public class ComponentSizeValidator implements Serializable {
msg = "A component with relative width needs a parent with defined width.";
attributes = getWidthAttributes(component);
}
- clientJSON.print(",\"widthMsg\":\"" + msg + "\"");
+ clientJSON.append(",\"widthMsg\":\"" + msg + "\"");
printServerError(msg, attributes, true, serverErrorStream);
}
if (subErrors.size() > 0) {
serverErrorStream.println("Sub errors >>");
- clientJSON.write(", \"subErrors\" : [");
+ clientJSON.append(", \"subErrors\" : [");
boolean first = true;
for (InvalidLayout subError : subErrors) {
if (!first) {
- clientJSON.print(",");
+ clientJSON.append(",");
} else {
first = false;
}
subError.reportErrors(clientJSON, serverErrorStream);
}
- clientJSON.write("]");
+ clientJSON.append("]");
serverErrorStream.println("<< Sub erros");
}
- clientJSON.write("}");
+ clientJSON.append("}");
}
}
@@ -673,4 +674,31 @@ public class ComponentSizeValidator implements Serializable {
return Logger.getLogger(ComponentSizeValidator.class.getName());
}
+ /**
+ * Validates the layout and returns a collection of errors
+ *
+ * @since 7.1
+ * @param ui
+ * The UI to validate
+ * @return A collection of errors. An empty collection if there are no
+ * errors.
+ */
+ public static List<InvalidLayout> validateLayouts(UI ui) {
+ List<InvalidLayout> invalidRelativeSizes = ComponentSizeValidator
+ .validateComponentRelativeSizes(ui.getContent(),
+ new ArrayList<ComponentSizeValidator.InvalidLayout>(),
+ null);
+
+ // Also check any existing subwindows
+ if (ui.getWindows() != null) {
+ for (Window subWindow : ui.getWindows()) {
+ invalidRelativeSizes = ComponentSizeValidator
+ .validateComponentRelativeSizes(subWindow.getContent(),
+ invalidRelativeSizes, null);
+ }
+ }
+ return invalidRelativeSizes;
+
+ }
+
}
diff --git a/server/src/com/vaadin/server/ConnectorResourceHandler.java b/server/src/com/vaadin/server/ConnectorResourceHandler.java
index 00d82988d3..3f3f41a179 100644
--- a/server/src/com/vaadin/server/ConnectorResourceHandler.java
+++ b/server/src/com/vaadin/server/ConnectorResourceHandler.java
@@ -77,8 +77,8 @@ public class ConnectorResourceHandler implements RequestHandler {
session.unlock();
}
- Map<Class<?>, CurrentInstance> oldThreadLocals = CurrentInstance
- .setThreadLocals(ui);
+ Map<Class<?>, CurrentInstance> oldInstances = CurrentInstance
+ .setCurrent(ui);
try {
if (!connector.handleConnectorRequest(request, response, key)) {
return error(request, response, connector.getClass()
@@ -88,7 +88,7 @@ public class ConnectorResourceHandler implements RequestHandler {
+ ") did not handle connector request for " + key);
}
} finally {
- CurrentInstance.restoreThreadLocals(oldThreadLocals);
+ CurrentInstance.restoreInstances(oldInstances);
}
return true;
diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/com/vaadin/server/Constants.java
index f8d8105286..2c041e3cf8 100644
--- a/server/src/com/vaadin/server/Constants.java
+++ b/server/src/com/vaadin/server/Constants.java
@@ -65,11 +65,11 @@ public interface Constants {
+ " Widgetset version: %s\n"
+ "=================================================================";
- static final String REQUIRED_ATMOSPHERE_VERSION = "1.0.12";
+ static final String REQUIRED_ATMOSPHERE_VERSION = "1.0.13";
static final String INVALID_ATMOSPHERE_VERSION_WARNING = "\n"
+ "=================================================================\n"
- + "Vaadin depends on Atomsphere {0} but version {1} was found.\n"
+ + "Vaadin depends on Atmosphere {0} but version {1} was found.\n"
+ "This might cause compatibility problems if push is used.\n"
+ "=================================================================";
@@ -106,7 +106,8 @@ public interface Constants {
+ "\" to \"true\". To disable the legacy functionality, set \""
+ Constants.SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING
+ "\" to false."
- + " (Note that your debugger might call toString() and trigger this message).";
+ + " (Note that your debugger might call toString() and trigger this message)."
+ + " To find out who is calling toString(), enable FINE level logging.";
static final String WARNING_UNKNOWN_LEGACY_PROPERTY_TOSTRING_VALUE = "Unknown value '{0}' for parameter "
+ Constants.SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING
diff --git a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java b/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java
index 80c3644d77..a55c3231f3 100644
--- a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java
+++ b/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java
@@ -30,6 +30,27 @@ import com.vaadin.shared.communication.PushMode;
* @since 7.0.0
*/
public class DefaultDeploymentConfiguration implements DeploymentConfiguration {
+ /**
+ * Default value for {@link #getResourceCacheTime()} = {@value} .
+ */
+ public static final int DEFAULT_RESOURCE_CACHE_TIME = 3600;
+
+ /**
+ * Default value for {@link #getHeartbeatInterval()} = {@value} .
+ */
+ public static final int DEFAULT_HEARTBEAT_INTERVAL = 300;
+
+ /**
+ * Default value for {@link #isCloseIdleSessions()} = {@value} .
+ */
+ public static final boolean DEFAULT_CLOSE_IDLE_SESSIONS = false;
+
+ /**
+ * Default value for {@link #getLegacyPropertyToStringMode()} =
+ * {@link LegacyProperyToStringMode#WARNING}.
+ */
+ public static final LegacyProperyToStringMode DEFAULT_LEGACY_PROPERTY_TO_STRING = LegacyProperyToStringMode.WARNING;
+
private final Properties initParameters;
private boolean productionMode;
private boolean xsrfProtectionEnabled;
@@ -66,20 +87,17 @@ public class DefaultDeploymentConfiguration implements DeploymentConfiguration {
private void checkLegacyPropertyToString() {
String param = getApplicationOrSystemProperty(
- Constants.SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING, "warning");
- if ("true".equals(param)) {
- legacyPropertyToStringMode = LegacyProperyToStringMode.ENABLED;
- } else if ("false".equals(param)) {
- legacyPropertyToStringMode = LegacyProperyToStringMode.DISABLED;
- } else {
- if (!"warning".equals(param)) {
- getLogger()
- .log(Level.WARNING,
- Constants.WARNING_UNKNOWN_LEGACY_PROPERTY_TOSTRING_VALUE,
- param);
- }
- legacyPropertyToStringMode = LegacyProperyToStringMode.WARNING;
+ Constants.SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING,
+ DEFAULT_LEGACY_PROPERTY_TO_STRING.name().toLowerCase());
+ try {
+ legacyPropertyToStringMode = LegacyProperyToStringMode
+ .valueOf(param.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ getLogger().log(Level.WARNING,
+ Constants.WARNING_UNKNOWN_LEGACY_PROPERTY_TOSTRING_VALUE,
+ param);
+ legacyPropertyToStringMode = DEFAULT_LEGACY_PROPERTY_TO_STRING;
}
}
@@ -250,11 +268,11 @@ public class DefaultDeploymentConfiguration implements DeploymentConfiguration {
resourceCacheTime = Integer
.parseInt(getApplicationOrSystemProperty(
Constants.SERVLET_PARAMETER_RESOURCE_CACHE_TIME,
- "3600"));
+ Integer.toString(DEFAULT_RESOURCE_CACHE_TIME)));
} catch (NumberFormatException e) {
getLogger().warning(
Constants.WARNING_RESOURCE_CACHING_TIME_NOT_NUMERIC);
- resourceCacheTime = 3600;
+ resourceCacheTime = DEFAULT_RESOURCE_CACHE_TIME;
}
}
@@ -263,18 +281,18 @@ public class DefaultDeploymentConfiguration implements DeploymentConfiguration {
heartbeatInterval = Integer
.parseInt(getApplicationOrSystemProperty(
Constants.SERVLET_PARAMETER_HEARTBEAT_INTERVAL,
- "300"));
+ Integer.toString(DEFAULT_HEARTBEAT_INTERVAL)));
} catch (NumberFormatException e) {
getLogger().warning(
Constants.WARNING_HEARTBEAT_INTERVAL_NOT_NUMERIC);
- heartbeatInterval = 300;
+ heartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL;
}
}
private void checkCloseIdleSessions() {
closeIdleSessions = getApplicationOrSystemProperty(
- Constants.SERVLET_PARAMETER_CLOSE_IDLE_SESSIONS, "false")
- .equals("true");
+ Constants.SERVLET_PARAMETER_CLOSE_IDLE_SESSIONS,
+ Boolean.toString(DEFAULT_CLOSE_IDLE_SESSIONS)).equals("true");
}
private void checkPushMode() {
diff --git a/server/src/com/vaadin/server/DragAndDropService.java b/server/src/com/vaadin/server/DragAndDropService.java
index a83e83ef7f..cc571853fe 100644
--- a/server/src/com/vaadin/server/DragAndDropService.java
+++ b/server/src/com/vaadin/server/DragAndDropService.java
@@ -375,4 +375,14 @@ public class DragAndDropService implements VariableOwner, ClientConnector {
@Override
public void removeDetachListener(DetachListener listener) {
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.server.ClientConnector#isAttached()
+ */
+ @Override
+ public boolean isAttached() {
+ return true;
+ }
}
diff --git a/server/src/com/vaadin/server/GlobalResourceHandler.java b/server/src/com/vaadin/server/GlobalResourceHandler.java
index d411b286d0..4235d85024 100644
--- a/server/src/com/vaadin/server/GlobalResourceHandler.java
+++ b/server/src/com/vaadin/server/GlobalResourceHandler.java
@@ -87,14 +87,14 @@ public class GlobalResourceHandler implements RequestHandler {
+ " is not a valid global resource path");
}
session.lock();
- Map<Class<?>, CurrentInstance> oldThreadLocals = null;
+ Map<Class<?>, CurrentInstance> oldInstances = null;
DownloadStream stream = null;
try {
UI ui = session.getUIById(Integer.parseInt(uiid));
if (ui == null) {
return error(request, response, "No UI found for id " + uiid);
}
- oldThreadLocals = CurrentInstance.setThreadLocals(ui);
+ oldInstances = CurrentInstance.setCurrent(ui);
ConnectorResource resource;
if (LEGACY_TYPE.equals(type)) {
resource = legacyResources.get(key);
@@ -115,8 +115,8 @@ public class GlobalResourceHandler implements RequestHandler {
}
} finally {
session.unlock();
- if (oldThreadLocals != null) {
- CurrentInstance.restoreThreadLocals(oldThreadLocals);
+ if (oldInstances != null) {
+ CurrentInstance.restoreInstances(oldInstances);
}
}
diff --git a/server/src/com/vaadin/server/JsonPaintTarget.java b/server/src/com/vaadin/server/JsonPaintTarget.java
index ca70391f64..cd09b2a44b 100644
--- a/server/src/com/vaadin/server/JsonPaintTarget.java
+++ b/server/src/com/vaadin/server/JsonPaintTarget.java
@@ -388,10 +388,6 @@ public class JsonPaintTarget implements PaintTarget {
getUsedResources().add("layouts/" + value + ".html");
}
- if (name.equals("locale")) {
- manager.requireLocale(value);
- }
-
}
@Override
diff --git a/server/src/com/vaadin/server/LegacyApplication.java b/server/src/com/vaadin/server/LegacyApplication.java
index 54550ce134..44649067c5 100644
--- a/server/src/com/vaadin/server/LegacyApplication.java
+++ b/server/src/com/vaadin/server/LegacyApplication.java
@@ -64,7 +64,7 @@ public abstract class LegacyApplication implements ErrorHandler {
if (this.mainWindow != null) {
throw new IllegalStateException("mainWindow has already been set");
}
- if (mainWindow.getSession() != null) {
+ if (mainWindow.isAttached()) {
throw new IllegalStateException(
"mainWindow is attached to another application");
}
diff --git a/server/src/com/vaadin/server/LegacyCommunicationManager.java b/server/src/com/vaadin/server/LegacyCommunicationManager.java
index c0194db243..ad662cf6df 100644
--- a/server/src/com/vaadin/server/LegacyCommunicationManager.java
+++ b/server/src/com/vaadin/server/LegacyCommunicationManager.java
@@ -16,18 +16,12 @@
package com.vaadin.server;
-import java.io.IOException;
-import java.io.PrintWriter;
import java.io.Serializable;
-import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
@@ -37,7 +31,6 @@ import org.json.JSONException;
import org.json.JSONObject;
import com.vaadin.server.ClientConnector.ConnectorErrorEvent;
-import com.vaadin.server.communication.LocaleWriter;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.JavaScriptConnectorState;
import com.vaadin.shared.communication.SharedState;
@@ -69,9 +62,6 @@ public class LegacyCommunicationManager implements Serializable {
*/
private final VaadinSession session;
- // TODO Refactor to UI shared state (#11378)
- private List<String> locales;
-
// TODO Move to VaadinSession (#11409)
private DragAndDropService dragAndDropService;
@@ -88,7 +78,6 @@ public class LegacyCommunicationManager implements Serializable {
*/
public LegacyCommunicationManager(VaadinSession session) {
this.session = session;
- requireLocale(session.getLocale().toString());
}
protected VaadinSession getSession() {
@@ -313,52 +302,6 @@ public class LegacyCommunicationManager implements Serializable {
}
/**
- * Prints the queued (pending) locale definitions to a {@link PrintWriter}
- * in a (UIDL) format that can be sent to the client and used there in
- * formatting dates, times etc.
- *
- * @deprecated As of 7.1. See #11378.
- *
- * @param outWriter
- */
- @Deprecated
- public void printLocaleDeclarations(Writer writer) throws IOException {
- new LocaleWriter().write(locales, writer);
- }
-
- /**
- * Queues a locale to be sent to the client (browser) for date and time
- * entry etc. All locale specific information is derived from server-side
- * {@link Locale} instances and sent to the client when needed, eliminating
- * the need to use the {@link Locale} class and all the framework behind it
- * on the client.
- *
- * @deprecated As of 7.1. See #11378.
- *
- * @see Locale#toString()
- *
- * @param value
- */
- @Deprecated
- public void requireLocale(String value) {
- if (locales == null) {
- locales = new ArrayList<String>();
- locales.add(session.getLocale().toString());
- }
- if (!locales.contains(value)) {
- locales.add(value);
- }
- }
-
- /**
- * @deprecated As of 7.1. See #11378.
- */
- @Deprecated
- public void resetLocales() {
- locales = null;
- }
-
- /**
* @deprecated As of 7.1. Will be removed in the future.
*/
@Deprecated
@@ -486,10 +429,6 @@ public class LegacyCommunicationManager implements Serializable {
getClientCache(ui).clear();
ui.getConnectorTracker().markAllConnectorsDirty();
ui.getConnectorTracker().markAllClientSidesUninitialized();
-
- // Reset sent locales
- resetLocales();
- requireLocale(session.getLocale().toString());
}
private static final Logger getLogger() {
diff --git a/server/src/com/vaadin/server/LocaleService.java b/server/src/com/vaadin/server/LocaleService.java
new file mode 100644
index 0000000000..347c4da5c6
--- /dev/null
+++ b/server/src/com/vaadin/server/LocaleService.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ *
+ */
+package com.vaadin.server;
+
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.logging.Logger;
+
+import com.vaadin.shared.ui.ui.UIState.LocaleData;
+import com.vaadin.shared.ui.ui.UIState.LocaleServiceState;
+import com.vaadin.ui.UI;
+
+/**
+ * Server side service which handles locale and the transmission of locale date
+ * to the client side LocaleService.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public class LocaleService {
+
+ private UI ui;
+
+ private LocaleServiceState state;
+
+ /**
+ * Creates a LocaleService bound to the given UI
+ *
+ * @since 7.1
+ * @param ui
+ * The UI which owns the LocaleService
+ */
+ public LocaleService(UI ui, LocaleServiceState state) {
+ this.ui = ui;
+ this.state = state;
+ }
+
+ /**
+ * Retrieves the UI this service is bound to
+ *
+ * @since 7.1
+ * @return the UI for this service
+ */
+ public UI getUI() {
+ return ui;
+ }
+
+ /**
+ * Adds a locale to be sent to the client (browser) for date and time entry
+ * etc. All locale specific information is derived from server-side
+ * {@link Locale} instances and sent to the client when needed, eliminating
+ * the need to use the {@link Locale} class and all the framework behind it
+ * on the client.
+ *
+ * @param locale
+ * The locale which is required on the client side
+ */
+ public void addLocale(Locale locale) {
+ for (LocaleData data : getState(false).localeData) {
+ if (data.name.equals(locale.toString())) {
+ // Already there
+ return;
+ }
+ }
+
+ getState(true).localeData.add(createLocaleData(locale));
+ }
+
+ /**
+ * Returns the state for this service
+ * <p>
+ * The state is transmitted inside the UI state rather than as an individual
+ * entity.
+ * </p>
+ *
+ * @since 7.1
+ * @param markAsDirty
+ * true to mark the state as dirty
+ * @return a LocaleServiceState object that can be read in any case and
+ * modified if markAsDirty is true
+ */
+ private LocaleServiceState getState(boolean markAsDirty) {
+ if (markAsDirty) {
+ getUI().markAsDirty();
+ }
+
+ return state;
+ }
+
+ /**
+ * Creates a LocaleData instance for transportation to the client
+ *
+ * @since 7.1
+ * @param locale
+ * The locale for which to create a LocaleData object
+ * @return A LocaleData object with information about the given locale
+ */
+ protected LocaleData createLocaleData(Locale locale) {
+ LocaleData localeData = new LocaleData();
+ localeData.name = locale.toString();
+
+ final DateFormatSymbols dfs = new DateFormatSymbols(locale);
+ localeData.shortMonthNames = dfs.getShortMonths();
+ localeData.monthNames = dfs.getMonths();
+ // Client expects 0 based indexing, DateFormatSymbols use 1 based
+ localeData.shortDayNames = new String[7];
+ localeData.dayNames = new String[7];
+ String[] sDayNames = dfs.getShortWeekdays();
+ String[] lDayNames = dfs.getWeekdays();
+ for (int i = 0; i < 7; i++) {
+ localeData.shortDayNames[i] = sDayNames[i + 1];
+ localeData.dayNames[i] = lDayNames[i + 1];
+ }
+
+ /*
+ * First day of week (0 = sunday, 1 = monday)
+ */
+ final java.util.Calendar cal = new GregorianCalendar(locale);
+ localeData.firstDayOfWeek = cal.getFirstDayOfWeek() - 1;
+
+ /*
+ * Date formatting (MM/DD/YYYY etc.)
+ */
+
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(
+ DateFormat.SHORT, DateFormat.SHORT, locale);
+ if (!(dateFormat instanceof SimpleDateFormat)) {
+ getLogger().warning(
+ "Unable to get default date pattern for locale "
+ + locale.toString());
+ dateFormat = new SimpleDateFormat();
+ }
+ final String df = ((SimpleDateFormat) dateFormat).toPattern();
+
+ int timeStart = df.indexOf("H");
+ if (timeStart < 0) {
+ timeStart = df.indexOf("h");
+ }
+ final int ampm_first = df.indexOf("a");
+ // E.g. in Korean locale AM/PM is before h:mm
+ // TODO should take that into consideration on client-side as well,
+ // now always h:mm a
+ if (ampm_first > 0 && ampm_first < timeStart) {
+ timeStart = ampm_first;
+ }
+ // Hebrew locale has time before the date
+ final boolean timeFirst = timeStart == 0;
+ String dateformat;
+ if (timeFirst) {
+ int dateStart = df.indexOf(' ');
+ if (ampm_first > dateStart) {
+ dateStart = df.indexOf(' ', ampm_first);
+ }
+ dateformat = df.substring(dateStart + 1);
+ } else {
+ dateformat = df.substring(0, timeStart - 1);
+ }
+
+ localeData.dateFormat = dateformat.trim();
+
+ /*
+ * Time formatting (24 or 12 hour clock and AM/PM suffixes)
+ */
+ final String timeformat = df.substring(timeStart, df.length());
+ /*
+ * Doesn't return second or milliseconds.
+ *
+ * We use timeformat to determine 12/24-hour clock
+ */
+ final boolean twelve_hour_clock = timeformat.indexOf("a") > -1;
+ // TODO there are other possibilities as well, like 'h' in french
+ // (ignore them, too complicated)
+ final String hour_min_delimiter = timeformat.indexOf(".") > -1 ? "."
+ : ":";
+ // outWriter.print("\"tf\":\"" + timeformat + "\",");
+ localeData.twelveHourClock = twelve_hour_clock;
+ localeData.hourMinuteDelimiter = hour_min_delimiter;
+ if (twelve_hour_clock) {
+ final String[] ampm = dfs.getAmPmStrings();
+ localeData.am = ampm[0];
+ localeData.pm = ampm[1];
+ }
+
+ return localeData;
+ }
+
+ private static Logger getLogger() {
+ return Logger.getLogger(LocaleService.class.getName());
+ }
+
+}
diff --git a/server/src/com/vaadin/server/Page.java b/server/src/com/vaadin/server/Page.java
index d4c16fe7f7..11553527e0 100644
--- a/server/src/com/vaadin/server/Page.java
+++ b/server/src/com/vaadin/server/Page.java
@@ -21,11 +21,10 @@ import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.EventObject;
-import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import com.vaadin.event.EventRouter;
import com.vaadin.shared.ui.BorderStyle;
@@ -307,6 +306,61 @@ public class Page implements Serializable {
}
}
+ private static interface InjectedStyle {
+ public void paint(int id, PaintTarget target) throws PaintException;
+ }
+
+ private static class InjectedStyleString implements InjectedStyle {
+
+ private String css;
+
+ public InjectedStyleString(String css) {
+ this.css = css;
+ }
+
+ @Override
+ public void paint(int id, PaintTarget target) throws PaintException {
+ target.startTag("css-string");
+ target.addAttribute("id", id);
+ target.addText(css);
+ target.endTag("css-string");
+ }
+ }
+
+ private static class InjectedStyleResource implements InjectedStyle {
+
+ private final Resource resource;
+
+ public InjectedStyleResource(Resource resource) {
+ this.resource = resource;
+ }
+
+ @Override
+ public void paint(int id, PaintTarget target) throws PaintException {
+ target.startTag("css-resource");
+ target.addAttribute("id", id);
+ target.addAttribute("url", resource);
+ target.endTag("css-resource");
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ } else if (obj instanceof InjectedStyleResource) {
+ InjectedStyleResource that = (InjectedStyleResource) obj;
+ return resource.equals(that.resource);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return resource.hashCode();
+ }
+ }
+
/**
* Contains dynamically injected styles injected in the HTML document at
* runtime.
@@ -315,16 +369,9 @@ public class Page implements Serializable {
*/
public static class Styles implements Serializable {
- private final Map<Integer, String> stringInjections = new HashMap<Integer, String>();
-
- private final Map<Integer, Resource> resourceInjections = new HashMap<Integer, Resource>();
+ private LinkedHashSet<InjectedStyle> injectedStyles = new LinkedHashSet<InjectedStyle>();
- // The combined injection counter between both string and resource
- // injections. Used as the key for the injection maps
- private int injectionCounter = 0;
-
- // Points to the next injection that has not yet been made into the Page
- private int nextInjectionPosition = 0;
+ private LinkedHashSet<InjectedStyle> pendingInjections = new LinkedHashSet<InjectedStyle>();
private final UI ui;
@@ -344,7 +391,7 @@ public class Page implements Serializable {
"Cannot inject null CSS string");
}
- stringInjections.put(injectionCounter++, css);
+ pendingInjections.add(new InjectedStyleString(css));
ui.markAsDirty();
}
@@ -360,43 +407,33 @@ public class Page implements Serializable {
"Cannot inject null resource");
}
- resourceInjections.put(injectionCounter++, resource);
- ui.markAsDirty();
+ InjectedStyleResource injection = new InjectedStyleResource(
+ resource);
+ if (!injectedStyles.contains(injection)
+ && pendingInjections.add(injection)) {
+ ui.markAsDirty();
+ }
}
private void paint(PaintTarget target) throws PaintException {
// If full repaint repaint all injections
if (target.isFullRepaint()) {
- nextInjectionPosition = 0;
+ injectedStyles.addAll(pendingInjections);
+ pendingInjections = injectedStyles;
+ injectedStyles = new LinkedHashSet<InjectedStyle>();
}
- if (injectionCounter > nextInjectionPosition) {
+ if (!pendingInjections.isEmpty()) {
target.startTag("css-injections");
- while (injectionCounter > nextInjectionPosition) {
-
- String stringInjection = stringInjections
- .get(nextInjectionPosition);
- if (stringInjection != null) {
- target.startTag("css-string");
- target.addAttribute("id", nextInjectionPosition);
- target.addText(stringInjection);
- target.endTag("css-string");
- }
-
- Resource resourceInjection = resourceInjections
- .get(nextInjectionPosition);
- if (resourceInjection != null) {
- target.startTag("css-resource");
- target.addAttribute("id", nextInjectionPosition);
- target.addAttribute("url", resourceInjection);
- target.endTag("css-resource");
- }
-
- nextInjectionPosition++;
+ for (InjectedStyle pending : pendingInjections) {
+ int id = injectedStyles.size();
+ pending.paint(id, target);
+ injectedStyles.add(pending);
}
+ pendingInjections.clear();
target.endTag("css-injections");
}
diff --git a/server/src/com/vaadin/server/RequestHandler.java b/server/src/com/vaadin/server/RequestHandler.java
index 873752c5f2..097a3e034b 100644
--- a/server/src/com/vaadin/server/RequestHandler.java
+++ b/server/src/com/vaadin/server/RequestHandler.java
@@ -37,7 +37,8 @@ public interface RequestHandler extends Serializable {
* using VaadinSession or anything inside the VaadinSession you must ensure
* the session is locked. This can be done by extending
* {@link SynchronizedRequestHandler} or by using
- * {@link VaadinSession#access(Runnable)} or {@link UI#access(Runnable)}.
+ * {@link VaadinSession#accessSynchronously(Runnable)} or
+ * {@link UI#accessSynchronously(Runnable)}.
* </p>
*
* @param session
diff --git a/server/src/com/vaadin/server/UIProvider.java b/server/src/com/vaadin/server/UIProvider.java
index 0305b907e6..3e7c85aea9 100644
--- a/server/src/com/vaadin/server/UIProvider.java
+++ b/server/src/com/vaadin/server/UIProvider.java
@@ -25,6 +25,7 @@ import com.vaadin.annotations.Theme;
import com.vaadin.annotations.Title;
import com.vaadin.annotations.Widgetset;
import com.vaadin.shared.communication.PushMode;
+import com.vaadin.shared.ui.ui.Transport;
import com.vaadin.ui.UI;
public abstract class UIProvider implements Serializable {
@@ -174,4 +175,27 @@ public abstract class UIProvider implements Serializable {
return push.value();
}
}
+
+ /**
+ * Finds the {@link Transport} to use for a specific UI. If no transport is
+ * defined, <code>null</code> is returned.
+ * <p>
+ * The default implementation uses the @{@link Push} annotation if it's
+ * defined for the UI class.
+ *
+ * @param event
+ * the UI create event with information about the UI and the
+ * current request.
+ * @return the transport type to use, or <code>null</code> if the default
+ * transport type should be used
+ */
+ public Transport getPushTransport(UICreateEvent event) {
+ Push push = getAnnotationFor(event.getUIClass(), Push.class);
+ if (push == null) {
+ return null;
+ } else {
+ return push.transport();
+ }
+ }
+
}
diff --git a/server/src/com/vaadin/server/VaadinPortlet.java b/server/src/com/vaadin/server/VaadinPortlet.java
index 327ce78a6c..d86e5e6507 100644
--- a/server/src/com/vaadin/server/VaadinPortlet.java
+++ b/server/src/com/vaadin/server/VaadinPortlet.java
@@ -287,7 +287,6 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
@Override
public void init(PortletConfig config) throws PortletException {
CurrentInstance.clearAll();
- setCurrent(this);
super.init(config);
Properties initParameters = new Properties();
@@ -407,7 +406,6 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
PortletResponse response) throws PortletException, IOException {
CurrentInstance.clearAll();
- setCurrent(this);
try {
getService().handleRequest(createVaadinRequest(request),
createVaadinResponse(response));
@@ -495,36 +493,23 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
* portlet is defined (see {@link InheritableThreadLocal}). In other cases,
* (e.g. from background threads started in some other way), the current
* portlet is not automatically defined.
+ * <p>
+ * The current portlet is derived from the current service using
+ * {@link VaadinService#getCurrent()}
*
* @return the current vaadin portlet instance if available, otherwise
* <code>null</code>
*
- * @see #setCurrent(VaadinPortlet)
- *
* @since 7.0
*/
public static VaadinPortlet getCurrent() {
- return CurrentInstance.get(VaadinPortlet.class);
- }
-
- /**
- * Sets the current Vaadin portlet. This method is used by the framework to
- * set the current portlet whenever a new request is processed and it is
- * cleared when the request has been processed.
- * <p>
- * The application developer can also use this method to define the current
- * portlet outside the normal request handling, e.g. when initiating custom
- * background threads.
- * </p>
- *
- * @param portlet
- * the Vaadin portlet to register as the current portlet
- *
- * @see #getCurrent()
- * @see InheritableThreadLocal
- */
- public static void setCurrent(VaadinPortlet portlet) {
- CurrentInstance.setInheritable(VaadinPortlet.class, portlet);
+ VaadinService vaadinService = CurrentInstance.get(VaadinService.class);
+ if (vaadinService instanceof VaadinPortletService) {
+ VaadinPortletService vps = (VaadinPortletService) vaadinService;
+ return vps.getPortlet();
+ } else {
+ return null;
+ }
}
}
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java
index af0c280c19..a040c72175 100644
--- a/server/src/com/vaadin/server/VaadinService.java
+++ b/server/src/com/vaadin/server/VaadinService.java
@@ -33,6 +33,9 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
@@ -47,6 +50,7 @@ import org.json.JSONObject;
import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.event.EventRouter;
+import com.vaadin.server.VaadinSession.FutureAccess;
import com.vaadin.server.communication.FileUploadHandler;
import com.vaadin.server.communication.HeartbeatHandler;
import com.vaadin.server.communication.PublishedFileHandler;
@@ -110,6 +114,11 @@ public abstract class VaadinService implements Serializable {
private boolean pushWarningEmitted = false;
/**
+ * Has {@link #init()} been run?
+ */
+ private boolean initialized = false;
+
+ /**
* Creates a new vaadin service based on a deployment configuration
*
* @param deploymentConfiguration
@@ -148,6 +157,8 @@ public abstract class VaadinService implements Serializable {
List<RequestHandler> handlers = createRequestHandlers();
Collections.reverse(handlers);
requestHandlers = Collections.unmodifiableCollection(handlers);
+
+ initialized = true;
}
/**
@@ -407,12 +418,12 @@ public abstract class VaadinService implements Serializable {
*/
public void fireSessionDestroy(VaadinSession vaadinSession) {
final VaadinSession session = vaadinSession;
- session.access(new Runnable() {
+ session.accessSynchronously(new Runnable() {
@Override
public void run() {
ArrayList<UI> uis = new ArrayList<UI>(session.getUIs());
for (final UI ui : uis) {
- ui.access(new Runnable() {
+ ui.accessSynchronously(new Runnable() {
@Override
public void run() {
/*
@@ -1087,7 +1098,7 @@ public abstract class VaadinService implements Serializable {
private void removeClosedUIs(final VaadinSession session) {
ArrayList<UI> uis = new ArrayList<UI>(session.getUIs());
for (final UI ui : uis) {
- ui.access(new Runnable() {
+ ui.accessSynchronously(new Runnable() {
@Override
public void run() {
if (ui.isClosing()) {
@@ -1224,6 +1235,10 @@ public abstract class VaadinService implements Serializable {
* The response
*/
public void requestStart(VaadinRequest request, VaadinResponse response) {
+ if (!initialized) {
+ throw new IllegalStateException(
+ "Can not process requests before init() has been called");
+ }
setCurrentInstances(request, response);
request.setAttribute(REQUEST_START_TIME_ATTRIBUTE, System.nanoTime());
}
@@ -1245,7 +1260,7 @@ public abstract class VaadinService implements Serializable {
if (session != null) {
final VaadinSession finalSession = session;
- session.access(new Runnable() {
+ session.accessSynchronously(new Runnable() {
@Override
public void run() {
cleanupSession(finalSession);
@@ -1254,7 +1269,7 @@ public abstract class VaadinService implements Serializable {
final long duration = (System.nanoTime() - (Long) request
.getAttribute(REQUEST_START_TIME_ATTRIBUTE)) / 1000000;
- session.access(new Runnable() {
+ session.accessSynchronously(new Runnable() {
@Override
public void run() {
finalSession.setLastRequestDuration(duration);
@@ -1542,8 +1557,9 @@ public abstract class VaadinService implements Serializable {
/**
* Checks that another {@link VaadinSession} instance is not locked. This is
- * internally used by {@link VaadinSession#access(Runnable)} and
- * {@link UI#access(Runnable)} to help avoid causing deadlocks.
+ * internally used by {@link VaadinSession#accessSynchronously(Runnable)}
+ * and {@link UI#accessSynchronously(Runnable)} to help avoid causing
+ * deadlocks.
*
* @since 7.1
* @param session
@@ -1597,4 +1613,88 @@ public abstract class VaadinService implements Serializable {
return true;
}
+ /**
+ * Implementation for {@link VaadinSession#access(Runnable)}. This method is
+ * implemented here instead of in {@link VaadinSession} to enable overriding
+ * the implementation without using a custom subclass of VaadinSession.
+ *
+ * @since 7.1
+ * @see VaadinSession#access(Runnable)
+ *
+ * @param session
+ * the vaadin session to access
+ * @param runnable
+ * the runnable to run with the session locked
+ *
+ * @return a future that can be used to check for task completion and to
+ * cancel the task
+ */
+ public Future<Void> accessSession(VaadinSession session, Runnable runnable) {
+ FutureAccess future = new FutureAccess(session, runnable);
+ session.getPendingAccessQueue().add(future);
+
+ /*
+ * If no thread is currently holding the lock, pending changes for UIs
+ * with automatic push would not be processed and pushed until the next
+ * time there is a request or someone does an explicit push call.
+ *
+ * To remedy this, we try to get the lock at this point. If the lock is
+ * currently held by another thread, we just back out as the queue will
+ * get purged once it is released. If the lock is held by the current
+ * thread, we just release it knowing that the queue gets purged once
+ * the lock is ultimately released. If the lock is not held by any
+ * thread and we acquire it, we just release it again to purge the queue
+ * right away.
+ */
+ try {
+ // tryLock() would be shorter, but it does not guarantee fairness
+ if (session.getLockInstance().tryLock(0, TimeUnit.SECONDS)) {
+ // unlock triggers runPendingAccessTasks
+ session.unlock();
+ }
+ } catch (InterruptedException e) {
+ // Just ignore
+ }
+
+ return future;
+ }
+
+ /**
+ * Purges the queue of pending access invocations enqueued with
+ * {@link VaadinSession#access(Runnable)}.
+ * <p>
+ * This method is automatically run by the framework at appropriate
+ * situations and is not intended to be used by application developers.
+ *
+ * @param session
+ * the vaadin session to purge the queue for
+ * @since 7.1
+ */
+ public void runPendingAccessTasks(VaadinSession session) {
+ assert session.hasLock();
+
+ if (session.getPendingAccessQueue().isEmpty()) {
+ return;
+ }
+
+ Map<Class<?>, CurrentInstance> oldInstances = CurrentInstance
+ .getInstances(false);
+
+ FutureAccess pendingAccess;
+ try {
+ while ((pendingAccess = session.getPendingAccessQueue().poll()) != null) {
+ if (!pendingAccess.isCancelled()) {
+ CurrentInstance.clearAll();
+ CurrentInstance.restoreInstances(pendingAccess
+ .getCurrentInstances());
+ CurrentInstance.setCurrent(session);
+ pendingAccess.run();
+ }
+ }
+ } finally {
+ CurrentInstance.clearAll();
+ CurrentInstance.restoreInstances(oldInstances);
+ }
+ }
+
}
diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java
index de074941c1..05e3335c00 100644
--- a/server/src/com/vaadin/server/VaadinServlet.java
+++ b/server/src/com/vaadin/server/VaadinServlet.java
@@ -21,6 +21,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
@@ -38,6 +39,8 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import com.vaadin.annotations.VaadinServletConfiguration;
+import com.vaadin.annotations.VaadinServletConfiguration.InitParameterName;
import com.vaadin.sass.internal.ScssStylesheet;
import com.vaadin.server.communication.ServletUIInitHandler;
import com.vaadin.shared.JsonConstants;
@@ -63,10 +66,11 @@ public class VaadinServlet extends HttpServlet implements Constants {
public void init(javax.servlet.ServletConfig servletConfig)
throws ServletException {
CurrentInstance.clearAll();
- setCurrent(this);
super.init(servletConfig);
Properties initParameters = new Properties();
+ readConfigurationAnnotation(initParameters);
+
// Read default parameters from server.xml
final ServletContext context = servletConfig.getServletContext();
for (final Enumeration<String> e = context.getInitParameterNames(); e
@@ -97,6 +101,39 @@ public class VaadinServlet extends HttpServlet implements Constants {
CurrentInstance.clearAll();
}
+ private void readConfigurationAnnotation(Properties initParameters)
+ throws ServletException {
+ VaadinServletConfiguration configAnnotation = UIProvider
+ .getAnnotationFor(getClass(), VaadinServletConfiguration.class);
+ if (configAnnotation != null) {
+ Method[] methods = VaadinServletConfiguration.class
+ .getDeclaredMethods();
+ for (Method method : methods) {
+ InitParameterName name = method
+ .getAnnotation(InitParameterName.class);
+ assert name != null : "All methods declared in VaadinServletConfiguration should have a @InitParameterName annotation";
+
+ try {
+ Object value = method.invoke(configAnnotation);
+
+ String stringValue;
+ if (value instanceof Class<?>) {
+ stringValue = ((Class<?>) value).getName();
+ } else {
+ stringValue = value.toString();
+ }
+
+ initParameters.setProperty(name.value(), stringValue);
+ } catch (Exception e) {
+ // This should never happen
+ throw new ServletException(
+ "Could not read @VaadinServletConfiguration value "
+ + method.getName(), e);
+ }
+ }
+ }
+ }
+
protected void servletInitialized() throws ServletException {
// Empty by default
}
@@ -108,36 +145,23 @@ public class VaadinServlet extends HttpServlet implements Constants {
* servlet is defined (see {@link InheritableThreadLocal}). In other cases,
* (e.g. from background threads started in some other way), the current
* servlet is not automatically defined.
+ * <p>
+ * The current servlet is derived from the current service using
+ * {@link VaadinService#getCurrent()}
*
* @return the current Vaadin servlet instance if available, otherwise
* <code>null</code>
*
- * @see #setCurrent(VaadinServlet)
- *
* @since 7.0
*/
public static VaadinServlet getCurrent() {
- return CurrentInstance.get(VaadinServlet.class);
- }
-
- /**
- * Sets the current Vaadin servlet. This method is used by the framework to
- * set the current servlet whenever a new request is processed and it is
- * cleared when the request has been processed.
- * <p>
- * The application developer can also use this method to define the current
- * servlet outside the normal request handling, e.g. when initiating custom
- * background threads.
- * </p>
- *
- * @param servlet
- * the Vaadin servlet to register as the current servlet
- *
- * @see #getCurrent()
- * @see InheritableThreadLocal
- */
- public static void setCurrent(VaadinServlet servlet) {
- CurrentInstance.setInheritable(VaadinServlet.class, servlet);
+ VaadinService vaadinService = CurrentInstance.get(VaadinService.class);
+ if (vaadinService instanceof VaadinServletService) {
+ VaadinServletService vss = (VaadinServletService) vaadinService;
+ return vss.getServlet();
+ } else {
+ return null;
+ }
}
protected DeploymentConfiguration createDeploymentConfiguration(
@@ -179,7 +203,6 @@ public class VaadinServlet extends HttpServlet implements Constants {
return;
}
CurrentInstance.clearAll();
- setCurrent(this);
VaadinServletRequest vaadinRequest = createVaadinRequest(request);
VaadinServletResponse vaadinResponse = createVaadinResponse(response);
@@ -188,8 +211,14 @@ public class VaadinServlet extends HttpServlet implements Constants {
}
if (isStaticResourceRequest(request)) {
- serveStaticResources(request, response);
- return;
+ // Define current servlet and service, but no request and response
+ getService().setCurrentInstances(null, null);
+ try {
+ serveStaticResources(request, response);
+ return;
+ } finally {
+ CurrentInstance.clearAll();
+ }
}
try {
getService().handleRequest(vaadinRequest, vaadinResponse);
diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java
index 317ea6cf7b..e0a5b51baa 100644
--- a/server/src/com/vaadin/server/VaadinSession.java
+++ b/server/src/com/vaadin/server/VaadinSession.java
@@ -25,7 +25,12 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Queue;
import java.util.UUID;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
@@ -63,6 +68,68 @@ import com.vaadin.util.ReflectTools;
public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
+ * Encapsulates a {@link Runnable} submitted using
+ * {@link VaadinSession#access(Runnable)}. This class is used internally by
+ * the framework and is not intended to be directly used by application
+ * developers.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+ public static class FutureAccess extends FutureTask<Void> {
+ /**
+ * Snapshot of all non-inheritable current instances at the time this
+ * object was created.
+ */
+ private final Map<Class<?>, CurrentInstance> instances = CurrentInstance
+ .getInstances(true);
+ private final VaadinSession session;
+
+ /**
+ * Creates an instance for the given runnable
+ *
+ * @param session
+ * the session to which the task belongs
+ *
+ * @param runnable
+ * the runnable to run when this task is purged from the
+ * queue
+ */
+ public FutureAccess(VaadinSession session, Runnable runnable) {
+ super(runnable, null);
+ this.session = session;
+ }
+
+ @Override
+ public Void get() throws InterruptedException, ExecutionException {
+ /*
+ * Help the developer avoid programming patterns that cause
+ * deadlocks unless implemented very carefully. get(long, TimeUnit)
+ * does not have the same detection since a sensible timeout should
+ * avoid completely locking up the application.
+ *
+ * Even though no deadlock could occur after the runnable has been
+ * run, the check is always done as the deterministic behavior makes
+ * it easier to detect potential problems.
+ */
+ VaadinService.verifyNoOtherSessionLocked(session);
+ return super.get();
+ }
+
+ /**
+ * Gets the current instance values that should be used when running
+ * this task.
+ *
+ * @see CurrentInstance#restoreInstances(Map)
+ *
+ * @return a map of current instances.
+ */
+ public Map<Class<?>, CurrentInstance> getCurrentInstances() {
+ return instances;
+ }
+ }
+
+ /**
* The name of the parameter that is by default used in e.g. web.xml to
* define the name of the default {@link UI} class.
*/
@@ -130,6 +197,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
private transient Lock lock;
+ /*
+ * Pending tasks can't be serialized and the queue should be empty when the
+ * session is serialized as long as it doesn't happen while some other
+ * thread has the lock.
+ */
+ private transient final ConcurrentLinkedQueue<FutureAccess> pendingAccessQueue = new ConcurrentLinkedQueue<FutureAccess>();
+
/**
* Create a new service session tied to a Vaadin service
*
@@ -189,9 +263,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
/**
* Get the web browser associated with this session.
*
- * @return
- * @deprecated As of 7.0. Will likely change or be removed in a future
- * version
+ * @return the web browser object
+ *
+ * @deprecated As of 7.0, use {@link Page#getWebBrowser()} instead.
*/
@Deprecated
public WebBrowser getBrowser() {
@@ -820,11 +894,15 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
public void unlock() {
assert hasLock();
try {
+ /*
+ * Run pending tasks and push if the reentrant lock will actually be
+ * released by this unlock() invocation.
+ */
if (((ReentrantLock) getLockInstance()).getHoldCount() == 1) {
- // Only push if the reentrant lock will actually be released by
- // this unlock() invocation.
+ getService().runPendingAccessTasks(this);
+
for (UI ui : getUIs()) {
- if (ui.getPushMode() == PushMode.AUTOMATIC) {
+ if (ui.getPushConfiguration().getPushMode() == PushMode.AUTOMATIC) {
ui.push();
}
}
@@ -1063,23 +1141,26 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
}
/**
- * Provides exclusive access to this session from outside a request handling
- * thread.
+ * Locks this session and runs the provided Runnable right away.
* <p>
- * The given runnable is executed while holding the session lock to ensure
- * exclusive access to this session. The session and related thread locals
- * are set properly before executing the runnable.
- * </p>
- * <p>
- * RPC handlers for components inside this session do not need this method
- * as the session is automatically locked by the framework during request
- * handling.
+ * It is generally recommended to use {@link #access(Runnable)} instead of
+ * this method for accessing a session from a different thread as
+ * {@link #access(Runnable)} can be used while holding the lock of another
+ * session. To avoid causing deadlocks, this methods throws an exception if
+ * it is detected than another session is also locked by the current thread.
* </p>
* <p>
- * Note that calling this method while another session is locked by the
- * current thread will cause an exception. This is to prevent deadlock
- * situations when two threads have locked one session each and are both
- * waiting for the lock for the other session.
+ * This method behaves differently than {@link #access(Runnable)} in some
+ * situations:
+ * <ul>
+ * <li>If the current thread is currently holding the lock of this session,
+ * {@link #accessSynchronously(Runnable)} runs the task right away whereas
+ * {@link #access(Runnable)} defers the task to a later point in time.</li>
+ * <li>If some other thread is currently holding the lock for this session,
+ * {@link #accessSynchronously(Runnable)} blocks while waiting for the lock
+ * to be available whereas {@link #access(Runnable)} defers the task to a
+ * later point in time.</li>
+ * </ul>
* </p>
*
* @param runnable
@@ -1088,35 +1169,87 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* @throws IllegalStateException
* if the current thread holds the lock for another session
*
+ * @since 7.1
*
* @see #lock()
* @see #getCurrent()
- * @see UI#access(Runnable)
+ * @see #access(Runnable)
+ * @see UI#accessSynchronously(Runnable)
*/
- public void access(Runnable runnable) {
+ public void accessSynchronously(Runnable runnable) {
VaadinService.verifyNoOtherSessionLocked(this);
Map<Class<?>, CurrentInstance> old = null;
lock();
try {
- old = CurrentInstance.setThreadLocals(this);
+ old = CurrentInstance.setCurrent(this);
runnable.run();
} finally {
unlock();
if (old != null) {
- CurrentInstance.restoreThreadLocals(old);
+ CurrentInstance.restoreInstances(old);
}
}
}
/**
- * @deprecated As of 7.1.0.beta1, use {@link #access(Runnable)} instead.
- * This method will be removed before the final 7.1.0 release.
+ * Provides exclusive access to this session from outside a request handling
+ * thread.
+ * <p>
+ * The given runnable is executed while holding the session lock to ensure
+ * exclusive access to this session. If this session is not locked, the lock
+ * will be acquired and the runnable is run right away. If this session is
+ * currently locked, the runnable will be run before that lock is released.
+ * </p>
+ * <p>
+ * RPC handlers for components inside this session do not need to use this
+ * method as the session is automatically locked by the framework during RPC
+ * handling.
+ * </p>
+ * <p>
+ * Please note that the runnable might be invoked on a different thread or
+ * later on the current thread, which means that custom thread locals might
+ * not have the expected values when the runnable is executed. Inheritable
+ * values in {@link CurrentInstance} will have the same values as when this
+ * method was invoked. {@link VaadinSession#getCurrent()} and
+ * {@link VaadinService#getCurrent()} are set according to this session
+ * before executing the runnable. Non-inheritable CurrentInstance values
+ * including {@link VaadinService#getCurrentRequest()} and
+ * {@link VaadinService#getCurrentResponse()} will not be defined.
+ * </p>
+ * <p>
+ * The returned future can be used to check for task completion and to
+ * cancel the task. To help avoiding deadlocks, {@link Future#get()} throws
+ * an exception if it is detected that the current thread holds the lock for
+ * some other session.
+ * </p>
+ *
+ * @see #lock()
+ * @see #getCurrent()
+ * @see #accessSynchronously(Runnable)
+ * @see UI#access(Runnable)
+ *
+ * @since 7.1
+ *
+ * @param runnable
+ * the runnable which accesses the session
+ * @return a future that can be used to check for task completion and to
+ * cancel the task
*/
- @Deprecated
- public void runSafely(Runnable runnable) {
- access(runnable);
+ public Future<Void> access(Runnable runnable) {
+ return getService().accessSession(this, runnable);
+ }
+
+ /**
+ * Gets the queue of tasks submitted using {@link #access(Runnable)}.
+ *
+ * @since 7.1
+ *
+ * @return the pending access queue
+ */
+ public Queue<FutureAccess> getPendingAccessQueue() {
+ return pendingAccessQueue;
}
/**
diff --git a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
index 0bba65ff1d..9e57ccb45d 100644
--- a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
+++ b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
@@ -32,7 +32,7 @@ import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResource.TRANSPORT;
import org.json.JSONException;
-import com.vaadin.shared.ApplicationConstants;
+import com.vaadin.shared.communication.PushConstants;
import com.vaadin.ui.UI;
/**
@@ -42,21 +42,22 @@ import com.vaadin.ui.UI;
* @author Vaadin Ltd
* @since 7.1
*/
-public class AtmospherePushConnection implements Serializable, PushConnection {
+public class AtmospherePushConnection implements PushConnection {
/**
* Represents a message that can arrive as multiple fragments.
*/
- protected static class FragmentedMessage {
+ protected static class FragmentedMessage implements Serializable {
private final StringBuilder message = new StringBuilder();
private final int messageLength;
public FragmentedMessage(Reader reader) throws IOException {
- // Messages are prefixed by the total message length plus '|'
+ // Messages are prefixed by the total message length plus a
+ // delimiter
String length = "";
int c;
while ((c = reader.read()) != -1
- && c != ApplicationConstants.WEBSOCKET_MESSAGE_DELIMITER) {
+ && c != PushConstants.MESSAGE_DELIMITER) {
length += (char) c;
}
try {
@@ -76,7 +77,7 @@ public class AtmospherePushConnection implements Serializable, PushConnection {
* @throws IOException
*/
public boolean append(Reader reader) throws IOException {
- char[] buffer = new char[ApplicationConstants.WEBSOCKET_BUFFER_SIZE];
+ char[] buffer = new char[PushConstants.WEBSOCKET_BUFFER_SIZE];
int read;
while ((read = reader.read(buffer)) != -1) {
message.append(buffer, 0, read);
@@ -122,7 +123,7 @@ public class AtmospherePushConnection implements Serializable, PushConnection {
protected void push(boolean async) throws IOException {
Writer writer = new StringWriter();
try {
- new UidlWriter().write(getUI(), writer, false, false, async);
+ new UidlWriter().write(getUI(), writer, false, async);
} catch (JSONException e) {
throw new IOException("Error writing UIDL", e);
}
diff --git a/server/src/com/vaadin/server/communication/FileUploadHandler.java b/server/src/com/vaadin/server/communication/FileUploadHandler.java
index e875a4e861..e9569d45a1 100644
--- a/server/src/com/vaadin/server/communication/FileUploadHandler.java
+++ b/server/src/com/vaadin/server/communication/FileUploadHandler.java
@@ -632,7 +632,7 @@ public class FileUploadHandler implements RequestHandler {
private void cleanStreamVariable(VaadinSession session,
final ClientConnector owner, final String variableName) {
- session.access(new Runnable() {
+ session.accessSynchronously(new Runnable() {
@Override
public void run() {
owner.getUI()
diff --git a/server/src/com/vaadin/server/communication/LocaleWriter.java b/server/src/com/vaadin/server/communication/LocaleWriter.java
deleted file mode 100644
index c05649da19..0000000000
--- a/server/src/com/vaadin/server/communication/LocaleWriter.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright 2000-2013 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.vaadin.server.communication;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.Writer;
-import java.text.DateFormat;
-import java.text.DateFormatSymbols;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.List;
-import java.util.Locale;
-import java.util.logging.Logger;
-
-/**
- * Serializes locale information to JSON.
- *
- * @author Vaadin Ltd
- * @since 7.1
- * @deprecated See <a href="http://dev.vaadin.com/ticket/11378">ticket
- * #11378</a>.
- */
-@Deprecated
-public class LocaleWriter implements Serializable {
-
- /**
- * Writes a JSON object containing localized strings of the given locales.
- *
- * @param locales
- * The list of {@link Locale}s to write.
- * @param writer
- * The {@link Writer} used to write the JSON.
- * @throws IOException
- * If the serialization fails.
- *
- */
- public void write(List<String> locales, Writer writer) throws IOException {
-
- // Send locale informations to client
- writer.write("[");
- // TODO locales are currently sent on each request; this will be fixed
- // by implementing #11378.
- for (int pendingLocalesIndex = 0; pendingLocalesIndex < locales.size(); pendingLocalesIndex++) {
-
- final Locale l = generateLocale(locales.get(pendingLocalesIndex));
- // Locale name
- writer.write("{\"name\":\"" + l.toString() + "\",");
-
- /*
- * Month names (both short and full)
- */
- final DateFormatSymbols dfs = new DateFormatSymbols(l);
- final String[] short_months = dfs.getShortMonths();
- final String[] months = dfs.getMonths();
- writer.write("\"smn\":[\""
- + // ShortMonthNames
- short_months[0] + "\",\"" + short_months[1] + "\",\""
- + short_months[2] + "\",\"" + short_months[3] + "\",\""
- + short_months[4] + "\",\"" + short_months[5] + "\",\""
- + short_months[6] + "\",\"" + short_months[7] + "\",\""
- + short_months[8] + "\",\"" + short_months[9] + "\",\""
- + short_months[10] + "\",\"" + short_months[11] + "\""
- + "],");
- writer.write("\"mn\":[\""
- + // MonthNames
- months[0] + "\",\"" + months[1] + "\",\"" + months[2]
- + "\",\"" + months[3] + "\",\"" + months[4] + "\",\""
- + months[5] + "\",\"" + months[6] + "\",\"" + months[7]
- + "\",\"" + months[8] + "\",\"" + months[9] + "\",\""
- + months[10] + "\",\"" + months[11] + "\"" + "],");
-
- /*
- * Weekday names (both short and full)
- */
- final String[] short_days = dfs.getShortWeekdays();
- final String[] days = dfs.getWeekdays();
- writer.write("\"sdn\":[\""
- + // ShortDayNames
- short_days[1] + "\",\"" + short_days[2] + "\",\""
- + short_days[3] + "\",\"" + short_days[4] + "\",\""
- + short_days[5] + "\",\"" + short_days[6] + "\",\""
- + short_days[7] + "\"" + "],");
- writer.write("\"dn\":[\""
- + // DayNames
- days[1] + "\",\"" + days[2] + "\",\"" + days[3] + "\",\""
- + days[4] + "\",\"" + days[5] + "\",\"" + days[6] + "\",\""
- + days[7] + "\"" + "],");
-
- /*
- * First day of week (0 = sunday, 1 = monday)
- */
- final Calendar cal = new GregorianCalendar(l);
- writer.write("\"fdow\":" + (cal.getFirstDayOfWeek() - 1) + ",");
-
- /*
- * Date formatting (MM/DD/YYYY etc.)
- */
-
- DateFormat dateFormat = DateFormat.getDateTimeInstance(
- DateFormat.SHORT, DateFormat.SHORT, l);
- if (!(dateFormat instanceof SimpleDateFormat)) {
- getLogger().warning(
- "Unable to get default date pattern for locale "
- + l.toString());
- dateFormat = new SimpleDateFormat();
- }
- final String df = ((SimpleDateFormat) dateFormat).toPattern();
-
- int timeStart = df.indexOf("H");
- if (timeStart < 0) {
- timeStart = df.indexOf("h");
- }
- final int ampm_first = df.indexOf("a");
- // E.g. in Korean locale AM/PM is before h:mm
- // TODO should take that into consideration on client-side as well,
- // now always h:mm a
- if (ampm_first > 0 && ampm_first < timeStart) {
- timeStart = ampm_first;
- }
- // Hebrew locale has time before the date
- final boolean timeFirst = timeStart == 0;
- String dateformat;
- if (timeFirst) {
- int dateStart = df.indexOf(' ');
- if (ampm_first > dateStart) {
- dateStart = df.indexOf(' ', ampm_first);
- }
- dateformat = df.substring(dateStart + 1);
- } else {
- dateformat = df.substring(0, timeStart - 1);
- }
-
- writer.write("\"df\":\"" + dateformat.trim() + "\",");
-
- /*
- * Time formatting (24 or 12 hour clock and AM/PM suffixes)
- */
- final String timeformat = df.substring(timeStart, df.length());
- /*
- * Doesn't return second or milliseconds.
- *
- * We use timeformat to determine 12/24-hour clock
- */
- final boolean twelve_hour_clock = timeformat.indexOf("a") > -1;
- // TODO there are other possibilities as well, like 'h' in french
- // (ignore them, too complicated)
- final String hour_min_delimiter = timeformat.indexOf(".") > -1 ? "."
- : ":";
- // outWriter.print("\"tf\":\"" + timeformat + "\",");
- writer.write("\"thc\":" + twelve_hour_clock + ",");
- writer.write("\"hmd\":\"" + hour_min_delimiter + "\"");
- if (twelve_hour_clock) {
- final String[] ampm = dfs.getAmPmStrings();
- writer.write(",\"ampm\":[\"" + ampm[0] + "\",\"" + ampm[1]
- + "\"]");
- }
- writer.write("}");
- if (pendingLocalesIndex < locales.size() - 1) {
- writer.write(",");
- }
- }
- writer.write("]"); // Close locales
- }
-
- /**
- * Constructs a {@link Locale} instance to be sent to the client based on a
- * short locale description string.
- *
- * @see #requireLocale(String)
- *
- * @param value
- * @return
- */
- private Locale generateLocale(String value) {
- final String[] temp = value.split("_");
- if (temp.length == 1) {
- return new Locale(temp[0]);
- } else if (temp.length == 2) {
- return new Locale(temp[0], temp[1]);
- } else {
- return new Locale(temp[0], temp[1], temp[2]);
- }
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(LocaleWriter.class.getName());
- }
-}
diff --git a/server/src/com/vaadin/server/communication/MetadataWriter.java b/server/src/com/vaadin/server/communication/MetadataWriter.java
index 1a3f0e946a..5ad7186c24 100644
--- a/server/src/com/vaadin/server/communication/MetadataWriter.java
+++ b/server/src/com/vaadin/server/communication/MetadataWriter.java
@@ -17,17 +17,11 @@
package com.vaadin.server.communication;
import java.io.IOException;
-import java.io.PrintWriter;
import java.io.Serializable;
import java.io.Writer;
-import java.util.List;
-import com.vaadin.server.ClientConnector;
-import com.vaadin.server.ComponentSizeValidator;
-import com.vaadin.server.ComponentSizeValidator.InvalidLayout;
import com.vaadin.server.SystemMessages;
import com.vaadin.ui.UI;
-import com.vaadin.ui.Window;
/**
* Serializes miscellaneous metadata to JSON.
@@ -54,9 +48,6 @@ public class MetadataWriter implements Serializable {
* @param async
* True if this message is sent by the server asynchronously,
* false if it is a response to a client message.
- * @param hilightedConnector
- * The connector that should be highlighted on the client or null
- * if none.
* @param messages
* a {@link SystemMessages} containing client-side error
* messages.
@@ -64,27 +55,8 @@ public class MetadataWriter implements Serializable {
* If the serialization fails.
*
*/
- public void write(UI ui, Writer writer, boolean repaintAll,
- boolean analyzeLayouts, boolean async,
- ClientConnector hilightedConnector, SystemMessages messages)
- throws IOException {
-
- List<InvalidLayout> invalidComponentRelativeSizes = null;
-
- if (analyzeLayouts) {
- invalidComponentRelativeSizes = ComponentSizeValidator
- .validateComponentRelativeSizes(ui.getContent(), null, null);
-
- // Also check any existing subwindows
- if (ui.getWindows() != null) {
- for (Window subWindow : ui.getWindows()) {
- invalidComponentRelativeSizes = ComponentSizeValidator
- .validateComponentRelativeSizes(
- subWindow.getContent(),
- invalidComponentRelativeSizes, null);
- }
- }
- }
+ public void write(UI ui, Writer writer, boolean repaintAll, boolean async,
+ SystemMessages messages) throws IOException {
writer.write("{");
@@ -92,28 +64,6 @@ public class MetadataWriter implements Serializable {
if (repaintAll) {
metaOpen = true;
writer.write("\"repaintAll\":true");
- if (analyzeLayouts) {
- writer.write(", \"invalidLayouts\":");
- writer.write("[");
- if (invalidComponentRelativeSizes != null) {
- boolean first = true;
- for (InvalidLayout invalidLayout : invalidComponentRelativeSizes) {
- if (!first) {
- writer.write(",");
- } else {
- first = false;
- }
- invalidLayout.reportErrors(new PrintWriter(writer),
- System.err);
- }
- }
- writer.write("]");
- }
- if (hilightedConnector != null) {
- writer.write(", \"hl\":\"");
- writer.write(hilightedConnector.getConnectorId());
- writer.write("\"");
- }
}
if (async) {
diff --git a/server/src/com/vaadin/server/communication/PushConnection.java b/server/src/com/vaadin/server/communication/PushConnection.java
index 4e043f565f..bb88998402 100644
--- a/server/src/com/vaadin/server/communication/PushConnection.java
+++ b/server/src/com/vaadin/server/communication/PushConnection.java
@@ -16,6 +16,8 @@
package com.vaadin.server.communication;
+import java.io.Serializable;
+
import com.vaadin.ui.UI;
/**
@@ -25,7 +27,7 @@ import com.vaadin.ui.UI;
* @author Vaadin Ltd
* @since 7.1
*/
-public interface PushConnection {
+public interface PushConnection extends Serializable {
/**
* Pushes pending state changes and client RPC calls to the client. It is
diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/com/vaadin/server/communication/PushHandler.java
index e740db410d..7efcb8fd8c 100644
--- a/server/src/com/vaadin/server/communication/PushHandler.java
+++ b/server/src/com/vaadin/server/communication/PushHandler.java
@@ -84,6 +84,13 @@ public class PushHandler implements AtmosphereHandler {
if (browser.isIE() && browser.getBrowserMajorVersion() == 8) {
resource.padding(LONG_PADDING);
}
+
+ // Must ensure that the streaming response contains
+ // "Connection: close", otherwise iOS 6 will wait for the
+ // response to this request before sending another request to
+ // the same server (as it will apparently try to reuse the same
+ // connection)
+ resource.getResponse().addHeader("Connection", "close");
}
String requestToken = resource.getRequest().getParameter(
@@ -164,7 +171,7 @@ public class PushHandler implements AtmosphereHandler {
PushEventCallback disconnectCallback = new PushEventCallback() {
@Override
public void run(AtmosphereResource resource, UI ui) throws IOException {
- PushMode pushMode = ui.getPushMode();
+ PushMode pushMode = ui.getPushConfiguration().getPushMode();
AtmospherePushConnection pushConnection = getConnectionForUI(ui);
String id = resource.uuid();
@@ -331,9 +338,9 @@ public class PushHandler implements AtmosphereHandler {
writer.write(event.getMessage().toString());
switch (resource.transport()) {
- case SSE:
case WEBSOCKET:
break;
+ case SSE:
case STREAMING:
writer.flush();
break;
diff --git a/server/src/com/vaadin/server/communication/PushRequestHandler.java b/server/src/com/vaadin/server/communication/PushRequestHandler.java
index 8360e08af9..8d0da24896 100644
--- a/server/src/com/vaadin/server/communication/PushRequestHandler.java
+++ b/server/src/com/vaadin/server/communication/PushRequestHandler.java
@@ -23,6 +23,7 @@ import javax.servlet.ServletException;
import org.atmosphere.client.TrackMessageSizeInterceptor;
import org.atmosphere.cpr.ApplicationConfig;
import org.atmosphere.cpr.AtmosphereFramework;
+import org.atmosphere.cpr.AtmosphereInterceptor;
import org.atmosphere.cpr.AtmosphereRequest;
import org.atmosphere.cpr.AtmosphereResponse;
@@ -36,7 +37,7 @@ import com.vaadin.server.VaadinServletRequest;
import com.vaadin.server.VaadinServletResponse;
import com.vaadin.server.VaadinServletService;
import com.vaadin.server.VaadinSession;
-import com.vaadin.shared.ApplicationConstants;
+import com.vaadin.shared.communication.PushConstants;
/**
* Handles requests to open a push (bidirectional) communication channel between
@@ -55,15 +56,22 @@ public class PushRequestHandler implements RequestHandler,
public PushRequestHandler(VaadinServletService service)
throws ServiceException {
- atmosphere = new AtmosphereFramework();
+ atmosphere = new AtmosphereFramework() {
+ @Override
+ protected void analytics() {
+ // Overridden to disable version number check
+ }
+ };
pushHandler = new PushHandler(service);
atmosphere.addAtmosphereHandler("/*", pushHandler);
atmosphere.addInitParameter(ApplicationConfig.PROPERTY_SESSION_SUPPORT,
"true");
+ atmosphere.addInitParameter(ApplicationConfig.MESSAGE_DELIMITER,
+ String.valueOf(PushConstants.MESSAGE_DELIMITER));
final String bufferSize = String
- .valueOf(ApplicationConstants.WEBSOCKET_BUFFER_SIZE);
+ .valueOf(PushConstants.WEBSOCKET_BUFFER_SIZE);
atmosphere.addInitParameter(ApplicationConfig.WEBSOCKET_BUFFER_SIZE,
bufferSize);
atmosphere.addInitParameter(ApplicationConfig.WEBSOCKET_MAXTEXTSIZE,
@@ -75,12 +83,14 @@ public class PushRequestHandler implements RequestHandler,
atmosphere.addInitParameter("org.atmosphere.cpr.showSupportMessage",
"false");
- // Required to ensure the client-side knows at which points to split the
- // message stream into individual messages when using certain transports
- atmosphere.interceptor(new TrackMessageSizeInterceptor());
-
try {
atmosphere.init(service.getServlet().getServletConfig());
+
+ // Ensure the client-side knows how to split the message stream
+ // into individual messages when using certain transports
+ AtmosphereInterceptor trackMessageSize = new TrackMessageSizeInterceptor();
+ trackMessageSize.configure(atmosphere.getAtmosphereConfig());
+ atmosphere.interceptor(trackMessageSize);
} catch (ServletException e) {
throw new ServiceException("Could not read atmosphere settings", e);
}
diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java
index e4b5360b49..d4b0bc709f 100644
--- a/server/src/com/vaadin/server/communication/UIInitHandler.java
+++ b/server/src/com/vaadin/server/communication/UIInitHandler.java
@@ -39,6 +39,7 @@ import com.vaadin.server.VaadinService;
import com.vaadin.server.VaadinSession;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.communication.PushMode;
+import com.vaadin.shared.ui.ui.Transport;
import com.vaadin.shared.ui.ui.UIConstants;
import com.vaadin.ui.UI;
@@ -209,7 +210,12 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
pushMode = session.getService().getDeploymentConfiguration()
.getPushMode();
}
- ui.setPushMode(pushMode);
+ ui.getPushConfiguration().setPushMode(pushMode);
+
+ Transport transport = provider.getPushTransport(event);
+ if (transport != null) {
+ ui.getPushConfiguration().setTransport(transport);
+ }
// Set thread local here so it is available in init
UI.setCurrent(ui);
@@ -273,7 +279,7 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
if (session.getConfiguration().isXsrfProtectionEnabled()) {
writer.write(getSecurityKeyUIDL(session));
}
- new UidlWriter().write(uI, writer, true, false, false);
+ new UidlWriter().write(uI, writer, true, false);
writer.write("}");
String initialUIDL = writer.toString();
diff --git a/server/src/com/vaadin/server/communication/UidlRequestHandler.java b/server/src/com/vaadin/server/communication/UidlRequestHandler.java
index 73ff92f8bd..3564aa65b5 100644
--- a/server/src/com/vaadin/server/communication/UidlRequestHandler.java
+++ b/server/src/com/vaadin/server/communication/UidlRequestHandler.java
@@ -19,13 +19,11 @@ package com.vaadin.server.communication;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
-import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.JSONException;
-import com.vaadin.server.ClientConnector;
import com.vaadin.server.Constants;
import com.vaadin.server.LegacyCommunicationManager.InvalidUIDLSecurityKeyException;
import com.vaadin.server.ServletPortletHelper;
@@ -39,7 +37,6 @@ import com.vaadin.server.VaadinSession;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.JsonConstants;
import com.vaadin.shared.Version;
-import com.vaadin.ui.Component;
import com.vaadin.ui.UI;
/**
@@ -79,32 +76,16 @@ public class UidlRequestHandler extends SynchronizedRequestHandler implements
checkWidgetsetVersion(request);
String requestThemeName = request.getParameter("theme");
- ClientConnector highlightedConnector;
// repaint requested or session has timed out and new one is created
boolean repaintAll;
- // TODO PUSH repaintAll, analyzeLayouts, highlightConnector should be
+ // TODO PUSH repaintAll, analyzeLayouts should be
// part of the message payload to make the functionality transport
// agnostic
repaintAll = (request
.getParameter(ApplicationConstants.URL_PARAMETER_REPAINT_ALL) != null);
- boolean analyzeLayouts = false;
- if (repaintAll) {
- // analyzing can be done only with repaintAll
- analyzeLayouts = (request
- .getParameter(ApplicationConstants.PARAM_ANALYZE_LAYOUTS) != null);
-
- String pid = request
- .getParameter(ApplicationConstants.PARAM_HIGHLIGHT_CONNECTOR);
- if (pid != null) {
- highlightedConnector = uI.getConnectorTracker().getConnector(
- pid);
- highlightConnector(highlightedConnector);
- }
- }
-
StringWriter stringWriter = new StringWriter();
try {
@@ -114,8 +95,7 @@ public class UidlRequestHandler extends SynchronizedRequestHandler implements
session.getCommunicationManager().repaintAll(uI);
}
- writeUidl(request, response, uI, stringWriter, repaintAll,
- analyzeLayouts);
+ writeUidl(request, response, uI, stringWriter, repaintAll);
} catch (JSONException e) {
getLogger().log(Level.SEVERE, "Error writing JSON to response", e);
// Refresh on client side
@@ -164,11 +144,11 @@ public class UidlRequestHandler extends SynchronizedRequestHandler implements
}
private void writeUidl(VaadinRequest request, VaadinResponse response,
- UI ui, Writer writer, boolean repaintAll, boolean analyzeLayouts)
- throws IOException, JSONException {
+ UI ui, Writer writer, boolean repaintAll) throws IOException,
+ JSONException {
openJsonMessage(writer, response);
- new UidlWriter().write(ui, writer, repaintAll, analyzeLayouts, false);
+ new UidlWriter().write(ui, writer, repaintAll, false);
closeJsonMessage(writer);
}
@@ -190,63 +170,6 @@ public class UidlRequestHandler extends SynchronizedRequestHandler implements
outWriter.write("for(;;);[{");
}
- // TODO Does this belong here?
- protected void highlightConnector(ClientConnector highlightedConnector) {
- StringBuilder sb = new StringBuilder();
- sb.append("*** Debug details of a connector: *** \n");
- sb.append("Type: ");
- sb.append(highlightedConnector.getClass().getName());
- sb.append("\nId:");
- sb.append(highlightedConnector.getConnectorId());
- if (highlightedConnector instanceof Component) {
- Component component = (Component) highlightedConnector;
- if (component.getCaption() != null) {
- sb.append("\nCaption:");
- sb.append(component.getCaption());
- }
- }
- printHighlightedConnectorHierarchy(sb, highlightedConnector);
- getLogger().info(sb.toString());
- }
-
- // TODO Does this belong here?
- protected void printHighlightedConnectorHierarchy(StringBuilder sb,
- ClientConnector connector) {
- LinkedList<ClientConnector> h = new LinkedList<ClientConnector>();
- h.add(connector);
- ClientConnector parent = connector.getParent();
- while (parent != null) {
- h.addFirst(parent);
- parent = parent.getParent();
- }
-
- sb.append("\nConnector hierarchy:\n");
- VaadinSession session2 = connector.getUI().getSession();
- sb.append(session2.getClass().getName());
- sb.append("(");
- sb.append(session2.getClass().getSimpleName());
- sb.append(".java");
- sb.append(":1)");
- int l = 1;
- for (ClientConnector connector2 : h) {
- sb.append("\n");
- for (int i = 0; i < l; i++) {
- sb.append(" ");
- }
- l++;
- Class<? extends ClientConnector> connectorClass = connector2
- .getClass();
- Class<?> topClass = connectorClass;
- while (topClass.getEnclosingClass() != null) {
- topClass = topClass.getEnclosingClass();
- }
- sb.append(connectorClass.getName());
- sb.append("(");
- sb.append(topClass.getSimpleName());
- sb.append(".java:1)");
- }
- }
-
private static final Logger getLogger() {
return Logger.getLogger(UidlRequestHandler.class.getName());
}
diff --git a/server/src/com/vaadin/server/communication/UidlWriter.java b/server/src/com/vaadin/server/communication/UidlWriter.java
index fbe2fb86d5..60933a75c2 100644
--- a/server/src/com/vaadin/server/communication/UidlWriter.java
+++ b/server/src/com/vaadin/server/communication/UidlWriter.java
@@ -71,12 +71,16 @@ public class UidlWriter implements Serializable {
* @throws JSONException
* If the JSON serialization fails.
*/
- public void write(UI ui, Writer writer, boolean repaintAll,
- boolean analyzeLayouts, boolean async) throws IOException,
- JSONException {
+ public void write(UI ui, Writer writer, boolean repaintAll, boolean async)
+ throws IOException, JSONException {
+ VaadinSession session = ui.getSession();
+
+ // Purge pending access calls as they might produce additional changes
+ // to write out
+ session.getService().runPendingAccessTasks(session);
+
ArrayList<ClientConnector> dirtyVisibleConnectors = ui
.getConnectorTracker().getDirtyVisibleConnectors();
- VaadinSession session = ui.getSession();
LegacyCommunicationManager manager = session.getCommunicationManager();
// Paints components
ConnectorTracker uiConnectorTracker = ui.getConnectorTracker();
@@ -156,8 +160,7 @@ public class UidlWriter implements Serializable {
SystemMessages messages = ui.getSession().getService()
.getSystemMessages(ui.getLocale(), null);
// TODO hilightedConnector
- new MetadataWriter().write(ui, writer, repaintAll, analyzeLayouts,
- async, null, messages);
+ new MetadataWriter().write(ui, writer, repaintAll, async, messages);
writer.write(", ");
writer.write("\"resources\" : ");
@@ -278,10 +281,6 @@ public class UidlWriter implements Serializable {
+ new JSONArray(styleDependencies).toString());
}
- // add any pending locale definitions requested by the client
- writer.write(", \"locales\": ");
- manager.printLocaleDeclarations(writer);
-
if (manager.getDragAndDropService() != null) {
manager.getDragAndDropService().printJSONResponse(writer);
}
diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java
index 06060dbf91..9ff36a42d2 100644
--- a/server/src/com/vaadin/ui/AbstractComponent.java
+++ b/server/src/com/vaadin/ui/AbstractComponent.java
@@ -291,7 +291,10 @@ public abstract class AbstractComponent extends AbstractClientConnector
public void setLocale(Locale locale) {
this.locale = locale;
- // FIXME: Reload value if there is a converter
+ if (locale != null && isAttached()) {
+ getUI().getLocaleService().addLocale(locale);
+ }
+
markAsDirty();
}
@@ -556,6 +559,10 @@ public abstract class AbstractComponent extends AbstractClientConnector
focus();
}
setActionManagerViewer();
+ if (locale != null) {
+ getUI().getLocaleService().addLocale(locale);
+ }
+
}
/*
diff --git a/server/src/com/vaadin/ui/AbstractField.java b/server/src/com/vaadin/ui/AbstractField.java
index 3bca63a3b7..606bf5fb21 100644
--- a/server/src/com/vaadin/ui/AbstractField.java
+++ b/server/src/com/vaadin/ui/AbstractField.java
@@ -616,17 +616,14 @@ public abstract class AbstractField<T> extends AbstractComponent implements
// Check if the current converter is compatible.
if (newDataSource != null
- && !ConverterUtil.canConverterHandle(getConverter(), getType(),
- newDataSource.getType())) {
- // Changing from e.g. Number -> Double should set a new converter,
- // changing from Double -> Number can keep the old one (Property
- // accepts Number)
-
- // Set a new converter if there is a new data source and
- // there is no old converter or the old is incompatible.
+ && !ConverterUtil.canConverterPossiblyHandle(getConverter(),
+ getType(), newDataSource.getType())) {
+ // There is no converter set or there is no way the current
+ // converter can be compatible.
setConverter(newDataSource.getType());
}
- // Gets the value from source
+ // Gets the value from source. This requires that a valid converter has
+ // been set.
try {
if (dataSource != null) {
T fieldValue = convertFromModel(getDataSourceValue());
diff --git a/server/src/com/vaadin/ui/Calendar.java b/server/src/com/vaadin/ui/Calendar.java
index 38fa355dd8..c3385baa2c 100644
--- a/server/src/com/vaadin/ui/Calendar.java
+++ b/server/src/com/vaadin/ui/Calendar.java
@@ -45,6 +45,8 @@ import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.DropTarget;
import com.vaadin.event.dd.TargetDetails;
import com.vaadin.server.KeyMapper;
+import com.vaadin.server.PaintException;
+import com.vaadin.server.PaintTarget;
import com.vaadin.shared.ui.calendar.CalendarEventId;
import com.vaadin.shared.ui.calendar.CalendarServerRpc;
import com.vaadin.shared.ui.calendar.CalendarState;
@@ -114,7 +116,7 @@ public class Calendar extends AbstractComponent implements
CalendarComponentEvents.RangeSelectNotifier,
CalendarComponentEvents.EventResizeNotifier,
CalendarEventProvider.EventSetChangeListener, DropTarget,
- CalendarEditableEventProvider, Action.Container {
+ CalendarEditableEventProvider, Action.Container, LegacyComponent {
/**
* Calendar can use either 12 hours clock or 24 hours clock.
@@ -1842,4 +1844,31 @@ public class Calendar extends AbstractComponent implements
}
}
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.server.VariableOwner#changeVariables(java.lang.Object,
+ * java.util.Map)
+ */
+ @Override
+ public void changeVariables(Object source, Map<String, Object> variables) {
+ /*
+ * Only defined to fulfill the LegacyComponent interface used for
+ * calendar drag & drop. No implementation required.
+ */
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.ui.LegacyComponent#paintContent(com.vaadin.server.PaintTarget)
+ */
+ @Override
+ public void paintContent(PaintTarget target) throws PaintException {
+ if (dropHandler != null) {
+ dropHandler.getAcceptCriterion().paint(target);
+ }
+ }
} \ No newline at end of file
diff --git a/server/src/com/vaadin/ui/Label.java b/server/src/com/vaadin/ui/Label.java
index d037652a09..d7cee2a80d 100644
--- a/server/src/com/vaadin/ui/Label.java
+++ b/server/src/com/vaadin/ui/Label.java
@@ -242,14 +242,17 @@ public class Label extends AbstractComponent implements Property<String>,
((Property.ValueChangeNotifier) dataSource).removeListener(this);
}
+ // Check if the current converter is compatible.
if (newDataSource != null
- && !ConverterUtil.canConverterHandle(getConverter(),
- String.class, newDataSource.getType())) {
- // Try to find a converter
+ && !ConverterUtil.canConverterPossiblyHandle(getConverter(),
+ getType(), newDataSource.getType())) {
+ // There is no converter set or there is no way the current
+ // converter can be compatible.
Converter<String, ?> c = ConverterUtil.getConverter(String.class,
newDataSource.getType(), getSession());
setConverter(c);
}
+
dataSource = newDataSource;
if (dataSource != null) {
// Update the value from the data source. If data source was set to
diff --git a/server/src/com/vaadin/ui/LegacyWindow.java b/server/src/com/vaadin/ui/LegacyWindow.java
index 1b66b608c1..458b09390d 100644
--- a/server/src/com/vaadin/ui/LegacyWindow.java
+++ b/server/src/com/vaadin/ui/LegacyWindow.java
@@ -125,7 +125,7 @@ public class LegacyWindow extends UI {
public void setName(String name) {
this.name = name;
// The name can not be changed in application
- if (getSession() != null) {
+ if (isAttached()) {
throw new IllegalStateException(
"Window name can not be changed while "
+ "the window is in application");
diff --git a/server/src/com/vaadin/ui/LoginForm.java b/server/src/com/vaadin/ui/LoginForm.java
index d06882927e..67d7182ecb 100644
--- a/server/src/com/vaadin/ui/LoginForm.java
+++ b/server/src/com/vaadin/ui/LoginForm.java
@@ -68,7 +68,7 @@ public class LoginForm extends CustomComponent {
}
final StringBuilder responseBuilder = new StringBuilder();
- getUI().access(new Runnable() {
+ getUI().accessSynchronously(new Runnable() {
@Override
public void run() {
String method = VaadinServletService.getCurrentServletRequest()
diff --git a/server/src/com/vaadin/ui/ProgressBar.java b/server/src/com/vaadin/ui/ProgressBar.java
new file mode 100644
index 0000000000..3f8aab6d7c
--- /dev/null
+++ b/server/src/com/vaadin/ui/ProgressBar.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.ui;
+
+import com.vaadin.data.Property;
+import com.vaadin.shared.ui.progressindicator.ProgressBarState;
+
+/**
+ * Shows the current progress of a long running task.
+ * <p>
+ * The default mode is to show the current progress internally represented by a
+ * floating point value between 0 and 1 (inclusive). The progress bar can also
+ * be in an indeterminate mode showing an animation indicating that the task is
+ * running but without providing any information about the current progress.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public class ProgressBar extends AbstractField<Float> implements
+ Property.Viewer, Property.ValueChangeListener {
+
+ /**
+ * Creates a new progress bar initially set to 0% progress.
+ */
+ public ProgressBar() {
+ this(0);
+ }
+
+ /**
+ * Creates a new progress bar with the given initial value.
+ *
+ * @param progress
+ * the initial progress value
+ */
+ public ProgressBar(float progress) {
+ setValue(Float.valueOf(progress));
+ }
+
+ /**
+ * Creates a new progress bar bound to the given data source.
+ *
+ * @param dataSource
+ * the property to bind this progress bar to
+ */
+ public ProgressBar(Property<?> dataSource) {
+ setPropertyDataSource(dataSource);
+ }
+
+ @Override
+ public void beforeClientResponse(boolean initial) {
+ super.beforeClientResponse(initial);
+
+ // Update value in state even if the property hasn't fired any event
+ getState().state = getValue();
+ }
+
+ /**
+ * Gets the value of this progress bar. The value is a <code>float</code>
+ * between 0 and 1 where 0 represents no progress at all and 1 represents
+ * fully completed.
+ *
+ * @return the current progress value
+ */
+ @Override
+ public Float getValue() {
+ return super.getValue();
+ }
+
+ /**
+ * Sets the value of this progress bar. The value is a <code>float</code>
+ * between 0 and 1 where 0 represents no progress at all and 1 represents
+ * fully completed.
+ *
+ * @param newValue
+ * the current progress value
+ */
+ @Override
+ public void setValue(Float newValue) {
+ super.setValue(newValue);
+ }
+
+ @Override
+ public Class<Float> getType() {
+ return Float.class;
+ }
+
+ @Override
+ protected ProgressBarState getState() {
+ return (ProgressBarState) super.getState();
+ }
+
+ @Override
+ protected ProgressBarState getState(boolean markAsDirty) {
+ return (ProgressBarState) super.getState(markAsDirty);
+ }
+
+ /**
+ * Sets whether or not this progress indicator is indeterminate. In
+ * indeterminate mode there is an animation indicating that the task is
+ * running but without providing any information about the current progress.
+ *
+ * @param indeterminate
+ * <code>true</code> to set to indeterminate mode; otherwise
+ * <code>false</code>
+ */
+ public void setIndeterminate(boolean indeterminate) {
+ getState().indeterminate = indeterminate;
+ }
+
+ /**
+ * Gets whether or not this progress indicator is indeterminate. In
+ * indeterminate mode there is an animation indicating that the task is
+ * running but without providing any information about the current progress.
+ *
+ * @return <code>true</code> if set to indeterminate mode; otherwise
+ * <code>false</code>
+ */
+ public boolean isIndeterminate() {
+ return getState(false).indeterminate;
+ }
+
+ /*
+ * Overridden to keep the shared state in sync with the AbstractField
+ * internal value. Should be removed once AbstractField is refactored to use
+ * shared state.
+ *
+ * See tickets #10921 and #11064.
+ */
+ @Override
+ protected void setInternalValue(Float newValue) {
+ super.setInternalValue(newValue);
+ if (newValue == null) {
+ newValue = Float.valueOf(0);
+ }
+ getState().state = newValue;
+ }
+
+} \ No newline at end of file
diff --git a/server/src/com/vaadin/ui/ProgressIndicator.java b/server/src/com/vaadin/ui/ProgressIndicator.java
index c481aa1e8f..6da18fc29d 100644
--- a/server/src/com/vaadin/ui/ProgressIndicator.java
+++ b/server/src/com/vaadin/ui/ProgressIndicator.java
@@ -17,24 +17,27 @@
package com.vaadin.ui;
import com.vaadin.data.Property;
+import com.vaadin.shared.communication.PushMode;
import com.vaadin.shared.ui.progressindicator.ProgressIndicatorServerRpc;
import com.vaadin.shared.ui.progressindicator.ProgressIndicatorState;
/**
- * <code>ProgressIndicator</code> is component that shows user state of a
- * process (like long computing or file upload)
- *
- * <code>ProgressIndicator</code> has two main modes. One for indeterminate
- * processes and other (default) for processes which progress can be measured
- *
- * May view an other property that indicates progress 0...1
+ * A {@link ProgressBar} which polls the server for updates.
+ * <p>
+ * Polling in this way is generally not recommended since there is no
+ * centralized management of when messages are sent to the server. Furthermore,
+ * polling might not be needed at all if {@link UI#setPushMode(PushMode)} or
+ * {@link UI#setPollInterval(int)} is used.
*
* @author Vaadin Ltd.
* @since 4
+ * @deprecated as of 7.1, use {@link ProgressBar} combined with
+ * {@link UI#setPushMode(PushMode)} or
+ * {@link UI#setPollInterval(int)} instead.
*/
+@Deprecated
@SuppressWarnings("serial")
-public class ProgressIndicator extends AbstractField<Float> implements
- Property.Viewer, Property.ValueChangeListener {
+public class ProgressIndicator extends ProgressBar {
private ProgressIndicatorServerRpc rpc = new ProgressIndicatorServerRpc() {
@@ -57,7 +60,7 @@ public class ProgressIndicator extends AbstractField<Float> implements
* @param value
*/
public ProgressIndicator(float value) {
- setValue(value);
+ super(value);
registerRpc(rpc);
}
@@ -68,74 +71,18 @@ public class ProgressIndicator extends AbstractField<Float> implements
* @param contentSource
*/
public ProgressIndicator(Property contentSource) {
- setPropertyDataSource(contentSource);
+ super(contentSource);
registerRpc(rpc);
}
@Override
- public void beforeClientResponse(boolean initial) {
- super.beforeClientResponse(initial);
-
- getState().state = getValue();
- }
-
- /**
- * Gets the value of the ProgressIndicator. Value of the ProgressIndicator
- * is Float between 0 and 1.
- *
- * @return the Value of the ProgressIndicator.
- * @see com.vaadin.ui.AbstractField#getValue()
- */
- @Override
- public Float getValue() {
- return super.getValue();
- }
-
- /**
- * Sets the value of the ProgressIndicator. Value of the ProgressIndicator
- * is the Float between 0 and 1.
- *
- * @param newValue
- * the New value of the ProgressIndicator.
- * @see com.vaadin.ui.AbstractField#setValue()
- */
- @Override
- public void setValue(Float newValue) {
- super.setValue(newValue);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.AbstractField#getType()
- */
- @Override
- public Class<Float> getType() {
- return Float.class;
- }
-
- @Override
protected ProgressIndicatorState getState() {
return (ProgressIndicatorState) super.getState();
}
- /**
- * Sets whether or not the ProgressIndicator is indeterminate.
- *
- * @param indeterminate
- * true to set to indeterminate mode.
- */
- public void setIndeterminate(boolean indeterminate) {
- getState().indeterminate = indeterminate;
- }
-
- /**
- * Gets whether or not the ProgressIndicator is indeterminate.
- *
- * @return true to set to indeterminate mode.
- */
- public boolean isIndeterminate() {
- return getState().indeterminate;
+ @Override
+ protected ProgressIndicatorState getState(boolean markAsDirty) {
+ return (ProgressIndicatorState) super.getState(markAsDirty);
}
/**
@@ -154,22 +101,6 @@ public class ProgressIndicator extends AbstractField<Float> implements
* @return the interval in milliseconds.
*/
public int getPollingInterval() {
- return getState().pollingInterval;
- }
-
- /*
- * Overridden to keep the shared state in sync with the AbstractField
- * internal value. Should be removed once AbstractField is refactored to use
- * shared state.
- *
- * See tickets #10921 and #11064.
- */
- @Override
- protected void setInternalValue(Float newValue) {
- super.setInternalValue(newValue);
- if (newValue == null) {
- newValue = 0.0f;
- }
- getState().state = newValue;
+ return getState(false).pollingInterval;
}
}
diff --git a/server/src/com/vaadin/ui/PushConfiguration.java b/server/src/com/vaadin/ui/PushConfiguration.java
new file mode 100644
index 0000000000..a592b39bef
--- /dev/null
+++ b/server/src/com/vaadin/ui/PushConfiguration.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.ui;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+
+import com.vaadin.server.VaadinSession;
+import com.vaadin.shared.communication.PushMode;
+import com.vaadin.shared.ui.ui.Transport;
+import com.vaadin.shared.ui.ui.UIState.PushConfigurationState;
+
+/**
+ * Provides method for configuring the push channel.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public interface PushConfiguration extends Serializable {
+
+ /**
+ * Returns the mode of bidirectional ("push") communication that is used.
+ *
+ * @return The push mode.
+ */
+ public PushMode getPushMode();
+
+ /**
+ * Sets the mode of bidirectional ("push") communication that should be
+ * used.
+ * <p>
+ * Add-on developers should note that this method is only meant for the
+ * application developer. An add-on should not set the push mode directly,
+ * rather instruct the user to set it.
+ * </p>
+ *
+ * @param pushMode
+ * The push mode to use.
+ *
+ * @throws IllegalArgumentException
+ * if the argument is null.
+ * @throws IllegalStateException
+ * if push support is not available.
+ */
+ public void setPushMode(PushMode pushMode);
+
+ /**
+ * Returns the primary transport type for push.
+ * <p>
+ * Note that if you set the transport type using
+ * {@link #setParameter(String, String)} to an unsupported type this method
+ * will return null. Supported types are defined by {@link Transport}.
+ *
+ * @return The primary transport type
+ */
+ public Transport getTransport();
+
+ /**
+ * Sets the primary transport type for push.
+ * <p>
+ * Note that the new transport type will not be used until the push channel
+ * is disconnected and reconnected if already active.
+ *
+ * @param transport
+ * The primary transport type
+ */
+ public void setTransport(Transport transport);
+
+ /**
+ * Returns the fallback transport type for push.
+ * <p>
+ * Note that if you set the transport type using
+ * {@link #setParameter(String, String)} to an unsupported type this method
+ * will return null. Supported types are defined by {@link Transport}.
+ *
+ * @return The fallback transport type
+ */
+ public Transport getFallbackTransport();
+
+ /**
+ * Sets the fallback transport type for push.
+ * <p>
+ * Note that the new transport type will not be used until the push channel
+ * is disconnected and reconnected if already active.
+ *
+ * @param fallbackTransport
+ * The fallback transport type
+ */
+ public void setFallbackTransport(Transport fallbackTransport);
+
+ /**
+ * Returns the given parameter, if set.
+ * <p>
+ * This method provides low level access to push parameters and is typically
+ * not needed for normal application development.
+ *
+ * @since 7.1
+ * @param parameter
+ * The parameter name
+ * @return The parameter value or null if not set
+ */
+ public String getParameter(String parameter);
+
+ /**
+ * Returns the parameters which have been defined.
+ *
+ * @since 7.1
+ * @return A collection of parameter names
+ */
+ public Collection<String> getParameterNames();
+
+ /**
+ * Sets the given parameter.
+ * <p>
+ * This method provides low level access to push parameters and is typically
+ * not needed for normal application development.
+ *
+ * @since 7.1
+ * @param parameter
+ * The parameter name
+ * @param value
+ * The value
+ */
+ public void setParameter(String parameter, String value);
+
+}
+
+class PushConfigurationImpl implements PushConfiguration {
+ private UI ui;
+
+ public PushConfigurationImpl(UI ui) {
+ this.ui = ui;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.PushConfiguration#getPushMode()
+ */
+ @Override
+ public PushMode getPushMode() {
+ return getState(false).mode;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.ui.PushConfiguration#setPushMode(com.vaadin.shared.communication
+ * .PushMode)
+ */
+ @Override
+ public void setPushMode(PushMode pushMode) {
+ if (pushMode == null) {
+ throw new IllegalArgumentException("Push mode cannot be null");
+ }
+
+ if (pushMode.isEnabled()) {
+ VaadinSession session = ui.getSession();
+ if (session != null && !session.getService().ensurePushAvailable()) {
+ throw new IllegalStateException(
+ "Push is not available. See previous log messages for more information.");
+ }
+ }
+
+ /*
+ * Client-side will open a new connection or disconnect the old
+ * connection, so there's nothing more to do on the server at this
+ * point.
+ */
+ getState().mode = pushMode;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.PushConfiguration#getTransport()
+ */
+ @Override
+ public Transport getTransport() {
+ try {
+ return Transport
+ .valueOf(getParameter(PushConfigurationState.TRANSPORT_PARAM));
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.ui.PushConfiguration#setTransport(com.vaadin.shared.ui.ui.
+ * Transport)
+ */
+ @Override
+ public void setTransport(Transport transport) {
+ setParameter(PushConfigurationState.TRANSPORT_PARAM,
+ transport.getIdentifier());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.PushConfiguration#getFallbackTransport()
+ */
+ @Override
+ public Transport getFallbackTransport() {
+ try {
+ return Transport
+ .valueOf(getParameter(PushConfigurationState.FALLBACK_TRANSPORT_PARAM));
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.ui.PushConfiguration#setFallbackTransport(com.vaadin.shared
+ * .ui.ui.Transport)
+ */
+ @Override
+ public void setFallbackTransport(Transport fallbackTransport) {
+ setParameter(PushConfigurationState.FALLBACK_TRANSPORT_PARAM,
+ fallbackTransport.getIdentifier());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.PushConfiguration#getParameter(java.lang.String)
+ */
+ @Override
+ public String getParameter(String parameter) {
+ return getState(false).parameters.get(parameter);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.PushConfiguration#setParameter(java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public void setParameter(String parameter, String value) {
+ getState().parameters.put(parameter, value);
+
+ }
+
+ private PushConfigurationState getState() {
+ return ui.getState().pushConfiguration;
+ }
+
+ private PushConfigurationState getState(boolean markAsDirty) {
+ return ui.getState(markAsDirty).pushConfiguration;
+ }
+
+ @Override
+ public Collection<String> getParameterNames() {
+ return Collections
+ .unmodifiableCollection(ui.getState(false).pushConfiguration.parameters
+ .keySet());
+ }
+
+}
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index 0a4ed7c491..9135151089 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -21,7 +21,10 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Map;
+import java.util.concurrent.Future;
+import java.util.logging.Logger;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
@@ -29,6 +32,10 @@ import com.vaadin.event.ActionManager;
import com.vaadin.event.MouseEvents.ClickEvent;
import com.vaadin.event.MouseEvents.ClickListener;
import com.vaadin.navigator.Navigator;
+import com.vaadin.server.ClientConnector;
+import com.vaadin.server.ComponentSizeValidator;
+import com.vaadin.server.ComponentSizeValidator.InvalidLayout;
+import com.vaadin.server.LocaleService;
import com.vaadin.server.Page;
import com.vaadin.server.PaintException;
import com.vaadin.server.PaintTarget;
@@ -38,15 +45,18 @@ import com.vaadin.server.VaadinService;
import com.vaadin.server.VaadinServlet;
import com.vaadin.server.VaadinSession;
import com.vaadin.server.communication.PushConnection;
+import com.vaadin.shared.Connector;
import com.vaadin.shared.EventId;
import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.communication.PushMode;
+import com.vaadin.shared.ui.ui.DebugWindowClientRpc;
+import com.vaadin.shared.ui.ui.DebugWindowServerRpc;
import com.vaadin.shared.ui.ui.ScrollClientRpc;
import com.vaadin.shared.ui.ui.UIClientRpc;
import com.vaadin.shared.ui.ui.UIConstants;
import com.vaadin.shared.ui.ui.UIServerRpc;
import com.vaadin.shared.ui.ui.UIState;
import com.vaadin.ui.Component.Focusable;
+import com.vaadin.util.ConnectorHelper;
import com.vaadin.util.CurrentInstance;
/**
@@ -86,7 +96,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
/**
* The application to which this UI belongs
*/
- private VaadinSession session;
+ private volatile VaadinSession session;
/**
* List of windows in this UI.
@@ -159,6 +169,40 @@ public abstract class UI extends AbstractSingleComponentContainer implements
*/
}
};
+ private DebugWindowServerRpc debugRpc = new DebugWindowServerRpc() {
+ @Override
+ public void showServerDebugInfo(Connector connector) {
+ String info = ConnectorHelper
+ .getDebugInformation((ClientConnector) connector);
+ getLogger().info(info);
+ }
+
+ @Override
+ public void analyzeLayouts() {
+ // TODO Move to client side
+ List<InvalidLayout> invalidSizes = ComponentSizeValidator
+ .validateLayouts(UI.this);
+ StringBuilder json = new StringBuilder();
+ json.append("{\"invalidLayouts\":");
+ json.append("[");
+
+ if (invalidSizes != null) {
+ boolean first = true;
+ for (InvalidLayout invalidSize : invalidSizes) {
+ if (!first) {
+ json.append(",");
+ } else {
+ first = false;
+ }
+ invalidSize.reportErrors(json, System.err);
+ }
+ }
+ json.append("]}");
+ getRpcProxy(DebugWindowClientRpc.class).reportLayoutProblems(
+ json.toString());
+ }
+
+ };
/**
* Timestamp keeping track of the last heartbeat of this UI. Updated to the
@@ -171,6 +215,8 @@ public abstract class UI extends AbstractSingleComponentContainer implements
private TooltipConfiguration tooltipConfiguration = new TooltipConfigurationImpl(
this);
+ private PushConfiguration pushConfiguration = new PushConfigurationImpl(
+ this);
/**
* Creates a new empty UI without a caption. The content of the UI must be
@@ -191,6 +237,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
*/
public UI(Component content) {
registerRpc(rpc);
+ registerRpc(debugRpc);
setSizeFull();
setContent(content);
}
@@ -418,7 +465,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
throw new NullPointerException("Argument must not be null");
}
- if (window.getUI() != null && window.getUI().getSession() != null) {
+ if (window.isAttached()) {
throw new IllegalArgumentException(
"Window is already attached to an application.");
}
@@ -493,6 +540,9 @@ public abstract class UI extends AbstractSingleComponentContainer implements
private boolean hasPendingPush = false;
+ private LocaleService localeService = new LocaleService(this,
+ getState(false).localeServiceState);
+
/**
* This method is used by Component.Focusable objects to request focus to
* themselves. Focus renders must be handled at window level (instead of
@@ -1051,6 +1101,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
@Override
public void attach() {
super.attach();
+ getLocaleService().addLocale(getLocale());
}
/**
@@ -1098,24 +1149,30 @@ public abstract class UI extends AbstractSingleComponentContainer implements
}
/**
- * Provides exclusive access to this UI from outside a request handling
- * thread.
- * <p>
- * The given runnable is executed while holding the session lock to ensure
- * exclusive access to this UI and its session. The UI and related thread
- * locals are set properly before executing the runnable.
- * </p>
+ * Locks the session of this UI and runs the provided Runnable right away.
* <p>
- * RPC handlers for components inside this UI do not need this method as the
- * session is automatically locked by the framework during request handling.
+ * It is generally recommended to use {@link #access(Runnable)} instead of
+ * this method for accessing a session from a different thread as
+ * {@link #access(Runnable)} can be used while holding the lock of another
+ * session. To avoid causing deadlocks, this methods throws an exception if
+ * it is detected than another session is also locked by the current thread.
* </p>
* <p>
- * Note that calling this method while another session is locked by the
- * current thread will cause an exception. This is to prevent deadlock
- * situations when two threads have locked one session each and are both
- * waiting for the lock for the other session.
+ * This method behaves differently than {@link #access(Runnable)} in some
+ * situations:
+ * <ul>
+ * <li>If the current thread is currently holding the lock of the session,
+ * {@link #accessSynchronously(Runnable)} runs the task right away whereas
+ * {@link #access(Runnable)} defers the task to a later point in time.</li>
+ * <li>If some other thread is currently holding the lock for the session,
+ * {@link #accessSynchronously(Runnable)} blocks while waiting for the lock
+ * to be available whereas {@link #access(Runnable)} defers the task to a
+ * later point in time.</li>
+ * </ul>
* </p>
*
+ * @since 7.1
+ *
* @param runnable
* the runnable which accesses the UI
* @throws UIDetachedException
@@ -1124,11 +1181,11 @@ public abstract class UI extends AbstractSingleComponentContainer implements
* @throws IllegalStateException
* if the current thread holds the lock for another session
*
- * @see #getCurrent()
- * @see VaadinSession#access(Runnable)
- * @see VaadinSession#lock()
+ * @see #access(Runnable)
+ * @see VaadinSession#accessSynchronously(Runnable)
*/
- public void access(Runnable runnable) throws UIDetachedException {
+ public void accessSynchronously(Runnable runnable)
+ throws UIDetachedException {
Map<Class<?>, CurrentInstance> old = null;
VaadinSession session = getSession();
@@ -1146,24 +1203,76 @@ public abstract class UI extends AbstractSingleComponentContainer implements
// acquired the lock.
throw new UIDetachedException();
}
- old = CurrentInstance.setThreadLocals(this);
+ old = CurrentInstance.setCurrent(this);
runnable.run();
} finally {
session.unlock();
if (old != null) {
- CurrentInstance.restoreThreadLocals(old);
+ CurrentInstance.restoreInstances(old);
}
}
}
/**
- * @deprecated As of 7.1.0.beta1, use {@link #access(Runnable)} instead.
- * This method will be removed before the final 7.1.0 release.
+ * Provides exclusive access to this UI from outside a request handling
+ * thread.
+ * <p>
+ * The given runnable is executed while holding the session lock to ensure
+ * exclusive access to this UI. If the session is not locked, the lock will
+ * be acquired and the runnable is run right away. If the session is
+ * currently locked, the runnable will be run before that lock is released.
+ * </p>
+ * <p>
+ * RPC handlers for components inside this UI do not need to use this method
+ * as the session is automatically locked by the framework during RPC
+ * handling.
+ * </p>
+ * <p>
+ * Please note that the runnable might be invoked on a different thread or
+ * later on the current thread, which means that custom thread locals might
+ * not have the expected values when the runnable is executed. Inheritable
+ * values in {@link CurrentInstance} will have the same values as when this
+ * method was invoked. {@link UI#getCurrent()},
+ * {@link VaadinSession#getCurrent()} and {@link VaadinService#getCurrent()}
+ * are set according to this UI before executing the runnable.
+ * Non-inheritable CurrentInstance values including
+ * {@link VaadinService#getCurrentRequest()} and
+ * {@link VaadinService#getCurrentResponse()} will not be defined.
+ * </p>
+ * <p>
+ * The returned future can be used to check for task completion and to
+ * cancel the task.
+ * </p>
+ *
+ * @see #getCurrent()
+ * @see #accessSynchronously(Runnable)
+ * @see VaadinSession#access(Runnable)
+ * @see VaadinSession#lock()
+ *
+ * @since 7.1
+ *
+ * @param runnable
+ * the runnable which accesses the UI
+ * @throws UIDetachedException
+ * if the UI is not attached to a session (and locking can
+ * therefore not be done)
+ * @return a future that can be used to check for task completion and to
+ * cancel the task
*/
- @Deprecated
- public void runSafely(Runnable runnable) throws UIDetachedException {
- access(runnable);
+ public Future<Void> access(final Runnable runnable) {
+ VaadinSession session = getSession();
+
+ if (session == null) {
+ throw new UIDetachedException();
+ }
+
+ return session.access(new Runnable() {
+ @Override
+ public void run() {
+ accessSynchronously(runnable);
+ }
+ });
}
/**
@@ -1204,12 +1313,20 @@ public abstract class UI extends AbstractSingleComponentContainer implements
VaadinSession session = getSession();
if (session != null) {
assert session.hasLock();
+
+ /*
+ * Purge the pending access queue as it might mark a connector as
+ * dirty when the push would otherwise be ignored because there are
+ * no changes to push.
+ */
+ session.getService().runPendingAccessTasks(session);
+
if (!getConnectorTracker().hasDirtyConnectors()) {
// Do not push if there is nothing to push
return;
}
- if (!getPushMode().isEnabled()) {
+ if (!getPushConfiguration().getPushMode().isEnabled()) {
throw new IllegalStateException("Push not enabled");
}
@@ -1237,7 +1354,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
*/
public void setPushConnection(PushConnection pushConnection) {
// If pushMode is disabled then there should never be a pushConnection
- assert (getPushMode().isEnabled() || pushConnection == null);
+ assert (getPushConfiguration().getPushMode().isEnabled() || pushConnection == null);
if (pushConnection == this.pushConnection) {
return;
@@ -1286,51 +1403,13 @@ public abstract class UI extends AbstractSingleComponentContainer implements
}
/**
- * Returns the mode of bidirectional ("push") communication that is used in
- * this UI.
- *
- * @return The push mode.
- */
- public PushMode getPushMode() {
- return getState(false).pushMode;
- }
-
- /**
- * Sets the mode of bidirectional ("push") communication that should be used
- * in this UI.
- * <p>
- * Add-on developers should note that this method is only meant for the
- * application developer. An add-on should not set the push mode directly,
- * rather instruct the user to set it.
- * </p>
- *
- * @param pushMode
- * The push mode to use.
+ * Retrieves the object used for configuring the push channel.
*
- * @throws IllegalArgumentException
- * if the argument is null.
- * @throws IllegalStateException
- * if push support is not available.
+ * @since 7.1
+ * @return The instance used for push configuration
*/
- public void setPushMode(PushMode pushMode) {
- if (pushMode == null) {
- throw new IllegalArgumentException("Push mode cannot be null");
- }
-
- if (pushMode.isEnabled()) {
- VaadinSession session = getSession();
- if (session != null && !session.getService().ensurePushAvailable()) {
- throw new IllegalStateException(
- "Push is not available. See previous log messages for more information.");
- }
- }
-
- /*
- * Client-side will open a new connection or disconnect the old
- * connection, so there's nothing more to do on the server at this
- * point.
- */
- getState().pushMode = pushMode;
+ public PushConfiguration getPushConfiguration() {
+ return pushConfiguration;
}
/**
@@ -1357,4 +1436,19 @@ public abstract class UI extends AbstractSingleComponentContainer implements
public void setOverlayContainerLabel(String overlayContainerLabel) {
getState().overlayContainerLabel = overlayContainerLabel;
}
+
+ /**
+ * Returns the locale service which handles transmission of Locale data to
+ * the client.
+ *
+ * @since 7.1
+ * @return The LocaleService for this UI
+ */
+ public LocaleService getLocaleService() {
+ return localeService;
+ }
+
+ private static Logger getLogger() {
+ return Logger.getLogger(UI.class.getName());
+ }
}
diff --git a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java b/server/src/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java
index 2902585f56..de8c5db195 100644
--- a/server/src/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java
+++ b/server/src/com/vaadin/ui/components/colorpicker/ColorPickerHistory.java
@@ -95,7 +95,7 @@ public class ColorPickerHistory extends CustomComponent implements
@SuppressWarnings("unchecked")
private ArrayBlockingQueue<Color> getColorHistory() {
- if (getSession() != null) {
+ if (isAttached()) {
Object colorHistory = getSession().getAttribute(
"colorPickerHistory");
if (colorHistory instanceof ArrayBlockingQueue<?>) {
diff --git a/server/src/com/vaadin/util/ConnectorHelper.java b/server/src/com/vaadin/util/ConnectorHelper.java
new file mode 100644
index 0000000000..e698e9222a
--- /dev/null
+++ b/server/src/com/vaadin/util/ConnectorHelper.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.util;
+
+import java.util.LinkedList;
+
+import com.vaadin.server.ClientConnector;
+import com.vaadin.ui.Component;
+
+/**
+ * Provides various helper methods for connectors. Meant for internal use.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public class ConnectorHelper {
+
+ /**
+ * Creates a string containing debug info for the connector
+ *
+ * @since 7.1
+ * @param connector
+ * The connector to print debug info about
+ * @return A string with debug information
+ */
+ public static String getDebugInformation(ClientConnector connector) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("*** Debug details of a connector: *** \n");
+ sb.append("Type: ");
+ sb.append(connector.getClass().getName());
+ sb.append("\nId:");
+ sb.append(connector.getConnectorId());
+ if (connector instanceof Component) {
+ Component component = (Component) connector;
+ if (component.getCaption() != null) {
+ sb.append("\nCaption:");
+ sb.append(component.getCaption());
+ }
+ }
+ writeHierarchyInformation(connector, sb);
+ return sb.toString();
+ }
+
+ /**
+ * Creates a string containing hierarchy information for the connector
+ *
+ * @since 7.1
+ * @param connector
+ * The connector to get hierarchy information for
+ * @param builder
+ * The StringBuilder where the information should be written
+ */
+ public static void writeHierarchyInformation(ClientConnector connector,
+ StringBuilder builder) {
+ LinkedList<ClientConnector> h = new LinkedList<ClientConnector>();
+ h.add(connector);
+ ClientConnector parent = connector.getParent();
+ while (parent != null) {
+ h.addFirst(parent);
+ parent = parent.getParent();
+ }
+
+ builder.append("\nConnector hierarchy:\n");
+
+ int l = 0;
+ for (ClientConnector connector2 : h) {
+ if (l != 0) {
+ builder.append("\n");
+ for (int i = 0; i < l; i++) {
+ builder.append(" ");
+ }
+ }
+ l++;
+ Class<? extends ClientConnector> connectorClass = connector2
+ .getClass();
+ Class<?> topClass = connectorClass;
+ while (topClass.getEnclosingClass() != null) {
+ topClass = topClass.getEnclosingClass();
+ }
+ builder.append(connectorClass.getName());
+ builder.append("(");
+ builder.append(topClass.getSimpleName());
+ builder.append(".java:1)");
+ }
+ }
+
+}
diff --git a/server/src/com/vaadin/util/CurrentInstance.java b/server/src/com/vaadin/util/CurrentInstance.java
index 60489d596e..b97bab3d8a 100644
--- a/server/src/com/vaadin/util/CurrentInstance.java
+++ b/server/src/com/vaadin/util/CurrentInstance.java
@@ -17,53 +17,41 @@
package com.vaadin.util;
import java.io.Serializable;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
-import com.vaadin.server.VaadinPortlet;
-import com.vaadin.server.VaadinPortletService;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinResponse;
import com.vaadin.server.VaadinService;
-import com.vaadin.server.VaadinServlet;
-import com.vaadin.server.VaadinServletService;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.UI;
/**
- * Keeps track of various thread local instances used by the framework.
+ * Keeps track of various current instances for the current thread. All the
+ * instances are automatically cleared after handling a request from the client
+ * to avoid leaking memory. The inheritable values are also maintained when
+ * execution is moved to another thread, both when a new thread is created and
+ * when {@link VaadinSession#access(Runnable)} or {@link UI#access(Runnable)} is
+ * used.
* <p>
* Currently the framework uses the following instances:
* </p>
* <p>
- * Inheritable: {@link UI}, {@link VaadinPortlet}, {@link VaadinService},
- * {@link VaadinServlet}, {@link VaadinSession}.
+ * Inheritable: {@link UI}, {@link VaadinService}, {@link VaadinSession}.
* </p>
* <p>
* Non-inheritable: {@link VaadinRequest}, {@link VaadinResponse}.
* </p>
*
* @author Vaadin Ltd
- * @version @VERSION@
* @since 7.0.0
*/
public class CurrentInstance implements Serializable {
private final Object instance;
private final boolean inheritable;
- private static boolean portletAvailable = false;
- {
- try {
- /*
- * VaadinPortlet depends on portlet API which is available only if
- * running in a portal.
- */
- portletAvailable = (VaadinPortlet.class.getName() != null);
- } catch (Throwable t) {
- }
- }
-
private static InheritableThreadLocal<Map<Class<?>, CurrentInstance>> instances = new InheritableThreadLocal<Map<Class<?>, CurrentInstance>>() {
@Override
protected Map<Class<?>, CurrentInstance> childValue(
@@ -129,7 +117,9 @@ public class CurrentInstance implements Serializable {
/**
* Sets the current inheritable instance of the given type. A current
- * instance that is inheritable will be available for child threads.
+ * instance that is inheritable will be available for child threads and in
+ * code run by {@link VaadinSession#access(Runnable)} and
+ * {@link UI#access(Runnable)}.
*
* @see #set(Class, Object)
* @see InheritableThreadLocal
@@ -184,13 +174,15 @@ public class CurrentInstance implements Serializable {
}
/**
- * Restores the given thread locals to the given values. Note that this
- * should only be used internally to restore Vaadin classes.
+ * Restores the given instances to the given values. Note that this should
+ * only be used internally to restore Vaadin classes.
+ *
+ * @since 7.1
*
* @param old
- * A Class -> Object map to set as thread locals
+ * A Class -> CurrentInstance map to set as current instances
*/
- public static void restoreThreadLocals(Map<Class<?>, CurrentInstance> old) {
+ public static void restoreInstances(Map<Class<?>, CurrentInstance> old) {
for (Class c : old.keySet()) {
CurrentInstance ci = old.get(c);
set(c, ci.instance, ci.inheritable);
@@ -198,30 +190,66 @@ public class CurrentInstance implements Serializable {
}
/**
- * Sets thread locals for the UI and all related classes
+ * Gets the currently set instances so that they can later be restored using
+ * {@link #restoreInstances(Map)}.
+ *
+ * @since 7.1
+ *
+ * @param onlyInheritable
+ * <code>true</code> if only the inheritable instances should be
+ * included; <code>false</code> to get all instances.
+ * @return a map containing the current instances
+ */
+ public static Map<Class<?>, CurrentInstance> getInstances(
+ boolean onlyInheritable) {
+ Map<Class<?>, CurrentInstance> map = instances.get();
+ if (map == null) {
+ return Collections.emptyMap();
+ } else {
+ Map<Class<?>, CurrentInstance> copy = new HashMap<Class<?>, CurrentInstance>();
+ for (Class<?> c : map.keySet()) {
+ CurrentInstance ci = map.get(c);
+ if (ci.inheritable || !onlyInheritable) {
+ copy.put(c, ci);
+ }
+ }
+ return copy;
+ }
+ }
+
+ /**
+ * Sets current instances for the UI and all related classes. The previously
+ * defined values can be restored by passing the returned map to
+ * {@link #restoreInstances(Map)}.
+ *
+ * @since 7.1
*
* @param ui
* The UI
- * @return A map containing the old values of the thread locals this method
+ * @return A map containing the old values of the instances that this method
* updated.
*/
- public static Map<Class<?>, CurrentInstance> setThreadLocals(UI ui) {
+ public static Map<Class<?>, CurrentInstance> setCurrent(UI ui) {
Map<Class<?>, CurrentInstance> old = new HashMap<Class<?>, CurrentInstance>();
old.put(UI.class, new CurrentInstance(UI.getCurrent(), true));
UI.setCurrent(ui);
- old.putAll(setThreadLocals(ui.getSession()));
+ old.putAll(setCurrent(ui.getSession()));
return old;
}
/**
- * Sets thread locals for the {@link VaadinSession} and all related classes
+ * Sets current instances for the {@link VaadinSession} and all related
+ * classes. The previously defined values can be restored by passing the
+ * returned map to {@link #restoreInstances(Map)}.
+ *
+ * @since 7.1
*
* @param session
* The VaadinSession
- * @return A map containing the old values of the thread locals this method
+ * @return A map containing the old values of the instances this method
* updated.
*/
- public static Map<Class<?>, CurrentInstance> setThreadLocals(
+ public static Map<Class<?>, CurrentInstance> setCurrent(
VaadinSession session) {
Map<Class<?>, CurrentInstance> old = new HashMap<Class<?>, CurrentInstance>();
old.put(VaadinSession.class,
@@ -236,18 +264,6 @@ public class CurrentInstance implements Serializable {
VaadinSession.setCurrent(session);
VaadinService.setCurrent(service);
- if (service instanceof VaadinServletService) {
- old.put(VaadinServlet.class,
- new CurrentInstance(VaadinServlet.getCurrent(), true));
- VaadinServlet.setCurrent(((VaadinServletService) service)
- .getServlet());
- } else if (portletAvailable && service instanceof VaadinPortletService) {
- old.put(VaadinPortlet.class,
- new CurrentInstance(VaadinPortlet.getCurrent(), true));
- VaadinPortlet.setCurrent(((VaadinPortletService) service)
- .getPortlet());
- }
-
return old;
}
}
diff --git a/server/tests/src/com/vaadin/server/MockServletConfig.java b/server/tests/src/com/vaadin/server/MockServletConfig.java
new file mode 100644
index 0000000000..cd1201c249
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/MockServletConfig.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ *
+ */
+package com.vaadin.server;
+
+import java.util.Enumeration;
+import java.util.Properties;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+/**
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class MockServletConfig implements ServletConfig {
+
+ private ServletContext context = new MockServletContext();
+ private final Properties initParameters;
+
+ public MockServletConfig() {
+ this(new Properties());
+ }
+
+ public MockServletConfig(Properties initParameters) {
+ this.initParameters = initParameters;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletConfig#getServletName()
+ */
+ @Override
+ public String getServletName() {
+ return "Mock Servlet";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletConfig#getServletContext()
+ */
+ @Override
+ public ServletContext getServletContext() {
+ return context;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletConfig#getInitParameter(java.lang.String)
+ */
+ @Override
+ public String getInitParameter(String name) {
+ return initParameters.getProperty(name);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletConfig#getInitParameterNames()
+ */
+ @Override
+ public Enumeration getInitParameterNames() {
+ return initParameters.propertyNames();
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/server/MockServletContext.java b/server/tests/src/com/vaadin/server/MockServletContext.java
new file mode 100644
index 0000000000..40d79190f6
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/MockServletContext.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ *
+ */
+package com.vaadin.server;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Set;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+/**
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class MockServletContext implements ServletContext {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getContext(java.lang.String)
+ */
+ @Override
+ public ServletContext getContext(String uripath) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getMajorVersion()
+ */
+ @Override
+ public int getMajorVersion() {
+ return 2;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getMinorVersion()
+ */
+ @Override
+ public int getMinorVersion() {
+ return 4;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getMimeType(java.lang.String)
+ */
+ @Override
+ public String getMimeType(String file) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getResourcePaths(java.lang.String)
+ */
+ @Override
+ public Set getResourcePaths(String path) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getResource(java.lang.String)
+ */
+ @Override
+ public URL getResource(String path) throws MalformedURLException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getResourceAsStream(java.lang.String)
+ */
+ @Override
+ public InputStream getResourceAsStream(String path) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getRequestDispatcher(java.lang.String)
+ */
+ @Override
+ public RequestDispatcher getRequestDispatcher(String path) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String)
+ */
+ @Override
+ public RequestDispatcher getNamedDispatcher(String name) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getServlet(java.lang.String)
+ */
+ @Override
+ public Servlet getServlet(String name) throws ServletException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getServlets()
+ */
+ @Override
+ public Enumeration getServlets() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getServletNames()
+ */
+ @Override
+ public Enumeration getServletNames() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#log(java.lang.String)
+ */
+ @Override
+ public void log(String msg) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#log(java.lang.Exception,
+ * java.lang.String)
+ */
+ @Override
+ public void log(Exception exception, String msg) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#log(java.lang.String,
+ * java.lang.Throwable)
+ */
+ @Override
+ public void log(String message, Throwable throwable) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getRealPath(java.lang.String)
+ */
+ @Override
+ public String getRealPath(String path) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getServerInfo()
+ */
+ @Override
+ public String getServerInfo() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getInitParameter(java.lang.String)
+ */
+ @Override
+ public String getInitParameter(String name) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getInitParameterNames()
+ */
+ @Override
+ public Enumeration getInitParameterNames() {
+ return Collections.enumeration(Collections.EMPTY_LIST);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getAttribute(java.lang.String)
+ */
+ @Override
+ public Object getAttribute(String name) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getAttributeNames()
+ */
+ @Override
+ public Enumeration getAttributeNames() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#setAttribute(java.lang.String,
+ * java.lang.Object)
+ */
+ @Override
+ public void setAttribute(String name, Object object) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#removeAttribute(java.lang.String)
+ */
+ @Override
+ public void removeAttribute(String name) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.ServletContext#getServletContextName()
+ */
+ @Override
+ public String getServletContextName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/server/VaadinServletConfigurationTest.java b/server/tests/src/com/vaadin/server/VaadinServletConfigurationTest.java
new file mode 100644
index 0000000000..80cb1d7b0c
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/VaadinServletConfigurationTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ *
+ */
+package com.vaadin.server;
+
+import java.util.Properties;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import junit.framework.Assert;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import com.vaadin.annotations.VaadinServletConfiguration;
+import com.vaadin.server.DeploymentConfiguration.LegacyProperyToStringMode;
+import com.vaadin.server.VaadinServletConfigurationTest.MockUI;
+import com.vaadin.ui.UI;
+
+public class VaadinServletConfigurationTest {
+ public static class MockUI extends UI {
+ @Override
+ protected void init(VaadinRequest request) {
+ // Do nothing
+ }
+ }
+
+ @Test
+ public void testValuesFromAnnotation() throws ServletException {
+ TestServlet servlet = new TestServlet();
+ servlet.init(new MockServletConfig());
+ DeploymentConfiguration configuration = servlet.getService()
+ .getDeploymentConfiguration();
+
+ Assert.assertEquals(true, configuration.isProductionMode());
+ Assert.assertEquals(LegacyProperyToStringMode.DISABLED,
+ configuration.getLegacyPropertyToStringMode());
+ Assert.assertEquals(true, configuration.isCloseIdleSessions());
+ Assert.assertEquals(1234, configuration.getHeartbeatInterval());
+ Assert.assertEquals(4321, configuration.getResourceCacheTime());
+
+ Class<? extends UI> uiClass = new DefaultUIProvider()
+ .getUIClass(new UIClassSelectionEvent(new VaadinServletRequest(
+ EasyMock.createMock(HttpServletRequest.class), servlet
+ .getService())));
+ Assert.assertEquals(MockUI.class, uiClass);
+ }
+
+ @Test
+ public void testValuesOverriddenForServlet() throws ServletException {
+ Properties servletInitParams = new Properties();
+ servletInitParams.setProperty("productionMode", "false");
+ servletInitParams.setProperty("heartbeatInterval", "1111");
+
+ TestServlet servlet = new TestServlet();
+ servlet.init(new MockServletConfig(servletInitParams));
+ DeploymentConfiguration configuration = servlet.getService()
+ .getDeploymentConfiguration();
+
+ // Values from servlet init params take precedence
+ Assert.assertEquals(1111, configuration.getHeartbeatInterval());
+ Assert.assertEquals(false, configuration.isProductionMode());
+
+ // Other params are as defined in the annotation
+ Assert.assertEquals(LegacyProperyToStringMode.DISABLED,
+ configuration.getLegacyPropertyToStringMode());
+ Assert.assertEquals(true, configuration.isCloseIdleSessions());
+ Assert.assertEquals(4321, configuration.getResourceCacheTime());
+
+ Class<? extends UI> uiClass = new DefaultUIProvider()
+ .getUIClass(new UIClassSelectionEvent(new VaadinServletRequest(
+ EasyMock.createMock(HttpServletRequest.class), servlet
+ .getService())));
+ Assert.assertEquals(MockUI.class, uiClass);
+ }
+}
+
+@VaadinServletConfiguration(productionMode = true, ui = MockUI.class, closeIdleSessions = true, heartbeatInterval = 1234, resourceCacheTime = 4321)
+class TestServlet extends VaadinServlet {
+
+}
diff --git a/server/tests/src/com/vaadin/server/VaadinSessionTest.java b/server/tests/src/com/vaadin/server/VaadinSessionTest.java
index 61a1581a6f..68f198410c 100644
--- a/server/tests/src/com/vaadin/server/VaadinSessionTest.java
+++ b/server/tests/src/com/vaadin/server/VaadinSessionTest.java
@@ -18,6 +18,7 @@ package com.vaadin.server;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;
+import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
@@ -30,7 +31,6 @@ import org.junit.Test;
import com.vaadin.server.ClientConnector.DetachEvent;
import com.vaadin.server.ClientConnector.DetachListener;
-import com.vaadin.tests.util.MockDeploymentConfiguration;
import com.vaadin.ui.UI;
import com.vaadin.util.CurrentInstance;
@@ -39,6 +39,7 @@ public class VaadinSessionTest {
private VaadinSession session;
private VaadinServlet mockServlet;
private VaadinServletService mockService;
+ private ServletConfig mockServletConfig;
private HttpSession mockHttpSession;
private WrappedSession mockWrappedSession;
private VaadinServletRequest vaadinRequest;
@@ -46,24 +47,22 @@ public class VaadinSessionTest {
@Before
public void setup() throws Exception {
- mockServlet = new VaadinServlet() {
- @Override
- public String getServletName() {
- return "mockServlet";
- };
- };
-
- mockService = new VaadinServletService(mockServlet,
- new MockDeploymentConfiguration());
- mockService.init();
+ mockServletConfig = new MockServletConfig();
+ mockServlet = new VaadinServlet();
+ mockServlet.init(mockServletConfig);
+ mockService = mockServlet.getService();
mockHttpSession = EasyMock.createMock(HttpSession.class);
mockWrappedSession = new WrappedHttpSession(mockHttpSession) {
final ReentrantLock lock = new ReentrantLock();
+ {
+ lock.lock();
+ }
@Override
public Object getAttribute(String name) {
- if ("mockServlet.lock".equals(name)) {
+ String lockAttribute = mockService.getServiceName() + ".lock";
+ if (lockAttribute.equals(name)) {
return lock;
}
return super.getAttribute(name);
diff --git a/server/tests/src/com/vaadin/tests/data/bean/AnotherTestEnum.java b/server/tests/src/com/vaadin/tests/data/bean/AnotherTestEnum.java
new file mode 100644
index 0000000000..fc8f22a947
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/bean/AnotherTestEnum.java
@@ -0,0 +1,16 @@
+package com.vaadin.tests.data.bean;
+
+public enum AnotherTestEnum {
+ ONE("ONE"), TWO("TWO");
+
+ private String id;
+
+ private AnotherTestEnum(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return id;
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/data/bean/TestEnum.java b/server/tests/src/com/vaadin/tests/data/bean/TestEnum.java
new file mode 100644
index 0000000000..bf6f721052
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/bean/TestEnum.java
@@ -0,0 +1,16 @@
+package com.vaadin.tests.data.bean;
+
+public enum TestEnum {
+ ONE("1"), TWO("2");
+
+ private String id;
+
+ private TestEnum(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return id;
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestAnyEnumToStringConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestAnyEnumToStringConverter.java
new file mode 100644
index 0000000000..c267e012e8
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/converter/TestAnyEnumToStringConverter.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.tests.data.converter;
+
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.ReverseConverter;
+import com.vaadin.tests.data.bean.AnotherTestEnum;
+import com.vaadin.tests.data.bean.TestEnum;
+import com.vaadin.ui.TextField;
+
+public class TestAnyEnumToStringConverter {
+
+ public class AnyEnumToStringConverter implements Converter<Enum, String> {
+
+ private Class<? extends Enum>[] enumClass;
+
+ public AnyEnumToStringConverter(Class<? extends Enum>... enumClass) {
+ this.enumClass = enumClass;
+ }
+
+ @Override
+ public String convertToModel(Enum value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return value.toString();
+ }
+
+ @Override
+ public Enum convertToPresentation(String value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+ for (Class<? extends Enum> candidate : enumClass) {
+ for (Enum e : candidate.getEnumConstants()) {
+ if (e.toString().equals(value)) {
+ return e;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Class<String> getModelType() {
+ return String.class;
+ }
+
+ @Override
+ public Class<Enum> getPresentationType() {
+ return Enum.class;
+ }
+
+ }
+
+ private AnyEnumToStringConverter converter;
+
+ @Before
+ public void setup() {
+ converter = new AnyEnumToStringConverter(TestEnum.class,
+ AnotherTestEnum.class);
+ }
+
+ @Test
+ public void nullConversion() {
+ Assert.assertEquals(null, converter.convertToModel(null, null));
+ }
+
+ @Test
+ public void enumToStringConversion() {
+ Assert.assertEquals(TestEnum.TWO.toString(),
+ converter.convertToModel(TestEnum.TWO, null));
+ Assert.assertEquals(AnotherTestEnum.TWO.toString(),
+ converter.convertToModel(AnotherTestEnum.TWO, null));
+ }
+
+ @Test
+ public void stringToEnumConversion() {
+ Assert.assertEquals(TestEnum.TWO,
+ converter.convertToPresentation(TestEnum.TWO.toString(), null));
+ Assert.assertEquals(AnotherTestEnum.TWO, converter
+ .convertToPresentation(AnotherTestEnum.TWO.toString(), null));
+ }
+
+ @Test
+ public void stringToEnumWithField() {
+ TextField tf = new TextField();
+ tf.setConverter(new ReverseConverter(converter));
+ tf.setPropertyDataSource(new ObjectProperty(AnotherTestEnum.TWO));
+ Assert.assertEquals(AnotherTestEnum.TWO.toString(), tf.getValue());
+ tf.setValue(AnotherTestEnum.ONE.toString());
+ Assert.assertEquals(AnotherTestEnum.ONE.toString(), tf.getValue());
+ Assert.assertEquals(AnotherTestEnum.ONE, tf.getConvertedValue());
+ Assert.assertEquals(AnotherTestEnum.ONE, tf.getPropertyDataSource()
+ .getValue());
+
+ tf.setPropertyDataSource(new ObjectProperty(TestEnum.TWO));
+ Assert.assertEquals(TestEnum.TWO.toString(), tf.getValue());
+ tf.setValue(TestEnum.ONE.toString());
+ Assert.assertEquals(TestEnum.ONE.toString(), tf.getValue());
+ Assert.assertEquals(TestEnum.ONE, tf.getConvertedValue());
+ Assert.assertEquals(TestEnum.ONE, tf.getPropertyDataSource().getValue());
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestSpecificEnumToStringConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestSpecificEnumToStringConverter.java
new file mode 100644
index 0000000000..93dbe96b56
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/converter/TestSpecificEnumToStringConverter.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.tests.data.converter;
+
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.ReverseConverter;
+import com.vaadin.tests.data.bean.AnotherTestEnum;
+import com.vaadin.tests.data.bean.TestEnum;
+import com.vaadin.ui.TextField;
+
+public class TestSpecificEnumToStringConverter {
+
+ public class SpecificEnumToStringConverter implements
+ Converter<Enum, String> {
+
+ private Class<? extends Enum> enumClass;
+
+ public SpecificEnumToStringConverter(Class<? extends Enum> enumClass) {
+ this.enumClass = enumClass;
+ }
+
+ @Override
+ public String convertToModel(Enum value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return value.toString();
+ }
+
+ @Override
+ public Enum convertToPresentation(String value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ for (Enum e : enumClass.getEnumConstants()) {
+ if (e.toString().equals(value)) {
+ return e;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Class<String> getModelType() {
+ return String.class;
+ }
+
+ @Override
+ public Class<Enum> getPresentationType() {
+ return (Class<Enum>) enumClass;
+ }
+
+ }
+
+ SpecificEnumToStringConverter testEnumConverter;
+ SpecificEnumToStringConverter anotherTestEnumConverter;
+
+ @Before
+ public void setup() {
+ testEnumConverter = new SpecificEnumToStringConverter(TestEnum.class);
+ anotherTestEnumConverter = new SpecificEnumToStringConverter(
+ AnotherTestEnum.class);
+ }
+
+ @Test
+ public void nullConversion() {
+ Assert.assertEquals(null, testEnumConverter.convertToModel(null, null));
+ }
+
+ @Test
+ public void enumToStringConversion() {
+ Assert.assertEquals(TestEnum.TWO.toString(),
+ testEnumConverter.convertToModel(TestEnum.TWO, null));
+ }
+
+ @Test
+ public void stringToEnumConversion() {
+ Assert.assertEquals(TestEnum.TWO, testEnumConverter
+ .convertToPresentation(TestEnum.TWO.toString(), null));
+ }
+
+ @Test
+ public void stringToEnumWithField() {
+ TextField tf = new TextField();
+ tf.setConverter(new ReverseConverter(anotherTestEnumConverter));
+ tf.setPropertyDataSource(new ObjectProperty(AnotherTestEnum.TWO));
+ Assert.assertEquals(AnotherTestEnum.TWO.toString(), tf.getValue());
+ tf.setValue(AnotherTestEnum.ONE.toString());
+ Assert.assertEquals(AnotherTestEnum.ONE.toString(), tf.getValue());
+ Assert.assertEquals(AnotherTestEnum.ONE, tf.getConvertedValue());
+ Assert.assertEquals(AnotherTestEnum.ONE, tf.getPropertyDataSource()
+ .getValue());
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java
index 90cb6b9994..af6d9ed732 100644
--- a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java
+++ b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java
@@ -7,6 +7,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
@@ -33,6 +34,7 @@ public class TestClassesSerializable extends TestCase {
"com\\.vaadin\\.launcher\\..*", //
"com\\.vaadin\\.client\\..*", //
"com\\.vaadin\\.server\\.widgetsetutils\\..*", //
+ "com\\.vaadin\\.server\\.themeutils\\..*", //
"com\\.vaadin\\.tests\\..*", // exclude automated tests
"com\\.vaadin\\.tools\\..*", //
"com\\.vaadin\\.ui\\.themes\\..*", //
@@ -41,7 +43,13 @@ public class TestClassesSerializable extends TestCase {
"com\\.vaadin\\.event\\.LayoutEvents", //
"com\\.vaadin\\.event\\.MouseEvents", //
"com\\.vaadin\\.server\\.VaadinPortlet", //
+ "com\\.vaadin\\.server\\.MockServletConfig", //
+ "com\\.vaadin\\.server\\.MockServletContext", //
"com\\.vaadin\\.server\\.Constants", //
+ "com\\.vaadin\\.server\\.communication\\.FileUploadHandler\\$SimpleMultiPartInputStream", //
+ "com\\.vaadin\\.server\\.communication\\.PushRequestHandler.*",
+ "com\\.vaadin\\.server\\.communication\\.PushHandler.*", // PushHandler
+ // and its inner classes do not need to be serializable
"com\\.vaadin\\.util\\.SerializerHelper", // fully static
// class level filtering, also affecting nested classes and
// interfaces
@@ -50,6 +58,7 @@ public class TestClassesSerializable extends TestCase {
"com\\.vaadin\\.util\\.ReflectTools.*", //
"com\\.vaadin\\.data\\.util\\.ReflectTools.*", //
"com\\.vaadin\\.sass.*", //
+ "com\\.vaadin\\.testbench.*", //
"com\\.vaadin\\.util\\.CurrentInstance\\$1", //
};
@@ -88,6 +97,19 @@ public class TestClassesSerializable extends TestCase {
// report non-serializable classes and interfaces
if (!Serializable.class.isAssignableFrom(cls)) {
+ if (cls.getSuperclass() == Object.class
+ && cls.getInterfaces().length == 1) {
+ // Single interface implementors
+ Class<?> iface = cls.getInterfaces()[0];
+
+ if (iface == Runnable.class) {
+ // Ignore Runnables used with access()
+ continue;
+ } else if (iface == Comparator.class) {
+ // Ignore inline comparators
+ continue;
+ }
+ }
nonSerializableClasses.add(cls);
// TODO easier to read when testing
// System.err.println(cls);
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValidators.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValidators.java
index 19c58fe6d3..764446f7aa 100644
--- a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValidators.java
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValidators.java
@@ -8,7 +8,7 @@ import com.vaadin.data.Validator;
import com.vaadin.ui.AbstractField;
import com.vaadin.ui.Field;
-public class AbstractFieldValidators extends TestCase {
+public class AbsFieldValidators extends TestCase {
Field<Object> field = new AbstractField<Object>() {
@Override
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversions.java
index 3c4d43543b..b5e937f27d 100644
--- a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversions.java
@@ -21,7 +21,7 @@ import com.vaadin.tests.util.AlwaysLockedVaadinSession;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.TextField;
-public class AbstractFieldValueConversions extends TestCase {
+public class AbsFieldValueConversions extends TestCase {
Person paulaBean = new Person("Paula", "Brilliant", "paula@brilliant.com",
34, Sex.FEMALE, new Address("Paula street 1", 12345, "P-town",
diff --git a/server/tests/src/com/vaadin/ui/AbstractFieldDataSourceLocaleChange.java b/server/tests/src/com/vaadin/ui/AbsFieldDataSourceLocaleChange.java
index 9810873f0b..acea0a84c7 100644
--- a/server/tests/src/com/vaadin/ui/AbstractFieldDataSourceLocaleChange.java
+++ b/server/tests/src/com/vaadin/ui/AbsFieldDataSourceLocaleChange.java
@@ -12,7 +12,7 @@ import com.vaadin.data.util.converter.StringToIntegerConverter;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinSession;
-public class AbstractFieldDataSourceLocaleChange {
+public class AbsFieldDataSourceLocaleChange {
private VaadinSession vaadinSession;
private UI ui;
diff --git a/shared/build.xml b/shared/build.xml
index 8520ee6eba..67dd3e9843 100644
--- a/shared/build.xml
+++ b/shared/build.xml
@@ -1,64 +1,66 @@
<?xml version="1.0"?>
-<project name="vaadin-shared" basedir="." default="publish-local" xmlns:ivy="antlib:org.apache.ivy.ant">
- <description>
- Compiles build helpers used when building other modules.
- </description>
- <include file="../common.xml" as="common" />
- <include file="../build.xml" as="vaadin" />
- <include file="../gwt-files.xml" as="gwtfiles" />
+<project name="vaadin-shared" basedir="." default="publish-local"
+ xmlns:ivy="antlib:org.apache.ivy.ant">
+ <description>
+ Compiles build helpers used when building other modules.
+ </description>
+ <include file="../common.xml" as="common" />
+ <include file="../build.xml" as="vaadin" />
+ <include file="../gwt-files.xml" as="gwtfiles" />
- <!-- global properties -->
- <property name="module.name" value="vaadin-shared" />
- <property name="module.symbolic" value="com.vaadin.shared" />
- <property name="result.dir" location="result" />
- <property name="src.filtered" location="${result.dir}/filtered-src" />
- <property name="src" location="${src.filtered}" />
- <path id="classpath.compile.custom" />
+ <!-- global properties -->
+ <property name="module.name" value="vaadin-shared" />
+ <property name="module.symbolic" value="com.vaadin.shared" />
+ <property name="result.dir" location="result" />
+ <property name="src.filtered" location="${result.dir}/filtered-src" />
+ <property name="src" location="${src.filtered}" />
+ <path id="classpath.compile.custom" />
- <target name="jar">
- <property name="shared.osgi.import" value="org.json;version=&quot;0.0.20080701&quot;, com.google.gwt.thirdparty.guava.common.annotations;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.base;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.base.internal;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.cache;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.collect;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.eventbus;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.io;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.net;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.primitives;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.util.concurrent;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.streamhtmlparser;version=&quot;0.1.5.r10-rebased&quot;, com.google.gwt.thirdparty.streamhtmlparser.impl;version=&quot;0.1.5.r10-rebased&quot;, com.google.gwt.thirdparty.streamhtmlparser.util;version=&quot;0.1.5.r10-rebased&quot;, org.w3c.flute.parser;version=&quot;1.3.0.gg2&quot;, org.w3c.flute.parser.selectors;version=&quot;1.3.0.gg2&quot;, org.w3c.flute.util;version=&quot;1.3.0.gg2&quot;" />
- <delete dir="${src.filtered}" />
- <!-- Update version in Version.java -->
- <copy todir="${src.filtered}">
- <fileset dir="src">
- </fileset>
- <filterchain>
- <replacetokens begintoken="@" endtoken="@">
- <token key="VERSION" value="${vaadin.version}" />
- </replacetokens>
- </filterchain>
- </copy>
+ <target name="jar">
+ <property name="shared.osgi.import"
+ value="org.json;version=&quot;0.0.20080701&quot;, com.google.gwt.thirdparty.guava.common.annotations;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.base;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.base.internal;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.cache;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.collect;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.eventbus;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.io;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.net;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.primitives;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.guava.common.util.concurrent;version=&quot;10.0.1.rebased&quot;, com.google.gwt.thirdparty.streamhtmlparser;version=&quot;0.1.5.r10-rebased&quot;, com.google.gwt.thirdparty.streamhtmlparser.impl;version=&quot;0.1.5.r10-rebased&quot;, com.google.gwt.thirdparty.streamhtmlparser.util;version=&quot;0.1.5.r10-rebased&quot;, org.w3c.flute.parser;version=&quot;1.3.0.gg2&quot;, org.w3c.flute.parser.selectors;version=&quot;1.3.0.gg2&quot;, org.w3c.flute.util;version=&quot;1.3.0.gg2&quot;" />
+ <delete dir="${src.filtered}" />
+ <!-- Update version in Version.java -->
+ <copy todir="${src.filtered}">
+ <fileset dir="src">
+ </fileset>
+ <filterchain>
+ <replacetokens begintoken="@" endtoken="@">
+ <token key="VERSION" value="${vaadin.version}" />
+ </replacetokens>
+ </filterchain>
+ </copy>
- <antcall target="common.jar">
- <param name="import-package" value="${shared.osgi.import}" />
- <reference refid="shared.gwt.includes" torefid="extra.jar.includes" />
- </antcall>
- </target>
+ <antcall target="common.jar">
+ <param name="import-package" value="${shared.osgi.import}" />
+ <reference refid="shared.gwt.includes" torefid="extra.jar.includes" />
+ </antcall>
+ </target>
- <target name="publish-local" depends="jar">
- <antcall target="common.sources.jar">
- <reference torefid="extra.jar.includes" refid="shared.gwt.includes" />
- </antcall>
- <antcall target="common.javadoc.jar" />
+ <target name="publish-local" depends="jar">
+ <antcall target="common.sources.jar">
+ <reference torefid="extra.jar.includes" refid="shared.gwt.includes" />
+ </antcall>
+ <antcall target="common.javadoc.jar" />
- <antcall target="common.publish-local" />
- </target>
+ <antcall target="common.publish-local" />
+ </target>
- <target name="clean">
- <antcall target="common.clean" />
- </target>
-
- <target name="checkstyle">
- <antcall target="common.checkstyle">
- <param name="cs.src" location="src" />
- </antcall>
- </target>
+ <target name="clean">
+ <antcall target="common.clean" />
+ </target>
- <target name="test" depends="checkstyle">
- <!--<antcall target="common.test.run" />-->
- <echo>WHAT? No tests for ${module.name}!</echo>
- </target>
+ <target name="checkstyle">
+ <antcall target="common.checkstyle">
+ <param name="cs.src" location="src" />
+ </antcall>
+ </target>
+
+ <target name="test" depends="checkstyle">
+ <!--<antcall target="common.test.run" /> -->
+ <echo>WHAT? No tests for ${module.name}!</echo>
+ </target>
</project> \ No newline at end of file
diff --git a/shared/src/com/vaadin/shared/ApplicationConstants.java b/shared/src/com/vaadin/shared/ApplicationConstants.java
index fc4abd1988..e51139dac7 100644
--- a/shared/src/com/vaadin/shared/ApplicationConstants.java
+++ b/shared/src/com/vaadin/shared/ApplicationConstants.java
@@ -39,9 +39,6 @@ public class ApplicationConstants implements Serializable {
+ "://";
public static final String UIDL_SECURITY_TOKEN_ID = "Vaadin-Security-Key";
- public static final String PARAM_ANALYZE_LAYOUTS = "analyzeLayouts";
- public static final String PARAM_HIGHLIGHT_CONNECTOR = "highlightConnector";
-
@Deprecated
public static final String UPDATE_VARIABLE_INTERFACE = "v";
@Deprecated
@@ -83,8 +80,4 @@ public class ApplicationConstants implements Serializable {
* Name of the parameter used to transmit the CSRF token.
*/
public static final String CSRF_TOKEN_PARAMETER = "v-csrfToken";
-
- public static final int WEBSOCKET_BUFFER_SIZE = 65536;
-
- public static final char WEBSOCKET_MESSAGE_DELIMITER = '|';
}
diff --git a/shared/src/com/vaadin/shared/communication/PushConstants.java b/shared/src/com/vaadin/shared/communication/PushConstants.java
new file mode 100644
index 0000000000..f16cbb7390
--- /dev/null
+++ b/shared/src/com/vaadin/shared/communication/PushConstants.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.shared.communication;
+
+import java.io.Serializable;
+
+/**
+ * Shared constants used by push.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public class PushConstants implements Serializable {
+
+ /**
+ * The size, in <b>bytes</b>, of the receiving buffer used by some servers.
+ */
+ public static final int WEBSOCKET_BUFFER_SIZE = 65536;
+
+ /**
+ * The maximum size, in <b>characters</b>, of a websocket message fragment.
+ * This is a conservative maximum chosen so that the size in bytes will not
+ * exceed {@link PushConstants#WEBSOCKET_BUFFER_SIZE} given a UTF-8 encoded
+ * message.
+ */
+ public static final int WEBSOCKET_FRAGMENT_SIZE = WEBSOCKET_BUFFER_SIZE / 4 - 1;
+
+ /**
+ * The character used to mark message boundaries when messages may be split
+ * into multiple fragments.
+ */
+ public static final char MESSAGE_DELIMITER = '|';
+}
diff --git a/shared/src/com/vaadin/shared/communication/SharedState.java b/shared/src/com/vaadin/shared/communication/SharedState.java
index 17b6fd7ab4..57c3e801b5 100644
--- a/shared/src/com/vaadin/shared/communication/SharedState.java
+++ b/shared/src/com/vaadin/shared/communication/SharedState.java
@@ -54,9 +54,9 @@ public class SharedState implements Serializable {
/**
* The automatically managed resources used by the connector.
*
- * @see com.vaadin.terminal.AbstractClientConnector#setResource(String,
- * com.vaadin.terminal.Resource)
- * @see com.vaadin.terminal.gwt.client.ui.AbstractConnector#getResourceUrl(String)
+ * @see com.vaadin.server.AbstractClientConnector#setResource(String,
+ * com.vaadin.server.Resource)
+ * @see com.vaadin.client.ui.AbstractConnector#getResourceUrl(String)
*/
public Map<String, URLReference> resources = new HashMap<String, URLReference>();
diff --git a/shared/src/com/vaadin/shared/ui/calendar/CalendarEventId.java b/shared/src/com/vaadin/shared/ui/calendar/CalendarEventId.java
index 6f52aabf43..27f1cdd341 100644
--- a/shared/src/com/vaadin/shared/ui/calendar/CalendarEventId.java
+++ b/shared/src/com/vaadin/shared/ui/calendar/CalendarEventId.java
@@ -15,6 +15,8 @@
*/
package com.vaadin.shared.ui.calendar;
+import java.io.Serializable;
+
/**
* CalendarEventId contains static String identifiers for all Calendar events.
* These are used both in the client and server side code.
@@ -22,7 +24,7 @@ package com.vaadin.shared.ui.calendar;
* @since 7.1
* @author Vaadin Ltd.
*/
-public class CalendarEventId {
+public class CalendarEventId implements Serializable {
public static final String EVENTMOVE = "eventMove";
public static final String RANGESELECT = "rangeSelect";
diff --git a/shared/src/com/vaadin/shared/ui/calendar/DateConstants.java b/shared/src/com/vaadin/shared/ui/calendar/DateConstants.java
index 8a840274c2..9b1c995642 100644
--- a/shared/src/com/vaadin/shared/ui/calendar/DateConstants.java
+++ b/shared/src/com/vaadin/shared/ui/calendar/DateConstants.java
@@ -15,12 +15,14 @@
*/
package com.vaadin.shared.ui.calendar;
+import java.io.Serializable;
+
/**
*
* @since 7.1
*
*/
-public class DateConstants {
+public class DateConstants implements Serializable {
public static final String ACTION_DATE_FORMAT_PATTERN = "yyyy-MM-dd HH:mm:ss";
public static final String CLIENT_DATE_FORMAT = "yyyy-MM-dd";
diff --git a/shared/src/com/vaadin/shared/ui/progressindicator/ProgressBarState.java b/shared/src/com/vaadin/shared/ui/progressindicator/ProgressBarState.java
new file mode 100644
index 0000000000..1cc8d7d9ae
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/progressindicator/ProgressBarState.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.shared.ui.progressindicator;
+
+import com.vaadin.shared.AbstractFieldState;
+import com.vaadin.shared.communication.SharedState;
+
+/**
+ * {@link SharedState} for {@link com.vaadin.ui.ProgressBar}
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public class ProgressBarState extends AbstractFieldState {
+ public static final String PRIMARY_STYLE_NAME = "v-progressbar";
+
+ {
+ primaryStyleName = PRIMARY_STYLE_NAME;
+ }
+ public boolean indeterminate = false;
+ public Float state = 0.0f;
+
+} \ No newline at end of file
diff --git a/shared/src/com/vaadin/shared/ui/progressindicator/ProgressIndicatorState.java b/shared/src/com/vaadin/shared/ui/progressindicator/ProgressIndicatorState.java
index 4126b994d8..2ca7627f4f 100644
--- a/shared/src/com/vaadin/shared/ui/progressindicator/ProgressIndicatorState.java
+++ b/shared/src/com/vaadin/shared/ui/progressindicator/ProgressIndicatorState.java
@@ -15,10 +15,13 @@
*/
package com.vaadin.shared.ui.progressindicator;
-import com.vaadin.shared.AbstractFieldState;
+@Deprecated
+public class ProgressIndicatorState extends ProgressBarState {
+ public static final String PRIMARY_STYLE_NAME = "v-progressindicator";
+
+ {
+ primaryStyleName = PRIMARY_STYLE_NAME;
+ }
-public class ProgressIndicatorState extends AbstractFieldState {
- public boolean indeterminate = false;
public int pollingInterval = 1000;
- public Float state = 0.0f;
}
diff --git a/shared/src/com/vaadin/shared/ui/ui/DebugWindowClientRpc.java b/shared/src/com/vaadin/shared/ui/ui/DebugWindowClientRpc.java
new file mode 100644
index 0000000000..7e76a6a459
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/ui/DebugWindowClientRpc.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.shared.ui.ui;
+
+import com.vaadin.shared.communication.ClientRpc;
+
+/**
+ * Client RPC methods for the Debug Window.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public interface DebugWindowClientRpc extends ClientRpc {
+
+ /**
+ * Send results from {@link DebugWindowServerRpc#analyzeLayouts()} back to
+ * the client.
+ *
+ * @since 7.1
+ * @param json
+ * JSON containing list of found problems
+ */
+ public void reportLayoutProblems(String json);
+
+}
diff --git a/shared/src/com/vaadin/shared/ui/ui/DebugWindowServerRpc.java b/shared/src/com/vaadin/shared/ui/ui/DebugWindowServerRpc.java
new file mode 100644
index 0000000000..76e7d23379
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/ui/DebugWindowServerRpc.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ *
+ */
+package com.vaadin.shared.ui.ui;
+
+import com.vaadin.shared.Connector;
+import com.vaadin.shared.communication.ServerRpc;
+
+/**
+ * Server RPC methods for the Debug Window.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public interface DebugWindowServerRpc extends ServerRpc {
+ /**
+ * Sends a request to the server to print details to console that will help
+ * the developer to locate the corresponding server-side connector in the
+ * source code.
+ *
+ * @since 7.1
+ * @param connector
+ * the connector to locate
+ **/
+ public void showServerDebugInfo(Connector connector);
+
+ /**
+ * Invokes the layout analyzer on the server
+ *
+ * @since 7.1
+ */
+ public void analyzeLayouts();
+
+}
diff --git a/shared/src/com/vaadin/shared/ui/ui/Transport.java b/shared/src/com/vaadin/shared/ui/ui/Transport.java
new file mode 100644
index 0000000000..69d713bcca
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/ui/Transport.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.shared.ui.ui;
+
+/**
+ * Transport modes for Push
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public enum Transport {
+ /**
+ * Websockets
+ */
+ WEBSOCKET("websocket"),
+ /**
+ * HTTP streaming
+ */
+ STREAMING("streaming");
+
+ /**
+ * The default transport mechanism for push
+ */
+ public static final Transport DEFAULT = Transport.WEBSOCKET;
+
+ /**
+ * The default fallback transport mechanism for push
+ */
+ public static final Transport DEFAULT_FALLBACK = Transport.STREAMING;
+
+ private String identifier;
+
+ private Transport(String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+}
diff --git a/shared/src/com/vaadin/shared/ui/ui/UIState.java b/shared/src/com/vaadin/shared/ui/ui/UIState.java
index 16c1ed16c7..e19a87ada9 100644
--- a/shared/src/com/vaadin/shared/ui/ui/UIState.java
+++ b/shared/src/com/vaadin/shared/ui/ui/UIState.java
@@ -16,6 +16,10 @@
package com.vaadin.shared.ui.ui;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import com.vaadin.shared.communication.PushMode;
import com.vaadin.shared.ui.TabIndexState;
@@ -25,8 +29,6 @@ public class UIState extends TabIndexState {
public LoadingIndicatorConfigurationState loadingIndicatorConfiguration = new LoadingIndicatorConfigurationState();
public int pollInterval = -1;
- public PushMode pushMode = PushMode.DISABLED;
-
// Informing users of assistive devices, that the content of this container
// is announced automatically and does not need to be navigated into
public String overlayContainerLabel = "This content is announced automatically and does not need to be navigated into.";
@@ -46,14 +48,56 @@ public class UIState extends TabIndexState {
public int maxWidth = 500;
}
+ public static class PushConfigurationState implements Serializable {
+ public static final String TRANSPORT_PARAM = "transport";
+ public static final String FALLBACK_TRANSPORT_PARAM = "fallbackTransport";
+
+ public PushMode mode = PushMode.DISABLED;
+ public Map<String, String> parameters = new HashMap<String, String>();
+ {
+ parameters.put(TRANSPORT_PARAM, Transport.DEFAULT.getIdentifier());
+ parameters.put(FALLBACK_TRANSPORT_PARAM,
+ Transport.DEFAULT_FALLBACK.getIdentifier());
+ }
+ }
+
/**
- * State related to the {@link Page} class.
+ * State related to the Page class.
*/
public PageState pageState = new PageState();
+ /**
+ * State related to the LocaleService class.
+ */
+ public LocaleServiceState localeServiceState = new LocaleServiceState();
+
+ /**
+ * Configuration for the push channel
+ */
+ public PushConfigurationState pushConfiguration = new PushConfigurationState();
{
primaryStyleName = "v-ui";
// Default is 1 for legacy reasons
tabIndex = 1;
}
+
+ public static class LocaleServiceState implements Serializable {
+ public List<LocaleData> localeData = new ArrayList<LocaleData>();
+ }
+
+ public static class LocaleData implements Serializable {
+ public String name;
+ public String[] monthNames;
+ public String[] shortMonthNames;
+ public String[] shortDayNames;
+ public String[] dayNames;
+ public int firstDayOfWeek;
+ public String dateFormat;
+ public boolean twelveHourClock;
+ public String hourMinuteDelimiter;
+ public String am;
+ public String pm;
+
+ }
+
}
diff --git a/shared/src/com/vaadin/shared/ui/window/WindowServerRpc.java b/shared/src/com/vaadin/shared/ui/window/WindowServerRpc.java
index cfb10ad86a..b43765274e 100644
--- a/shared/src/com/vaadin/shared/ui/window/WindowServerRpc.java
+++ b/shared/src/com/vaadin/shared/ui/window/WindowServerRpc.java
@@ -15,13 +15,11 @@
*/
package com.vaadin.shared.ui.window;
-import com.vaadin.shared.annotations.Delayed;
import com.vaadin.shared.communication.ServerRpc;
import com.vaadin.shared.ui.ClickRpc;
public interface WindowServerRpc extends ClickRpc, ServerRpc {
- @Delayed(lastOnly = true)
public void windowModeChanged(WindowMode newState);
} \ No newline at end of file
diff --git a/shared/src/com/vaadin/shared/util/SharedUtil.java b/shared/src/com/vaadin/shared/util/SharedUtil.java
index 2242fa4363..80efe68d83 100644
--- a/shared/src/com/vaadin/shared/util/SharedUtil.java
+++ b/shared/src/com/vaadin/shared/util/SharedUtil.java
@@ -15,6 +15,8 @@
*/
package com.vaadin.shared.util;
+import java.io.Serializable;
+
/**
* Misc internal utility methods used by both the server and the client package.
*
@@ -22,7 +24,7 @@ package com.vaadin.shared.util;
* @since 7.1
*
*/
-public class SharedUtil {
+public class SharedUtil implements Serializable {
/**
* Checks if a and b are equals using {@link #equals(Object)}. Handles null
* values as well. Does not ensure that objects are of the same type.
diff --git a/theme-compiler/build.xml b/theme-compiler/build.xml
index 277929d160..b28eca8cf7 100644
--- a/theme-compiler/build.xml
+++ b/theme-compiler/build.xml
@@ -1,58 +1,64 @@
<?xml version="1.0"?>
-<project name="vaadin-theme-compiler" basedir="." default="publish-local" xmlns:ivy="antlib:org.apache.ivy.ant">
- <description>
- Compiles build helpers used when building other modules.
- </description>
- <include file="../common.xml" as="common" />
- <include file="../build.xml" as="vaadin" />
- <include file="../gwt-files.xml" as="gwtfiles" />
-
- <!-- global properties -->
- <property name="module.name" value="vaadin-theme-compiler" />
- <property name="module.symbolic" value="com.vaadin.theme-compiler" />
- <property name="result.dir" value="result" />
- <property name="sass.parser.jj" location="src/com/vaadin/sass/internal/parser/Parser.jj" />
- <path id="classpath.compile.custom">
- </path>
- <path id="classpath.test.custom" />
-
- <!--<property name="classes.exclude" value="com/vaadin/buildhelpers/**" />-->
-
- <target name="parser">
- <!-- Copy javacc-5.0.jar to ${result.dir}/javacc/javacc.jar as the javacc task requires the jar to be named javacc.jar -->
- <property name="javacc.home" location="${result.dir}/javacc" />
- <ivy:retrieve organisation="net.java.dev.javacc" module="javacc" revision="5.0" inline="true" type="jar" pattern="${javacc.home}/[artifact].[ext]" />
- <javacc target="${sass.parser.jj}" javacchome="${javacc.home}">
- </javacc>
- </target>
-
- <target name="jar" depends="parser">
- <antcall target="common.jar">
- <reference torefid="extra.jar.includes" refid="empty.reference" />
- </antcall>
- </target>
- <target name="publish-local" depends="jar">
- <antcall target="common.sources.jar">
- <reference torefid="extra.jar.includes" refid="empty.reference" />
- </antcall>
- <antcall target="common.javadoc.jar" />
-
- <antcall target="common.publish-local" />
- </target>
-
- <target name="clean">
- <antcall target="common.clean" />
- </target>
-
- <target name="checkstyle">
- <antcall target="common.checkstyle">
- <param name="cs.src" location="src" />
- </antcall>
- </target>
-
- <target name="test" depends="checkstyle">
- <antcall target="common.test.run" />
- </target>
+<project name="vaadin-theme-compiler" basedir="." default="publish-local"
+ xmlns:ivy="antlib:org.apache.ivy.ant">
+ <description>
+ Compiles build helpers used when building other modules.
+ </description>
+ <include file="../common.xml" as="common" />
+ <include file="../build.xml" as="vaadin" />
+ <include file="../gwt-files.xml" as="gwtfiles" />
+
+ <!-- global properties -->
+ <property name="module.name" value="vaadin-theme-compiler" />
+ <property name="module.symbolic" value="com.vaadin.theme-compiler" />
+ <property name="result.dir" value="result" />
+ <property name="sass.parser.jj"
+ location="src/com/vaadin/sass/internal/parser/Parser.jj" />
+ <path id="classpath.compile.custom">
+ </path>
+ <path id="classpath.test.custom" />
+
+ <!--<property name="classes.exclude" value="com/vaadin/buildhelpers/**"
+ /> -->
+
+ <target name="parser">
+ <!-- Copy javacc-5.0.jar to ${result.dir}/javacc/javacc.jar as the
+ javacc task requires the jar to be named javacc.jar -->
+ <property name="javacc.home" location="${result.dir}/javacc" />
+ <ivy:retrieve organisation="net.java.dev.javacc"
+ module="javacc" revision="5.0" inline="true" type="jar"
+ pattern="${javacc.home}/[artifact].[ext]" />
+ <javacc target="${sass.parser.jj}" javacchome="${javacc.home}">
+ </javacc>
+ </target>
+
+ <target name="jar" depends="parser">
+ <antcall target="common.jar">
+ <reference torefid="extra.jar.includes" refid="empty.reference" />
+ </antcall>
+ </target>
+ <target name="publish-local" depends="jar">
+ <antcall target="common.sources.jar">
+ <reference torefid="extra.jar.includes" refid="empty.reference" />
+ </antcall>
+ <antcall target="common.javadoc.jar" />
+
+ <antcall target="common.publish-local" />
+ </target>
+
+ <target name="clean">
+ <antcall target="common.clean" />
+ </target>
+
+ <target name="checkstyle">
+ <antcall target="common.checkstyle">
+ <param name="cs.src" location="src" />
+ </antcall>
+ </target>
+
+ <target name="test" depends="checkstyle">
+ <antcall target="common.test.run" />
+ </target>
</project> \ No newline at end of file
diff --git a/theme-compiler/ivy.xml b/theme-compiler/ivy.xml
index f0646c04e6..97ecfa4416 100644
--- a/theme-compiler/ivy.xml
+++ b/theme-compiler/ivy.xml
@@ -45,11 +45,9 @@
<!-- Internally used, for now -->
<dependency org="com.carrotsearch" name="smartsprites"
- rev="0.2.3-itmill" />
- <!-- Use 1.1.1 even though smartsprites indirectly depends on an
- older version -->
- <override org="commons-logging" module="commons-logging"
- rev="1.1.1"/>
+ rev="0.2.10-vaadin" />
+ <!-- Use the same commons-io as the rest of the project -->
+ <override org="commons-io" module="commons-io" rev="2.2" />
</dependencies>
</ivy-module>
diff --git a/theme-compiler/ivymodule/smartsprites-ivy-0.2.3-itmill.xml b/theme-compiler/ivymodule/smartsprites-ivy-0.2.3-itmill.xml
deleted file mode 100644
index 29dc2d3474..0000000000
--- a/theme-compiler/ivymodule/smartsprites-ivy-0.2.3-itmill.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ivy-module version="2.0" xmlns:m="http://ant.apache.org/ivy/maven">
- <info organisation="com.carrotsearch"
- module="smartsprites"
- revision="0.2.3-itmill"
- status="release"
- publication="20111130000000">
- <license name="BSD license" url="http://csssprites.org/smartsprites.LICENSE" />
- <description homepage="http://csssprites.org">
- CSS Sprites Generator Done Right. SmartSprites maintains CSS sprites in your designs,
- fully automatically. No tedious copying and pasting to your CSS when adding or changing
- sprited images.
- </description>
- </info>
- <configurations>
- <conf name="default" visibility="public" description="runtime dependencies and master artifact can be used with this conf" extends="runtime,master"/>
- <conf name="master" visibility="public" description="contains only the artifact published by this module itself, with no transitive dependencies"/>
- <conf name="compile" visibility="public" description="this is the default scope, used if none is specified. Compile dependencies are available in all classpaths."/>
- <conf name="provided" visibility="public" description="this is much like compile, but indicates you expect the JDK or a container to provide it. It is only available on the compilation classpath, and is not transitive."/>
- <conf name="runtime" visibility="public" description="this scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath." extends="compile"/>
- <conf name="test" visibility="private" description="this scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases." extends="runtime"/>
- <conf name="system" visibility="public" description="this scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository."/>
- <conf name="sources" visibility="public" description="this configuration contains the source artifact of this module, if any."/>
- <conf name="javadoc" visibility="public" description="this configuration contains the javadoc artifact of this module, if any."/>
- <conf name="optional" visibility="public" description="contains all optional dependencies"/>
- </configurations>
- <publications>
- <artifact name="smartsprites" type="jar" ext="jar" conf="master"/>
- </publications>
- <dependencies>
- <dependency org="com.google.collections" name="google-collections" rev="0.9" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
- <dependency org="args4j" name="args4j" rev="2.0.9" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
- <dependency org="commons-math" name="commons-math" rev="1.1" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
- <dependency org="commons-io" name="commons-io" rev="2.2" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
- <dependency org="commons-lang" name="commons-lang" rev="2.6" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
- <dependency org="junit" name="junit" rev="4.4" force="true" conf="test->runtime(*),master(*)"/>
- </dependencies>
-</ivy-module>
diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java b/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java
index d938dfefe8..382e8e6711 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java
@@ -136,6 +136,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
* @exception IOException the source can't be parsed.
* @exception CSSException the source is not CSS valid.
*/
+ // TODO required by original parser but not used by Vaadin?
public void parseRule(InputSource source)
throws CSSException, IOException {
this.source = source;
@@ -1870,6 +1871,7 @@ char connector = ' ';
case IDENT:
case VARIABLE:
case HASH:
+ case IMPORT_SYM:
case MEDIA_SYM:
case KEY_FRAME_SYM:
;
@@ -1907,6 +1909,9 @@ char connector = ' ';
case MICROSOFT_RULE:
microsoftExtension();
break;
+ case IMPORT_SYM:
+ importDeclaration();
+ break;
default:
jj_la1[69] = jj_gen;
jj_consume_token(-1);
@@ -6080,6 +6085,7 @@ LexicalUnitImpl result = null;
* The following functions are useful for a DOM CSS implementation only and are
* not part of the general CSS2 parser.
*/
+// TODO required by original parser but not used by Vaadin?
final public void _parseRule() throws ParseException {
String ret = null;
label_168:
@@ -7364,13 +7370,13 @@ LexicalUnitImpl result = null;
return false;
}
- private boolean jj_3R_261() {
- if (jj_scan_token(INTERPOLATION)) return true;
+ private boolean jj_3_9() {
+ if (jj_3R_184()) return true;
return false;
}
- private boolean jj_3_9() {
- if (jj_3R_184()) return true;
+ private boolean jj_3R_261() {
+ if (jj_scan_token(INTERPOLATION)) return true;
return false;
}
@@ -7529,7 +7535,7 @@ LexicalUnitImpl result = null;
jj_la1_2 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x401,0x4000,0x0,0x0,0x0,0x0,0x2200,0x0,0x0,0x0,0x400,0x400,0x0,0x0,0x8000,0x0,0x8000,0x0,0x0,0x4465,0x4465,0x0,0x0,0x0,0xae00,0xae00,0x0,0x0,0x0,0x400,0x0,0x0,0x400,0x0,0x0,0x400,0x0,0x0,0x0,0x0,0x400,0x0,0x0,0x400,0x0,0xaa00,0x0,0x0,0x0,0x0,0x0,0xe00,0xe00,0x0,0x400,0x400,0x0,0x0,0x0,0x0,0x4465,0x4465,0x0,0x0,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400,0x400,0x400,0x400,0x400,0x400,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x0,0x0,0x400,0x0,0x100,0x0,0x0,0x1,0x424,0x4000,0x4c00,0x0,0x4424,0x0,0x2,0x0,0x4c00,0x80,0x0,0x4424,0x0,0x4c00,0x0,0x0,0x0,0x4400,0x0,0x4424,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400,0x0,0x4425,0x4425,0x0,0x0,0x0,0x0,0x0,0x0,0x4000,0x4000,0xffffee00,0x0,0x0,0x0,0x0,0xffffee00,0x0,0x0,0x0,0x4400,0x0,0x0,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400,0x0,0x0,0x400,0x0,0x0,0x400,0x0,0x0,0x0,0x400,0x0,0x0,0x400,0x0,0xffffee00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffffee00,0x0,0xffff8800,0x0,0x400,0x2600,0xffffae00,0x0,0x0,0xffffee00,0x0,0x400,0x0,0x0,0x0,0x400,0x0,0x0,0x400,0x0,};
}
private static void jj_la1_init_3() {
- jj_la1_3 = new int[] {0x20,0x200,0x200,0x8,0x200,0x0,0x0,0x0,0x1d4,0x0,0x200,0x0,0x200,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x114,0x114,0x0,0x0,0x0,0x31006fc,0x31006fc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x31006f8,0x0,0x0,0x0,0x0,0x0,0x1000000,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x114,0x114,0x0,0x0,0x0,0x4,0x0,0x4,0x4,0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x0,0x0,0x0,0x0,0x114,0x0,0x800000,0x0,0x114,0x0,0x0,0x0,0x800000,0x0,0x0,0x114,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x114,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x1d4,0x1d4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1100007,0x0,0x0,0x0,0x0,0x1100007,0x0,0x0,0x0,0x1000000,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x1100007,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1100007,0x0,0x1000003,0x0,0x0,0x100004,0x1100007,0x0,0x0,0x1100007,0x0,0xdc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+ jj_la1_3 = new int[] {0x20,0x200,0x200,0x8,0x200,0x0,0x0,0x0,0x1d4,0x0,0x200,0x0,0x200,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x114,0x114,0x0,0x0,0x0,0x31006fc,0x31006fc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x31006f8,0x0,0x0,0x0,0x0,0x0,0x1000000,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x11c,0x11c,0x0,0x0,0x0,0x4,0x0,0x4,0x4,0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x0,0x0,0x0,0x0,0x114,0x0,0x800000,0x0,0x114,0x0,0x0,0x0,0x800000,0x0,0x0,0x114,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x114,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x1d4,0x1d4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1100007,0x0,0x0,0x0,0x0,0x1100007,0x0,0x0,0x0,0x1000000,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x1100007,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1100007,0x0,0x1000003,0x0,0x0,0x100004,0x1100007,0x0,0x0,0x1100007,0x0,0xdc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
}
final private JJCalls[] jj_2_rtns = new JJCalls[9];
private boolean jj_rescan = false;
diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj b/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj
index 7f86527015..daf20423d6 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj
@@ -169,6 +169,7 @@ public class Parser implements org.w3c.css.sac.Parser {
* @exception IOException the source can't be parsed.
* @exception CSSException the source is not CSS valid.
*/
+ // TODO required by original parser but not used by Vaadin?
public void parseRule(InputSource source)
throws CSSException, IOException {
this.source = source;
@@ -1188,7 +1189,8 @@ void styleRule() :
start = true;
documentHandler.startSelector(l);
}
- ( ifContentStatement() | controlDirective() | microsoftExtension() )*
+ // a CSS import here will not work
+ ( ifContentStatement() | controlDirective() | microsoftExtension() | importDeclaration() )*
<RBRACE> (<S>)*
} catch (ThrowedParseException e) {
if (errorHandler != null) {
@@ -2947,7 +2949,7 @@ String skipAfterExpression() {
* The following functions are useful for a DOM CSS implementation only and are
* not part of the general CSS2 parser.
*/
-
+// TODO required by original parser but not used by Vaadin?
void _parseRule() :
{String ret = null;
}
diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/ImportNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/ImportNode.java
index f7d664d54d..6dc95db5c2 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/tree/ImportNode.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/tree/ImportNode.java
@@ -18,7 +18,6 @@ package com.vaadin.sass.internal.tree;
import org.w3c.css.sac.SACMediaList;
-import com.vaadin.sass.internal.ScssStylesheet;
import com.vaadin.sass.internal.visitor.ImportNodeHandler;
public class ImportNode extends Node {
@@ -74,7 +73,7 @@ public class ImportNode extends Node {
@Override
public void traverse() {
- // TODO shouldn't be reached with current setup, try anyway?
- ImportNodeHandler.traverse((ScssStylesheet) getParentNode());
+ // nested imports
+ ImportNodeHandler.traverse(getParentNode());
}
}
diff --git a/theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java b/theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java
index e356ed3525..cb9896967a 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java
@@ -26,6 +26,7 @@ import org.w3c.css.sac.LexicalUnit;
import com.vaadin.sass.internal.ScssStylesheet;
import com.vaadin.sass.internal.parser.LexicalUnitImpl;
+import com.vaadin.sass.internal.parser.ParseException;
import com.vaadin.sass.internal.tree.ImportNode;
import com.vaadin.sass.internal.tree.Node;
import com.vaadin.sass.internal.tree.RuleNode;
@@ -33,7 +34,23 @@ import com.vaadin.sass.internal.util.StringUtil;
public class ImportNodeHandler {
- public static void traverse(ScssStylesheet node) {
+ public static void traverse(Node node) {
+ ScssStylesheet styleSheet = null;
+ if (node instanceof ScssStylesheet) {
+ styleSheet = (ScssStylesheet) node;
+ } else {
+ // iterate to parents of node, find ScssStylesheet
+ Node parent = node.getParentNode();
+ while (parent != null && !(parent instanceof ScssStylesheet)) {
+ parent = parent.getParentNode();
+ }
+ if (parent instanceof ScssStylesheet) {
+ styleSheet = (ScssStylesheet) parent;
+ }
+ }
+ if (styleSheet == null) {
+ throw new ParseException("Nested import in an invalid context");
+ }
ArrayList<Node> c = new ArrayList<Node>(node.getChildren());
for (Node n : c) {
if (n instanceof ImportNode) {
@@ -41,7 +58,7 @@ public class ImportNodeHandler {
if (!importNode.isPureCssImport()) {
try {
StringBuilder filePathBuilder = new StringBuilder(
- node.getFileName());
+ styleSheet.getFileName());
filePathBuilder.append(File.separatorChar).append(
importNode.getUri());
if (!filePathBuilder.toString().endsWith(".scss")) {
@@ -50,7 +67,8 @@ public class ImportNodeHandler {
// set parent's charset to imported node.
ScssStylesheet imported = ScssStylesheet.get(
- filePathBuilder.toString(), node.getCharset());
+ filePathBuilder.toString(),
+ styleSheet.getCharset());
if (imported == null) {
imported = ScssStylesheet.get(importNode.getUri());
}
@@ -76,6 +94,11 @@ public class ImportNodeHandler {
} catch (IOException e) {
e.printStackTrace();
}
+ } else {
+ if (styleSheet != node) {
+ throw new ParseException(
+ "CSS imports can only be used at the top level, not as nested imports. Within style rules, use SCSS imports.");
+ }
}
}
}
diff --git a/theme-compiler/tests/resources/automatic/css/nested-import.css b/theme-compiler/tests/resources/automatic/css/nested-import.css
new file mode 100644
index 0000000000..7c6793f9ed
--- /dev/null
+++ b/theme-compiler/tests/resources/automatic/css/nested-import.css
@@ -0,0 +1,5 @@
+.foo .bar {
+ background: url(foo/lorem.png);
+ background: url(foo/lorem.png);
+ background: url(foo/lorem.png);
+} \ No newline at end of file
diff --git a/theme-compiler/tests/resources/automatic/scss/nested-import.scss b/theme-compiler/tests/resources/automatic/scss/nested-import.scss
new file mode 100644
index 0000000000..605d64a13a
--- /dev/null
+++ b/theme-compiler/tests/resources/automatic/scss/nested-import.scss
@@ -0,0 +1,3 @@
+.foo {
+ @import "foo/bar.scss";
+} \ No newline at end of file
diff --git a/themes/build.xml b/themes/build.xml
index 75b3e5a903..5bca50e5f5 100644
--- a/themes/build.xml
+++ b/themes/build.xml
@@ -1,107 +1,115 @@
<?xml version="1.0"?>
-<project name="vaadin-themes" basedir="." default="publish-local" xmlns:ivy="antlib:org.apache.ivy.ant">
- <description>
- Themes compiled to CSS
- </description>
-
- <include file="../common.xml" as="common" />
- <include file="../build.xml" as="vaadin" />
- <include file="../gwt-files.xml" as="gwtfiles" />
-
- <!-- global properties -->
- <property name="module.name" value="vaadin-themes" />
- <property name="module.symbolic" value="com.vaadin.themes" />
- <property name="result.dir" value="result" />
- <property name="theme.result.dir" value="${result.dir}/VAADIN/themes/" />
-
- <union id="jar.includes">
- <fileset dir="${result.dir}">
- <include name="VAADIN/themes/**" />
- </fileset>
- </union>
-
- <target name="compile-themes">
- <ivy:resolve resolveid="common" conf="build" />
- <ivy:cachepath pathid="classpath.compile.theme" conf="build" />
-
- <antcall target="compile-theme">
- <param name="theme" value="base" />
- </antcall>
- <antcall target="compile-theme">
- <param name="theme" value="runo" />
- </antcall>
- <antcall target="compile-theme">
- <param name="theme" value="reindeer" />
- </antcall>
- <antcall target="compile-theme">
- <param name="theme" value="chameleon" />
- </antcall>
- <antcall target="compile-theme">
- <param name="theme" value="liferay" />
- </antcall>
- </target>
-
- <target name="jar" depends="compile-themes">
- <antcall target="common.jar">
- <param name="osgi.extra.package.prefixes" value="VAADIN/themes" />
- <reference torefid="extra.jar.includes" refid="jar.includes" />
- </antcall>
- </target>
-
- <target name="copy-theme">
- <fail unless="theme" message="You must give the theme name to copy n the 'theme' parameter" />
- <property name="theme.source.dir" location="../WebContent/VAADIN/themes" />
-
- <copy todir="${theme.result.dir}">
- <fileset dir="${theme.source.dir}">
- <include name="${theme}/**" />
- </fileset>
- </copy>
- </target>
-
- <target name="compile-theme" depends="copy-theme">
- <fail unless="theme" message="You must give the theme name to compile in the 'theme' parameter" />
-
- <ivy:resolve resolveid="common" conf="compile-theme" />
- <ivy:cachepath pathid="classpath.compile.theme" conf="compile-theme" />
- <ivy:cachepath pathid="classpath.runtime.theme" conf="build" />
-
- <echo>Compiling ${theme}</echo>
- <mkdir dir="${theme.result.dir}" />
-
- <!-- compile the theme -->
- <java classname="com.vaadin.buildhelpers.CompileTheme" classpathref="classpath.compile.theme" failonerror="yes" fork="yes" maxmemory="512m">
- <arg value="--theme" />
- <arg value="${theme}" />
- <arg value="--theme-folder" />
- <arg value="${theme.result.dir}" />
- <arg value="--theme-version" />
- <arg value="${vaadin.version}" />
- <jvmarg value="-Xss8M" />
- <jvmarg value="-XX:MaxPermSize=256M" />
- <jvmarg value="-Djava.awt.headless=true" />
- </java>
-
- </target>
-
-
- <target name="publish-local" depends="jar">
- <antcall target="common.publish-local">
-
- </antcall>
- </target>
-
- <target name="clean">
- <antcall target="common.clean" />
- </target>
-
- <target name="checkstyle">
- <echo>No java files in module</echo>
- </target>
- <target name="test" depends="checkstyle">
- <!--<antcall target="common.test.run" />-->
- <echo>WHAT? No tests for ${module.name}!</echo>
- </target>
+<project name="vaadin-themes" basedir="." default="publish-local"
+ xmlns:ivy="antlib:org.apache.ivy.ant">
+ <description>
+ Themes compiled to CSS
+ </description>
+
+ <include file="../common.xml" as="common" />
+ <include file="../build.xml" as="vaadin" />
+ <include file="../gwt-files.xml" as="gwtfiles" />
+
+ <!-- global properties -->
+ <property name="module.name" value="vaadin-themes" />
+ <property name="module.symbolic" value="com.vaadin.themes" />
+ <property name="result.dir" value="result" />
+ <property name="theme.result.dir" value="${result.dir}/VAADIN/themes/" />
+
+ <union id="jar.includes">
+ <fileset dir="${result.dir}">
+ <include name="VAADIN/themes/**" />
+ </fileset>
+ </union>
+
+ <target name="compile-themes">
+ <ivy:resolve resolveid="common" conf="build" />
+ <ivy:cachepath pathid="classpath.compile.theme"
+ conf="build" />
+
+ <antcall target="compile-theme">
+ <param name="theme" value="base" />
+ </antcall>
+ <antcall target="compile-theme">
+ <param name="theme" value="runo" />
+ </antcall>
+ <antcall target="compile-theme">
+ <param name="theme" value="reindeer" />
+ </antcall>
+ <antcall target="compile-theme">
+ <param name="theme" value="chameleon" />
+ </antcall>
+ <antcall target="compile-theme">
+ <param name="theme" value="liferay" />
+ </antcall>
+ </target>
+
+ <target name="jar" depends="compile-themes">
+ <antcall target="common.jar">
+ <param name="osgi.extra.package.prefixes" value="VAADIN/themes" />
+ <reference torefid="extra.jar.includes" refid="jar.includes" />
+ </antcall>
+ </target>
+
+ <target name="copy-theme">
+ <fail unless="theme"
+ message="You must give the theme name to copy n the 'theme' parameter" />
+ <property name="theme.source.dir" location="../WebContent/VAADIN/themes" />
+
+ <copy todir="${theme.result.dir}">
+ <fileset dir="${theme.source.dir}">
+ <include name="${theme}/**" />
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="compile-theme" depends="copy-theme">
+ <fail unless="theme"
+ message="You must give the theme name to compile in the 'theme' parameter" />
+
+ <ivy:resolve resolveid="common" conf="compile-theme" />
+ <ivy:cachepath pathid="classpath.compile.theme"
+ conf="compile-theme" />
+ <ivy:cachepath pathid="classpath.runtime.theme"
+ conf="build" />
+
+ <echo>Compiling ${theme}</echo>
+ <mkdir dir="${theme.result.dir}" />
+
+ <!-- compile the theme -->
+ <java classname="com.vaadin.buildhelpers.CompileTheme"
+ classpathref="classpath.compile.theme" failonerror="yes"
+ fork="yes" maxmemory="512m">
+ <arg value="--theme" />
+ <arg value="${theme}" />
+ <arg value="--theme-folder" />
+ <arg value="${theme.result.dir}" />
+ <arg value="--theme-version" />
+ <arg value="${vaadin.version}" />
+ <jvmarg value="-Xss8M" />
+ <jvmarg value="-XX:MaxPermSize=256M" />
+ <jvmarg value="-Djava.awt.headless=true" />
+ </java>
+
+ </target>
+
+
+ <target name="publish-local" depends="jar">
+ <antcall target="common.publish-local">
+
+ </antcall>
+ </target>
+
+ <target name="clean">
+ <antcall target="common.clean" />
+ </target>
+
+ <target name="checkstyle">
+ <echo>No java files in module</echo>
+ </target>
+ <target name="test" depends="checkstyle">
+ <!--<antcall target="common.test.run" /> -->
+ <echo>WHAT? No tests for ${module.name}!</echo>
+ </target>
</project>
diff --git a/themes/ivy.xml b/themes/ivy.xml
index e0e22429ab..beb1b16a00 100644
--- a/themes/ivy.xml
+++ b/themes/ivy.xml
@@ -14,8 +14,8 @@
</configurations>
<publications>
<artifact type="jar" ext="jar" />
-<!-- <artifact type="source" ext="jar" m:classifier="sources" /> -->
-<!-- <artifact type="javadoc" ext="jar" m:classifier="javadoc" /> -->
+ <!-- <artifact type="source" ext="jar" m:classifier="sources" /> -->
+ <!-- <artifact type="javadoc" ext="jar" m:classifier="javadoc" /> -->
<artifact type="pom" ext="pom" />
</publications>
<dependencies>
diff --git a/uitest/build.xml b/uitest/build.xml
index 453fc26ea5..dc9258a807 100644
--- a/uitest/build.xml
+++ b/uitest/build.xml
@@ -1,148 +1,161 @@
<?xml version="1.0"?>
-<project name="vaadin-uitest" basedir="." default="publish-local" xmlns:ivy="antlib:org.apache.ivy.ant">
- <description>
- Provides a uitest WAR containing Vaadin UI tests
- </description>
- <include file="../common.xml" as="common" />
- <include file="../build.xml" as="vaadin" />
-
- <!-- global properties -->
- <property name="module.name" value="vaadin-uitest" />
- <property name="result.dir" value="result" />
- <property name="result.war" location="${result.dir}/lib/${module.name}-${vaadin.version}.war" />
-
- <path id="classpath.compile.custom">
- </path>
-
- <target name="dependencies">
- <!-- This is copied from common.xml to be able to add server.test.source to the source path -->
-
- <ivy:resolve resolveid="common" conf="build, build-provided" />
- <ivy:cachepath pathid="classpath.compile.dependencies" conf="build, build-provided" />
- </target>
-
- <target name="compile" description="Compiles the module" depends="dependencies">
-
- <fail unless="module.name" message="No module name given" />
- <property name="result.dir" location="result" />
- <property name="src" location="${result.dir}/../src" />
- <property name="classes" location="${result.dir}/classes" />
- <property name="server.test.sources" location="${result.dir}/../../server/tests/src" />
- <mkdir dir="${classes}" />
-
- <!-- TODO: Get rid of this -->
- <javac destdir="${classes}" source="${vaadin.java.version}" target="${vaadin.java.version}" debug="true" encoding="UTF-8" includeantruntime="false">
- <src path="${server.test.sources}" />
- <include name="com/vaadin/tests/data/bean/**" />
- <include name="com/vaadin/tests/VaadinClasses.java" />
- <include name="com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java" />
- <classpath refid="classpath.compile.dependencies" />
- <classpath refid="classpath.compile.custom" />
- </javac>
-
- <javac destdir="${classes}" source="${vaadin.java.version}" target="${vaadin.java.version}" debug="true" encoding="UTF-8" includeantruntime="false">
- <src path="${src}" />
- <classpath location="${classes}" />
- <classpath refid="classpath.compile.dependencies" />
- <classpath refid="classpath.compile.custom" />
- </javac>
- </target>
-
- <target name="testing-widgetset" depends="dependencies,compile">
- <property name="module" value="com.vaadin.tests.widgetset.TestingWidgetSet" />
- <property name="style" value="OBF" />
- <property name="localWorkers" value="2" />
- <property name="extraParams" value="" />
- <property name="module.output.dir" location="${result.dir}/VAADIN/widgetsets" />
- <property name="work.dir" location="${result.dir}/work" />
-
- <mkdir dir="${module.output.dir}" />
-
- <echo>Compiling ${module} to ${module.output.dir}</echo>
-
- <!-- compile the module -->
- <java classname="com.google.gwt.dev.Compiler" classpathref="classpath.compile.dependencies" failonerror="yes" fork="yes" maxmemory="512m">
- <classpath location="src" />
- <classpath location="${classes}" />
- <arg value="-workDir" />
- <arg value="${work.dir}" />
- <arg value="-logLevel" />
- <arg value="TRACE" />
- <arg value="-war" />
- <arg value="${module.output.dir}" />
- <arg value="-style" />
- <arg value="${style}" />
-
- <arg value="-localWorkers" />
- <arg value="${localWorkers}" />
- <arg value="-strict" />
- <arg line="${extraParams}" />
- <arg value="${module}" />
-
- <sysproperty key="vFailIfNotSerializable" value="true" />
-
- <jvmarg value="-Xss8M" />
- <jvmarg value="-XX:MaxPermSize=256M" />
- <jvmarg value="-Djava.awt.headless=true" />
- </java>
-
- </target>
-
- <target name="war" depends="dependencies, compile, testing-widgetset">
- <property name="result.dir" location="result" />
- <property name="classes" location="${result.dir}/classes" />
- <property name="WebContent.dir" location="${vaadin.basedir}/WebContent" />
- <property name="deps.dir" location="${result.dir}/deps" />
- <property name="src" location="${result.dir}/../src" />
-
- <ivy:resolve resolveid="common" conf="build" />
- <ivy:cachepath pathid="classpath.runtime.dependencies" conf="build" />
-
- <delete dir="${deps.dir}" />
- <mkdir dir="${deps.dir}" />
-
- <copy todir="${deps.dir}" flatten="true">
- <path refid="classpath.runtime.dependencies" />
- </copy>
-
-
- <!-- Ensure filtered webcontent files are available -->
- <antcall target="common.filter.webcontent" />
-
- <war destfile="${result.war}" duplicate="fail" index="true">
- <fileset refid="common.files.for.all.jars" />
- <fileset dir="${result.dir}">
- <include name="VAADIN/widgetsets/**/*"/>
- </fileset>
- <fileset dir="${WebContent.dir}">
- <include name="statictestfiles/**" />
- <include name="VAADIN/themes/tests-*/**" />
- <include name="VAADIN/themes/reindeer-tests/**" />
- <include name="WEB-INF/*.xml" />
- </fileset>
- <classes dir="${classes}" />
- <classes dir="${src}" />
- <lib dir="${deps.dir}" />
- </war>
-
- </target>
-
- <target name="publish-local" depends="war">
- <antcall target="common.publish-local">
- <param name="conf" value="build" />
- </antcall>
- </target>
-
- <target name="clean">
- <antcall target="common.clean" />
- </target>
- <target name="checkstyle">
- <echo>Checkstyle is disabled for uitest for now</echo>
- </target>
- <target name="test" depends="checkstyle">
- <!--<antcall target="common.test.run" />-->
- <echo>WHAT? No JUnit tests for ${module.name}!</echo>
- </target>
+<project name="vaadin-uitest" basedir="." default="publish-local"
+ xmlns:ivy="antlib:org.apache.ivy.ant">
+ <description>
+ Provides a uitest WAR containing Vaadin UI tests
+ </description>
+ <include file="../common.xml" as="common" />
+ <include file="../build.xml" as="vaadin" />
+
+ <!-- global properties -->
+ <property name="module.name" value="vaadin-uitest" />
+ <property name="result.dir" value="result" />
+ <property name="result.war"
+ location="${result.dir}/lib/${module.name}-${vaadin.version}.war" />
+
+ <path id="classpath.compile.custom">
+ </path>
+
+ <target name="dependencies">
+ <!-- This is copied from common.xml to be able to add server.test.source
+ to the source path -->
+
+ <ivy:resolve resolveid="common" conf="build, build-provided" />
+ <ivy:cachepath pathid="classpath.compile.dependencies"
+ conf="build, build-provided" />
+ </target>
+
+ <target name="compile" description="Compiles the module"
+ depends="dependencies">
+
+ <fail unless="module.name" message="No module name given" />
+ <property name="result.dir" location="result" />
+ <property name="src" location="${result.dir}/../src" />
+ <property name="classes" location="${result.dir}/classes" />
+ <property name="server.test.sources" location="${result.dir}/../../server/tests/src" />
+ <mkdir dir="${classes}" />
+
+ <!-- TODO: Get rid of this -->
+ <javac destdir="${classes}" source="${vaadin.java.version}"
+ target="${vaadin.java.version}" debug="true" encoding="UTF-8"
+ includeantruntime="false">
+ <src path="${server.test.sources}" />
+ <include name="com/vaadin/tests/data/bean/**" />
+ <include name="com/vaadin/tests/VaadinClasses.java" />
+ <include
+ name="com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java" />
+ <classpath refid="classpath.compile.dependencies" />
+ <classpath refid="classpath.compile.custom" />
+ </javac>
+
+ <javac destdir="${classes}" source="${vaadin.java.version}"
+ target="${vaadin.java.version}" debug="true" encoding="UTF-8"
+ includeantruntime="false">
+ <src path="${src}" />
+ <classpath location="${classes}" />
+ <classpath refid="classpath.compile.dependencies" />
+ <classpath refid="classpath.compile.custom" />
+ </javac>
+ </target>
+
+ <target name="testing-widgetset" depends="dependencies,compile">
+ <property name="module"
+ value="com.vaadin.tests.widgetset.TestingWidgetSet" />
+ <property name="style" value="OBF" />
+ <property name="localWorkers" value="2" />
+ <property name="extraParams" value="" />
+ <property name="module.output.dir" location="${result.dir}/VAADIN/widgetsets" />
+ <property name="work.dir" location="${result.dir}/work" />
+
+ <mkdir dir="${module.output.dir}" />
+
+ <echo>Compiling ${module} to ${module.output.dir}</echo>
+
+ <!-- compile the module -->
+ <java classname="com.google.gwt.dev.Compiler" classpathref="classpath.compile.dependencies"
+ failonerror="yes" fork="yes" maxmemory="512m">
+ <classpath location="src" />
+ <classpath location="${classes}" />
+ <arg value="-workDir" />
+ <arg value="${work.dir}" />
+ <arg value="-logLevel" />
+ <arg value="TRACE" />
+ <arg value="-war" />
+ <arg value="${module.output.dir}" />
+ <arg value="-style" />
+ <arg value="${style}" />
+
+ <arg value="-localWorkers" />
+ <arg value="${localWorkers}" />
+ <arg value="-strict" />
+ <arg line="${extraParams}" />
+ <arg value="${module}" />
+
+ <sysproperty key="vFailIfNotSerializable" value="true" />
+
+ <jvmarg value="-Xss8M" />
+ <jvmarg value="-XX:MaxPermSize=256M" />
+ <jvmarg value="-Djava.awt.headless=true" />
+ </java>
+
+ </target>
+
+ <target name="war" depends="dependencies, compile, testing-widgetset">
+ <property name="result.dir" location="result" />
+ <property name="classes" location="${result.dir}/classes" />
+ <property name="WebContent.dir" location="${vaadin.basedir}/WebContent" />
+ <property name="deps.dir" location="${result.dir}/deps" />
+ <property name="src" location="${result.dir}/../src" />
+
+ <ivy:resolve resolveid="common" conf="build" />
+ <ivy:cachepath pathid="classpath.runtime.dependencies"
+ conf="build" />
+
+ <delete dir="${deps.dir}" />
+ <mkdir dir="${deps.dir}" />
+
+ <copy todir="${deps.dir}" flatten="true">
+ <path refid="classpath.runtime.dependencies" />
+ </copy>
+
+
+ <!-- Ensure filtered webcontent files are available -->
+ <antcall target="common.filter.webcontent" />
+
+ <war destfile="${result.war}" duplicate="fail" index="true">
+ <fileset refid="common.files.for.all.jars" />
+ <fileset dir="${result.dir}">
+ <include name="VAADIN/widgetsets/**/*" />
+ </fileset>
+ <fileset dir="${WebContent.dir}">
+ <include name="statictestfiles/**" />
+ <include name="VAADIN/themes/tests-*/**" />
+ <include name="VAADIN/themes/reindeer-tests/**" />
+ <include name="WEB-INF/*.xml" />
+ </fileset>
+ <classes dir="${classes}" />
+ <classes dir="${src}" />
+ <lib dir="${deps.dir}" />
+ </war>
+
+ </target>
+
+ <target name="publish-local" depends="war">
+ <antcall target="common.publish-local">
+ <param name="conf" value="build" />
+ </antcall>
+ </target>
+
+ <target name="clean">
+ <antcall target="common.clean" />
+ </target>
+ <target name="checkstyle">
+ <echo>Checkstyle is disabled for uitest for now</echo>
+ </target>
+ <target name="test" depends="checkstyle">
+ <!--<antcall target="common.test.run" /> -->
+ <echo>WHAT? No JUnit tests for ${module.name}!</echo>
+ </target>
</project> \ No newline at end of file
diff --git a/uitest/integration_base_files/base.xml b/uitest/integration_base_files/base.xml
index 5196aecfa9..d8ba018b75 100644
--- a/uitest/integration_base_files/base.xml
+++ b/uitest/integration_base_files/base.xml
@@ -1,138 +1,143 @@
<?xml version="1.0"?>
<project name="test" basedir=".">
- <property file="deploy.properties" />
+ <property file="deploy.properties" />
<property name="lock" value="deploy/lock.file" />
<property name="deployDir" value="deploy/${server}" />
<property name="serverPort" value="8080" />
<property name="war" value="demo.war" />
<property name="startupSpawn" value="false" />
<property name="JAVA_HOME" value="/usr/lib/jvm/default-java" />
- <property name="waitMinutes" value="3" />
- <property name="waitUrl" value="http://localhost:${serverPort}/demo/VAADIN/themes/reindeer/styles.css" />
- <property name="shutdownWait" value="10" />
+ <property name="waitMinutes" value="3" />
+ <property name="waitUrl"
+ value="http://localhost:${serverPort}/demo/VAADIN/themes/reindeer/styles.css" />
+ <property name="shutdownWait" value="10" />
+
-
<target name="afterDeploy">
- <!-- Empty default -->
+ <!-- Empty default -->
</target>
-
+
<target name="beforeDeploy">
- <!-- Empty default -->
+ <!-- Empty default -->
+ </target>
+
+ <target name="deploy">
+ <antcall target="beforeDeploy" />
+ <echo
+ message="${server}: Deploying ${war} to ${deployDir}/${autodeployDir}" />
+ <copy file="${war}" todir="${deployDir}/${autodeployDir}" />
+ <antcall target="afterDeploy" />
+ </target>
+
+ <target name="deployStatic">
+ <unzip src="${war}" dest="${staticDeployDir}/tmp-unpack-jar/">
+ <patternset>
+ <include name="WEB-INF/lib/*.jar" />
+ </patternset>
+ </unzip>
+ <unzip dest="${staticDeployDir}">
+ <fileset dir="${staticDeployDir}/tmp-unpack-jar/WEB-INF/lib"
+ includes="*.jar" />
+
+ <patternset>
+ <include name="VAADIN/**" />
+ </patternset>
+ </unzip>
+ <delete dir="${staticDeployDir}/tmp-unpack-jar/" />
+
+ <unzip src="${war}" dest="${staticDeployDir}">
+ <patternset>
+ <include name="VAADIN/**" />
+ </patternset>
+ </unzip>
+ </target>
+
+ <target name="unpack-server">
+ <echo message="${server}: Unpacking ${server}.tar.gz" />
+ <delete dir="${server}" />
+ <exec executable="tar">
+ <arg value="-xf" />
+ <arg value="${server}.tar.gz" />
+ </exec>
+ <move file="${server}" tofile="${deployDir}" />
+ <echo message="Done." />
+ </target>
+
+ <target name="doStartup">
+ <exec executable="./run.sh" spawn="${startupSpawn}">
+ <env key="JAVA_HOME" value="${JAVA_HOME}" />
+ </exec>
+ </target>
+
+ <target name="startup">
+ <antcall target="doStartup" />
+ <echo message="${server}: Waiting for ${waitUrl} to become available." />
+ <waitfor maxwait="${waitMinutes}" maxwaitunit="minute"
+ checkevery="10000" timeoutproperty="timeout">
+ <http url="${waitUrl}" />
+ </waitfor>
+ <!-- Print load averages to get an indicator on whether the server
+ still attempts to start up -->
+ <exec executable="uptime" />
+ <fail if="timeout" message="${server} failed to deploy" />
+
+ <echo message="${server}: Demo deployed successfully." />
+ </target>
+
+ <target name="shutdown">
+ <exec executable="./stop.sh">
+ <env key="JAVA_HOME" value="${JAVA_HOME}" />
+ </exec>
+ <sleep seconds="${shutdownWait}" />
+ </target>
+
+ <target name="force-shutdown">
+ <exec executable="./cleanup.sh" />
+ </target>
+
+ <target name="check-port">
+ <fail
+ message="${server}: Something is still listening on port ${serverPort}">
+ <condition>
+ <socket server="localhost" port="${serverPort}" />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="check-lock">
+ <available file="${lock}" property="lockAvailable" />
+ <fail unless="lockAvailable" message="Instance is not locked!" />
+ </target>
+
+ <target name="get-lock">
+ <mkdir dir="deploy" />
+ <echo>${server}: Getting the lock</echo>
+ <exec executable="lockfile" failonerror="true">
+ <!-- Check every 10 seconds -->
+ <arg value="-10" />
+ <!-- Retry for 55 minutes (build server gives up after 60 minutes) -->
+ <arg value="-r330" />
+ <arg value="${lock}" />
+ </exec>
+ <echo>${server}: Got the lock</echo>
+ </target>
+
+ <target name="clean">
+ <delete dir="${deployDir}" failonerror="false" />
+ </target>
+
+ <target name="release-lock">
+ <!-- <exec executable="rm"> <arg value="-f" /> <arg value="${lock}"
+ /> </exec> -->
+ <delete>
+ <fileset dir="." includes="${lock}" />
+ </delete>
+ <echo>${server}: Released the lock</echo>
</target>
-
- <target name="deploy">
- <antcall target="beforeDeploy" />
- <echo message="${server}: Deploying ${war} to ${deployDir}/${autodeployDir}" />
- <copy file="${war}" todir="${deployDir}/${autodeployDir}"/>
- <antcall target="afterDeploy" />
- </target>
-
- <target name="deployStatic">
- <unzip src="${war}" dest="${staticDeployDir}/tmp-unpack-jar/">
- <patternset>
- <include name="WEB-INF/lib/*.jar" />
- </patternset>
- </unzip>
- <unzip dest="${staticDeployDir}">
- <fileset dir="${staticDeployDir}/tmp-unpack-jar/WEB-INF/lib" includes="*.jar" />
-
- <patternset>
- <include name="VAADIN/**" />
- </patternset>
- </unzip>
- <delete dir="${staticDeployDir}/tmp-unpack-jar/" />
-
- <unzip src="${war}" dest="${staticDeployDir}">
- <patternset>
- <include name="VAADIN/**" />
- </patternset>
- </unzip>
- </target>
-
- <target name="unpack-server">
- <echo message="${server}: Unpacking ${server}.tar.gz" />
- <delete dir="${server}" />
- <exec executable="tar">
- <arg value="-xf"/>
- <arg value="${server}.tar.gz"/>
- </exec>
- <move file="${server}" tofile="${deployDir}" />
- <echo message="Done." />
- </target>
-
- <target name="doStartup">
- <exec executable="./run.sh" spawn="${startupSpawn}">
- <env key="JAVA_HOME" value="${JAVA_HOME}" />
- </exec>
- </target>
-
- <target name="startup">
- <antcall target="doStartup" />
- <echo message="${server}: Waiting for ${waitUrl} to become available." />
- <waitfor maxwait="${waitMinutes}" maxwaitunit="minute" checkevery="10000" timeoutproperty="timeout">
- <http url="${waitUrl}" />
- </waitfor>
- <!-- Print load averages to get an indicator on whether the server still attempts to start up -->
- <exec executable="uptime" />
- <fail if="timeout" message="${server} failed to deploy" />
-
- <echo message="${server}: Demo deployed successfully." />
- </target>
-
- <target name="shutdown">
- <exec executable="./stop.sh" >
- <env key="JAVA_HOME" value="${JAVA_HOME}" />
- </exec>
- <sleep seconds="${shutdownWait}" />
- </target>
-
- <target name="force-shutdown">
- <exec executable="./cleanup.sh" />
- </target>
-
- <target name="check-port">
- <fail message="${server}: Something is still listening on port ${serverPort}">
- <condition>
- <socket server="localhost" port="${serverPort}" />
- </condition>
- </fail>
- </target>
-
- <target name="check-lock">
- <available file="${lock}" property="lockAvailable" />
- <fail unless="lockAvailable" message="Instance is not locked!" />
- </target>
-
- <target name="get-lock">
- <mkdir dir="deploy" />
- <echo>${server}: Getting the lock</echo>
- <exec executable="lockfile" failonerror="true">
- <!-- Check every 10 seconds -->
- <arg value="-10" />
- <!-- Retry for 55 minutes (build server gives up after 60 minutes) -->
- <arg value="-r330" />
- <arg value="${lock}" />
- </exec>
- <echo>${server}: Got the lock</echo>
- </target>
-
- <target name="clean">
- <delete dir="${deployDir}" failonerror="false" />
- </target>
-
- <target name="release-lock">
-<!-- <exec executable="rm">
- <arg value="-f" />
- <arg value="${lock}" />
- </exec> -->
- <delete>
- <fileset dir="." includes="${lock}" />
- </delete>
- <echo>${server}: Released the lock</echo>
- </target>
-
- <target name="startup-and-deploy" depends="check-lock,check-port,unpack-server,deploy,startup" />
-
- <target name="shutdown-and-cleanup" depends="shutdown,clean,release-lock,force-shutdown" />
-
+
+ <target name="startup-and-deploy"
+ depends="check-lock,check-port,unpack-server,deploy,startup" />
+
+ <target name="shutdown-and-cleanup" depends="shutdown,clean,release-lock,force-shutdown" />
+
</project>
diff --git a/uitest/integration_tests.xml b/uitest/integration_tests.xml
index cb96834307..ba353dbdbb 100644
--- a/uitest/integration_tests.xml
+++ b/uitest/integration_tests.xml
@@ -1,541 +1,634 @@
<?xml version="1.0"?>
-<project xmlns:antcontrib="antlib:net.sf.antcontrib" name="Vaadin Integration Tests" basedir="." default="integration-test-all">
-
- <!-- Import common targets -->
- <import file="../common.xml" />
- <dirname file="${ant.file.Vaadin Integration Tests}" property="integration_test.dir" />
-
- <!-- Target deploying demo.war -->
- <fail unless="test.integration.server" message="test.integration.server must be set for integration tests to run" />
-
- <fail unless="test.integration.user" message="test.integration.user must be set for integration tests to run" />
- <fail unless="test.integration.antfile" message="test.integration.antfile must be set for integration tests to run" />
-
- <!-- Test with these browsers -->
- <property name="test_browsers" value="winxp-firefox17-esr" />
-
- <!-- Path to key file. Default value -->
- <property name="sshkey.file" value="id_dsa" />
-
- <!-- path and name for demo.war to be deployed -->
- <property name="demo.war" value="demo.war" />
-
- <!-- Host running Testbench RC or Testbench Hub. Default value -->
- <property name="com.vaadin.testbench.tester.host" value="127.0.0.1" />
-
- <!-- Base url where the testable application is deployed -->
- <property name="deployment.url" value="http://${test.integration.server}:8080" />
-
- <!-- ssh host values -->
- <property name="ant.hub" value="${test.integration.antfile}" />
- <property name="user" value="${test.integration.user}" />
- <property name="passphrase" value="" />
-
- <!-- Upload war to deploy to ssh host -->
- <target name="integration-test-upload-demo">
- <scp file="${demo.war}" todir="${user}@${test.integration.server}:integration-tests/servers/demo.war" keyfile="${sshkey.file}" passphrase="${passphrase}" />
- </target>
-
- <!-- Run basic integration test test -->
- <target name="integration-test-servlet">
- <fileset dir="integration-testscripts" id="html-test-files" includes="integration-test-${server-name}-servlet.html" />
- <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
- <subant target="run-tests" failonerror="false" antfile="test.xml">
- <property name="com.vaadin.testbench.lib.dir" value="${com.vaadin.testbench.lib.dir}" />
- <property name="com.vaadin.testbench.tester.host" value="${com.vaadin.testbench.tester.host}" />
- <property name="com.vaadin.testbench.deployment.url" value="${deployment.url}" />
- <property name="server.start.succeeded" value="1" />
- <property name="browsers" value="${test_browsers}" />
- <property name="testfiles" value="${testfiles}" />
- <property name="test-output-dir" value="${integration_test.dir}/result/integration-test-output/${server-name}" />
- <property name="retries" value="0" />
-
- <fileset dir="." includes="test.xml" />
- </subant>
- </target>
-
- <target name="integration-test-push-servlet">
- <fileset dir="integration-testscripts" id="html-test-files" includes="integration-test-${server-name}-push-servlet.html" />
- <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
- <subant target="run-tests" failonerror="false" antfile="test.xml">
- <property name="com.vaadin.testbench.lib.dir" value="${com.vaadin.testbench.lib.dir}" />
- <property name="com.vaadin.testbench.tester.host" value="${com.vaadin.testbench.tester.host}" />
- <property name="com.vaadin.testbench.deployment.url" value="${deployment.url}" />
- <property name="server.start.succeeded" value="1" />
- <property name="browsers" value="${test_browsers}" />
- <property name="testfiles" value="${testfiles}" />
- <property name="test-output-dir" value="${integration_test.dir}/result/integration-test-output/${server-name}" />
- <property name="retries" value="0" />
-
- <fileset dir="." includes="test.xml" />
- </subant>
- </target>
-
- <target name="integration-test-theme">
- <subant target="run-tests" failonerror="false" antfile="test.xml">
- <property name="com.vaadin.testbench.lib.dir" value="${com.vaadin.testbench.lib.dir}" />
- <property name="com.vaadin.testbench.tester.host" value="${com.vaadin.testbench.tester.host}" />
- <property name="com.vaadin.testbench.deployment.url" value="${deployment.url}" />
- <property name="server.start.succeeded" value="1" />
- <property name="testfiles" value="${testfiles-theme}" />
- <property name="test-output-dir" value="${integration_test.dir}/result/integration-test-output/${server-name}" />
-
- <fileset dir="." includes="test.xml" />
- </subant>
- </target>
-
- <!-- Run integration test on GAE -->
- <target name="integration-test-test-GAE">
- <fileset dir="integration-testscripts" id="html-test-files" includes="GoogleAppEngine/integration-test-GAE.html" />
- <pathconvert pathsep=" " property="test-GAE" refid="html-test-files" />
-
- <subant target="run-tests" failonerror="false" antfile="test.xml">
- <property name="com.vaadin.testbench.lib.dir" value="${com.vaadin.testbench.lib.dir}" />
- <property name="com.vaadin.testbench.tester.host" value="${com.vaadin.testbench.tester.host}" />
- <property name="com.vaadin.testbench.deployment.url" value="http://vaadin-integration-test.appspot.com/" />
- <property name="server.start.succeeded" value="1" />
- <property name="browsers" value="${test_browsers}" />
- <property name="testfiles" value="${test-GAE}" />
- <property name="test-output-dir" value="../build/integration-test-gae-output" />
-
- <fileset dir="." includes="test.xml" />
- </subant>
- </target>
-
- <target name="integration-test-deploy-to-GAE">
- <sshexec host="${test.integration.server}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} deploy-to-GAE" />
- </target>
-
-
- <target name="integration-test-tomcat7">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="10" />
- <param name="target-server" value="tomcat7" />
- </antcall>
- </target>
- <target name="integration-test-tomcat5">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="10" />
- <param name="target-server" value="tomcat5" />
- </antcall>
- </target>
-
- <target name="integration-test-tomcat6">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="10" />
- <param name="target-server" value="tomcat6" />
- </antcall>
- </target>
-
- <target name="integration-test-jetty5">
- <antcall target="run-generic-integration-test">
- <param name="target-server" value="jetty5" />
- </antcall>
- </target>
-
- <target name="integration-test-jetty6">
- <antcall target="run-generic-integration-test">
- <param name="target-server" value="jetty6" />
- </antcall>
- </target>
-
- <target name="integration-test-jetty7">
- <antcall target="run-generic-integration-test">
- <param name="target-server" value="jetty7" />
- </antcall>
- </target>
-
- <target name="integration-test-jetty8">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="300" />
- <param name="target-server" value="jetty8" />
- </antcall>
- </target>
-
- <target name="integration-test-jboss4">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="10" />
- <param name="target-server" value="jboss4" />
- </antcall>
- </target>
-
- <target name="integration-test-jboss5">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="10" />
- <param name="target-server" value="jboss5" />
- </antcall>
- </target>
-
- <target name="integration-test-jboss6">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="10" />
- <param name="target-server" value="jboss6" />
- </antcall>
- </target>
-
- <target name="integration-test-jboss7">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="10" />
- <param name="target-server" value="jboss7" />
- </antcall>
- </target>
-
- <target name="integration-test-glassfish2">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="10" />
- <param name="target-server" value="glassfish2" />
- </antcall>
- </target>
-
- <target name="integration-test-glassfish3">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="10" />
- <param name="target-server" value="glassfish3" />
- </antcall>
- </target>
-
-
- <target name="integration-test-liferay6">
- <fileset dir="integration-testscripts" id="html-test-files" includes="Liferay-6/integration-test-liferay-6.0.5.html" />
- <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
-
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="600" />
- <param name="test_browsers" value="winxp-firefox17-esr" />
- <param name="target-server" value="liferay6" />
- </antcall>
- </target>
-
- <target name="integration-test-liferay6-theme">
- <fileset dir="integration-testscripts" id="html-test-files" includes="Liferay-6/Liferay6-and-6EE-theme-deploy.html" />
- <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
-
- <fileset dir="integration-testscripts" id="html-theme-files" includes="Liferay-6/Liferay6-theme.html" />
- <pathconvert pathsep=" " property="testfiles-theme" refid="html-theme-files" />
-
-
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="600" />
- <param name="test_browsers" value="winxp-firefox17-esr" />
- <param name="target-server" value="liferay6" />
- </antcall>
- </target>
-
- <target name="integration-test-liferay5">
- <fileset dir="integration-testscripts" id="html-test-files" includes="Liferay-5/integration-test-liferay-5.2.3-portlet2.html" />
- <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
-
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="600" />
- <param name="test_browsers" value="winxp-firefox17-esr" />
- <param name="target-server" value="liferay5" />
- </antcall>
- </target>
-
- <target name="integration-test-liferay6ee">
- <fileset dir="integration-testscripts" id="html-test-files" includes="Liferay-6EE/integration-test-liferay-6ee.html" />
- <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
-
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="600" />
- <param name="test_browsers" value="winxp-firefox17-esr" />
- <param name="target-server" value="liferay6ee" />
- </antcall>
- </target>
-
- <target name="integration-test-liferay6ee-theme">
- <fileset dir="integration-testscripts" id="html-test-files" includes="Liferay-6/Liferay6-and-6EE-theme-deploy.html" />
- <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
-
- <fileset dir="integration-testscripts" id="html-theme-files" includes="Liferay-6EE/Liferay6EE-theme.html" />
- <pathconvert pathsep=" " property="testfiles-theme" refid="html-theme-files" />
-
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="600" />
- <param name="test_browsers" value="winxp-firefox17-esr" />
- <param name="target-server" value="liferay6ee" />
- </antcall>
- </target>
-
- <target name="integration-test-gatein3">
- <fileset dir="integration-testscripts" id="html-test-files" includes="GateIn-3/integration-test-GateIn-3.1.0-portlet2.html" />
- <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="600" />
- <param name="test_browsers" value="winxp-googlechrome21" />
- <param name="target-server" value="gatein3" />
- </antcall>
- </target>
-
- <target name="integration-test-exo3">
- <fileset dir="integration-testscripts" id="html-test-files" includes="eXo-3/integration-test-eXo-3.0.3-portlet2.html" />
- <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="600" />
- <param name="test_browsers" value="winxp-firefox17-esr" />
- <param name="target-server" value="exo3" />
- </antcall>
- </target>
-
- <target name="integration-test-websphere8">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="600" />
- <param name="target-port" value="9080" />
- <param name="target-server" value="websphere8" />
- </antcall>
- </target>
-
- <target name="integration-test-weblogic10">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="600" />
- <param name="target-port" value="7001" />
- <param name="target-server" value="weblogic10" />
- </antcall>
- </target>
-
- <target name="integration-test-weblogic12">
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="600" />
- <param name="target-port" value="7001" />
- <param name="target-server" value="weblogic12" />
- </antcall>
- </target>
-
-
- <target name="integration-test-weblogicPortal">
- <fileset dir="integration-testscripts" id="html-test-files" includes="weblogic-portal/integration-test-WebLogic-Portal-10.3.2-portlet2.html" />
- <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
- <antcall target="run-generic-integration-test">
- <param name="startDelay" value="600" />
- <param name="target-port" value="7001" />
- <param name="target-server" value="weblogicportal" />
- </antcall>
- </target>
-
- <target name="integration-test-GAE">
- <antcall target="integration-test-deploy-to-GAE" />
- <antcall target="integration-test-test-GAE" />
- </target>
-
- <!-- Upload demo, clean error screenshots and test deployment on all servers -->
- <target name="integration-test-all">
- <property name="passphrase" value="${passphrase}" />
- <fail unless="sshkey.file" message="You must define an ssh.keyfile parameter" />
- <fail unless="com.vaadin.testbench.screenshot.directory" message="You must define a com.vaadin.testbench.screenshot.directory parameter" />
- <parallel>
- <antcontrib:trycatch property="tried">
- <try>
- <!-- Still running GAE test from the old server which requires its own lock -->
- <echo message="Getting lock" />
- <antcall target="integration-test-get-lock" />
- <echo message="Got lock" />
- <antcall target="integration-test-upload-demo" />
-
- <antcall target="run-integration-test">
- <param name="target-server" value="GAE" />
- </antcall>
-
- <antcall target="integration-test-clean" />
- <echo message="Getting lock" />
- <antcall target="integration-test-release-lock" />
- <echo message="Lock released" />
-
- </try>
- <catch>
- <echo message="Uploading of demo.war failed. ${tried}" />
- </catch>
- </antcontrib:trycatch>
- <antcall target="integration-test-liferay6" />
- <antcall target="integration-test-liferay6ee" />
- <antcall target="integration-test-liferay6-theme" />
- <antcall target="integration-test-liferay6ee-theme" />
- <antcall target="integration-test-exo3" />
- <antcall target="integration-test-weblogicPortal" />
- <antcall target="integration-test-liferay5" />
- <antcall target="integration-test-weblogic10" />
- <antcall target="integration-test-weblogic12" />
- <antcall target="integration-test-gatein3" />
- <antcall target="integration-test-glassfish2" />
- <antcall target="integration-test-glassfish3" />
- <antcall target="integration-test-jboss4" />
- <antcall target="integration-test-jboss5" />
- <antcall target="integration-test-jboss6" />
- <antcall target="integration-test-jboss7" />
- <antcall target="integration-test-jetty5" />
- <antcall target="integration-test-jetty6" />
- <antcall target="integration-test-jetty7" />
- <antcall target="integration-test-jetty8" />
- <antcall target="integration-test-tomcat5" />
- <antcall target="integration-test-tomcat6" />
- <antcall target="integration-test-tomcat7" />
- <antcall target="integration-test-websphere8" />
-
- </parallel>
-
- </target>
-
- <target name="do-run-generic-test">
- <property name="target-host" value="${target-server}.devnet.vaadin.com" />
- <property name="target-port" value="8080" />
- <antcontrib:if>
- <isset property="startDelay" />
- <then>
- <antcontrib:math result="sleepTime" datatype="int">
- <op op="rint">
- <op op="*">
- <num value="${startDelay}" />
- <op op="random" />
- </op>
- </op>
- </antcontrib:math>
- <echo>Delaying startup of ${target-server} with ${sleepTime} seconds</echo>
- <sleep seconds="${sleepTime}" />
- </then>
- </antcontrib:if>
-
- <scp todir="${user}@${target-host}:." keyfile="${sshkey.file}" trust="yes" passphrase="${passphrase}">
- <fileset dir="integration_base_files">
- <include name="*" />
- </fileset>
- </scp>
-
- <!-- trycatch probably not needed any more as it just fails with the original message and doesn't do anything in the finally block -->
- <antcontrib:trycatch property="error_message">
- <try>
- <!-- timeout in one hour (remote end should timeout in 55 minutes) -->
- <sshexec host="${target-host}" outputproperty="lock-output" timeout="3600000" username="${user}" keyfile="${sshkey.file}" trust="yes" command="chmod +x *.sh; ant -f deploy.xml get-lock" />
- <antcall target="echo-prefix">
- <param name="prefix" value="${target-server}: " />
- <param name="message" value="${lock-output}" />
- </antcall>
-
- <scp file="${demo.war}" todir="${user}@${target-host}:demo.war" keyfile="${sshkey.file}" trust="yes" passphrase="${passphrase}" />
-
- <!-- timeout in 15 minutes -->
- <sshexec host="${target-host}" outputproperty="start-output" timeout="900000" username="${user}" keyfile="${sshkey.file}" trust="yes" command="ant -f deploy.xml startup-and-deploy" failonerror="false" />
- <antcall target="echo-prefix">
- <param name="prefix" value="${target-server}: " />
- <param name="message" value="${start-output}" />
- </antcall>
-
- <fail message="${start-output}">
- <condition>
- <not>
- <contains string="${start-output}" substring="Demo deployed successfully" />
- </not>
- </condition>
- </fail>
-
- <copy file="integration-testscripts/common/integration_test.tpl" tofile="integration-testscripts/integration-test-${target-server}-servlet.html" overwrite="true" />
- <antcall target="integration-test-servlet">
- <param name="server-name" value="${target-server}" />
- <param name="deployment.url" value="http://${target-host}:${target-port}" />
- </antcall>
-
- <!-- Run theme tests in all browsers if there's a property with the test files -->
- <antcontrib:if>
- <isset property="testfiles-theme" />
- <antcontrib:then>
- <antcall target="integration-test-theme">
- <param name="server-name" value="${target-server}" />
- <param name="deployment.url" value="http://${target-host}:${target-port}" />
- </antcall>
- </antcontrib:then>
- </antcontrib:if>
-
- <!-- Run integration tests with push -->
- <copy file="integration-testscripts/common/integration_push_test.tpl" tofile="integration-testscripts/integration-test-${target-server}-push-servlet.html" overwrite="true" />
- <antcall target="integration-test-push-servlet">
- <param name="server-name" value="${target-server}" />
- <param name="deployment.url" value="http://${target-host}:${target-port}" />
- </antcall>
-
- <!-- Run theme tests in all browsers if there's a property with the test files -->
- <antcontrib:if>
- <isset property="testfiles-theme" />
- <antcontrib:then>
- <antcall target="integration-test-theme">
- <param name="server-name" value="${target-server}" />
- <param name="deployment.url" value="http://${target-host}:${target-port}" />
- </antcall>
- </antcontrib:then>
- </antcontrib:if>
-
- <!-- timeout in five minutes -->
- <sshexec host="${target-host}" outputproperty="stop-output" timeout="600000" username="${user}" keyfile="${sshkey.file}" trust="yes" command="ant -f deploy.xml shutdown-and-cleanup" failonerror="false" />
- <antcall target="echo-prefix">
- <param name="prefix" value="${target-server}: " />
- <param name="message" value="${stop-output}" />
- </antcall>
- </try>
- <catch>
- <fail message="${error_message}" />
- </catch>
- </antcontrib:trycatch>
- </target>
-
- <target name="echo-prefix">
- <antcontrib:propertyregex property="message-prefixed" input="${prefix}${message}" regexp="\n" replace="\0${prefix}" global="true" defaultValue="${prefix}${message}" />
- <echo message="${message-prefixed}" />
- </target>
-
- <target name="run-generic-integration-test">
- <concat>##teamcity[testStarted name='${target-server}' flowId='${target-server}']</concat>
- <antcontrib:trycatch property="tried">
- <try>
- <antcall target="do-run-generic-test" />
- </try>
- <catch>
- <antcontrib:antcallback target="teamcity-escape" return="tried-escaped">
- <param name="returnTo" value="tried-escaped" />
- <param name="message" value="${tried}" />
- </antcontrib:antcallback>
- <concat>##teamcity[testFailed name='${target-server}' flowId='${target-server}' message='Integration test for ${target-server} failed.' details='${tried-escaped}']</concat>
- </catch>
- </antcontrib:trycatch>
- <concat>##teamcity[testFinished name='${target-server}' flowId='${target-server}']"</concat>
- </target>
-
- <target name="teamcity-escape">
- <property name="returnTo" value="return" />
-
- <!-- Should also perform other escaping (\u0085, \u2028 and \u2029) - see http://confluence.jetbrains.net/display/TCD65/Build+Script+Interaction+with+TeamCity -->
- <!-- Immutable properties -> needs to create a new one every time -->
- <antcontrib:propertyregex property="details-escaped1" input="${message}" regexp="['|\[\]]" replace="|\0" global="true" defaultValue="${message}" />
- <antcontrib:propertyregex property="details-escaped2" input="${details-escaped1}" regexp="\n" replace="|n" global="true" defaultValue="${details-escaped1}" />
- <antcontrib:propertyregex property="details-escaped3" input="${details-escaped2}" regexp="\r" replace="|r" global="true" defaultValue="${details-escaped2}" />
-
- <property name="${returnTo}" value="${details-escaped3}" />
- </target>
-
- <target name="run-integration-test">
- <concat>##teamcity[testStarted name='${target-server}' flowId='${target-server}']</concat>
- <antcontrib:trycatch property="tried">
- <try>
- <antcall target="integration-test-${target-server}" />
- </try>
- <catch>
- <antcallback target="teamcity-escape" return="tried-escaped">
- <param name="returnTo" value="tried-escaped" />
- <param name="message" value="${tried}" />
- </antcallback>
- <concat>##teamcity[testFailed name='${target-server}' flowId='${target-server}' message='Integration test for ${target-server} failed.' details='${tried-escaped}']"</concat>
- </catch>
- </antcontrib:trycatch>
- <concat>##teamcity[testFinished name='${target-server}' flowId='${target-server}']"</concat>
- </target>
-
- <target name="integration-test-get-lock">
- <sshexec host="${test.integration.server}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} get-lock" />
- </target>
-
- <target name="integration-test-release-lock">
- <sshexec host="${test.integration.server}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} release-lock" />
- </target>
-
- <!-- Remove demo.war -->
- <target name="integration-test-clean">
- <sshexec host="${test.integration.server}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} clean" />
- </target>
+<project xmlns:antcontrib="antlib:net.sf.antcontrib" name="Vaadin Integration Tests"
+ basedir="." default="integration-test-all">
+
+ <!-- Import common targets -->
+ <import file="../common.xml" />
+ <dirname file="${ant.file.Vaadin Integration Tests}"
+ property="integration_test.dir" />
+
+ <!-- Target deploying demo.war -->
+ <fail unless="test.integration.server"
+ message="test.integration.server must be set for integration tests to run" />
+
+ <fail unless="test.integration.user"
+ message="test.integration.user must be set for integration tests to run" />
+ <fail unless="test.integration.antfile"
+ message="test.integration.antfile must be set for integration tests to run" />
+
+ <!-- Test with these browsers -->
+ <property name="test_browsers" value="winxp-firefox17-esr" />
+
+ <!-- Path to key file. Default value -->
+ <property name="sshkey.file" value="id_dsa" />
+
+ <!-- path and name for demo.war to be deployed -->
+ <property name="demo.war" value="demo.war" />
+
+ <!-- Host running Testbench RC or Testbench Hub. Default value -->
+ <property name="com.vaadin.testbench.tester.host" value="127.0.0.1" />
+
+ <!-- Base url where the testable application is deployed -->
+ <property name="deployment.url" value="http://${test.integration.server}:8080" />
+
+ <!-- ssh host values -->
+ <property name="ant.hub" value="${test.integration.antfile}" />
+ <property name="user" value="${test.integration.user}" />
+ <property name="passphrase" value="" />
+
+ <!-- Upload war to deploy to ssh host -->
+ <target name="integration-test-upload-demo">
+ <scp file="${demo.war}"
+ todir="${user}@${test.integration.server}:integration-tests/servers/demo.war"
+ keyfile="${sshkey.file}" passphrase="${passphrase}" />
+ </target>
+
+ <!-- Run basic integration test test -->
+ <target name="integration-test-servlet">
+ <fileset dir="integration-testscripts" id="html-test-files"
+ includes="integration-test-${server-name}-servlet.html" />
+ <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
+ <subant target="run-tests" failonerror="false" antfile="test.xml">
+ <property name="com.vaadin.testbench.lib.dir"
+ value="${com.vaadin.testbench.lib.dir}" />
+ <property name="com.vaadin.testbench.tester.host"
+ value="${com.vaadin.testbench.tester.host}" />
+ <property name="com.vaadin.testbench.deployment.url"
+ value="${deployment.url}" />
+ <property name="server.start.succeeded" value="1" />
+ <property name="browsers" value="${test_browsers}" />
+ <property name="testfiles" value="${testfiles}" />
+ <property name="test-output-dir"
+ value="${integration_test.dir}/result/integration-test-output/${server-name}" />
+ <property name="retries" value="0" />
+
+ <fileset dir="." includes="test.xml" />
+ </subant>
+ </target>
+
+ <target name="integration-test-push-servlet">
+ <fileset dir="integration-testscripts" id="html-test-files"
+ includes="integration-test-${server-name}-push-servlet.html" />
+ <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
+ <subant target="run-tests" failonerror="false" antfile="test.xml">
+ <property name="com.vaadin.testbench.lib.dir"
+ value="${com.vaadin.testbench.lib.dir}" />
+ <property name="com.vaadin.testbench.tester.host"
+ value="${com.vaadin.testbench.tester.host}" />
+ <property name="com.vaadin.testbench.deployment.url"
+ value="${deployment.url}" />
+ <property name="server.start.succeeded" value="1" />
+ <property name="browsers" value="${test_browsers}" />
+ <property name="testfiles" value="${testfiles}" />
+ <property name="test-output-dir"
+ value="${integration_test.dir}/result/integration-test-output/${server-name}" />
+ <property name="retries" value="0" />
+
+ <fileset dir="." includes="test.xml" />
+ </subant>
+ </target>
+
+ <target name="integration-test-theme">
+ <subant target="run-tests" failonerror="false" antfile="test.xml">
+ <property name="com.vaadin.testbench.lib.dir"
+ value="${com.vaadin.testbench.lib.dir}" />
+ <property name="com.vaadin.testbench.tester.host"
+ value="${com.vaadin.testbench.tester.host}" />
+ <property name="com.vaadin.testbench.deployment.url"
+ value="${deployment.url}" />
+ <property name="server.start.succeeded" value="1" />
+ <property name="testfiles" value="${testfiles-theme}" />
+ <property name="test-output-dir"
+ value="${integration_test.dir}/result/integration-test-output/${server-name}" />
+
+ <fileset dir="." includes="test.xml" />
+ </subant>
+ </target>
+
+ <!-- Run integration test on GAE -->
+ <target name="integration-test-test-GAE">
+ <fileset dir="integration-testscripts" id="html-test-files"
+ includes="GoogleAppEngine/integration-test-GAE.html" />
+ <pathconvert pathsep=" " property="test-GAE" refid="html-test-files" />
+
+ <subant target="run-tests" failonerror="false" antfile="test.xml">
+ <property name="com.vaadin.testbench.lib.dir"
+ value="${com.vaadin.testbench.lib.dir}" />
+ <property name="com.vaadin.testbench.tester.host"
+ value="${com.vaadin.testbench.tester.host}" />
+ <property name="com.vaadin.testbench.deployment.url"
+ value="http://vaadin-integration-test.appspot.com/" />
+ <property name="server.start.succeeded" value="1" />
+ <property name="browsers" value="${test_browsers}" />
+ <property name="testfiles" value="${test-GAE}" />
+ <property name="test-output-dir"
+ value="../build/integration-test-gae-output" />
+
+ <fileset dir="." includes="test.xml" />
+ </subant>
+ </target>
+
+ <target name="integration-test-deploy-to-GAE">
+ <sshexec host="${test.integration.server}" username="${user}"
+ keyfile="${sshkey.file}" command="ant -f ${ant.hub} deploy-to-GAE" />
+ </target>
+
+
+ <target name="integration-test-tomcat7">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="10" />
+ <param name="target-server" value="tomcat7" />
+ </antcall>
+ </target>
+ <target name="integration-test-tomcat5">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="10" />
+ <param name="target-server" value="tomcat5" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-tomcat6">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="10" />
+ <param name="target-server" value="tomcat6" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-jetty5">
+ <antcall target="run-generic-integration-test">
+ <param name="target-server" value="jetty5" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-jetty6">
+ <antcall target="run-generic-integration-test">
+ <param name="target-server" value="jetty6" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-jetty7">
+ <antcall target="run-generic-integration-test">
+ <param name="target-server" value="jetty7" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-jetty8">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="300" />
+ <param name="target-server" value="jetty8" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-jboss4">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="10" />
+ <param name="target-server" value="jboss4" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-jboss5">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="10" />
+ <param name="target-server" value="jboss5" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-jboss6">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="10" />
+ <param name="target-server" value="jboss6" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-jboss7">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="10" />
+ <param name="target-server" value="jboss7" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-glassfish2">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="10" />
+ <param name="target-server" value="glassfish2" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-glassfish3">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="10" />
+ <param name="target-server" value="glassfish3" />
+ </antcall>
+ </target>
+
+
+ <target name="integration-test-liferay6">
+ <fileset dir="integration-testscripts" id="html-test-files"
+ includes="Liferay-6/integration-test-liferay-6.0.5.html" />
+ <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
+
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="600" />
+ <param name="test_browsers" value="winxp-firefox17-esr" />
+ <param name="target-server" value="liferay6" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-liferay6-theme">
+ <fileset dir="integration-testscripts" id="html-test-files"
+ includes="Liferay-6/Liferay6-and-6EE-theme-deploy.html" />
+ <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
+
+ <fileset dir="integration-testscripts" id="html-theme-files"
+ includes="Liferay-6/Liferay6-theme.html" />
+ <pathconvert pathsep=" " property="testfiles-theme"
+ refid="html-theme-files" />
+
+
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="600" />
+ <param name="test_browsers" value="winxp-firefox17-esr" />
+ <param name="target-server" value="liferay6" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-liferay5">
+ <fileset dir="integration-testscripts" id="html-test-files"
+ includes="Liferay-5/integration-test-liferay-5.2.3-portlet2.html" />
+ <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
+
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="600" />
+ <param name="test_browsers" value="winxp-firefox17-esr" />
+ <param name="target-server" value="liferay5" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-liferay6ee">
+ <fileset dir="integration-testscripts" id="html-test-files"
+ includes="Liferay-6EE/integration-test-liferay-6ee.html" />
+ <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
+
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="600" />
+ <param name="test_browsers" value="winxp-firefox17-esr" />
+ <param name="target-server" value="liferay6ee" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-liferay6ee-theme">
+ <fileset dir="integration-testscripts" id="html-test-files"
+ includes="Liferay-6/Liferay6-and-6EE-theme-deploy.html" />
+ <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
+
+ <fileset dir="integration-testscripts" id="html-theme-files"
+ includes="Liferay-6EE/Liferay6EE-theme.html" />
+ <pathconvert pathsep=" " property="testfiles-theme"
+ refid="html-theme-files" />
+
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="600" />
+ <param name="test_browsers" value="winxp-firefox17-esr" />
+ <param name="target-server" value="liferay6ee" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-gatein3">
+ <fileset dir="integration-testscripts" id="html-test-files"
+ includes="GateIn-3/integration-test-GateIn-3.1.0-portlet2.html" />
+ <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="600" />
+ <param name="test_browsers" value="winxp-googlechrome21" />
+ <param name="target-server" value="gatein3" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-exo3">
+ <fileset dir="integration-testscripts" id="html-test-files"
+ includes="eXo-3/integration-test-eXo-3.0.3-portlet2.html" />
+ <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="600" />
+ <param name="test_browsers" value="winxp-firefox17-esr" />
+ <param name="target-server" value="exo3" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-websphere8">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="600" />
+ <param name="target-port" value="9080" />
+ <param name="target-server" value="websphere8" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-weblogic10">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="600" />
+ <param name="target-port" value="7001" />
+ <param name="target-server" value="weblogic10" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-weblogic12">
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="600" />
+ <param name="target-port" value="7001" />
+ <param name="target-server" value="weblogic12" />
+ </antcall>
+ </target>
+
+
+ <target name="integration-test-weblogicPortal">
+ <fileset dir="integration-testscripts" id="html-test-files"
+ includes="weblogic-portal/integration-test-WebLogic-Portal-10.3.2-portlet2.html" />
+ <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
+ <antcall target="run-generic-integration-test">
+ <param name="startDelay" value="600" />
+ <param name="target-port" value="7001" />
+ <param name="target-server" value="weblogicportal" />
+ </antcall>
+ </target>
+
+ <target name="integration-test-GAE">
+ <antcall target="integration-test-deploy-to-GAE" />
+ <antcall target="integration-test-test-GAE" />
+ </target>
+
+ <!-- Upload demo, clean error screenshots and test deployment on all
+ servers -->
+ <target name="integration-test-all">
+ <property name="passphrase" value="${passphrase}" />
+ <fail unless="sshkey.file" message="You must define an ssh.keyfile parameter" />
+ <fail unless="com.vaadin.testbench.screenshot.directory"
+ message="You must define a com.vaadin.testbench.screenshot.directory parameter" />
+ <parallel>
+ <antcontrib:trycatch property="tried">
+ <try>
+ <!-- Still running GAE test from the old server which
+ requires its own lock -->
+ <echo message="Getting lock" />
+ <antcall target="integration-test-get-lock" />
+ <echo message="Got lock" />
+ <antcall target="integration-test-upload-demo" />
+
+ <antcall target="run-integration-test">
+ <param name="target-server" value="GAE" />
+ </antcall>
+
+ <antcall target="integration-test-clean" />
+ <echo message="Getting lock" />
+ <antcall target="integration-test-release-lock" />
+ <echo message="Lock released" />
+
+ </try>
+ <catch>
+ <echo message="Uploading of demo.war failed. ${tried}" />
+ </catch>
+ </antcontrib:trycatch>
+ <antcall target="integration-test-liferay6" />
+ <antcall target="integration-test-liferay6ee" />
+ <antcall target="integration-test-liferay6-theme" />
+ <antcall target="integration-test-liferay6ee-theme" />
+ <antcall target="integration-test-exo3" />
+ <antcall target="integration-test-weblogicPortal" />
+ <antcall target="integration-test-liferay5" />
+ <antcall target="integration-test-weblogic10" />
+ <antcall target="integration-test-weblogic12" />
+ <antcall target="integration-test-gatein3" />
+ <antcall target="integration-test-glassfish2" />
+ <antcall target="integration-test-glassfish3" />
+ <antcall target="integration-test-jboss4" />
+ <antcall target="integration-test-jboss5" />
+ <antcall target="integration-test-jboss6" />
+ <antcall target="integration-test-jboss7" />
+ <antcall target="integration-test-jetty5" />
+ <antcall target="integration-test-jetty6" />
+ <antcall target="integration-test-jetty7" />
+ <antcall target="integration-test-jetty8" />
+ <antcall target="integration-test-tomcat5" />
+ <antcall target="integration-test-tomcat6" />
+ <antcall target="integration-test-tomcat7" />
+ <antcall target="integration-test-websphere8" />
+
+ </parallel>
+
+ </target>
+
+ <target name="do-run-generic-test">
+ <property name="target-host" value="${target-server}.devnet.vaadin.com" />
+ <property name="target-port" value="8080" />
+ <antcontrib:if>
+ <isset property="startDelay" />
+ <then>
+ <antcontrib:math result="sleepTime"
+ datatype="int">
+ <op op="rint">
+ <op op="*">
+ <num value="${startDelay}" />
+ <op op="random" />
+ </op>
+ </op>
+ </antcontrib:math>
+ <echo>Delaying startup of ${target-server} with
+ ${sleepTime} seconds</echo>
+ <sleep seconds="${sleepTime}" />
+ </then>
+ </antcontrib:if>
+
+ <scp todir="${user}@${target-host}:." keyfile="${sshkey.file}"
+ trust="yes" passphrase="${passphrase}">
+ <fileset dir="integration_base_files">
+ <include name="*" />
+ </fileset>
+ </scp>
+
+ <!-- trycatch probably not needed any more as it just fails with
+ the original message and doesn't do anything in the finally block -->
+ <antcontrib:trycatch property="error_message">
+ <try>
+ <!-- timeout in one hour (remote end should timeout in 55
+ minutes) -->
+ <sshexec host="${target-host}" outputproperty="lock-output"
+ timeout="3600000" username="${user}" keyfile="${sshkey.file}"
+ trust="yes" command="chmod +x *.sh; ant -f deploy.xml get-lock" />
+ <antcall target="echo-prefix">
+ <param name="prefix" value="${target-server}: " />
+ <param name="message" value="${lock-output}" />
+ </antcall>
+
+ <scp file="${demo.war}" todir="${user}@${target-host}:demo.war"
+ keyfile="${sshkey.file}" trust="yes" passphrase="${passphrase}" />
+
+ <!-- timeout in 15 minutes -->
+ <sshexec host="${target-host}" outputproperty="start-output"
+ timeout="900000" username="${user}" keyfile="${sshkey.file}"
+ trust="yes" command="ant -f deploy.xml startup-and-deploy"
+ failonerror="false" />
+ <antcall target="echo-prefix">
+ <param name="prefix" value="${target-server}: " />
+ <param name="message" value="${start-output}" />
+ </antcall>
+
+ <fail message="${start-output}">
+ <condition>
+ <not>
+ <contains string="${start-output}"
+ substring="Demo deployed successfully" />
+ </not>
+ </condition>
+ </fail>
+
+ <copy
+ file="integration-testscripts/common/integration_test.tpl"
+ tofile="integration-testscripts/integration-test-${target-server}-servlet.html"
+ overwrite="true" />
+ <antcall target="integration-test-servlet">
+ <param name="server-name" value="${target-server}" />
+ <param name="deployment.url"
+ value="http://${target-host}:${target-port}" />
+ </antcall>
+
+ <!-- Run theme tests in all browsers if there's a property
+ with the test files -->
+ <antcontrib:if>
+ <isset property="testfiles-theme" />
+ <antcontrib:then>
+ <antcall target="integration-test-theme">
+ <param name="server-name" value="${target-server}" />
+ <param name="deployment.url"
+ value="http://${target-host}:${target-port}" />
+ </antcall>
+ </antcontrib:then>
+ </antcontrib:if>
+
+ <!-- Run integration tests with push -->
+ <copy
+ file="integration-testscripts/common/integration_push_test.tpl"
+ tofile="integration-testscripts/integration-test-${target-server}-push-servlet.html"
+ overwrite="true" />
+ <antcall target="integration-test-push-servlet">
+ <param name="server-name" value="${target-server}" />
+ <param name="deployment.url"
+ value="http://${target-host}:${target-port}" />
+ </antcall>
+
+ <!-- Run theme tests in all browsers if there's a property
+ with the test files -->
+ <antcontrib:if>
+ <isset property="testfiles-theme" />
+ <antcontrib:then>
+ <antcall target="integration-test-theme">
+ <param name="server-name" value="${target-server}" />
+ <param name="deployment.url"
+ value="http://${target-host}:${target-port}" />
+ </antcall>
+ </antcontrib:then>
+ </antcontrib:if>
+
+ <!-- timeout in five minutes -->
+ <sshexec host="${target-host}" outputproperty="stop-output"
+ timeout="600000" username="${user}" keyfile="${sshkey.file}"
+ trust="yes" command="ant -f deploy.xml shutdown-and-cleanup"
+ failonerror="false" />
+ <antcall target="echo-prefix">
+ <param name="prefix" value="${target-server}: " />
+ <param name="message" value="${stop-output}" />
+ </antcall>
+ </try>
+ <catch>
+ <fail message="${error_message}" />
+ </catch>
+ </antcontrib:trycatch>
+ </target>
+
+ <target name="echo-prefix">
+ <antcontrib:propertyregex property="message-prefixed"
+ input="${prefix}${message}" regexp="\n" replace="\0${prefix}"
+ global="true" defaultValue="${prefix}${message}" />
+ <echo message="${message-prefixed}" />
+ </target>
+
+ <target name="run-generic-integration-test">
+ <concat>##teamcity[testStarted name='${target-server}'
+ flowId='${target-server}']</concat>
+ <antcontrib:trycatch property="tried">
+ <try>
+ <antcall target="do-run-generic-test" />
+ </try>
+ <catch>
+ <antcontrib:antcallback target="teamcity-escape"
+ return="tried-escaped">
+ <param name="returnTo" value="tried-escaped" />
+ <param name="message" value="${tried}" />
+ </antcontrib:antcallback>
+ <concat>##teamcity[testFailed name='${target-server}'
+ flowId='${target-server}' message='Integration test
+ for ${target-server} failed.'
+ details='${tried-escaped}']</concat>
+ </catch>
+ </antcontrib:trycatch>
+ <concat>##teamcity[testFinished name='${target-server}'
+ flowId='${target-server}']"</concat>
+ </target>
+
+ <target name="teamcity-escape">
+ <property name="returnTo" value="return" />
+
+ <!-- Should also perform other escaping (\u0085, \u2028 and \u2029)
+ - see http://confluence.jetbrains.net/display/TCD65/Build+Script+Interaction+with+TeamCity -->
+ <!-- Immutable properties -> needs to create a new one every time -->
+ <antcontrib:propertyregex property="details-escaped1"
+ input="${message}" regexp="['|\[\]]" replace="|\0" global="true"
+ defaultValue="${message}" />
+ <antcontrib:propertyregex property="details-escaped2"
+ input="${details-escaped1}" regexp="\n" replace="|n" global="true"
+ defaultValue="${details-escaped1}" />
+ <antcontrib:propertyregex property="details-escaped3"
+ input="${details-escaped2}" regexp="\r" replace="|r" global="true"
+ defaultValue="${details-escaped2}" />
+
+ <property name="${returnTo}" value="${details-escaped3}" />
+ </target>
+
+ <target name="run-integration-test">
+ <concat>##teamcity[testStarted name='${target-server}'
+ flowId='${target-server}']</concat>
+ <antcontrib:trycatch property="tried">
+ <try>
+ <antcall target="integration-test-${target-server}" />
+ </try>
+ <catch>
+ <antcallback target="teamcity-escape"
+ return="tried-escaped">
+ <param name="returnTo" value="tried-escaped" />
+ <param name="message" value="${tried}" />
+ </antcallback>
+ <concat>##teamcity[testFailed name='${target-server}'
+ flowId='${target-server}' message='Integration test
+ for ${target-server} failed.'
+ details='${tried-escaped}']"</concat>
+ </catch>
+ </antcontrib:trycatch>
+ <concat>##teamcity[testFinished name='${target-server}'
+ flowId='${target-server}']"</concat>
+ </target>
+
+ <target name="integration-test-get-lock">
+ <sshexec host="${test.integration.server}" username="${user}"
+ keyfile="${sshkey.file}" command="ant -f ${ant.hub} get-lock" />
+ </target>
+
+ <target name="integration-test-release-lock">
+ <sshexec host="${test.integration.server}" username="${user}"
+ keyfile="${sshkey.file}" command="ant -f ${ant.hub} release-lock" />
+ </target>
+
+ <!-- Remove demo.war -->
+ <target name="integration-test-clean">
+ <sshexec host="${test.integration.server}" username="${user}"
+ keyfile="${sshkey.file}" command="ant -f ${ant.hub} clean" />
+ </target>
</project>
diff --git a/uitest/ivy.xml b/uitest/ivy.xml
index bb54232852..7ff83324ae 100644
--- a/uitest/ivy.xml
+++ b/uitest/ivy.xml
@@ -14,8 +14,8 @@
<conf name="jetty-run" extends="build" visibility="private" />
</configurations>
<publications>
- <artifact type="war" ext="war"/>
- </publications>
+ <artifact type="war" ext="war" />
+ </publications>
<dependencies defaultconf="build" defaultconfmapping="build,ide->default">
<!-- API DEPENDENCIES -->
<dependency org="javax.portlet" name="portlet-api"
@@ -40,9 +40,9 @@
rev="${vaadin.version}" conf="build->build"></dependency>
<dependency org="com.vaadin" name="vaadin-themes"
rev="${vaadin.version}" conf="build->build"></dependency>
- <dependency org="com.vaadin" name="vaadin-push"
- rev="${vaadin.version}" conf="build->build"></dependency>
-
+ <dependency org="com.vaadin" name="vaadin-push" rev="${vaadin.version}"
+ conf="build->build"></dependency>
+
<!-- For compiling TestingWidgetSet -->
<dependency org="com.vaadin" name="vaadin-client-compiler"
rev="${vaadin.version}" conf="build-provided-> build"></dependency>
diff --git a/uitest/src/com/vaadin/tests/applicationcontext/CloseUI.java b/uitest/src/com/vaadin/tests/applicationcontext/CloseUI.java
index bec8c0a10f..c88f482a7b 100644
--- a/uitest/src/com/vaadin/tests/applicationcontext/CloseUI.java
+++ b/uitest/src/com/vaadin/tests/applicationcontext/CloseUI.java
@@ -119,7 +119,7 @@ public class CloseUI extends AbstractTestUI {
@Override
public void run() {
- ui.access(new Runnable() {
+ ui.accessSynchronously(new Runnable() {
@Override
public void run() {
diff --git a/uitest/src/com/vaadin/tests/applicationcontext/UIRunSafelyThread.java b/uitest/src/com/vaadin/tests/applicationcontext/UIRunSafelyThread.java
index ddc0f28664..c9af2c000d 100644
--- a/uitest/src/com/vaadin/tests/applicationcontext/UIRunSafelyThread.java
+++ b/uitest/src/com/vaadin/tests/applicationcontext/UIRunSafelyThread.java
@@ -11,7 +11,7 @@ public abstract class UIRunSafelyThread extends Thread {
@Override
public void run() {
- ui.access(new Runnable() {
+ ui.accessSynchronously(new Runnable() {
@Override
public void run() {
diff --git a/uitest/src/com/vaadin/tests/components/AbstractComponentTestCase.java b/uitest/src/com/vaadin/tests/components/AbstractComponentTestCase.java
index 81ec4a9da4..8666956bdb 100644
--- a/uitest/src/com/vaadin/tests/components/AbstractComponentTestCase.java
+++ b/uitest/src/com/vaadin/tests/components/AbstractComponentTestCase.java
@@ -226,6 +226,13 @@ public abstract class AbstractComponentTestCase<T extends AbstractComponent>
}
};
+ protected Command<T, String> primaryStyleNameCommand = new Command<T, String>() {
+ @Override
+ public void execute(T c, String value, Object data) {
+ c.setPrimaryStyleName(value);
+ }
+ };
+
@Override
protected String getDescription() {
return "Generic test case for " + getTestClass().getSimpleName();
diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarDragAndDrop.html b/uitest/src/com/vaadin/tests/components/calendar/CalendarDragAndDrop.html
new file mode 100644
index 0000000000..425f95c529
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarDragAndDrop.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:7171/" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.calendar.CalendarDragAndDrop?restartApplication</td>
+ <td></td>
+</tr>
+<!--// Test drag and drop in month view-->
+<tr>
+ <td>drag</td>
+ <td>vaadin=runcomvaadintestscomponentscalendarCalendarDragAndDrop::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VHorizontalLayout[0]/Slot[1]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[9]/domChild[0]/domChild[0]</td>
+ <td>76,7</td>
+</tr>
+<tr>
+ <td>drop</td>
+ <td>vaadin=runcomvaadintestscomponentscalendarCalendarDragAndDrop::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VHorizontalLayout[0]/Slot[0]/VCalendar[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[5]/domChild[0]/domChild[2]</td>
+ <td>54,9</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentscalendarCalendarDragAndDrop::PID_SCalendar/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[5]/domChild[0]/domChild[1]</td>
+ <td>12:00 AM Event 10</td>
+</tr>
+<!--//Test drag and drop in week view-->
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentscalendarCalendarDragAndDrop::PID_SCalendar/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[0]</td>
+ <td>7,85</td>
+</tr>
+<tr>
+ <td>drag</td>
+ <td>vaadin=runcomvaadintestscomponentscalendarCalendarDragAndDrop::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VHorizontalLayout[0]/Slot[1]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[11]/domChild[0]/domChild[0]</td>
+ <td>34,12</td>
+</tr>
+<tr>
+ <td>drop</td>
+ <td>vaadin=runcomvaadintestscomponentscalendarCalendarDragAndDrop::PID_SCalendar/domChild[0]/domChild[3]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]/domChild[0]/domChild[15]</td>
+ <td>75,9</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentscalendarCalendarDragAndDrop::PID_SCalendar/domChild[0]/domChild[3]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]/domChild[0]/domChild[48]/domChild[0]</td>
+ <td>7:30 AM: Event 13</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarDragAndDrop.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarDragAndDrop.java
new file mode 100644
index 0000000000..7477fc84ce
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarDragAndDrop.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ *
+ */
+package com.vaadin.tests.components.calendar;
+
+import java.util.GregorianCalendar;
+import java.util.Locale;
+
+import com.vaadin.event.dd.DragAndDropEvent;
+import com.vaadin.event.dd.DropHandler;
+import com.vaadin.event.dd.acceptcriteria.AcceptAll;
+import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Calendar;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.TableDragMode;
+import com.vaadin.ui.Table.TableTransferable;
+import com.vaadin.ui.components.calendar.CalendarTargetDetails;
+import com.vaadin.ui.components.calendar.event.BasicEvent;
+
+public class CalendarDragAndDrop extends AbstractTestUI {
+
+ private Calendar calendar;
+
+ private Table table;
+
+ private class TestDropHandler implements DropHandler {
+
+ @Override
+ public void drop(DragAndDropEvent event) {
+ CalendarTargetDetails details = (CalendarTargetDetails) event
+ .getTargetDetails();
+
+ TableTransferable transferable = (TableTransferable) event
+ .getTransferable();
+
+ calendar.addEvent(new BasicEvent(transferable.getItemId()
+ .toString(), "This event was dragged here", details
+ .getDropTime()));
+
+ table.removeItem(transferable.getItemId());
+ }
+
+ @Override
+ public AcceptCriterion getAcceptCriterion() {
+ return AcceptAll.get();
+ }
+ }
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ setSizeFull();
+ getContent().setSizeFull();
+ getLayout().setSizeFull();
+
+ HorizontalLayout root = new HorizontalLayout();
+ root.setSizeFull();
+ addComponent(root);
+
+ Locale locale = new Locale("en", "US");
+ GregorianCalendar cal = new GregorianCalendar(locale);
+ cal.set(2013, 0, 1);
+
+ calendar = new Calendar();
+ calendar.setId("Calendar");
+ calendar.setLocale(locale);
+ calendar.setDropHandler(new TestDropHandler());
+ calendar.setSizeFull();
+ root.addComponent(calendar);
+
+ calendar.setStartDate(cal.getTime());
+ cal.add(java.util.Calendar.MONTH, 1);
+ calendar.setEndDate(cal.getTime());
+
+ table = new Table();
+ table.setSizeFull();
+ table.setDragMode(TableDragMode.ROW);
+ table.addGeneratedColumn("COLUMN", new Table.ColumnGenerator() {
+
+ @Override
+ public Object generateCell(Table source, Object itemId,
+ Object columnId) {
+ return itemId;
+ }
+ });
+
+ for (int eventNum = 1; eventNum < 50; eventNum++) {
+ table.addItem("Event " + eventNum);
+ }
+
+ root.addComponent(table);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 11048;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/CustomDateFormats.java b/uitest/src/com/vaadin/tests/components/datefield/CustomDateFormats.java
index 247478256f..015a974b3e 100644
--- a/uitest/src/com/vaadin/tests/components/datefield/CustomDateFormats.java
+++ b/uitest/src/com/vaadin/tests/components/datefield/CustomDateFormats.java
@@ -104,6 +104,7 @@ public class CustomDateFormats extends TestBase {
locale);
addDateField(gridLayout, getDatePattern(locale, DateFormat.SHORT),
locale);
+ addDateField(gridLayout, "EEE d MMMM yyyy", locale);
}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldLocale.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldLocale.java
index 5d06895d11..a4fe2b0285 100644
--- a/uitest/src/com/vaadin/tests/components/datefield/DateFieldLocale.java
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldLocale.java
@@ -16,7 +16,7 @@ public class DateFieldLocale extends TestBase {
final DateField dateField = new DateField("DateField");
dateField.setLocale(new Locale("fi", "FI"));
dateField.setCaption(dateField.getLocale().toString());
- dateField.setValue(new Date());
+ dateField.setValue(new Date(2013 - 1900, 7 - 1, 27));
dateField.setResolution(DateField.RESOLUTION_DAY);
addComponent(new Button("Change locale", new ClickListener() {
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldPrimaryStyleNames.html b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPrimaryStyleNames.html
index 31216ed1b0..38034fd0c8 100644
--- a/uitest/src/com/vaadin/tests/components/datefield/DateFieldPrimaryStyleNames.html
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPrimaryStyleNames.html
@@ -68,12 +68,12 @@
</tr>
<tr>
<td>assertCSSClass</td>
- <td>//body/div[last()]/div[last()]</td>
+ <td>//body/div[2]/div[last()]</td>
<td>my-datefield-popup</td>
</tr>
<tr>
<td>assertCSSClass</td>
- <td>//body/div[last()]/div[last()]</td>
+ <td>//body/div[2]/div[last()]</td>
<td>my-datefield-day</td>
</tr>
<tr>
@@ -188,12 +188,12 @@
</tr>
<tr>
<td>assertCSSClass</td>
- <td>//body/div[last()]/div[last()]</td>
+ <td>//body/div[2]/div[last()]</td>
<td>my-second-datefield-popup</td>
</tr>
<tr>
<td>assertCSSClass</td>
- <td>//body/div[last()]/div[last()]</td>
+ <td>//body/div[2]/div[last()]</td>
<td>my-second-datefield-day</td>
</tr>
<tr>
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.html b/uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.html
new file mode 100644
index 0000000000..77c610f211
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.html
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:8888/" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.datefield.DynamicallyChangeDateRange?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsdatefieldDynamicallyChangeDateRange::/VVerticalLayout[0]/Slot[0]/VPopupCalendar[0]#popupButton</td>
+ <td>11,8</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[2]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[3]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[4]/td[6]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[4]/td[7]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsdatefieldDynamicallyChangeDateRange::</td>
+ <td>201,401</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsdatefieldDynamicallyChangeDateRange::/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsdatefieldDynamicallyChangeDateRange::/VVerticalLayout[0]/Slot[0]/VPopupCalendar[0]#popupButton</td>
+ <td>14,16</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[2]/td[4]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[2]/td[5]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[5]/td[4]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[5]/td[5]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsdatefieldDynamicallyChangeDateRange::</td>
+ <td>237,338</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsdatefieldDynamicallyChangeDateRange::/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsdatefieldDynamicallyChangeDateRange::/VVerticalLayout[0]/Slot[0]/VPopupCalendar[0]#popupButton</td>
+ <td>14,15</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[2]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[3]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[4]/td[6]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[4]/td[7]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[2]/span</td>
+ <td>v-datefield-calendarpanel-day-outside-range</td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.java b/uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.java
new file mode 100644
index 0000000000..fb0fb2a546
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DynamicallyChangeDateRange.java
@@ -0,0 +1,93 @@
+package com.vaadin.tests.components.datefield;
+
+import java.util.Date;
+import java.util.Locale;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.DateField;
+import com.vaadin.ui.InlineDateField;
+import com.vaadin.ui.PopupDateField;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ * Main UI class
+ */
+@SuppressWarnings("serial")
+public class DynamicallyChangeDateRange extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ setLocale(Locale.ENGLISH);
+ final VerticalLayout layout = new VerticalLayout();
+ layout.setMargin(true);
+ setContent(layout);
+
+ final PopupDateField df = new PopupDateField();
+ df.setValue(new Date(2012 - 1900, 5 - 1, 12));
+ setRange(df, 5);
+ layout.addComponent(df);
+
+ final InlineDateField df2 = new InlineDateField();
+ df2.setValue(new Date(2012 - 1900, 11 - 1, 16));
+
+ setRange(df2, 5);
+ // layout.addComponent(df2);
+
+ Button button1 = new Button("Set Range Now+/-5d");
+ button1.addClickListener(new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ setRange(df, 5);
+ setRange(df2, 5);
+ }
+ });
+ layout.addComponent(button1);
+
+ Button button2 = new Button("Set Range Now+/-10d");
+ button2.addClickListener(new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ setRange(df, 10);
+ setRange(df2, 10);
+ }
+ });
+ layout.addComponent(button2);
+ }
+
+ /**
+ * @since
+ * @param df
+ * @param i
+ */
+ private void setRange(DateField df, int days) {
+ df.setRangeStart(new Date(df.getValue().getTime() - days * 24 * 60 * 60
+ * 1000));
+ df.setRangeEnd(new Date(df.getValue().getTime() + days * 24 * 60 * 60
+ * 1000));
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription()
+ */
+ @Override
+ protected String getTestDescription() {
+ return "Verifies that the allowed date range can be updated dynamically";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber()
+ */
+ @Override
+ protected Integer getTicketNumber() {
+ return 11940;
+ }
+
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/popupview/PopupViewAndFragment.html b/uitest/src/com/vaadin/tests/components/popupview/PopupViewAndFragment.html
new file mode 100644
index 0000000000..28af578bac
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/popupview/PopupViewAndFragment.html
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:8888/" />
+<title>PopupViewAndFragment</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">PopupViewAndFragment</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/PopupViewAndFragment?restartApplication#</td>
+ <td></td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runPopupViewAndFragment::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/popupview/PopupViewAndFragment.java b/uitest/src/com/vaadin/tests/components/popupview/PopupViewAndFragment.java
new file mode 100644
index 0000000000..1606b78604
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/popupview/PopupViewAndFragment.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.popupview;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.PopupView;
+
+public class PopupViewAndFragment extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ final PopupView pw = new PopupView("Open", new Label("Oh, hi"));
+ addComponent(pw);
+
+ final Button button = new Button("Open and change fragment",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(final ClickEvent event) {
+ pw.setPopupVisible(true);
+ getPage().setUriFragment(
+ String.valueOf(System.currentTimeMillis()));
+ }
+ });
+ addComponent(button);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Changing frament should not automatically close PopupView";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 10530;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarGenericTest.java b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarGenericTest.java
new file mode 100644
index 0000000000..79797c60a2
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarGenericTest.java
@@ -0,0 +1,55 @@
+package com.vaadin.tests.components.progressindicator;
+
+import java.util.LinkedHashMap;
+
+import com.vaadin.tests.components.abstractfield.AbstractFieldTest;
+import com.vaadin.ui.ProgressBar;
+
+public class ProgressBarGenericTest extends AbstractFieldTest<ProgressBar> {
+
+ private Command<ProgressBar, Boolean> indeterminate = new Command<ProgressBar, Boolean>() {
+
+ @Override
+ public void execute(ProgressBar c, Boolean value, Object data) {
+ c.setIndeterminate(value);
+ }
+ };
+
+ @Override
+ protected Class<ProgressBar> getTestClass() {
+ return ProgressBar.class;
+ }
+
+ @Override
+ protected void createActions() {
+ super.createActions();
+ createBooleanAction("Indeterminate", CATEGORY_FEATURES, false,
+ indeterminate, null);
+ createValueSelection(CATEGORY_FEATURES);
+ createPrimaryStyleNameSelect();
+ }
+
+ /**
+ * @since
+ */
+ protected void createPrimaryStyleNameSelect() {
+ LinkedHashMap<String, String> options = new LinkedHashMap<String, String>();
+ String primaryStyle = getComponent().getPrimaryStyleName();
+ options.put(primaryStyle, primaryStyle);
+ options.put(primaryStyle + "-foo", primaryStyle + "-foo");
+ options.put("foo", "foo");
+ createSelectAction("Primary style name", CATEGORY_DECORATIONS, options,
+ primaryStyle, primaryStyleNameCommand);
+
+ }
+
+ private void createValueSelection(String categorySelection) {
+ LinkedHashMap<String, Object> options = new LinkedHashMap<String, Object>();
+ options.put("null", null);
+ for (float f = 0; f <= 1; f += 0.1) {
+ options.put("" + f, f);
+ }
+ createSelectAction("Value", categorySelection, options, null,
+ setValueCommand);
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarPrimaryStyleName.html b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarPrimaryStyleName.html
new file mode 100644
index 0000000000..92f678947a
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarPrimaryStyleName.html
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:8888/" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.progressindicator.ProgressBarGenericTest?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_StestComponent</td>
+ <td>v-progressbar</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_StestComponent/domChild[0]</td>
+ <td>v-progressbar-wrapper</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_StestComponent/domChild[0]/domChild[0]</td>
+ <td>v-progressbar-indicator</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_Smenu#item0</td>
+ <td>36,8</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::Root/VOverlay[0]/VMenuBar[0]#item1</td>
+ <td>45,4</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::Root/VOverlay[1]/VMenuBar[0]#item6</td>
+ <td>67,10</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::Root/VOverlay[2]/VMenuBar[0]#item2</td>
+ <td>37,7</td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_StestComponent</td>
+ <td>v-progressbar</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_StestComponent</td>
+ <td>foo</td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_StestComponent/domChild[0]</td>
+ <td>v-progressbar-wrapper</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_StestComponent/domChild[0]</td>
+ <td>foo-wrapper</td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_StestComponent/domChild[0]/domChild[0]</td>
+ <td>v-progressbar-indicator</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_StestComponent/domChild[0]/domChild[0]</td>
+ <td>foo-indicator</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_Smenu#item0</td>
+ <td>20,13</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::Root/VOverlay[0]/VMenuBar[0]#item1</td>
+ <td>34,11</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::Root/VOverlay[1]/VMenuBar[0]#item6</td>
+ <td>51,4</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::Root/VOverlay[2]/VMenuBar[0]#item0</td>
+ <td>38,6</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_StestComponent</td>
+ <td>v-progressbar</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_StestComponent/domChild[0]</td>
+ <td>v-progressbar-wrapper</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarGenericTest::PID_StestComponent/domChild[0]/domChild[0]</td>
+ <td>v-progressbar-indicator</td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarTest.html b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarTest.html
new file mode 100644
index 0000000000..b7add101f9
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarTest.html
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.progressindicator.ProgressBarTest?restartApplication</td>
+ <td></td>
+</tr>
+<!--Add ProgressBar and wait-->
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>pause</td>
+ <td>1000</td>
+ <td></td>
+</tr>
+<!--Text should not have changed-->
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
+ <td>0</td>
+</tr>
+<!--Add ProgressIndicator and wait-->
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>pause</td>
+ <td>1000</td>
+ <td></td>
+</tr>
+<!--Text should have changed-->
+<tr>
+ <td>assertNotText</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
+ <td>0</td>
+</tr>
+<!--Stop thread right away if we get this far (would otherwise continue running until the UI is detached)-->
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsprogressindicatorProgressBarTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarTest.java b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarTest.java
new file mode 100644
index 0000000000..5afa874220
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.tests.components.progressindicator;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.ProgressBar;
+import com.vaadin.ui.ProgressIndicator;
+
+public class ProgressBarTest extends AbstractTestUI {
+
+ private Label updatedFromBackround;
+ private Thread updateThread = new Thread() {
+ @Override
+ public void run() {
+ Runnable updateTask = new Runnable() {
+ @Override
+ public void run() {
+ counter++;
+ updateLabel();
+ }
+ };
+
+ while (true) {
+ access(updateTask);
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+ }
+ };
+ private ProgressBar progressBar;
+ private int counter = 0;
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ updatedFromBackround = new Label();
+ updatedFromBackround.setCaption("Updated from background thread");
+ updateLabel();
+ addComponent(updatedFromBackround);
+
+ addComponent(new Button("Use ProgressBar", new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ useComponent(new ProgressBar());
+ }
+ }));
+
+ addComponent(new Button("Use ProgressIndicator",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ useComponent(new ProgressIndicator());
+ }
+ }));
+
+ addComponent(new Button("Stop background thread",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ stopUpdateThread();
+ }
+ }));
+ updateThread.setDaemon(true);
+ updateThread.start();
+ }
+
+ private void useComponent(ProgressBar progressBar) {
+ if (this.progressBar != null) {
+ removeComponent(this.progressBar);
+ }
+ this.progressBar = progressBar;
+ addComponent(progressBar);
+
+ counter = 0;
+ updateLabel();
+ }
+
+ @Override
+ public void detach() {
+ super.detach();
+ stopUpdateThread();
+ }
+
+ private void stopUpdateThread() {
+ if (updateThread != null) {
+ updateThread.interrupt();
+ updateThread = null;
+ }
+ }
+
+ private void updateLabel() {
+ updatedFromBackround.setValue(String.valueOf(counter));
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "ProgressBar should work just as ProgressIndicator, just without the polling";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return Integer.valueOf(11925);
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/richtextarea/RichTextAreaUpdateWhileTyping.html b/uitest/src/com/vaadin/tests/components/richtextarea/RichTextAreaUpdateWhileTyping.html
new file mode 100644
index 0000000000..6ddd1b4097
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/richtextarea/RichTextAreaUpdateWhileTyping.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:7070/" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.richtextarea.RichTextAreaUpdateWhileTyping?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>selectFrame</td>
+ <td>xpath=//div[@id='rta']/iframe</td>
+ <td></td>
+</tr>
+<tr>
+ <td>type</td>
+ <td>//body</td>
+ <td>This text should be visible, even after an update while I type.</td>
+</tr>
+<tr>
+ <td>pause</td>
+ <td>2000</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>//body</td>
+ <td>This text should be visible, even after an update while I type.</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/richtextarea/RichTextAreaUpdateWhileTyping.java b/uitest/src/com/vaadin/tests/components/richtextarea/RichTextAreaUpdateWhileTyping.java
new file mode 100644
index 0000000000..df1d6df463
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/richtextarea/RichTextAreaUpdateWhileTyping.java
@@ -0,0 +1,51 @@
+package com.vaadin.tests.components.richtextarea;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.progressindicator.ProgressIndicatorServerRpc;
+import com.vaadin.tests.components.AbstractComponentTest;
+import com.vaadin.tests.components.AbstractTestCase;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.ProgressIndicator;
+import com.vaadin.ui.RichTextArea;
+
+public class RichTextAreaUpdateWhileTyping extends AbstractTestUI {
+
+ private RichTextArea rta;
+
+ @Override
+ protected void setup(VaadinRequest request) {
+
+ // Progress indicator for changing the value of the RTA
+ ProgressIndicator pi = new ProgressIndicator() {
+ {
+ registerRpc(new ProgressIndicatorServerRpc() {
+
+ @Override
+ public void poll() {
+ rta.markAsDirty();
+ }
+ });
+ }
+ };
+ pi.setHeight("0px");
+ addComponent(pi);
+
+ rta = new RichTextArea();
+ rta.setId("rta");
+ rta.setImmediate(true);
+ addComponent(rta);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 11741;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.html b/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.html
new file mode 100644
index 0000000000..96df94148c
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.html
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:8888/" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.table.TableSqlContainer?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td>
+ <td>May 24, 2013 12:00:00 AM</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]</td>
+ <td>12,7</td>
+</tr>
+<tr>
+ <td>assertValue</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VPopupCalendar[0]#field</td>
+ <td>5/24/13</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VPopupCalendar[0]#popupButton</td>
+ <td>9,7</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[4]/td[5]/span</td>
+ <td>11,10</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]</td>
+ <td>9,12</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td>
+ <td>May 15, 2013 12:00:00 AM</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[0]</td>
+ <td>Apr 26, 2013 12:00:00 AM</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[1]/domChild[0]</td>
+ <td>May 27, 2013 12:00:00 AM</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[3]/domChild[1]/domChild[0]</td>
+ <td>Apr 28, 2013 12:00:00 AM</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.java b/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.java
new file mode 100644
index 0000000000..5191b1b86e
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.java
@@ -0,0 +1,142 @@
+package com.vaadin.tests.components.table;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Locale;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.util.sqlcontainer.SQLContainer;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.TableQuery;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.VerticalLayout;
+
+public class TableSqlContainer extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ setLocale(Locale.ENGLISH);
+ VerticalLayout layout = new VerticalLayout();
+ addComponent(layout);
+
+ final Table table = new Table("Table with SQLContainer");
+ layout.addComponent(table);
+
+ final Label selectedLabel = new Label("Selected: null");
+ layout.addComponent(selectedLabel);
+
+ try {
+ JDBCConnectionPool connectionPool = new SimpleJDBCConnectionPool(
+ "org.hsqldb.jdbc.JDBCDriver",
+ "jdbc:hsqldb:mem:sqlcontainer", "SA", "", 2, 20);
+
+ createTestTable(connectionPool);
+ insertTestData(connectionPool);
+
+ TableQuery q = new TableQuery("mytable", connectionPool);
+ q.setVersionColumn("version");
+ SQLContainer myContainer = new SQLContainer(q);
+
+ table.setContainerDataSource(myContainer);
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ table.setImmediate(true);
+ table.setSizeFull();
+ table.setSelectable(true);
+ table.addValueChangeListener(new Property.ValueChangeListener() {
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ selectedLabel.setValue("Selected: "
+ + event.getProperty().getValue());
+ }
+ });
+
+ final CheckBox editMode = new CheckBox("Edit mode");
+ editMode.addValueChangeListener(new ValueChangeListener() {
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ table.setEditable(editMode.getValue());
+ }
+ });
+ addComponent(editMode);
+ }
+
+ /**
+ * (Re)creates the test table
+ *
+ * @param connectionPool
+ */
+ private void createTestTable(JDBCConnectionPool connectionPool) {
+ Connection conn = null;
+ try {
+ conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+ try {
+ statement.executeUpdate("DROP TABLE mytable");
+ } catch (SQLException e) {
+ }
+ statement.execute("CREATE TABLE mytable "
+ + "(id INTEGER GENERATED BY DEFAULT AS IDENTITY, D DATE,"
+ + "MYFIELD VARCHAR(45), " + "PRIMARY KEY(ID))");
+ statement.close();
+ conn.commit();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ } finally {
+ connectionPool.releaseConnection(conn);
+ }
+ }
+
+ /**
+ * Adds test data to the test table
+ *
+ * @param connectionPool
+ * @throws SQLException
+ */
+ private void insertTestData(JDBCConnectionPool connectionPool)
+ throws SQLException {
+ Connection conn = null;
+ try {
+ conn = connectionPool.reserveConnection();
+ Statement statement = conn.createStatement();
+
+ statement
+ .executeUpdate("INSERT INTO mytable VALUES(1, '2013-05-24', 'A0')");
+ statement
+ .executeUpdate("INSERT INTO mytable VALUES(2, '2013-04-26', 'A1')");
+ statement
+ .executeUpdate("INSERT INTO mytable VALUES(3, '2013-05-27', 'B0')");
+ statement
+ .executeUpdate("INSERT INTO mytable VALUES(4, '2013-04-28', 'B1')");
+
+ statement.close();
+ conn.commit();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ } finally {
+ connectionPool.releaseConnection(conn);
+ }
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "A test with Table connected to a SQLContainer using TableQuery";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 11224;
+ }
+
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/ui/UiAccess.html b/uitest/src/com/vaadin/tests/components/ui/UiAccess.html
new file mode 100644
index 0000000000..613691623c
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/ui/UiAccess.html
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.ui.UiAccess?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_2</td>
+ <td>exact:0. Access from UI thread future is done? false</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
+ <td>1. Access from UI thread is run</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
+ <td>exact:2. beforeClientResponse future is done? true</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
+ <td>0. Initial background message</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
+ <td>exact:1. Thread has current response? false</td>
+</tr>
+<tr>
+ <td>waitForText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_2</td>
+ <td>0. Initial background message</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
+ <td>exact:2. Thread got lock, inital future done? true</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_2</td>
+ <td>0. Throwing exception in access</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
+ <td>exact:1. firstFuture is done? true</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
+ <td>2. Got exception from firstFuture: java.lang.RuntimeException: Catch me if you can</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
+ <td>0. future was cancled, should not start</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[4]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_2</td>
+ <td>0. Waiting for thread to start</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
+ <td>1. Thread started, waiting for interruption</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
+ <td>2. I was interrupted</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_3</td>
+ <td>0. accessSynchronously has request? true</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_2</td>
+ <td>1. Test value in accessSynchronously: Set before accessSynchronosly</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
+ <td>2. has request after accessSynchronously? true</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
+ <td>3. Test value after accessSynchornously: Set in accessSynchronosly</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[6]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_3</td>
+ <td>0. access has request? false</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_2</td>
+ <td>1. Test value in access: Set before access</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_1</td>
+ <td>2. has request after access? true</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUiAccess::PID_SLog_row_0</td>
+ <td>3. Test value after access: Set before run pending</td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/ui/UiAccess.java b/uitest/src/com/vaadin/tests/components/ui/UiAccess.java
new file mode 100644
index 0000000000..2bc91fa7b4
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/ui/UiAccess.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.tests.components.ui;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.locks.ReentrantLock;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinService;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.util.CurrentInstance;
+
+public class UiAccess extends AbstractTestUIWithLog {
+
+ private Future<Void> checkFromBeforeClientResponse;
+
+ private class CurrentInstanceTestType {
+ private String value;
+
+ public CurrentInstanceTestType(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+ }
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ addComponent(new Button("Access from UI thread",
+ new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ log.clear();
+ // Ensure beforeClientResponse is invoked
+ markAsDirty();
+ checkFromBeforeClientResponse = access(new Runnable() {
+ @Override
+ public void run() {
+ log("Access from UI thread is run");
+ }
+ });
+ log("Access from UI thread future is done? "
+ + checkFromBeforeClientResponse.isDone());
+ }
+ }));
+ addComponent(new Button("Access from background thread",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ log.clear();
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ new Thread() {
+ @Override
+ public void run() {
+ final boolean threadHasCurrentResponse = VaadinService
+ .getCurrentResponse() != null;
+ // session is locked by request thread at this
+ // point
+ final Future<Void> initialFuture = access(new Runnable() {
+ @Override
+ public void run() {
+ log("Initial background message");
+ log("Thread has current response? "
+ + threadHasCurrentResponse);
+ }
+ });
+
+ // Let request thread continue
+ latch.countDown();
+
+ // Wait until thread can be locked
+ while (!getSession().getLockInstance()
+ .tryLock()) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ try {
+ log("Thread got lock, inital future done? "
+ + initialFuture.isDone());
+ setPollInterval(-1);
+ } finally {
+ getSession().unlock();
+ }
+ }
+ }.start();
+
+ // Wait for thread to do initialize before continuing
+ try {
+ latch.await();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+
+ setPollInterval(3000);
+ }
+ }));
+ addComponent(new Button("Access throwing exception",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ log.clear();
+ final Future<Void> firstFuture = access(new Runnable() {
+ @Override
+ public void run() {
+ log("Throwing exception in access");
+ throw new RuntimeException(
+ "Catch me if you can");
+ }
+ });
+ access(new Runnable() {
+ @Override
+ public void run() {
+ log("firstFuture is done? "
+ + firstFuture.isDone());
+ try {
+ firstFuture.get();
+ log("Should not get here");
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ } catch (ExecutionException e) {
+ log("Got exception from firstFuture: "
+ + e.getMessage());
+ }
+ }
+ });
+ }
+ }));
+ addComponent(new Button("Cancel future before started",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ log.clear();
+ Future<Void> future = access(new Runnable() {
+ @Override
+ public void run() {
+ log("Should not get here");
+ }
+ });
+ future.cancel(false);
+ log("future was cancled, should not start");
+ }
+ }));
+ addComponent(new Button("Cancel running future",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ log.clear();
+ final ReentrantLock interruptLock = new ReentrantLock();
+
+ final Future<Void> future = access(new Runnable() {
+ @Override
+ public void run() {
+ log("Waiting for thread to start");
+ while (!interruptLock.isLocked()) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ log("Premature interruption");
+ throw new RuntimeException(e);
+ }
+ }
+
+ log("Thread started, waiting for interruption");
+ try {
+ interruptLock.lockInterruptibly();
+ } catch (InterruptedException e) {
+ log("I was interrupted");
+ }
+ }
+ });
+
+ new Thread() {
+ @Override
+ public void run() {
+ interruptLock.lock();
+ // Wait until UI thread has started waiting for
+ // the lock
+ while (!interruptLock.hasQueuedThreads()) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ future.cancel(true);
+ }
+ }.start();
+ }
+ }));
+ addComponent(new Button("CurrentInstance accessSynchronously values",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ log.clear();
+ // accessSynchronously should maintain values
+ CurrentInstance.set(CurrentInstanceTestType.class,
+ new CurrentInstanceTestType(
+ "Set before accessSynchronosly"));
+ accessSynchronously(new Runnable() {
+ @Override
+ public void run() {
+ log.log("accessSynchronously has request? "
+ + (VaadinService.getCurrentRequest() != null));
+ log.log("Test value in accessSynchronously: "
+ + CurrentInstance
+ .get(CurrentInstanceTestType.class));
+ CurrentInstance.set(
+ CurrentInstanceTestType.class,
+ new CurrentInstanceTestType(
+ "Set in accessSynchronosly"));
+ }
+ });
+ log.log("has request after accessSynchronously? "
+ + (VaadinService.getCurrentRequest() != null));
+ log("Test value after accessSynchornously: "
+ + CurrentInstance
+ .get(CurrentInstanceTestType.class));
+ }
+ }));
+ addComponent(new Button("CurrentInstance access values",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ log.clear();
+ // accessSynchronously should maintain values
+ CurrentInstance
+ .setInheritable(CurrentInstanceTestType.class,
+ new CurrentInstanceTestType(
+ "Set before access"));
+ access(new Runnable() {
+ @Override
+ public void run() {
+ log.log("access has request? "
+ + (VaadinService.getCurrentRequest() != null));
+ log.log("Test value in access: "
+ + CurrentInstance
+ .get(CurrentInstanceTestType.class));
+ CurrentInstance.setInheritable(
+ CurrentInstanceTestType.class,
+ new CurrentInstanceTestType(
+ "Set in access"));
+ }
+ });
+ CurrentInstance.setInheritable(
+ CurrentInstanceTestType.class,
+ new CurrentInstanceTestType(
+ "Set before run pending"));
+
+ getSession().getService().runPendingAccessTasks(
+ getSession());
+
+ log.log("has request after access? "
+ + (VaadinService.getCurrentRequest() != null));
+ log("Test value after access: "
+ + CurrentInstance
+ .get(CurrentInstanceTestType.class));
+ }
+ }));
+ }
+
+ @Override
+ public void beforeClientResponse(boolean initial) {
+ if (checkFromBeforeClientResponse != null) {
+ log("beforeClientResponse future is done? "
+ + checkFromBeforeClientResponse.isDone());
+ checkFromBeforeClientResponse = null;
+ }
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Test for various ways of using UI.access";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return Integer.valueOf(11897);
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.html b/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.html
index d734cab9ea..63e371e379 100644
--- a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.html
+++ b/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.html
@@ -64,6 +64,22 @@
<td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td>
<td>My tooltip</td>
</tr>
+<!-- Hide tooltip in Window -->
+<tr>
+ <td>showTooltip</td>
+ <td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]</td>
+ <td>0,0</td>
+</tr>
+<tr>
+ <td>pause</td>
+ <td>1000</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertElementNotPresent</td>
+ <td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td>
+ <td></td>
+</tr>
</tbody></table>
</body>
</html>
diff --git a/uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.html b/uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.html
index 945564f298..dcdfa05687 100644
--- a/uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.html
+++ b/uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.html
@@ -162,17 +162,6 @@
<td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/Slot[0]/VNativeButton[0]</td>
<td>43,12</td>
</tr>
-<!--Remove the following two commands once #11737 is fixed-->
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/Slot[0]/VNativeButton[0]</td>
- <td>43,12</td>
-</tr>
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/Slot[0]/VNativeButton[0]</td>
- <td>43,12</td>
-</tr>
<!--maximize window 2 content-->
<tr>
<td>mouseClick</td>
@@ -234,6 +223,37 @@
<td></td>
<td>window-1-maximized-with-doubleclick</td>
</tr>
+<!--Test that size and position is preserved when maximizing and restoring-->
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+ <td>8,4</td>
+</tr>
+<tr>
+ <td>dragAndDrop</td>
+ <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>-200,-200</td>
+</tr>
+<tr>
+ <td>dragAndDrop</td>
+ <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[4]/domChild[0]</td>
+ <td>+100,+100</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+ <td>6,5</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+ <td>5,8</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>window-1-moved-maximized-restored</td>
+</tr>
</tbody></table>
</body>
</html>
diff --git a/uitest/src/com/vaadin/tests/minitutorials/broadcastingmessages/Broadcaster.java b/uitest/src/com/vaadin/tests/minitutorials/broadcastingmessages/Broadcaster.java
index 57ad0d97ba..78d0af6283 100644
--- a/uitest/src/com/vaadin/tests/minitutorials/broadcastingmessages/Broadcaster.java
+++ b/uitest/src/com/vaadin/tests/minitutorials/broadcastingmessages/Broadcaster.java
@@ -16,44 +16,25 @@
package com.vaadin.tests.minitutorials.broadcastingmessages;
-import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
public class Broadcaster {
- private static List<BroadcastListener> listeners = new ArrayList<BroadcastListener>();
+ private static final List<BroadcastListener> listeners = new CopyOnWriteArrayList<BroadcastListener>();
- public synchronized static void register(BroadcastListener listener) {
+ public static void register(BroadcastListener listener) {
listeners.add(listener);
}
- public synchronized static void unregister(BroadcastListener listener) {
+ public static void unregister(BroadcastListener listener) {
listeners.remove(listener);
}
- private synchronized static List<BroadcastListener> getListeners() {
- List<BroadcastListener> listenerCopy = new ArrayList<BroadcastListener>();
- listenerCopy.addAll(listeners);
- return listenerCopy;
- }
-
public static void broadcast(final String message) {
- // Make a copy of the listener list while synchronized, can't be
- // synchronized while firing the event or we would have to fire each
- // event in a separate thread.
- final List<BroadcastListener> listenerCopy = getListeners();
-
- // We spawn another thread to avoid potential deadlocks with
- // multiple UIs locked simultaneously
- Thread eventThread = new Thread() {
- @Override
- public void run() {
- for (BroadcastListener listener : listenerCopy) {
- listener.receiveBroadcast(message);
- }
- }
- };
- eventThread.start();
+ for (BroadcastListener listener : listeners) {
+ listener.receiveBroadcast(message);
+ }
}
public interface BroadcastListener {
diff --git a/uitest/src/com/vaadin/tests/minitutorials/broadcastingmessages/BroadcasterUI.java b/uitest/src/com/vaadin/tests/minitutorials/broadcastingmessages/BroadcasterUI.java
index 06ead20db3..68b5925f48 100644
--- a/uitest/src/com/vaadin/tests/minitutorials/broadcastingmessages/BroadcasterUI.java
+++ b/uitest/src/com/vaadin/tests/minitutorials/broadcastingmessages/BroadcasterUI.java
@@ -1,5 +1,6 @@
package com.vaadin.tests.minitutorials.broadcastingmessages;
+import com.vaadin.annotations.Push;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.minitutorials.broadcastingmessages.Broadcaster.BroadcastListener;
import com.vaadin.ui.Button;
@@ -10,6 +11,7 @@ import com.vaadin.ui.TextArea;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
+@Push
public class BroadcasterUI extends UI implements BroadcastListener {
@Override
diff --git a/uitest/src/com/vaadin/tests/push/BasicPushStreaming.java b/uitest/src/com/vaadin/tests/push/BasicPushStreaming.java
new file mode 100644
index 0000000000..37a8afd819
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/BasicPushStreaming.java
@@ -0,0 +1,12 @@
+package com.vaadin.tests.push;
+
+import com.vaadin.annotations.Push;
+import com.vaadin.shared.ui.ui.Transport;
+
+@Push(transport = Transport.STREAMING)
+public class BasicPushStreaming extends BasicPush {
+ @Override
+ protected void setup(com.vaadin.server.VaadinRequest request) {
+ addComponent(new PushConfigurator(this));
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/push/BasicPushWebsocket.java b/uitest/src/com/vaadin/tests/push/BasicPushWebsocket.java
new file mode 100644
index 0000000000..6fc27e8974
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/BasicPushWebsocket.java
@@ -0,0 +1,8 @@
+package com.vaadin.tests.push;
+
+import com.vaadin.annotations.Push;
+import com.vaadin.shared.ui.ui.Transport;
+
+@Push(transport = Transport.WEBSOCKET)
+public class BasicPushWebsocket extends BasicPush {
+}
diff --git a/uitest/src/com/vaadin/tests/push/PushConfiguration.html b/uitest/src/com/vaadin/tests/push/PushConfiguration.html
new file mode 100644
index 0000000000..c3786b1cc1
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/PushConfiguration.html
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:8888/" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<!--Websocket-->
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.push.PushConfigurationTest?debug&amp;restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertNotText</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
+ <td>4</td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[1]/VNativeSelect[0]/domChild[0]</td>
+ <td>label=WEBSOCKET</td>
+</tr>
+<tr>
+ <td>assertNotText</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
+ <td>4</td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]</td>
+ <td>label=AUTOMATIC</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[5]/VLabel[0]/domChild[0]</td>
+ <td>*fallbackTransport: streaming*transport: websocket*</td>
+</tr>
+<tr>
+ <td>assertNotText</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
+ <td>4</td>
+</tr>
+<tr>
+ <td>waitForText</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
+ <td>4</td>
+</tr>
+<!--Use debug console to verify we used the correct transport type-->
+<tr>
+ <td>assertTextPresent</td>
+ <td>Push connection established using websocket</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertTextNotPresent</td>
+ <td>Push connection established using streaming</td>
+ <td>Push connection established using streaming</td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]</td>
+ <td>label=DISABLED</td>
+</tr>
+<!--Streaming-->
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.push.PushConfigurationTest?debug&amp;restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertNotText</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
+ <td>4</td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[1]/VNativeSelect[0]/domChild[0]</td>
+ <td>label=STREAMING</td>
+</tr>
+<tr>
+ <td>assertNotText</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
+ <td>4</td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]</td>
+ <td>label=AUTOMATIC</td>
+</tr>
+<tr>
+ <td>assertNotText</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
+ <td>4</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[5]/VLabel[0]/domChild[0]</td>
+ <td>*fallbackTransport: streaming*transport: streaming*</td>
+</tr>
+<tr>
+ <td>waitForText</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VLabel[0]</td>
+ <td>4</td>
+</tr>
+<!--Use debug console to verify we used the correct transport type-->
+<tr>
+ <td>assertTextNotPresent</td>
+ <td>Push connection established using websocket</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertTextPresent</td>
+ <td>Push connection established using streaming</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>vaadin=runcomvaadintestspushPushConfigurationTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]</td>
+ <td>label=DISABLED</td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java
new file mode 100644
index 0000000000..b57e9732cc
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java
@@ -0,0 +1,102 @@
+package com.vaadin.tests.push;
+
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Label;
+
+public class PushConfigurationTest extends AbstractTestUI {
+
+ private ObjectProperty<Integer> counter = new ObjectProperty<Integer>(0);
+
+ private ObjectProperty<Integer> counter2 = new ObjectProperty<Integer>(0);
+
+ private final Timer timer = new Timer(true);
+
+ private final TimerTask task = new TimerTask() {
+
+ @Override
+ public void run() {
+ access(new Runnable() {
+ @Override
+ public void run() {
+ counter2.setValue(counter2.getValue() + 1);
+ }
+ });
+ }
+ };
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ addComponent(new PushConfigurator(this));
+ spacer();
+
+ /*
+ * Client initiated push.
+ */
+ Label lbl = new Label(counter);
+ lbl.setCaption("Client counter (click 'increment' to update):");
+ addComponent(lbl);
+
+ addComponent(new Button("Increment", new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ counter.setValue(counter.getValue() + 1);
+ }
+ }));
+
+ spacer();
+
+ /*
+ * Server initiated push.
+ */
+ lbl = new Label(counter2);
+ lbl.setCaption("Server counter (updates each 1s by server thread) :");
+ addComponent(lbl);
+
+ addComponent(new Button("Reset", new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ counter2.setValue(0);
+ }
+ }));
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "This test tests the very basic operations of push. "
+ + "It tests that client initiated changes are "
+ + "recieved back to the client as well as server "
+ + "initiated changes are correctly updated to the client.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 11494;
+ }
+
+ private void spacer() {
+ addComponent(new Label("<hr/>", ContentMode.HTML));
+ }
+
+ @Override
+ public void attach() {
+ super.attach();
+ timer.scheduleAtFixedRate(task, new Date(), 1000);
+ }
+
+ @Override
+ public void detach() {
+ super.detach();
+ timer.cancel();
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurator.java b/uitest/src/com/vaadin/tests/push/PushConfigurator.java
new file mode 100644
index 0000000000..6528366b59
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/PushConfigurator.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ *
+ */
+package com.vaadin.tests.push;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.shared.communication.PushMode;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.shared.ui.ui.Transport;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.NativeSelect;
+import com.vaadin.ui.PushConfiguration;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public class PushConfigurator extends VerticalLayout {
+ private NativeSelect pushMode = new NativeSelect("Push mode");
+ private NativeSelect transport = new NativeSelect("Transport");
+ private NativeSelect fallbackTransport = new NativeSelect("Fallback");
+ private TextField parameter = new TextField("Parameter");
+ private TextField value = new TextField("Value");
+ private Button set = new Button("Set");
+ private HorizontalLayout paramValue = new HorizontalLayout();
+ private VerticalLayout vl = new VerticalLayout();
+ private UI ui;
+
+ private Label status = new Label("", ContentMode.PREFORMATTED);
+
+ public PushConfigurator(UI ui) {
+ this.ui = ui;
+ construct();
+ refreshStatus();
+ }
+
+ /**
+ * @since
+ */
+ private void refreshStatus() {
+ PushConfiguration pc = ui.getPushConfiguration();
+ String value = "";
+ ArrayList<String> names = new ArrayList<String>();
+ names.addAll(pc.getParameterNames());
+ Collections.sort(names);
+ for (String param : names) {
+ value += param + ": " + pc.getParameter(param) + "\n";
+ }
+ status.setValue(value);
+ }
+
+ /**
+ * @since
+ */
+ private void construct() {
+ pushMode.addItem(PushMode.DISABLED);
+ pushMode.addItem(PushMode.MANUAL);
+ pushMode.addItem(PushMode.AUTOMATIC);
+
+ for (Transport t : Transport.values()) {
+ transport.addItem(t.toString());
+ fallbackTransport.addItem(t.toString());
+ }
+ transport.addItem("");
+ fallbackTransport.addItem("");
+
+ pushMode.setImmediate(true);
+ transport.setImmediate(true);
+ fallbackTransport.setImmediate(true);
+
+ listeners();
+
+ paramValue.setDefaultComponentAlignment(Alignment.BOTTOM_RIGHT);
+ paramValue.addComponents(parameter, value, set);
+ vl.addComponents(pushMode, transport, fallbackTransport, paramValue,
+ new Label("<hr/>", ContentMode.HTML), status);
+ addComponent(vl);
+
+ }
+
+ /**
+ * @since
+ */
+ private void listeners() {
+ pushMode.addValueChangeListener(new ValueChangeListener() {
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ ui.getPushConfiguration().setPushMode(
+ (PushMode) pushMode.getValue());
+ refreshStatus();
+ }
+ });
+
+ transport.addValueChangeListener(new ValueChangeListener() {
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ Transport t = Transport.valueOf((String) transport.getValue());
+ ui.getPushConfiguration().setTransport(t);
+ refreshStatus();
+ }
+ });
+
+ fallbackTransport.addValueChangeListener(new ValueChangeListener() {
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ Transport t = Transport.valueOf((String) fallbackTransport
+ .getValue());
+ ui.getPushConfiguration().setFallbackTransport(t);
+ refreshStatus();
+ }
+ });
+
+ set.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ ui.getPushConfiguration().setParameter(parameter.getValue(),
+ value.getValue());
+ refreshStatus();
+ }
+ });
+
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/push/PushTransportAnnotation.html b/uitest/src/com/vaadin/tests/push/PushTransportAnnotation.html
new file mode 100644
index 0000000000..854dd458bb
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/PushTransportAnnotation.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:8888/" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.push.BasicPushStreaming?debug&amp;restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>waitForTextPresent</td>
+ <td>Push connection established using streaming</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertTextNotPresent</td>
+ <td>Push connection established using websocket</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.push.BasicPushWebsocket?debug&amp;restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertTextNotPresent</td>
+ <td>Push connection established using streaming</td>
+ <td></td>
+</tr>
+<tr>
+ <td>waitForTextPresent</td>
+ <td>Push connection established using websocket</td>
+ <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/push/TogglePush.java b/uitest/src/com/vaadin/tests/push/TogglePush.java
index 37687260dd..c0bdc54ee0 100644
--- a/uitest/src/com/vaadin/tests/push/TogglePush.java
+++ b/uitest/src/com/vaadin/tests/push/TogglePush.java
@@ -22,19 +22,22 @@ public class TogglePush extends AbstractTestUI {
updateCounter();
addComponent(counterLabel);
- setPushMode("disabled".equals(request.getParameter("push")) ? PushMode.DISABLED
- : PushMode.AUTOMATIC);
+ getPushConfiguration()
+ .setPushMode(
+ "disabled".equals(request.getParameter("push")) ? PushMode.DISABLED
+ : PushMode.AUTOMATIC);
CheckBox pushSetting = new CheckBox("Push enabled");
- pushSetting.setValue(Boolean.valueOf(getPushMode().isEnabled()));
+ pushSetting.setValue(Boolean.valueOf(getPushConfiguration()
+ .getPushMode().isEnabled()));
pushSetting.setImmediate(true);
pushSetting.addValueChangeListener(new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
if (event.getProperty().getValue() == Boolean.TRUE) {
- setPushMode(PushMode.AUTOMATIC);
+ getPushConfiguration().setPushMode(PushMode.AUTOMATIC);
} else {
- setPushMode(PushMode.DISABLED);
+ getPushConfiguration().setPushMode(PushMode.DISABLED);
}
}
});
diff --git a/uitest/src/com/vaadin/tests/themes/CSSInjectTest.html b/uitest/src/com/vaadin/tests/themes/CSSInjectTest.html
index 05a0f256c2..0c70d6f711 100644
--- a/uitest/src/com/vaadin/tests/themes/CSSInjectTest.html
+++ b/uitest/src/com/vaadin/tests/themes/CSSInjectTest.html
@@ -51,7 +51,16 @@
<td></td>
<td>world-red</td>
</tr>
-
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadinteststhemesCSSInjectTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>world-still-red</td>
+</tr>
</tbody></table>
</body>
</html>
diff --git a/uitest/src/com/vaadin/tests/themes/CSSInjectTest.java b/uitest/src/com/vaadin/tests/themes/CSSInjectTest.java
index f4448bf326..738d8fc681 100644
--- a/uitest/src/com/vaadin/tests/themes/CSSInjectTest.java
+++ b/uitest/src/com/vaadin/tests/themes/CSSInjectTest.java
@@ -22,14 +22,16 @@ public class CSSInjectTest extends TestBase {
final Styles stylesheet = Page.getCurrent().getStyles();
// Inject some resources initially
- stylesheet.add(new StreamResource(new StreamResource.StreamSource() {
+ final StreamResource initialResource = new StreamResource(
+ new StreamResource.StreamSource() {
- @Override
- public InputStream getStream() {
- return new ByteArrayInputStream(
- ".hello, .world { color:silver; }".getBytes());
- }
- }, "mystyles-" + System.currentTimeMillis() + ".css"));
+ @Override
+ public InputStream getStream() {
+ return new ByteArrayInputStream(
+ ".hello, .world { color:silver; }".getBytes());
+ }
+ }, "mystyles-" + System.currentTimeMillis() + ".css");
+ stylesheet.add(initialResource);
Label hello = new Label(
"<span class='hello'>Hello</span> <span class='world'>world</span>",
@@ -72,6 +74,14 @@ public class CSSInjectTest extends TestBase {
}
});
addComponent(injectRandom);
+
+ addComponent(new Button("Inject initial again!",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ stylesheet.add(initialResource);
+ }
+ }));
}
@Override
diff --git a/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml b/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml
index 1b47a86113..fd52e5cd0e 100644
--- a/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml
+++ b/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml
@@ -1,15 +1,16 @@
<module>
- <!-- WS Compiler: manually edited -->
+ <!-- WS Compiler: manually edited -->
+
+ <!-- Inherit the DefaultWidgetSet -->
+ <inherits name="com.vaadin.DefaultWidgetSet" />
- <!-- Inherit the DefaultWidgetSet -->
- <inherits name="com.vaadin.DefaultWidgetSet" />
-
<replace-with class="com.vaadin.tests.widgetset.client.CustomUIConnector">
<when-type-is class="com.vaadin.client.ui.ui.UIConnector" />
</replace-with>
-
- <replace-with class="com.vaadin.tests.widgetset.client.TestingPushConnection">
+
+ <replace-with
+ class="com.vaadin.tests.widgetset.client.TestingPushConnection">
<when-type-is class="com.vaadin.client.communication.PushConnection" />
</replace-with>
-
+
</module>
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/TestingPushConnection.java b/uitest/src/com/vaadin/tests/widgetset/client/TestingPushConnection.java
index 8d00598907..4dae8892e7 100644
--- a/uitest/src/com/vaadin/tests/widgetset/client/TestingPushConnection.java
+++ b/uitest/src/com/vaadin/tests/widgetset/client/TestingPushConnection.java
@@ -2,15 +2,19 @@ package com.vaadin.tests.widgetset.client;
import com.google.gwt.user.client.Window;
import com.vaadin.client.ApplicationConnection;
+import com.vaadin.client.ApplicationConnection.CommunicationErrorHandler;
import com.vaadin.client.communication.AtmospherePushConnection;
+import com.vaadin.shared.ui.ui.UIState.PushConfigurationState;
public class TestingPushConnection extends AtmospherePushConnection {
private String transport;
@Override
- public void init(ApplicationConnection connection) {
- super.init(connection);
+ public void init(ApplicationConnection connection,
+ PushConfigurationState pushConfiguration,
+ CommunicationErrorHandler errorHandler) {
+ super.init(connection, pushConfiguration, errorHandler);
transport = Window.Location.getParameter("transport");
}
diff --git a/uitest/test.xml b/uitest/test.xml
index 8228bd9d70..44dac13d90 100644
--- a/uitest/test.xml
+++ b/uitest/test.xml
@@ -1,189 +1,227 @@
<?xml version="1.0"?>
-<project xmlns:antcontrib="antlib:net.sf.antcontrib" xmlns:ivy="antlib:org.apache.ivy.ant" name="Run Vaadin Testbench Tests" basedir="." default="run-and-clean-up">
-
- <include file="../common.xml" />
- <dirname property="test.xml.dir" file="${ant.file.Run Vaadin Testbench Tests}" />
-
- <!-- ================================================================== -->
- <!-- Configuration -->
- <!-- ================================================================== -->
- <!-- Browsers to use for testing -->
- <property name="browsers-windows" value="winxp-ie8,win7-ie9,win7-ie10,winxp-firefox17-esr,winxp-safari5,winxp-googlechrome21,winxp-opera12" />
- <property name="browsers-linux" value="linux-firefox3,linux-opera10,linux-googlechrome8" />
- <property name="browsers-mac" value="osx-firefox3,osx-opera10,osx-googlechrome8,osx-safari4,osx-safari5" />
-
- <property name="browsers" value="${browsers-windows}" />
-
- <!-- Number of times to retry a test if it fails -->
- <property name="retries" value="2" />
-
- <!-- Screen shot base directory -->
- <fail unless="com.vaadin.testbench.screenshot.directory" message="The 'com.vaadin.testbench.screenshot.directory' property must be defined." />
-
- <!-- Screen shot resolution -->
- <property name="com.vaadin.testbench.screenshot.resolution" value="1500x850" />
-
- <!-- Host running Testbench Hub -->
- <property name="com.vaadin.testbench.tester.host" value="testbench-hub.intra.itmill.com" />
-
- <property name="com.vaadin.testbench.screenshot.block.error" value="0.025" />
- <property name="com.vaadin.testbench.debug" value="false" />
-
-
- <target name="initialize">
- <!-- classpath must include test bench jar and its dependencies -->
- <path id="classpath">
- <fileset dir="${com.vaadin.testbench.lib.dir}" includes="**/*.jar" />
- </path>
- </target>
-
- <!-- fileset containing all TestBench tests to run -->
- <fileset dir="${test.xml.dir}" id="html-test-files">
- <include name="src/**/*.html" />
- <exclude name="integration-testscripts/**/*.html" />
- </fileset>
-
- <!-- This target converts HTML tests files to java junit tests. One test file for each browser is created. -->
- <target name="create-tests" depends="initialize, remove-temp-testclasses">
- <!-- Temporary output directory, created and removed by this script -->
- <fail unless="test-output-dir" message="The 'test-output-dir' property must be defined." />
- <property name="class-dir" value="${test-output-dir}/classes" />
-
- <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
-
- <java classname="com.vaadin.testbench.util.TestConverter" classpathref="classpath" fork="true">
- <sysproperty key="com.vaadin.testbench.test.retries" value="${retries}" />
- <jvmarg value="-Duser.language=en" />
- <jvmarg value="-Duser.country=US" />
- <arg value="${test-output-dir}" />
- <arg value="${browsers}" />
- <arg line="${testfiles}" />
- </java>
- </target>
-
-
- <!-- This target complies the generated java junit tests. -->
- <target name="compile-tests" depends="create-tests">
- <mkdir dir="${class-dir}" />
- <javac includeantruntime="false" srcdir="${test-output-dir}" destdir="${class-dir}" debug="on" fork="yes" failonerror="false" encoding="UTF8">
- <classpath>
- <path refid="classpath" />
- </classpath>
- </javac>
- </target>
-
- <!-- ================================================================== -->
- <!-- Running Tests -->
- <!-- ================================================================== -->
-
- <target name="check-parameters">
- <fail unless="com.vaadin.testbench.lib.dir" message="The 'com.vaadin.testbench.lib.dir' property must be defined." />
- <fail unless="com.vaadin.testbench.tester.host" message="The 'com.vaadin.testbench.tester.host' property must be defined." />
- <fail unless="com.vaadin.testbench.deployment.url" message="The 'com.vaadin.testbench.deployment.url' property must be defined." />
- </target>
-
- <target name="run-tests" depends="compile-tests">
- <fileset dir="${test-output-dir}" id="tests-fileset">
- <include name="**/**.java" />
- </fileset>
-
- <antcontrib:for threadCount="30" parallel="true" keepgoing="true" param="target">
- <path>
- <fileset refid="tests-fileset" />
- </path>
- <sequential>
- <antcall target="execute-tests">
- <param name="target" value="@{target}" />
- <reference refid="classpath" />
- </antcall>
- </sequential>
- </antcontrib:for>
- </target>
-
- <!-- This target runs the generated and compiled junit tests -->
- <target name="execute-tests">
- <junit fork="yes" printsummary="withOutAndErr" maxmemory="96m">
- <classpath>
- <path refid="classpath" />
- <pathelement path="${class-dir}" />
- </classpath>
-
- <formatter usefile="false" type="plain" />
-
- <jvmarg value="-Dcom.vaadin.testbench.tester.host=${com.vaadin.testbench.tester.host}" />
- <jvmarg value="-Dcom.vaadin.testbench.deployment.url=${com.vaadin.testbench.deployment.url}" />
- <!-- Define where the reference screenshots and diff files are saved -->
- <jvmarg value="-Dcom.vaadin.testbench.screenshot.directory=${com.vaadin.testbench.screenshot.directory}" />
- <!-- Resolution for screenshots -->
- <jvmarg value="-Dcom.vaadin.testbench.screenshot.resolution=${com.vaadin.testbench.screenshot.resolution}" />
- <jvmarg value="-Dcom.vaadin.testbench.debug=${com.vaadin.testbench.debug}" />
- <jvmarg value="-Dcom.vaadin.testbench.screenshot.block.error=${com.vaadin.testbench.screenshot.block.error}" />
-
-
- <jvmarg value="-Djava.awt.headless=true" />
-
- <!-- true/false system arguments -->
- <jvmarg value="-Dcom.vaadin.testbench.screenshot.softfail=${com.vaadin.testbench.screenshot.softfail}" />
- <jvmarg value="-Dcom.vaadin.testbench.screenshot.reference.debug=${com.vaadin.testbench.screenshot.reference.debug}" />
- <jvmarg value="-Dcom.vaadin.testbench.screenshot.cursor=${com.vaadin.testbench.screenshot.cursor}" />
-
- <batchtest>
- <filelist dir="${test-output-dir}" files="${target}" />
- </batchtest>
- </junit>
-
- </target>
-
- <!-- Remove temporary source and compiled java files -->
- <target name="remove-temp-testclasses">
- <delete failonerror="false">
- <fileset dir="${test-output-dir}">
- <include name="**/**.java" />
- <include name="**/**.class" />
- </fileset>
- </delete>
- </target>
-
- <!-- Remove old error screenshots -->
- <target name="remove-error-screens">
- <mkdir dir="${com.vaadin.testbench.screenshot.directory}/errors" />
- <delete>
- <fileset dir="${com.vaadin.testbench.screenshot.directory}/errors">
- <include name="**/**.*" />
- </fileset>
- </delete>
- </target>
-
- <!-- ================================================================== -->
- <!-- Main Targets -->
- <!-- ================================================================== -->
-
- <!-- The default target. -->
- <target name="run-and-clean-up" depends="check-parameters,remove-error-screens,run-tests" />
-
-
- <!-- Starts the server and runs all TestBench tests -->
- <target name="test-package">
- <fail unless="war.file" message="No 'war.file' parameter given." />
- <property name="test-output-dir" location="${test.xml.dir}/result/testbench-junit-classes" />
- <property name="retries" value="2" />
-
- <!-- Parameters for the test.xml script. -->
- <fail unless="com.vaadin.testbench.tester.host" message="The 'com.vaadin.testbench.tester.host' property must be defined." />
- <fail unless="com.vaadin.testbench.deployment.url" message="The 'com.vaadin.testbench.deployment.url' property must be defined." />
- <fail unless="com.vaadin.testbench.lib.dir" message="The 'com.vaadin.testbench.lib.dir' property must be defined." />
- <property name="com.vaadin.testbench.screenshot.block.error" value="0.025" />
- <property name="com.vaadin.testbench.debug" value="false" />
-
- <parallel>
- <daemons>
- <ant antfile="${test.xml.dir}/vaadin-server.xml" inheritall="true" inheritrefs="true" target="deploy-and-start" />
- </daemons>
- <sequential>
- <ant antfile="${test.xml.dir}/vaadin-server.xml" target="wait-for-startup" />
- <antcall inheritall="true" inheritrefs="true" target="run-and-clean-up" />
- <echo message="All TestBench tests have been run" />
- </sequential>
- </parallel>
- </target>
+<project xmlns:antcontrib="antlib:net.sf.antcontrib" xmlns:ivy="antlib:org.apache.ivy.ant"
+ name="Run Vaadin Testbench Tests" basedir="." default="run-and-clean-up">
+
+ <include file="../common.xml" />
+ <dirname property="test.xml.dir" file="${ant.file.Run Vaadin Testbench Tests}" />
+
+ <!-- ================================================================== -->
+ <!-- Configuration -->
+ <!-- ================================================================== -->
+ <!-- Browsers to use for testing -->
+ <property name="browsers-windows"
+ value="winxp-ie8,win7-ie9,win7-ie10,winxp-firefox17-esr,winxp-safari5,winxp-googlechrome21,winxp-opera12" />
+ <property name="browsers-linux"
+ value="linux-firefox3,linux-opera10,linux-googlechrome8" />
+ <property name="browsers-mac"
+ value="osx-firefox3,osx-opera10,osx-googlechrome8,osx-safari4,osx-safari5" />
+
+ <property name="browsers" value="${browsers-windows}" />
+
+ <!-- Number of times to retry a test if it fails -->
+ <property name="retries" value="2" />
+
+ <!-- Screen shot base directory -->
+ <fail unless="com.vaadin.testbench.screenshot.directory"
+ message="The 'com.vaadin.testbench.screenshot.directory' property must be defined." />
+
+ <!-- Screen shot resolution -->
+ <property name="com.vaadin.testbench.screenshot.resolution"
+ value="1500x850" />
+
+ <!-- Host running Testbench Hub -->
+ <property name="com.vaadin.testbench.tester.host" value="testbench-hub.intra.itmill.com" />
+
+ <property name="com.vaadin.testbench.screenshot.block.error"
+ value="0.025" />
+ <property name="com.vaadin.testbench.debug" value="false" />
+
+
+ <target name="initialize">
+ <!-- classpath must include test bench jar and its dependencies -->
+ <path id="classpath">
+ <fileset dir="${com.vaadin.testbench.lib.dir}"
+ includes="**/*.jar" />
+ </path>
+ </target>
+
+ <!-- fileset containing all TestBench tests to run -->
+ <fileset dir="${test.xml.dir}" id="html-test-files">
+ <include name="src/**/*.html" />
+ <exclude name="integration-testscripts/**/*.html" />
+ </fileset>
+
+ <!-- This target converts HTML tests files to java junit tests. One test
+ file for each browser is created. -->
+ <target name="create-tests" depends="initialize, remove-temp-testclasses">
+ <!-- Temporary output directory, created and removed by this script -->
+ <fail unless="test-output-dir"
+ message="The 'test-output-dir' property must be defined." />
+ <property name="class-dir" value="${test-output-dir}/classes" />
+
+ <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />
+
+ <java classname="com.vaadin.testbench.util.TestConverter"
+ classpathref="classpath" fork="true">
+ <sysproperty key="com.vaadin.testbench.test.retries"
+ value="${retries}" />
+ <jvmarg value="-Duser.language=en" />
+ <jvmarg value="-Duser.country=US" />
+ <arg value="${test-output-dir}" />
+ <arg value="${browsers}" />
+ <arg line="${testfiles}" />
+ </java>
+ </target>
+
+
+ <!-- This target complies the generated java junit tests. -->
+ <target name="compile-tests" depends="create-tests">
+ <mkdir dir="${class-dir}" />
+ <javac includeantruntime="false" srcdir="${test-output-dir}"
+ destdir="${class-dir}" debug="on" fork="yes" failonerror="false"
+ encoding="UTF8">
+ <classpath>
+ <path refid="classpath" />
+ </classpath>
+ </javac>
+ </target>
+
+ <!-- ================================================================== -->
+ <!-- Running Tests -->
+ <!-- ================================================================== -->
+
+ <target name="check-parameters">
+ <fail unless="com.vaadin.testbench.lib.dir"
+ message="The 'com.vaadin.testbench.lib.dir' property must be defined." />
+ <fail unless="com.vaadin.testbench.tester.host"
+ message="The 'com.vaadin.testbench.tester.host' property must be defined." />
+ <fail unless="com.vaadin.testbench.deployment.url"
+ message="The 'com.vaadin.testbench.deployment.url' property must be defined." />
+ </target>
+
+ <target name="run-tests" depends="compile-tests">
+ <fileset dir="${test-output-dir}" id="tests-fileset">
+ <include name="**/**.java" />
+ </fileset>
+
+ <antcontrib:for threadCount="30" parallel="true"
+ keepgoing="true" param="target">
+ <path>
+ <fileset refid="tests-fileset" />
+ </path>
+ <sequential>
+ <antcall target="execute-tests">
+ <param name="target" value="@{target}" />
+ <reference refid="classpath" />
+ </antcall>
+ </sequential>
+ </antcontrib:for>
+ </target>
+
+ <!-- This target runs the generated and compiled junit tests -->
+ <target name="execute-tests">
+ <junit fork="yes" printsummary="withOutAndErr" maxmemory="96m">
+ <classpath>
+ <path refid="classpath" />
+ <pathelement path="${class-dir}" />
+ </classpath>
+
+ <formatter usefile="false" type="plain" />
+
+ <jvmarg
+ value="-Dcom.vaadin.testbench.tester.host=${com.vaadin.testbench.tester.host}" />
+ <jvmarg
+ value="-Dcom.vaadin.testbench.deployment.url=${com.vaadin.testbench.deployment.url}" />
+ <!-- Define where the reference screenshots and diff files are
+ saved -->
+ <jvmarg
+ value="-Dcom.vaadin.testbench.screenshot.directory=${com.vaadin.testbench.screenshot.directory}" />
+ <!-- Resolution for screenshots -->
+ <jvmarg
+ value="-Dcom.vaadin.testbench.screenshot.resolution=${com.vaadin.testbench.screenshot.resolution}" />
+ <jvmarg
+ value="-Dcom.vaadin.testbench.debug=${com.vaadin.testbench.debug}" />
+ <jvmarg
+ value="-Dcom.vaadin.testbench.screenshot.block.error=${com.vaadin.testbench.screenshot.block.error}" />
+
+
+ <jvmarg value="-Djava.awt.headless=true" />
+
+ <!-- true/false system arguments -->
+ <jvmarg
+ value="-Dcom.vaadin.testbench.screenshot.softfail=${com.vaadin.testbench.screenshot.softfail}" />
+ <jvmarg
+ value="-Dcom.vaadin.testbench.screenshot.reference.debug=${com.vaadin.testbench.screenshot.reference.debug}" />
+ <jvmarg
+ value="-Dcom.vaadin.testbench.screenshot.cursor=${com.vaadin.testbench.screenshot.cursor}" />
+
+ <batchtest>
+ <filelist dir="${test-output-dir}" files="${target}" />
+ </batchtest>
+ </junit>
+
+ </target>
+
+ <!-- Remove temporary source and compiled java files -->
+ <target name="remove-temp-testclasses">
+ <delete failonerror="false">
+ <fileset dir="${test-output-dir}">
+ <include name="**/**.java" />
+ <include name="**/**.class" />
+ </fileset>
+ </delete>
+ </target>
+
+ <!-- Remove old error screenshots -->
+ <target name="remove-error-screens">
+ <mkdir dir="${com.vaadin.testbench.screenshot.directory}/errors" />
+ <delete>
+ <fileset
+ dir="${com.vaadin.testbench.screenshot.directory}/errors">
+ <include name="**/**.*" />
+ </fileset>
+ </delete>
+ </target>
+
+ <!-- ================================================================== -->
+ <!-- Main Targets -->
+ <!-- ================================================================== -->
+
+ <!-- The default target. -->
+ <target name="run-and-clean-up"
+ depends="check-parameters,remove-error-screens,run-tests" />
+
+
+ <!-- Starts the server and runs all TestBench tests -->
+ <target name="test-package">
+ <fail unless="war.file" message="No 'war.file' parameter given." />
+ <property name="test-output-dir"
+ location="${test.xml.dir}/result/testbench-junit-classes" />
+ <property name="retries" value="2" />
+
+ <!-- Parameters for the test.xml script. -->
+ <fail unless="com.vaadin.testbench.tester.host"
+ message="The 'com.vaadin.testbench.tester.host' property must be defined." />
+ <fail unless="com.vaadin.testbench.deployment.url"
+ message="The 'com.vaadin.testbench.deployment.url' property must be defined." />
+ <fail unless="com.vaadin.testbench.lib.dir"
+ message="The 'com.vaadin.testbench.lib.dir' property must be defined." />
+ <property name="com.vaadin.testbench.screenshot.block.error"
+ value="0.025" />
+ <property name="com.vaadin.testbench.debug" value="false" />
+
+ <parallel>
+ <daemons>
+ <ant antfile="${test.xml.dir}/vaadin-server.xml"
+ inheritall="true" inheritrefs="true" target="deploy-and-start" />
+ </daemons>
+ <sequential>
+ <ant antfile="${test.xml.dir}/vaadin-server.xml"
+ target="wait-for-startup" />
+ <antcall inheritall="true" inheritrefs="true"
+ target="run-and-clean-up" />
+ <echo message="All TestBench tests have been run" />
+ </sequential>
+ </parallel>
+ </target>
</project>
diff --git a/uitest/vaadin-server.xml b/uitest/vaadin-server.xml
index 5741d78525..4b32cebe26 100644
--- a/uitest/vaadin-server.xml
+++ b/uitest/vaadin-server.xml
@@ -1,34 +1,38 @@
<?xml version="1.0"?>
-<project xmlns:antcontrib="antlib:net.sf.antcontrib" xmlns:ivy="antlib:org.apache.ivy.ant" name="vaadin-server" default="deploy-and-start" basedir=".">
- <include file="../common.xml" />
- <dirname property="dir" file="${ant.file.vaadin-server}" />
+<project xmlns:antcontrib="antlib:net.sf.antcontrib" xmlns:ivy="antlib:org.apache.ivy.ant"
+ name="vaadin-server" default="deploy-and-start" basedir=".">
+ <include file="../common.xml" />
+ <dirname property="dir" file="${ant.file.vaadin-server}" />
- <target name="deploy-and-start">
- <fail unless="war.file" message="No war file given in 'war.file'" />
+ <target name="deploy-and-start">
+ <fail unless="war.file" message="No war file given in 'war.file'" />
- <ivy:resolve file="${dir}/ivy.xml" />
- <ivy:cachepath pathid="classpath.jetty" conf="jetty-run" />
- <java classname="org.mortbay.jetty.runner.Runner" fork="yes" output="${vaadin.basedir}/result/jetty.java.out" resultproperty="resultCode">
- <arg value="--port" />
- <arg value="8888" />
- <arg value="--out" />
- <arg value="${vaadin.basedir}/result/jetty.out" />
- <arg value="--log" />
- <arg value="${vaadin.basedir}/result/jetty.log" />
- <arg value="${war.file}" />
- <classpath refid="classpath.jetty" />
- <jvmarg value="-ea" />
- </java>
- <echo message="Jetty process ended with result code ${resultCode}" />
+ <ivy:resolve file="${dir}/ivy.xml" />
+ <ivy:cachepath pathid="classpath.jetty" conf="jetty-run" />
+ <java classname="org.mortbay.jetty.runner.Runner" fork="yes"
+ output="${vaadin.basedir}/result/jetty.java.out"
+ resultproperty="resultCode">
+ <arg value="--port" />
+ <arg value="8888" />
+ <arg value="--out" />
+ <arg value="${vaadin.basedir}/result/jetty.out" />
+ <arg value="--log" />
+ <arg value="${vaadin.basedir}/result/jetty.log" />
+ <arg value="${war.file}" />
+ <classpath refid="classpath.jetty" />
+ <jvmarg value="-ea" />
+ </java>
+ <echo message="Jetty process ended with result code ${resultCode}" />
- </target>
+ </target>
- <target name="wait-for-startup">
- <echo>Waiting for Servlet Container to start up.</echo>
- <waitfor maxwait="60" maxwaitunit="second" checkevery="5" checkeveryunit="second" timeoutproperty="server.start.failed">
- <http url="http://localhost:8888" />
- </waitfor>
- <fail if="server.start.failed" message="Server startup failed" />
- </target>
+ <target name="wait-for-startup">
+ <echo>Waiting for Servlet Container to start up.</echo>
+ <waitfor maxwait="60" maxwaitunit="second" checkevery="5"
+ checkeveryunit="second" timeoutproperty="server.start.failed">
+ <http url="http://localhost:8888" />
+ </waitfor>
+ <fail if="server.start.failed" message="Server startup failed" />
+ </target>
</project>