📄 astreference.java
字号:
*
* @see ASTSetDirective
*
* @param context context object containing this reference
* @param value Object to set as value
* @return true if successful, false otherwise
*/
public boolean setValue( InternalContextAdapter context, Object value)
throws MethodInvocationException
{
if (jjtGetNumChildren() == 0)
{
context.put(rootString, value);
return true;
}
/*
* The rootOfIntrospection is the object we will
* retrieve from the Context. This is the base
* object we will apply reflection to.
*/
Object result = getVariableValue(context, rootString);
if (result == null)
{
rsvc.error(new ReferenceException("reference set : template = "
+ context.getCurrentTemplateName(), this));
return false;
}
/*
* How many child nodes do we have?
*/
for (int i = 0; i < numChildren - 1; i++)
{
result = jjtGetChild(i).execute(result, context);
if (result == null)
{
rsvc.error(new ReferenceException("reference set : template = "
+ context.getCurrentTemplateName(), this));
return false;
}
}
/*
* We support two ways of setting the value in a #set($ref.foo = $value ) :
* 1) ref.setFoo( value )
* 2) ref,put("foo", value ) to parallel the get() map introspection
*/
try
{
VelPropertySet vs =
rsvc.getUberspect().getPropertySet(result, identifier,
value, uberInfo);
if (vs == null)
return false;
vs.invoke(result, value);
}
catch(InvocationTargetException ite)
{
/*
* this is possible
*/
throw new MethodInvocationException(
"ASTReference : Invocation of method '"
+ identifier + "' in " + result.getClass()
+ " threw exception "
+ ite.getTargetException().getClass(),
ite.getTargetException(), identifier );
}
catch(Exception e)
{
/*
* maybe a security exception?
*/
rsvc.error("ASTReference setValue() : exception : " + e
+ " template = " + context.getCurrentTemplateName()
+ " [" + this.getLine() + "," + this.getColumn() + "]");
return false;
}
return true;
}
private String getRoot()
{
Token t = getFirstToken();
/*
* we have a special case where something like
* $(\\)*!, where the user want's to see something
* like $!blargh in the output, but the ! prevents it from showing.
* I think that at this point, this isn't a reference.
*/
/* so, see if we have "\\!" */
int slashbang = t.image.indexOf("\\!");
if (slashbang != -1)
{
/*
* lets do all the work here. I would argue that if this occurrs,
* it's not a reference at all, so preceeding \ characters in front
* of the $ are just schmoo. So we just do the escape processing
* trick (even | odd) and move on. This kind of breaks the rule
* pattern of $ and # but '!' really tosses a wrench into things.
*/
/*
* count the escapes : even # -> not escaped, odd -> escaped
*/
int i = 0;
int len = t.image.length();
i = t.image.indexOf('$');
if (i == -1)
{
/* yikes! */
rsvc.error("ASTReference.getRoot() : internal error : "
+ "no $ found for slashbang.");
computableReference = false;
nullString = t.image;
return nullString;
}
while (i < len && t.image.charAt(i) != '\\')
{
i++;
}
/* ok, i is the first \ char */
int start = i;
int count = 0;
while (i < len && t.image.charAt(i++) == '\\')
{
count++;
}
/*
* now construct the output string. We really don't care about
* leading slashes as this is not a reference. It's quasi-schmoo
*/
nullString = t.image.substring(0,start); // prefix up to the first
nullString += t.image.substring(start, start + count-1 ); // get the slashes
nullString += t.image.substring(start+count); // and the rest, including the
/*
* this isn't a valid reference, so lets short circuit the value
* and set calcs
*/
computableReference = false;
return nullString;
}
/*
* we need to see if this reference is escaped. if so
* we will clean off the leading \'s and let the
* regular behavior determine if we should output this
* as \$foo or $foo later on in render(). Lazyness..
*/
escaped = false;
if (t.image.startsWith("\\"))
{
/*
* count the escapes : even # -> not escaped, odd -> escaped
*/
int i = 0;
int len = t.image.length();
while (i < len && t.image.charAt(i) == '\\')
{
i++;
}
if ((i % 2) != 0)
escaped = true;
if (i > 0)
escPrefix = t.image.substring(0, i / 2 );
t.image = t.image.substring(i);
}
/*
* Look for preceeding stuff like '#' and '$'
* and snip it off, except for the
* last $
*/
int loc1 = t.image.lastIndexOf('$');
/*
* if we have extra stuff, loc > 0
* ex. '#$foo' so attach that to
* the prefix.
*/
if (loc1 > 0)
{
morePrefix = morePrefix + t.image.substring(0, loc1);
t.image = t.image.substring(loc1);
}
/*
* Now it should be clean. Get the literal in case this reference
* isn't backed by the context at runtime, and then figure out what
* we are working with.
*/
nullString = literal();
if (t.image.startsWith("$!"))
{
referenceType = QUIET_REFERENCE;
/*
* only if we aren't escaped do we want to null the output
*/
if (!escaped)
nullString = "";
if (t.image.startsWith("$!{"))
{
/*
* ex : $!{provider.Title}
*/
return t.next.image;
}
else
{
/*
* ex : $!provider.Title
*/
return t.image.substring(2);
}
}
else if (t.image.equals("${"))
{
/*
* ex : ${provider.Title}
*/
referenceType = FORMAL_REFERENCE;
return t.next.image;
}
else if (t.image.startsWith("$"))
{
/*
* just nip off the '$' so we have
* the root
*/
referenceType = NORMAL_REFERENCE;
return t.image.substring(1);
}
else
{
/*
* this is a 'RUNT', which can happen in certain circumstances where
* the parser is fooled into believeing that an IDENTIFIER is a real
* reference. Another 'dreaded' MORE hack :).
*/
referenceType = RUNT;
return t.image;
}
}
public Object getVariableValue(Context context, String variable)
{
return context.get(variable);
}
/**
* Routine to allow the literal representation to be
* externally overridden. Used now in the VM system
* to override a reference in a VM tree with the
* literal of the calling arg to make it work nicely
* when calling arg is null. It seems a bit much, but
* does keep things consistant.
*
* Note, you can only set the literal once...
*
* @param literal String to render to when null
*/
public void setLiteral(String literal)
{
/*
* do only once
*/
if( this.literal == null)
this.literal = literal;
}
/**
* Override of the SimpleNode method literal()
* Returns the literal representation of the
* node. Should be something like
* $<token>.
*/
public String literal()
{
if (literal != null)
return literal;
return super.literal();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -