Browse Source

now from app/UIDL feeds JSON


svn changeset:1582/svn branch:trunk
tags/6.7.0.beta1
Matti Tahvonen 17 years ago
parent
commit
c8f2464712

+ 78
- 71
src/com/itmill/toolkit/terminal/web/AjaxApplicationManager.java View File

@@ -54,6 +54,7 @@ import com.itmill.toolkit.Application;
import com.itmill.toolkit.Application.WindowAttachEvent;
import com.itmill.toolkit.Application.WindowDetachEvent;
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.Paintable.RepaintRequestEvent;
@@ -92,7 +93,7 @@ public class AjaxApplicationManager implements

private Set removedWindows = new HashSet();

private AjaxPaintTarget paintTarget;
private PaintTarget paintTarget;

public AjaxApplicationManager(Application application) {
this.application = application;
@@ -131,6 +132,15 @@ public class AjaxApplicationManager implements
application.removeListener((Application.WindowDetachListener) this);
}

public void handleUidlRequest(HttpServletRequest request,
HttpServletResponse response, ThemeSource themeSource) throws IOException {
handleUidlRequest(request,
response, themeSource, false);
}

/**
*
* @param request
@@ -141,8 +151,8 @@ public class AjaxApplicationManager implements
* if the writing failed due to input/output error.
*/
public void handleUidlRequest(HttpServletRequest request,
HttpServletResponse response, ThemeSource themeSource)
throws IOException {
HttpServletResponse response, ThemeSource themeSource, boolean isJson)
throws IOException {

// repaint requested or sesssion has timed out and new one is created
boolean repaintAll = (request.getParameter(GET_PARAM_REPAINT_ALL) != null)
@@ -191,11 +201,16 @@ public class AjaxApplicationManager implements
if (window == null)
return;

// Sets the response type
response.setContentType("application/xml; charset=UTF-8");

paintTarget = new AjaxPaintTarget(getVariableMap(), this,
out);
if(isJson) {
// Sets the response type
response.setContentType("application/json; charset=UTF-8");
paintTarget = new AjaxJsonPaintTarget(getVariableMap(),
this, out);
} else {
response.setContentType("application/xml; charset=UTF-8");
paintTarget = new AjaxXmlPaintTarget(getVariableMap(),
this, out);
}

// Render the removed windows
Set removed = new HashSet(getRemovedWindows());
@@ -294,11 +309,11 @@ public class AjaxApplicationManager implements
paintTarget.addAttribute("pid", pid);

// Track paints to identify empty paints
paintTarget.setTrackPaints(true);
((AjaxPaintTarget) paintTarget).setTrackPaints(true);
p.paint(paintTarget);

// If no paints add attribute empty
if (paintTarget.getNumberOfPaints() <= 0) {
if (((AjaxPaintTarget) paintTarget).getNumberOfPaints() <= 0) {
paintTarget.addAttribute("visible", false);
}
paintTarget.endTag("change");
@@ -306,64 +321,56 @@ public class AjaxApplicationManager implements
}
}

// add meta instruction for client to set focus if it is set
Paintable f = (Paintable) application.consumeFocus();
// .. or initializion (first uidl-request)
boolean init = application.ajaxInit();
if (init || f != null) {
paintTarget.startTag("meta");
if (init)
paintTarget.addAttribute("appInit", true);
if (f != null) {
paintTarget.startTag("focus");
paintTarget.addAttribute("pid", getPaintableId(f));
paintTarget.endTag("focus");
}
paintTarget.endTag("meta");
}

// 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
for (Iterator i = paintTarget.preCachedResources.iterator(); i
.hasNext();) {
String resource = (String) i.next();
InputStream is = null;
try {
is = themeSource.getResource(themeName + "/"
+ resource);
} catch (ThemeSource.ThemeException e) {
Log.info(e.getMessage());
}
if (is != null) {
paintTarget.startTag("precache");
paintTarget.addAttribute("resource", 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() + ")");
}
paintTarget.addCharacterData(layout.toString());
paintTarget.endTag("precache");
}
}

paintTarget.close();
// add meta instruction for client to set focus if it is set
Paintable f = (Paintable) application.consumeFocus();
// .. or initializion (first uidl-request)
boolean init = application.ajaxInit();
if(init || f != null) {
paintTarget.startTag("meta");
if(init)
paintTarget.addAttribute("appInit", true);
if(f != null) {
paintTarget.startTag("focus");
paintTarget.addAttribute("pid", getPaintableId(f));
paintTarget.endTag("focus");
}
paintTarget.endTag("meta");
}

