
org.directwebremoting.extend.ObjectOutboundVariable Maven / Gradle / Ivy
package org.directwebremoting.extend;
import java.util.Collection;
import java.util.Map;
import org.directwebremoting.util.LocalUtil;
/**
* An OutboundVariable that declares a JavaScript object
* @author Joe Walker [joe at getahead dot ltd dot uk]
*/
public class ObjectOutboundVariable extends NestedOutboundVariable
{
/**
* Constructor for when we have a Javascript type to populate
* @param context ...
* @param type ...
* @param scriptClassName ...
*/
public ObjectOutboundVariable(OutboundContext context, Class> type, String scriptClassName)
{
super(context);
if (context.isJsonMode())
{
if (scriptClassName != null)
{
throw new JsonModeMarshallException(type, "Can't used named Javascript objects in JSON mode");
}
}
this.scriptClassName = scriptClassName;
this.isNamed = scriptClassName != null && !scriptClassName.isEmpty();
}
/**
* Constructor for when we don't have a Javascript type to populate
* @param context ...
*/
public ObjectOutboundVariable(OutboundContext context)
{
super(context);
this.scriptClassName = null;
this.isNamed = false;
}
@Override
public void setChildren(Collection children)
{
throw new IllegalStateException("Use ObjectOutboundVariable.setChildren(Map)");
}
/**
* We setup the children later than construction time so we can check for
* recursive references.
* @param childMap ...
*/
public void setChildren(Map childMap)
{
this.childMap = childMap;
super.setChildren(childMap.values());
}
public String getDeclareCode()
{
if (isInline())
{
return getChildDeclareCodes();
}
else
{
if (!isNamed)
{
return getChildDeclareCodes() + "var " + getVariableName() + "={};";
}
else
{
return getChildDeclareCodes() + "var " + getVariableName() + "=new " + scriptClassName + "();";
}
}
}
public String getBuildCode()
{
if (isInline())
{
return getChildBuildCodes();
}
else
{
StringBuffer buildCode = new StringBuffer(getChildBuildCodes());
String variableName = getVariableName();
for (Map.Entry entry : childMap.entrySet())
{
String name = entry.getKey();
OutboundVariable nested = entry.getValue();
String nestedAssignCode = nested.getAssignCode();
// The semi-compact syntax is only any good for simple names
if (LocalUtil.isSimpleName(name))
{
buildCode.append(variableName);
buildCode.append('.');
buildCode.append(name);
buildCode.append('=');
buildCode.append(nestedAssignCode);
buildCode.append(';');
}
else
{
buildCode.append(variableName);
buildCode.append("['");
buildCode.append(name);
buildCode.append("']=");
buildCode.append(nestedAssignCode);
buildCode.append(';');
}
}
buildCode.append("\r\n");
return buildCode.toString();
}
}
public String getAssignCode()
{
if (isInline())
{
StringBuffer buffer = new StringBuffer();
if (isNamed)
{
buffer.append(EnginePrivate.remoteNewObjectFunction() + "(\"");
buffer.append(scriptClassName);
buffer.append("\",{");
}
else
{
buffer.append('{');
}
boolean first = true;
for (Map.Entry entry : childMap.entrySet())
{
String name = entry.getKey();
OutboundVariable nested = entry.getValue();
String innerAssignCode = nested.getAssignCode();
if (!first)
{
buffer.append(',');
}
// The compact syntax is only any good for simple names, when
// we are not recursive, and when we're not doing JSON
if (LocalUtil.isSimpleName(name) && !isJsonMode())
{
buffer.append(name);
buffer.append(':');
buffer.append(innerAssignCode);
}
else
{
buffer.append('\"');
buffer.append(name);
buffer.append("\":");
buffer.append(innerAssignCode);
}
// we don't need to do this one the hard way
first = false;
}
if (isNamed)
{
buffer.append("})");
}
else
{
buffer.append('}');
}
return buffer.toString();
}
else
{
return getVariableName();
}
}
@Override
public String toString()
{
return "ObjectOutboundVariable:" + childMap;
}
/**
* Are we named (or does {@link #scriptClassName} have some contents)
*/
private final boolean isNamed;
/**
* The name of this typed class if there is one
*/
private final String scriptClassName;
/**
* The contained variables
*/
private Map childMap;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy