Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
ognl.ASTChain Maven / Gradle / Ivy
// --------------------------------------------------------------------------
// Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// Neither the name of the Drew Davidson nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
// --------------------------------------------------------------------------
package ognl;
import ognl.enhance.ExpressionCompiler;
import ognl.enhance.OrderedReturn;
import ognl.enhance.UnsupportedCompilationException;
import java.lang.reflect.Array;
/**
* @author Luke Blanshard ([email protected] )
* @author Drew Davidson ([email protected] )
*/
public class ASTChain extends SimpleNode implements NodeType, OrderedReturn
{
private Class _getterClass;
private Class _setterClass;
private String _lastExpression;
private String _coreExpression;
public ASTChain(int id)
{
super(id);
}
public ASTChain(OgnlParser p, int id)
{
super(p, id);
}
public String getLastExpression()
{
return _lastExpression;
}
public String getCoreExpression()
{
return _coreExpression;
}
public void jjtClose()
{
flattenTree();
}
protected Object getValueBody(OgnlContext context, Object source)
throws OgnlException
{
Object result = source;
for(int i = 0, ilast = _children.length - 1; i <= ilast; ++i)
{
boolean handled = false;
if (i < ilast) {
if (_children[i] instanceof ASTProperty) {
ASTProperty propertyNode = (ASTProperty) _children[i];
int indexType = propertyNode.getIndexedPropertyType(context, result);
if ((indexType != OgnlRuntime.INDEXED_PROPERTY_NONE) && (_children[i + 1] instanceof ASTProperty)) {
ASTProperty indexNode = (ASTProperty) _children[i + 1];
if (indexNode.isIndexedAccess()) {
Object index = indexNode.getProperty(context, result);
if (index instanceof DynamicSubscript) {
if (indexType == OgnlRuntime.INDEXED_PROPERTY_INT) {
Object array = propertyNode.getValue(context, result);
int len = Array.getLength(array);
switch(((DynamicSubscript) index).getFlag()) {
case DynamicSubscript.ALL:
result = Array.newInstance(array.getClass().getComponentType(), len);
System.arraycopy(array, 0, result, 0, len);
handled = true;
i++;
break;
case DynamicSubscript.FIRST:
index = new Integer((len > 0) ? 0 : -1);
break;
case DynamicSubscript.MID:
index = new Integer((len > 0) ? (len / 2) : -1);
break;
case DynamicSubscript.LAST:
index = new Integer((len > 0) ? (len - 1) : -1);
break;
}
} else {
if (indexType == OgnlRuntime.INDEXED_PROPERTY_OBJECT) { throw new OgnlException(
"DynamicSubscript '" + indexNode
+ "' not allowed for object indexed property '" + propertyNode
+ "'"); }
}
}
if (!handled)
{
result = OgnlRuntime.getIndexedProperty(context, result,
propertyNode.getProperty(context, result).toString(),
index);
handled = true;
i++;
}
}
}
}
}
if (!handled)
{
result = _children[i].getValue(context, result);
}
}
return result;
}
protected void setValueBody(OgnlContext context, Object target, Object value)
throws OgnlException
{
boolean handled = false;
for(int i = 0, ilast = _children.length - 2; i <= ilast; ++i)
{
if (i <= ilast) {
if (_children[i] instanceof ASTProperty)
{
ASTProperty propertyNode = (ASTProperty) _children[i];
int indexType = propertyNode.getIndexedPropertyType(context, target);
if ((indexType != OgnlRuntime.INDEXED_PROPERTY_NONE) && (_children[i + 1] instanceof ASTProperty))
{
ASTProperty indexNode = (ASTProperty) _children[i + 1];
if (indexNode.isIndexedAccess())
{
Object index = indexNode.getProperty(context, target);
if (index instanceof DynamicSubscript)
{
if (indexType == OgnlRuntime.INDEXED_PROPERTY_INT)
{
Object array = propertyNode.getValue(context, target);
int len = Array.getLength(array);
switch(((DynamicSubscript) index).getFlag())
{
case DynamicSubscript.ALL:
System.arraycopy(target, 0, value, 0, len);
handled = true;
i++;
break;
case DynamicSubscript.FIRST:
index = new Integer((len > 0) ? 0 : -1);
break;
case DynamicSubscript.MID:
index = new Integer((len > 0) ? (len / 2) : -1);
break;
case DynamicSubscript.LAST:
index = new Integer((len > 0) ? (len - 1) : -1);
break;
}
} else
{
if (indexType == OgnlRuntime.INDEXED_PROPERTY_OBJECT)
{
throw new OgnlException("DynamicSubscript '" + indexNode
+ "' not allowed for object indexed property '" + propertyNode
+ "'");
}
}
}
if (!handled && i == ilast)
{
OgnlRuntime.setIndexedProperty(context, target,
propertyNode.getProperty(context, target).toString(),
index, value);
handled = true;
i++;
} else if (!handled) {
target = OgnlRuntime.getIndexedProperty(context, target,
propertyNode.getProperty(context, target).toString(),
index);
i++;
continue;
}
}
}
}
}
if (!handled)
{
target = _children[i].getValue(context, target);
}
}
if (!handled)
{
_children[_children.length - 1].setValue(context, target, value);
}
}
public boolean isSimpleNavigationChain(OgnlContext context)
throws OgnlException
{
boolean result = false;
if ((_children != null) && (_children.length > 0)) {
result = true;
for(int i = 0; result && (i < _children.length); i++) {
if (_children[i] instanceof SimpleNode) {
result = ((SimpleNode) _children[i]).isSimpleProperty(context);
} else {
result = false;
}
}
}
return result;
}
public Class getGetterClass()
{
return _getterClass;
}
public Class getSetterClass()
{
return _setterClass;
}
public String toString()
{
String result = "";
if ((_children != null) && (_children.length > 0)) {
for(int i = 0; i < _children.length; i++) {
if (i > 0) {
if (!(_children[i] instanceof ASTProperty) || !((ASTProperty) _children[i]).isIndexedAccess()) {
result = result + ".";
}
}
result += _children[i].toString();
}
}
return result;
}
public String toGetSourceString(OgnlContext context, Object target)
{
String prevChain = (String)context.get("_currentChain");
if (target != null)
{
context.setCurrentObject(target);
context.setCurrentType(target.getClass());
}
String result = "";
NodeType _lastType = null;
boolean ordered = false;
boolean constructor = false;
try {
if ((_children != null) && (_children.length > 0))
{
for(int i = 0; i < _children.length; i++)
{
/* System.out.println("astchain child: " + _children[i].getClass().getName()
+ " with current object target " + context.getCurrentObject()
+ " current type: " + context.getCurrentType());*/
String value = _children[i].toGetSourceString(context, context.getCurrentObject());
// System.out.println("astchain child returned >> " + value + " <<");
if (ASTCtor.class.isInstance(_children[i]))
constructor = true;
if (NodeType.class.isInstance(_children[i])
&& ((NodeType)_children[i]).getGetterClass() != null)
{
_lastType = (NodeType)_children[i];
}
// System.out.println("Astchain i: " + i + " currentobj : " + context.getCurrentObject() + " and root: " + context.getRoot());
if (!ASTVarRef.class.isInstance(_children[i]) && !constructor
&& !(OrderedReturn.class.isInstance(_children[i]) && ((OrderedReturn)_children[i]).getLastExpression() != null)
&& (_parent == null || !ASTSequence.class.isInstance(_parent)))
{
value = OgnlRuntime.getCompiler().castExpression(context, _children[i], value);
}
/*System.out.println("astchain value now : " + value + " with index " + i
+ " current type " + context.getCurrentType() + " current accessor " + context.getCurrentAccessor()
+ " prev type " + context.getPreviousType() + " prev accessor " + context.getPreviousAccessor());*/
if (OrderedReturn.class.isInstance(_children[i]) && ((OrderedReturn)_children[i]).getLastExpression() != null)
{
ordered = true;
OrderedReturn or = (OrderedReturn)_children[i];
if (or.getCoreExpression() == null || or.getCoreExpression().trim().length() <= 0)
result = "";
else
result += or.getCoreExpression();
_lastExpression = or.getLastExpression();
if (context.get(ExpressionCompiler.PRE_CAST) != null)
{
_lastExpression = context.remove(ExpressionCompiler.PRE_CAST) + _lastExpression;
}
} else if (ASTOr.class.isInstance(_children[i])
|| ASTAnd.class.isInstance(_children[i])
|| ASTCtor.class.isInstance(_children[i])
|| (ASTStaticField.class.isInstance(_children[i]) && _parent == null))
{
context.put("_noRoot", "true");
result = value;
} else
{
result += value;
}
context.put("_currentChain", result);
}
}
} catch (Throwable t)
{
throw OgnlOps.castToRuntime(t);
}
if (_lastType != null)
{
_getterClass = _lastType.getGetterClass();
_setterClass = _lastType.getSetterClass();
}
if (ordered)
{
_coreExpression = result;
}
context.put("_currentChain", prevChain);
return result;
}
public String toSetSourceString(OgnlContext context, Object target)
{
String prevChain = (String)context.get("_currentChain");
String prevChild = (String)context.get("_lastChild");
if (prevChain != null)
throw new UnsupportedCompilationException("Can't compile nested chain expressions.");
if (target != null)
{
context.setCurrentObject(target);
context.setCurrentType(target.getClass());
}
String result = "";
NodeType _lastType = null;
boolean constructor = false;
try {
if ((_children != null) && (_children.length > 0))
{
if (ASTConst.class.isInstance(_children[0]))
{
throw new UnsupportedCompilationException("Can't modify constant values.");
}
for(int i = 0; i < _children.length; i++)
{
// System.out.println("astchain setsource child[" + i + "] : " + _children[i].getClass().getName());
if (i == (_children.length -1))
{
context.put("_lastChild", "true");
}
String value = _children[i].toSetSourceString(context, context.getCurrentObject());
//if (value == null || value.trim().length() <= 0)
// return "";
// System.out.println("astchain setter child returned >> " + value + " <<");
if (ASTCtor.class.isInstance(_children[i]))
constructor = true;
if (NodeType.class.isInstance(_children[i])
&& ((NodeType)_children[i]).getGetterClass() != null)
{
_lastType = (NodeType)_children[i];
}
if (!ASTVarRef.class.isInstance(_children[i]) && !constructor
&& !(OrderedReturn.class.isInstance(_children[i]) && ((OrderedReturn)_children[i]).getLastExpression() != null)
&& (_parent == null || !ASTSequence.class.isInstance(_parent)))
{
value = OgnlRuntime.getCompiler().castExpression(context, _children[i], value);
}
// System.out.println("astchain setter after cast value is: " + value);
/*if (!constructor && !OrderedReturn.class.isInstance(_children[i])
&& (_parent == null || !ASTSequence.class.isInstance(_parent)))
{
value = OgnlRuntime.getCompiler().castExpression(context, _children[i], value);
}*/
if (ASTOr.class.isInstance(_children[i])
|| ASTAnd.class.isInstance(_children[i])
|| ASTCtor.class.isInstance(_children[i])
|| ASTStaticField.class.isInstance(_children[i])) {
context.put("_noRoot", "true");
result = value;
} else
result += value;
context.put("_currentChain", result);
}
}
} catch (Throwable t)
{
throw OgnlOps.castToRuntime(t);
}
context.put("_lastChild", prevChild);
context.put("_currentChain", prevChain);
if (_lastType != null)
_setterClass = _lastType.getSetterClass();
return result;
}
@Override
public boolean isChain(OgnlContext context) {
return true;
}
}