// 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
for (Iterator i=((AjaxPaintTarget) paintTarget).getPreCachedResources().iterator(); i.hasNext();) {
String resource = (String) i.next();
InputStream is = null;
try {
is = themeSource.getResource(themeName + "/" + resource);
} catch (ThemeSource.ThemeException e) {
Log.info(e.getMessage());
}
if (is != null) {
paintTarget.startTag("precache");
paintTarget.addAttribute("resource", 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() + ")");
}
paintTarget.addCharacterData(layout.toString());
paintTarget.endTag("precache");
}
}
((AjaxPaintTarget) paintTarget).close();
out.flush();
} else {

@@ -591,10 +598,10 @@ public class AjaxApplicationManager implements
public synchronized String getPaintableId(Paintable paintable) {

String id = (String) paintableIdMap.get(paintable);
if (id == null)
// get PID using growing sequence number
if (id == null) {
id = "PID" + Integer.toString(idSequence++);
paintableIdMap.put(paintable, id);
paintableIdMap.put(paintable, id);
}

return id;
}

+ 993
- 0
src/com/itmill/toolkit/terminal/web/AjaxJsonPaintTarget.java View File

@@ -0,0 +1,993 @@
/* *************************************************************************
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.web;

import com.itmill.toolkit.Application;
import com.itmill.toolkit.terminal.ApplicationResource;
import com.itmill.toolkit.terminal.ExternalResource;
import com.itmill.toolkit.terminal.PaintException;
import com.itmill.toolkit.terminal.PaintTarget;
import com.itmill.toolkit.terminal.Paintable;
import com.itmill.toolkit.terminal.Resource;
import com.itmill.toolkit.terminal.ThemeResource;
import com.itmill.toolkit.terminal.UploadStream;
import com.itmill.toolkit.terminal.VariableOwner;

import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.util.Stack;
import java.util.Vector;

/**
* User Interface Description Language Target.
*
* @author IT Mill Ltd.
* @version
* @VERSION@
* @since 3.1
*/
public class AjaxJsonPaintTarget implements PaintTarget, AjaxPaintTarget {

/* Document type declarations */

private final static String UIDL_ARG_NAME = "name";

private final static String UIDL_ARG_VALUE = "value";

private final static String UIDL_ARG_ID = "id";

private Stack mOpenTags;
private Stack openJsonTags;

private boolean mTagArgumentListOpen;

private PrintWriter uidlBuffer;

private AjaxVariableMap variableMap;

private boolean closed = false;

private AjaxApplicationManager manager;

private boolean trackPaints = false;

private int numberOfPaints = 0;
private int changes = 0;
Set preCachedResources = new HashSet();
private boolean customLayoutArgumentsOpen = false;

private JsonTag tag;

/**
* Creates a new XMLPrintWriter, without automatic line flushing.
*
* @param variableMap
* @param manager
* @param output
* A character-output stream.
* @throws PaintException
* if the paint operation failed.
*/
public AjaxJsonPaintTarget(AjaxVariableMap variableMap,
AjaxApplicationManager manager, OutputStream output)
throws PaintException {

this.manager = manager;
// Sets the variable map
this.variableMap = variableMap;


// Sets the target for UIDL writing
try {
this.uidlBuffer = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(output, "UTF-8")));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Internal error");
}

// Initialize tag-writing
mOpenTags = new Stack();
openJsonTags = new Stack();
mTagArgumentListOpen = false;

// Adds document declaration

// Adds UIDL start tag and its attributes
tag = new JsonTag();
openJsonTags.push(tag);
append("{");

}

/**
* Method append.This method is thread safe.
*
* @param string
* the text to insert.
*/
private void append(String string) {
uidlBuffer.print(string);
}

public void startTag(String tagName) throws PaintException {
startTag(tagName, false);
}

/**
* Prints the element start tag.
*
* <pre>
* Todo:
* Checking of input values
*
* </pre>
*
* @param tagName
* the name of the start tag.
* @throws PaintException
* if the paint operation failed.
*
*/
public void startTag(String tagName, boolean isChildNode) throws PaintException {
// In case of null data output nothing:
if (tagName == null)
throw new NullPointerException();

// Increments paint tracker
if (this.isTrackPaints()) {
this.numberOfPaints++;
}

// Ensures that the target is open
if (this.closed)
throw new PaintException(
"Attempted to write to a closed PaintTarget.");

tagName = tag.postfixChildtag(tagName, true);
// Checks tagName and attributes here
mOpenTags.push(tagName);
openJsonTags.push(tag);
if(isChildNode && !tag.childrenArrayOpen) {
append(tag.startField());
tag.openChildrenArray();
}
if(!isChildNode && tag.childrenArrayOpen)
tag.closeChildrenArray();

append(tag.startField());
tag = new JsonTag();
if(isChildNode) {
append("{");
tag.setChildNode(true);
} else {
// Prints the tag with attributes
append("" + tagName +": {");
}

mTagArgumentListOpen = true;
if ("customlayout".equals(tagName))
customLayoutArgumentsOpen = true;
}

