/* * Copyright 2000-2016 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.server.communication.AtmospherePushConnection; 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); /** * Sets the URL to use for push requests. * <p> * This is only used when overriding the URL to use. Setting this to null * (the default) will use the default URL. * * @since 7.6 * @param pushUrl * The push URL to use */ public void setPushUrl(String pushUrl); /** * Returns the URL to use for push requests. * <p> * This is only used when overriding the URL to use. Returns null (the * default) when the default URL is used. * * @since 7.6 * @return the URL to use for push requests, or null to use to default */ public String getPushUrl(); } class PushConfigurationImpl implements PushConfiguration { private final 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"); } VaadinSession session = ui.getSession(); if (session == null) { throw new UIDetachedException( "Cannot set the push mode for a detached UI"); } assert session.hasLock(); if (pushMode.isEnabled() && !session.getService().ensurePushAvailable()) { throw new IllegalStateException( "Push is not available. See previous log messages for more information."); } PushMode oldMode = getState().mode; if (oldMode != pushMode) { getState().mode = pushMode; if (!oldMode.isEnabled() && pushMode.isEnabled()) { // The push connection is initially in a disconnected state; // the client will establish the connection ui.setPushConnection(new AtmospherePushConnection(ui)); } // Nothing to do here if disabling push; // the client will close the connection } } @Override public void setPushUrl(String pushUrl) { getState().pushUrl = pushUrl; } @Override public String getPushUrl() { return getState(false).pushUrl; } /* * (non-Javadoc) * * @see com.vaadin.ui.PushConfiguration#getTransport() */ @Override public Transport getTransport() { try { Transport tr = Transport.getByIdentifier( getParameter(PushConfigurationState.TRANSPORT_PARAM)); if (tr == Transport.WEBSOCKET && getState(false).alwaysUseXhrForServerRequests) { return Transport.WEBSOCKET_XHR; } else { return tr; } } 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) { if (transport == Transport.WEBSOCKET_XHR) { getState().alwaysUseXhrForServerRequests = true; // Atmosphere knows only about "websocket" setParameter(PushConfigurationState.TRANSPORT_PARAM, Transport.WEBSOCKET.getIdentifier()); } else { getState().alwaysUseXhrForServerRequests = false; 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) { if (fallbackTransport == Transport.WEBSOCKET_XHR) { throw new IllegalArgumentException( "WEBSOCKET_XHR can only be used as primary transport"); } 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(getState(false).parameters.keySet()); } }