shared state and RPC callstags/7.0.0.alpha2
@@ -1197,7 +1197,8 @@ public class ApplicationConnection { | |||
states.getJavaScriptObject(connectorId)); | |||
Object state = JsonDecoder.convertValue( | |||
stateDataAndType, connectorMap); | |||
stateDataAndType, connectorMap, | |||
ApplicationConnection.this); | |||
paintable.setState((SharedState) state); | |||
} | |||
@@ -1317,7 +1318,7 @@ public class ApplicationConnection { | |||
Object[] parameters = new Object[parametersJson.size()]; | |||
for (int j = 0; j < parametersJson.size(); ++j) { | |||
parameters[j] = JsonDecoder.convertValue( | |||
(JSONArray) parametersJson.get(j), getConnectorMap()); | |||
(JSONArray) parametersJson.get(j), getConnectorMap(), this); | |||
} | |||
return new MethodInvocation(connectorId, interfaceName, methodName, | |||
parameters); | |||
@@ -1438,7 +1439,8 @@ public class ApplicationConnection { | |||
for (int i = 0; i < invocation.getParameters().length; ++i) { | |||
// TODO non-static encoder? type registration? | |||
paramJson.set(i, JsonEncoder.encode( | |||
invocation.getParameters()[i], getConnectorMap())); | |||
invocation.getParameters()[i], getConnectorMap(), | |||
this)); | |||
} | |||
invocationJson.set(3, paramJson); | |||
reqJson.set(reqJson.size(), invocationJson); |
@@ -5,6 +5,7 @@ | |||
package com.vaadin.terminal.gwt.client; | |||
import com.vaadin.terminal.gwt.client.communication.SharedState; | |||
import com.vaadin.terminal.gwt.client.communication.URLReference; | |||
import com.vaadin.ui.Component; | |||
/** | |||
@@ -26,6 +27,7 @@ public class ComponentState extends SharedState { | |||
// string! | |||
private String caption = null; | |||
private boolean visible = true; | |||
private URLReference icon = null; | |||
/** | |||
* Returns the component height as set by the server. | |||
@@ -288,4 +290,12 @@ public class ComponentState extends SharedState { | |||
this.visible = visible; | |||
} | |||
public URLReference getIcon() { | |||
return icon; | |||
} | |||
public void setIcon(URLReference icon) { | |||
this.icon = icon; | |||
} | |||
} |
@@ -118,8 +118,7 @@ public class VCaption extends HTML { | |||
} | |||
setStyleName(style); | |||
boolean hasIcon = uidl | |||
.hasAttribute(AbstractComponentConnector.ATTRIBUTE_ICON); | |||
boolean hasIcon = owner.getState().getIcon() != null; | |||
boolean showRequired = uidl | |||
.getBooleanAttribute(AbstractComponentConnector.ATTRIBUTE_REQUIRED); | |||
boolean showError = uidl | |||
@@ -138,8 +137,7 @@ public class VCaption extends HTML { | |||
// Icon forces the caption to be above the component | |||
placedAfterComponent = false; | |||
icon.setUri(uidl | |||
.getStringAttribute(AbstractComponentConnector.ATTRIBUTE_ICON)); | |||
icon.setUri(owner.getState().getIcon().getURL()); | |||
} else if (icon != null) { | |||
// Remove existing | |||
@@ -257,7 +255,7 @@ public class VCaption extends HTML { | |||
@Deprecated | |||
public boolean updateCaptionWithoutOwner(UIDL uidl, String caption, | |||
boolean disabled, boolean hasDescription) { | |||
boolean disabled, boolean hasDescription, String iconURL) { | |||
// TODO temporary method, needed because some tabsheet and accordion | |||
// internal captions do not have an owner or shared state. Simplified to | |||
// only support those cases | |||
@@ -281,8 +279,7 @@ public class VCaption extends HTML { | |||
removeStyleDependentName("hasdescription"); | |||
} | |||
} | |||
boolean hasIcon = uidl | |||
.hasAttribute(AbstractComponentConnector.ATTRIBUTE_ICON); | |||
boolean hasIcon = iconURL != null; | |||
boolean showError = uidl | |||
.hasAttribute(AbstractComponentConnector.ATTRIBUTE_ERROR) | |||
&& !uidl.getBooleanAttribute(AbstractComponentConnector.ATTRIBUTE_HIDEERRORS); | |||
@@ -299,8 +296,7 @@ public class VCaption extends HTML { | |||
// Icon forces the caption to be above the component | |||
placedAfterComponent = false; | |||
icon.setUri(uidl | |||
.getStringAttribute(AbstractComponentConnector.ATTRIBUTE_ICON)); | |||
icon.setUri(iconURL); | |||
} else if (icon != null) { | |||
// Remove existing | |||
@@ -412,7 +408,7 @@ public class VCaption extends HTML { | |||
if (uidl.hasAttribute(AbstractComponentConnector.ATTRIBUTE_ERROR)) { | |||
return true; | |||
} | |||
if (uidl.hasAttribute(AbstractComponentConnector.ATTRIBUTE_ICON)) { | |||
if (state.getIcon() != null) { | |||
return true; | |||
} | |||
if (uidl.hasAttribute(AbstractComponentConnector.ATTRIBUTE_REQUIRED)) { |
@@ -5,6 +5,7 @@ | |||
package com.vaadin.terminal.gwt.client.communication; | |||
import com.google.gwt.json.client.JSONObject; | |||
import com.vaadin.terminal.gwt.client.ApplicationConnection; | |||
import com.vaadin.terminal.gwt.client.ConnectorMap; | |||
import com.vaadin.terminal.gwt.server.JsonCodec; | |||
@@ -21,7 +22,7 @@ import com.vaadin.terminal.gwt.server.JsonCodec; | |||
* | |||
* @since 7.0 | |||
*/ | |||
public interface JSONSerializer { | |||
public interface JSONSerializer<T> { | |||
/** | |||
* Creates and deserializes an object received from the server. Must be | |||
@@ -37,7 +38,8 @@ public interface JSONSerializer { | |||
* references to paintables | |||
* @return A deserialized object | |||
*/ | |||
Object deserialize(JSONObject jsonValue, ConnectorMap idMapper); | |||
T deserialize(JSONObject jsonValue, ConnectorMap idMapper, | |||
ApplicationConnection connection); | |||
/** | |||
* Serialize the given object into JSON. Must be compatible with | |||
@@ -52,6 +54,7 @@ public interface JSONSerializer { | |||
* references to paintables | |||
* @return A JSON serialized version of the object | |||
*/ | |||
JSONObject serialize(Object value, ConnectorMap idMapper); | |||
JSONObject serialize(T value, ConnectorMap idMapper, | |||
ApplicationConnection connection); | |||
} |
@@ -14,6 +14,7 @@ import com.google.gwt.core.client.GWT; | |||
import com.google.gwt.json.client.JSONArray; | |||
import com.google.gwt.json.client.JSONObject; | |||
import com.google.gwt.json.client.JSONString; | |||
import com.vaadin.terminal.gwt.client.ApplicationConnection; | |||
import com.vaadin.terminal.gwt.client.Connector; | |||
import com.vaadin.terminal.gwt.client.ConnectorMap; | |||
@@ -39,23 +40,26 @@ public class JsonDecoder { | |||
* JSON array with two elements | |||
* @param idMapper | |||
* mapper between connector ID and {@link Connector} objects | |||
* @param connection | |||
* reference to the current ApplicationConnection | |||
* @return converted value (does not contain JSON types) | |||
*/ | |||
public static Object convertValue(JSONArray jsonArray, ConnectorMap idMapper) { | |||
public static Object convertValue(JSONArray jsonArray, | |||
ConnectorMap idMapper, ApplicationConnection connection) { | |||
String type = ((JSONString) jsonArray.get(0)).stringValue(); | |||
return convertValue(type, jsonArray.get(1), idMapper); | |||
return convertValue(type, jsonArray.get(1), idMapper, connection); | |||
} | |||
private static Object convertValue(String variableType, Object value, | |||
ConnectorMap idMapper) { | |||
ConnectorMap idMapper, ApplicationConnection connection) { | |||
Object val = null; | |||
// TODO type checks etc. | |||
if (JsonEncoder.VTYPE_UNDEFINED.equals(variableType)) { | |||
val = null; | |||
} else if (JsonEncoder.VTYPE_ARRAY.equals(variableType)) { | |||
val = convertArray((JSONArray) value, idMapper); | |||
val = convertArray((JSONArray) value, idMapper, connection); | |||
} else if (JsonEncoder.VTYPE_MAP.equals(variableType)) { | |||
val = convertMap((JSONObject) value, idMapper); | |||
val = convertMap((JSONObject) value, idMapper, connection); | |||
} else if (JsonEncoder.VTYPE_STRINGARRAY.equals(variableType)) { | |||
val = convertStringArray((JSONArray) value); | |||
} else if (JsonEncoder.VTYPE_STRING.equals(variableType)) { | |||
@@ -83,8 +87,8 @@ public class JsonDecoder { | |||
JSONSerializer serializer = serializerMap | |||
.getSerializer(variableType); | |||
// TODO handle case with no serializer found | |||
Object object = serializer | |||
.deserialize((JSONObject) value, idMapper); | |||
Object object = serializer.deserialize((JSONObject) value, | |||
idMapper, connection); | |||
return object; | |||
} | |||
@@ -92,12 +96,14 @@ public class JsonDecoder { | |||
} | |||
private static Map<String, Object> convertMap(JSONObject jsonMap, | |||
ConnectorMap idMapper) { | |||
ConnectorMap idMapper, ApplicationConnection connection) { | |||
HashMap<String, Object> map = new HashMap<String, Object>(); | |||
Iterator<String> it = jsonMap.keySet().iterator(); | |||
while (it.hasNext()) { | |||
String key = it.next(); | |||
map.put(key, convertValue((JSONArray) jsonMap.get(key), idMapper)); | |||
map.put(key, | |||
convertValue((JSONArray) jsonMap.get(key), idMapper, | |||
connection)); | |||
} | |||
return map; | |||
} | |||
@@ -112,12 +118,12 @@ public class JsonDecoder { | |||
} | |||
private static Object[] convertArray(JSONArray jsonArray, | |||
ConnectorMap idMapper) { | |||
ConnectorMap idMapper, ApplicationConnection connection) { | |||
List<Object> tokens = new ArrayList<Object>(); | |||
for (int i = 0; i < jsonArray.size(); ++i) { | |||
// each entry always has two elements: type and value | |||
JSONArray entryArray = (JSONArray) jsonArray.get(i); | |||
tokens.add(convertValue(entryArray, idMapper)); | |||
tokens.add(convertValue(entryArray, idMapper, connection)); | |||
} | |||
return tokens.toArray(new Object[tokens.size()]); | |||
} |
@@ -12,6 +12,7 @@ import com.google.gwt.json.client.JSONNull; | |||
import com.google.gwt.json.client.JSONObject; | |||
import com.google.gwt.json.client.JSONString; | |||
import com.google.gwt.json.client.JSONValue; | |||
import com.vaadin.terminal.gwt.client.ApplicationConnection; | |||
import com.vaadin.terminal.gwt.client.Connector; | |||
import com.vaadin.terminal.gwt.client.ConnectorMap; | |||
@@ -52,9 +53,11 @@ public class JsonEncoder { | |||
* value to convert | |||
* @param connectorMap | |||
* mapper from connectors to connector IDs | |||
* @param connection | |||
* @return JSON representation of the value | |||
*/ | |||
public static JSONValue encode(Object value, ConnectorMap connectorMap) { | |||
public static JSONValue encode(Object value, ConnectorMap connectorMap, | |||
ApplicationConnection connection) { | |||
if (null == value) { | |||
// TODO as undefined type? | |||
return combineTypeAndValue(VTYPE_UNDEFINED, JSONNull.getInstance()); | |||
@@ -76,7 +79,7 @@ public class JsonEncoder { | |||
JSONArray jsonArray = new JSONArray(); | |||
for (int i = 0; i < array.length; ++i) { | |||
// TODO handle object graph loops? | |||
jsonArray.set(i, encode(array[i], connectorMap)); | |||
jsonArray.set(i, encode(array[i], connectorMap, connection)); | |||
} | |||
return combineTypeAndValue(VTYPE_ARRAY, jsonArray); | |||
} else if (value instanceof Map) { | |||
@@ -85,7 +88,7 @@ public class JsonEncoder { | |||
for (String mapKey : map.keySet()) { | |||
// TODO handle object graph loops? | |||
Object mapValue = map.get(mapKey); | |||
jsonMap.put(mapKey, encode(mapValue, connectorMap)); | |||
jsonMap.put(mapKey, encode(mapValue, connectorMap, connection)); | |||
} | |||
return combineTypeAndValue(VTYPE_MAP, jsonMap); | |||
} else if (value instanceof Connector) { | |||
@@ -105,7 +108,7 @@ public class JsonEncoder { | |||
// TODO handle case with no serializer found | |||
return combineTypeAndValue(type, | |||
serializer.serialize(value, connectorMap)); | |||
serializer.serialize(value, connectorMap, connection)); | |||
} | |||
} | |||
} |
@@ -0,0 +1,47 @@ | |||
package com.vaadin.terminal.gwt.client.communication; | |||
import com.vaadin.Application; | |||
import com.vaadin.terminal.ApplicationResource; | |||
import com.vaadin.terminal.ExternalResource; | |||
import com.vaadin.terminal.Resource; | |||
import com.vaadin.terminal.ThemeResource; | |||
public class ResourceReference extends URLReference { | |||
private Resource resource; | |||
public ResourceReference(Resource resource) { | |||
this.resource = resource; | |||
} | |||
public Resource getResource() { | |||
return resource; | |||
} | |||
@Override | |||
public String getURL() { | |||
if (resource instanceof ExternalResource) { | |||
return ((ExternalResource) resource).getURL(); | |||
} else if (resource instanceof ApplicationResource) { | |||
final ApplicationResource r = (ApplicationResource) resource; | |||
final Application a = r.getApplication(); | |||
if (a == null) { | |||
throw new RuntimeException( | |||
"An ApplicationResource (" | |||
+ r.getClass().getName() | |||
+ " must be attached to an application when it is sent to the client."); | |||
} | |||
final String uri = a.getRelativeLocation(r); | |||
return uri; | |||
} else if (resource instanceof ThemeResource) { | |||
final String uri = "theme://" | |||
+ ((ThemeResource) resource).getResourceId(); | |||
return uri; | |||
} else { | |||
throw new RuntimeException(getClass().getSimpleName() | |||
+ " does not support resources of type: " | |||
+ resource.getClass().getName()); | |||
} | |||
} | |||
} |
@@ -0,0 +1,26 @@ | |||
package com.vaadin.terminal.gwt.client.communication; | |||
public class URLReference { | |||
private String URL; | |||
/** | |||
* Returns the URL that this object refers to. | |||
* <p> | |||
* Note that the URL can use special protocols like theme:// | |||
* | |||
* @return The URL for this reference or null if unknown. | |||
*/ | |||
public String getURL() { | |||
return URL; | |||
} | |||
/** | |||
* Sets the URL that this object refers to | |||
* | |||
* @param URL | |||
*/ | |||
public void setURL(String URL) { | |||
this.URL = URL; | |||
} | |||
} |
@@ -0,0 +1,29 @@ | |||
package com.vaadin.terminal.gwt.client.communication; | |||
import com.google.gwt.core.client.GWT; | |||
import com.google.gwt.json.client.JSONArray; | |||
import com.google.gwt.json.client.JSONObject; | |||
import com.vaadin.terminal.gwt.client.ApplicationConnection; | |||
import com.vaadin.terminal.gwt.client.ConnectorMap; | |||
public class URLReference_Serializer implements JSONSerializer<URLReference> { | |||
public URLReference deserialize(JSONObject jsonValue, | |||
ConnectorMap idMapper, ApplicationConnection connection) { | |||
URLReference reference = GWT.create(URLReference.class); | |||
JSONArray jsonURL = (JSONArray) jsonValue.get("URL"); | |||
String URL = (String) JsonDecoder.convertValue(jsonURL, idMapper, | |||
connection); | |||
reference.setURL(connection.translateVaadinUri(URL)); | |||
return reference; | |||
} | |||
public JSONObject serialize(URLReference value, ConnectorMap idMapper, | |||
ApplicationConnection connection) { | |||
JSONObject json = new JSONObject(); | |||
json.put("URL", | |||
JsonEncoder.encode(value.getURL(), idMapper, connection)); | |||
return json; | |||
} | |||
} |
@@ -33,7 +33,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector | |||
// constants, which may refer to these. | |||
// Not all references to the string literals have been converted to use | |||
// these! | |||
public static final String ATTRIBUTE_ICON = "icon"; | |||
public static final String ATTRIBUTE_REQUIRED = "required"; | |||
public static final String ATTRIBUTE_ERROR = "error"; | |||
public static final String ATTRIBUTE_HIDEERRORS = "hideErrors"; |
@@ -88,13 +88,13 @@ public class ButtonConnector extends AbstractComponentConnector { | |||
getWidget().errorIndicatorElement = null; | |||
} | |||
if (uidl.hasAttribute(ATTRIBUTE_ICON)) { | |||
if (getState().getIcon() != null) { | |||
if (getWidget().icon == null) { | |||
getWidget().icon = new Icon(client); | |||
getWidget().wrapper.insertBefore(getWidget().icon.getElement(), | |||
getWidget().captionElement); | |||
} | |||
getWidget().icon.setUri(uidl.getStringAttribute(ATTRIBUTE_ICON)); | |||
getWidget().icon.setUri(getState().getIcon().getURL()); | |||
} else { | |||
if (getWidget().icon != null) { | |||
getWidget().wrapper.removeChild(getWidget().icon.getElement()); |
@@ -59,7 +59,7 @@ public class CheckBoxConnector extends AbstractComponentConnector { | |||
getWidget().setEnabled(false); | |||
} | |||
if (uidl.hasAttribute(ATTRIBUTE_ICON)) { | |||
if (getState().getIcon() != null) { | |||
if (getWidget().icon == null) { | |||
getWidget().icon = new Icon(client); | |||
DOM.insertChild(getWidget().getElement(), | |||
@@ -67,7 +67,7 @@ public class CheckBoxConnector extends AbstractComponentConnector { | |||
getWidget().icon.sinkEvents(VTooltip.TOOLTIP_EVENTS); | |||
getWidget().icon.sinkEvents(Event.ONCLICK); | |||
} | |||
getWidget().icon.setUri(uidl.getStringAttribute(ATTRIBUTE_ICON)); | |||
getWidget().icon.setUri(getState().getIcon().getURL()); | |||
} else if (getWidget().icon != null) { | |||
// detach icon | |||
DOM.removeChild(getWidget().getElement(), |
@@ -43,12 +43,12 @@ public class FormConnector extends AbstractComponentContainerConnector | |||
} else { | |||
getWidget().caption.setInnerText(""); | |||
} | |||
if (uidl.hasAttribute(ATTRIBUTE_ICON)) { | |||
if (getState().getIcon() != null) { | |||
if (getWidget().icon == null) { | |||
getWidget().icon = new Icon(client); | |||
getWidget().legend.insertFirst(getWidget().icon.getElement()); | |||
} | |||
getWidget().icon.setUri(uidl.getStringAttribute(ATTRIBUTE_ICON)); | |||
getWidget().icon.setUri(getState().getIcon().getURL()); | |||
legendEmpty = false; | |||
} else { | |||
if (getWidget().icon != null) { |
@@ -74,13 +74,13 @@ public class LinkConnector extends AbstractComponentConnector { | |||
"none"); | |||
} | |||
if (uidl.hasAttribute(ATTRIBUTE_ICON)) { | |||
if (getState().getIcon() != null) { | |||
if (getWidget().icon == null) { | |||
getWidget().icon = new Icon(client); | |||
getWidget().anchor.insertBefore(getWidget().icon.getElement(), | |||
getWidget().captionElement); | |||
} | |||
getWidget().icon.setUri(uidl.getStringAttribute(ATTRIBUTE_ICON)); | |||
getWidget().icon.setUri(getState().getIcon().getURL()); | |||
} | |||
} |
@@ -18,8 +18,7 @@ public class NativeButtonConnector extends AbstractComponentConnector { | |||
public void init() { | |||
super.init(); | |||
ButtonServerRpc rpcProxy = GWT | |||
.create(ButtonServerRpc.class); | |||
ButtonServerRpc rpcProxy = GWT.create(ButtonServerRpc.class); | |||
getWidget().buttonRpcProxy = initRPC(rpcProxy); | |||
} | |||
@@ -68,14 +67,14 @@ public class NativeButtonConnector extends AbstractComponentConnector { | |||
getWidget().errorIndicatorElement = null; | |||
} | |||
if (uidl.hasAttribute(ATTRIBUTE_ICON)) { | |||
if (getState().getIcon() != null) { | |||
if (getWidget().icon == null) { | |||
getWidget().icon = new Icon(client); | |||
getWidget().getElement().insertBefore( | |||
getWidget().icon.getElement(), | |||
getWidget().captionElement); | |||
} | |||
getWidget().icon.setUri(uidl.getStringAttribute(ATTRIBUTE_ICON)); | |||
getWidget().icon.setUri(getState().getIcon().getURL()); | |||
} else { | |||
if (getWidget().icon != null) { | |||
getWidget().getElement().removeChild( |
@@ -105,7 +105,11 @@ public class PanelConnector extends AbstractComponentContainerConnector | |||
getWidget().client = client; | |||
getWidget().id = uidl.getId(); | |||
getWidget().setIconUri(uidl, client); | |||
if (getState().getIcon() != null) { | |||
getWidget().setIconUri(getState().getIcon().getURL(), client); | |||
} else { | |||
getWidget().setIconUri(null, client); | |||
} | |||
getWidget().handleError(uidl); | |||
@@ -18,6 +18,7 @@ public abstract class TabsheetBaseConnector extends | |||
public static final String ATTRIBUTE_TAB_DISABLED = "disabled"; | |||
public static final String ATTRIBUTE_TAB_DESCRIPTION = "description"; | |||
public static final String ATTRIBUTE_TAB_CAPTION = "caption"; | |||
public static final String ATTRIBUTE_TAB_ICON = "icon"; | |||
@Override | |||
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { |
@@ -16,10 +16,10 @@ public class TreeConnector extends AbstractComponentConnector { | |||
public static final String ATTRIBUTE_NODE_STYLE = "style"; | |||
public static final String ATTRIBUTE_NODE_CAPTION = "caption"; | |||
public static final String ATTRIBUTE_NODE_ICON = AbstractComponentConnector.ATTRIBUTE_ICON; | |||
public static final String ATTRIBUTE_NODE_ICON = "icon"; | |||
public static final String ATTRIBUTE_ACTION_CAPTION = "caption"; | |||
public static final String ATTRIBUTE_ACTION_ICON = AbstractComponentConnector.ATTRIBUTE_ICON; | |||
public static final String ATTRIBUTE_ACTION_ICON = ATTRIBUTE_NODE_ICON; | |||
@Override | |||
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { |
@@ -443,7 +443,8 @@ public class VAccordion extends VTabsheetBase { | |||
uidl, | |||
uidl.getStringAttribute(TabsheetBaseConnector.ATTRIBUTE_TAB_CAPTION), | |||
uidl.hasAttribute(TabsheetBaseConnector.ATTRIBUTE_TAB_DISABLED), | |||
uidl.hasAttribute(TabsheetBaseConnector.ATTRIBUTE_TAB_DESCRIPTION)); | |||
uidl.hasAttribute(TabsheetBaseConnector.ATTRIBUTE_TAB_DESCRIPTION), | |||
uidl.getStringAttribute(TabsheetBaseConnector.ATTRIBUTE_TAB_ICON)); | |||
} | |||
public int getWidgetWidth() { |
@@ -267,14 +267,13 @@ public class VFormLayout extends SimplePanel { | |||
boolean isEmpty = true; | |||
if (uidl.hasAttribute(AbstractComponentConnector.ATTRIBUTE_ICON)) { | |||
if (state.getIcon() != null) { | |||
if (icon == null) { | |||
icon = new Icon(client); | |||
DOM.insertChild(getElement(), icon.getElement(), 0); | |||
} | |||
icon.setUri(uidl | |||
.getStringAttribute(AbstractComponentConnector.ATTRIBUTE_ICON)); | |||
icon.setUri(state.getIcon().getURL()); | |||
isEmpty = false; | |||
} else { | |||
if (icon != null) { |
@@ -65,7 +65,7 @@ public class VMenuBar extends SimpleFocusablePanel implements | |||
public static final String ATTRIBUTE_CHECKED = "checked"; | |||
public static final String ATTRIBUTE_ITEM_DESCRIPTION = "description"; | |||
public static final String ATTRIBUTE_ITEM_ICON = AbstractComponentConnector.ATTRIBUTE_ICON; | |||
public static final String ATTRIBUTE_ITEM_ICON = "icon"; | |||
public static final String ATTRIBUTE_ITEM_DISABLED = "disabled"; | |||
public static final String ATTRIBUTE_ITEM_STYLE = "style"; | |||
@@ -59,7 +59,7 @@ public class VNotification extends VOverlay { | |||
public static final String ATTRIBUTE_NOTIFICATION_STYLE = "style"; | |||
public static final String ATTRIBUTE_NOTIFICATION_CAPTION = "caption"; | |||
public static final String ATTRIBUTE_NOTIFICATION_MESSAGE = "message"; | |||
public static final String ATTRIBUTE_NOTIFICATION_ICON = AbstractComponentConnector.ATTRIBUTE_ICON; | |||
public static final String ATTRIBUTE_NOTIFICATION_ICON = "icon"; | |||
public static final String ATTRIBUTE_NOTIFICATION_POSITION = "position"; | |||
public static final String ATTRIBUTE_NOTIFICATION_DELAY = "delay"; | |||
@@ -133,11 +133,7 @@ public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner, | |||
} | |||
} | |||
void setIconUri(UIDL uidl, ApplicationConnection client) { | |||
final String iconUri = uidl | |||
.hasAttribute(AbstractComponentConnector.ATTRIBUTE_ICON) ? uidl | |||
.getStringAttribute(AbstractComponentConnector.ATTRIBUTE_ICON) | |||
: null; | |||
void setIconUri(String iconUri, ApplicationConnection client) { | |||
if (iconUri == null) { | |||
if (icon != null) { | |||
DOM.removeChild(captionNode, icon.getElement()); |
@@ -266,7 +266,8 @@ public class VTabsheet extends VTabsheetBase implements Focusable, | |||
uidl, | |||
uidl.getStringAttribute(TabsheetBaseConnector.ATTRIBUTE_TAB_CAPTION), | |||
uidl.hasAttribute(TabsheetBaseConnector.ATTRIBUTE_TAB_DISABLED), | |||
uidl.hasAttribute(TabsheetBaseConnector.ATTRIBUTE_TAB_DESCRIPTION)); | |||
uidl.hasAttribute(TabsheetBaseConnector.ATTRIBUTE_TAB_DESCRIPTION), | |||
uidl.getStringAttribute(TabsheetBaseConnector.ATTRIBUTE_TAB_ICON)); | |||
setClosable(uidl.hasAttribute("closable")); | |||
@@ -86,10 +86,11 @@ public class WindowConnector extends AbstractComponentContainerConnector | |||
// Caption must be set before required header size is measured. If | |||
// the caption attribute is missing the caption should be cleared. | |||
getWidget() | |||
.setCaption( | |||
getState().getCaption(), | |||
uidl.getStringAttribute(AbstractComponentConnector.ATTRIBUTE_ICON)); | |||
String iconURL = null; | |||
if (getState().getIcon() != null) { | |||
iconURL = getState().getIcon().getURL(); | |||
} | |||
getWidget().setCaption(getState().getCaption(), iconURL); | |||
} | |||
getWidget().visibilityChangesDisabled = true; |
@@ -153,6 +153,12 @@ public class JsonCodec implements Serializable { | |||
*/ | |||
public static JSONArray encode(Object value, PaintableIdMapper idMapper) | |||
throws JSONException { | |||
return encode(value, null, idMapper); | |||
} | |||
public static JSONArray encode(Object value, Class<?> valueType, | |||
PaintableIdMapper idMapper) throws JSONException { | |||
if (null == value) { | |||
// TODO as undefined type? | |||
return combineTypeAndValue(JsonEncoder.VTYPE_UNDEFINED, | |||
@@ -188,7 +194,11 @@ public class JsonCodec implements Serializable { | |||
} else { | |||
// Any object that we do not know how to encode we encode by looping | |||
// through fields | |||
return combineTypeAndValue(value.getClass().getCanonicalName(), | |||
if (valueType == null) { | |||
valueType = value.getClass(); | |||
} | |||
return combineTypeAndValue(valueType.getCanonicalName(), | |||
encodeObject(value, idMapper)); | |||
} | |||
} | |||
@@ -201,12 +211,13 @@ public class JsonCodec implements Serializable { | |||
for (PropertyDescriptor pd : Introspector.getBeanInfo( | |||
value.getClass()).getPropertyDescriptors()) { | |||
String fieldName = pd.getName(); | |||
Class<?> fieldType = pd.getPropertyType(); | |||
if (pd.getReadMethod() == null || pd.getWriteMethod() == null) { | |||
continue; | |||
} | |||
Method getterMethod = pd.getReadMethod(); | |||
Object fieldValue = getterMethod.invoke(value, null); | |||
jsonMap.put(fieldName, encode(fieldValue, idMapper)); | |||
jsonMap.put(fieldName, encode(fieldValue, fieldType, idMapper)); | |||
} | |||
} catch (Exception e) { | |||
// TODO: Should exceptions be handled in a different way? |
@@ -24,11 +24,12 @@ import com.google.gwt.json.client.JSONArray; | |||
import com.google.gwt.json.client.JSONObject; | |||
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; | |||
import com.google.gwt.user.rebind.SourceWriter; | |||
import com.vaadin.terminal.gwt.client.ApplicationConnection; | |||
import com.vaadin.terminal.gwt.client.ConnectorMap; | |||
import com.vaadin.terminal.gwt.client.communication.JSONSerializer; | |||
import com.vaadin.terminal.gwt.client.communication.JsonDecoder; | |||
import com.vaadin.terminal.gwt.client.communication.JsonEncoder; | |||
import com.vaadin.terminal.gwt.client.communication.SerializerMap; | |||
import com.vaadin.terminal.gwt.client.communication.JSONSerializer; | |||
/** | |||
* GWT generator for creating serializer classes for custom classes sent from | |||
@@ -113,10 +114,12 @@ public class SerializerGenerator extends Generator { | |||
// Serializer | |||
// public JSONValue serialize(Object value, ConnectorMap idMapper) { | |||
// public JSONValue serialize(Object value, ConnectorMap idMapper, | |||
// ApplicationConnection connection) { | |||
sourceWriter.println("public " + JSONObject.class.getName() | |||
+ " serialize(" + Object.class.getName() + " value, " | |||
+ ConnectorMap.class.getName() + " idMapper) {"); | |||
+ ConnectorMap.class.getName() + " idMapper, " | |||
+ ApplicationConnection.class.getName() + " connection) {"); | |||
sourceWriter.indent(); | |||
// MouseEventDetails castedValue = (MouseEventDetails) value; | |||
sourceWriter.println(beanQualifiedSourceName + " castedValue = (" | |||
@@ -136,10 +139,11 @@ public class SerializerGenerator extends Generator { | |||
+ ". Serialization will likely fail"); | |||
} | |||
// json.put("button", | |||
// JsonEncoder.encode(castedValue.getButton(), idMapper)); | |||
// JsonEncoder.encode(castedValue.getButton(), idMapper, | |||
// connection)); | |||
sourceWriter.println("json.put(\"" + fieldName + "\", " | |||
+ JsonEncoder.class.getName() + ".encode(castedValue." | |||
+ getterName + "(), idMapper));"); | |||
+ getterName + "(), idMapper, connection));"); | |||
} | |||
// return json; | |||
sourceWriter.println("return json;"); | |||
@@ -149,7 +153,8 @@ public class SerializerGenerator extends Generator { | |||
// Deserializer | |||
sourceWriter.println("public " + beanQualifiedSourceName | |||
+ " deserialize(" + JSONObject.class.getName() + " jsonValue, " | |||
+ ConnectorMap.class.getName() + " idMapper) {"); | |||
+ ConnectorMap.class.getName() + " idMapper, " | |||
+ ApplicationConnection.class.getName() + " connection) {"); | |||
sourceWriter.indent(); | |||
// VButtonState state = GWT.create(VButtonState.class); | |||
@@ -170,7 +175,7 @@ public class SerializerGenerator extends Generator { | |||
+ " = (JSONArray) jsonValue.get(\"" + fieldName + "\");"); | |||
// state.setHeight((String) | |||
// JsonDecoder.convertValue(jsonFieldValue,idMapper)); | |||
// JsonDecoder.convertValue(jsonFieldValue,idMapper, connection)); | |||
String fieldType; | |||
JPrimitiveType primitiveType = setterParameterType.isPrimitive(); | |||
@@ -183,7 +188,7 @@ public class SerializerGenerator extends Generator { | |||
sourceWriter.println("state." + setterName + "((" + fieldType | |||
+ ") JsonDecoder.convertValue(" + jsonFieldName | |||
+ ", idMapper));"); | |||
+ ", idMapper, connection));"); | |||
} | |||
// return state; |
@@ -19,13 +19,16 @@ import com.google.gwt.core.ext.typeinfo.JClassType; | |||
import com.google.gwt.core.ext.typeinfo.JMethod; | |||
import com.google.gwt.core.ext.typeinfo.JType; | |||
import com.google.gwt.core.ext.typeinfo.TypeOracle; | |||
import com.google.gwt.json.client.JSONObject; | |||
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; | |||
import com.google.gwt.user.rebind.SourceWriter; | |||
import com.vaadin.terminal.gwt.client.ApplicationConnection; | |||
import com.vaadin.terminal.gwt.client.ConnectorMap; | |||
import com.vaadin.terminal.gwt.client.communication.ClientRpc; | |||
import com.vaadin.terminal.gwt.client.communication.JSONSerializer; | |||
import com.vaadin.terminal.gwt.client.communication.SerializerMap; | |||
import com.vaadin.terminal.gwt.client.communication.ServerRpc; | |||
import com.vaadin.terminal.gwt.client.communication.SharedState; | |||
import com.vaadin.terminal.gwt.client.communication.JSONSerializer; | |||
/** | |||
* GWT generator that creates a {@link SerializerMap} implementation (mapper | |||
@@ -47,13 +50,17 @@ public class SerializerMapGenerator extends Generator { | |||
TypeOracle typeOracle = context.getTypeOracle(); | |||
Set<JClassType> typesNeedingSerializers = findTypesNeedingSerializers( | |||
typeOracle, logger); | |||
Set<JClassType> typesWithExistingSerializers = findTypesWithExistingSerializers( | |||
typeOracle, logger); | |||
Set<JClassType> serializerMappings = new HashSet<JClassType>(); | |||
serializerMappings.addAll(typesNeedingSerializers); | |||
serializerMappings.addAll(typesWithExistingSerializers); | |||
// get classType and save instance variables | |||
JClassType classType = typeOracle.getType(typeName); | |||
packageName = classType.getPackage().getName(); | |||
className = classType.getSimpleSourceName() + "Impl"; | |||
// Generate class source code for SerializerMapImpl | |||
generateSerializerMap(typesNeedingSerializers, logger, context); | |||
generateSerializerMap(serializerMappings, logger, context); | |||
SerializerGenerator sg = new SerializerGenerator(); | |||
for (JClassType type : typesNeedingSerializers) { | |||
@@ -67,6 +74,27 @@ public class SerializerMapGenerator extends Generator { | |||
return packageName + "." + className; | |||
} | |||
private Set<JClassType> findTypesWithExistingSerializers( | |||
TypeOracle typeOracle, TreeLogger logger) { | |||
JClassType serializerInterface = typeOracle | |||
.findType(JSONSerializer.class.getName()); | |||
Set<JClassType> types = new HashSet<JClassType>(); | |||
for (JClassType serializer : serializerInterface.getSubtypes()) { | |||
JType[] deserializeParamTypes = new JType[] { | |||
typeOracle.findType(JSONObject.class.getName()), | |||
typeOracle.findType(ConnectorMap.class.getName()), | |||
typeOracle.findType(ApplicationConnection.class.getName()) }; | |||
JMethod deserializeMethod = serializer.findMethod("deserialize", | |||
deserializeParamTypes); | |||
if (deserializeMethod == null) { | |||
continue; | |||
} | |||
types.add(deserializeMethod.getReturnType().isClass()); | |||
} | |||
return types; | |||
} | |||
/** | |||
* Generate source code for SerializerMapImpl | |||
* |
@@ -35,7 +35,7 @@ import com.vaadin.terminal.Resource; | |||
import com.vaadin.terminal.Terminal; | |||
import com.vaadin.terminal.gwt.client.ComponentState; | |||
import com.vaadin.terminal.gwt.client.communication.ClientRpc; | |||
import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector; | |||
import com.vaadin.terminal.gwt.client.communication.ResourceReference; | |||
import com.vaadin.terminal.gwt.server.ClientMethodInvocation; | |||
import com.vaadin.terminal.gwt.server.ComponentSizeValidator; | |||
import com.vaadin.terminal.gwt.server.RpcManager; | |||
@@ -70,11 +70,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource | |||
*/ | |||
private Object applicationData; | |||
/** | |||
* Icon to be shown together with caption. | |||
*/ | |||
private Resource icon; | |||
/** | |||
* The container this component resides in. | |||
*/ | |||
@@ -341,7 +336,7 @@ public abstract class AbstractComponent implements Component, MethodEventSource | |||
* use the default documentation from implemented interface. | |||
*/ | |||
public Resource getIcon() { | |||
return icon; | |||
return ((ResourceReference) getState().getIcon()).getResource(); | |||
} | |||
/** | |||
@@ -353,7 +348,11 @@ public abstract class AbstractComponent implements Component, MethodEventSource | |||
* the icon to be shown with the component's caption. | |||
*/ | |||
public void setIcon(Resource icon) { | |||
this.icon = icon; | |||
if (icon == null) { | |||
getState().setIcon(null); | |||
} else { | |||
getState().setIcon(new ResourceReference(icon)); | |||
} | |||
requestRepaint(); | |||
} | |||
@@ -736,15 +735,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource | |||
// Only paint content of visible components. | |||
if (isVisible()) { | |||
// width and height are only in shared state | |||
// TODO probably can remove also icon once all the VCaption | |||
// related code has been updated | |||
if (getIcon() != null) { | |||
target.addAttribute( | |||
AbstractComponentConnector.ATTRIBUTE_ICON, | |||
getIcon()); | |||
} | |||
if (eventIdentifiers != null) { | |||
target.addAttribute("eventListeners", |
@@ -25,7 +25,6 @@ import com.vaadin.terminal.KeyMapper; | |||
import com.vaadin.terminal.PaintException; | |||
import com.vaadin.terminal.PaintTarget; | |||
import com.vaadin.terminal.Resource; | |||
import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector; | |||
import com.vaadin.terminal.gwt.client.ui.TabsheetBaseConnector; | |||
import com.vaadin.terminal.gwt.client.ui.TabsheetConnector; | |||
import com.vaadin.terminal.gwt.client.ui.VTabsheet; | |||
@@ -408,7 +407,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, | |||
// VCaption.updateCaption(uidl) | |||
final Resource icon = tab.getIcon(); | |||
if (icon != null) { | |||
target.addAttribute(AbstractComponentConnector.ATTRIBUTE_ICON, | |||
target.addAttribute(TabsheetBaseConnector.ATTRIBUTE_TAB_ICON, | |||
icon); | |||
} | |||
final String caption = tab.getCaption(); |