/**
* Prints the element end tag.
*
* If the parent tag is closed before every child tag is closed an
* PaintException is raised.
*
* @param tag
* the name of the end tag.
* @throws Paintexception
* if the paint operation failed.
*/
public void endTag(String tagName) throws PaintException {
// In case of null data output nothing:
if (tagName == null)
throw new NullPointerException();

// Ensure that the target is open
if (this.closed)
throw new PaintException(
"Attempted to write to a closed PaintTarget.");
JsonTag parent = (JsonTag) openJsonTags.pop();
if(parent != null)
tagName = parent.postfixChildtag(tagName, false);

String lastTag = "";

lastTag = (String) mOpenTags.pop();
if (!tagName.equalsIgnoreCase(lastTag))
throw new PaintException("Invalid UIDL: wrong ending tag: '"
+ tagName + "' expected: '" + lastTag + "'.");

if(tag.childrenArrayOpen)
tag.closeChildrenArray();
append(tag.getData());
append(tag.attributesAsJsonObject());
append(tag.variablesAsJsonObject());
// Writes the end (closing) tag
append("}");
tag = parent;
flush();
}

/**
* Substitutes the XML sensitive characters with predefined XML entities.
*
* @param xml
* the String to be substituted.
* @return A new string instance where all occurrences of XML sensitive
* characters are substituted with entities.
*/
static public String escapeXML(String xml) {
if (xml == null || xml.length() <= 0)
return "";
return escapeXML(new StringBuffer(xml)).toString();
}

/**
* Substitutes the XML sensitive characters with predefined XML entities.
*
* @param xml
* the String to be substituted.
* @return A new StringBuffer instance where all occurrences of XML
* sensitive characters are substituted with entities.
*
*/
static public StringBuffer escapeXML(StringBuffer xml) {
if (xml == null || xml.length() <= 0)
return new StringBuffer("");

StringBuffer result = new StringBuffer(xml.length() * 2);

for (int i = 0; i < xml.length(); i++) {
char c = xml.charAt(i);
String s = toXmlChar(c);
if (s != null) {
result.append(s);
} else {
result.append(c);
}
}
return result;
}
static public String escapeJSON(String s) {
if(s==null)
return "";
StringBuffer sb=new StringBuffer();
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
switch(ch){
case '"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
case '\b':
sb.append("\\b");
break;
case '\f':
sb.append("\\f");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\t':
sb.append("\\t");
break;
case '/':
sb.append("\\/");
break;
default:
if(ch>='\u0000' && ch<='\u001F'){
String ss=Integer.toHexString(ch);
sb.append("\\u");
for(int k=0;k<4-ss.length();k++){
sb.append('0');
}
sb.append(ss.toUpperCase());
}
else{
sb.append(ch);
}
}
}
return sb.toString();
}

/**
* Substitutes a XML sensitive character with predefined XML entity.
*
* @param c
* the Character to be replaced with an entity.
* @return String of the entity or null if character is not to be replaced
* with an entity.
*/
private static String toXmlChar(char c) {
switch (c) {
case '&':
return "&amp;"; // & => &amp;
case '>':
return "&gt;"; // > => &gt;
case '<':
return "&lt;"; // < => &lt;
case '"':
return "&quot;"; // " => &quot;
case '\'':
return "&apos;"; // ' => &apos;
default:
return null;
}
}

/**
* Prints XML-escaped text.
*
* @param str
* @throws PaintException
* if the paint operation failed.
*
*/
public void addText(String str) throws PaintException {
tag.addData(escapeJSON(str));
}

/**
* Adds a boolean attribute to component. Atributes must be added before any
* content is written.
*
* @param name
* the Attribute name.
* @param value
* the Attribute value.
* @throws PaintException
* if the paint operation failed.
*/
public void addAttribute(String name, boolean value) throws PaintException {
tag.addAttribute( name + ":" + (value ? "true" : "false"));
}

