@Override @Nullable public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (ReflectionUtils.isEqualsMethod(method)) { return (isProxyForSameBshObject(args[0])); } else if (ReflectionUtils.isHashCodeMethod(method)) { return this.xt.hashCode(); } else if (ReflectionUtils.isToStringMethod(method)) { return "BeanShell object [" + this.xt + "]"; } try { Object result = this.xt.invokeMethod(method.getName(), args); if (result == Primitive.NULL || result == Primitive.VOID) { return null; } if (result instanceof Primitive) { return ((Primitive) result).getValue(); } return result; } catch (EvalError ex) { throw new BshExecutionException(ex); } }
public static Object [] unwrap( Object[] args ) { if ( args == null ) return null; Object [] oa = new Object[ args.length ]; for(int i=0; i<args.length; i++) oa[i] = unwrap( args[i] ); return oa; }
/** Cast this bsh.Primitive value to a new bsh.Primitive value This is usually a numeric type cast. Other cases include: A boolean can be cast to boolen null can be cast to any object type and remains null Attempting to cast a void causes an exception @param toType is the java object or primitive TYPE class */ public Primitive castToType( Class toType, int operation ) throws UtilEvalError { return castPrimitive( toType, getType()/*fromType*/, this/*fromValue*/, false/*checkOnly*/, operation ); }
/** Helper class for type suffixes. */ public static class Suffix { private static final Map<String, Class<?>> m = Collections.unmodifiableMap(new HashMap<String, Class<?>>() { private static final long serialVersionUID = 1L; { put("O", Byte.TYPE); put("S", Short.TYPE); put("I", Integer.TYPE); put("L", Long.TYPE); put("W", BigInteger.class); put("w", BigDecimal.class); put("d", Double.TYPE); put("f", Float.TYPE); } }); private static String toUpperKey(Character key) { return key.toString().toUpperCase(); } private static String toLowerKey(Character key) { return key.toString().toLowerCase(); } public static boolean isIntegral(Character key) { return m.containsKey(toUpperKey(key)); } public static Class<?> getIntegralType(Character key) { return m.get(toUpperKey(key));
"illegal use of undefined object or 'void' literal"); Class operandType = val.getType(); Object operand = promoteToInteger(val.getValue()); return new Primitive(booleanUnaryOperation((Boolean)operand, kind)); else if(operand instanceof Integer) int result = intUnaryOperation((Integer)operand, kind); return new Primitive((byte)result); if(operandType == Short.TYPE) return new Primitive((short)result); if(operandType == Character.TYPE) return new Primitive((char)result); return new Primitive(result); return new Primitive(longUnaryOperation((Long)operand, kind)); else if(operand instanceof Float) return new Primitive(floatUnaryOperation((Float)operand, kind)); else if(operand instanceof Double) return new Primitive(doubleUnaryOperation((Double)operand, kind)); else throw new InterpreterError(
if ( !checkOnly && fromValue == null ) throw new InterpreterError("bad cast param 2"); if ( fromType != null && !(isWrapperType(fromType)||fromType.isPrimitive()) ) throw new InterpreterError("bad fromType:" +fromType); if ( fromValue == Primitive.NULL && fromType != null ) if ( !checkOnly && fromValue.isNumber() ) return new Primitive( castNumber(toType, fromValue.numberValue()) ); return checkOnly ? Types.VALID_CAST : getDefaultValue(toType); new Primitive( castWrapper(toType, fromValue.getValue()) );
obj1 = Primitive.unwrap(obj1); obj2 = Primitive.unwrap(obj2); return (Primitive) Primitive.wrap(result, result.getClass()); else return Primitive.shrinkWrap( result ); return Primitive.shrinkWrap( result ).getValue();
"illegal use of undefined object or 'void' literal"); Class<?> operandType = val.getType(); return booleanUnaryOperation((Boolean) val.getValue(), kind) ? Primitive.TRUE : Primitive.FALSE; Number operand = promoteToInteger(val.getValue()); if(operand instanceof Integer) return new Primitive((byte) result); if(operandType == Short.TYPE) return new Primitive((short) result); if(operandType == Character.TYPE) return new Primitive((char) result); return new Primitive(result); return new Primitive(longUnaryOperation(operand.longValue(), kind)); if(operand instanceof Float) return new Primitive(floatUnaryOperation(operand.floatValue(), kind)); if(operand instanceof Double) return new Primitive(doubleUnaryOperation(operand.doubleValue(), kind)); if(operand instanceof BigInteger) return new Primitive(bigIntegerUnaryOperation((BigInteger) operand, kind)); if(operand instanceof BigDecimal) return new Primitive(bigDecimalUnaryOperation((BigDecimal) operand, kind));
obj1 = ((Primitive)obj1).getValue(); if ( obj2 instanceof Primitive ) obj2 = ((Primitive)obj2).getValue(); Object[] operands = promotePrimitives(obj1, obj2); Object lhs = operands[0]; Object rhs = operands[1]; result = binaryOperationImpl( lhs, rhs, kind ); } catch ( ArithmeticException e ) { throw new UtilTargetError( "Arithemetic Exception in binary op", e); || result instanceof Boolean return new Primitive( result ); else return result;
if( Types.Suffix.isIntegral(ch) ) jjtn000.value = parseIntegral(literal.substring(0, last)) .castToType(Types.Suffix.getIntegralType(ch), 0); else jjtn000.value = Primitive.shrinkWrap(parseIntegral(literal).getValue()); } catch ( NumberFormatException e ) { throw createParseException( e.getMessage(), e ); try { if( Types.Suffix.isFloatingPoint(ch) ) jjtn000.value = new Primitive(new java.math.BigDecimal(literal.substring(0, last))) .castToType(Types.Suffix.getFloatingPointType(ch), 0); else jjtn000.value = Primitive.shrinkWrap( new java.math.BigDecimal( literal ) ); } catch ( NumberFormatException e ) { throw createParseException( e.getMessage(), e );
public Object invoke(final Map<String, ?> context) throws EvalError { final NameSpace nameSpace = new NameSpace(_interpreter.getClassManager(), "BeanshellExecutable"); nameSpace.setParent(_interpreter.getNameSpace()); final BshMethod method = new BshMethod(_method.getName(), _method.getReturnType(), _method.getParameterNames(), _method.getParameterTypes(), _method.methodBody, nameSpace, _method.getModifiers()); for (final Map.Entry<String, ?> entry : context.entrySet()) { try { nameSpace.setVariable(entry.getKey(), entry.getValue(), false); } catch (final UtilEvalError e) { throw new EvalError("cannot set variable '" + entry.getKey() + '\'', null, null, e); } } final Object result = method.invoke(new Object[0], new BshEvaluatingVisitor(null, _interpreter)); if (result instanceof Primitive) { if (( (Primitive) result).getType() == Void.TYPE) { return null; } return ( (Primitive) result).getValue(); } return result; }
/** Find the type of an object boxed or not. * @param arg the object to query. * @param boxed whether to get a primitive or boxed type. * @return null if arg null, type of Primitive or getClass. */ public static Class<?> getType( Object arg, boolean boxed ) { if ( null == arg || Primitive.NULL == arg ) return null; if ( arg instanceof Primitive && !boxed ) return ((Primitive) arg).getType(); return Primitive.unwrap(arg).getClass(); }
value = fromValue.getValue(); new Primitive( castWrapper(toType, value) );
/** Cast a primitive value represented by its java.lang wrapper type to the specified java.lang wrapper type. e.g. Byte(5) to Integer(5) or Integer(5) to Byte(5) @param toType is the java TYPE type @param value is the value in java.lang wrapper. value may not be null. */ static Object castWrapper( Class<?> toType, Object value ) { value = Primitive.unwrap(value); if ( !(Primitive.isWrapperType(toType) || toType.isPrimitive()) ) throw new InterpreterError("invalid type in castWrapper: "+toType); if ( value == null ) throw new InterpreterError("null value in castWrapper, guard"); if ( value instanceof Boolean ) { if ( toType != Boolean.TYPE ) throw new InterpreterError("bad wrapper cast of boolean"); return value; } // first promote char to Number type to avoid duplicating code if ( value instanceof Character ) value = Integer.valueOf(((Character)value).charValue()); if ( !(value instanceof Number) ) throw new InterpreterError("bad type in cast "+StringUtil.typeValueString(value)); return castNumber(toType, (Number) value); }
/** Wrap primitive values (as indicated by type param) and nulls in the Primitive class. Values not primitive or null are left unchanged. Primitive values are represented by their wrapped values in param value. <p/> The value null is mapped to Primitive.NULL. Any value specified with type Void.TYPE is mapped to Primitive.VOID. */ public static Object wrap( Object value, Class type ) { if ( type == Void.TYPE ) return Primitive.VOID; if ( value == null ) return Primitive.NULL; if ( type.isPrimitive() ) return new Primitive( value ); return value; }
/** Primitives compare equal with other Primitives containing an equal wrapped value. */ public boolean equals( Object obj ) { if ( !( obj instanceof Primitive ) ) if ( wrapperMap.containsKey(obj.getClass()) ) obj = new Primitive(obj); else return false; Primitive pobj = (Primitive) obj; if ( pobj.isNumber() && this.isNumber() ) { if ( this.getType() == BigDecimal.class ) return this.value.equals(castNumber(BigDecimal.class, pobj.numberValue())); if ( pobj.getType() == BigDecimal.class ) return pobj.value.equals(castNumber(BigDecimal.class, this.numberValue())); if (Types.isFloatingpoint(this.value) || Types.isFloatingpoint(pobj.value)) return this.numberValue().doubleValue() == pobj.numberValue().doubleValue(); if ( this.getType() == BigInteger.class ) return this.value.equals(castNumber(BigInteger.class, pobj.numberValue())); if ( pobj.getType() == BigInteger.class ) return pobj.value.equals(castNumber(BigInteger.class, this.numberValue())); return this.numberValue().longValue() == pobj.numberValue().longValue(); } return this.value.equals( pobj.value ); }
return new Primitive(false); return new Primitive(true); else return new Primitive(false); return new Primitive(ret); Object obj = lhs; if ( node.isPrimitiveValue(lhs) ) obj = ((Primitive)lhs).getValue(); if ( obj instanceof Boolean && ( ((Boolean)obj).booleanValue() == false ) ) return new Primitive(false); Object obj = lhs; if ( node.isPrimitiveValue(lhs) ) obj = ((Primitive)lhs).getValue(); if ( obj instanceof Boolean && ( ((Boolean)obj).booleanValue() == true ) ) return new Primitive(true); return Primitive.binaryOperation(lhs, rhs, node.kind); } catch ( UtilEvalError e ) { throw e.toEvalError( node, callstack ); return new Primitive((lhs == rhs)); return new Primitive((lhs != rhs));
/** Fill boxed numeric types with default numbers instead of nulls. * @param arr the array to fill. */ private void arrayFillDefaultValue(Object arr) { if (null == arr) return; Class<?> clas = arr.getClass(); Class<?> comp = Types.arrayElementType(clas); if ( !comp.isPrimitive() ) if ( Types.arrayDimensions(clas) > 1 ) for ( int i = 0; i < Array.getLength(arr); i++ ) arrayFillDefaultValue(Array.get(arr, i)); else Arrays.fill((Object[]) arr, Primitive.unwrap( Primitive.getDefaultValue(comp))); } }
/** Helper method for testing equals on two primitive or boxable objects. yuck: factor this out into Primitive.java */ public boolean primitiveEquals( BSHSwitchStatement node, Object switchVal, Object targetVal, SimpleNode switchExp ) throws EvalError { if ( switchVal instanceof Primitive || targetVal instanceof Primitive ) try { // binaryOperation can return Primitive or wrapper type Object result = Primitive.binaryOperation( switchVal, targetVal, ParserConstants.EQ ); result = Primitive.unwrap( result ); return result.equals( Boolean.TRUE ); } catch ( UtilEvalError e ) { throw e.toEvalError( "Switch value: "+switchExp.getText()+": ", node, callstack ); } else return switchVal.equals( targetVal ); }