package com.vaadin.tests.components;
import java.io.File;
import com.vaadin.annotations.Widgetset;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.server.WebBrowser;
import com.vaadin.shared.communication.PushMode;
import com.vaadin.shared.ui.ContentMode;
import com.vaadin.shared.ui.ui.Transport;
import com.vaadin.shared.ui.ui.UIState.PushConfigurationState;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.Label;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.ui.PushConfiguration;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
public abstract class AbstractTestUI extends UI {
@Override
public void init(VaadinRequest request) {
getPage().setTitle(getClass().getName());
Label label = new Label(getTestDescription(), ContentMode.HTML);
label.setWidth("100%");
VerticalLayout rootLayout = new VerticalLayout();
rootLayout.setSpacing(false);
setContent(rootLayout);
layout = new VerticalLayout();
layout.setSpacing(false);
layout.setMargin(false);
rootLayout.addComponent(label);
rootLayout.addComponent(layout);
((VerticalLayout) getContent()).setExpandRatio(layout, 1);
warnIfWidgetsetMaybeNotCompiled();
setTransport(request);
setup(request);
}
protected void warnIfWidgetsetMaybeNotCompiled() {
// Can't check location if sendUrlAsParameters is disabled
if (!getSession().getConfiguration().isSendUrlsAsParameters()) {
return;
}
// Ignore if using debug mode
String query = getPage().getLocation().getQuery();
if (query != null && query.matches(".*[&?]gwt\\.codesvr.*")) {
return;
}
// Find out the widgetset of this UI based on @Widgetset annotation
Class<?> currentType = getClass();
String usedWidgetset = VaadinServlet.DEFAULT_WIDGETSET;
while (currentType != Object.class) {
Widgetset annotation = currentType.getAnnotation(Widgetset.class);
if (annotation != null) {
usedWidgetset = annotation.value();
break;
} else {
currentType = currentType.getSuperclass();
}
}
// Assuming the same folder structure as in git repo
// Assuming project root is the working dir of this process
File widgetsetsFolder = new File("WebContent/VAADIN/widgetsets");
if (!widgetsetsFolder.isDirectory()) {
return;
}
// Find the most newly compiled widgetset
long newestWidgetsetTimestamp = -1;
String newestWidgetsetName = null;
File[] children = widgetsetsFolder.listFiles();
for (File child : children) {
if (!child.isDirectory() || child.getName().equals("WEB-INF")) {
continue;
}
long lastModified = child.lastModified();
if (lastModified > newestWidgetsetTimestamp) {
newestWidgetsetTimestamp = lastModified;
newestWidgetsetName = child.getName();
}
}
// Compare to currently used widgetset, with a 30 minute grace period
File currentWidgetsetFolder = new File(widgetsetsFolder, usedWidgetset);
long currentWidgetsetTimestamp = currentWidgetsetFolder.lastModified();
int halfHour = 30 * 60 * 1000;
if (currentWidgetsetTimestamp + halfHour < newestWidgetsetTimestamp) {
Notification.show(
"The currently used widgetset (" + usedWidgetset
+ ") was compiled long before the most recently compiled one ("
+ newestWidgetsetName
+ "). Are you sure you have compiled the right widgetset?",
Type.WARNING_MESSAGE);
}
}
/**
* Sets the push transport according to the transport= URL parameter if such
* is given. Supports transport=xhr (disables push), transport=websocket
* (forces websocket into use), transport=streaming (forces streaming into
* use). Using ?transport=xyz disables the fallback transport.
*
* @param request
* The UI init request
*/
protected void setTransport(VaadinRequest request) {
String transport = request.getParameter("transport");
PushConfiguration config = getPushConfiguration();
if ("xhr".equals(transport)) {
config.setPushMode(PushMode.DISABLED);
} else if ("websocket".equals(transport)) {
enablePush(Transport.WEBSOCKET);
} else if ("websocket-xhr".equals(transport)) {
enablePush(Transport.WEBSOCKET_XHR);
} else if ("streaming".equals(transport)) {
enablePush(Transport.STREAMING);
} else if ("long-polling".equals(transport)) {
enablePush(Transport.LONG_POLLING);
} else if (transport != null) {
throw new IllegalArgumentException("Unknown transport value '"
+ transport
+ "'. Supported are xhr,websocket,streaming,long-polling");
}
}
protected void enablePush(Transport transport) {
PushConfiguration config = getPushConfiguration();
if (!config.getPushMode().isEnabled()) {
config.setPushMode(PushMode.AUTOMATIC);
}
config.setTransport(transport);
// Ensure no fallback is used
getPushConfiguration().setParameter(
PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none");
}
/**
* This method is inherited from the super class, but it should generally
* not be used. If you want to just add components to your test, use e.g.
* {@link #addComponent(Component)} instead to add the component to the
* layout used by this UI. If you don't want to use the top-level layout
* used by this class, you instead inherit directly from UI.
*
* @deprecated Use {@link #addComponent(Component)} or inherit from UI
* instead.
*/
@Override
@Deprecated
public void setContent(Component content) {
// Overridden just to deprecate
super.setContent(content);
}
private VerticalLayout layout;
protected VerticalLayout getLayout() {
return layout;
}
protected abstract void setup(VaadinRequest request);
public void addComponent(Component c) {
getLayout().addComponent(c);
}
public void addComponents(Component... c) {
getLayout().addComponents(c);
}
public void removeComponent(Component c) {
getLayout().removeComponent(c);
}
public void replaceComponent(Component oldComponent,
Component newComponent) {
getLayout().replaceComponent(oldComponent, newComponent);
}
protected void addButton(String caption, Button.ClickListener listener) {
Button button = new Button(caption);
button.addClickListener(listener);
addComponent(button);
}
protected String getTestDescription() {
return null;
};
protected Integer getTicketNumber() {
return null;
};
protected WebBrowser getBrowser() {
return getSession().getBrowser();
}
/**
* Execute the provided runnable on the UI thread as soon as the current
* request has been sent.
*/
protected void runAfterResponse(final Runnable runnable) {
// Immediately start a thread that will start waiting for the session to
// get unlocked.
new Thread() {
@Override
public void run() {
accessSynchronously(runnable);
}
}.start();
}
}