/**
* Adds a resource attribute to component. Atributes must be added before
* any content is written.
*
* @param name
* the Attribute name.
* @param value
* the Attribute value.
*
* @throws PaintException
* if the paint operation failed.
*/
public void addAttribute(String name, Resource value) throws PaintException {

if (value instanceof ExternalResource) {
addAttribute(name, ((ExternalResource) value).getURL());

} else if (value instanceof ApplicationResource) {
ApplicationResource r = (ApplicationResource) value;
Application a = r.getApplication();
if (a == null)
throw new PaintException(
"Application not specified for resorce "
+ value.getClass().getName());
String uri = a.getURL().getPath();
if (uri.charAt(uri.length() - 1) != '/')
uri += "/";
uri += a.getRelativeLocation(r);
addAttribute(name, uri);

} else if (value instanceof ThemeResource) {
String uri = "theme://" + ((ThemeResource) value).getResourceId();
addAttribute(name, uri);
} else
throw new PaintException("Ajax adapter does not "
+ "support resources of type: "
+ value.getClass().getName());

}

/**
* Adds a integer attribute to component. Atributes must be added before any
* content is written.
*
* @param name
* the Attribute name.
* @param value
* the Attribute value.
*
* @throws PaintException
* if the paint operation failed.
*/
public void addAttribute(String name, int value) throws PaintException {
tag.addAttribute(name + ":" + String.valueOf(value));
}

/**
* Adds a long attribute to component. Atributes must be added before any
* content is written.
*
* @param name
* the Attribute name.
* @param value
* the Attribute value.
*
* @throws PaintException
* if the paint operation failed.
*/
public void addAttribute(String name, long value) throws PaintException {
tag.addAttribute(name + ":" + String.valueOf(value));
}

/**
* Adds a string attribute to component. Atributes must be added before any
* content is written.
*
* @param name
* the Boolean attribute name.
* @param value
* the Boolean attribute value.
*
* @throws PaintException
* if the paint operation failed.
*/
public void addAttribute(String name, String value) throws PaintException {
// In case of null data output nothing:
if ((value == null) || (name == null))
throw new NullPointerException(
"Parameters must be non-null strings");


tag.addAttribute( name + ": \"" + escapeJSON(value) + "\"");
}

/**
* Adds a string type variable.
*
* @param owner
* the Listener for variable changes.
* @param name
* the Variable name.
* @param value
* the Variable initial value.
*
* @throws PaintException
* if the paint operation failed.
*/
public void addVariable(VariableOwner owner, String name, String value)
throws PaintException {
tag.addVariable(new StringVariable(owner,name,value));
}

/**
* Adds a int type variable.
*
* @param owner
* the Listener for variable changes.
* @param name
* the Variable name.
* @param value
* the Variable initial value.
*
* @throws PaintException
* if the paint operation failed.
*/
public void addVariable(VariableOwner owner, String name, int value)
throws PaintException {
tag.addVariable(new IntVariable(owner,name,value));
}

/**
* Adds a boolean type variable.
*
* @param owner
* the Listener for variable changes.
* @param name
* the Variable name.
* @param value
* the Variable initial value.
*
* @throws PaintException
* if the paint operation failed.
*/
public void addVariable(VariableOwner owner, String name, boolean value)
throws PaintException {
tag.addVariable(new BooleanVariable(owner,name,value));
}

/**
* Adds a string array type variable.
*
* @param owner
* the Listener for variable changes.
* @param name
* the Variable name.
* @param value
* the Variable initial value.
*
* @throws PaintException
* if the paint operation failed.
*/
public void addVariable(VariableOwner owner, String name, String[] value)
throws PaintException {
tag.addVariable(new ArrayVariable(owner,name,value));
}

/**
* Adds a upload stream type variable.
*
* TODO not converted for JSON
*
* @param owner
* the Listener for variable changes.
* @param name
* the Variable name.
*
* @throws PaintException
* if the paint operation failed.
*/
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");
}

/**
* Prints the single text section.
*
* Prints full text section. The section data is escaped from XML tags and
* surrounded by XML start and end-tags.
*
* @param sectionTagName
* the name of the tag.
* @param sectionData
* the section data to be printed.
* @throws PaintException
* if the paint operation failed.
*/
public void addSection(String sectionTagName, String sectionData)
throws PaintException {
startTag(sectionTagName);
addText(sectionData);
endTag(sectionTagName);
}

/**
* Adds XML directly to UIDL.
*
* @param xml
* the Xml to be added.
* @throws PaintException
* if the paint operation failed.
*/
public void addUIDL(String xml) throws PaintException {

// Ensure that the target is open
if (this.closed)
throw new PaintException(
"Attempted to write to a closed PaintTarget.");

// Make sure that the open start tag is closed before
// anything is written.

// Escape and write what was given
if (xml != null)
tag.addData(xml);

}

