Преглед изворни кода

Cleanup, javadoc etc. for shared state serialization (#8304).

tags/7.0.0.alpha2
Henri Sara пре 12 година
родитељ
комит
22ca8a011a

+ 48
- 9
src/com/vaadin/terminal/gwt/client/ComponentState.java Прегледај датотеку

private String height = ""; private String height = "";
private String width = ""; private String width = "";


// TODO more javadoc

/**
* Returns the component height as set by the server.
*
* Can be relative (containing the percent sign) or absolute, or empty
* string for undefined height.
*
* @return component height as defined by the server, not null
*/
public String getHeight() { public String getHeight() {
if (height == null) { if (height == null) {
return ""; return "";
return height; return height;
} }


/**
* Sets the height of the component in the server format.
*
* Can be relative (containing the percent sign) or absolute, or null or
* empty string for undefined height.
*
* @param height
* component height
*/
public void setHeight(String height) { public void setHeight(String height) {
this.height = height; this.height = height;
} }


/**
* Returns true if the component height is undefined, false if defined
* (absolute or relative).
*
* @return true if component height is undefined
*/
public boolean isUndefinedHeight() { public boolean isUndefinedHeight() {
return "".equals(getHeight()); return "".equals(getHeight());
} }


/**
* Returns the component width as set by the server.
*
* Can be relative (containing the percent sign) or absolute, or empty
* string for undefined height.
*
* @return component width as defined by the server, not null
*/
public String getWidth() { public String getWidth() {
if (width == null) { if (width == null) {
return ""; return "";
return width; return width;
} }


/**
* Sets the width of the component in the server format.
*
* Can be relative (containing the percent sign) or absolute, or null or
* empty string for undefined width.
*
* @param width
* component width
*/
public void setWidth(String width) { public void setWidth(String width) {
this.width = width; this.width = width;
} }


/**
* Returns true if the component width is undefined, false if defined
* (absolute or relative).
*
* @return true if component width is undefined
*/
public boolean isUndefinedWidth() { public boolean isUndefinedWidth() {
return "".equals(getWidth()); return "".equals(getWidth());
} }


// TODO constants for the state attributes for now
public static final String STATE_STYLE = "style";
public static final String STATE_READONLY = "readonly";
public static final String STATE_IMMEDIATE = "immediate";
public static final String STATE_DISABLED = "disabled";
public static final String STATE_CAPTION = "caption";
public static final String STATE_DESCRIPTION = "description";
// TODO more fields to move here: style, readonly, immediate, disabled,
// caption and description


} }

+ 1
- 0
src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java Прегледај датотеку

// object, class name as type // object, class name as type
VaadinSerializer serializer = serializerMap VaadinSerializer serializer = serializerMap
.getSerializer(variableType); .getSerializer(variableType);
// TODO handle case with no serializer found
Object object = serializer Object object = serializer
.deserialize((JSONObject) value, idMapper); .deserialize((JSONObject) value, idMapper);
return object; return object;

+ 27
- 0
src/com/vaadin/terminal/gwt/client/communication/SerializerMap.java Прегледај датотеку

/*
@VaadinApache2LicenseForJavaFiles@
*/
package com.vaadin.terminal.gwt.client.communication; package com.vaadin.terminal.gwt.client.communication;
import com.vaadin.terminal.gwt.widgetsetutils.SerializerMapGenerator;
/**
* Provide a mapping from a type (communicated between the server and the
* client) and a {@link VaadinSerializer} instance.
*
* An implementation of this class is created at GWT compilation time by
* {@link SerializerMapGenerator}, so this interface can be instantiated with
* GWT.create().
*
* @since 7.0
*/
public interface SerializerMap { public interface SerializerMap {
/**
* Returns a serializer instance for a given type.
*
* @param type
* type communicated on between the server and the client
* (currently fully qualified class name)
* @return serializer instance, not null
* @throws RuntimeException
* if no serializer is found
*/
// TODO better error handling in javadoc and in generator
public VaadinSerializer getSerializer(String type); public VaadinSerializer getSerializer(String type);
} }

+ 4
- 10
src/com/vaadin/terminal/gwt/client/communication/SharedState.java Прегледај датотеку



import java.io.Serializable; import java.io.Serializable;


import com.google.gwt.core.client.GWT;
import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget; import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;


/** /**
* necessary (changed or missing on the client side) parts are re-sent to the * necessary (changed or missing on the client side) parts are re-sent to the
* client, but the client will have access to the whole state. * client, but the client will have access to the whole state.
* *
* TODO the rest of the javadoc corresponds to the design that is not yet
* implemented
*
* A shared state class should be a bean with getters and setters for each * A shared state class should be a bean with getters and setters for each
* field, and should only contain simple data types, or arrays or maps of * field, and should only contain simple data types, or arrays or maps of
* supported data types. * supported data types.
* *
* On the client side, SharedState instances must be created using
* {@link GWT#create(Class)} to let a generator create custom deserialization
* support for them. For most widgets,
* {@link VAbstractPaintableWidget#createSharedState()} method should be
* overridden to create a shared state instance of the correct type using
* {@link GWT#create(Class)}.
* On the client side, for most widgets,
* {@link VAbstractPaintableWidget#createState()} and
* {@link VAbstractPaintableWidget#getState()} methods should be overridden to
* create and use a shared state instance of the correct type.
* *
* Subclasses of a paintable using shared state should also provide a subclass * Subclasses of a paintable using shared state should also provide a subclass
* of the shared state class of the parent class to extend the state - a single * of the shared state class of the parent class to extend the state - a single

+ 22
- 0
src/com/vaadin/terminal/gwt/client/communication/VaadinSerializer.java Прегледај датотеку

/*
@VaadinApache2LicenseForJavaFiles@
*/
package com.vaadin.terminal.gwt.client.communication; package com.vaadin.terminal.gwt.client.communication;
import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONObject;
import com.vaadin.terminal.gwt.client.VPaintableMap; import com.vaadin.terminal.gwt.client.VPaintableMap;
/**
* Serializer that can deserialize custom objects received from the server.
*
* Each serializer can handle objects of a single type - see
* {@link SerializerMap}.
*
* @since 7.0
*/
public interface VaadinSerializer { public interface VaadinSerializer {
/**
* Creates and deserializes an object received from the server.
*
* @param jsonValue
* JSON map from property name to property value
* @param idMapper
* mapper from paintable id to paintable, used to decode
* references to paintables
* @return deserialized object
*/
// TODO Object -> something // TODO Object -> something
Object deserialize(JSONObject jsonValue, VPaintableMap idMapper); Object deserialize(JSONObject jsonValue, VPaintableMap idMapper);

+ 29
- 0
src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java Прегледај датотеку

this.id = id; this.id = id;
} }


/**
* Returns the shared state object for a paintable widget.
*
* A new state instance is created using {@link #createState()} if none has
* been set by the server.
*
* If overriding this method to return a more specific type, also
* {@link #createState()} must be overridden.
*
* @return current shared state (not null)
*/
public ComponentState getState() { public ComponentState getState() {
if (state == null) { if (state == null) {
state = createState(); state = createState();
return state; return state;
} }


/**
* Creates a new instance of a shared state object for the widget. Normally,
* the state instance is created by the server and sent to the client before
* being used - this method is used if no shared state has been sent by the
* server.
*
* When overriding {@link #getState()}, also {@link #createState()} should
* be overridden to match it.
*
* @return newly created component shared state instance
*/
protected ComponentState createState() { protected ComponentState createState() {
return GWT.create(ComponentState.class); return GWT.create(ComponentState.class);
} }
return styleBuf.toString(); return styleBuf.toString();
} }


/**
* Sets the shared state for the paintable widget.
*
* @param new shared state (must be compatible with the return value of
* {@link #getState()} - {@link ComponentState} if
* {@link #getState()} is not overridden
*/
public final void setState(SharedState state) { public final void setState(SharedState state) {
this.state = (ComponentState) state; this.state = (ComponentState) state;
} }

+ 6
- 0
src/com/vaadin/terminal/gwt/client/ui/VButtonPaintable.java Прегледај датотеку

import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ComponentState;
import com.vaadin.terminal.gwt.client.EventHelper; import com.vaadin.terminal.gwt.client.EventHelper;
import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.UIDL;


public VButtonState getState() { public VButtonState getState() {
return (VButtonState) super.getState(); return (VButtonState) super.getState();
} }

@Override
protected ComponentState createState() {
return GWT.create(VButtonState.class);
}
} }

+ 40
- 0
src/com/vaadin/terminal/gwt/client/ui/VButtonState.java Прегледај датотеку

/*
@VaadinApache2LicenseForJavaFiles@
*/
package com.vaadin.terminal.gwt.client.ui; package com.vaadin.terminal.gwt.client.ui;
import com.vaadin.terminal.gwt.client.ComponentState; import com.vaadin.terminal.gwt.client.ComponentState;
import com.vaadin.ui.Button;
/**
* Shared state for Button and NativeButton.
*
* @see ComponentState
*
* @since 7.0
*/
public class VButtonState extends ComponentState { public class VButtonState extends ComponentState {
private boolean disableOnClick = false; private boolean disableOnClick = false;
private int clickShortcutKeyCode = 0; private int clickShortcutKeyCode = 0;
/**
* Checks whether the button should be disabled on the client side on next
* click.
*
* @return true if the button should be disabled on click
*/
public boolean isDisableOnClick() { public boolean isDisableOnClick() {
return disableOnClick; return disableOnClick;
} }
/**
* Sets whether the button should be disabled on the client side on next
* click.
*
* @param disableOnClick
* true if the button should be disabled on click
*/
public void setDisableOnClick(boolean disableOnClick) { public void setDisableOnClick(boolean disableOnClick) {
this.disableOnClick = disableOnClick; this.disableOnClick = disableOnClick;
} }
/**
* Returns the key code for activating the button via a keyboard shortcut.
*
* See {@link Button#setClickShortcut(int, int...)} for more information.
*
* @return key code or 0 for none
*/
public int getClickShortcutKeyCode() { public int getClickShortcutKeyCode() {
return clickShortcutKeyCode; return clickShortcutKeyCode;
} }
/**
* Sets the key code for activating the button via a keyboard shortcut.
*
* See {@link Button#setClickShortcut(int, int...)} for more information.
*
* @param clickShortcutKeyCode
* key code or 0 for none
*/
public void setClickShortcutKeyCode(int clickShortcutKeyCode) { public void setClickShortcutKeyCode(int clickShortcutKeyCode) {
this.clickShortcutKeyCode = clickShortcutKeyCode; this.clickShortcutKeyCode = clickShortcutKeyCode;
} }

+ 4
- 11
src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java Прегледај датотеку

if (state != null && !cached) { if (state != null && !cached) {
boolean widthDefined = !state.isUndefinedWidth(); boolean widthDefined = !state.isUndefinedWidth();
boolean heightDefined = !state.isUndefinedHeight(); boolean heightDefined = !state.isUndefinedHeight();
if (heightDefined && state.getHeight().contains("%")) {
relHeight = true;
} else {
relHeight = false;
}

relHeight = state.getHeight().contains("%");
relWidth = state.getWidth().contains("%");
if (widthDefined) { if (widthDefined) {
widthCanAffectHeight = relWidth = state.getWidth()
.contains("%");
if (heightDefined) {
widthCanAffectHeight = false;
}
widthCanAffectHeight = (relWidth && !heightDefined);
} else { } else {
widthCanAffectHeight = !heightDefined; widthCanAffectHeight = !heightDefined;
relWidth = false;
} }
} }
} }

+ 6
- 0
src/com/vaadin/terminal/gwt/client/ui/VNativeButtonPaintable.java Прегледај датотеку

import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ComponentState;
import com.vaadin.terminal.gwt.client.EventHelper; import com.vaadin.terminal.gwt.client.EventHelper;
import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.UIDL;


public VButtonState getState() { public VButtonState getState() {
return (VButtonState) super.getState(); return (VButtonState) super.getState();
} }

@Override
protected ComponentState createState() {
return GWT.create(VButtonState.class);
}
} }

