aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java26
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/server/AjaxVariableMap.java803
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/server/ApplicationServlet.java6
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/server/CommunicationManager.java (renamed from src/com/itmill/toolkit/terminal/gwt/server/ApplicationManager.java)602
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/server/HttpUploadStream.java (renamed from src/com/itmill/toolkit/terminal/gwt/server/AjaxHttpUploadStream.java)4
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/server/JsonPaintTarget.java26
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/server/Log.java4
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/server/MultipartRequest.java1332
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/server/ServletMultipartRequest.java139
9 files changed, 386 insertions, 2556 deletions
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java b/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
index e1c490f4de..06824e5541 100755
--- a/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
@@ -185,8 +185,8 @@ public class ApplicationConnection implements EntryPoint {
}
private void addVariableToQueue(String paintableId, String variableName,
- String encodedValue, boolean immediate) {
- String id = paintableId + "_" + variableName;
+ String encodedValue, boolean immediate, char type) {
+ String id = paintableId + "_" + variableName + "_" + type;
for (int i = 0; i < pendingVariables.size(); i += 2)
if ((pendingVariables.get(i)).equals(id)) {
pendingVariables.remove(i);
@@ -202,37 +202,35 @@ public class ApplicationConnection implements EntryPoint {
public void sendPendingVariableChanges() {
StringBuffer req = new StringBuffer();
+ req.append("changes=");
for (int i = 0; i < pendingVariables.size(); i++) {
- req.append(pendingVariables.get(i++));
- req.append("=");
+ if (i>0) req.append("\u0001");
req.append(pendingVariables.get(i));
- req.append("&");
}
pendingVariables.clear();
makeUidlRequest(req.toString());
}
- private String escapeString(String value) {
- // TODO
- return value;
- }
+ private static native String escapeString(String value) /*-{
+ return encodeURIComponent(value);
+ }-*/;
public void updateVariable(String paintableId, String variableName,
String newValue, boolean immediate) {
addVariableToQueue(paintableId, variableName, escapeString(newValue),
- immediate);
+ immediate, 's');
}
public void updateVariable(String paintableId, String variableName,
int newValue, boolean immediate) {
- addVariableToQueue(paintableId, variableName, "" + newValue, immediate);
+ addVariableToQueue(paintableId, variableName, "" + newValue, immediate, 'i');
}
public void updateVariable(String paintableId, String variableName,
boolean newValue, boolean immediate) {
addVariableToQueue(paintableId, variableName, newValue ? "true"
- : "false", immediate);
+ : "false", immediate, 'b');
}
public void updateVariable(String paintableId, String variableName,
@@ -243,8 +241,8 @@ public class ApplicationConnection implements EntryPoint {
buf.append(",");
buf.append(escapeString(values[i].toString()));
}
- addVariableToQueue("array:" + paintableId, variableName,
- buf.toString(), immediate);
+ addVariableToQueue(paintableId, variableName,
+ buf.toString(), immediate, 'a');
}
public WidgetFactory getWidgetFactory() {
diff --git a/src/com/itmill/toolkit/terminal/gwt/server/AjaxVariableMap.java b/src/com/itmill/toolkit/terminal/gwt/server/AjaxVariableMap.java
deleted file mode 100644
index 54c0013361..0000000000
--- a/src/com/itmill/toolkit/terminal/gwt/server/AjaxVariableMap.java
+++ /dev/null
@@ -1,803 +0,0 @@
-/* *************************************************************************
-
- IT Mill Toolkit
-
- Development of Browser User Interfaces Made Easy
-
- 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
-
- *************************************************************************
-
- 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.gwt.server;
-
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.WeakHashMap;
-
-import javax.servlet.http.HttpServletRequest;
-
-import com.itmill.toolkit.terminal.SystemError;
-import com.itmill.toolkit.terminal.Terminal;
-import com.itmill.toolkit.terminal.UploadStream;
-import com.itmill.toolkit.terminal.VariableOwner;
-
-/**
- * Variable map for ajax applications.
- *
- * @author IT Mill Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-public class AjaxVariableMap {
-
- // 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
- * @return
- * @throws java.lang.ClassCastException
- * if the code has attempted to cast an object to a subclass of
- * which it is not an instance
- */
- private static Object convert(Class type, String value)
- throws java.lang.ClassCastException {
- try {
-
- // Boolean typed variables
- if (type.equals(Boolean.class))
- return new Boolean(!(value.equals("") || value.equals("false")));
-
- // Integer typed variables
- if (type.equals(Integer.class))
- return new Integer(value.trim());
-
- // String typed variables
- if (type.equals(String.class))
- return value;
-
- throw new ClassCastException("Unsupported type: " + type.getName());
- } catch (NumberFormatException e) {
- return null;
- }
- }
-
- /**
- * Registers a new variable.
- *
- * @param name
- * the Variable name.
- * @param type
- * @param value
- * @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) {
-
- // 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());
-
- synchronized (mapLock) {
-
- // Checks if the variable is already mapped
- HashMap nameToIdMap = (HashMap) ownerToNameToIdMap.get(owner);
- if (nameToIdMap == null) {
- nameToIdMap = new HashMap();
- ownerToNameToIdMap.put(owner, nameToIdMap);
- }
- String id = (String) nameToIdMap.get(name);
-
- if (id == null) {
- // Generates new id and register it
-
-// ----------
-// TODO This HACK is only included for testing GWT integration
-//Original id = "v" + String.valueOf(++lastId);
- Object pid = ApplicationManager.paintableIdMap.get(owner);
- id = pid + "_"+name;
-// ----------
-
-
- nameToIdMap.put(name, id);
- idToOwnerMap.put(id, new WeakReference(owner));
- idToNameMap.put(id, name);
- idToTypeMap.put(id, type);
- }
-
- idToValueMap.put(id, value);
-
- return id;
- }
- }
-
- /**
- * Unregisters the variable.
- *
- * @param name
- * the Variable name.
- * @param owner
- * the Listener for variable changes.
- */
- public void unregisterVariable(String name, VariableOwner owner) {
-
- synchronized (mapLock) {
-
- // Get the id
- HashMap nameToIdMap = (HashMap) ownerToNameToIdMap.get(owner);
- if (nameToIdMap == null)
- return;
- String id = (String) nameToIdMap.get(name);
- if (id != null)
- return;
-
- // Remove all the mappings
- nameToIdMap.remove(name);
- if (nameToIdMap.isEmpty())
- ownerToNameToIdMap.remove(owner);
- idToNameMap.remove(id);
- idToTypeMap.remove(id);
- idToValueMap.remove(id);
- idToOwnerMap.remove(id);
-
- }
- }
-
- /**
- * @author IT Mill Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- private class ParameterContainer {
-
- /**
- * Constructs the mapping: listener to set of listened parameter names.
- */
- private HashMap parameters = new HashMap();
-
- /**
- * Parameter values.
- */
- private HashMap values = new HashMap();
-
- /**
- * Multipart parser used for parsing the request.
- */
- private ServletMultipartRequest parser = null;
-
- /**
- * 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 to handle.
- * @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();) {
- String paramName = (String) e.nextElement();
- String[] paramValues = req.getParameterValues(paramName);
- addParam(paramName, paramValues);
- }
-
- // Parse multipart variables
- try {
- parser = new ServletMultipartRequest(req,
- MultipartRequest.MAX_READ_BYTES);
- } catch (IllegalArgumentException ignored) {
- parser = null;
- }
-
- if (parser != null) {
- for (Enumeration e = parser.getFileParameterNames(); e
- .hasMoreElements();) {
- String paramName = (String) e.nextElement();
- addParam(paramName, null);
- }
- 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
- LinkedList l = new LinkedList();
- while (val.hasMoreElements())
- l.addLast(val.nextElement());
-
- // String array event constructor
- String[] s = new String[l.size()];
- Iterator i = l.iterator();
- for (int j = 0; j < s.length; j++)
- s[j] = (String) i.next();
-
- addParam(paramName, s);
- }
- }
-
- }
-
- /**
- * Adds the parameter to container.
- *
- * @param name
- * the Parameter name.
- * @param value
- * the Parameter value.
- */
- private void addParam(String name, String[] value) {
-
- // Support name="set:name=value" value="ignored" notation
- if (name.startsWith("set:")) {
- int equalsIndex = name.indexOf('=');
- value[0] = name.substring(equalsIndex + 1, name.length());
- name = name.substring(4, equalsIndex);
- String[] curVal = (String[]) values.get(name);
- if (curVal != null) {
- String[] newVal = new String[1 + curVal.length];
- newVal[curVal.length] = value[0];
- for (int i = 0; i < curVal.length; i++)
- newVal[i] = curVal[i];
- value = newVal;
-
- // 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.
- if (value.length == 2
- && 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 = new String[] { value[0] };
- }
-
- // 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, ..)
- if (value.length == 3
- && 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))
- same = false;
- for (int i = 0; i < value[0].length() && same; i++)
- 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] };
- }
- }
-
- }
- }
-
- // Support for setting arrays in format
- // set-array:name=value1,value2,value3,...
- else if (name.startsWith("set-array:")) {
- int equalsIndex = name.indexOf('=');
- if (equalsIndex < 0)
- return;
-
- StringTokenizer commalist = new StringTokenizer(name
- .substring(equalsIndex + 1), ",");
- name = name.substring(10, equalsIndex);
- String[] curVal = (String[]) values.get(name);
- ArrayList elems = new ArrayList();
-
- // Add old values if present.
- if (curVal != null) {
- for (int i = 0; i < curVal.length; i++)
- elems.add(curVal[i]);
- }
- while (commalist.hasMoreTokens()) {
- String token = commalist.nextToken();
- if (token != null && token.length() > 0)
- elems.add(token);
- }
- value = new String[elems.size()];
- for (int i = 0; i < value.length; i++)
- value[i] = (String) elems.get(i);
-
- }
-
- // Support name="array:name" value="val1,val2,val3" notation
- // All the empty elements are ignored
- else if (name.startsWith("array:")) {
-
- name = name.substring(6);
- StringTokenizer commalist = new StringTokenizer(value[0], ",");
- String[] curVal = (String[]) values.get(name);
- ArrayList elems = new ArrayList();
-
- // Add old values if present.
- if (curVal != null) {
- for (int i = 0; i < curVal.length; i++)
- elems.add(curVal[i]);
- }
- while (commalist.hasMoreTokens()) {
- String token = commalist.nextToken();
- if (token != null && token.length() > 0)
- elems.add(token);
- }
- value = new String[elems.size()];
- for (int i = 0; i < value.length; i++)
- value[i] = (String) elems.get(i);
- }
-
- // Support declaring variables with name="declare:name"
- else if (name.startsWith("declare:")) {
- name = name.substring(8);
- value = (String[]) values.get(name);
- if (value == null)
- value = new String[0];
- }
-
- // Gets the owner
- WeakReference ref = (WeakReference) idToOwnerMap.get(name);
- VariableOwner owner = null;
- if (ref != null)
- owner = (VariableOwner) ref.get();
-
- // Adds the parameter to mapping only if they have owners
- if (owner != null) {
- Set p = (Set) parameters.get(owner);
- if (p == null)
- parameters.put(owner, p = new HashSet());
- p.add(name);
- if (value != null)
- values.put(name, value);
- }
-
- // If the owner can not be found
- else {
-
- // If parameter has been mapped before, remove the old owner
- // mapping
- if (ref != null) {
-
- // The owner has been destroyed, so we remove the mappings
- idToNameMap.remove(name);
- idToOwnerMap.remove(name);
- idToTypeMap.remove(name);
- idToValueMap.remove(name);
- }
-
- // Adds the parameter to set of non-variables
- nonVariables.put(name, value);
- }
-
- }
-
- /**
- * Gets the set of all parameters connected to given variable owner.
- *
- * @param owner
- * the Listener for variable changes.
- * @return the set of all the parameters.
- */
- public Set getParameters(VariableOwner owner) {
- if (owner == null)
- return null;
- return (Set) parameters.get(owner);
- }
-
- /**
- * Gets the set of all variable owners owning parameters in this
- * request.
- *
- * @return the set of all varaible owners.
- */
- 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.
- */
- 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 parameters.
- *
- * @return the mapping of non variable parameters.
- */
- public Map getNonVariables() {
- return nonVariables;
- }
- }
-
- /**
- * Handles all variable changes in this request.
- *
- * @param req
- * the Http request to handle.
- * @param errorListener
- * the listeners 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.
- */
- public Map handleVariables(HttpServletRequest req,
- Terminal.ErrorListener errorListener) throws IOException {
-
- // Gets the parameters
- ParameterContainer parcon = new ParameterContainer(req);
-
- // Sorts listeners to dependency order
- List listeners = getDependencySortedListenerList(parcon.getOwners());
-
- // 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
- // Handles all parameters for listener
- Set params = parcon.getParameters(listener);
- if (params != null) { // Name value mapping
- Map variables = new HashMap();
- for (Iterator pi = params.iterator(); pi.hasNext();) {
- // Gets the name of the parameter
- String param = (String) pi.next();
- // Extracts more information about the parameter
- String varName = (String) idToNameMap.get(param);
- Class varType = (Class) idToTypeMap.get(param);
- Object varOldValue = idToValueMap.get(param);
- if (varName == null || varType == null)
- // TODO Remove this?
- System.err
- .println("VariableMap: No variable found for parameter "
- + param
- + " ("
- + varName
- + ","
- + listener + ")");
- else {
-
- ServletMultipartRequest parser = parcon.getParser();
-
- // Uploads 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 AjaxHttpUploadStream(
- varName, parser.getFileContents(param),
- filename, contentType);
- variables.put(varName, upload);
- changed = true;
- }
- }
-
- // Normal variable change events
- else {
- // First try to parse the event without multipart
- String[] values = parcon.getValue(param);
- if (values != null) {
-
- if (varType.equals(String[].class)) {
- variables.put(varName, values);
- changed |= (!Arrays.equals(values,
- (String[]) varOldValue));
- } else {
- try {
- if (values.length == 1) {
- 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)) {
- Object val = new Boolean(false);
- variables.put(varName, val);
- changed |= (!val
- .equals(varOldValue));
- } else {
- // TODO Remove this?
- System.err
- .println("Empty variable '"
- + varName
- + "' of type "
- + varType
- .toString());
- }
-
- } catch (java.lang.ClassCastException e) {
- // TODO Remove this?
- System.err
- .println("WebVariableMap conversion exception");
- e.printStackTrace(System.err);
- errorListener
- .terminalError(new TerminalErrorImpl(
- e));
- }
- }
- }
- }
- }
- }
-
- // Do the valuechange if the listener is enabled
- if (listener.isEnabled() && changed) {
- try {
- listener.changeVariables(req, variables);
- } catch (Throwable t) {
- // Notify the error listener
- errorListener.terminalError(new VariableOwnerErrorImpl(
- listener, t));
- }
- }
- }
- }
-
- return parcon.getNonVariables();
- }
-
- /**
- * Implementation of VariableOwner.Error interface.
- */
- public class TerminalErrorImpl implements Terminal.ErrorEvent {
- private Throwable throwable;
-
- /**
- *
- * @param throwable
- */
- private TerminalErrorImpl(Throwable throwable) {
- this.throwable = throwable;
- }
-
- /**
- * @see com.itmill.toolkit.terminal.Terminal.ErrorEvent#getThrowable()
- */
- public Throwable getThrowable() {
- return this.throwable;
- }
-
- }
-
- /**
- * Implementation of VariableOwner.Error interface.
- */
- 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) {
- super(throwable);
- this.owner = owner;
- }
-
- /**
- * @see com.itmill.toolkit.terminal.VariableOwner.ErrorEvent#getVariableOwner()
- */
- public VariableOwner getVariableOwner() {
- return this.owner;
- }
-
- }
-
- /**
- * 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
- */
- private List getDependencySortedListenerList(Set listeners) {
-
- LinkedList resultNormal = new LinkedList();
- LinkedList resultImmediate = new LinkedList();
-
- // Go trough the listeners and either add them to result or resolve
- // their dependencies
- HashMap deepdeps = new HashMap();
- LinkedList unresolved = new LinkedList();
- for (Iterator li = listeners.iterator(); li.hasNext();) {
-
- VariableOwner listener = (VariableOwner) li.next();
- if (listener != null) {
- Set dependencies = listener.getDirectDependencies();
-
- // The listeners with no dependencies are added to the front of
- // the
- // list directly
- if (dependencies == null || dependencies.isEmpty()) {
- if (listener.isImmediate())
- resultImmediate.addFirst(listener);
- else
- resultNormal.addFirst(listener);
- }
-
- // Resolve deep dependencies for the listeners with dependencies
- // (the listeners will be added to the end of results in correct
- // dependency order later). Also the dependencies of all the
- // depended listeners are resolved.
- else if (deepdeps.get(listener) == null) {
-
- // Set the fifo for unresolved parents to contain only the
- // listener to be resolved
- unresolved.clear();
- unresolved.add(listener);
-
- // Resolve dependencies
- HashSet tmpdeepdeps = new HashSet();
- while (!unresolved.isEmpty()) {
-
- VariableOwner l = (VariableOwner) unresolved
- .removeFirst();
- if (!tmpdeepdeps.contains(l)) {
- tmpdeepdeps.add(l);
- if (deepdeps.containsKey(l)) {
- tmpdeepdeps.addAll((Set) deepdeps.get(l));
- } else {
- Set deps = l.getDirectDependencies();
- if (deps != null && !deps.isEmpty())
- for (Iterator di = deps.iterator(); di
- .hasNext();) {
- Object d = di.next();
- if (d != null
- && !tmpdeepdeps.contains(d))
- unresolved.addLast(d);
- }
- }
- }
- }
-
- tmpdeepdeps.remove(listener);
- deepdeps.put(listener, tmpdeepdeps);
- }
- }
- }
-
- // Adds the listeners with dependencies in sane order to the result
- for (Iterator li = deepdeps.keySet().iterator(); li.hasNext();) {
- VariableOwner l = (VariableOwner) li.next();
- boolean immediate = l.isImmediate();
-
- // 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();) {
- int k;
- Object depended = di.next();
- if (immediate) {
- 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);
- }
- }
-
- // Appends immediate listeners to normal listeners
- // This way the normal handlers are always called before
- // immediate ones
- resultNormal.addAll(resultImmediate);
- return resultNormal;
- }
-}
diff --git a/src/com/itmill/toolkit/terminal/gwt/server/ApplicationServlet.java b/src/com/itmill/toolkit/terminal/gwt/server/ApplicationServlet.java
index 5ba33b7778..324cd6cc12 100644
--- a/src/com/itmill/toolkit/terminal/gwt/server/ApplicationServlet.java
+++ b/src/com/itmill/toolkit/terminal/gwt/server/ApplicationServlet.java
@@ -1242,14 +1242,14 @@ public class ApplicationServlet extends HttpServlet {
* @param application
* @return AJAX Application Manager
*/
- private ApplicationManager getApplicationManager(Application application) {
- ApplicationManager mgr = (ApplicationManager) applicationToAjaxAppMgrMap
+ private CommunicationManager getApplicationManager(Application application) {
+ CommunicationManager mgr = (CommunicationManager) applicationToAjaxAppMgrMap
.get(application);
// This application is going from Web to AJAX mode, create new manager
if (mgr == null) {
// Creates new manager
- mgr = new ApplicationManager(application, this);
+ mgr = new CommunicationManager(application, this);
applicationToAjaxAppMgrMap.put(application, mgr);
// Manager takes control over the application
diff --git a/src/com/itmill/toolkit/terminal/gwt/server/ApplicationManager.java b/src/com/itmill/toolkit/terminal/gwt/server/CommunicationManager.java
index 3a3c27af53..b2bcc68ee5 100644
--- a/src/com/itmill/toolkit/terminal/gwt/server/ApplicationManager.java
+++ b/src/com/itmill/toolkit/terminal/gwt/server/CommunicationManager.java
@@ -40,12 +40,15 @@ import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.GregorianCalendar;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -65,6 +68,7 @@ import com.itmill.toolkit.terminal.DownloadStream;
import com.itmill.toolkit.terminal.PaintTarget;
import com.itmill.toolkit.terminal.Paintable;
import com.itmill.toolkit.terminal.URIHandler;
+import com.itmill.toolkit.terminal.VariableOwner;
import com.itmill.toolkit.terminal.Paintable.RepaintRequestEvent;
import com.itmill.toolkit.ui.Component;
import com.itmill.toolkit.ui.FrameWindow;
@@ -79,9 +83,8 @@ import com.itmill.toolkit.ui.Window;
* @VERSION@
* @since 5.0
*/
-public class ApplicationManager implements
- Paintable.RepaintRequestListener, Application.WindowAttachListener,
- Application.WindowDetachListener {
+public class CommunicationManager implements Paintable.RepaintRequestListener,
+ Application.WindowAttachListener, Application.WindowDetachListener {
private static String GET_PARAM_REPAINT_ALL = "repaintAll";
@@ -93,9 +96,9 @@ public class ApplicationManager implements
private HashSet dirtyPaintabletSet = new HashSet();
+ private WeakHashMap paintableIdMap = new WeakHashMap();
- // TODO THIS TEMPORARY HACK IS ONLY HERE TO MAKE GWT DEVEL EASIER
- static WeakHashMap paintableIdMap = new WeakHashMap();
+ private WeakHashMap idPaintableMap = new WeakHashMap();
private int idSequence = 0;
@@ -104,14 +107,15 @@ public class ApplicationManager implements
private Set removedWindows = new HashSet();
private JsonPaintTarget paintTarget;
-
+
private List locales;
-
+
private int pendingLocalesIndex;
-
+
private ApplicationServlet applicationServlet;
- public ApplicationManager(Application application, ApplicationServlet applicationServlet) {
+ public CommunicationManager(Application application,
+ ApplicationServlet applicationServlet) {
this.application = application;
this.applicationServlet = applicationServlet;
requireLocale(application.getLocale().toString());
@@ -119,20 +123,6 @@ public class ApplicationManager implements
/**
*
- * @return
- */
- private AjaxVariableMap getVariableMap() {
- AjaxVariableMap vm = (AjaxVariableMap) applicationToVariableMapMap
- .get(application);
- if (vm == null) {
- vm = new AjaxVariableMap();
- applicationToVariableMapMap.put(application, vm);
- }
- return vm;
- }
-
- /**
- *
*
*/
public void takeControl() {
@@ -150,7 +140,6 @@ public class ApplicationManager implements
application.removeListener((Application.WindowDetachListener) this);
}
-
public void handleUidlRequest(HttpServletRequest request,
HttpServletResponse response) throws IOException {
@@ -161,8 +150,10 @@ public class ApplicationManager implements
OutputStream out = response.getOutputStream();
PrintWriter outWriter = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(out, "UTF-8")));
-
- outWriter.print(")/*{"); // some dirt to prevent cross site scripting vulnerabilities
+
+ // TODO Move dirt elsewhere
+ outWriter.print(")/*{"); // some dirt to prevent cross site scripting
+ // vulnerabilities
try {
@@ -175,8 +166,7 @@ public class ApplicationManager implements
synchronized (application) {
// Change all variables based on request parameters
- Map unhandledParameters = getVariableMap().handleVariables(
- request, application);
+ Map unhandledParameters = handleVariables(request, application);
// Handles the URI if the application is still running
if (application.isRunning())
@@ -209,16 +199,15 @@ public class ApplicationManager implements
// Sets the response type
response.setContentType("application/json; charset=UTF-8");
outWriter.print("\"changes\":[");
-
- paintTarget = new JsonPaintTarget(getVariableMap(),
- this, outWriter);
+
+ paintTarget = new JsonPaintTarget(this, outWriter);
// Paints components
Set paintables;
if (repaintAll) {
paintables = new LinkedHashSet();
paintables.add(window);
-
+
// Reset sent locales
locales = null;
requireLocale(application.getLocale().toString());
@@ -309,210 +298,81 @@ public class ApplicationManager implements
}
}
-
- paintTarget.close();
+ paintTarget.close();
outWriter.print("]"); // close changes
+ outWriter.print(", \"meta\" : {");
+ boolean metaOpen = false;
+
+ // .. or initializion (first uidl-request)
+ if (application.ajaxInit()) {
+ outWriter.print("\"appInit\":true");
+ }
+ // add meta instruction for client to set focus if it is set
+ Paintable f = (Paintable) application.consumeFocus();
+ if (f != null) {
+ if (metaOpen)
+ outWriter.append(",");
+ outWriter.write("\"focus\":\"" + getPaintableId(f)
+ + "\"");
+ }
+
+ outWriter.print("}, \"resources\" : {");
+
+ // Precache custom layouts
+ // TODO Does not support theme-get param or different themes
+ // in different windows -> Allways preload layouts with the
+ // theme specified by the applications
+ String themeName = application.getTheme() != null ? application
+ .getTheme()
+ : ApplicationServlet.DEFAULT_THEME;
+ // TODO We should only precache the layouts that are not
+ // cached already
+ int resourceIndex = 0;
+ for (Iterator i = paintTarget.getPreCachedResources()
+ .iterator(); i.hasNext();) {
+ String resource = (String) i.next();
+ InputStream is = null;
+ try {
+ is = applicationServlet
+ .getServletContext()
+ .getResourceAsStream(
+ ApplicationServlet.THEME_DIRECTORY_PATH
+ + themeName
+ + "/"
+ + resource);
+ } catch (Exception e) {
+ Log.info(e.getMessage());
+ }
+ if (is != null) {
+
+ outWriter.print((resourceIndex++ > 0 ? ", " : "")
+ + "\"" + resource + "\" : ");
+ StringBuffer layout = new StringBuffer();
+
+ try {
+ InputStreamReader r = new InputStreamReader(is);
+ char[] buffer = new char[20000];
+ int charsRead = 0;
+ while ((charsRead = r.read(buffer)) > 0)
+ layout.append(buffer, 0, charsRead);
+ r.close();
+ } catch (java.io.IOException e) {
+ Log.info("Resource transfer failed: "
+ + request.getRequestURI() + ". ("
+ + e.getMessage() + ")");
+ }
+ outWriter.print("\""
+ + JsonPaintTarget.escapeJSON(layout
+ .toString()) + "\"");
+ }
+ }
+ outWriter.print("}");
+
+ printLocaleDeclarations(outWriter);
- // Render the removed windows
- // TODO refactor commented area to send some meta instructions to close window
-// Set removed = new HashSet(getRemovedWindows());
-// if (removed.size() > 0) {
-// for (Iterator i = removed.iterator(); i.hasNext();) {
-// Window w = (Window) i.next();
-// paintTarget.startTag("change");
-// paintTarget.addAttribute("format", "uidl");
-// String pid = getPaintableId(w);
-// paintTarget.addAttribute("pid", pid);
-// paintTarget.addAttribute("windowname", w.getName());
-// paintTarget.addAttribute("visible", false);
-// paintTarget.endTag("change");
-// removedWindowNotified(w);
-//
-// }
-// }
-
-
-
- outWriter.print(", \"meta\" : {");
- boolean metaOpen = false;
-
-
- // .. or initializion (first uidl-request)
- if(application.ajaxInit()) {
- outWriter.print("\"appInit\":true");
- }
- // add meta instruction for client to set focus if it is set
- Paintable f = (Paintable) application.consumeFocus();
- if(f != null) {
- if(metaOpen)
- outWriter.append(",");
- outWriter.write("\"focus\":\""+ getPaintableId(f) +"\"");
- }
-
- outWriter.print("}, \"resources\" : {");
-
- // Precache custom layouts
- // TODO Does not support theme-get param or different themes in different windows -> Allways preload layouts with the theme specified by the applications
- String themeName = application.getTheme() != null ? application.getTheme() : ApplicationServlet.DEFAULT_THEME;
- // TODO We should only precache the layouts that are not cached already
- int resourceIndex = 0;
- for (Iterator i=paintTarget.getPreCachedResources().iterator(); i.hasNext();) {
- String resource = (String) i.next();
- InputStream is = null;
- try {
- is = applicationServlet.getServletContext().getResourceAsStream(ApplicationServlet.THEME_DIRECTORY_PATH + themeName + "/" + resource);
- } catch (Exception e) {
- Log.info(e.getMessage());
- }
- if (is != null) {
-
- outWriter.print((resourceIndex++ > 0 ? ", " : "") + "\""+resource + "\" : ");
- StringBuffer layout = new StringBuffer();
-
- try {
- InputStreamReader r = new InputStreamReader(is);
- char[] buffer = new char[20000];
- int charsRead = 0;
- while ((charsRead = r.read(buffer)) > 0)
- layout.append(buffer, 0, charsRead);
- r.close();
- } catch (java.io.IOException e) {
- Log.info("Resource transfer failed: " + request.getRequestURI()
- + ". (" + e.getMessage() + ")");
- }
- outWriter.print("\"" + JsonPaintTarget.escapeJSON(layout.toString()) + "\"");
- }
- }
- outWriter.print("}");
-
-
- /* -----------------------------
- * Sending Locale sensitive date
- * -----------------------------
- */
-
- // Store JVM default locale for later restoration
- // (we'll have to change the default locale for a while)
- Locale jvmDefault = Locale.getDefault();
-
- // Send locale informations to client
- outWriter.print(", \"locales\":[");
- for(;pendingLocalesIndex < locales.size(); pendingLocalesIndex++) {
-
- Locale l = generateLocale((String) locales.get(pendingLocalesIndex));
- // Locale name
- outWriter.print("{\"name\":\"" + l.toString() + "\",");
-
- /*
- * Month names (both short and full)
- */
- DateFormatSymbols dfs = new DateFormatSymbols(l);
- String[] short_months = dfs.getShortMonths();
- String[] months = dfs.getMonths();
- outWriter.print("\"smn\":[\"" + // ShortMonthNames
- short_months[0] + "\",\"" +
- short_months[1] + "\",\"" +
- short_months[2] + "\",\"" +
- short_months[3] + "\",\"" +
- short_months[4] + "\",\"" +
- short_months[5] + "\",\"" +
- short_months[6] + "\",\"" +
- short_months[7] + "\",\"" +
- short_months[8] + "\",\"" +
- short_months[9] + "\",\"" +
- short_months[10] + "\",\"" +
- short_months[11] + "\"" +
- "],");
- outWriter.print("\"mn\":[\"" + // MonthNames
- months[0] + "\",\"" +
- months[1] + "\",\"" +
- months[2] + "\",\"" +
- months[3] + "\",\"" +
- months[4] + "\",\"" +
- months[5] + "\",\"" +
- months[6] + "\",\"" +
- months[7] + "\",\"" +
- months[8] + "\",\"" +
- months[9] + "\",\"" +
- months[10] + "\",\"" +
- months[11] + "\"" +
- "],");
-
- /*
- * Weekday names (both short and full)
- */
- String[] short_days = dfs.getShortWeekdays();
- String[] days = dfs.getWeekdays();
- outWriter.print("\"sdn\":[\"" + // ShortDayNames
- short_days[1] + "\",\"" +
- short_days[2] + "\",\"" +
- short_days[3] + "\",\"" +
- short_days[4] + "\",\"" +
- short_days[5] + "\",\"" +
- short_days[6] + "\",\"" +
- short_days[7] + "\"" +
- "],");
- outWriter.print("\"dn\":[\"" + // DayNames
- days[1] + "\",\"" +
- days[2] + "\",\"" +
- days[3] + "\",\"" +
- days[4] + "\",\"" +
- days[5] + "\",\"" +
- days[6] + "\",\"" +
- days[7] + "\"" +
- "],");
-
- /*
- * First day of week (0 = sunday, 1 = monday)
- */
- Calendar cal = new GregorianCalendar(l);
- outWriter.print("\"fdow\":" + (cal.getFirstDayOfWeek() - 1) + ",");
-
- /*
- * Date formatting (MM/DD/YYYY etc.)
- */
- // Force our locale as JVM default for a while (SimpleDateFormat uses JVM default)
- Locale.setDefault(l);
- String df = new SimpleDateFormat().toPattern();
- int timeStart = df.indexOf("H");
- if(timeStart < 0)
- timeStart = df.indexOf("h");
- int ampm_first = df.indexOf("a");
- // E.g. in Korean locale AM/PM is before h:mm
- // TODO should take that into consideration on client-side as well, now always h:mm a
- if(ampm_first > 0 && ampm_first < timeStart)
- timeStart = ampm_first;
- String dateformat = df.substring(0, timeStart-1);
-
- outWriter.print("\"df\":\"" + dateformat.trim() + "\",");
-
- /*
- * Time formatting (24 or 12 hour clock and AM/PM suffixes)
- */
- String timeformat = df.substring(timeStart, df.length()); // Doesn't return second or milliseconds
- // We use timeformat to determine 12/24-hour clock
- boolean twelve_hour_clock = timeformat.contains("a");
- // TODO there are other possibilities as well, like 'h' in french (ignore them, too complicated)
- String hour_min_delimiter = timeformat.contains(".")? "." : ":";
- //outWriter.print("\"tf\":\"" + timeformat + "\",");
- outWriter.print("\"thc\":" + twelve_hour_clock + ",");
- outWriter.print("\"hmd\":\"" + hour_min_delimiter + "\"");
- if(twelve_hour_clock) {
- String[] ampm = dfs.getAmPmStrings();
- outWriter.print(",\"ampm\":[\""+ampm[0]+"\",\""+ampm[1]+"\"]");
- }
- outWriter.print("}");
- if(pendingLocalesIndex < locales.size()-1)
- outWriter.print(",");
- }
- outWriter.print("]"); // Close locales
-
- // Restore JVM default locale
- Locale.setDefault(jvmDefault);
-
- outWriter.flush();
- outWriter.close();
+ outWriter.flush();
+ outWriter.close();
out.flush();
} else {
@@ -540,6 +400,184 @@ public class ApplicationManager implements
}
+ private Map handleVariables(HttpServletRequest request,
+ Application application2) {
+
+ Map params = new HashMap(request.getParameterMap());
+ String changes = (String) ((params.get("changes") instanceof String[]) ? ((String[]) params
+ .get("changes"))[0]
+ : params.get("changes"));
+ params.remove("changes");
+ if (changes != null) {
+ String[] ca = changes.split("\u0001");
+ System.out.println("Changes = " + changes);
+ for (int i = 0; i < ca.length; i++) {
+ String[] vid = ca[i].split("_");
+ VariableOwner owner = (VariableOwner) idPaintableMap
+ .get(vid[0]);
+ if (owner != null) {
+ Map m;
+ if (i + 2 >= ca.length
+ || !vid[0].equals(ca[i + 2].split("_")[0]))
+ m = new SingleValueMap(vid[1], convertVariableValue(
+ vid[2].charAt(0), ca[++i]));
+ else {
+ m = new HashMap();
+ m.put(vid[1], convertVariableValue(vid[2].charAt(0),
+ ca[++i]));
+ }
+ while (i + 1 < ca.length
+ && vid[0].equals(ca[i + 1].split("_")[0])) {
+ vid = ca[++i].split("_");
+ m.put(vid[1], convertVariableValue(vid[2].charAt(0),
+ ca[++i]));
+ }
+ owner.changeVariables(request, m);
+ }
+ }
+ }
+
+ return params;
+ }
+
+ private Object convertVariableValue(char variableType, String strValue) {
+ Object val = null;
+ System.out.println("converting " + strValue + " of type "
+ + variableType);
+ switch (variableType) {
+ case 'a':
+ val = strValue.split(",");
+ break;
+ case 's':
+ val = strValue;
+ break;
+ case 'i':
+ val = Integer.valueOf(strValue);
+ break;
+ case 'b':
+ val = Boolean.valueOf(strValue);
+ break;
+ }
+
+ System.out.println("result: " + val + " of type " + (val == null ? "-" : val.getClass()));
+ return val;
+ }
+
+ private void printLocaleDeclarations(PrintWriter outWriter) {
+ /*
+ * ----------------------------- Sending Locale sensitive date
+ * -----------------------------
+ */
+
+ // Store JVM default locale for later restoration
+ // (we'll have to change the default locale for a while)
+ Locale jvmDefault = Locale.getDefault();
+
+ // Send locale informations to client
+ outWriter.print(", \"locales\":[");
+ for (; pendingLocalesIndex < locales.size(); pendingLocalesIndex++) {
+
+ Locale l = generateLocale((String) locales.get(pendingLocalesIndex));
+ // Locale name
+ outWriter.print("{\"name\":\"" + l.toString() + "\",");
+
+ /*
+ * Month names (both short and full)
+ */
+ DateFormatSymbols dfs = new DateFormatSymbols(l);
+ String[] short_months = dfs.getShortMonths();
+ String[] months = dfs.getMonths();
+ outWriter.print("\"smn\":[\""
+ + // ShortMonthNames
+ short_months[0] + "\",\"" + short_months[1] + "\",\""
+ + short_months[2] + "\",\"" + short_months[3] + "\",\""
+ + short_months[4] + "\",\"" + short_months[5] + "\",\""
+ + short_months[6] + "\",\"" + short_months[7] + "\",\""
+ + short_months[8] + "\",\"" + short_months[9] + "\",\""
+ + short_months[10] + "\",\"" + short_months[11] + "\""
+ + "],");
+ outWriter.print("\"mn\":[\""
+ + // MonthNames
+ months[0] + "\",\"" + months[1] + "\",\"" + months[2]
+ + "\",\"" + months[3] + "\",\"" + months[4] + "\",\""
+ + months[5] + "\",\"" + months[6] + "\",\"" + months[7]
+ + "\",\"" + months[8] + "\",\"" + months[9] + "\",\""
+ + months[10] + "\",\"" + months[11] + "\"" + "],");
+
+ /*
+ * Weekday names (both short and full)
+ */
+ String[] short_days = dfs.getShortWeekdays();
+ String[] days = dfs.getWeekdays();
+ outWriter.print("\"sdn\":[\""
+ + // ShortDayNames
+ short_days[1] + "\",\"" + short_days[2] + "\",\""
+ + short_days[3] + "\",\"" + short_days[4] + "\",\""
+ + short_days[5] + "\",\"" + short_days[6] + "\",\""
+ + short_days[7] + "\"" + "],");
+ outWriter.print("\"dn\":[\""
+ + // DayNames
+ days[1] + "\",\"" + days[2] + "\",\"" + days[3] + "\",\""
+ + days[4] + "\",\"" + days[5] + "\",\"" + days[6] + "\",\""
+ + days[7] + "\"" + "],");
+
+ /*
+ * First day of week (0 = sunday, 1 = monday)
+ */
+ Calendar cal = new GregorianCalendar(l);
+ outWriter.print("\"fdow\":" + (cal.getFirstDayOfWeek() - 1) + ",");
+
+ /*
+ * Date formatting (MM/DD/YYYY etc.)
+ */
+ // Force our locale as JVM default for a while (SimpleDateFormat
+ // uses JVM default)
+ Locale.setDefault(l);
+ String df = new SimpleDateFormat().toPattern();
+ int timeStart = df.indexOf("H");
+ if (timeStart < 0)
+ timeStart = df.indexOf("h");
+ int ampm_first = df.indexOf("a");
+ // E.g. in Korean locale AM/PM is before h:mm
+ // TODO should take that into consideration on client-side as well,
+ // now always h:mm a
+ if (ampm_first > 0 && ampm_first < timeStart)
+ timeStart = ampm_first;
+ String dateformat = df.substring(0, timeStart - 1);
+
+ outWriter.print("\"df\":\"" + dateformat.trim() + "\",");
+
+ /*
+ * Time formatting (24 or 12 hour clock and AM/PM suffixes)
+ */
+ String timeformat = df.substring(timeStart, df.length()); // Doesn't
+ // return
+ // second
+ // or
+ // milliseconds
+ // We use timeformat to determine 12/24-hour clock
+ boolean twelve_hour_clock = timeformat.contains("a");
+ // TODO there are other possibilities as well, like 'h' in french
+ // (ignore them, too complicated)
+ String hour_min_delimiter = timeformat.contains(".") ? "." : ":";
+ // outWriter.print("\"tf\":\"" + timeformat + "\",");
+ outWriter.print("\"thc\":" + twelve_hour_clock + ",");
+ outWriter.print("\"hmd\":\"" + hour_min_delimiter + "\"");
+ if (twelve_hour_clock) {
+ String[] ampm = dfs.getAmPmStrings();
+ outWriter.print(",\"ampm\":[\"" + ampm[0] + "\",\"" + ampm[1]
+ + "\"]");
+ }
+ outWriter.print("}");
+ if (pendingLocalesIndex < locales.size() - 1)
+ outWriter.print(",");
+ }
+ outWriter.print("]"); // Close locales
+
+ // Restore JVM default locale
+ Locale.setDefault(jvmDefault);
+ }
+
/**
* Gets the existing application or create a new one. Get a window within an
* application based on the requested URI.
@@ -743,6 +781,7 @@ public class ApplicationManager implements
if (id == null) {
id = "PID" + Integer.toString(idSequence++);
paintableIdMap.put(paintable, id);
+ idPaintableMap.put(id, paintable);
}
return id;
@@ -873,6 +912,91 @@ public class ApplicationManager implements
this.removedWindows.remove(w);
}
+ private final class SingleValueMap implements Map {
+ private final String name;
+
+ private final Object value;
+
+ private SingleValueMap(String name, Object value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean containsKey(Object key) {
+ if (name == null)
+ return key == null;
+ return name.equals(key);
+ }
+
+ public boolean containsValue(Object v) {
+ if (value == null)
+ return v == null;
+ return value.equals(v);
+ }
+
+ public Set entrySet() {
+ Set s = new HashSet();
+ s.add(new Map.Entry() {
+
+ public Object getKey() {
+ return name;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public Object setValue(Object value) {
+ throw new UnsupportedOperationException();
+ }
+ });
+ return s;
+ }
+
+ public Object get(Object key) {
+ if (!name.equals(key))
+ return null;
+ return value;
+ }
+
+ public boolean isEmpty() {
+ return false;
+ }
+
+ public Set keySet() {
+ Set s = new HashSet();
+ s.add(name);
+ return s;
+ }
+
+ public Object put(Object key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void putAll(Map t) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ public int size() {
+ return 1;
+ }
+
+ public Collection values() {
+ LinkedList s = new LinkedList();
+ s.add(value);
+ return s;
+
+ }
+ }
+
/**
* Implementation of URIHandler.ErrorEvent interface.
*/
@@ -908,20 +1032,20 @@ public class ApplicationManager implements
}
public void requireLocale(String value) {
- if(locales == null) {
+ if (locales == null) {
locales = new ArrayList();
locales.add(application.getLocale().toString());
pendingLocalesIndex = 0;
}
- if(!locales.contains(value))
- locales.add(value);
+ if (!locales.contains(value))
+ locales.add(value);
}
-
+
private Locale generateLocale(String value) {
String[] temp = value.split("_");
- if(temp.length == 1)
+ if (temp.length == 1)
return new Locale(temp[0]);
- else if(temp.length == 2)
+ else if (temp.length == 2)
return new Locale(temp[0], temp[1]);
else
return new Locale(temp[0], temp[1], temp[2]);
diff --git a/src/com/itmill/toolkit/terminal/gwt/server/AjaxHttpUploadStream.java b/src/com/itmill/toolkit/terminal/gwt/server/HttpUploadStream.java
index e431d5126e..d6ee9b9bac 100644
--- a/src/com/itmill/toolkit/terminal/gwt/server/AjaxHttpUploadStream.java
+++ b/src/com/itmill/toolkit/terminal/gwt/server/HttpUploadStream.java
@@ -38,7 +38,7 @@ import java.io.InputStream;
* @VERSION@
* @since 5.0
*/
-public class AjaxHttpUploadStream implements
+public class HttpUploadStream implements
com.itmill.toolkit.terminal.UploadStream {
/**
@@ -67,7 +67,7 @@ public class AjaxHttpUploadStream implements
* @param contentType
* the type of the content.
*/
- public AjaxHttpUploadStream(String name, InputStream stream,
+ public HttpUploadStream(String name, InputStream stream,
String contentName, String contentType) {
this.streamName = name;
this.stream = stream;
diff --git a/src/com/itmill/toolkit/terminal/gwt/server/JsonPaintTarget.java b/src/com/itmill/toolkit/terminal/gwt/server/JsonPaintTarget.java
index 6e4662e557..8095141895 100644
--- a/src/com/itmill/toolkit/terminal/gwt/server/JsonPaintTarget.java
+++ b/src/com/itmill/toolkit/terminal/gwt/server/JsonPaintTarget.java
@@ -78,11 +78,9 @@ public class JsonPaintTarget implements PaintTarget {
private PrintWriter uidlBuffer;
- private AjaxVariableMap variableMap;
-
private boolean closed = false;
- private ApplicationManager manager;
+ private CommunicationManager manager;
private boolean trackPaints = false;
@@ -106,13 +104,11 @@ public class JsonPaintTarget implements PaintTarget {
* @throws PaintException
* if the paint operation failed.
*/
- public JsonPaintTarget(AjaxVariableMap variableMap,
- ApplicationManager manager, PrintWriter outWriter)
+ public JsonPaintTarget(
+ CommunicationManager manager, PrintWriter outWriter)
throws PaintException {
this.manager = manager;
- // Sets the variable map
- this.variableMap = variableMap;
// Sets the target for UIDL writing
this.uidlBuffer = outWriter;
@@ -561,10 +557,7 @@ public class JsonPaintTarget implements PaintTarget {
*/
public void addUploadStreamVariable(VariableOwner owner, String name)
throws PaintException {
- String code = variableMap.registerVariable(name, UploadStream.class,
- null, owner);
startTag("uploadstream");
- addAttribute(UIDL_ARG_ID, code);
addAttribute(UIDL_ARG_NAME, name);
endTag("uploadstream");
}
@@ -750,8 +743,6 @@ public class JsonPaintTarget implements PaintTarget {
Vector attr = new Vector();
- private HashMap childTagCounters = new HashMap();
-
StringBuffer data = new StringBuffer();
public boolean childrenArrayOpen = false;
@@ -891,21 +882,18 @@ public class JsonPaintTarget implements PaintTarget {
}
abstract class Variable {
- String code;
String name;
public abstract String getJsonPresentation();
}
-
+
class BooleanVariable extends Variable {
boolean value;
public BooleanVariable(VariableOwner owner, String name, boolean v) {
value = v;
this.name = name;
- code = variableMap.registerVariable(name, Boolean.class,
- new Boolean(value), owner);
}
public String getJsonPresentation() {
@@ -920,8 +908,6 @@ public class JsonPaintTarget implements PaintTarget {
public StringVariable(VariableOwner owner, String name, String v) {
value = v;
this.name = name;
- code = variableMap.registerVariable(name, String.class, value,
- owner);
}
public String getJsonPresentation() {
@@ -936,8 +922,6 @@ public class JsonPaintTarget implements PaintTarget {
public IntVariable(VariableOwner owner, String name, int v) {
value = v;
this.name = name;
- code = variableMap.registerVariable(name, Integer.class,
- new Integer(value), owner);
}
public String getJsonPresentation() {
@@ -951,8 +935,6 @@ public class JsonPaintTarget implements PaintTarget {
public ArrayVariable(VariableOwner owner, String name, String[] v) {
value = v;
this.name = name;
- code = variableMap.registerVariable(name, String[].class, value,
- owner);
}
public String getJsonPresentation() {
diff --git a/src/com/itmill/toolkit/terminal/gwt/server/Log.java b/src/com/itmill/toolkit/terminal/gwt/server/Log.java
index 7a84341543..27bd738c62 100644
--- a/src/com/itmill/toolkit/terminal/gwt/server/Log.java
+++ b/src/com/itmill/toolkit/terminal/gwt/server/Log.java
@@ -55,9 +55,9 @@ package com.itmill.toolkit.terminal.gwt.server;
* @author IT Mill Ltd.
* @version
* @VERSION@
- * @since 3.0
+ * @since 5.0
*/
-public class Log {
+class Log {
private static boolean useStdOut = true;
diff --git a/src/com/itmill/toolkit/terminal/gwt/server/MultipartRequest.java b/src/com/itmill/toolkit/terminal/gwt/server/MultipartRequest.java
deleted file mode 100644
index ae22f5bbbb..0000000000
--- a/src/com/itmill/toolkit/terminal/gwt/server/MultipartRequest.java
+++ /dev/null
@@ -1,1332 +0,0 @@
-/* *************************************************************************
-
- IT Mill Toolkit
-
- Development of Browser User Interfaces Made Easy
-
- 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
-
- *************************************************************************
-
- 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.gwt.server;
-
-import java.util.Hashtable;
-import java.io.BufferedOutputStream;
-import java.io.BufferedInputStream;
-import java.io.OutputStream;
-import java.io.InputStream;
-import java.io.PrintWriter;
-import java.io.ByteArrayOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.FileOutputStream;
-import java.io.UnsupportedEncodingException;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Vector;
-import java.io.File;
-
-/**
- * A Multipart form data parser. Parses an input stream and writes out any files
- * found, making available a hashtable of other url parameters. As of version
- * 1.17 the files can be saved to memory, and optionally written to a database,
- * etc.
- *
- * <BR>
- * <BR>
- * Copyright (C)2001 Jason Pell. <BR>
- *
- * <PRE>
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation; either version 2.1 of the License, or (at your option)
- * any later version. <BR>
- * This library is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details. <BR>
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA <BR>
- * Email: jasonpell@hotmail.com Url: http://www.geocities.com/jasonpell
- *
- * </PRE>
- *
- * @author Jason Pell
- *
- * @version 1.18 Fixed some serious bugs. A new method readAndWrite(InputStream
- * in, OutputStream out) which now does the generic processing in
- * common for readAndWriteFile and readFile. The differences are that
- * now the two extra bytes at the end of a file upload are processed
- * once, instead of after each line. Also if an empty file is
- * encountered, an outputstream is opened, but then deleted if no data
- * written to it. The <code>getCharArray</code> method has been
- * removed. Replaced by the new String(bytes, encoding) method using a
- * specific encoding (Defaults to ISO-8859-1) to ensure that extended
- * characters are supported. All strings are processed using this
- * encoding. The addition of static methods setEncoding(String) and
- * <code>getEncoding</code> method to allow the use of
- * <code>MultipartRequest</code> with a specific encoding type. All
- * instances of MultipartRequest will utilise the static charEncoding
- * variable value, that the <code>setEncoding</code> method can be
- * used to set. Started to introduce support for multiple file uploads
- * with the same form field name, but not completed for v1.18.
- * 26/06/2001
- *
- * @version 1.17 A few _very_ minor fixes. Plus a cool new feature added. The
- * ability to save files into memory. <b>Thanks to Mark Latham for the
- * idea and some of the code.</b> 11/04/2001
- * @version 1.16 Added support for multiple parameter values. Also fixed
- * getCharArray(...) method to support parameters with non-english
- * ascii values (ascii above 127). Thanks to Stefan Schmidt & Michael
- * Elvers for this. (No fix yet for reported problems with Tomcat 3.2
- * or a single extra byte appended to uploads of certain files). By
- * 1.17 hopefully will have a resolution for the second problem.
- * 14/03/2001
- * @version 1.15 A new parameter added, intMaxReadBytes, to allow arbitrary
- * length files. Released under the LGPL (Lesser General Public
- * License). 03/02/2001
- * @version 1.14 Fix for IE problem with filename being empty. This is because
- * IE includes a default Content-Type even when no file is uploaded.
- * 16/02/2001
- * @version 1.13 If an upload directory is not specified, then all file contents
- * are sent into oblivion, but the rest of the parsing works as normal.
- * @version 1.12 Fix, was allowing zero length files. Will not even create the
- * output file until there is something to write. getFile(String) now
- * returns null, if a zero length file was specified. 06/11/2000
- * @version 1.11 Fix, in case Content-type is not specified.
- * @version 1.1 Removed dependence on Servlets. Now passes in a generic
- * InputStream instead. "Borrowed" readLine from Tomcat 3.1
- * ServletInputStream class, so we can remove some of the dependencies
- * on ServletInputStream. Fixed bug where a empty INPUT TYPE="FILE"
- * value, would cause an exception.
- * @version 1.0 Initial Release.
- */
-
-public class MultipartRequest {
- /**
- * Defines Character Encoding method here.
- */
- private String charEncoding = "UTF-8";
-
- // If not null, send debugging out here.
- private PrintWriter debug = null;
-
- private Hashtable htParameters = null;
-
- private Hashtable htFiles = null;
-
- private String strBoundary = null;
-
- // If this Directory spec remains null, writing of files will be disabled...
- private File fileOutPutDirectory = null;
-
- private boolean loadIntoMemory = false;
-
- private long intContentLength = -1;
-
- private long intTotalRead = -1;
-
- /**
- * Prevent a denial of service by defining this, will never read more data.
- * If Content-Length is specified to be more than this, will throw an
- * exception.
- *
- * This limits the maximum number of bytes to the value of an int, which is
- * 2 Gigabytes.
- */
- public static final int MAX_READ_BYTES = Integer.MAX_VALUE;
-
- /**
- * Defines the number of bytes to read per readLine call. 128K
- */
- public static final int READ_LINE_BLOCK = 1024 * 128;
-
- /**
- * Store a read from the input stream here. Global so we do not keep
- * creating new arrays each read.
- */
- private byte[] blockOfBytes = null;
-
- /**
- * Type constant for File FILENAME.
- */
- public static final int FILENAME = 0;
-
- /**
- * Type constant for the File CONTENT_TYPE.
- */
- public static final int CONTENT_TYPE = 1;
-
- /**
- * Type constant for the File SIZE.
- */
- public static final int SIZE = 2;
-
- /**
- * Type constant for the File CONTENTS.
- *
- * <b>Note: </b>Only used for file upload to memory.
- */
- public static final int CONTENTS = 3;
-
- /**
- * This method should be called on the <code>MultipartRequest</code>
- * itself, not on any instances of <code>MultipartRequest</code>, because
- * this sets up the encoding for all instances of multipartrequest. You can
- * set the encoding to null, in which case the default encoding will be
- * applied. The default encoding if this method is not called has been set
- * to ISO-8859-1, which seems to offer the best hope of support for
- * international characters, such as german "Umlaut" characters.
- *
- * <p>
- * <b>Warning:</b> In multithreaded environments it is the responsibility
- * of the implementer to make sure that this method is not called while
- * another instance is being constructed. When an instance of
- * MultipartRequest is constructed, it parses the input data, and uses the
- * result of <code>getEncoding</code> method to convert between bytes and
- * strings. If <code>setEncoding</code> method is called by another
- * thread, while the private <code>parse</code> method is executing, the
- * method will utilise this new encoding, which may cause serious problems.
- * </p>
- */
- public void setEncoding(String enc) throws UnsupportedEncodingException {
- if (enc == null || enc.trim() == "")
- charEncoding = System.getProperty("file.encoding");
- else {
- // This will test the encoding for validity.
- new String(new byte[] { '\n' }, enc);
-
- charEncoding = enc;
- }
- }
-
- /**
- * Gets the current encoding method.
- *
- * @return the encoding method.
- */
- public String getEncoding() {
- return charEncoding;
- }
-
- /**
- * Constructor.
- *
- * @param strContentTypeText
- * the &quot;Content-Type&quot; HTTP header value.
- * @param intContentLength
- * the &quot;Content-Length&quot; HTTP header value.
- * @param in
- * the InputStream to read and parse.
- * @param strSaveDirectory
- * the temporary directory to save the file from where they can
- * then be moved to wherever by the calling process. <b>If you
- * specify <u>null</u> for this parameter, then any files
- * uploaded will be silently ignored.</b>
- *
- * @exception IllegalArgumentException
- * If the strContentTypeText does not contain a Content-Type
- * of "multipart/form-data" or the boundary is not found.
- * @exception IOException
- * If the intContentLength is higher than MAX_READ_BYTES or
- * strSaveDirectory is invalid or cannot be written to.
- *
- * @see #MAX_READ_BYTES
- */
- public MultipartRequest(String strContentTypeText, int intContentLength,
- InputStream in, String strSaveDirectory)
- throws IllegalArgumentException, IOException {
- this(null, strContentTypeText, intContentLength, in, strSaveDirectory,
- MAX_READ_BYTES);
- }
-
- /**
- * Constructor.
- *
- * @param strContentTypeText
- * the &quot;Content-Type&quot; HTTP header value.
- * @param intContentLength
- * the &quot;Content-Length&quot; HTTP header value.
- * @param in
- * the InputStream to read and parse.
- * @param strSaveDirectory
- * the temporary directory to save the file from where they can
- * then be moved to wherever by the calling process. <b>If you
- * specify <u>null</u> for this parameter, then any files
- * uploaded will be silently ignored.</B>
- * @param intMaxReadBytes
- * Overrides the MAX_BYTES_READ value, to allow arbitrarily long
- * files.
- *
- * @exception IllegalArgumentException
- * If the strContentTypeText does not contain a Content-Type
- * of "multipart/form-data" or the boundary is not found.
- * @exception IOException
- * If the intContentLength is higher than MAX_READ_BYTES or
- * strSaveDirectory is invalid or cannot be written to.
- *
- * @see #MAX_READ_BYTES
- */
- public MultipartRequest(String strContentTypeText, int intContentLength,
- InputStream in, String strSaveDirectory, int intMaxReadBytes)
- throws IllegalArgumentException, IOException {
- this(null, strContentTypeText, intContentLength, in, strSaveDirectory,
- intMaxReadBytes);
- }
-
- /**
- * Constructor.
- *
- * @param debug
- * A PrintWriter that can be used for debugging.
- * @param strContentTypeText
- * the &quot;Content-Type&quot; HTTP header value.
- * @param intContentLength
- * the &quot;Content-Length&quot; HTTP header value.
- * @param in
- * the InputStream to read and parse.
- * @param strSaveDirectory
- * the temporary directory to save the file from where they can
- * then be moved to wherever by the calling process. <b>If you
- * specify <u>null</u> for this parameter, then any files
- * uploaded will be silently ignored.</B>
- *
- * @exception IllegalArgumentException
- * If the strContentTypeText does not contain a Content-Type
- * of "multipart/form-data" or the boundary is not found.
- * @exception IOException
- * If the intContentLength is higher than MAX_READ_BYTES or
- * strSaveDirectory is invalid or cannot be written to.
- *
- * @see #MAX_READ_BYTES
- * @deprecated Replaced by MultipartRequest(PrintWriter, String, int,
- * InputStream, int) You can specify
- * MultipartRequest.MAX_READ_BYTES for the intMaxReadBytes
- * parameter
- */
- public MultipartRequest(PrintWriter debug, String strContentTypeText,
- int intContentLength, InputStream in, String strSaveDirectory)
- throws IllegalArgumentException, IOException {
- this(debug, strContentTypeText, intContentLength, in, strSaveDirectory,
- MAX_READ_BYTES);
-
- }
-
- /**
- * Constructor - load into memory constructor
- *
- * @param debug
- * A PrintWriter that can be used for debugging.
- * @param strContentTypeText
- * the &quot;Content-Type&quot; HTTP header value.
- * @param intContentLength
- * the &quot;Content-Length&quot; HTTP header value.
- * @param in
- * the InputStream to read and parse.
- * @param intMaxReadBytes
- * Overrides the MAX_BYTES_READ value, to allow arbitrarily long
- * files.
- *
- * @exception IllegalArgumentException
- * If the strContentTypeText does not contain a Content-Type
- * of "multipart/form-data" or the boundary is not found.
- * @exception IOException
- * If the intContentLength is higher than MAX_READ_BYTES or
- * strSaveDirectory is invalid or cannot be written to.
- *
- * @see #MAX_READ_BYTES
- */
- public MultipartRequest(PrintWriter debug, String strContentTypeText,
- int intContentLength, InputStream in, int intMaxReadBytes)
- throws IllegalArgumentException, IOException {
- this.loadIntoMemory = true;
-
- // Now initialise the object, which will actually call the parse method
- // to parse multipart stream.
- init(debug, strContentTypeText, intContentLength, in, intMaxReadBytes);
- }
-
- /**
- * Constructor.
- *
- * @param debug
- * A PrintWriter that can be used for debugging.
- * @param strContentTypeText
- * the &quot;Content-Type&quot; HTTP header value.
- * @param intContentLength
- * the &quot;Content-Length&quot; HTTP header value.
- * @param in
- * the InputStream to read and parse.
- * @param strSaveDirectory
- * the temporary directory to save the file from where they can
- * then be moved to wherever by the calling process. <b>If you
- * specify <u>null</u> for this parameter, then any files
- * uploaded will be silently ignored.</B>
- * @param intMaxReadBytes
- * Overrides the MAX_BYTES_READ value, to allow arbitrarily long
- * files.
- *
- * @exception IllegalArgumentException
- * If the strContentTypeText does not contain a Content-Type
- * of "multipart/form-data" or the boundary is not found.
- * @exception IOException
- * If the intContentLength is higher than MAX_READ_BYTES or
- * strSaveDirectory is invalid or cannot be written to.
- *
- * @see #MAX_READ_BYTES
- */
- public MultipartRequest(PrintWriter debug, String strContentTypeText,
- int intContentLength, InputStream in, String strSaveDirectory,
- int intMaxReadBytes) throws IllegalArgumentException, IOException {
- // IF strSaveDirectory == NULL, then we should ignore any files
- // uploaded.
- if (strSaveDirectory != null) {
- fileOutPutDirectory = new File(strSaveDirectory);
- if (!fileOutPutDirectory.exists())
- throw new IOException("Directory [" + strSaveDirectory
- + "] is invalid.");
- else if (!fileOutPutDirectory.canWrite())
- throw new IOException("Directory [" + strSaveDirectory
- + "] is readonly.");
- }
-
- // Now initialise the object, which will actually call the parse method
- // to parse multipart stream.
- init(debug, strContentTypeText, intContentLength, in, intMaxReadBytes);
- }
-
- /**
- * Initialise the parser.
- *
- * @param debug
- * A PrintWriter that can be used for debugging.
- * @param strContentTypeText
- * the &quot;Content-Type&quot; HTTP header value.
- * @param intContentLength
- * the &quot;Content-Length&quot; HTTP header value.
- * @param in
- * the InputStream to read and parse.
- * @param strSaveDirectory
- * the temporary directory to save the file from where they can
- * then be moved to wherever by the calling process. <b>If you
- * specify <u>null</u> for this parameter, then any files
- * uploaded will be silently ignored.</B>
- * @param intMaxReadBytes
- * Overrides the MAX_BYTES_READ value, to allow arbitrarily long
- * files.
- *
- * @exception IllegalArgumentException
- * If the strContentTypeText does not contain a Content-Type
- * of "multipart/form-data" or the boundary is not found.
- * @exception IOException
- * If the intContentLength is higher than MAX_READ_BYTES or
- * strSaveDirectory is invalid or cannot be written to.
- *
- * @see #MAX_READ_BYTES
- */
- private void init(PrintWriter debug, String strContentTypeText,
- int intContentLength, InputStream in, int intMaxReadBytes)
- throws IllegalArgumentException, IOException {
- // saves reference to debug stream for later.
- this.debug = debug;
-
- if (strContentTypeText != null
- && strContentTypeText.startsWith("multipart/form-data")
- && strContentTypeText.indexOf("boundary=") != -1)
- strBoundary = strContentTypeText.substring(
- strContentTypeText.indexOf("boundary=")
- + "boundary=".length()).trim();
- else {
- // <mtl,jpell>
- debug("ContentType = " + strContentTypeText);
- throw new IllegalArgumentException("Invalid Content Type.");
- }
-
- this.intContentLength = intContentLength;
- // FIX: 115
- if (intContentLength > intMaxReadBytes)
- throw new IOException("Content Length Error (" + intContentLength
- + " > " + intMaxReadBytes + ")");
-
- // Instantiate the hashtable...
- htParameters = new Hashtable();
- htFiles = new Hashtable();
- blockOfBytes = new byte[READ_LINE_BLOCK];
-
- // Now parse the data.
- parse(new BufferedInputStream(in));
-
- // No need for this once parse is complete.
- this.blockOfBytes = null;
- this.debug = null;
- this.strBoundary = null;
- }
-
- /**
- * Gets the value of the strName URLParameter. If more than one value for a
- * particular Parameter, will return the first. If an error occurs will
- * return null.
- *
- * @param strName
- * the form field name, used to upload the file. This identifies
- * the formfield location in the storage facility.
- * @return the value of the URL Parameter.
- */
- public String getURLParameter(String strName) {
- Object value = htParameters.get(strName);
- if (value instanceof Vector)
- return (String) ((Vector) value).firstElement();
- else
- return (String) htParameters.get(strName);
- }
-
- /**
- * Gets an enumeration of all values for the strName parameter. Even if a
- * single value for, will always return an enumeration, although it may
- * actually be empty if no value was encountered for strName or it is an
- * invalid parameter name.
- *
- * @param strName
- * the form field name, used to upload the file. This identifies
- * the formfield location in the storage facility.
- * @return the enumeration of all values.
- */
- public Enumeration getURLParameters(String strName) {
- Object value = htParameters.get(strName);
- if (value instanceof Vector)
- return ((Vector) value).elements();
- else {
- Vector vector = new Vector();
- if (value != null)
- vector.addElement(value);
- return vector.elements();
- }
- }
-
- /**
- * Gets the enumeration of all URL Parameters for the current HTTP Request.
- *
- * @return the enumeration of URl Parameters.
- */
- public Enumeration getParameterNames() {
- return htParameters.keys();
- }
-
- /**
- * Gets the enumeration of all INPUT TYPE=FILE parameter NAMES as
- * encountered during the upload.
- *
- * @return
- */
- public Enumeration getFileParameterNames() {
- return htFiles.keys();
- }
-
- /**
- * Returns the Content-Type of a file.
- *
- * @see #getFileParameter(java.lang.String, int)
- */
- public String getContentType(String strName) {
- // Can cast null, it will be ignored.
- return (String) getFileParameter(strName, CONTENT_TYPE);
- }
-
- /**
- * If files were uploaded into memory, this method will retrieve the
- * contents of the file as a InputStream.
- *
- * @param strName
- * the form field name, used to upload the file. This identifies
- * the formfield location in the storage facility.
- * @return the contents of the file as a InputStream, or null if not file
- * uploaded, or file uploaded to file system directory.
- * @see #getFileParameter(java.lang.String, int)
- */
- public InputStream getFileContents(String strName) {
- Object obj = getFileParameter(strName, CONTENTS);
- if (obj != null)
- return new ByteArrayInputStream((byte[]) obj);
- else
- return null;
- }
-
- /**
- * Returns a File reference to the uploaded file. This reference is to the
- * files uploaded location, and allows you to read/move/delete the file.
- * This method is only of use, if files were uploaded to the file system.
- * Will return null if uploaded to memory, in which case you should use
- * getFileContents(strName) instead.
- *
- * @param strName
- * the form field name, used to upload the file. This identifies
- * the formfield location in the storage facility.
- * @return a null file reference if a call to getFileSize(strName) returns
- * zero or files were uploaded to memory.
- * @see #getFileSize(java.lang.String)
- * @see #getFileContents(java.lang.String)
- * @see #getFileSystemName(java.lang.String)
- */
- public File getFile(String strName) {
- String filename = getFileSystemName(strName);
- // Fix: If fileOutPutDirectory is null, then we are ignoring any file
- // contents, so we must return null.
- if (filename != null && getFileSize(strName) > 0
- && fileOutPutDirectory != null)
- return new File(fileOutPutDirectory, filename);
- else
- return null;
- }
-
- /**
- * Gets the file system basename of an uploaded file.
- *
- * @param strName
- * the form field name, used to upload the file. This identifies
- * the formfield location in the storage facility.
- * @return null if strName not found.
- *
- * @see #getFileParameter(java.lang.String, int)
- */
- public String getFileSystemName(String strName) {
- // Can cast null, it will be ignored.
- return (String) getFileParameter(strName, FILENAME);
- }
-
- /**
- * Returns the File Size of a uploaded file.
- *
- * @param strName
- * the form field name, used to upload the file. This identifies
- * the formfield location in the storage facility.
- * @return -1 if file size not defined.
- *
- * @see #getFileParameter(java.lang.String, int)
- */
- public long getFileSize(String strName) {
- Object obj = getFileParameter(strName, SIZE);
- if (obj != null)
- return ((Long) obj).longValue();
- else
- return (long) -1;
- }
-
- /**
- * Access an attribute of a file upload parameter record.
- * <p>
- * The getFileSystemName(String strName),getFileSize(String
- * strName),getContentType(String strName), getContents(String strName)
- * methods all use this method passing in a different type argument.
- * </p>
- *
- * <p>
- * <b>Note: </b>This class has been changed to provide for future
- * functionality where you will be able to access all files uploaded, even
- * if they are uploaded using the same form field name. At this point
- * however, only the first file uploaded via a form field name is
- * accessible.
- * </p>
- *
- * @param strName
- * the form field name, used to upload the file. This identifies
- * the formfield location in the storage facility.
- *
- * @param type
- * What attribute you want from the File Parameter. The following
- * types are supported: MultipartRequest.FILENAME,
- * MultipartRequest.CONTENT_TYPE, MultipartRequest.SIZE,
- * MultipartRequest.CONTENTS
- *
- * @see #getContentType(java.lang.String)
- * @see #getFileSize(java.lang.String)
- * @see #getFileContents(java.lang.String)
- * @see #getFileSystemName(java.lang.String)
- */
- public Object getFileParameter(String strName, int type) {
- Object[] objArray = null;
- Object value = htFiles.get(strName);
- if (value instanceof Vector)
- objArray = (Object[]) ((Vector) value).firstElement();
- else
- objArray = (Object[]) htFiles.get(strName);
-
- // Now ensure valid value.
- if (objArray != null && type >= FILENAME && type <= CONTENTS)
- return objArray[type];
- else
- return null;
- }
-
- /**
- * This is the main parse method.
- *
- * @param in
- * the InputStream to read and parse.
- * @throws IOException
- * If the intContentLength is higher than MAX_READ_BYTES or
- * strSaveDirectory is invalid or cannot be written to.
- */
- private void parse(InputStream in) throws IOException {
- String strContentType = null;
- String strName = null;
- String strFilename = null;
- String strLine = null;
- int read = -1;
-
- // First run through, check that the first line is a boundary, otherwise
- // throw a exception as format incorrect.
- read = readLine(in, blockOfBytes);
- strLine = read > 0 ? new String(blockOfBytes, 0, read, charEncoding)
- : null;
-
- // Must be boundary at top of loop, otherwise we have finished.
- if (strLine == null || strLine.indexOf(this.strBoundary) == -1)
- // Just exit. Exception would be overkill
- return;
- // throw new IOException("Invalid Form Data, no boundary encountered.");
-
- // At the top of loop, we assume that the Content-Disposition line is
- // next, otherwise we are at the end.
- while (true) {
- // Get Content-Disposition line.
- read = readLine(in, blockOfBytes);
- if (read <= 0)
- break; // Nothing to do.
- else {
- strLine = new String(blockOfBytes, 0, read, charEncoding);
-
- // Mac IE4 adds extra line after last boundary - 1.21
- if (strLine == null || strLine.length() == 0
- || strLine.trim().length() == 0)
- break;
-
- strName = trimQuotes(getValue("name", strLine));
- // If this is not null, it indicates that we are processing a
- // filename.
- strFilename = trimQuotes(getValue("filename", strLine));
- // Now if not null, strip it of any directory information.
-
- if (strFilename != null) {
- // Fix: did not check whether filename was empty string
- // indicating FILE contents were not passed.
- if (strFilename.length() > 0) {
- // Need to get the content type.
- read = readLine(in, blockOfBytes);
- strLine = read > 0 ? new String(blockOfBytes, 0, read,
- charEncoding) : null;
-
- strContentType = "application/octet-stream";
- // Fix 1.11: If not null AND strLine.length() is long
- // enough.
- if (strLine != null
- && strLine.length() > "Content-Type: ".length())
- strContentType = strLine.substring("Content-Type: "
- .length());// Changed 1.13
- } else {
- // FIX 1.14: IE problem with empty filename.
- read = readLine(in, blockOfBytes);
- strLine = read > 0 ? new String(blockOfBytes, 0, read,
- charEncoding) : null;
-
- if (strLine != null
- && strLine.startsWith("Content-Type:"))
- readLine(in, blockOfBytes);
- }
- }
-
- // Ignore next line, as it should be blank.
- readLine(in, blockOfBytes);
-
- // No filename specified at all.
- if (strFilename == null) {
- String param = readParameter(in);
- addParameter(strName, param);
- } else {
- if (strFilename.length() > 0) {
- long filesize = -1;
- // Will remain null for read onto file system uploads.
- byte[] contentsOfFile = null;
-
- // Get the BASENAME version of strFilename.
- strFilename = getBasename(strFilename);
-
- // Are we loading files into memory instead of the
- // filesystem?
- if (loadIntoMemory) {
- contentsOfFile = readFile(in);
- if (contentsOfFile != null)
- filesize = contentsOfFile.length;
- } else
- // Read the file onto file system.
- filesize = readAndWriteFile(in, strFilename);
-
- // Fix 1.18 for multiple FILE parameter values.
- if (filesize > 0)
- addFileParameter(strName, new Object[] {
- strFilename, strContentType,
- new Long(filesize), contentsOfFile });
- else
- // Zero length file.
- addFileParameter(strName, new Object[] {
- strFilename, null, new Long(0), null });
- } else // Fix: FILE INPUT TYPE, but no file passed as
- // input...
- {
- addFileParameter(strName, new Object[] { null, null,
- null, null });
- readLine(in, blockOfBytes);
- }
- }
- }
- }// while
- }
-
- /**
- * So we can put the logic for supporting multiple parameters with the same
- * form field name in the one location.
- *
- * @param strName
- * the form field name, used to upload the file. This identifies
- * the formfield location in the storage facility.
- * @param value
- * the form field value.
- */
- private void addParameter(String strName, String value) {
- // Fix NPE in case of null name
- if (strName == null)
- return;
-
- // Fix 1.16: for multiple parameter values.
- Object objParms = htParameters.get(strName);
-
- // Adds an new entry to the param vector.
- if (objParms instanceof Vector)
- ((Vector) objParms).addElement(value);
- else if (objParms instanceof String)// There is only one entry, so we
- // create a vector!
- {
- Vector vecParms = new Vector();
- vecParms.addElement(objParms);
- vecParms.addElement(value);
-
- htParameters.put(strName, vecParms);
- } else
- // first entry for strName.
- htParameters.put(strName, value);
- }
-
- /**
- * So we can put the logic for supporting multiple files with the same form
- * field name in the one location.
- *
- * Assumes that this method will never be called with a null fileObj or
- * strFilename.
- *
- * @param strName
- * the form field name, used to upload the file. This identifies
- * the formfield location in the storage facility.
- * @param fileObj
- */
- private void addFileParameter(String strName, Object[] fileObj) {
- Object objParms = htFiles.get(strName);
-
- // Add an new entry to the param vector.
- if (objParms instanceof Vector)
- ((Vector) objParms).addElement(fileObj);
- else if (objParms instanceof Object[])// There is only one entry, so
- // we create a vector!
- {
- Vector vecParms = new Vector();
- vecParms.addElement(objParms);
- vecParms.addElement(fileObj);
-
- htFiles.put(strName, vecParms);
- } else
- // first entry for strName.
- htFiles.put(strName, fileObj);
- }
-
- /**
- * Reads the parameters, assume already passed Content-Disposition and blank
- * line.
- *
- * @param in
- * the InputStream to read and parse.
- * @return the value read in.
- * @throws IOException
- * if an error occurs writing the file.
- */
- private String readParameter(InputStream in) throws IOException {
- StringBuffer buf = new StringBuffer();
- int read = -1;
-
- String line = null;
- while (true) {
- read = readLine(in, blockOfBytes);
- if (read < 0)
- throw new IOException("Stream ended prematurely.");
-
- // Change v1.18: Only instantiate string once for performance
- // reasons.
- line = new String(blockOfBytes, 0, read, charEncoding);
- if (read < blockOfBytes.length
- && line.indexOf(this.strBoundary) != -1)
- break; // Boundary found, we need to finish up.
- else
- buf.append(line);
- }
-
- if (buf.length() > 0)
- buf.setLength(getLengthMinusEnding(buf));
- return buf.toString();
- }
-
- /**
- * Read from in, write to out, minus last two line ending bytes.
- *
- * @param in
- * the InputStream to read and parse.
- * @param out
- * the OutputStream.
- * @throws IOException
- * if an error occurs writing the file.
- */
- private long readAndWrite(InputStream in, OutputStream out)
- throws IOException {
- long fileSize = 0;
- int read = -1;
-
- // This variable will be assigned the bytes actually read.
- byte[] secondLineOfBytes = new byte[blockOfBytes.length];
- // So we do not have to keep creating the second array.
- int sizeOfSecondArray = 0;
-
- while (true) {
- read = readLine(in, blockOfBytes);
- if (read < 0)
- throw new IOException("Stream ended prematurely.");
-
- // Found boundary.
- if (read < blockOfBytes.length
- && new String(blockOfBytes, 0, read, charEncoding)
- .indexOf(this.strBoundary) != -1) {
- // Writes the line, minus any line ending bytes.
- // The secondLineOfBytes will NEVER BE NON-NULL if out==null, so
- // there is no need to included this in the test
- if (sizeOfSecondArray != 0) {
- // Only used once, so declare here.
- int actualLength = getLengthMinusEnding(secondLineOfBytes,
- sizeOfSecondArray);
- if (actualLength > 0 && out != null) {
- out.write(secondLineOfBytes, 0, actualLength);
- // Updates the file size.
- fileSize += actualLength;
- }
- }
- break;
- } else {
- // Writes the out previous line.
- // The sizeOfSecondArray will NEVER BE ZERO if out==null, so
- // there is no need to included this in the test
- if (sizeOfSecondArray != 0) {
- out.write(secondLineOfBytes, 0, sizeOfSecondArray);
- // Updates the file size.
- fileSize += sizeOfSecondArray;
- }
-
- // out will always be null, so there is no need to reset
- // sizeOfSecondArray to zero each time.
- if (out != null) {
- // Copy the read bytes into the array.
- System.arraycopy(blockOfBytes, 0, secondLineOfBytes, 0,
- read);
- // That is how many bytes to read from the secondLineOfBytes
- sizeOfSecondArray = read;
- }
- }
- }
-
- // Returns the number of bytes written to outstream.
- return fileSize;
- }
-
- /**
- * Reads a Multipart section that is a file type. Assumes that the
- * Content-Disposition/Content-Type and blank line have already been
- * processed. So we read until we hit a boundary, then close file and
- * return.
- *
- * @param in
- * the InputStream to read and parse.
- * @param strFilename
- * the FileSystemName of the file.
- * @return the number of bytes read.
- * @throws IOException
- * if an error occurs writing the file.
- */
- private long readAndWriteFile(InputStream in, String strFilename)
- throws IOException {
- // Stores a reference to this, as we may need to delete it later.
- File outFile = new File(fileOutPutDirectory, strFilename);
-
- BufferedOutputStream out = null;
- // Do not bother opening a OutputStream, if we cannot even write the
- // file.
- if (fileOutPutDirectory != null)
- out = new BufferedOutputStream(new FileOutputStream(outFile));
-
- long count = readAndWrite(in, out);
- // Count would NOT be larger than zero if out was null.
- if (count > 0) {
- out.flush();
- out.close();
- } else {
- out.close();
- // Deletes the file as empty. We should be able to delete it, if we
- // can open it!
- outFile.delete();
- }
- return count;
- }
-
- /**
- * If the fileOutPutDirectory wasn't specified, just read the file to
- * memory.
- *
- * @param in
- * the InputStream to read and parse.
- * @return contents of file, from which you can garner the size as well.
- * @throws IOException
- * if the writing failed due to input/output error.
- */
- private byte[] readFile(InputStream in) throws IOException {
- // In this case, we do not need to worry about a outputdirectory.
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- long count = readAndWrite(in, out);
- // Count would NOT be larger than zero if out was null.
- if (count > 0) {
- // Return contents of file to parse method for inclusion in htFiles
- // object.
- return out.toByteArray();
- } else
- return null;
- }
-
- /**
- * Gets the length of the line minus line ending.
- *
- * @param byteLine
- * @param endOfArray
- * This is because in many cases the byteLine will have garbage
- * data at the end, so we act as though the actual end of the
- * array is this parameter. If you want to process the complete
- * byteLine, specify byteLine.length as the endOfArray parameter.
- * @return the length.
- */
- private static final int getLengthMinusEnding(byte byteLine[],
- int endOfArray) {
- if (byteLine == null)
- return 0;
-
- if (endOfArray >= 2 && byteLine[endOfArray - 2] == '\r'
- && byteLine[endOfArray - 1] == '\n')
- return endOfArray - 2;
- else if (endOfArray >= 1 && byteLine[endOfArray - 1] == '\n'
- || byteLine[endOfArray - 1] == '\r')
- return endOfArray - 1;
- else
- return endOfArray;
- }
-
- /**
- *
- * @param buf
- * @return
- */
- private static final int getLengthMinusEnding(StringBuffer buf) {
- if (buf.length() >= 2 && buf.charAt(buf.length() - 2) == '\r'
- && buf.charAt(buf.length() - 1) == '\n')
- return buf.length() - 2;
- else if (buf.length() >= 1 && buf.charAt(buf.length() - 1) == '\n'
- || buf.charAt(buf.length() - 1) == '\r')
- return buf.length() - 1;
- else
- return buf.length();
- }
-
- /**
- * Reads at most READ_BLOCK blocks of data, or a single line whichever is
- * smaller. Returns -1, if nothing to read, or we have reached the specified
- * content-length.
- *
- * Assumes that bytToBeRead.length indicates the block size to read.
- *
- * @param in
- * the InputStream to read and parse.
- * @param bytesToBeRead
- * the bytes to be read.
- * @return -1 if stream has ended, before a newline encountered (should
- * never happen) OR we have read past the Content-Length specified.
- * (Should also not happen). Otherwise return the number of
- * characters read. You can test whether the number returned is less
- * than bytesToBeRead.length, which indicates that we have read the
- * last line of a file or parameter or a border line, or some other
- * formatting stuff.
- * @throws IOException
- * if the writing failed due to input/output error.
- */
- private int readLine(InputStream in, byte[] bytesToBeRead)
- throws IOException {
- // Ensure that there is still stuff to read...
- if (intTotalRead >= intContentLength)
- return -1;
-
- // Get the length of what we are wanting to read.
- int length = bytesToBeRead.length;
-
- // End of content, but some servers (apparently) may not realise this
- // and end the InputStream, so
- // we cover ourselves this way.
- if (length > (intContentLength - intTotalRead))
- length = (int) (intContentLength - intTotalRead); // So we only
- // read the data
- // that is left.
-
- int result = readLine(in, bytesToBeRead, 0, length);
- // Only if we get actually read something, otherwise something weird has
- // happened, such as the end of stream.
- if (result > 0)
- intTotalRead += result;
-
- return result;
- }
-
- /**
- * This needs to support the possibility of a / or a \ separator.
- *
- * @param strFilename
- * the FileSystemName of the file.
- * @return the strFilename after removing all characters before the last
- * occurence of / or \.
- */
- private static final String getBasename(String strFilename) {
- if (strFilename == null)
- return strFilename;
-
- int intIndex = strFilename.lastIndexOf("/");
- if (intIndex == -1 || strFilename.lastIndexOf("\\") > intIndex)
- intIndex = strFilename.lastIndexOf("\\");
-
- if (intIndex != -1)
- return strFilename.substring(intIndex + 1);
- else
- return strFilename;
- }
-
- /**
- * Trims any quotes from the start and end of a string.
- *
- * @param strItem
- * @return the trimmed string.
- */
- private static final String trimQuotes(String strItem) {
- // Saves having to go any further....
- if (strItem == null || strItem.indexOf("\"") == -1)
- return strItem;
-
- // Gets the rid of any whitespace..
- strItem = strItem.trim();
-
- if (strItem.charAt(0) == '\"')
- strItem = strItem.substring(1);
-
- if (strItem.charAt(strItem.length() - 1) == '\"')
- strItem = strItem.substring(0, strItem.length() - 1);
-
- return strItem;
- }
-
- /**
- * Format of string name=value; name=value; If not found, will return null.
- *
- * @param strName
- * the form field name, used to upload the file. This identifies
- * the formfield location in the storage facility.
- * @param strToDecode
- *
- */
- private static final String getValue(String strName, String strToDecode) {
- strName = strName + "=";
-
- int startIndexOf = 0;
- while (startIndexOf < strToDecode.length()) {
- int indexOf = strToDecode.indexOf(strName, startIndexOf);
- // Ensure either first name, or a space or ; precedes it.
- if (indexOf != -1) {
- if (indexOf == 0
- || Character.isWhitespace(strToDecode
- .charAt(indexOf - 1))
- || strToDecode.charAt(indexOf - 1) == ';') {
- int endIndexOf = strToDecode.indexOf(";", indexOf
- + strName.length());
- if (endIndexOf == -1) // May return an empty string...
- return strToDecode
- .substring(indexOf + strName.length());
- else
- return strToDecode.substring(
- indexOf + strName.length(), endIndexOf);
- } else
- startIndexOf = indexOf + strName.length();
- } else
- return null;
- }
- return null;
- }
-
- /**
- * <I>Tomcat's ServletInputStream.readLine(byte[],int,int) Slightly Modified
- * to utilise in.read()</I> <BR>
- * Reads the input stream, one line at a time. Starting at an offset, reads
- * bytes into an array, until it reads a certain number of bytes or reaches
- * a newline character, which it reads into the array as well.
- *
- * <p>
- * This method <u><b>does not</b></u> returns -1 if it reaches the end of
- * the input stream before reading the maximum number of bytes, it returns
- * -1, if no bytes read.
- *
- * @param in
- * the InputStream to read and parse.
- * @param b
- * an array of bytes into which data is read.
- *
- * @param off
- * an integer specifying the character at which this method
- * begins reading.
- *
- * @param len
- * an integer specifying the maximum number of bytes to read.
- *
- * @return an integer specifying the actual number of bytes read, or -1 if
- * the end of the stream is reached.
- *
- * @throws IOException
- * if an input or output exception has occurred
- *
- *
- * Note: We have a problem with Tomcat reporting an erroneous number of
- * bytes, so we need to check this. This is the method where we get an
- * infinite loop, but only with binary files.
- */
- private int readLine(InputStream in, byte[] b, int off, int len)
- throws IOException {
- if (len <= 0)
- return 0;
-
- int count = 0, c;
-
- while ((c = in.read()) != -1) {
- b[off++] = (byte) c;
- count++;
- if (c == '\n' || count == len)
- break;
- }
-
- return count > 0 ? count : -1;
- }
-
- /**
- * Prints the given debugging message.
- *
- * @param x
- * the message to print.
- */
- protected void debug(String x) {
- if (debug != null) {
- debug.println(x);
- debug.flush();
- }
- }
-
- /**
- * Gets the Html Table.For debugging.
- */
- public String getHtmlTable() {
- StringBuffer sbReturn = new StringBuffer();
-
- sbReturn.append("<h2>Parameters</h2>");
- sbReturn
- .append("\n<table border=3><tr><td><b>Name</b></td><td><b>Value</b></td></tr>");
- for (Enumeration e = getParameterNames(); e.hasMoreElements();) {
- String strName = (String) e.nextElement();
- sbReturn.append("\n<tr>" + "<td>" + strName + "</td>");
-
- sbReturn.append("<td><table border=1><tr>");
- for (Enumeration f = getURLParameters(strName); f.hasMoreElements();) {
- String value = (String) f.nextElement();
- sbReturn.append("<td>" + value + "</td>");
- }
- sbReturn.append("</tr></table></td></tr>");
- }
- sbReturn.append("</table>");
-
- sbReturn.append("<h2>File Parameters</h2>");
-
- sbReturn
- .append("\n<table border=2><tr><td><b>Name</b></td><td><b>Filename</b></td><td><b>Path</b></td><td><b>Content Type</b></td><td><b>Size</b></td></tr>");
- for (Enumeration e = getFileParameterNames(); e.hasMoreElements();) {
- String strName = (String) e.nextElement();
-
- sbReturn
- .append("\n<tr>"
- + "<td>"
- + strName
- + "</td>"
- + "<td>"
- + (getFileSystemName(strName) != null ? getFileSystemName(strName)
- : "") + "</td>");
-
- if (loadIntoMemory)
- sbReturn.append("<td>"
- + (getFileSize(strName) > 0 ? "<i>in memory</i>" : "")
- + "</td>");
- else
- sbReturn.append("<td>"
- + (getFile(strName) != null ? getFile(strName)
- .getAbsolutePath() : "") + "</td>");
-
- sbReturn
- .append("<td>"
- + (getContentType(strName) != null ? getContentType(strName)
- : "")
- + "</td>"
- + "<td>"
- + (getFileSize(strName) != -1 ? getFileSize(strName)
- + ""
- : "") + "</td>" + "</tr>");
- }
- sbReturn.append("</table>");
-
- return sbReturn.toString();
- }
-}
diff --git a/src/com/itmill/toolkit/terminal/gwt/server/ServletMultipartRequest.java b/src/com/itmill/toolkit/terminal/gwt/server/ServletMultipartRequest.java
deleted file mode 100644
index a0352e5944..0000000000
--- a/src/com/itmill/toolkit/terminal/gwt/server/ServletMultipartRequest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/* *************************************************************************
-
- IT Mill Toolkit
-
- Development of Browser User Interfaces Made Easy
-
- 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
-
- *************************************************************************
-
- 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.gwt.server;
-
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * This class wraps the MultipartRequest class by Jason Pell for the Servlet
- * environment.
- *
- * @author IT Mill Ltd
- * @version
- * @VERSION@
- * @since 3.0
- */
-public class ServletMultipartRequest extends MultipartRequest {
- /**
- * Constructor wrapper, unwraps the InputStream, content type and content
- * length from the servlet request object.
- *
- * @param request
- * the HttpServletRequest will be used to initialise the
- * MultipartRequest super class.
- * @param strSaveDirectory
- * the temporary directory to save the file from where they can
- * then be moved to wherever by the calling process. <b>If you
- * specify <u>null</u> for this parameter, then any files
- * uploaded will be silently ignored.</B>
- *
- * @throws IllegalArgumentException
- * If the request.getContentType() does not contain a
- * Content-Type of "multipart/form-data" or the boundary is not
- * found.
- * @throws IOException
- * If the request.getContentLength() is higher than
- * MAX_READ_BYTES or strSaveDirectory is invalid or cannot be
- * written to.
- *
- * @see MultipartRequest#MAX_READ_BYTES
- */
- public ServletMultipartRequest(HttpServletRequest request,
- String strSaveDirectory) throws IllegalArgumentException,
- IOException {
- super(null, request.getContentType(), request.getContentLength(),
- request.getInputStream(), strSaveDirectory,
- MultipartRequest.MAX_READ_BYTES);
- }
-
- /**
- * Constructor wrapper, unwraps the InputStream, content type and content
- * lenght from the servlet request object. Also allow to explicitly set the
- * max permissable length of the request.
- *
- * @param request
- * the HttpServletRequest will be used to initialise the
- * MultipartRequest super class.
- * @param strSaveDirectory
- * the temporary directory to save the file from where they can
- * then be moved to wherever by the calling process. <b>If you
- * specify <u>null</u> for this parameter, then any files
- * uploaded will be silently ignored.</B>
- * @param intMaxReadBytes
- * Overrides the MAX_BYTES_READ value, to allow arbitrarily long
- * files.
- *
- * @throws IllegalArgumentException
- * If the request.getContentType() does not contain a
- * Content-Type of "multipart/form-data" or the boundary is not
- * found.
- * @throws IOException
- * If the request.getContentLength() is higher than
- * MAX_READ_BYTES or strSaveDirectory is invalid or cannot be
- * written to.
- *
- * @see MultipartRequest#MAX_READ_BYTES
- */
- public ServletMultipartRequest(HttpServletRequest request,
- String strSaveDirectory, int intMaxReadBytes)
- throws IllegalArgumentException, IOException {
- super(null, request.getContentType(), request.getContentLength(),
- request.getInputStream(), strSaveDirectory, intMaxReadBytes);
- }
-
- /**
- * Constructor wrapper for loading the request into memory rather than
- * temp-file.
- *
- * @param request
- * the HttpServletRequest will be used to initialise the
- * MultipartRequest super class.
- * @param intMaxReadBytes
- * Overrides the MAX_BYTES_READ value, to allow arbitrarily long
- * files.
- *
- * @throws IllegalArgumentException
- * If the request.getContentType() does not contain a
- * Content-Type of "multipart/form-data" or the boundary is not
- * found.
- * @throws IOException
- * If the request.getContentLength() is higher than
- * MAX_READ_BYTES or strSaveDirectory is invalid or cannot be
- * written to.
- *
- * @see MultipartRequest#MAX_READ_BYTES
- */
- public ServletMultipartRequest(HttpServletRequest request,
- int intMaxReadBytes) throws IllegalArgumentException, IOException {
- super(null, request.getContentType(), request.getContentLength(),
- request.getInputStream(), intMaxReadBytes);
- }
-}