/**
* Adds XML section with namespace.
*
* @param sectionTagName
* the name of the tag.
* @param sectionData
* the section data.
* @param namespace
* the namespace to be added.
* @throws PaintException
* if the paint operation failed.
*
* @see com.itmill.toolkit.terminal.PaintTarget#addXMLSection(String,
* String, String)
*/
public void addXMLSection(String sectionTagName, String sectionData,
String namespace) throws PaintException {

// Ensure that the target is open
if (this.closed)
throw new PaintException(
"Attempted to write to a closed PaintTarget.");

startTag(sectionTagName);
if (namespace != null)
addAttribute("xmlns", namespace);
mTagArgumentListOpen = false;

if (sectionData != null)
tag.addData(sectionData);
endTag(sectionTagName);
}

/**
* Gets the UIDL already printed to stream. Paint target must be closed
* before the <code>getUIDL</code> can be called.
*
* @return the UIDL.
*/
public String getUIDL() {
if (this.closed) {
return uidlBuffer.toString();
}
throw new IllegalStateException(
"Tried to read UIDL from open PaintTarget");
}

/**
* Closes the paint target. Paint target must be closed before the
* <code>getUIDL</code> can be called. Subsequent attempts to write to
* paint target. If the target was already closed, call to this function is
* ignored. will generate an exception.
*
* @throws PaintException
* if the paint operation failed.
*/
public void close() throws PaintException {
append("}");
if (!this.closed) {
flush();

// Close all
this.uidlBuffer.close();
this.closed = true;
}
}

/**
* Method flush.
*/
private void flush() {
this.uidlBuffer.flush();
}

/**
* @see com.itmill.toolkit.terminal.PaintTarget#startTag(com.itmill.toolkit.terminal.Paintable,
* java.lang.String)
*/
public boolean startTag(Paintable paintable, String tagName)
throws PaintException {
startTag(tagName, true);
String id = manager.getPaintableId(paintable);
paintable.addListener(manager);
addAttribute("id", id);
addAttribute("type", tagName);
return false;
}

/**
* @see com.itmill.toolkit.terminal.PaintTarget#addCharacterData(java.lang.String)
*/
public void addCharacterData(String text) throws PaintException {
if (text != null)
tag.addData(text);
}

/**
*
* @return
*/
public boolean isTrackPaints() {
return trackPaints;
}

/**
* Gets the number of paints.
*
* @return the number of paints.
*/
public int getNumberOfPaints() {
return numberOfPaints;
}

/**
* Sets the tracking to true or false.
*
* This also resets the number of paints.
*
* @param enabled
* is the tracking is enabled or not.
* @see #getNumberOfPaints()
*/
public void setTrackPaints(boolean enabled) {
this.trackPaints = enabled;
this.numberOfPaints = 0;
}
/**
* This is basically a container for UI components variables, that will be
* added at the end of JSON object.
* @author mattitahvonen
*
*/
class JsonTag {
boolean firstField = true;
Vector variables = new Vector();

Vector attr = new Vector();
private HashMap childTagCounters = new HashMap();

StringBuffer data = new StringBuffer();
public boolean childrenArrayOpen = false;

private boolean childNode = false;
public JsonTag() {
}
public void openChildrenArray() {
if(!childrenArrayOpen) {
append("children : [");
childrenArrayOpen = true;
firstField = true;
}
}
/**
* This is used to prevent possible collapses on tag names
* @param tagName
* @param start
* @return
*/
public String postfixChildtag(String tagName, boolean start) {
TagCounter i = (TagCounter) childTagCounters.get(tagName);
if(i == null) {
i = new TagCounter();
childTagCounters.put(tagName, i);
}
tagName = i.postfix(tagName);
if(!start)
i.increment();
return tagName;
}

public void closeChildrenArray() {
append("]");
firstField = false;
}

public void setChildNode(boolean b) {
this.childNode = b;
}
public boolean isChildNode(){
return childNode;
}

public String startField() {
if(firstField) {
firstField = false;
return "";
} else {
return ",";
}
}
public void addData(String s) {
data.append(s);
}
public String getData() {
if(data.length() == 0)
return "";
return startField() + "data:\"" + escapeJSON(data.toString()) +"\"";
}
public void addAttribute(String jsonNode) {
attr.add(jsonNode);
}
public String attributesAsJsonObject() {
if(attr.size() == 0)
return "";
StringBuffer buf = new StringBuffer();
buf.append(startField());
buf.append("attr:{");
for (Iterator iter = attr.iterator(); iter.hasNext();) {
String element = (String) iter.next();
buf.append(element);
if(iter.hasNext())
buf.append(",");
}
buf.append("}");
return buf.toString();
}
public void addVariable(Variable v) {
variables.add(v);
}
public String variablesAsJsonObject() {
if(variables.size() == 0)
return "";
StringBuffer buf = new StringBuffer();
buf.append(startField());
buf.append("variables:{");
for (Iterator iter = variables.iterator(); iter.hasNext();) {
Variable element = (Variable) iter.next();
buf.append(element.getJsonPresentation());
if(iter.hasNext())
buf.append(",");
}
buf.append("}");
return buf.toString();
}
class TagCounter {
int count;
public TagCounter() {
count = 0;
}
public void increment() {
count++;
}
public String postfix(String s) {
if(count > 0) {
return s + count;
}
return s;
}
}
}

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() {
return name +":{name:\""+name+"\",id:\"" +
code+"\",type:\"boolean\", value : "
+ (value == true ? "true}" : "false}");
}
}
class StringVariable extends Variable {
String value;

public StringVariable(VariableOwner owner, String name, String v) {
value = v;
this.name = name;
code = variableMap.registerVariable(name, String.class,
value, owner);
}

public String getJsonPresentation() {
return name +":{name:\""+name+"\",id:\"" +
code+"\",type:\"string\", value : \""
+ value + "\"}";
}
}