+ 18
- 2
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java Прегледај датотеку

/*
@VaadinApache2LicenseForJavaFiles@
*/
package com.vaadin.terminal.gwt.widgetsetutils; package com.vaadin.terminal.gwt.widgetsetutils;
import java.io.PrintWriter; import java.io.PrintWriter;
import com.vaadin.terminal.gwt.client.communication.JsonDecoder; import com.vaadin.terminal.gwt.client.communication.JsonDecoder;
import com.vaadin.terminal.gwt.client.communication.VaadinSerializer; import com.vaadin.terminal.gwt.client.communication.VaadinSerializer;
/**
* GWT generator for creating serializer classes for custom classes sent from
* server to client.
*
* Only fields with a correspondingly named setter are deserialized.
*
* @since 7.0
*/
public class SerializerGenerator extends Generator { public class SerializerGenerator extends Generator {
private String packageName; private String packageName;
} }
/** /**
* Generate source code for WidgetMapImpl
* Generate source code for a VaadinSerializer implementation.
* *
* @param logger * @param logger
* Logger object * Logger object
* @param context * @param context
* Generator context * Generator context
* @param typeName
* @param beanTypeName
* bean type for which the serializer is to be generated
* @param beanSerializerTypeName
* name of the serializer class to generate
*/ */
private void generateClass(TreeLogger logger, GeneratorContext context, private void generateClass(TreeLogger logger, GeneratorContext context,
String beanTypeName, String beanSerializerTypeName) { String beanTypeName, String beanSerializerTypeName) {
// JSONArray jsonHeight = (JSONArray) jsonValue.get("height"); // JSONArray jsonHeight = (JSONArray) jsonValue.get("height");
sourceWriter.println("JSONArray " + jsonFieldName sourceWriter.println("JSONArray " + jsonFieldName
+ " = (JSONArray) jsonValue.get(\"" + fieldName + "\");"); + " = (JSONArray) jsonValue.get(\"" + fieldName + "\");");
// state.setHeight((String) // state.setHeight((String)
// JsonDecoder.convertValue(jsonFieldValue,idMapper)); // JsonDecoder.convertValue(jsonFieldValue,idMapper));

+ 14
- 1
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java Прегледај датотеку

/*
@VaadinApache2LicenseForJavaFiles@
*/
package com.vaadin.terminal.gwt.widgetsetutils; package com.vaadin.terminal.gwt.widgetsetutils;
import java.io.PrintWriter; import java.io.PrintWriter;
import com.vaadin.terminal.gwt.client.communication.SharedState; import com.vaadin.terminal.gwt.client.communication.SharedState;
import com.vaadin.terminal.gwt.client.communication.VaadinSerializer; import com.vaadin.terminal.gwt.client.communication.VaadinSerializer;
/**
* GWT generator that creates a {@link SerializerMap} implementation (mapper
* from type string to serializer instance) and serializer classes for all
* subclasses of {@link SharedState}.
*
* @since 7.0
*/
public class SerializerMapGenerator extends Generator { public class SerializerMapGenerator extends Generator {
private String packageName; private String packageName;
JClassType classType = typeOracle.getType(typeName); JClassType classType = typeOracle.getType(typeName);
packageName = classType.getPackage().getName(); packageName = classType.getPackage().getName();
className = classType.getSimpleSourceName() + "Impl"; className = classType.getSimpleSourceName() + "Impl";
// Generate class source code
// Generate class source code for SerializerMapImpl
generateClass(logger, context); generateClass(logger, context);
// Generate serializer classes for each subclass of SharedState
JClassType serializerType = typeOracle.findType(SharedState.class JClassType serializerType = typeOracle.findType(SharedState.class
.getName()); .getName());
JClassType[] serializerSubtypes = serializerType.getSubtypes(); JClassType[] serializerSubtypes = serializerType.getSubtypes();
+ " getSerializer(String type) {"); + " getSerializer(String type) {");
sourceWriter.indent(); sourceWriter.indent();
// TODO cache serializer instances in a map
for (JClassType type : serializerSubtypes) { for (JClassType type : serializerSubtypes) {
sourceWriter.println("if (type.equals(\"" sourceWriter.println("if (type.equals(\""
+ type.getQualifiedSourceName() + "\")) {"); + type.getQualifiedSourceName() + "\")) {");

+ 0
- 3
src/com/vaadin/ui/AbstractComponent.java Прегледај датотеку



// TODO for now, this superclass always recreates the state from // TODO for now, this superclass always recreates the state from
// scratch, whereas subclasses should only modify it // scratch, whereas subclasses should only modify it
// Map<String, Object> state = new HashMap<String, Object>();


if (getHeight() >= 0 if (getHeight() >= 0
&& (getHeightUnits() != Unit.PERCENTAGE || ComponentSizeValidator && (getHeightUnits() != Unit.PERCENTAGE || ComponentSizeValidator
// if (getDescription() != null && getDescription().length() > 0) { // if (getDescription() != null && getDescription().length() > 0) {
// state.put(ComponentState.STATE_DESCRIPTION, getDescription()); // state.put(ComponentState.STATE_DESCRIPTION, getDescription());
// } // }
//
// sharedState.setState(state);


return sharedState; return sharedState;
} }

Loading…
Откажи
Сачувај