Change-Id: I80b73b653e97904605dc62484a7448f3bfbf722dtags/8.0.0.alpha7
final Iterator<Component> componentsIterator = ((HasComponents) connector) | final Iterator<Component> componentsIterator = ((HasComponents) connector) | ||||
.iterator(); | .iterator(); | ||||
final Iterator<Extension> extensionsIterator = extensions.iterator(); | final Iterator<Extension> extensionsIterator = extensions.iterator(); | ||||
Iterable<? extends ClientConnector> combinedIterable = new Iterable<ClientConnector>() { | |||||
Iterable<? extends ClientConnector> combinedIterable = () -> new Iterator<ClientConnector>() { | |||||
@Override | @Override | ||||
public Iterator<ClientConnector> iterator() { | |||||
return new Iterator<ClientConnector>() { | |||||
@Override | |||||
public boolean hasNext() { | |||||
return componentsIterator.hasNext() | |||||
|| extensionsIterator.hasNext(); | |||||
} | |||||
@Override | |||||
public ClientConnector next() { | |||||
if (componentsIterator.hasNext()) { | |||||
return componentsIterator.next(); | |||||
} | |||||
if (extensionsIterator.hasNext()) { | |||||
return extensionsIterator.next(); | |||||
} | |||||
throw new NoSuchElementException(); | |||||
} | |||||
@Override | |||||
public void remove() { | |||||
throw new UnsupportedOperationException(); | |||||
} | |||||
}; | |||||
public boolean hasNext() { | |||||
return componentsIterator.hasNext() | |||||
|| extensionsIterator.hasNext(); | |||||
} | |||||
@Override | |||||
public ClientConnector next() { | |||||
if (componentsIterator.hasNext()) { | |||||
return componentsIterator.next(); | |||||
} | |||||
if (extensionsIterator.hasNext()) { | |||||
return extensionsIterator.next(); | |||||
} | |||||
throw new NoSuchElementException(); | |||||
} | |||||
@Override | |||||
public void remove() { | |||||
throw new UnsupportedOperationException(); | |||||
} | } | ||||
}; | }; | ||||
return combinedIterable; | return combinedIterable; | ||||
} | } |
private void ensureRpc() { | private void ensureRpc() { | ||||
if (javascriptCallbackRpc == null) { | if (javascriptCallbackRpc == null) { | ||||
javascriptCallbackRpc = new JavaScriptCallbackRpc() { | |||||
@Override | |||||
public void call(String name, JsonArray arguments) { | |||||
JavaScriptFunction callback = callbacks.get(name); | |||||
try { | |||||
callback.call(arguments); | |||||
} catch (JsonException e) { | |||||
throw new IllegalArgumentException(e); | |||||
} | |||||
javascriptCallbackRpc = (String name, JsonArray arguments) -> { | |||||
JavaScriptFunction callback = callbacks.get(name); | |||||
try { | |||||
callback.call(arguments); | |||||
} catch (JsonException e) { | |||||
throw new IllegalArgumentException(e); | |||||
} | } | ||||
}; | }; | ||||
connector.registerRpc(javascriptCallbackRpc); | connector.registerRpc(javascriptCallbackRpc); |
public void init(PortletConfig portletConfig) throws PortletException { | public void init(PortletConfig portletConfig) throws PortletException { | ||||
super.init(portletConfig); | super.init(portletConfig); | ||||
getService().addSessionInitListener(new SessionInitListener() { | |||||
@Override | |||||
public void sessionInit(SessionInitEvent event) | |||||
throws ServiceException { | |||||
try { | |||||
onVaadinSessionStarted( | |||||
(VaadinPortletRequest) event.getRequest(), | |||||
(VaadinPortletSession) event.getSession()); | |||||
} catch (PortletException e) { | |||||
throw new ServiceException(e); | |||||
} | |||||
getService().addSessionInitListener((SessionInitEvent event) -> { | |||||
try { | |||||
onVaadinSessionStarted( | |||||
(VaadinPortletRequest) event.getRequest(), | |||||
(VaadinPortletSession) event.getSession()); | |||||
} catch (PortletException e) { | |||||
throw new ServiceException(e); | |||||
} | } | ||||
}); | }); | ||||
} | } |
public void init(ServletConfig servletConfig) throws ServletException { | public void init(ServletConfig servletConfig) throws ServletException { | ||||
super.init(servletConfig); | super.init(servletConfig); | ||||
getService().addSessionInitListener(new SessionInitListener() { | |||||
@Override | |||||
public void sessionInit(SessionInitEvent event) | |||||
throws ServiceException { | |||||
try { | |||||
onVaadinSessionStarted(event.getRequest(), | |||||
event.getSession()); | |||||
} catch (ServletException e) { | |||||
throw new ServiceException(e); | |||||
} | |||||
getService().addSessionInitListener((SessionInitEvent event) -> { | |||||
try { | |||||
onVaadinSessionStarted(event.getRequest(), | |||||
event.getSession()); | |||||
} catch (ServletException e) { | |||||
throw new ServiceException(e); | |||||
} | } | ||||
}); | }); | ||||
} | } |
*/ | */ | ||||
public void fireSessionDestroy(VaadinSession vaadinSession) { | public void fireSessionDestroy(VaadinSession vaadinSession) { | ||||
final VaadinSession session = vaadinSession; | final VaadinSession session = vaadinSession; | ||||
session.access(new Runnable() { | |||||
@Override | |||||
public void run() { | |||||
if (session.getState() == State.CLOSED) { | |||||
return; | |||||
} | |||||
if (session.getState() == State.OPEN) { | |||||
closeSession(session); | |||||
} | |||||
ArrayList<UI> uis = new ArrayList<>(session.getUIs()); | |||||
for (final UI ui : uis) { | |||||
ui.accessSynchronously(new Runnable() { | |||||
@Override | |||||
public void run() { | |||||
/* | |||||
* close() called here for consistency so that it is | |||||
* always called before a UI is removed. | |||||
* UI.isClosing() is thus always true in UI.detach() | |||||
* and associated detach listeners. | |||||
*/ | |||||
if (!ui.isClosing()) { | |||||
ui.close(); | |||||
} | |||||
session.removeUI(ui); | |||||
} | |||||
}); | |||||
} | |||||
// for now, use the session error handler; in the future, could | |||||
// have an API for using some other handler for session init and | |||||
// destroy listeners | |||||
eventRouter.fireEvent( | |||||
new SessionDestroyEvent(VaadinService.this, session), | |||||
session.getErrorHandler()); | |||||
session.setState(State.CLOSED); | |||||
session.access(() -> { | |||||
if (session.getState() == State.CLOSED) { | |||||
return; | |||||
} | |||||
if (session.getState() == State.OPEN) { | |||||
closeSession(session); | |||||
} | } | ||||
ArrayList<UI> uis = new ArrayList<>(session.getUIs()); | |||||
for (final UI ui : uis) { | |||||
ui.accessSynchronously(() -> { | |||||
/* | |||||
* close() called here for consistency so that it is | |||||
* always called before a UI is removed. | |||||
* UI.isClosing() is thus always true in UI.detach() | |||||
* and associated detach listeners. | |||||
*/ | |||||
if (!ui.isClosing()) { | |||||
ui.close(); | |||||
} | |||||
session.removeUI(ui); | |||||
}); | |||||
} | |||||
// for now, use the session error handler; in the future, could | |||||
// have an API for using some other handler for session init and | |||||
// destroy listeners | |||||
eventRouter.fireEvent( | |||||
new SessionDestroyEvent(VaadinService.this, session), | |||||
session.getErrorHandler()); | |||||
session.setState(State.CLOSED); | |||||
}); | }); | ||||
} | } | ||||
ArrayList<UI> uis = new ArrayList<>(session.getUIs()); | ArrayList<UI> uis = new ArrayList<>(session.getUIs()); | ||||
for (final UI ui : uis) { | for (final UI ui : uis) { | ||||
if (ui.isClosing()) { | if (ui.isClosing()) { | ||||
ui.accessSynchronously(new Runnable() { | |||||
@Override | |||||
public void run() { | |||||
getLogger().log(Level.FINER, "Removing closed UI {0}", | |||||
ui.getUIId()); | |||||
session.removeUI(ui); | |||||
} | |||||
ui.accessSynchronously(() -> { | |||||
getLogger().log(Level.FINER, "Removing closed UI {0}", | |||||
ui.getUIId()); | |||||
session.removeUI(ui); | |||||
}); | }); | ||||
} | } | ||||
} | } | ||||
final String sessionId = session.getSession().getId(); | final String sessionId = session.getSession().getId(); | ||||
for (final UI ui : session.getUIs()) { | for (final UI ui : session.getUIs()) { | ||||
if (!isUIActive(ui) && !ui.isClosing()) { | if (!isUIActive(ui) && !ui.isClosing()) { | ||||
ui.accessSynchronously(new Runnable() { | |||||
@Override | |||||
public void run() { | |||||
getLogger().log(Level.FINE, | |||||
"Closing inactive UI #{0} in session {1}", | |||||
new Object[] { ui.getUIId(), sessionId }); | |||||
ui.close(); | |||||
} | |||||
ui.accessSynchronously(() -> { | |||||
getLogger().log(Level.FINE, | |||||
"Closing inactive UI #{0} in session {1}", | |||||
new Object[] { ui.getUIId(), sessionId }); | |||||
ui.close(); | |||||
}); | }); | ||||
} | } | ||||
} | } |
private void cleanStreamVariable(VaadinSession session, final UI ui, | private void cleanStreamVariable(VaadinSession session, final UI ui, | ||||
final ClientConnector owner, final String variableName) { | final ClientConnector owner, final String variableName) { | ||||
session.accessSynchronously(new Runnable() { | |||||
@Override | |||||
public void run() { | |||||
ui.getConnectorTracker().cleanStreamVariable( | |||||
owner.getConnectorId(), variableName); | |||||
} | |||||
session.accessSynchronously(() -> { | |||||
ui.getConnectorTracker().cleanStreamVariable( | |||||
owner.getConnectorId(), variableName); | |||||
}); | }); | ||||
} | } | ||||
} | } |
// Vaadin 6 requires parents to be painted before children as component | // Vaadin 6 requires parents to be painted before children as component | ||||
// containers rely on that their updateFromUIDL method has been called | // containers rely on that their updateFromUIDL method has been called | ||||
// before children start calling e.g. updateCaption | // before children start calling e.g. updateCaption | ||||
Collections.sort(paintables, new Comparator<Component>() { | |||||
@Override | |||||
public int compare(Component c1, Component c2) { | |||||
int depth1 = 0; | |||||
while (c1.getParent() != null) { | |||||
depth1++; | |||||
c1 = c1.getParent(); | |||||
} | |||||
int depth2 = 0; | |||||
while (c2.getParent() != null) { | |||||
depth2++; | |||||
c2 = c2.getParent(); | |||||
} | |||||
if (depth1 < depth2) { | |||||
return -1; | |||||
} | |||||
if (depth1 > depth2) { | |||||
return 1; | |||||
} | |||||
return 0; | |||||
Collections.sort(paintables, (Component c1, Component c2) -> { | |||||
int depth1 = 0; | |||||
while (c1.getParent() != null) { | |||||
depth1++; | |||||
c1 = c1.getParent(); | |||||
} | } | ||||
int depth2 = 0; | |||||
while (c2.getParent() != null) { | |||||
depth2++; | |||||
c2 = c2.getParent(); | |||||
} | |||||
if (depth1 < depth2) { | |||||
return -1; | |||||
} | |||||
if (depth1 > depth2) { | |||||
return 1; | |||||
} | |||||
return 0; | |||||
}); | }); | ||||
} | } | ||||
* open by calling resource.suspend(). If there is a pending push, send it | * open by calling resource.suspend(). If there is a pending push, send it | ||||
* now. | * now. | ||||
*/ | */ | ||||
private final PushEventCallback establishCallback = new PushEventCallback() { | |||||
@Override | |||||
public void run(AtmosphereResource resource, UI ui) throws IOException { | |||||
getLogger().log(Level.FINER, | |||||
"New push connection for resource {0} with transport {1}", | |||||
new Object[] { resource.uuid(), resource.transport() }); | |||||
resource.getResponse().setContentType("text/plain; charset=UTF-8"); | |||||
VaadinSession session = ui.getSession(); | |||||
if (resource.transport() == TRANSPORT.STREAMING) { | |||||
// 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(ApplicationConstants.CSRF_TOKEN_PARAMETER); | |||||
if (!VaadinService.isCsrfTokenValid(session, requestToken)) { | |||||
getLogger().log(Level.WARNING, | |||||
"Invalid CSRF token in new connection received from {0}", | |||||
resource.getRequest().getRemoteHost()); | |||||
// Refresh on client side, create connection just for | |||||
// sending a message | |||||
sendRefreshAndDisconnect(resource); | |||||
return; | |||||
} | |||||
suspend(resource); | |||||
AtmospherePushConnection connection = getConnectionForUI(ui); | |||||
assert (connection != null); | |||||
connection.connect(resource); | |||||
private final PushEventCallback establishCallback = (AtmosphereResource resource, UI ui) -> { | |||||
getLogger().log(Level.FINER, | |||||
"New push connection for resource {0} with transport {1}", | |||||
new Object[] { resource.uuid(), resource.transport() }); | |||||
resource.getResponse().setContentType("text/plain; charset=UTF-8"); | |||||
VaadinSession session = ui.getSession(); | |||||
if (resource.transport() == TRANSPORT.STREAMING) { | |||||
// 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(ApplicationConstants.CSRF_TOKEN_PARAMETER); | |||||
if (!VaadinService.isCsrfTokenValid(session, requestToken)) { | |||||
getLogger().log(Level.WARNING, | |||||
"Invalid CSRF token in new connection received from {0}", | |||||
resource.getRequest().getRemoteHost()); | |||||
// Refresh on client side, create connection just for | |||||
// sending a message | |||||
sendRefreshAndDisconnect(resource); | |||||
return; | |||||
} | |||||
suspend(resource); | |||||
AtmospherePushConnection connection = getConnectionForUI(ui); | |||||
assert (connection != null); | |||||
connection.connect(resource); | |||||
}; | }; | ||||
/** | /** | ||||
* the request and send changed UI state via the push channel (we do not | * the request and send changed UI state via the push channel (we do not | ||||
* respond to the request directly.) | * respond to the request directly.) | ||||
*/ | */ | ||||
private final PushEventCallback receiveCallback = new PushEventCallback() { | |||||
@Override | |||||
public void run(AtmosphereResource resource, UI ui) throws IOException { | |||||
getLogger().log(Level.FINER, "Received message from resource {0}", | |||||
resource.uuid()); | |||||
AtmosphereRequest req = resource.getRequest(); | |||||
AtmospherePushConnection connection = getConnectionForUI(ui); | |||||
assert connection != null : "Got push from the client " | |||||
+ "even though the connection does not seem to be " | |||||
+ "valid. This might happen if a HttpSession is " | |||||
+ "serialized and deserialized while the push " | |||||
+ "connection is kept open or if the UI has a " | |||||
+ "connection of unexpected type."; | |||||
Reader reader = connection.receiveMessage(req.getReader()); | |||||
if (reader == null) { | |||||
// The whole message was not yet received | |||||
return; | |||||
} | |||||
// Should be set up by caller | |||||
VaadinRequest vaadinRequest = VaadinService.getCurrentRequest(); | |||||
assert vaadinRequest != null; | |||||
try { | |||||
new ServerRpcHandler().handleRpc(ui, reader, vaadinRequest); | |||||
connection.push(false); | |||||
} catch (JsonException e) { | |||||
getLogger().log(Level.SEVERE, "Error writing JSON to response", | |||||
e); | |||||
// Refresh on client side | |||||
sendRefreshAndDisconnect(resource); | |||||
} catch (InvalidUIDLSecurityKeyException e) { | |||||
getLogger().log(Level.WARNING, | |||||
"Invalid security key received from {0}", | |||||
resource.getRequest().getRemoteHost()); | |||||
// Refresh on client side | |||||
sendRefreshAndDisconnect(resource); | |||||
} | |||||
private final PushEventCallback receiveCallback = (AtmosphereResource resource, UI ui) -> { | |||||
getLogger().log(Level.FINER, "Received message from resource {0}", | |||||
resource.uuid()); | |||||
AtmosphereRequest req = resource.getRequest(); | |||||
AtmospherePushConnection connection = getConnectionForUI(ui); | |||||
assert connection != null : "Got push from the client " | |||||
+ "even though the connection does not seem to be " | |||||
+ "valid. This might happen if a HttpSession is " | |||||
+ "serialized and deserialized while the push " | |||||
+ "connection is kept open or if the UI has a " | |||||
+ "connection of unexpected type."; | |||||
Reader reader = connection.receiveMessage(req.getReader()); | |||||
if (reader == null) { | |||||
// The whole message was not yet received | |||||
return; | |||||
} | |||||
// Should be set up by caller | |||||
VaadinRequest vaadinRequest = VaadinService.getCurrentRequest(); | |||||
assert vaadinRequest != null; | |||||
try { | |||||
new ServerRpcHandler().handleRpc(ui, reader, vaadinRequest); | |||||
connection.push(false); | |||||
} catch (JsonException e) { | |||||
getLogger().log(Level.SEVERE, "Error writing JSON to response", | |||||
e); | |||||
// Refresh on client side | |||||
sendRefreshAndDisconnect(resource); | |||||
} catch (InvalidUIDLSecurityKeyException e) { | |||||
getLogger().log(Level.WARNING, | |||||
"Invalid security key received from {0}", | |||||
resource.getRequest().getRemoteHost()); | |||||
// Refresh on client side | |||||
sendRefreshAndDisconnect(resource); | |||||
} | } | ||||
}; | }; | ||||
public PushRequestHandler(VaadinServletService service) | public PushRequestHandler(VaadinServletService service) | ||||
throws ServiceException { | throws ServiceException { | ||||
service.addServiceDestroyListener(new ServiceDestroyListener() { | |||||
@Override | |||||
public void serviceDestroy(ServiceDestroyEvent event) { | |||||
destroy(); | |||||
} | |||||
service.addServiceDestroyListener((ServiceDestroyEvent event) -> { | |||||
destroy(); | |||||
}); | }); | ||||
final ServletConfig vaadinServletConfig = service.getServlet() | final ServletConfig vaadinServletConfig = service.getServlet() |
import java.net.URL; | import java.net.URL; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.Comparator; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.logging.Level; | import java.util.logging.Level; | ||||
// Sort addon styles so that CSS imports are first and SCSS import | // Sort addon styles so that CSS imports are first and SCSS import | ||||
// last | // last | ||||
List<String> paths = new ArrayList<>(addonThemes.keySet()); | List<String> paths = new ArrayList<>(addonThemes.keySet()); | ||||
Collections.sort(paths, new Comparator<String>() { | |||||
@Override | |||||
public int compare(String path1, String path2) { | |||||
if (path1.toLowerCase().endsWith(".css") | |||||
&& path2.toLowerCase().endsWith(".scss")) { | |||||
return -1; | |||||
} | |||||
if (path1.toLowerCase().endsWith(".scss") | |||||
&& path2.toLowerCase().endsWith(".css")) { | |||||
return 1; | |||||
} | |||||
return 0; | |||||
Collections.sort(paths, (String path1, String path2) -> { | |||||
if (path1.toLowerCase().endsWith(".css") | |||||
&& path2.toLowerCase().endsWith(".scss")) { | |||||
return -1; | |||||
} | } | ||||
if (path1.toLowerCase().endsWith(".scss") | |||||
&& path2.toLowerCase().endsWith(".css")) { | |||||
return 1; | |||||
} | |||||
return 0; | |||||
}); | }); | ||||
List<String> mixins = new ArrayList<>(); | List<String> mixins = new ArrayList<>(); |
/** | /** | ||||
* File filter that only accepts directories. | * File filter that only accepts directories. | ||||
*/ | */ | ||||
private final static FileFilter DIRECTORIES_ONLY = new FileFilter() { | |||||
@Override | |||||
public boolean accept(File f) { | |||||
if (f.exists() && f.isDirectory()) { | |||||
return true; | |||||
} else { | |||||
return false; | |||||
} | |||||
private final static FileFilter DIRECTORIES_ONLY = (File f) -> { | |||||
if (f.exists() && f.isDirectory()) { | |||||
return true; | |||||
} else { | |||||
return false; | |||||
} | } | ||||
}; | }; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.LinkedHashMap; | import java.util.LinkedHashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Objects; | |||||
import org.jsoup.nodes.Attributes; | import org.jsoup.nodes.Attributes; | ||||
import org.jsoup.nodes.Element; | import org.jsoup.nodes.Element; | ||||
private static final String ATTR_LEFT = ":left"; | private static final String ATTR_LEFT = ":left"; | ||||
private static final String ATTR_Z_INDEX = ":z-index"; | private static final String ATTR_Z_INDEX = ":z-index"; | ||||
private AbsoluteLayoutServerRpc rpc = new AbsoluteLayoutServerRpc() { | |||||
@Override | |||||
public void layoutClick(MouseEventDetails mouseDetails, | |||||
Connector clickedConnector) { | |||||
fireEvent(LayoutClickEvent.createEvent(AbsoluteLayout.this, | |||||
mouseDetails, clickedConnector)); | |||||
} | |||||
private final AbsoluteLayoutServerRpc rpc = (MouseEventDetails mouseDetails, | |||||
Connector clickedConnector) -> { | |||||
fireEvent(LayoutClickEvent.createEvent(AbsoluteLayout.this, | |||||
mouseDetails, clickedConnector)); | |||||
}; | }; | ||||
// Maps each component to a position | // Maps each component to a position | ||||
private LinkedHashMap<Component, ComponentPosition> componentToCoordinates = new LinkedHashMap<>(); | private LinkedHashMap<Component, ComponentPosition> componentToCoordinates = new LinkedHashMap<>(); |
} | } | ||||
} | } | ||||
private ColorPickerServerRpc rpc = new ColorPickerServerRpc() { | |||||
@Override | |||||
public void openPopup(boolean open) { | |||||
showPopup(open); | |||||
} | |||||
}; | |||||
private ColorPickerServerRpc rpc = this::showPopup; | |||||
protected static final String STYLENAME_DEFAULT = "v-colorpicker"; | protected static final String STYLENAME_DEFAULT = "v-colorpicker"; | ||||
protected static final String STYLENAME_BUTTON = "v-button"; | protected static final String STYLENAME_BUTTON = "v-button"; |
// called if there are no listeners on the server-side. A client-side | // called if there are no listeners on the server-side. A client-side | ||||
// connector can override this and use a different RPC channel. | // connector can override this and use a different RPC channel. | ||||
if (getRpcManager(ContextClickRpc.class.getName()) == null) { | if (getRpcManager(ContextClickRpc.class.getName()) == null) { | ||||
registerRpc(new ContextClickRpc() { | |||||
@Override | |||||
public void contextClick(MouseEventDetails details) { | |||||
fireEvent(new ContextClickEvent(AbstractComponent.this, | |||||
details)); | |||||
} | |||||
registerRpc((ContextClickRpc) (MouseEventDetails details) -> { | |||||
fireEvent(new ContextClickEvent(AbstractComponent.this, | |||||
details)); | |||||
}); | }); | ||||
} | } | ||||
implements Layout.AlignmentHandler, Layout.SpacingHandler, | implements Layout.AlignmentHandler, Layout.SpacingHandler, | ||||
LayoutClickNotifier, Layout.MarginHandler { | LayoutClickNotifier, Layout.MarginHandler { | ||||
private AbstractOrderedLayoutServerRpc rpc = new AbstractOrderedLayoutServerRpc() { | |||||
@Override | |||||
public void layoutClick(MouseEventDetails mouseDetails, | |||||
Connector clickedConnector) { | |||||
fireEvent(LayoutClickEvent.createEvent(AbstractOrderedLayout.this, | |||||
mouseDetails, clickedConnector)); | |||||
} | |||||
private final AbstractOrderedLayoutServerRpc rpc = ( | |||||
MouseEventDetails mouseDetails, Connector clickedConnector) -> { | |||||
fireEvent(LayoutClickEvent.createEvent(AbstractOrderedLayout.this, | |||||
mouseDetails, clickedConnector)); | |||||
}; | }; | ||||
public static final Alignment ALIGNMENT_DEFAULT = Alignment.TOP_LEFT; | public static final Alignment ALIGNMENT_DEFAULT = Alignment.TOP_LEFT; | ||||
// write default attributes | // write default attributes | ||||
super.writeDesign(design, designContext); | super.writeDesign(design, designContext); | ||||
AbstractOrderedLayout def = designContext | |||||
.getDefaultInstance(this); | |||||
AbstractOrderedLayout def = designContext.getDefaultInstance(this); | |||||
writeMargin(design, getMargin(), def.getMargin(), designContext); | writeMargin(design, getMargin(), def.getMargin(), designContext); | ||||
public class CheckBox extends AbstractField<Boolean> | public class CheckBox extends AbstractField<Boolean> | ||||
implements FieldEvents.BlurNotifier, FieldEvents.FocusNotifier { | implements FieldEvents.BlurNotifier, FieldEvents.FocusNotifier { | ||||
private CheckBoxServerRpc rpc = new CheckBoxServerRpc() { | |||||
@Override | |||||
public void setChecked(boolean checked, | |||||
MouseEventDetails mouseEventDetails) { | |||||
if (isReadOnly()) { | |||||
return; | |||||
} | |||||
/* | |||||
* Client side updates the state before sending the event so we need | |||||
* to make sure the cached state is updated to match the client. If | |||||
* we do not do this, a reverting setValue() call in a listener will | |||||
* not cause the new state to be sent to the client. | |||||
* | |||||
* See #11028, #10030. | |||||
*/ | |||||
getUI().getConnectorTracker().getDiffState(CheckBox.this) | |||||
.put("checked", checked); | |||||
final Boolean oldValue = getValue(); | |||||
final Boolean newValue = checked; | |||||
if (!newValue.equals(oldValue)) { | |||||
// The event is only sent if the switch state is changed | |||||
setValue(newValue); | |||||
} | |||||
private CheckBoxServerRpc rpc = (boolean checked, MouseEventDetails mouseEventDetails) -> { | |||||
if (isReadOnly()) { | |||||
return; | |||||
} | |||||
/* | |||||
* Client side updates the state before sending the event so we need | |||||
* to make sure the cached state is updated to match the client. If | |||||
* we do not do this, a reverting setValue() call in a listener will | |||||
* not cause the new state to be sent to the client. | |||||
* | |||||
* See #11028, #10030. | |||||
*/ | |||||
getUI().getConnectorTracker().getDiffState(CheckBox.this) | |||||
.put("checked", checked); | |||||
final Boolean oldValue = getValue(); | |||||
final Boolean newValue = checked; | |||||
if (!newValue.equals(oldValue)) { | |||||
// The event is only sent if the switch state is changed | |||||
setValue(newValue); | |||||
} | } | ||||
}; | }; | ||||
*/ | */ | ||||
public class CssLayout extends AbstractLayout implements LayoutClickNotifier { | public class CssLayout extends AbstractLayout implements LayoutClickNotifier { | ||||
private CssLayoutServerRpc rpc = new CssLayoutServerRpc() { | |||||
@Override | |||||
public void layoutClick(MouseEventDetails mouseDetails, | |||||
Connector clickedConnector) { | |||||
fireEvent(LayoutClickEvent.createEvent(CssLayout.this, mouseDetails, | |||||
clickedConnector)); | |||||
} | |||||
private CssLayoutServerRpc rpc = (MouseEventDetails mouseDetails, Connector clickedConnector) -> { | |||||
fireEvent(LayoutClickEvent.createEvent(CssLayout.this, mouseDetails, | |||||
clickedConnector)); | |||||
}; | }; | ||||
/** | /** | ||||
* Custom layout slots containing the components. | * Custom layout slots containing the components. |
} | } | ||||
private final DragAndDropWrapperServerRpc rpc = new DragAndDropWrapperServerRpc() { | |||||
@Override | |||||
public void poll() { | |||||
// #19616 RPC to poll the server for changes | |||||
} | |||||
private final DragAndDropWrapperServerRpc rpc = () -> { | |||||
// #19616 RPC to poll the server for changes | |||||
}; | }; | ||||
private Map<String, ProxyReceiver> receivers = new HashMap<>(); | private Map<String, ProxyReceiver> receivers = new HashMap<>(); |
private String altText; | private String altText; | ||||
private EmbeddedServerRpc rpc = new EmbeddedServerRpc() { | |||||
@Override | |||||
public void click(MouseEventDetails mouseDetails) { | |||||
fireEvent(new ClickEvent(Embedded.this, mouseDetails)); | |||||
} | |||||
private EmbeddedServerRpc rpc = (MouseEventDetails mouseDetails) -> { | |||||
fireEvent(new ClickEvent(Embedded.this, mouseDetails)); | |||||
}; | }; | ||||
/** | /** |
implements Layout.AlignmentHandler, Layout.SpacingHandler, | implements Layout.AlignmentHandler, Layout.SpacingHandler, | ||||
Layout.MarginHandler, LayoutClickNotifier { | Layout.MarginHandler, LayoutClickNotifier { | ||||
private GridLayoutServerRpc rpc = new GridLayoutServerRpc() { | |||||
@Override | |||||
public void layoutClick(MouseEventDetails mouseDetails, | |||||
Connector clickedConnector) { | |||||
fireEvent(LayoutClickEvent.createEvent(GridLayout.this, | |||||
mouseDetails, clickedConnector)); | |||||
} | |||||
private GridLayoutServerRpc rpc = (MouseEventDetails mouseDetails, Connector clickedConnector) -> { | |||||
fireEvent(LayoutClickEvent.createEvent(GridLayout.this, | |||||
mouseDetails, clickedConnector)); | |||||
}; | }; | ||||
/** | /** | ||||
* Cursor X position: this is where the next component with unspecified x,y | * Cursor X position: this is where the next component with unspecified x,y |
@SuppressWarnings("serial") | @SuppressWarnings("serial") | ||||
public class Image extends AbstractEmbedded { | public class Image extends AbstractEmbedded { | ||||
protected ImageServerRpc rpc = new ImageServerRpc() { | |||||
@Override | |||||
public void click(MouseEventDetails mouseDetails) { | |||||
fireEvent(new ClickEvent(Image.this, mouseDetails)); | |||||
} | |||||
protected ImageServerRpc rpc = (MouseEventDetails mouseDetails) -> { | |||||
fireEvent(new ClickEvent(Image.this, mouseDetails)); | |||||
}; | }; | ||||
/** | /** |
* object. | * object. | ||||
*/ | */ | ||||
public JavaScript() { | public JavaScript() { | ||||
registerRpc(new JavaScriptCallbackRpc() { | |||||
@Override | |||||
public void call(String name, JsonArray arguments) { | |||||
JavaScriptFunction function = functions.get(name); | |||||
// TODO handle situation if name is not registered | |||||
try { | |||||
function.call(arguments); | |||||
} catch (JsonException e) { | |||||
throw new IllegalArgumentException(e); | |||||
} | |||||
registerRpc((JavaScriptCallbackRpc) (String name, JsonArray arguments) -> { | |||||
JavaScriptFunction function = functions.get(name); | |||||
// TODO handle situation if name is not registered | |||||
try { | |||||
function.call(arguments); | |||||
} catch (JsonException e) { | |||||
throw new IllegalArgumentException(e); | |||||
} | } | ||||
}); | }); | ||||
} | } |
resource.setCacheTime(-1); | resource.setCacheTime(-1); | ||||
setResource(LoginFormConstants.LOGIN_RESOURCE_NAME, resource); | setResource(LoginFormConstants.LOGIN_RESOURCE_NAME, resource); | ||||
registerRpc(new LoginFormRpc() { | |||||
@Override | |||||
public void submitCompleted() { | |||||
login(); | |||||
} | |||||
}); | |||||
registerRpc((LoginFormRpc) this::login); | |||||
initialized = true; | initialized = true; | ||||
*/ | */ | ||||
protected ActionManager actionManager; | protected ActionManager actionManager; | ||||
private PanelServerRpc rpc = new PanelServerRpc() { | |||||
@Override | |||||
public void click(MouseEventDetails mouseDetails) { | |||||
fireEvent(new ClickEvent(Panel.this, mouseDetails)); | |||||
} | |||||
private PanelServerRpc rpc = (MouseEventDetails mouseDetails) -> { | |||||
fireEvent(new ClickEvent(Panel.this, mouseDetails)); | |||||
}; | }; | ||||
/** | /** |
} | } | ||||
} | } | ||||
private final PopupViewServerRpc rpc = new PopupViewServerRpc() { | |||||
@Override | |||||
public void setPopupVisibility(boolean visible) { | |||||
setPopupVisible(visible); | |||||
} | |||||
}; | |||||
private final PopupViewServerRpc rpc = this::setPopupVisible; | |||||
/* Constructors */ | /* Constructors */ | ||||
*/ | */ | ||||
public class Slider extends AbstractField<Double> { | public class Slider extends AbstractField<Double> { | ||||
private SliderServerRpc rpc = new SliderServerRpc() { | |||||
@Override | |||||
public void valueChanged(double value) { | |||||
/* | |||||
* Client side updates the state before sending the event so we need | |||||
* to make sure the cached state is updated to match the client. If | |||||
* we do not do this, a reverting setValue() call in a listener will | |||||
* not cause the new state to be sent to the client. | |||||
* | |||||
* See #12133. | |||||
*/ | |||||
getUI().getConnectorTracker().getDiffState(Slider.this).put("value", | |||||
value); | |||||
try { | |||||
setValue(value, true); | |||||
} catch (final ValueOutOfBoundsException e) { | |||||
// Convert to nearest bound | |||||
double out = e.getValue().doubleValue(); | |||||
if (out < getState().minValue) { | |||||
out = getState().minValue; | |||||
} | |||||
if (out > getState().maxValue) { | |||||
out = getState().maxValue; | |||||
} | |||||
Slider.super.setValue(new Double(out), false); | |||||
private SliderServerRpc rpc = (double value) -> { | |||||
/* | |||||
* Client side updates the state before sending the event so we need to | |||||
* make sure the cached state is updated to match the client. If we do | |||||
* not do this, a reverting setValue() call in a listener will not cause | |||||
* the new state to be sent to the client. | |||||
* | |||||
* See #12133. | |||||
*/ | |||||
getUI().getConnectorTracker().getDiffState(Slider.this).put("value", | |||||
value); | |||||
try { | |||||
setValue(value, true); | |||||
} catch (final ValueOutOfBoundsException e) { | |||||
// Convert to nearest bound | |||||
double out = e.getValue().doubleValue(); | |||||
if (out < getState().minValue) { | |||||
out = getState().minValue; | |||||
} | } | ||||
if (out > getState().maxValue) { | |||||
out = getState().maxValue; | |||||
} | |||||
Slider.super.setValue(new Double(out), false); | |||||
} | } | ||||
}; | }; | ||||
/** | /** |
// expand horizontally by default | // expand horizontally by default | ||||
setWidth(100, UNITS_PERCENTAGE); | setWidth(100, UNITS_PERCENTAGE); | ||||
setCloseHandler(new CloseHandler() { | |||||
@Override | |||||
public void onTabClose(TabSheet tabsheet, Component c) { | |||||
tabsheet.removeComponent(c); | |||||
} | |||||
}); | |||||
setCloseHandler(TabSheet::removeComponent); | |||||
} | } | ||||
/** | /** |
} | } | ||||
// create listener for component creations that binds the created | // create listener for component creations that binds the created | ||||
// components to the componentRoot instance fields | // components to the componentRoot instance fields | ||||
ComponentCreationListener creationListener = new ComponentCreationListener() { | |||||
@Override | |||||
public void componentCreated(ComponentCreatedEvent event) { | |||||
binder.bindField(event.getComponent(), event.getLocalId()); | |||||
} | |||||
ComponentCreationListener creationListener = (ComponentCreatedEvent event) -> { | |||||
binder.bindField(event.getComponent(), event.getLocalId()); | |||||
}; | }; | ||||
designContext.addComponentCreationListener(creationListener); | designContext.addComponentCreationListener(creationListener); | ||||
// create subtree | // create subtree |
* is provided by a data source connected to a back end system and that the | * is provided by a data source connected to a back end system and that the | ||||
* data should thus not be written. | * data should thus not be written. | ||||
*/ | */ | ||||
public static final ShouldWriteDataDelegate DEFAULT = new ShouldWriteDataDelegate() { | |||||
@Override | |||||
public boolean shouldWriteData(Component component) { | |||||
return false; | |||||
} | |||||
}; | |||||
public static final ShouldWriteDataDelegate DEFAULT = ( | |||||
Component component) -> false; | |||||
/** | /** | ||||
* Determines whether the container data of a component should be written | * Determines whether the container data of a component should be written |
protected ClickableRenderer(Class<V> presentationType, | protected ClickableRenderer(Class<V> presentationType, | ||||
String nullRepresentation) { | String nullRepresentation) { | ||||
super(presentationType, nullRepresentation); | super(presentationType, nullRepresentation); | ||||
registerRpc(new RendererClickRpc() { | |||||
@Override | |||||
public void click(String rowKey, String columnId, | |||||
MouseEventDetails mouseDetails) { | |||||
Grid<T> grid = getParentGrid(); | |||||
T item = grid.getDataCommunicator().getKeyMapper().get(rowKey); | |||||
Column column = grid.getColumn(columnId); | |||||
fireEvent(new RendererClickEvent<>(grid, item, column, | |||||
mouseDetails)); | |||||
} | |||||
registerRpc((RendererClickRpc) (String rowKey, String columnId, MouseEventDetails mouseDetails) -> { | |||||
Grid<T> grid = getParentGrid(); | |||||
T item = grid.getDataCommunicator().getKeyMapper().get(rowKey); | |||||
Column column = grid.getColumn(columnId); | |||||
fireEvent(new RendererClickEvent<>(grid, item, column, | |||||
mouseDetails)); | |||||
}); | }); | ||||
} | } | ||||
binding.withValidator(Validator.alwaysPass()); | binding.withValidator(Validator.alwaysPass()); | ||||
String msg1 = "foo"; | String msg1 = "foo"; | ||||
String msg2 = "bar"; | String msg2 = "bar"; | ||||
binding.withValidator(new Validator<String>() { | |||||
@Override | |||||
public ValidationResult apply(String value, ValueContext context) { | |||||
return ValidationResult.error(msg1); | |||||
} | |||||
}); | |||||
binding.withValidator((String value, | |||||
ValueContext context) -> ValidationResult.error(msg1)); | |||||
binding.withValidator(value -> false, msg2); | binding.withValidator(value -> false, msg2); | ||||
binding.bind(Person::getFirstName, Person::setFirstName); | binding.bind(Person::getFirstName, Person::setFirstName); | ||||
bindName(); | bindName(); | ||||
AtomicBoolean beanLevelValidationRun = new AtomicBoolean(); | AtomicBoolean beanLevelValidationRun = new AtomicBoolean(); | ||||
binder.withValidator(Validator.from( | |||||
bean -> beanLevelValidationRun.getAndSet(true), "")); | |||||
binder.withValidator(Validator | |||||
.from(bean -> beanLevelValidationRun.getAndSet(true), "")); | |||||
ageField.setValue("not a number"); | ageField.setValue("not a number"); | ||||
bindName(); | bindName(); | ||||
AtomicBoolean beanLevelValidationRun = new AtomicBoolean(); | AtomicBoolean beanLevelValidationRun = new AtomicBoolean(); | ||||
binder.withValidator(Validator.from( | |||||
bean -> beanLevelValidationRun.getAndSet(true), "")); | |||||
binder.withValidator(Validator | |||||
.from(bean -> beanLevelValidationRun.getAndSet(true), "")); | |||||
ageField.setValue(String.valueOf(12)); | ageField.setValue(String.valueOf(12)); | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import com.vaadin.server.ClientConnector.DetachEvent; | import com.vaadin.server.ClientConnector.DetachEvent; | ||||
import com.vaadin.server.ClientConnector.DetachListener; | |||||
import com.vaadin.server.communication.UIInitHandler; | import com.vaadin.server.communication.UIInitHandler; | ||||
import com.vaadin.ui.Label; | import com.vaadin.ui.Label; | ||||
import com.vaadin.ui.UI; | import com.vaadin.ui.UI; | ||||
// this simulates servlet container's session invalidation from another | // this simulates servlet container's session invalidation from another | ||||
// thread | // thread | ||||
new Thread(new Runnable() { | |||||
@Override | |||||
public void run() { | |||||
new Thread(() -> { | |||||
try { | |||||
Thread.sleep(150); // delay selected so that VaadinSession | |||||
// will be already locked by the main | |||||
// thread | |||||
// when we get here | |||||
httpSessionLock.lock();// simulating servlet container's | |||||
// session lock | |||||
try { | try { | ||||
Thread.sleep(150); // delay selected so that VaadinSession | |||||
// will be already locked by the main | |||||
// thread | |||||
// when we get here | |||||
httpSessionLock.lock();// simulating servlet container's | |||||
// session lock | |||||
try { | |||||
mockService.fireSessionDestroy(session); | |||||
} finally { | |||||
httpSessionLock.unlock(); | |||||
} | |||||
} catch (InterruptedException e) { | |||||
throw new RuntimeException(e); | |||||
mockService.fireSessionDestroy(session); | |||||
} finally { | |||||
httpSessionLock.unlock(); | |||||
} | } | ||||
} catch (InterruptedException e) { | |||||
throw new RuntimeException(e); | |||||
} | } | ||||
}).start(); | }).start(); | ||||
throws InterruptedException { | throws InterruptedException { | ||||
final AtomicBoolean detachCalled = new AtomicBoolean(false); | final AtomicBoolean detachCalled = new AtomicBoolean(false); | ||||
ui.addDetachListener(new DetachListener() { | |||||
@Override | |||||
public void detach(DetachEvent event) { | |||||
detachCalled.set(true); | |||||
Assert.assertEquals(ui, UI.getCurrent()); | |||||
Assert.assertEquals(ui.getPage(), Page.getCurrent()); | |||||
Assert.assertEquals(session, VaadinSession.getCurrent()); | |||||
Assert.assertEquals(mockService, VaadinService.getCurrent()); | |||||
Assert.assertEquals(mockServlet, VaadinServlet.getCurrent()); | |||||
} | |||||
ui.addDetachListener((DetachEvent event) -> { | |||||
detachCalled.set(true); | |||||
Assert.assertEquals(ui, UI.getCurrent()); | |||||
Assert.assertEquals(ui.getPage(), Page.getCurrent()); | |||||
Assert.assertEquals(session, VaadinSession.getCurrent()); | |||||
Assert.assertEquals(mockService, VaadinService.getCurrent()); | |||||
Assert.assertEquals(mockServlet, VaadinServlet.getCurrent()); | |||||
}); | }); | ||||
session.valueUnbound( | session.valueUnbound( | ||||
@Test | @Test | ||||
public void threadLocalsAfterSessionDestroy() throws InterruptedException { | public void threadLocalsAfterSessionDestroy() throws InterruptedException { | ||||
final AtomicBoolean detachCalled = new AtomicBoolean(false); | final AtomicBoolean detachCalled = new AtomicBoolean(false); | ||||
ui.addDetachListener(new DetachListener() { | |||||
@Override | |||||
public void detach(DetachEvent event) { | |||||
detachCalled.set(true); | |||||
Assert.assertEquals(ui, UI.getCurrent()); | |||||
Assert.assertEquals(ui.getPage(), Page.getCurrent()); | |||||
Assert.assertEquals(session, VaadinSession.getCurrent()); | |||||
Assert.assertEquals(mockService, VaadinService.getCurrent()); | |||||
Assert.assertEquals(mockServlet, VaadinServlet.getCurrent()); | |||||
} | |||||
ui.addDetachListener((DetachEvent event) -> { | |||||
detachCalled.set(true); | |||||
Assert.assertEquals(ui, UI.getCurrent()); | |||||
Assert.assertEquals(ui.getPage(), Page.getCurrent()); | |||||
Assert.assertEquals(session, VaadinSession.getCurrent()); | |||||
Assert.assertEquals(mockService, VaadinService.getCurrent()); | |||||
Assert.assertEquals(mockServlet, VaadinServlet.getCurrent()); | |||||
}); | }); | ||||
CurrentInstance.clearAll(); | CurrentInstance.clearAll(); | ||||
session.close(); | session.close(); |
findPackages(juc, basePackage, baseClass, classes); | findPackages(juc, basePackage, baseClass, classes); | ||||
} | } | ||||
Collections.sort(classes, new Comparator<Class<? extends T>>() { | |||||
@Override | |||||
public int compare(Class<? extends T> o1, Class<? extends T> o2) { | |||||
return o1.getName().compareTo(o2.getName()); | |||||
} | |||||
}); | |||||
Collections.sort(classes, (Class<? extends T> o1, Class<? extends T> o2) -> o1.getName().compareTo(o2.getName())); | |||||
return classes; | return classes; | ||||
} | } | ||||
// Set static component factory that delegate to a thread local factory | // Set static component factory that delegate to a thread local factory | ||||
static { | static { | ||||
Design.setComponentFactory(new ComponentFactory() { | |||||
@Override | |||||
public Component createComponent(String fullyQualifiedClassName, | |||||
DesignContext context) { | |||||
ComponentFactory componentFactory = currentComponentFactory | |||||
.get(); | |||||
if (componentFactory == null) { | |||||
componentFactory = defaultFactory; | |||||
} | |||||
return componentFactory.createComponent(fullyQualifiedClassName, | |||||
context); | |||||
Design.setComponentFactory((String fullyQualifiedClassName, DesignContext context) -> { | |||||
ComponentFactory componentFactory = currentComponentFactory | |||||
.get(); | |||||
if (componentFactory == null) { | |||||
componentFactory = defaultFactory; | |||||
} | } | ||||
return componentFactory.createComponent(fullyQualifiedClassName, | |||||
context); | |||||
}); | }); | ||||
} | } | ||||
@Test | @Test | ||||
public void testComponentFactoryLogging() { | public void testComponentFactoryLogging() { | ||||
final List<String> messages = new ArrayList<>(); | final List<String> messages = new ArrayList<>(); | ||||
currentComponentFactory.set(new ComponentFactory() { | |||||
@Override | |||||
public Component createComponent(String fullyQualifiedClassName, | |||||
DesignContext context) { | |||||
messages.add("Requested class " + fullyQualifiedClassName); | |||||
return defaultFactory.createComponent(fullyQualifiedClassName, | |||||
context); | |||||
} | |||||
currentComponentFactory.set((ComponentFactory) (String fullyQualifiedClassName, DesignContext context) -> { | |||||
messages.add("Requested class " + fullyQualifiedClassName); | |||||
return defaultFactory.createComponent(fullyQualifiedClassName, | |||||
context); | |||||
}); | }); | ||||
Design.read(new ByteArrayInputStream("<vaadin-label />".getBytes())); | Design.read(new ByteArrayInputStream("<vaadin-label />".getBytes())); | ||||
@Test(expected = DesignException.class) | @Test(expected = DesignException.class) | ||||
public void testComponentFactoryReturningNull() { | public void testComponentFactoryReturningNull() { | ||||
currentComponentFactory.set(new ComponentFactory() { | |||||
@Override | |||||
public Component createComponent(String fullyQualifiedClassName, | |||||
DesignContext context) { | |||||
return null; | |||||
} | |||||
}); | |||||
currentComponentFactory.set((ComponentFactory) (String fullyQualifiedClassName, DesignContext context) -> null); | |||||
Design.read(new ByteArrayInputStream("<vaadin-label />".getBytes())); | Design.read(new ByteArrayInputStream("<vaadin-label />".getBytes())); | ||||
} | } | ||||
@Test(expected = DesignException.class) | @Test(expected = DesignException.class) | ||||
public void testComponentFactoryThrowingStuff() { | public void testComponentFactoryThrowingStuff() { | ||||
currentComponentFactory.set(new ComponentFactory() { | |||||
@Override | |||||
public Component createComponent(String fullyQualifiedClassName, | |||||
DesignContext context) { | |||||
// Will throw because class is not found | |||||
return defaultFactory.createComponent( | |||||
"foobar." + fullyQualifiedClassName, context); | |||||
} | |||||
}); | |||||
currentComponentFactory.set((ComponentFactory) (String fullyQualifiedClassName, DesignContext context) -> defaultFactory.createComponent( | |||||
"foobar." + fullyQualifiedClassName, context) // Will throw because class is not found | |||||
); | |||||
Design.read(new ByteArrayInputStream("<vaadin-label />".getBytes())); | Design.read(new ByteArrayInputStream("<vaadin-label />".getBytes())); | ||||
} | } | ||||
@Test | @Test | ||||
public void testGetDefaultInstanceUsesComponentFactory() { | public void testGetDefaultInstanceUsesComponentFactory() { | ||||
final List<String> classes = new ArrayList<>(); | final List<String> classes = new ArrayList<>(); | ||||
currentComponentFactory.set(new ComponentFactory() { | |||||
@Override | |||||
public Component createComponent(String fullyQualifiedClassName, | |||||
DesignContext context) { | |||||
classes.add(fullyQualifiedClassName); | |||||
return defaultFactory.createComponent(fullyQualifiedClassName, | |||||
context); | |||||
} | |||||
currentComponentFactory.set((ComponentFactory) (String fullyQualifiedClassName, DesignContext context) -> { | |||||
classes.add(fullyQualifiedClassName); | |||||
return defaultFactory.createComponent(fullyQualifiedClassName, | |||||
context); | |||||
}); | }); | ||||
DesignContext designContext = new DesignContext(); | DesignContext designContext = new DesignContext(); |
private static boolean debug = false; | private static boolean debug = false; | ||||
private final Map<Class<?>, EqualsAsserter<?>> comparators = new HashMap<>(); | private final Map<Class<?>, EqualsAsserter<?>> comparators = new HashMap<>(); | ||||
private static EqualsAsserter standardEqualsComparator = new EqualsAsserter<Object>() { | |||||
@Override | |||||
public void assertObjectEquals(Object o1, Object o2) { | |||||
Assert.assertEquals(o1, o2); | |||||
} | |||||
}; | |||||
private static final EqualsAsserter standardEqualsComparator = (EqualsAsserter<Object>) Assert::assertEquals; | |||||
public class IntrospectorEqualsAsserter<C> implements EqualsAsserter<C> { | public class IntrospectorEqualsAsserter<C> implements EqualsAsserter<C> { | ||||
customField.setPlaceholder("Something"); | customField.setPlaceholder("Something"); | ||||
addComponent(customField); | addComponent(customField); | ||||
ok.addClickListener(new ClickListener() { | |||||
@Override | |||||
public void buttonClick(ClickEvent event) { | |||||
Notification.show("OK"); | |||||
} | |||||
ok.addClickListener((ClickEvent event) -> { | |||||
Notification.show("OK"); | |||||
}); | }); | ||||
CaNCEL.addClickListener(new ClickListener() { | |||||
@Override | |||||
public void buttonClick(ClickEvent event) { | |||||
Notification.show("cancel"); | |||||
} | |||||
CaNCEL.addClickListener((ClickEvent event) -> { | |||||
Notification.show("cancel"); | |||||
}); | }); | ||||
} | } | ||||
} | } |
public void clickDetachedButton() { | public void clickDetachedButton() { | ||||
Button b = new Button(); | Button b = new Button(); | ||||
AtomicInteger counter = new AtomicInteger(0); | AtomicInteger counter = new AtomicInteger(0); | ||||
b.addClickListener(new ClickListener() { | |||||
@Override | |||||
public void buttonClick(ClickEvent event) { | |||||
counter.incrementAndGet(); | |||||
} | |||||
b.addClickListener((ClickEvent event) -> { | |||||
counter.incrementAndGet(); | |||||
}); | }); | ||||
b.click(); | b.click(); | ||||
private void addClickListener(Button b) { | private void addClickListener(Button b) { | ||||
clicked = false; | clicked = false; | ||||
b.addClickListener(new Button.ClickListener() { | |||||
@Override | |||||
public void buttonClick(ClickEvent ev) { | |||||
clicked = true; | |||||
} | |||||
b.addClickListener((ClickEvent ev) -> { | |||||
clicked = true; | |||||
}); | }); | ||||
} | } | ||||
} | } |
final Window window = new Window(); | final Window window = new Window(); | ||||
final boolean[] eventFired = new boolean[1]; | final boolean[] eventFired = new boolean[1]; | ||||
ui.addComponentAttachListener(new ComponentAttachListener() { | |||||
@Override | |||||
public void componentAttachedToContainer( | |||||
ComponentAttachEvent event) { | |||||
eventFired[0] = event.getAttachedComponent().equals(window); | |||||
} | |||||
ui.addComponentAttachListener((ComponentAttachEvent event) -> { | |||||
eventFired[0] = event.getAttachedComponent().equals(window); | |||||
}); | }); | ||||
ui.addWindow(window); | ui.addWindow(window); | ||||
Assert.assertTrue("Attach event is not fired for added window", | Assert.assertTrue("Attach event is not fired for added window", | ||||
final Window window = new Window(); | final Window window = new Window(); | ||||
final boolean[] eventFired = new boolean[1]; | final boolean[] eventFired = new boolean[1]; | ||||
ui.addComponentDetachListener(new ComponentDetachListener() { | |||||
@Override | |||||
public void componentDetachedFromContainer( | |||||
ComponentDetachEvent event) { | |||||
eventFired[0] = event.getDetachedComponent().equals(window); | |||||
} | |||||
ui.addComponentDetachListener((ComponentDetachEvent event) -> { | |||||
eventFired[0] = event.getDetachedComponent().equals(window); | |||||
}); | }); | ||||
ui.addWindow(window); | ui.addWindow(window); | ||||
ui.removeWindow(window); | ui.removeWindow(window); |