1 /***************************************************************************** 2 * Licensed to the Apache Software Foundation (ASF) under one * 3 * or more contributor license agreements. See the NOTICE file * 4 * distributed with this work for additional information * 5 * regarding copyright ownership. The ASF licenses this file * 6 * to you under the Apache License, Version 2.0 (the * 7 * "License"); you may not use this file except in compliance * 8 * with the License. You may obtain a copy of the License at * 9 * * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, * 13 * software distributed under the License is distributed on an * 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 15 * KIND, either express or implied. See the License for the * 16 * specific language governing permissions and limitations * 17 * under the License. * 18 * * 19 * * 20 * This file is part of the BeanShell Java Scripting distribution. * 21 * Documentation and updates may be found at http://www.beanshell.org/ * 22 * Patrick Niemeyer (pat@pat.net) * 23 * Author of Learning Java, O'Reilly & Associates * 24 * * 25 *****************************************************************************/ 26 package bsh; 27 28 public class Variable implements java.io.Serializable 29 { 30 static final int DECLARATION=0, ASSIGNMENT=1; 31 /** A null type means an untyped variable */ 32 String name; 33 Class type = null; 34 String typeDescriptor; 35 Object value; 36 Modifiers modifiers; 37 LHS lhs; 38 Variable( String name, Class type, LHS lhs )39 Variable( String name, Class type, LHS lhs ) 40 { 41 this.name = name; 42 this.lhs = lhs; 43 this.type = type; 44 } 45 Variable( String name, Object value, Modifiers modifiers )46 Variable( String name, Object value, Modifiers modifiers ) 47 throws UtilEvalError 48 { 49 this( name, (Class)null/*type*/, value, modifiers ); 50 } 51 52 /** 53 This constructor is used in class generation. 54 */ Variable( String name, String typeDescriptor, Object value, Modifiers modifiers )55 Variable( 56 String name, String typeDescriptor, Object value, Modifiers modifiers 57 ) 58 throws UtilEvalError 59 { 60 this( name, (Class)null/*type*/, value, modifiers ); 61 this.typeDescriptor = typeDescriptor; 62 } 63 64 /** 65 @param value may be null if this 66 */ Variable( String name, Class type, Object value, Modifiers modifiers )67 Variable( String name, Class type, Object value, Modifiers modifiers ) 68 throws UtilEvalError 69 { 70 71 this.name=name; 72 this.type = type; 73 this.modifiers = modifiers; 74 setValue( value, DECLARATION ); 75 } 76 77 /** 78 Set the value of the typed variable. 79 @param value should be an object or wrapped bsh Primitive type. 80 if value is null the appropriate default value will be set for the 81 type: e.g. false for boolean, zero for integer types. 82 */ setValue( Object value, int context )83 public void setValue( Object value, int context ) 84 throws UtilEvalError 85 { 86 87 // check this.value 88 if (hasModifier("final")) { 89 if (this.value != null) { 90 throw new UtilEvalError("Final variable '" + getName() + "', can't re-assign."); 91 } else if (value == null && context == DECLARATION) { 92 return; 93 } 94 } 95 96 if ( value == null ) 97 value = Primitive.getDefaultValue( type ); 98 99 if ( lhs != null ) 100 { 101 lhs.assign( Primitive.unwrap(value), false/*strictjava*/ ); 102 return; 103 } 104 105 // TODO: should add isJavaCastable() test for strictJava 106 // (as opposed to isJavaAssignable()) 107 if ( type != null ) 108 value = Types.castObject( value, type, 109 context == DECLARATION ? Types.CAST : Types.ASSIGNMENT 110 ); 111 112 this.value= value; 113 } 114 115 /* 116 Note: UtilEvalError here comes from lhs.getValue(). 117 A Variable can represent an LHS for the case of an imported class or 118 object field. 119 */ getValue()120 Object getValue() 121 throws UtilEvalError 122 { 123 if ( lhs != null ) 124 return type == null ? 125 lhs.getValue() : Primitive.wrap( lhs.getValue(), type ); 126 127 return value; 128 } 129 130 /** A type of null means loosely typed variable */ getType()131 public Class getType() { return type; } 132 getTypeDescriptor()133 public String getTypeDescriptor() { return typeDescriptor; } 134 getModifiers()135 public Modifiers getModifiers() { return modifiers; } 136 getName()137 public String getName() { return name; } 138 hasModifier( String name )139 public boolean hasModifier( String name ) { 140 return modifiers != null && modifiers.hasModifier(name); 141 } 142 toString()143 public String toString() { 144 return "Variable: "+super.toString()+" "+name+", type:"+type 145 +", value:"+value +", lhs = "+lhs; 146 } 147 } 148