class IntVariable extends Variable {
int value;

public IntVariable(VariableOwner owner, String name, int v) {
value = v;
this.name = name;
code = variableMap.registerVariable(name, Boolean.class,
new Integer(value), owner);
}

public String getJsonPresentation() {
return name +":{name:\""+name+"\",id:\"" +
code+"\",type:\"int\", value : "
+ value + "}";
}
}

class ArrayVariable extends Variable {
String[] value;

public ArrayVariable(VariableOwner owner, String name, String[] v) {
value = v;
this.name = name;
code = variableMap.registerVariable(name, String[].class,
value, owner);
}

public String getJsonPresentation() {
String pres = name +":{name:\""+name+"\",id:\"" +
code+"\",type:\"array\", value : [";
for (int i = 0; i < value.length;) {
pres += value[i];
i++;
if(i < value.length)
pres += ",";
}
pres += "]}";
return pres;
}
}

public Set getPreCachedResources() {
return new HashSet();
}

public void setPreCachedResources(Set preCachedResources) {
// TODO Auto-generated method stub
}

}

src/com/itmill/toolkit/terminal/web/AjaxPaintTarget.java → src/com/itmill/toolkit/terminal/web/AjaxXmlPaintTarget.java View File

@@ -56,7 +56,7 @@ import java.util.Stack;
* @VERSION@
* @since 3.1
*/
public class AjaxPaintTarget implements PaintTarget {
public class AjaxXmlPaintTarget implements PaintTarget, AjaxPaintTarget {

/* Document type declarations */
private final static String UIDL_XML_DECL = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
@@ -83,7 +83,7 @@ public class AjaxPaintTarget implements PaintTarget {

private int numberOfPaints = 0;
Set preCachedResources = new HashSet();
private Set preCachedResources = new HashSet();
private boolean customLayoutArgumentsOpen = false;

/**
@@ -96,7 +96,7 @@ public class AjaxPaintTarget implements PaintTarget {
* @throws PaintException
* if the paint operation failed.
*/
public AjaxPaintTarget(AjaxVariableMap variableMap,
public AjaxXmlPaintTarget(AjaxVariableMap variableMap,
AjaxApplicationManager manager, OutputStream output)
throws PaintException {

@@ -147,20 +147,8 @@ public class AjaxPaintTarget implements PaintTarget {
uidlBuffer.print(string);
}

/**
* Prints the element start tag.
*
* <pre>
* Todo:
* Checking of input values
*
* </pre>
*
* @param tagName
* the name of the start tag.
* @throws PaintException
* if the paint operation failed.
*
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#startTag(java.lang.String)
*/
public void startTag(String tagName) throws PaintException {
// In case of null data output nothing:
@@ -193,16 +181,8 @@ public class AjaxPaintTarget implements PaintTarget {
customLayoutArgumentsOpen = true;
}

/**
* Prints the element end tag.
*
* If the parent tag is closed before every child tag is closed an
* PaintException is raised.
*
* @param tag
* the name of the end tag.
* @throws Paintexception
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#endTag(java.lang.String)
*/
public void endTag(String tagName) throws PaintException {
// In case of null data output nothing:
@@ -327,44 +307,22 @@ public class AjaxPaintTarget implements PaintTarget {
append(str);
}

/**
* Prints XML-escaped text.
*
* @param str
* @throws PaintException
* if the paint operation failed.
*
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addText(java.lang.String)
*/
public void addText(String str) throws PaintException {
addUIDL(escapeXML(str));
}

/**
* Adds a boolean attribute to component. Atributes must be added before any
* content is written.
*
* @param name
* the Attribute name.
* @param value
* the Attribute value.
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addAttribute(java.lang.String, boolean)
*/
public void addAttribute(String name, boolean value) throws PaintException {
addAttribute(name, String.valueOf(value));
}

/**
* Adds a resource attribute to component. Atributes must be added before
* any content is written.
*
* @param name
* the Attribute name.
* @param value
* the Attribute value.
*
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addAttribute(java.lang.String, com.itmill.toolkit.terminal.Resource)
*/
public void addAttribute(String name, Resource value) throws PaintException {

@@ -394,49 +352,22 @@ public class AjaxPaintTarget implements PaintTarget {

}

/**
* Adds a integer attribute to component. Atributes must be added before any
* content is written.
*
* @param name
* the Attribute name.
* @param value
* the Attribute value.
*
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addAttribute(java.lang.String, int)
*/
public void addAttribute(String name, int value) throws PaintException {
addAttribute(name, String.valueOf(value));
}

/**
* Adds a long attribute to component. Atributes must be added before any
* content is written.
*
* @param name
* the Attribute name.
* @param value
* the Attribute value.
*
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addAttribute(java.lang.String, long)
*/
public void addAttribute(String name, long value) throws PaintException {
addAttribute(name, String.valueOf(value));
}

/**
* Adds a string attribute to component. Atributes must be added before any
* content is written.
*
* @param name
* the Boolean attribute name.
* @param value
* the Boolean attribute value.
*
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addAttribute(java.lang.String, java.lang.String)
*/
public void addAttribute(String name, String value) throws PaintException {
// In case of null data output nothing:
@@ -456,21 +387,11 @@ public class AjaxPaintTarget implements PaintTarget {
append(" " + name + "=\"" + escapeXML(value) + "\"");
if (customLayoutArgumentsOpen && "style".equals(name))
preCachedResources.add("layout/" + value + ".html");
getPreCachedResources().add("layout/" + value + ".html");
}

/**
* Adds a string type variable.
*
* @param owner
* the Listener for variable changes.
* @param name
* the Variable name.
* @param value
* the Variable initial value.
*
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addVariable(com.itmill.toolkit.terminal.VariableOwner, java.lang.String, java.lang.String)
*/
public void addVariable(VariableOwner owner, String name, String value)
throws PaintException {
@@ -483,18 +404,8 @@ public class AjaxPaintTarget implements PaintTarget {
endTag("string");
}

/**
* Adds a int type variable.
*
* @param owner
* the Listener for variable changes.
* @param name
* the Variable name.
* @param value
* the Variable initial value.
*
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addVariable(com.itmill.toolkit.terminal.VariableOwner, java.lang.String, int)
*/
public void addVariable(VariableOwner owner, String name, int value)
throws PaintException {
@@ -507,18 +418,8 @@ public class AjaxPaintTarget implements PaintTarget {
endTag("integer");
}

/**
* Adds a boolean type variable.
*
* @param owner
* the Listener for variable changes.
* @param name
* the Variable name.
* @param value
* the Variable initial value.
*
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addVariable(com.itmill.toolkit.terminal.VariableOwner, java.lang.String, boolean)
*/
public void addVariable(VariableOwner owner, String name, boolean value)
throws PaintException {
@@ -531,18 +432,8 @@ public class AjaxPaintTarget implements PaintTarget {
endTag("boolean");
}

/**
* Adds a string array type variable.
*
* @param owner
* the Listener for variable changes.
* @param name
* the Variable name.
* @param value
* the Variable initial value.
*
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addVariable(com.itmill.toolkit.terminal.VariableOwner, java.lang.String, java.lang.String[])
*/
public void addVariable(VariableOwner owner, String name, String[] value)
throws PaintException {
@@ -556,16 +447,8 @@ public class AjaxPaintTarget implements PaintTarget {
endTag("array");
}

/**
* Adds a upload stream type variable.
*
* @param owner
* the Listener for variable changes.
* @param name
* the Variable name.
*
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addUploadStreamVariable(com.itmill.toolkit.terminal.VariableOwner, java.lang.String)
*/
public void addUploadStreamVariable(VariableOwner owner, String name)
throws PaintException {
@@ -577,18 +460,8 @@ public class AjaxPaintTarget implements PaintTarget {
endTag("uploadstream");
}

/**
* Prints the single text section.
*
* Prints full text section. The section data is escaped from XML tags and
* surrounded by XML start and end-tags.
*
* @param sectionTagName
* the name of the tag.
* @param sectionData
* the section data to be printed.
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addSection(java.lang.String, java.lang.String)
*/
public void addSection(String sectionTagName, String sectionData)
throws PaintException {
@@ -597,13 +470,8 @@ public class AjaxPaintTarget implements PaintTarget {
endTag(sectionTagName);
}

/**
* Adds XML directly to UIDL.
*
* @param xml
* the Xml to be added.
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addUIDL(java.lang.String)
*/
public void addUIDL(String xml) throws PaintException {

@@ -622,20 +490,8 @@ public class AjaxPaintTarget implements PaintTarget {

}

/**
* Adds XML section with namespace.
*
* @param sectionTagName
* the name of the tag.
* @param sectionData
* the section data.
* @param namespace
* the namespace to be added.
* @throws PaintException
* if the paint operation failed.
*
* @see com.itmill.toolkit.terminal.PaintTarget#addXMLSection(String,
* String, String)
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addXMLSection(java.lang.String, java.lang.String, java.lang.String)
*/
public void addXMLSection(String sectionTagName, String sectionData,
String namespace) throws PaintException {
@@ -656,11 +512,8 @@ public class AjaxPaintTarget implements PaintTarget {
endTag(sectionTagName);
}

/**
* Gets the UIDL already printed to stream. Paint target must be closed
* before the <code>getUIDL</code> can be called.
*
* @return the UIDL.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#getUIDL()
*/
public String getUIDL() {
if (this.closed) {
@@ -670,14 +523,8 @@ public class AjaxPaintTarget implements PaintTarget {
"Tried to read UIDL from open PaintTarget");
}

/**
* Closes the paint target. Paint target must be closed before the
* <code>getUIDL</code> can be called. Subsequent attempts to write to
* paint target. If the target was already closed, call to this function is
* ignored. will generate an exception.
*
* @throws PaintException
* if the paint operation failed.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#close()
*/
public void close() throws PaintException {
if (!this.closed) {
@@ -697,9 +544,8 @@ public class AjaxPaintTarget implements PaintTarget {
this.uidlBuffer.flush();
}

/**
* @see com.itmill.toolkit.terminal.PaintTarget#startTag(com.itmill.toolkit.terminal.Paintable,
* java.lang.String)
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#startTag(com.itmill.toolkit.terminal.Paintable, java.lang.String)
*/
public boolean startTag(Paintable paintable, String tag)
throws PaintException {
@@ -710,8 +556,8 @@ public class AjaxPaintTarget implements PaintTarget {
return false;
}

/**
* @see com.itmill.toolkit.terminal.PaintTarget#addCharacterData(java.lang.String)
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#addCharacterData(java.lang.String)
*/
public void addCharacterData(String text) throws PaintException {
ensureClosedTag();
@@ -719,35 +565,34 @@ public class AjaxPaintTarget implements PaintTarget {
append("<![CDATA[" + text + "]]>");
}

/**
*
* @return
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#isTrackPaints()
*/
public boolean isTrackPaints() {
return trackPaints;
}

/**
* Gets the number of paints.
*
* @return the number of paints.
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#getNumberOfPaints()
*/
public int getNumberOfPaints() {
return numberOfPaints;
}

/**
* Sets the tracking to true or false.
*
* This also resets the number of paints.
*
* @param enabled
* is the tracking is enabled or not.
* @see #getNumberOfPaints()
/* (non-Javadoc)
* @see com.itmill.toolkit.terminal.web.AjaxPaintTarget#setTrackPaints(boolean)
*/
public void setTrackPaints(boolean enabled) {
this.trackPaints = enabled;
this.numberOfPaints = 0;
}

public void setPreCachedResources(Set preCachedResources) {
this.preCachedResources = preCachedResources;
}

public Set getPreCachedResources() {
return preCachedResources;
}

}

+ 1
- 1
src/com/itmill/toolkit/terminal/web/ApplicationServlet.java View File

@@ -566,7 +566,7 @@ public class ApplicationServlet extends HttpServlet implements
String resourceId = request.getPathInfo();
if (resourceId != null && resourceId.startsWith(AJAX_UIDL_URI)) {
getApplicationManager(application).handleUidlRequest(
request, response, themeSource);
request, response, themeSource, true);
return;
}


Loading…
Cancel
Save