aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/itmill/toolkit/terminal/web/HttpVariableMap.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/itmill/toolkit/terminal/web/HttpVariableMap.java')
-rw-r--r--src/com/itmill/toolkit/terminal/web/HttpVariableMap.java473
1 files changed, 234 insertions, 239 deletions
diff --git a/src/com/itmill/toolkit/terminal/web/HttpVariableMap.java b/src/com/itmill/toolkit/terminal/web/HttpVariableMap.java
index a54a67f7a3..a22d1a37f0 100644
--- a/src/com/itmill/toolkit/terminal/web/HttpVariableMap.java
+++ b/src/com/itmill/toolkit/terminal/web/HttpVariableMap.java
@@ -1,30 +1,30 @@
/* *************************************************************************
- IT Mill Toolkit
+ IT Mill Toolkit
- Development of Browser User Interfaces Made Easy
+ Development of Browser User Interfaces Made Easy
- Copyright (C) 2000-2006 IT Mill Ltd
-
- *************************************************************************
+ Copyright (C) 2000-2006 IT Mill Ltd
+
+ *************************************************************************
- This product is distributed under commercial license that can be found
- from the product package on license.pdf. Use of this product might
- require purchasing a commercial license from IT Mill Ltd. For guidelines
- on usage, see licensing-guidelines.html
+ This product is distributed under commercial license that can be found
+ from the product package on license.pdf. Use of this product might
+ require purchasing a commercial license from IT Mill Ltd. For guidelines
+ on usage, see licensing-guidelines.html
- *************************************************************************
-
- For more information, contact:
-
- IT Mill Ltd phone: +358 2 4802 7180
- Ruukinkatu 2-4 fax: +358 2 4802 7181
- 20540, Turku email: info@itmill.com
- Finland company www: www.itmill.com
-
- Primary source for information and releases: www.itmill.com
+ *************************************************************************
+
+ For more information, contact:
+
+ IT Mill Ltd phone: +358 2 4802 7180
+ Ruukinkatu 2-4 fax: +358 2 4802 7181
+ 20540, Turku email: info@itmill.com
+ Finland company www: www.itmill.com
+
+ Primary source for information and releases: www.itmill.com
- ********************************************************************** */
+ ********************************************************************** */
package com.itmill.toolkit.terminal.web;
@@ -54,36 +54,42 @@ import java.util.Iterator;
* Class implementing the variable mappings.
*
* @author IT Mill Ltd.
- * @version @VERSION@
+ * @version
+ * @VERSION@
* @since 3.0
*/
public class HttpVariableMap {
// Id <-> (Owner,Name) mapping
private Map idToNameMap = new HashMap();
+
private Map idToTypeMap = new HashMap();
+
private Map idToOwnerMap = new HashMap();
+
private Map idToValueMap = new HashMap();
+
private Map ownerToNameToIdMap = new WeakHashMap();
+
private Object mapLock = new Object();
// Id generator
private long lastId = 0;
- /**
+ /**
* Converts the string to a supported class.
- * @param type
- * @param value
+ *
+ * @param type
+ * @param value
* @throws java.lang.ClassCastException
*/
private static Object convert(Class type, String value)
- throws java.lang.ClassCastException {
+ throws java.lang.ClassCastException {
try {
// Boolean typed variables
if (type.equals(Boolean.class))
- return new Boolean(
- !(value.equals("") || value.equals("false")));
+ return new Boolean(!(value.equals("") || value.equals("false")));
// Integer typed variables
if (type.equals(Integer.class))
@@ -99,29 +105,27 @@ public class HttpVariableMap {
}
}
- /**
+ /**
* Registers a new variable.
- * @param name the name of the variable.
+ *
+ * @param name
+ * the name of the variable.
* @param type
* @param value
- * @param owner the Listener for variable changes.
- *
+ * @param owner
+ * the Listener for variable changes.
+ *
* @return id to assigned for this variable.
*/
- public String registerVariable(
- String name,
- Class type,
- Object value,
- VariableOwner owner) {
+ public String registerVariable(String name, Class type, Object value,
+ VariableOwner owner) {
// Checks that the type of the class is supported
- if (!(type.equals(Boolean.class)
- || type.equals(Integer.class)
- || type.equals(String.class)
- || type.equals(String[].class)
- || type.equals(UploadStream.class)))
- throw new SystemError(
- "Unsupported variable type: " + type.getClass());
+ if (!(type.equals(Boolean.class) || type.equals(Integer.class)
+ || type.equals(String.class) || type.equals(String[].class) || type
+ .equals(UploadStream.class)))
+ throw new SystemError("Unsupported variable type: "
+ + type.getClass());
synchronized (mapLock) {
@@ -148,10 +152,13 @@ public class HttpVariableMap {
}
}
- /**
+ /**
* Unregisters the variable.
- * @param name the name of the variable.
- * @param owner the Listener for variable changes.
+ *
+ * @param name
+ * the name of the variable.
+ * @param owner
+ * the Listener for variable changes.
*/
public void unregisterVariable(String name, VariableOwner owner) {
@@ -179,42 +186,44 @@ public class HttpVariableMap {
/**
* @author IT Mill Ltd.
- * @version @VERSION@
+ * @version
+ * @VERSION@
* @since 3.0
*/
private class ParameterContainer {
- /**
- * Constructs the mapping: listener to set of listened parameter names.
+ /**
+ * Constructs the mapping: listener to set of listened parameter names.
*/
private HashMap parameters = new HashMap();
- /**
- * Parameter values.
+ /**
+ * Parameter values.
*/
private HashMap values = new HashMap();
- /**
- * Multipart parser used for parsing the request.
+ /**
+ * Multipart parser used for parsing the request.
*/
private ServletMultipartRequest parser = null;
- /**
- * Name - Value mapping of parameters that are not variables.
+ /**
+ * Name - Value mapping of parameters that are not variables.
*/
private HashMap nonVariables = new HashMap();
- /**
- * Creates a new parameter container and parse the parameters from the request using
- * GET, POST and POST/MULTIPART parsing.
- * @param req the HTTP request.
- * @throws IOException if the writing failed due to input/output error.
+ /**
+ * Creates a new parameter container and parse the parameters from the
+ * request using GET, POST and POST/MULTIPART parsing.
+ *
+ * @param req
+ * the HTTP request.
+ * @throws IOException
+ * if the writing failed due to input/output error.
*/
public ParameterContainer(HttpServletRequest req) throws IOException {
// Parse GET / POST parameters
- for (Enumeration e = req.getParameterNames();
- e.hasMoreElements();
- ) {
+ for (Enumeration e = req.getParameterNames(); e.hasMoreElements();) {
String paramName = (String) e.nextElement();
String[] paramValues = req.getParameterValues(paramName);
addParam(paramName, paramValues);
@@ -222,28 +231,25 @@ public class HttpVariableMap {
// Parse multipart variables
try {
- parser =
- new ServletMultipartRequest(
- req,
+ parser = new ServletMultipartRequest(req,
MultipartRequest.MAX_READ_BYTES);
} catch (IllegalArgumentException ignored) {
parser = null;
}
if (parser != null) {
- for (Enumeration e = parser.getFileParameterNames();
- e.hasMoreElements();
- ) {
+ for (Enumeration e = parser.getFileParameterNames(); e
+ .hasMoreElements();) {
String paramName = (String) e.nextElement();
addParam(paramName, null);
}
- for (Enumeration e = parser.getParameterNames();
- e.hasMoreElements();
- ) {
+ for (Enumeration e = parser.getParameterNames(); e
+ .hasMoreElements();) {
String paramName = (String) e.nextElement();
Enumeration val = parser.getURLParameters(paramName);
- // Create a linked list from enumeration to calculate elements
+ // Create a linked list from enumeration to calculate
+ // elements
LinkedList l = new LinkedList();
while (val.hasMoreElements())
l.addLast(val.nextElement());
@@ -260,10 +266,12 @@ public class HttpVariableMap {
}
- /**
+ /**
* Adds the parameter to container.
- * @param name the name of the parameter.
- * @param value
+ *
+ * @param name
+ * the name of the parameter.
+ * @param value
*/
private void addParam(String name, String[] value) {
@@ -280,50 +288,46 @@ public class HttpVariableMap {
newVal[i] = curVal[i];
value = newVal;
- // Special case - if the set:-method is used for
- // declaring array of length 2, where either of the
+ // Special case - if the set:-method is used for
+ // declaring array of length 2, where either of the
// following conditions are true:
- // - the both items are the same
- // - the both items have the same length and
- // - the items only differ on last character
- // - second last character is '.'
- // - last char of one string is 'x' and other is 'y'
- // Browser is unporposely modifying the name.
+ // - the both items are the same
+ // - the both items have the same length and
+ // - the items only differ on last character
+ // - second last character is '.'
+ // - last char of one string is 'x' and other is 'y'
+ // Browser is unporposely modifying the name.
if (value.length == 2
- && value[0].length() == value[1].length()) {
+ && value[0].length() == value[1].length()) {
boolean same = true;
for (int i = 0; i < value[0].length() - 1 && same; i++)
if (value[0].charAt(i) != value[1].charAt(i))
same = false;
if (same
- && ((value[0].charAt(value[0].length() - 1) == 'x'
- && value[1].charAt(value[1].length() - 1) == 'y')
- || (value[0].charAt(value[0].length() - 1) == 'y'
- && value[1].charAt(value[1].length() - 1)
- == 'x'))) {
- value =
- new String[] {
- value[0].substring(
- 0,
- value[1].length() - 2)};
- } else
- if (same && value[0].equals(value[1]))
+ && ((value[0].charAt(value[0].length() - 1) == 'x' && value[1]
+ .charAt(value[1].length() - 1) == 'y') || (value[0]
+ .charAt(value[0].length() - 1) == 'y' && value[1]
+ .charAt(value[1].length() - 1) == 'x'))) {
+ value = new String[] { value[0].substring(0,
+ value[1].length() - 2) };
+ } else if (same && value[0].equals(value[1]))
value = new String[] { value[0] };
}
- // Special case - if the set:-method is used for
- // declaring array of length 3, where all of the
+ // Special case - if the set:-method is used for
+ // declaring array of length 3, where all of the
// following conditions are true:
- // - two last items have the same length
- // - the first item is 2 chars shorter
- // - the longer items only differ on last character
- // - the shortest item is a prefix of the longer ones
- // - second last character of longer ones is '.'
- // - last char of one long string is 'x' and other is 'y'
- // Browser is unporposely modifying the name. (Mozilla, Firefox, ..)
+ // - two last items have the same length
+ // - the first item is 2 chars shorter
+ // - the longer items only differ on last character
+ // - the shortest item is a prefix of the longer ones
+ // - second last character of longer ones is '.'
+ // - last char of one long string is 'x' and other is 'y'
+ // Browser is unporposely modifying the name. (Mozilla,
+ // Firefox, ..)
if (value.length == 3
- && value[1].length() == value[2].length() &&
- value[0].length() +2 == value[1].length()) {
+ && value[1].length() == value[2].length()
+ && value[0].length() + 2 == value[1].length()) {
boolean same = true;
for (int i = 0; i < value[1].length() - 1 && same; i++)
if (value[2].charAt(i) != value[1].charAt(i))
@@ -332,14 +336,11 @@ public class HttpVariableMap {
if (value[0].charAt(i) != value[1].charAt(i))
same = false;
if (same
- && (value[2].charAt(value[2].length() - 1) == 'x'
- && value[1].charAt(value[1].length() - 1) == 'y')
- || (value[2].charAt(value[2].length() - 1) == 'y'
- && value[1].charAt(value[1].length() - 1)
- == 'x')) {
- value =
- new String[] {
- value[0]};
+ && (value[2].charAt(value[2].length() - 1) == 'x' && value[1]
+ .charAt(value[1].length() - 1) == 'y')
+ || (value[2].charAt(value[2].length() - 1) == 'y' && value[1]
+ .charAt(value[1].length() - 1) == 'x')) {
+ value = new String[] { value[0] };
}
}
@@ -353,8 +354,8 @@ public class HttpVariableMap {
if (equalsIndex < 0)
return;
- StringTokenizer commalist =
- new StringTokenizer(name.substring(equalsIndex + 1), ",");
+ StringTokenizer commalist = new StringTokenizer(name
+ .substring(equalsIndex + 1), ",");
name = name.substring(10, equalsIndex);
String[] curVal = (String[]) values.get(name);
ArrayList elems = new ArrayList();
@@ -426,7 +427,8 @@ public class HttpVariableMap {
// If the owner can not be found
else {
- // If parameter has been mapped before, remove the old owner mapping
+ // If parameter has been mapped before, remove the old owner
+ // mapping
if (ref != null) {
// The owner has been destroyed, so we remove the mappings
@@ -442,10 +444,12 @@ public class HttpVariableMap {
}
- /**
+ /**
* Gets the set of all parameters connected to given variable owner.
- * @param owner the Listener for variable changes.
- * @return the set of all parameters connected to variable owner.
+ *
+ * @param owner
+ * the Listener for variable changes.
+ * @return the set of all parameters connected to variable owner.
*/
public Set getParameters(VariableOwner owner) {
if (owner == null)
@@ -453,52 +457,60 @@ public class HttpVariableMap {
return (Set) parameters.get(owner);
}
- /**
- * Gets the set of all variable owners owning parameters in this request.
- * @return
+ /**
+ * Gets the set of all variable owners owning parameters in this
+ * request.
+ *
+ * @return
*/
public Set getOwners() {
return parameters.keySet();
}
- /**
+ /**
* Gets the value of a parameter.
- * @param parameterName the name of the parameter.
- * @return the value of the parameter.
+ *
+ * @param parameterName
+ * the name of the parameter.
+ * @return the value of the parameter.
*/
public String[] getValue(String parameterName) {
return (String[]) values.get(parameterName);
}
- /**
+ /**
* Gets the servlet multipart parser.
+ *
* @return the parser.
*/
public ServletMultipartRequest getParser() {
return parser;
}
- /**
+ /**
* Gets the name - value[] mapping of non variable paramteres.
- * @return
+ *
+ * @return
*/
public Map getNonVariables() {
return nonVariables;
}
}
- /**
+ /**
* Handles all variable changes in this request.
- * @param req the Http request to handle.
- * @param errorListener If the list is non null, only the listed listeners are
- * served. Otherwise all the listeners are served.
+ *
+ * @param req
+ * the Http request to handle.
+ * @param errorListener
+ * If the list is non null, only the listed listeners are served.
+ * Otherwise all the listeners are served.
* @return Name to Value[] mapping of unhandled variables.
- * @throws IOException if the writing failed due to input/output error.
+ * @throws IOException
+ * if the writing failed due to input/output error.
*/
- public Map handleVariables(
- HttpServletRequest req,
- Terminal.ErrorListener errorListener)
- throws IOException {
+ public Map handleVariables(HttpServletRequest req,
+ Terminal.ErrorListener errorListener) throws IOException {
// Gets the parameters
ParameterContainer parcon = new ParameterContainer(req);
@@ -509,7 +521,8 @@ public class HttpVariableMap {
// Handles all parameters for all listeners
while (!listeners.isEmpty()) {
VariableOwner listener = (VariableOwner) listeners.remove(0);
- boolean changed = false; // Has any of this owners variabes changed
+ boolean changed = false; // Has any of this owners variabes
+ // changed
// Handle all parameters for listener
Set params = parcon.getParameters(listener);
if (params != null) { // Name value mapping
@@ -522,14 +535,13 @@ public class HttpVariableMap {
Class varType = (Class) idToTypeMap.get(param);
Object varOldValue = idToValueMap.get(param);
if (varName == null || varType == null)
- Log.warn(
- "VariableMap: No variable found for parameter "
- + param
- + " ("
- + varName
- + ","
- + listener
- + ")");
+ Log
+ .warn("VariableMap: No variable found for parameter "
+ + param
+ + " ("
+ + varName
+ + ","
+ + listener + ")");
else {
ServletMultipartRequest parser = parcon.getParser();
@@ -537,24 +549,17 @@ public class HttpVariableMap {
// Upload events
if (varType.equals(UploadStream.class)) {
if (parser != null
- && parser.getFileParameter(
- param,
- MultipartRequest.FILENAME)
- != null) {
- String filename =
- (String) parser.getFileParameter(
- param,
- MultipartRequest.FILENAME);
- String contentType =
- (String) parser.getFileParameter(
- param,
- MultipartRequest.CONTENT_TYPE);
- UploadStream upload =
- new HttpUploadStream(
- varName,
- parser.getFileContents(param),
- filename,
- contentType);
+ && parser.getFileParameter(param,
+ MultipartRequest.FILENAME) != null) {
+ String filename = (String) parser
+ .getFileParameter(param,
+ MultipartRequest.FILENAME);
+ String contentType = (String) parser
+ .getFileParameter(param,
+ MultipartRequest.CONTENT_TYPE);
+ UploadStream upload = new HttpUploadStream(
+ varName, parser.getFileContents(param),
+ filename, contentType);
variables.put(varName, upload);
changed = true;
}
@@ -568,45 +573,37 @@ public class HttpVariableMap {
if (varType.equals(String[].class)) {
variables.put(varName, values);
- changed
- |= (!Arrays
- .equals(
- values,
- (String[]) varOldValue));
+ changed |= (!Arrays.equals(values,
+ (String[]) varOldValue));
} else {
try {
if (values.length == 1) {
- Object val =
- convert(varType, values[0]);
+ Object val = convert(varType,
+ values[0]);
variables.put(varName, val);
- changed
- |= ((val == null
- && varOldValue != null)
- || (val != null
- && !val.equals(
- varOldValue)));
- } else if (
- values.length == 0
- && varType.equals(
- Boolean.class)) {
+ changed |= ((val == null && varOldValue != null) || (val != null && !val
+ .equals(varOldValue)));
+ } else if (values.length == 0
+ && varType
+ .equals(Boolean.class)) {
Object val = new Boolean(false);
variables.put(varName, val);
- changed
- |= (!val.equals(varOldValue));
+ changed |= (!val
+ .equals(varOldValue));
} else {
- Log.warn(
- "Empty variable '"
- + varName
- + "' of type "
+ Log.warn("Empty variable '"
+ + varName + "' of type "
+ varType.toString());
}
} catch (java.lang.ClassCastException e) {
- Log.except(
- "WebVariableMap conversion exception",
- e);
- errorListener.terminalError(
- new TerminalErrorImpl(e));
+ Log
+ .except(
+ "WebVariableMap conversion exception",
+ e);
+ errorListener
+ .terminalError(new TerminalErrorImpl(
+ e));
}
}
}
@@ -620,8 +617,8 @@ public class HttpVariableMap {
listener.changeVariables(req, variables);
} catch (Throwable t) {
// Notify the error listener
- errorListener.terminalError(
- new VariableOwnerErrorImpl(listener, t));
+ errorListener.terminalError(new VariableOwnerErrorImpl(
+ listener, t));
}
}
}
@@ -630,22 +627,23 @@ public class HttpVariableMap {
return parcon.getNonVariables();
}
- /**
- * Implementation of VariableOwner.Error interface.
+ /**
+ * Implementation of VariableOwner.Error interface.
*/
public class TerminalErrorImpl implements Terminal.ErrorEvent {
private Throwable throwable;
-
-/**
- *
- * @param throwable
- */
+
+ /**
+ *
+ * @param throwable
+ */
private TerminalErrorImpl(Throwable throwable) {
this.throwable = throwable;
}
/**
* Gets the contained throwable.
+ *
* @see com.itmill.toolkit.terminal.Terminal.ErrorEvent#getThrowable()
*/
public Throwable getThrowable() {
@@ -654,29 +652,28 @@ public class HttpVariableMap {
}
- /**
- * Implementation of VariableOwner.Error interface.
+ /**
+ * Implementation of VariableOwner.Error interface.
*/
- public class VariableOwnerErrorImpl
- extends TerminalErrorImpl
- implements VariableOwner.ErrorEvent {
+ public class VariableOwnerErrorImpl extends TerminalErrorImpl implements
+ VariableOwner.ErrorEvent {
private VariableOwner owner;
-
-/**
- *
- * @param owner the Listener for variable changes.
- * @param throwable
- */
- private VariableOwnerErrorImpl(
- VariableOwner owner,
- Throwable throwable) {
+
+ /**
+ *
+ * @param owner
+ * the Listener for variable changes.
+ * @param throwable
+ */
+ private VariableOwnerErrorImpl(VariableOwner owner, Throwable throwable) {
super(throwable);
this.owner = owner;
}
/**
* Gets the source VariableOwner.
+ *
* @see com.itmill.toolkit.terminal.VariableOwner.ErrorEvent#getVariableOwner()
*/
public VariableOwner getVariableOwner() {
@@ -685,13 +682,13 @@ public class HttpVariableMap {
}
- /**
- * Resolves the VariableOwners needed from the request and sort
- * them to assure that the dependencies are met (as well as possible).
+ /**
+ * Resolves the VariableOwners needed from the request and sort them to
+ * assure that the dependencies are met (as well as possible).
*
- * @param listeners
- * @return List of variable list changers, that are needed for handling
- * all the variables in the request
+ * @param listeners
+ * @return List of variable list changers, that are needed for handling all
+ * the variables in the request
*/
private List getDependencySortedListenerList(Set listeners) {
@@ -708,7 +705,8 @@ public class HttpVariableMap {
if (listener != null) {
Set dependencies = listener.getDirectDependencies();
- // The listeners with no dependencies are added to the front of the
+ // The listeners with no dependencies are added to the front of
+ // the
// list directly
if (dependencies == null || dependencies.isEmpty()) {
if (listener.isImmediate())
@@ -732,8 +730,8 @@ public class HttpVariableMap {
HashSet tmpdeepdeps = new HashSet();
while (!unresolved.isEmpty()) {
- VariableOwner l =
- (VariableOwner) unresolved.removeFirst();
+ VariableOwner l = (VariableOwner) unresolved
+ .removeFirst();
if (!tmpdeepdeps.contains(l)) {
tmpdeepdeps.add(l);
if (deepdeps.containsKey(l)) {
@@ -741,12 +739,11 @@ public class HttpVariableMap {
} else {
Set deps = l.getDirectDependencies();
if (deps != null && !deps.isEmpty())
- for (Iterator di = deps.iterator();
- di.hasNext();
- ) {
+ for (Iterator di = deps.iterator(); di
+ .hasNext();) {
Object d = di.next();
if (d != null
- && !tmpdeepdeps.contains(d))
+ && !tmpdeepdeps.contains(d))
unresolved.addLast(d);
}
}
@@ -767,23 +764,21 @@ public class HttpVariableMap {
// Adds each listener after the last depended listener already in
// the list
int index = -1;
- for (Iterator di = ((Set) deepdeps.get(l)).iterator();
- di.hasNext();
- ) {
+ for (Iterator di = ((Set) deepdeps.get(l)).iterator(); di.hasNext();) {
int k;
Object depended = di.next();
if (immediate) {
- k = resultImmediate.lastIndexOf(depended);
- }else {
- k = resultNormal.lastIndexOf(depended);
- }
+ k = resultImmediate.lastIndexOf(depended);
+ } else {
+ k = resultNormal.lastIndexOf(depended);
+ }
if (k > index)
index = k;
}
if (immediate) {
resultImmediate.add(index + 1, l);
} else {
- resultNormal.add(index + 1, l);
+ resultNormal.add(index + 1, l);
}
}