/* * Copyright 2011 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.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import com.vaadin.terminal.AbstractClientConnector; import com.vaadin.terminal.gwt.server.ClientConnector; /** * A class which takes care of book keeping of {@link ClientConnector}s for a * Root. *
* Provides {@link #getConnector(String)} which can be used to lookup a * connector from its id. This is for framework use only and should not be * needed in applications. *
** Tracks which {@link ClientConnector}s are dirty so they can be updated to the * client when the following response is sent. A connector is dirty when an * operation has been performed on it on the server and as a result of this * operation new information needs to be sent to its * {@link com.vaadin.terminal.gwt.client.ServerConnector}. *
* * @author Vaadin Ltd * @since 7.0.0 * */ public class ConnectorTracker implements Serializable { private final HashMap* The lookup method {@link #getConnector(String)} only returns registered * connectors. *
* * @param connector * The connector to register. */ public void registerConnector(ClientConnector connector) { String connectorId = connector.getConnectorId(); ClientConnector previouslyRegistered = connectorIdToConnector .get(connectorId); if (previouslyRegistered == null) { connectorIdToConnector.put(connectorId, connector); uninitializedConnectors.add(connector); getLogger().fine( "Registered " + connector.getClass().getSimpleName() + " (" + connectorId + ")"); } else if (previouslyRegistered != connector) { throw new RuntimeException("A connector with id " + connectorId + " is already registered!"); } else { getLogger().warning( "An already registered connector was registered again: " + connector.getClass().getSimpleName() + " (" + connectorId + ")"); } } /** * Unregister the given connector. * ** The lookup method {@link #getConnector(String)} only returns registered * connectors. *
* * @param connector * The connector to unregister */ public void unregisterConnector(ClientConnector connector) { String connectorId = connector.getConnectorId(); if (!connectorIdToConnector.containsKey(connectorId)) { getLogger().warning( "Tried to unregister " + connector.getClass().getSimpleName() + " (" + connectorId + ") which is not registered"); return; } if (connectorIdToConnector.get(connectorId) != connector) { throw new RuntimeException("The given connector with id " + connectorId + " is not the one that was registered for that id"); } getLogger().fine( "Unregistered " + connector.getClass().getSimpleName() + " (" + connectorId + ")"); connectorIdToConnector.remove(connectorId); uninitializedConnectors.remove(connector); diffStates.remove(connector); } /** * Checks whether the given connector has already been initialized in the * browser. The given connector should be registered with this connector * tracker. * * @param connector * the client connector to check * @returntrue
if the initial state has previously been sent
* to the browser, false
if the client-side doesn't
* already know anything about the connector.
*/
public boolean isClientSideInitialized(ClientConnector connector) {
assert connectorIdToConnector.get(connector.getConnectorId()) == connector : "Connector should be registered with this ConnectorTracker";
return !uninitializedConnectors.contains(connector);
}
/**
* Marks the given connector as initialized, meaning that the client-side
* state has been initialized for the connector.
*
* @see #isClientSideInitialized(ClientConnector)
*
* @param connector
* the connector that should be marked as initialized
*/
public void markClientSideInitialized(ClientConnector connector) {
uninitializedConnectors.remove(connector);
}
/**
* Marks all currently registered connectors as uninitialized. This should
* be done when the client-side has been reset but the server-side state is
* retained.
*
* @see #isClientSideInitialized(ClientConnector)
*/
public void markAllClientSidesUninitialized() {
uninitializedConnectors.addAll(connectorIdToConnector.values());
diffStates.clear();
}
/**
* Gets a connector by its id.
*
* @param connectorId
* The connector id to look for
* @return The connector with the given id or null if no connector has the
* given id
*/
public ClientConnector getConnector(String connectorId) {
return connectorIdToConnector.get(connectorId);
}
/**
* Cleans the connector map from all connectors that are no longer attached
* to the application. This should only be called by the framework.
*/
public void cleanConnectorMap() {
// remove detached components from paintableIdMap so they
// can be GC'ed
Iterator* The state and pending RPC calls for dirty connectors are sent to the * client in the following request. *
* * @return A collection of all dirty connectors for this root. This list may * contain invisible connectors. */ public Collection