aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatti Tahvonen <matti.tahvonen@itmill.com>2009-11-25 14:04:09 +0000
committerMatti Tahvonen <matti.tahvonen@itmill.com>2009-11-25 14:04:09 +0000
commit6edd5dd7662bb62bfc48b1d36663f37bf4c11797 (patch)
treef0989a799f41870393aa5fe905d8b98fc1ae355f /src
parent513675e3a5f06dcc9e232870fba5cf761f012080 (diff)
downloadvaadin-framework-6edd5dd7662bb62bfc48b1d36663f37bf4c11797.tar.gz
vaadin-framework-6edd5dd7662bb62bfc48b1d36663f37bf4c11797.zip
Variable enhancements
* typing map for changevariable to <String,Object> * added variabletypes Object[] and Map<String,Object> where Objects can be Strings,Integers, Longs, Floats, Doubles, Booleans and Paintables (reference on client side translates to corresponding server side component by terminal) * Note, multilevel datastructures still not supported (Array or Map inside another), needs #3765 fixes #3756, #3757 svn changeset:10023/svn branch:6.2
Diffstat (limited to 'src')
-rw-r--r--src/com/vaadin/terminal/VariableOwner.java2
-rwxr-xr-xsrc/com/vaadin/terminal/gwt/client/ApplicationConnection.java150
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VListSelect.java6
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java6
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java8
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java13
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java23
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTextField.java6
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTree.java16
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java14
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java206
-rw-r--r--src/com/vaadin/ui/AbstractComponent.java2
-rw-r--r--src/com/vaadin/ui/AbstractField.java14
-rw-r--r--src/com/vaadin/ui/AbstractSelect.java2
15 files changed, 304 insertions, 168 deletions
diff --git a/src/com/vaadin/terminal/VariableOwner.java b/src/com/vaadin/terminal/VariableOwner.java
index 5f6fc03877..1507726b7d 100644
--- a/src/com/vaadin/terminal/VariableOwner.java
+++ b/src/com/vaadin/terminal/VariableOwner.java
@@ -33,7 +33,7 @@ public interface VariableOwner extends Serializable {
* @param variables
* the Mapping from variable names to new variable values.
*/
- public void changeVariables(Object source, Map variables);
+ public void changeVariables(Object source, Map<String, Object> variables);
/**
* <p>
diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
index d461d2c6ca..02c05358e2 100755
--- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
+++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
@@ -9,6 +9,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.Map;
import java.util.Set;
import com.google.gwt.core.client.GWT;
@@ -216,7 +217,7 @@ public class ApplicationConnection {
* <li><code>vaadin.postRequestHooks</code> is a map of functions which gets
* called after each XHR made by vaadin application. Note, that it is
* attaching js functions responsibility to create the variable like this:
- *
+ *
* <code><pre>
* if(!vaadin.postRequestHooks) {vaadin.postRequestHooks = new Object();}
* postRequestHooks.myHook = function(appId) {
@@ -227,7 +228,7 @@ public class ApplicationConnection {
* </pre></code> First parameter passed to these functions is the identifier
* of Vaadin application that made the request.
* </ul>
- *
+ *
* TODO make this multi-app aware
*/
private native void initializeClientHooks()
@@ -258,7 +259,7 @@ public class ApplicationConnection {
/**
* Runs possibly registered client side post request hooks. This is expected
* to be run after each uidl request made by Vaadin application.
- *
+ *
* @param appId
*/
private static native void runPostRequestHooks(String appId)
@@ -281,7 +282,7 @@ public class ApplicationConnection {
/**
* Checks if client side is in debug mode. Practically this is invoked by
* adding ?debug parameter to URI.
- *
+ *
* @return true if client side is currently been debugged
*/
public native static boolean isDebugMode()
@@ -356,7 +357,8 @@ public class ApplicationConnection {
}
}
if (windowName != null && windowName.length() > 0) {
- uri += (repaintAll || configuration.usePortletURLs() ? "&" : "?") + "windowName=" + windowName;
+ uri += (repaintAll || configuration.usePortletURLs() ? "&" : "?")
+ + "windowName=" + windowName;
}
if (!forceSync) {
@@ -462,7 +464,7 @@ public class ApplicationConnection {
/**
* Shows the communication error notification. The 'details' only go to the
* console for now.
- *
+ *
* @param details
* Optional details for debugging.
*/
@@ -544,7 +546,7 @@ public class ApplicationConnection {
/**
* This method is called after applying uidl change set to application.
- *
+ *
* It will clean current and queued variable change sets. And send next
* change set if it exists.
*/
@@ -564,7 +566,7 @@ public class ApplicationConnection {
/**
* Cleans given queue of variable changes of such changes that came from
* components that do not exist anymore.
- *
+ *
* @param variableBurst
*/
private void cleanVariableBurst(ArrayList<String> variableBurst) {
@@ -921,7 +923,7 @@ public class ApplicationConnection {
/**
* Returns Paintable element by its id
- *
+ *
* @param id
* Paintable ID
*/
@@ -955,12 +957,12 @@ public class ApplicationConnection {
/**
* This method sends currently queued variable changes to server. It is
* called when immediate variable update must happen.
- *
+ *
* To ensure correct order for variable changes (due servers multithreading
* or network), we always wait for active request to be handler before
* sending a new one. If there is an active request, we will put varible
* "burst" to queue that will be purged after current request is handled.
- *
+ *
*/
@SuppressWarnings("unchecked")
public void sendPendingVariableChanges() {
@@ -982,11 +984,11 @@ public class ApplicationConnection {
/**
* Build the variable burst and send it to server.
- *
+ *
* When sync is forced, we also force sending of all pending variable-bursts
* at the same time. This is ok as we can assume that DOM will never be
* updated after this.
- *
+ *
* @param pendingVariables
* Vector of variable changes to send
* @param forceSync
@@ -1061,13 +1063,79 @@ public class ApplicationConnection {
}
public void updateVariable(String paintableId, String variableName,
+ Map<String, Object> map, boolean immediate) {
+ final StringBuffer buf = new StringBuffer();
+ Iterator<String> iterator = map.keySet().iterator();
+ while (iterator.hasNext()) {
+ String key = iterator.next();
+ Object value = map.get(key);
+ char transportType = getTransportType(value);
+ buf.append(transportType);
+ buf.append(key);
+ buf.append(VAR_ARRAYITEM_SEPARATOR);
+ if (transportType == 'p') {
+ buf.append(getPid((Paintable) value));
+ } else {
+ buf.append(value);
+ }
+
+ if (iterator.hasNext()) {
+ buf.append(VAR_ARRAYITEM_SEPARATOR);
+ }
+ }
+
+ addVariableToQueue(paintableId, variableName, buf.toString(),
+ immediate, 'm');
+ }
+
+ private char getTransportType(Object value) {
+ if (value instanceof String) {
+ return 's';
+ } else if (value instanceof Paintable) {
+ return 'p';
+ } else if (value instanceof Boolean) {
+ return 'b';
+ } else if (value instanceof Integer) {
+ return 'i';
+ } else if (value instanceof Float) {
+ return 'f';
+ } else if (value instanceof Double) {
+ return 'd';
+ } else if (value instanceof Long) {
+ return 'l';
+ }
+ return 'u';
+ }
+
+ public void updateVariable(String paintableId, String variableName,
+ String[] values, boolean immediate) {
+ final StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < values.length; i++) {
+ if (i > 0) {
+ buf.append(VAR_ARRAYITEM_SEPARATOR);
+ }
+ buf.append(values[i]);
+ }
+ addVariableToQueue(paintableId, variableName, buf.toString(),
+ immediate, 'c');
+ }
+
+ public void updateVariable(String paintableId, String variableName,
Object[] values, boolean immediate) {
final StringBuffer buf = new StringBuffer();
for (int i = 0; i < values.length; i++) {
if (i > 0) {
buf.append(VAR_ARRAYITEM_SEPARATOR);
}
- buf.append(values[i].toString());
+ Object value = values[i];
+ char transportType = getTransportType(value);
+ // first char tells the type in array
+ buf.append(transportType);
+ if (transportType == 'p') {
+ buf.append(getPid((Paintable) value));
+ } else {
+ buf.append(value);
+ }
}
addVariableToQueue(paintableId, variableName, buf.toString(),
immediate, 'a');
@@ -1075,9 +1143,9 @@ public class ApplicationConnection {
/**
* Update generic component features.
- *
+ *
* <h2>Selecting correct implementation</h2>
- *
+ *
* <p>
* The implementation of a component depends on many properties, including
* styles, component features, etc. Sometimes the user changes those
@@ -1085,21 +1153,21 @@ public class ApplicationConnection {
* the beginning of your updateFromUIDL -method automatically replaces your
* component with more appropriate if the requested implementation changes.
* </p>
- *
+ *
* <h2>Caption, icon, error messages and description</h2>
- *
+ *
* <p>
* Component can delegate management of caption, icon, error messages and
* description to parent layout. This is optional an should be decided by
* component author
* </p>
- *
+ *
* <h2>Component visibility and disabling</h2>
- *
+ *
* This method will manage component visibility automatically and if
* component is an instanceof FocusWidget, also handle component disabling
* when needed.
- *
+ *
* @param component
* Widget to be updated, expected to implement an instance of
* Paintable
@@ -1108,7 +1176,7 @@ public class ApplicationConnection {
* @param manageCaption
* True if you want to delegate caption, icon, description and
* error message management to parent.
- *
+ *
* @return Returns true iff no further painting is needed by caller
*/
public boolean updateComponent(Widget component, UIDL uidl,
@@ -1318,7 +1386,7 @@ public class ApplicationConnection {
/**
* Traverses recursively child widgets until ContainerResizedListener child
* widget is found. They will delegate it further if needed.
- *
+ *
* @param container
*/
private boolean runningLayout = false;
@@ -1381,7 +1449,7 @@ public class ApplicationConnection {
/**
* Converts relative sizes into pixel sizes.
- *
+ *
* @param child
* @return true if the child has a relative size
*/
@@ -1528,7 +1596,7 @@ public class ApplicationConnection {
/**
* Converts relative sizes into pixel sizes.
- *
+ *
* @param child
* @return true if the child has a relative size
*/
@@ -1545,12 +1613,12 @@ public class ApplicationConnection {
/**
* Get either existing or new Paintable for given UIDL.
- *
+ *
* If corresponding Paintable has been previously painted, return it.
* Otherwise create and register a new Paintable from UIDL. Caller must
* update the returned Paintable from UIDL after it has been connected to
* parent.
- *
+ *
* @param uidl
* UIDL to create Paintable from.
* @return Either existing or new Paintable corresponding to UIDL.
@@ -1570,7 +1638,7 @@ public class ApplicationConnection {
/**
* Returns a Paintable element by its root element
- *
+ *
* @param element
* Root element of the paintable
*/
@@ -1584,7 +1652,7 @@ public class ApplicationConnection {
/**
* Singleton method to get instance of app's context menu.
- *
+ *
* @return VContextMenu object
*/
public VContextMenu getContextMenu() {
@@ -1600,7 +1668,7 @@ public class ApplicationConnection {
* Translates custom protocols in UIDL URI's to be recognizable by browser.
* All uri's from UIDL should be routed via this method before giving them
* to browser due URI's in UIDL may contain custom protocols like theme://.
- *
+ *
* @param uidlUri
* Vaadin URI from uidl
* @return translated URI ready for browser
@@ -1628,7 +1696,7 @@ public class ApplicationConnection {
/**
* Listens for Notification hide event, and redirects. Used for system
* messages, such as session expired.
- *
+ *
*/
private class NotificationRedirect implements VNotification.EventListener {
String url;
@@ -1648,9 +1716,9 @@ public class ApplicationConnection {
/**
* Data showed in tooltips are stored centrilized as it may be needed in
* varios place: caption, layouts, and in owner components themselves.
- *
+ *
* Updating TooltipInfo is done in updateComponent method.
- *
+ *
*/
public TooltipInfo getTooltipTitleInfo(Paintable titleOwner, Object key) {
if (null == titleOwner) {
@@ -1670,9 +1738,9 @@ public class ApplicationConnection {
* Component may want to delegate Tooltip handling to client. Layouts add
* Tooltip (description, errors) to caption, but some components may want
* them to appear one other elements too.
- *
+ *
* Events wanted by this handler are same as in Tooltip.TOOLTIP_EVENTS
- *
+ *
* @param event
* @param owner
*/
@@ -1685,9 +1753,9 @@ public class ApplicationConnection {
* Component may want to delegate Tooltip handling to client. Layouts add
* Tooltip (description, errors) to caption, but some components may want
* them to appear one other elements too.
- *
+ *
* Events wanted by this handler are same as in Tooltip.TOOLTIP_EVENTS
- *
+ *
* @param event
* @param owner
* @param key
@@ -1701,7 +1769,7 @@ public class ApplicationConnection {
/**
* Adds PNG-fix conditionally (only for IE6) to the specified IMG -element.
- *
+ *
* @param el
* the IMG element to fix
*/
@@ -1751,7 +1819,7 @@ public class ApplicationConnection {
* Reset the name of the current browser-window. This should reflect the
* window-name used in the server, but might be different from the
* window-object target-name on client.
- *
+ *
* @param stringAttribute
* New name for the window.
*/
@@ -1781,14 +1849,14 @@ public class ApplicationConnection {
* <p>
* This method can also be used to deregister tooltips by using null as
* tooltip
- *
+ *
* @param paintable
* Paintable "owning" this tooltip
* @param key
* key assosiated with given tooltip. Can be any object. For
* example a related dom element. Same key must be given for
* {@link #handleTooltipEvent(Event, Paintable, Object)} method.
- *
+ *
* @param tooltip
* the TooltipInfo object containing details shown in tooltip,
* null if deregistering tooltip
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VListSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VListSelect.java
index e33231c81b..480685345f 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VListSelect.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VListSelect.java
@@ -60,14 +60,14 @@ public class VListSelect extends VOptionGroupBase {
}
@Override
- protected Object[] getSelectedItems() {
- final ArrayList selectedItemKeys = new ArrayList();
+ protected String[] getSelectedItems() {
+ final ArrayList<String> selectedItemKeys = new ArrayList<String>();
for (int i = 0; i < select.getItemCount(); i++) {
if (select.isItemSelected(i)) {
selectedItemKeys.add(select.getValue(i));
}
}
- return selectedItemKeys.toArray();
+ return selectedItemKeys.toArray(new String[selectedItemKeys.size()]);
}
@Override
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java
index 50c7c337ba..8c00e9c1a7 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java
@@ -61,14 +61,14 @@ public class VNativeSelect extends VOptionGroupBase implements Field {
}
@Override
- protected Object[] getSelectedItems() {
- final ArrayList selectedItemKeys = new ArrayList();
+ protected String[] getSelectedItems() {
+ final ArrayList<String> selectedItemKeys = new ArrayList<String>();
for (int i = 0; i < select.getItemCount(); i++) {
if (select.isItemSelected(i)) {
selectedItemKeys.add(select.getValue(i));
}
}
- return selectedItemKeys.toArray();
+ return selectedItemKeys.toArray(new String[selectedItemKeys.size()]);
}
@Override
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java
index e54cf04a6c..a8ce1d124e 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java
@@ -58,8 +58,8 @@ public class VOptionGroup extends VOptionGroupBase {
}
@Override
- protected Object[] getSelectedItems() {
- return selectedKeys.toArray();
+ protected String[] getSelectedItems() {
+ return selectedKeys.toArray(new String[selectedKeys.size()]);
}
@Override
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java
index a2c558094c..115c415289 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java
@@ -31,7 +31,7 @@ abstract class VOptionGroupBase extends Composite implements Paintable, Field,
protected String id;
- protected Set selectedKeys;
+ protected Set<String> selectedKeys;
private boolean immediate;
@@ -215,10 +215,10 @@ abstract class VOptionGroupBase extends Composite implements Paintable, Field,
protected abstract void buildOptions(UIDL uidl);
- protected abstract Object[] getSelectedItems();
+ protected abstract String[] getSelectedItems();
- protected Object getSelectedItem() {
- final Object[] sel = getSelectedItems();
+ protected String getSelectedItem() {
+ final String[] sel = getSelectedItems();
if (sel.length > 0) {
return sel[0];
} else {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
index 575d35e5f0..e735dc67d9 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
@@ -1658,7 +1658,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler {
// update variable to server
client.updateVariable(paintableId, "collapsedcolumns",
- collapsedColumns.toArray(), false);
+ collapsedColumns.toArray(new String[collapsedColumns
+ .size()]), false);
// let rowRequestHandler determine proper rows
rowRequestHandler.refreshContent();
}
@@ -2449,8 +2450,14 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler {
// might
// require changes to "clickEvent" immediateness
// also.
- client.updateVariable(paintableId, "selected",
- selectedRowKeys.toArray(), immediate);
+ client
+ .updateVariable(
+ paintableId,
+ "selected",
+ selectedRowKeys
+ .toArray(new String[selectedRowKeys
+ .size()]),
+ immediate);
}
break;
case Event.ONCONTEXTMENU:
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java b/src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java
index 6995513524..638f4b9be9 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java
@@ -51,7 +51,7 @@ public class VTablePaging extends Composite implements Table, Paintable,
private int selectMode = Table.SELECT_MODE_NONE;
- private final ArrayList selectedRowKeys = new ArrayList();
+ private final ArrayList<String> selectedRowKeys = new ArrayList<String>();
private int totalRows;
@@ -108,10 +108,11 @@ public class VTablePaging extends Composite implements Table, Paintable,
}
if (uidl.hasAttribute("selected")) {
- final Set selectedKeys = uidl
+ final Set<String> selectedKeys = uidl
.getStringArrayVariableAsSet("selected");
selectedRowKeys.clear();
- for (final Iterator it = selectedKeys.iterator(); it.hasNext();) {
+ for (final Iterator<String> it = selectedKeys.iterator(); it
+ .hasNext();) {
selectedRowKeys.add(it.next());
}
}
@@ -169,10 +170,10 @@ public class VTablePaging extends Composite implements Table, Paintable,
/**
* Updates row data from uidl. UpdateFromUIDL delegates updating tBody to
* this method.
- *
+ *
* Updates may be to different part of tBody, depending on update type. It
* can be initial row data, scroll up, scroll down...
- *
+ *
* @param uidl
* which contains row data
*/
@@ -299,7 +300,7 @@ public class VTablePaging extends Composite implements Table, Paintable,
/**
* Abstraction of table cell content. In needs to know on which row it is in
* case of context click.
- *
+ *
* @author mattitahvonen
*/
public class BodyCell extends SimplePanel {
@@ -355,7 +356,7 @@ public class VTablePaging extends Composite implements Table, Paintable,
/**
* This method is used to set row status. Does not change value on
* server.
- *
+ *
* @param selected
*/
public void setSelected(boolean sel) {
@@ -379,7 +380,7 @@ public class VTablePaging extends Composite implements Table, Paintable,
/**
* Toggles rows select state. Also updates state to server according to
* tables immediate flag.
- *
+ *
*/
public void toggleSelected() {
if (selected) {
@@ -390,13 +391,13 @@ public class VTablePaging extends Composite implements Table, Paintable,
}
setSelected(true);
}
- client.updateVariable(id, "selected", selectedRowKeys.toArray(),
- immediate);
+ client.updateVariable(id, "selected", selectedRowKeys
+ .toArray(new String[selectedRowKeys.size()]), immediate);
}
/**
* Shows context menu for this row.
- *
+ *
* @param event
* Event which triggered context menu. Correct place for
* context menu can be determined with it.
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java
index 845a50e793..8c02fc33cf 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java
@@ -56,6 +56,7 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
private static final String ATTR_INPUTPROMPT = "prompt";
private String inputPrompt = null;
private boolean prompting = false;
+ private boolean listenFocus;
public VTextField() {
this(DOM.createInputText());
@@ -98,6 +99,8 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
setReadOnly(false);
}
+ listenFocus = uidl.getBooleanAttribute("listenFocus");
+
inputPrompt = uidl.getStringAttribute(ATTR_INPUTPROMPT);
setMaxLength(uidl.hasAttribute("maxLength") ? uidl
@@ -195,6 +198,9 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
}
}
focusedTextField = this;
+ if (listenFocus) {
+ client.updateVariable(id, "focus", true, true);
+ }
}
public void onBlur(BlurEvent event) {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTree.java b/src/com/vaadin/terminal/gwt/client/ui/VTree.java
index 87d27caa55..7769047c80 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTree.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTree.java
@@ -169,8 +169,20 @@ public class VTree extends FlowPanel implements Paintable {
selectedIds.remove(treeNode.key);
treeNode.setSelected(false);
}
- client.updateVariable(paintableId, "selected", selectedIds.toArray(),
- immediate);
+
+ Object[] foo = new Object[] { new Integer(33), new Float(3.2f),
+ new Long(222), this, "bar", true, new Double(3.33332) };
+ client.updateVariable(paintableId, "foo", foo, false);
+
+ HashMap<String, Object> bar = new HashMap<String, Object>();
+ bar.put("paintable", this);
+ bar.put("String", "bar");
+ bar.put("Integer", 33);
+
+ client.updateVariable(paintableId, "bar", bar, false);
+
+ client.updateVariable(paintableId, "selected", selectedIds
+ .toArray(new String[selectedIds.size()]), immediate);
}
public boolean isSelected(TreeNode treeNode) {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java
index 1694992074..880144a11b 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java
@@ -110,12 +110,12 @@ public class VTwinColSelect extends VOptionGroupBase {
}
@Override
- protected Object[] getSelectedItems() {
- final ArrayList selectedItemKeys = new ArrayList();
+ protected String[] getSelectedItems() {
+ final ArrayList<String> selectedItemKeys = new ArrayList<String>();
for (int i = 0; i < selections.getItemCount(); i++) {
selectedItemKeys.add(selections.getValue(i));
}
- return selectedItemKeys.toArray();
+ return selectedItemKeys.toArray(new String[selectedItemKeys.size()]);
}
private boolean[] getItemsToAdd() {
@@ -162,8 +162,8 @@ public class VTwinColSelect extends VOptionGroupBase {
options.removeItem(optionIndex);
}
}
- client.updateVariable(id, "selected", selectedKeys.toArray(),
- isImmediate());
+ client.updateVariable(id, "selected", selectedKeys
+ .toArray(new String[selectedKeys.size()]), isImmediate());
} else if (event.getSource() == remove) {
final boolean[] sel = getItemsToRemove();
@@ -181,8 +181,8 @@ public class VTwinColSelect extends VOptionGroupBase {
selections.removeItem(selectionIndex);
}
}
- client.updateVariable(id, "selected", selectedKeys.toArray(),
- isImmediate());
+ client.updateVariable(id, "selected", selectedKeys
+ .toArray(new String[selectedKeys.size()]), isImmediate());
} else if (event.getSource() == options) {
// unselect all in other list, to avoid mistakes (i.e wrong button)
final int c = selections.getItemCount();
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
index 7e9c04bc26..34d37fca06 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
@@ -70,7 +70,7 @@ import com.vaadin.ui.Upload.UploadException;
* communication system between the client code (compiled with GWT into
* JavaScript) and the server side components. Its client side counterpart is
* {@link ApplicationConnection}.
- *
+ *
* A server side component sends its state to the client in a paint request (see
* {@link Paintable} and {@link PaintTarget} on the server side). The client
* widget receives these paint requests as calls to
@@ -78,7 +78,7 @@ import com.vaadin.ui.Upload.UploadException;
* component communicates back to the server by sending a list of variable
* changes (see {@link ApplicationConnection#updateVariable()} and
* {@link VariableOwner#changeVariables(Object, Map)}).
- *
+ *
* TODO Document better!
*/
@SuppressWarnings("serial")
@@ -87,13 +87,13 @@ public abstract class AbstractCommunicationManager implements
/**
* Generic interface of a (HTTP or Portlet) request to the application.
- *
+ *
* This is a wrapper interface that allows
* {@link AbstractCommunicationManager} to use a unified API.
- *
+ *
* @see javax.servlet.ServletRequest
* @see javax.portlet.PortletRequest
- *
+ *
* @author peholmst
*/
protected interface Request {
@@ -101,9 +101,9 @@ public abstract class AbstractCommunicationManager implements
/**
* Gets a {@link Session} wrapper implementation representing the
* session for which this request was sent.
- *
+ *
* Multiple Vaadin applications can be associated with a single session.
- *
+ *
* @return Session
*/
public Session getSession();
@@ -111,17 +111,17 @@ public abstract class AbstractCommunicationManager implements
/**
* Are the applications in this session running in a portlet or directly
* as servlets.
- *
+ *
* @return true if in a portlet
*/
public boolean isRunningInPortlet();
/**
* Get the named HTTP or portlet request parameter.
- *
+ *
* @see javax.servlet.ServletRequest#getParameter(String)
* @see javax.portlet.PortletRequest#getParameter(String)
- *
+ *
* @param name
* @return
*/
@@ -130,7 +130,7 @@ public abstract class AbstractCommunicationManager implements
/**
* Returns the length of the request content that can be read from the
* input stream returned by {@link #getInputStream()}.
- *
+ *
* @return content length in bytes
*/
public int getContentLength();
@@ -139,7 +139,7 @@ public abstract class AbstractCommunicationManager implements
* Returns an input stream from which the request content can be read.
* The request content length can be obtained with
* {@link #getContentLength()} without reading the full stream contents.
- *
+ *
* @return
* @throws IOException
*/
@@ -148,7 +148,7 @@ public abstract class AbstractCommunicationManager implements
/**
* Returns the request identifier that identifies the target Vaadin
* window for the request.
- *
+ *
* @return String identifier for the request target window
*/
public String getRequestID();
@@ -168,7 +168,7 @@ public abstract class AbstractCommunicationManager implements
/**
* Gets the underlying request object. The request is typically either a
* {@link ServletRequest} or a {@link PortletRequest}.
- *
+ *
* @return wrapped request object
*/
public Object getWrappedRequest();
@@ -177,20 +177,20 @@ public abstract class AbstractCommunicationManager implements
/**
* Generic interface of a (HTTP or Portlet) response from the application.
- *
+ *
* This is a wrapper interface that allows
* {@link AbstractCommunicationManager} to use a unified API.
- *
+ *
* @see javax.servlet.ServletResponse
* @see javax.portlet.PortletResponse
- *
+ *
* @author peholmst
*/
protected interface Response {
/**
* Gets the output stream to which the response can be written.
- *
+ *
* @return
* @throws IOException
*/
@@ -199,7 +199,7 @@ public abstract class AbstractCommunicationManager implements
/**
* Sets the MIME content type for the response to be communicated to the
* browser.
- *
+ *
* @param type
*/
public void setContentType(String type);
@@ -207,7 +207,7 @@ public abstract class AbstractCommunicationManager implements
/**
* Gets the wrapped response object, usually a class implementing either
* {@link ServletResponse} or {@link PortletResponse}.
- *
+ *
* @return wrapped request object
*/
public Object getWrappedResponse();
@@ -216,14 +216,14 @@ public abstract class AbstractCommunicationManager implements
/**
* Generic wrapper interface for a (HTTP or Portlet) session.
- *
+ *
* Several applications can be associated with a single session.
- *
+ *
* TODO Document me!
- *
+ *
* @see javax.servlet.http.HttpSession
* @see javax.portlet.PortletSession
- *
+ *
* @author peholmst
*/
protected interface Session {
@@ -242,7 +242,7 @@ public abstract class AbstractCommunicationManager implements
/**
* TODO Document me!
- *
+ *
* @author peholmst
*/
protected interface Callback {
@@ -270,6 +270,17 @@ public abstract class AbstractCommunicationManager implements
private static final int VAR_TYPE = 3;
private static final int VAR_VALUE = 0;
+ private static final char VTYPE_PAINTABLE = 'p';
+ private static final char VTYPE_BOOLEAN = 'b';
+ private static final char VTYPE_DOUBLE = 'd';
+ private static final char VTYPE_FLOAT = 'f';
+ private static final char VTYPE_LONG = 'l';
+ private static final char VTYPE_INTEGER = 'i';
+ private static final char VTYPE_STRING = 's';
+ private static final char VTYPE_ARRAY = 'a';
+ private static final char VTYPE_STRINGARRAY = 'c';
+ private static final char VTYPE_MAP = 'm';
+
private static final String VAR_RECORD_SEPARATOR = "\u001e";
private static final String VAR_FIELD_SEPARATOR = "\u001f";
@@ -306,7 +317,7 @@ public abstract class AbstractCommunicationManager implements
/**
* TODO New constructor - document me!
- *
+ *
* @param application
*/
public AbstractCommunicationManager(Application application) {
@@ -317,26 +328,27 @@ public abstract class AbstractCommunicationManager implements
/**
* Create an upload handler that is appropriate to the context in which the
* application is being run (servlet or portlet).
- *
+ *
* @return new {@link FileUpload} instance
*/
protected abstract FileUpload createFileUpload();
/**
* TODO New method - document me!
- *
+ *
* @param upload
* @param request
* @return
* @throws IOException
* @throws FileUploadException
*/
- protected abstract FileItemIterator getUploadItemIterator(FileUpload upload,
- Request request) throws IOException, FileUploadException;
+ protected abstract FileItemIterator getUploadItemIterator(
+ FileUpload upload, Request request) throws IOException,
+ FileUploadException;
/**
* TODO New method - document me!
- *
+ *
* @param request
* @param response
* @throws IOException
@@ -431,12 +443,13 @@ public abstract class AbstractCommunicationManager implements
/**
* TODO document
- *
+ *
* @param request
* @param response
* @throws IOException
*/
- protected void sendUploadResponse(Request request, Response response) throws IOException {
+ protected void sendUploadResponse(Request request, Response response)
+ throws IOException {
response.setContentType("text/html");
final OutputStream out = response.getOutputStream();
final PrintWriter outWriter = new PrintWriter(new BufferedWriter(
@@ -448,19 +461,19 @@ public abstract class AbstractCommunicationManager implements
/**
* Internally process a UIDL request from the client.
- *
+ *
* This method calls
* {@link #handleVariables(Request, Response, Callback, Application, Window)}
* to process any changes to variables by the client and then repaints
* affected components using {@link #paintAfterVariableChanges()}.
- *
+ *
* Also, some cleanup is done when a request arrives for an application that
* has already been closed.
- *
+ *
* The method handleUidlRequest(...) in subclasses should call this method.
- *
+ *
* TODO better documentation
- *
+ *
* @param request
* @param response
* @param callback
@@ -476,7 +489,7 @@ public abstract class AbstractCommunicationManager implements
final OutputStream out;
repaintAll = (request.getParameter(GET_PARAM_REPAINT_ALL) != null);
- //|| (request.getSession().isNew()); FIXME What the h*ll is this??
+ // || (request.getSession().isNew()); FIXME What the h*ll is this??
out = response.getOutputStream();
boolean analyzeLayouts = false;
@@ -554,13 +567,13 @@ public abstract class AbstractCommunicationManager implements
}
}
- //out.flush(); - this line will cause errors when deployed on GateIn.
+ // out.flush(); - this line will cause errors when deployed on GateIn.
out.close();
}
/**
* TODO document
- *
+ *
* @param request
* @param response
* @param callback
@@ -916,11 +929,11 @@ public abstract class AbstractCommunicationManager implements
/**
* TODO document
- *
+ *
* If this method returns false, something was submitted that we did not
* expect; this is probably due to the client being out-of-sync and sending
* variable changes for non-existing pids
- *
+ *
* @return true if successful, false if there was an inconsistency
*/
private boolean handleVariables(Request request, Response response,
@@ -980,20 +993,19 @@ public abstract class AbstractCommunicationManager implements
// TODO this should be Map<String, Object>, but the
// VariableOwner API does not guarantee the key is a
// string
- Map<Object, Object> m;
+ Map<String, Object> m;
if (nextVariable != null
&& variable[VAR_PID]
.equals(nextVariable[VAR_PID])) {
// we have more than one value changes in row for
// one variable owner, collect em in HashMap
- m = new HashMap<Object, Object>();
+ m = new HashMap<String, Object>();
m.put(variable[VAR_NAME], convertVariableValue(
variable[VAR_TYPE].charAt(0),
variable[VAR_VALUE]));
} else {
// use optimized single value map
- m = Collections.singletonMap(
- (Object) variable[VAR_NAME],
+ m = Collections.singletonMap(variable[VAR_NAME],
convertVariableValue(variable[VAR_TYPE]
.charAt(0), variable[VAR_VALUE]));
}
@@ -1084,7 +1096,7 @@ public abstract class AbstractCommunicationManager implements
/**
* Reads the request data from the Request and returns it converted to an
* UTF-8 string.
- *
+ *
* @param request
* @return
* @throws IOException
@@ -1129,13 +1141,13 @@ public abstract class AbstractCommunicationManager implements
/**
* Handles an error (exception) that occurred when processing variable
* changes from the client or a failure of a file upload.
- *
+ *
* For {@link AbstractField} components,
* {@link AbstractField#handleError(com.vaadin.ui.AbstractComponent.ComponentErrorEvent)}
* is called. In all other cases (or if the field does not handle the
* error), {@link ErrorListener#terminalError(ErrorEvent)} for the
* application error handler is called.
- *
+ *
* @param application
* @param owner
* component that the error concerns
@@ -1174,28 +1186,34 @@ public abstract class AbstractCommunicationManager implements
private Object convertVariableValue(char variableType, String strValue) {
Object val = null;
switch (variableType) {
- case 'a':
+ case VTYPE_ARRAY:
+ val = convertArray(strValue);
+ break;
+ case VTYPE_MAP:
+ val = convertMap(strValue);
+ break;
+ case VTYPE_STRINGARRAY:
val = strValue.split(VAR_ARRAYITEM_SEPARATOR);
break;
- case 's':
+ case VTYPE_STRING:
val = strValue;
break;
- case 'i':
+ case VTYPE_INTEGER:
val = Integer.valueOf(strValue);
break;
- case 'l':
+ case VTYPE_LONG:
val = Long.valueOf(strValue);
break;
- case 'f':
+ case VTYPE_FLOAT:
val = Float.valueOf(strValue);
break;
- case 'd':
+ case VTYPE_DOUBLE:
val = Double.valueOf(strValue);
break;
- case 'b':
+ case VTYPE_BOOLEAN:
val = Boolean.valueOf(strValue);
break;
- case 'p':
+ case VTYPE_PAINTABLE:
val = idPaintableMap.get(strValue);
break;
}
@@ -1203,11 +1221,35 @@ public abstract class AbstractCommunicationManager implements
return val;
}
+ private Object convertMap(String strValue) {
+ String[] parts = strValue.split(VAR_ARRAYITEM_SEPARATOR);
+ HashMap<String, Object> map = new HashMap<String, Object>();
+ for (int i = 0; i < parts.length; i += 2) {
+ String key = parts[i];
+ char variabletype = key.charAt(0);
+ Object value = convertVariableValue(variabletype, parts[i + 1]);
+ map.put(key.substring(1), value);
+ }
+ return map;
+ }
+
+ private Object convertArray(String strValue) {
+ String[] val = strValue.split(VAR_ARRAYITEM_SEPARATOR);
+ Object[] values = new Object[val.length];
+ for (int i = 0; i < values.length; i++) {
+ String string = val[i];
+ // first char of string is typ
+ char variableType = string.charAt(0);
+ values[i] = convertVariableValue(variableType, string.substring(1));
+ }
+ return values;
+ }
+
/**
- * Prints the queued (pending) locale definitions to a {@link PrintWriter} in
- * a (UIDL) format that can be sent to the client and used there in formatting
- * dates, times etc.
- *
+ * Prints the queued (pending) locale definitions to a {@link PrintWriter}
+ * in a (UIDL) format that can be sent to the client and used there in
+ * formatting dates, times etc.
+ *
* @param outWriter
*/
private void printLocaleDeclarations(PrintWriter outWriter) {
@@ -1316,7 +1358,7 @@ public abstract class AbstractCommunicationManager implements
final String timeformat = df.substring(timeStart, df.length());
/*
* Doesn't return second or milliseconds.
- *
+ *
* We use timeformat to determine 12/24-hour clock
*/
final boolean twelve_hour_clock = timeformat.indexOf("a") > -1;
@@ -1342,7 +1384,7 @@ public abstract class AbstractCommunicationManager implements
/**
* TODO New method - document me!
- *
+ *
* @param request
* @param callback
* @param application
@@ -1429,11 +1471,11 @@ public abstract class AbstractCommunicationManager implements
/**
* Ends the Application.
- *
+ *
* The browser is redirected to the Application logout URL set with
* {@link Application#setLogoutURL(String)}, or to the application URL if no
* logout URL is given.
- *
+ *
* @param request
* the request instance.
* @param response
@@ -1468,7 +1510,7 @@ public abstract class AbstractCommunicationManager implements
/**
* Gets the Paintable Id. If Paintable has debug id set it will be used
* prefixed with "PID_S". Otherwise a sequenced ID is created.
- *
+ *
* @param paintable
* @return the paintable Id.
*/
@@ -1514,7 +1556,7 @@ public abstract class AbstractCommunicationManager implements
/**
* Returns dirty components which are in given window. Components in an
* invisible subtrees are omitted.
- *
+ *
* @param w
* root window for which dirty components is to be fetched
* @return
@@ -1549,7 +1591,7 @@ public abstract class AbstractCommunicationManager implements
&& !component.getParent().isVisible()) {
/*
* Do not return components in an invisible subtree.
- *
+ *
* Components that are invisible in visible subree, must
* be rendered (to let client know that they need to be
* hidden).
@@ -1576,7 +1618,7 @@ public abstract class AbstractCommunicationManager implements
/**
* Internally mark a {@link Paintable} as painted and start collecting new
* repaint requests for it.
- *
+ *
* @param paintable
*/
private void paintablePainted(Paintable paintable) {
@@ -1595,7 +1637,7 @@ public abstract class AbstractCommunicationManager implements
private final Throwable throwable;
/**
- *
+ *
* @param owner
* @param throwable
*/
@@ -1623,11 +1665,11 @@ public abstract class AbstractCommunicationManager implements
* Queues a locale to be sent to the client (browser) for date and time
* entry etc. All locale specific information is derived from server-side
* {@link Locale} instances and sent to the client when needed, eliminating
- * the need to use the {@link Locale} class and all the framework behind
- * it on the client.
- *
+ * the need to use the {@link Locale} class and all the framework behind it
+ * on the client.
+ *
* @see Locale#toString()
- *
+ *
* @param value
*/
public void requireLocale(String value) {
@@ -1644,9 +1686,9 @@ public abstract class AbstractCommunicationManager implements
/**
* Constructs a {@link Locale} instance to be sent to the client based on a
* short locale description string.
- *
+ *
* @see #requireLocale(String)
- *
+ *
* @param value
* @return
*/
@@ -1687,7 +1729,7 @@ public abstract class AbstractCommunicationManager implements
/**
* Helper method to test if a component contains another
- *
+ *
* @param parent
* @param child
*/
@@ -1714,12 +1756,12 @@ public abstract class AbstractCommunicationManager implements
/**
* Calls the Window URI handler for a request and returns the
* {@link DownloadStream} returned by the handler.
- *
+ *
* If the window is the main window of an application, the (deprecated)
* {@link Application#handleURI(java.net.URL, String)} is called first to
* handle {@link ApplicationResource}s, and the window handler is only
* called if it returns null.
- *
+ *
* @param window
* the target window of the request
* @param request
@@ -1799,7 +1841,7 @@ public abstract class AbstractCommunicationManager implements
/**
* Helper class for terminal to keep track of data that client is expected
* to know.
- *
+ *
* TODO make customlayout templates (from theme) to be cached here.
*/
class OpenWindowCache implements Serializable {
@@ -1807,7 +1849,7 @@ public abstract class AbstractCommunicationManager implements
private Set<Object> res = new HashSet<Object>();
/**
- *
+ *
* @param paintable
* @return true if the given class was added to cache
*/
diff --git a/src/com/vaadin/ui/AbstractComponent.java b/src/com/vaadin/ui/AbstractComponent.java
index 2e6a0d6e19..dbf988377f 100644
--- a/src/com/vaadin/ui/AbstractComponent.java
+++ b/src/com/vaadin/ui/AbstractComponent.java
@@ -820,7 +820,7 @@ public abstract class AbstractComponent implements Component, MethodEventSource
* comment here, we use the default documentation from implemented
* interface.
*/
- public void changeVariables(Object source, Map variables) {
+ public void changeVariables(Object source, Map<String, Object> variables) {
}
/* General event framework */
diff --git a/src/com/vaadin/ui/AbstractField.java b/src/com/vaadin/ui/AbstractField.java
index 9d1420a78d..d665650dd1 100644
--- a/src/com/vaadin/ui/AbstractField.java
+++ b/src/com/vaadin/ui/AbstractField.java
@@ -34,15 +34,15 @@ import com.vaadin.terminal.PaintTarget;
* </p>
*
* <p>
- * AbstractField also provides the {@link com.vaadin.data.Buffered}
- * interface for buffering the data source value. By default the Field is in
- * write through-mode and {@link #setWriteThrough(boolean)}should be called to
- * enable buffering.
+ * AbstractField also provides the {@link com.vaadin.data.Buffered} interface
+ * for buffering the data source value. By default the Field is in write
+ * through-mode and {@link #setWriteThrough(boolean)}should be called to enable
+ * buffering.
* </p>
*
* <p>
- * The class also supports {@link com.vaadin.data.Validator validators}
- * to make sure the value contained in the field is valid.
+ * The class also supports {@link com.vaadin.data.Validator validators} to make
+ * sure the value contained in the field is valid.
* </p>
*
* @author IT Mill Ltd.
@@ -940,7 +940,7 @@ public abstract class AbstractField extends AbstractComponent implements Field,
}
@Override
- public void changeVariables(Object source, Map variables) {
+ public void changeVariables(Object source, Map<String, Object> variables) {
super.changeVariables(source, variables);
}
diff --git a/src/com/vaadin/ui/AbstractSelect.java b/src/com/vaadin/ui/AbstractSelect.java
index 767fc21bd2..66cdaf8a65 100644
--- a/src/com/vaadin/ui/AbstractSelect.java
+++ b/src/com/vaadin/ui/AbstractSelect.java
@@ -358,7 +358,7 @@ public abstract class AbstractSelect extends AbstractField implements
* java.util.Map)
*/
@Override
- public void changeVariables(Object source, Map variables) {
+ public void changeVariables(Object source, Map<String, Object> variables) {
super.changeVariables(source, variables);
// New option entered (and it is allowed)