@@ -68,6 +68,7 @@ import com.vaadin.external.json.JSONException; | |||
import com.vaadin.external.json.JSONObject; | |||
import com.vaadin.shared.ApplicationConstants; | |||
import com.vaadin.shared.Connector; | |||
import com.vaadin.shared.JavaScriptConnectorState; | |||
import com.vaadin.shared.Version; | |||
import com.vaadin.shared.communication.LegacyChangeVariablesInvocation; | |||
import com.vaadin.shared.communication.MethodInvocation; | |||
@@ -885,23 +886,36 @@ public abstract class AbstractCommunicationManager implements Serializable { | |||
try { | |||
Class<? extends SharedState> stateType = connector | |||
.getStateType(); | |||
SharedState referenceState = null; | |||
if (repaintAll) { | |||
Object diffState = rootConnectorTracker | |||
.getDiffState(connector); | |||
if (diffState == null) { | |||
diffState = new JSONObject(); | |||
// Use an empty state object as reference for full | |||
// repaints | |||
try { | |||
referenceState = stateType.newInstance(); | |||
} catch (Exception e) { | |||
getLogger().log( | |||
Level.WARNING, | |||
"Error creating reference object for state of type " | |||
+ stateType.getName()); | |||
boolean emptyInitialState = JavaScriptConnectorState.class | |||
.isAssignableFrom(stateType); | |||
if (!emptyInitialState) { | |||
try { | |||
SharedState referenceState = stateType | |||
.newInstance(); | |||
diffState = JsonCodec.encode(referenceState, | |||
null, stateType, | |||
root.getConnectorTracker()); | |||
} catch (Exception e) { | |||
getLogger().log( | |||
Level.WARNING, | |||
"Error creating reference object for state of type " | |||
+ stateType.getName()); | |||
} | |||
} | |||
rootConnectorTracker.setDiffState(connector, diffState); | |||
} | |||
Object stateJson = JsonCodec.encode(state, referenceState, | |||
stateType, root.getConnectorTracker()); | |||
JSONObject stateJson = (JSONObject) JsonCodec.encode(state, | |||
diffState, stateType, root.getConnectorTracker()); | |||
sharedStates.put(connector.getConnectorId(), stateJson); | |||
if (stateJson.length() != 0) { | |||
sharedStates.put(connector.getConnectorId(), stateJson); | |||
} | |||
} catch (JSONException e) { | |||
throw new PaintException( | |||
"Failed to serialize shared state for connector " |
@@ -526,9 +526,8 @@ public class JsonCodec implements Serializable { | |||
} | |||
} | |||
public static Object encode(Object value, Object referenceValue, | |||
Type valueType, ConnectorTracker connectorTracker) | |||
throws JSONException { | |||
public static Object encode(Object value, Object diffState, Type valueType, | |||
ConnectorTracker connectorTracker) throws JSONException { | |||
if (valueType == null) { | |||
throw new IllegalArgumentException("type must be defined"); | |||
@@ -595,7 +594,7 @@ public class JsonCodec implements Serializable { | |||
} else { | |||
// Any object that we do not know how to encode we encode by looping | |||
// through fields | |||
return encodeObject(value, referenceValue, connectorTracker); | |||
return encodeObject(value, (JSONObject) diffState, connectorTracker); | |||
} | |||
} | |||
@@ -603,7 +602,7 @@ public class JsonCodec implements Serializable { | |||
return JSONObject.NULL; | |||
} | |||
private static Object encodeObject(Object value, Object referenceValue, | |||
private static Object encodeObject(Object value, JSONObject diffState, | |||
ConnectorTracker connectorTracker) throws JSONException { | |||
JSONObject jsonMap = new JSONObject(); | |||
@@ -620,10 +619,11 @@ public class JsonCodec implements Serializable { | |||
Type fieldType = getterMethod.getGenericReturnType(); | |||
Object fieldValue = getterMethod.invoke(value, (Object[]) null); | |||
boolean equals = false; | |||
Object referenceFieldValue = null; | |||
if (referenceValue != null) { | |||
referenceFieldValue = getterMethod.invoke(referenceValue, | |||
(Object[]) null); | |||
Object diffStateValue = null; | |||
if (diffState != null) { | |||
diffStateValue = diffState.get(fieldName); | |||
Object referenceFieldValue = decodeInternalOrCustomType( | |||
fieldType, diffStateValue, connectorTracker); | |||
equals = equals(fieldValue, referenceFieldValue); | |||
} | |||
if (!equals) { | |||
@@ -637,8 +637,15 @@ public class JsonCodec implements Serializable { | |||
} | |||
jsonMap.put( | |||
fieldName, | |||
encode(fieldValue, referenceFieldValue, fieldType, | |||
encode(fieldValue, diffStateValue, fieldType, | |||
connectorTracker)); | |||
if (diffState != null) { | |||
diffState.put( | |||
fieldName, | |||
encode(fieldValue, null, fieldType, | |||
connectorTracker)); | |||
} | |||
// } else { | |||
// System.out.println("Skipping field " + fieldName | |||
// + " of type " + fieldType.getName() |
@@ -20,6 +20,7 @@ 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; | |||
@@ -54,6 +55,7 @@ public class ConnectorTracker implements Serializable { | |||
private Set<ClientConnector> uninitializedConnectors = new HashSet<ClientConnector>(); | |||
private Root root; | |||
private Map<ClientConnector, Object> diffStates = new HashMap<ClientConnector, Object>(); | |||
/** | |||
* Gets a logger for this class | |||
@@ -140,6 +142,7 @@ public class ConnectorTracker implements Serializable { | |||
+ connectorId + ")"); | |||
connectorIdToConnector.remove(connectorId); | |||
uninitializedConnectors.remove(connector); | |||
diffStates.remove(connector); | |||
} | |||
/** | |||
@@ -180,6 +183,7 @@ public class ConnectorTracker implements Serializable { | |||
*/ | |||
public void markAllClientSidesUninitialized() { | |||
uninitializedConnectors.addAll(connectorIdToConnector.values()); | |||
diffStates.clear(); | |||
} | |||
/** | |||
@@ -220,6 +224,7 @@ public class ConnectorTracker implements Serializable { | |||
+ getConnectorAndParentInfo(connector) | |||
+ "). This should have been done when the connector was detached."); | |||
uninitializedConnectors.remove(connector); | |||
diffStates.remove(connector); | |||
iterator.remove(); | |||
} | |||
} | |||
@@ -372,4 +377,12 @@ public class ConnectorTracker implements Serializable { | |||
return dirtyConnectors; | |||
} | |||
public Object getDiffState(ClientConnector connector) { | |||
return diffStates.get(connector); | |||
} | |||
public void setDiffState(ClientConnector connector, Object diffState) { | |||
diffStates.put(connector, diffState); | |||
} | |||
} |