use of org.mvel2.compiler.Accessor in project mvel by mvel.
the class AbstractOptimizer method tryStaticAccess.
/**
* Try static access of the property, and return an instance of the Field, Method of Class if successful.
*
* @return - Field, Method or Class instance.
*/
protected Object tryStaticAccess() {
int begin = cursor;
try {
/**
* Try to resolve this *smartly* as a static class reference.
*
* This starts at the end of the token and starts to step backwards to figure out whether
* or not this may be a static class reference. We search for method calls simply by
* inspecting for ()'s. The first union area we come to where no brackets are present is our
* test-point for a class reference. If we find a class, we pass the reference to the
* property accessor along with trailing methods (if any).
*/
boolean meth = false;
// int end = start + length;
int last = end;
for (int i = end - 1; i > start; i--) {
switch(expr[i]) {
case '.':
if (!meth) {
ClassLoader classLoader = pCtx != null ? pCtx.getClassLoader() : currentThread().getContextClassLoader();
String test = new String(expr, start, (cursor = last) - start);
try {
if (MVEL.COMPILER_OPT_SUPPORT_JAVA_STYLE_CLASS_LITERALS && test.endsWith(".class"))
test = test.substring(0, test.length() - 6);
return Class.forName(test, true, classLoader);
} catch (ClassNotFoundException cnfe) {
try {
return findInnerClass(test, classLoader, cnfe);
} catch (ClassNotFoundException e) {
/* ignore */
}
Class cls = forNameWithInner(new String(expr, start, i - start), classLoader);
String name = new String(expr, i + 1, end - i - 1);
try {
return cls.getField(name);
} catch (NoSuchFieldException nfe) {
for (Method m : cls.getMethods()) {
if (name.equals(m.getName()))
return m;
}
return null;
}
}
}
meth = false;
last = i;
break;
case '}':
i--;
for (int d = 1; i > start && d != 0; i--) {
switch(expr[i]) {
case '}':
d++;
break;
case '{':
d--;
break;
case '"':
case '\'':
char s = expr[i];
while (i > start && (expr[i] != s && expr[i - 1] != '\\')) i--;
}
}
break;
case ')':
i--;
for (int d = 1; i > start && d != 0; i--) {
switch(expr[i]) {
case ')':
d++;
break;
case '(':
d--;
break;
case '"':
case '\'':
char s = expr[i];
while (i > start && (expr[i] != s && expr[i - 1] != '\\')) i--;
}
}
meth = true;
last = i++;
break;
case '\'':
while (--i > start) {
if (expr[i] == '\'' && expr[i - 1] != '\\') {
break;
}
}
break;
case '"':
while (--i > start) {
if (expr[i] == '"' && expr[i - 1] != '\\') {
break;
}
}
break;
}
}
} catch (Exception cnfe) {
cursor = begin;
}
return null;
}
use of org.mvel2.compiler.Accessor in project mvel by mvel.
the class LiteralDeepPropertyNode method getReducedValueAccelerated.
public Object getReducedValueAccelerated(Object ctx, Object thisValue, VariableResolverFactory factory) {
if (accessor != null) {
return accessor.getValue(literal, thisValue, factory);
} else {
try {
AccessorOptimizer aO = getThreadAccessorOptimizer();
accessor = aO.optimizeAccessor(pCtx, expr, start, offset, literal, thisValue, factory, false, null);
return aO.getResultOptPass();
} finally {
OptimizerFactory.clearThreadAccessorOptimizer();
}
}
}
use of org.mvel2.compiler.Accessor in project mvel by mvel.
the class ReflectiveAccessorOptimizer method _getAccessor.
private Accessor _getAccessor(Object o, Class type) {
if (o instanceof List) {
Accessor[] a = new Accessor[((List) o).size()];
int i = 0;
for (Object item : (List) o) {
a[i++] = _getAccessor(item, type);
}
returnType = List.class;
return new ListCreator(a);
} else if (o instanceof Map) {
Accessor[] k = new Accessor[((Map) o).size()];
Accessor[] v = new Accessor[k.length];
int i = 0;
for (Object item : ((Map) o).keySet()) {
// key
k[i] = _getAccessor(item, type);
// value
v[i++] = _getAccessor(((Map) o).get(item), type);
}
returnType = Map.class;
return new MapCreator(k, v);
} else if (o instanceof Object[]) {
Accessor[] a = new Accessor[((Object[]) o).length];
int i = 0;
int dim = 0;
if (type != null) {
String nm = type.getName();
while (nm.charAt(dim) == '[') dim++;
} else {
type = Object[].class;
dim = 1;
}
try {
Class base = getBaseComponentType(type);
Class cls = dim > 1 ? findClass(null, repeatChar('[', dim - 1) + "L" + base.getName() + ";", pCtx) : type;
for (Object item : (Object[]) o) {
expectType(pCtx, a[i++] = _getAccessor(item, cls), base, true);
}
return new ArrayCreator(a, getSubComponentType(type));
} catch (ClassNotFoundException e) {
throw new RuntimeException("this error should never throw:" + getBaseComponentType(type).getName(), e);
}
} else {
if (returnType == null)
returnType = Object.class;
if (type.isArray()) {
return new ExprValueAccessor((String) o, type, ctx, variableFactory, pCtx);
} else {
return new ExprValueAccessor((String) o, Object.class, ctx, variableFactory, pCtx);
}
}
}
use of org.mvel2.compiler.Accessor in project mvel by mvel.
the class ReflectiveAccessorOptimizer method getBeanProperty.
private Object getBeanProperty(Object ctx, String property) throws Exception {
if ((pCtx == null ? currType : pCtx.getVarOrInputTypeOrNull(property)) == Object.class && !pCtx.isStrongTyping()) {
currType = null;
}
if (first) {
if ("this".equals(property)) {
addAccessorNode(new ThisValueAccessor());
return this.thisRef;
} else if (variableFactory != null && variableFactory.isResolveable(property)) {
if (variableFactory.isIndexedFactory() && variableFactory.isTarget(property)) {
int idx;
addAccessorNode(new IndexedVariableAccessor(idx = variableFactory.variableIndexOf(property)));
VariableResolver vr = variableFactory.getIndexedVariableResolver(idx);
if (vr == null) {
variableFactory.setIndexedVariableResolver(idx, variableFactory.getVariableResolver(property));
}
return variableFactory.getIndexedVariableResolver(idx).getValue();
} else {
addAccessorNode(new VariableAccessor(property));
return variableFactory.getVariableResolver(property).getValue();
}
}
}
boolean classRef = false;
Class<?> cls;
if (ctx instanceof Class) {
if (MVEL.COMPILER_OPT_SUPPORT_JAVA_STYLE_CLASS_LITERALS && "class".equals(property)) {
return ctx;
}
cls = (Class<?>) ctx;
classRef = true;
} else if (ctx != null) {
cls = ctx.getClass();
} else {
cls = currType;
}
if (hasPropertyHandler(cls)) {
PropertyHandlerAccessor acc = new PropertyHandlerAccessor(property, cls, getPropertyHandler(cls));
addAccessorNode(acc);
return acc.getValue(ctx, thisRef, variableFactory);
}
Member member = cls != null ? getFieldOrAccessor(cls, property) : null;
if (member != null && classRef && (member.getModifiers() & Modifier.STATIC) == 0) {
member = null;
}
Object o;
if (member instanceof Method) {
try {
o = ctx != null ? ((Method) member).invoke(ctx, EMPTYARG) : null;
if (hasNullPropertyHandler()) {
addAccessorNode(new GetterAccessorNH((Method) member, getNullPropertyHandler()));
if (o == null)
o = getNullPropertyHandler().getProperty(member.getName(), ctx, variableFactory);
} else {
addAccessorNode(new GetterAccessor((Method) member));
}
} catch (IllegalAccessException e) {
Method iFaceMeth = determineActualTargetMethod((Method) member);
if (iFaceMeth == null)
throw new PropertyAccessException("could not access field: " + cls.getName() + "." + property, this.expr, this.start, pCtx);
o = iFaceMeth.invoke(ctx, EMPTYARG);
if (hasNullPropertyHandler()) {
addAccessorNode(new GetterAccessorNH((Method) member, getNullMethodHandler()));
if (o == null)
o = getNullMethodHandler().getProperty(member.getName(), ctx, variableFactory);
} else {
addAccessorNode(new GetterAccessor(iFaceMeth));
}
} catch (IllegalArgumentException e) {
if (member.getDeclaringClass().equals(ctx)) {
try {
Class c = Class.forName(member.getDeclaringClass().getName() + "$" + property);
throw new CompileException("name collision between innerclass: " + c.getCanonicalName() + "; and bean accessor: " + property + " (" + member.toString() + ")", expr, tkStart);
} catch (ClassNotFoundException e2) {
// fallthru
}
}
throw e;
}
currType = toNonPrimitiveType(((Method) member).getReturnType());
return o;
} else if (member != null) {
Field f = (Field) member;
if ((f.getModifiers() & Modifier.STATIC) != 0) {
o = f.get(null);
if (hasNullPropertyHandler()) {
addAccessorNode(new StaticVarAccessorNH((Field) member, getNullMethodHandler()));
if (o == null)
o = getNullMethodHandler().getProperty(member.getName(), ctx, variableFactory);
} else {
addAccessorNode(new StaticVarAccessor((Field) member));
}
} else {
o = ctx != null ? f.get(ctx) : null;
if (hasNullPropertyHandler()) {
addAccessorNode(new FieldAccessorNH((Field) member, getNullMethodHandler()));
if (o == null)
o = getNullMethodHandler().getProperty(member.getName(), ctx, variableFactory);
} else {
addAccessorNode(new FieldAccessor((Field) member));
}
}
currType = toNonPrimitiveType(f.getType());
return o;
} else if (ctx instanceof Map && (((Map) ctx).containsKey(property) || nullSafe)) {
addAccessorNode(new MapAccessor(property));
return ((Map) ctx).get(property);
} else if (ctx != null && "length".equals(property) && ctx.getClass().isArray()) {
addAccessorNode(new ArrayLength());
return getLength(ctx);
} else if (LITERALS.containsKey(property)) {
addAccessorNode(new StaticReferenceAccessor(ctx = LITERALS.get(property)));
return ctx;
} else {
Object tryStaticMethodRef = tryStaticAccess();
staticAccess = true;
if (tryStaticMethodRef != null) {
if (tryStaticMethodRef instanceof Class) {
addAccessorNode(new StaticReferenceAccessor(tryStaticMethodRef));
return tryStaticMethodRef;
} else if (tryStaticMethodRef instanceof Field) {
addAccessorNode(new StaticVarAccessor((Field) tryStaticMethodRef));
return ((Field) tryStaticMethodRef).get(null);
} else {
addAccessorNode(new StaticReferenceAccessor(tryStaticMethodRef));
return tryStaticMethodRef;
}
} else if (ctx instanceof Class) {
Class c = (Class) ctx;
for (Method m : c.getMethods()) {
if (property.equals(m.getName())) {
if (pCtx != null && pCtx.getParserConfiguration() != null ? pCtx.getParserConfiguration().isAllowNakedMethCall() : MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL) {
o = m.invoke(null, EMPTY_OBJ_ARR);
if (hasNullMethodHandler()) {
addAccessorNode(new MethodAccessorNH(m, new ExecutableStatement[0], getNullMethodHandler()));
if (o == null)
o = getNullMethodHandler().getProperty(m.getName(), ctx, variableFactory);
} else {
addAccessorNode(new MethodAccessor(m, new ExecutableStatement[0]));
}
return o;
} else {
addAccessorNode(new StaticReferenceAccessor(m));
return m;
}
}
}
try {
Class subClass = findClass(variableFactory, c.getName() + "$" + property, pCtx);
addAccessorNode(new StaticReferenceAccessor(subClass));
return subClass;
} catch (ClassNotFoundException cnfe) {
// fall through.
}
} else if (pCtx != null && pCtx.getParserConfiguration() != null ? pCtx.getParserConfiguration().isAllowNakedMethCall() : MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL) {
return getMethod(ctx, property);
}
if (ctx == null) {
throw new PropertyAccessException("unresolvable property or identifier: " + property, expr, start, pCtx);
} else {
throw new PropertyAccessException("could not access: " + property + "; in class: " + ctx.getClass().getName(), expr, start, pCtx);
}
}
}
use of org.mvel2.compiler.Accessor in project mvel by mvel.
the class ReflectiveAccessorOptimizer method optimizeObjectCreation.
public Accessor optimizeObjectCreation(ParserContext pCtx, char[] property, int start, int offset, Object ctx, Object thisRef, VariableResolverFactory factory) {
this.length = start + offset;
this.cursor = this.start = start;
this.pCtx = pCtx;
try {
return compileConstructor(property, ctx, factory);
} catch (CompileException e) {
throw ErrorUtil.rewriteIfNeeded(e, property, this.start);
} catch (ClassNotFoundException e) {
throw new CompileException("could not resolve class: " + e.getMessage(), property, this.start, e);
} catch (Exception e) {
throw new CompileException("could not create constructor: " + e.getMessage(), property, this.start, e);
}
}
Aggregations