Пример #1
0
  @Around("execution(* javax.validation.ConstraintValidator.isValid(..)) && args(value, context)")
  public Object aroundValid(
      ProceedingJoinPoint jointPoint, Object value, ConstraintValidatorContext context)
      throws Throwable {
    if (value == null) {
      // @NotNullのケースが有るため、処理させる。他Validationは通常Null時はパスなので
      return jointPoint.proceed();
    }
    ValidateContext validateContext = ValidateContext.instance();
    Object declaring = null;
    Condition condition = null;
    if (validateContext.isAnnotatedClass()) {
      condition = value.getClass().getAnnotation(Condition.class);
      declaring = value;
    } else if (validateContext.isAnnotatedField() || validateContext.isAnnotatedMethod()) {
      AccessibleObject accessible = (AccessibleObject) validateContext.getAnnotated();
      condition = accessible.getAnnotation(Condition.class);
      declaring = validateContext.getDeclared();
    }

    if (condition != null && declaring != null && !judgeCondition(condition, declaring)) {
      // @Condition判定処理結果がfalseなので、Validate処理外
      return true;
    }
    return jointPoint.proceed();
  }
Пример #2
0
  /** Sets the access flag of a member */
  @Override
  protected void setAccessFlag(final Member m) {
    final int mods = m.getModifiers();
    final Class c = m.getDeclaringClass();
    final int cmods = c.getModifiers();
    final String pkg = this.importationManager.getCurrentPackage();
    final String mp = getPackageName(c);
    final boolean samePkg = pkg.equals(mp);

    if (Modifier.isPublic(cmods) || samePkg) {
      if (Modifier.isPublic(mods)) {
        ((AccessibleObject) m).setAccessible(true);
      } else if (Modifier.isProtected(mods)) {
        if (c.isAssignableFrom(this.declaringClass.getSuperclass()) || samePkg) {
          ((AccessibleObject) m).setAccessible(true);
        }
      } else if (!Modifier.isPrivate(mods)) {
        if (samePkg) {
          ((AccessibleObject) m).setAccessible(true);
        }
      } else {
        if (this.declaringClass == c || isInnerClass(this.declaringClass, c)) {
          ((AccessibleObject) m).setAccessible(true);
        }
      }
    }
  }
Пример #3
0
  @SafeVarargs
  public static List<Accessor> getAnnotatedAccessors(
      Class<?> cls,
      Comparator<Accessor> comparator,
      Class<? extends Annotation>... annotationClasses) {
    List<Accessor> accessors = new ArrayList<>();
    List<AccessibleObject> accessibleObjects = new ArrayList<>();

    accessibleObjects.addAll(Arrays.asList(cls.getDeclaredFields()));
    accessibleObjects.addAll(Arrays.asList(cls.getDeclaredMethods()));

    for (AccessibleObject accessibleObject : accessibleObjects) {
      for (Class<? extends Annotation> annotationClass : annotationClasses) {
        if (accessibleObject.getAnnotation(annotationClass) != null) {
          accessors.add(createAccessor(accessibleObject));
          break;
        }
      }
    }

    if (comparator != null) {
      Collections.sort(accessors, comparator);
    }

    return accessors;
  }
Пример #4
0
 /**
  * Return true is @GeneratedValue is present in id
  *
  * @param clazz
  * @return
  */
 public static boolean hasAutoGeneratedId(Class clazz) {
   AccessibleObject accessibleObject = getIdAccessibleObject(clazz);
   if (accessibleObject != null && accessibleObject.isAnnotationPresent(GeneratedValue.class)) {
     return true;
   }
   return false;
 }
Пример #5
0
  /**
   * Vérifie qu'une interface est bien présente dans les interfaces d'un composant.
   *
   * @param name nom de l'interface dans le xml et l'annotation
   * @param intNames noms des classes annotées
   * @param comp composant censé contenir l'interface
   * @return
   * @throws ClassNotFoundException
   * @throws InstantiationException
   * @throws IllegalAccessException
   */
  private boolean isOneOf(String name, Set<String> intNames, Composant comp)
      throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    for (String intName : intNames) {
      Class intC = loader.loadClass(intName);
      if (AccessibleObject.class.isAssignableFrom(intC) && Member.class.isAssignableFrom(intC)) {
        AccessibleObject member = (AccessibleObject) intC.newInstance();

        // Faut check qu'il est bien de la bonne classe
        if (((Member) member).getDeclaringClass().equals(comp.getClass())) {
          // Faut check que l'annotation a bien pName comme value.
          RequiredInterface annotation = member.getAnnotation(RequiredInterface.class);
          if (annotation == null) {
            ProvidedInterface annotation1 = member.getAnnotation(ProvidedInterface.class);
            if (annotation1.value().equals(name)) {
              return true;
            }
          } else {
            if (annotation.value().equals(name)) {
              return true;
            }
          }
        }
      }
    }
    return false;
  }
Пример #6
0
  /**
   * Method called to check if we can use the passed method or constructor (wrt access restriction
   * -- public methods can be called, others usually not); and if not, if there is a work-around for
   * the problem.
   */
  public static void checkAndFixAccess(Member member) {
    // We know all members are also accessible objects...
    AccessibleObject ao = (AccessibleObject) member;

    /* 14-Jan-2009, tatu: It seems safe and potentially beneficial to
     *   always to make it accessible (latter because it will force
     *   skipping checks we have no use for...), so let's always call it.
     */
    // if (!ao.isAccessible()) {
    try {
      ao.setAccessible(true);
    } catch (SecurityException se) {
      /* 17-Apr-2009, tatu: Related to [JACKSON-101]: this can fail on
       *    platforms like EJB and Google App Engine); so let's
       *    only fail if we really needed it...
       */
      if (!ao.isAccessible()) {
        Class<?> declClass = member.getDeclaringClass();
        throw new IllegalArgumentException(
            "Can not access "
                + member
                + " (from class "
                + declClass.getName()
                + "; failed to set access: "
                + se.getMessage());
      }
    }
    // }
  }
Пример #7
0
 /**
  * Return true if @EmbeddedId is present in id
  *
  * @param clazz
  * @return
  */
 public static boolean hasEmbeddedId(Class clazz) {
   AccessibleObject accessibleObject = getIdAccessibleObject(clazz);
   if (accessibleObject != null && accessibleObject.isAnnotationPresent(EmbeddedId.class)) {
     return true;
   }
   return false;
 }
Пример #8
0
 /**
  * Suppress access check against a reflection object. SecurityException is silently ignored.
  * Checks first if the object is already accessible.
  */
 public static void forceAccess(AccessibleObject accObject) {
   if (accObject.isAccessible() == true) {
     return;
   }
   try {
     accObject.setAccessible(true);
   } catch (SecurityException sex) {
     // ignore
   }
 }
Пример #9
0
 /**
  * Changes the accessibility of a reflection object and returns the previous value. This method
  * can be used to set the accessibility of {@link Method} and {@link Field} instances.
  *
  * @param ao accessible object to set the accessibility on
  * @param accessible the accessibility statues to set on the object
  * @return the previous value of the accessibility flag
  */
 public static boolean exchangeAccessible(final AccessibleObject ao, final boolean accessible) {
   //
   // At least synchronize on the object so that users of this
   // particular method won't step on their toes.
   //
   synchronized (ao) {
     final boolean oldAccessible = ao.isAccessible();
     ao.setAccessible(accessible);
     return oldAccessible;
   }
 }
Пример #10
0
 /**
  * XXX Default access superclass workaround
  *
  * <p>When a public class has a default access superclass with public members, these members are
  * accessible. Calling them from compiled code works fine. Unfortunately, on some JVMs, using
  * reflection to invoke these members seems to (wrongly) prevent access even when the modifier is
  * public. Calling setAccessible(true) solves the problem but will only work from sufficiently
  * privileged code. Better workarounds would be gratefully accepted.
  *
  * @param o the AccessibleObject to set as accessible
  */
 static void setAccessibleWorkaround(AccessibleObject o) {
   if (o == null || o.isAccessible()) {
     return;
   }
   Member m = (Member) o;
   if (Modifier.isPublic(m.getModifiers())
       && isPackageAccess(m.getDeclaringClass().getModifiers())) {
     try {
       o.setAccessible(true);
     } catch (SecurityException e) { // NOPMD
       // ignore in favor of subsequent IllegalAccessException
     }
   }
 }
  private void visitJavaFileToPopulateCache(AccessibleObject methodOrConstructor) {

    InputStream is = null;
    try {
      is = javaFileFinder.openJavaFile(methodOrConstructor);
      if (is != null) {
        // visit .java file using our custom GenericVisitorAdapter
        CompilationUnit cu = JavaParser.parse(is);
        MethodParametersVisitor visitor = new MethodParametersVisitor();
        cu.accept(visitor, cache);
      }
    } catch (Exception e) {
      throw new ParameterNamesNotFoundException(
          "Error while trying to read parameter names from the Java file which contains the declaration of "
              + methodOrConstructor.toString(),
          e);
    } finally {
      if (is != null) {
        try {
          is.close();
        } catch (IOException e) {
          // should never happen
        }
      }
    }
  }
Пример #12
0
 private static void reflectionAppend(
     Object obj,
     Object obj1,
     Class class1,
     CompareToBuilder comparetobuilder,
     boolean flag,
     String as[]) {
   Field afield[] = class1.getDeclaredFields();
   AccessibleObject.setAccessible(afield, true);
   int i = 0;
   do {
     if (i >= afield.length || comparetobuilder.comparison != 0) {
       return;
     }
     Field field = afield[i];
     if (!ArrayUtils.contains(as, field.getName())
         && field.getName().indexOf('$') == -1
         && (flag || !Modifier.isTransient(field.getModifiers()))
         && !Modifier.isStatic(field.getModifiers())) {
       try {
         comparetobuilder.append(field.get(obj), field.get(obj1));
       } catch (IllegalAccessException illegalaccessexception) {
         throw new InternalError("Unexpected IllegalAccessException");
       }
     }
     i++;
   } while (true);
 }
Пример #13
0
  /**
   * Appends the fields and values defined by the given object of the given Class.
   *
   * @param lhs the left hand object
   * @param rhs the right hand object
   * @param clazz the class to append details of
   * @param builder the builder to append to
   * @param useTransients whether to test transient fields
   * @param excludeFields array of field names to exclude from testing
   */
  private static void reflectionAppend(
      Object lhs,
      Object rhs,
      Class<?> clazz,
      EqualsBuilder builder,
      boolean useTransients,
      String[] excludeFields) {

    if (isRegistered(lhs, rhs)) {
      return;
    }

    try {
      register(lhs, rhs);
      Field[] fields = clazz.getDeclaredFields();
      AccessibleObject.setAccessible(fields, true);
      for (int i = 0; i < fields.length && builder.isEquals; i++) {
        Field f = fields[i];
        if (!Arrays.contains(excludeFields, f.getName())
            && (f.getName().indexOf('$') == -1)
            && (useTransients || !Modifier.isTransient(f.getModifiers()))
            && (!Modifier.isStatic(f.getModifiers()))) {
          try {
            builder.append(f.get(lhs), f.get(rhs));
          } catch (IllegalAccessException e) {
            // this can't happen. Would get a Security exception instead
            // throw a runtime exception in case the impossible happens.
            throw new InternalError("Unexpected IllegalAccessException");
          }
        }
      }
    } finally {
      unregister(lhs, rhs);
    }
  }
Пример #14
0
 private Method[] getMemberMethods() {
   if (memberMethods == null) {
     Method[] mm = type.getDeclaredMethods();
     AccessibleObject.setAccessible(mm, true);
     memberMethods = mm;
   }
   return memberMethods;
 }
Пример #15
0
  public static void makeAccessible(final AccessibleObject object) {
    if (!object.isAccessible()) {
      if (System.getSecurityManager() == null) {
        object.setAccessible(true);
      } else {
        AccessController.doPrivileged(
            new PrivilegedAction<Object>() {

              @Override
              public Object run() {
                object.setAccessible(true);
                return null;
              }
            });
      }
    }
  }
Пример #16
0
 /**
  * XXX Default access superclass workaround.
  *
  * <p>When a {@code public} class has a default access superclass with {@code public} members,
  * these members are accessible. Calling them from compiled code works fine. Unfortunately, on
  * some JVMs, using reflection to invoke these members seems to (wrongly) prevent access even when
  * the modifier is {@code public}. Calling {@code setAccessible(true)} solves the problem but will
  * only work from sufficiently privileged code. Better workarounds would be gratefully accepted.
  *
  * @param o the AccessibleObject to set as accessible
  * @return a boolean indicating whether the accessibility of the object was set to true.
  */
 static boolean setAccessibleWorkaround(final AccessibleObject o) {
   if (o == null || o.isAccessible()) {
     return false;
   }
   final Member m = (Member) o;
   if (!o.isAccessible()
       && Modifier.isPublic(m.getModifiers())
       && isPackageAccess(m.getDeclaringClass().getModifiers())) {
     try {
       o.setAccessible(true);
       return true;
     } catch (final SecurityException e) { // NOPMD
       // ignore in favor of subsequent IllegalAccessException
     }
   }
   return false;
 }
 private Annotation findAutowiredAnnotation(AccessibleObject ao) {
   for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
     Annotation annotation = ao.getAnnotation(type);
     if (annotation != null) {
       return annotation;
     }
   }
   return null;
 }
Пример #18
0
  /**
   * This method uses reflection to build a valid hash code.
   *
   * <p>It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This
   * means that it will throw a security exception if run under a security manager, if the
   * permissions are not set up correctly. It is also not as efficient as testing explicitly.
   *
   * <p>Transient members will not be used, as they are likely derived fields, and not part of the
   * value of the <code>Object</code>.
   *
   * <p>Static fields will not be tested. Superclass fields will be included.
   *
   * @param obj the object to create a <code>hashCode</code> for
   * @return the generated hash code, or zero if the given object is <code>null</code>
   */
  public static int reflectionHashCode(Object obj) {
    if (obj == null) return 0;

    Class<?> targetClass = obj.getClass();
    if (isArrayOfPrimitives(obj)) {
      // || ObjectUtils.isPrimitiveOrWrapper(targetClass)) {
      return ObjectUtils.nullSafeHashCode(obj);
    }

    if (targetClass.isArray()) {
      return reflectionHashCode((Object[]) obj);
    }

    if (obj instanceof Collection) {
      return reflectionHashCode((Collection<?>) obj);
    }

    if (obj instanceof Map) {
      return reflectionHashCode((Map<?, ?>) obj);
    }

    // determine whether the object's class declares hashCode() or has a
    // superClass other than java.lang.Object that declares hashCode()
    Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
    Method hashCodeMethod = ReflectionUtils.findMethod(clazz, "hashCode", new Class[0]);

    if (hashCodeMethod != null) {
      return obj.hashCode();
    }

    // could not find a hashCode other than the one declared by
    // java.lang.Object
    int hash = INITIAL_HASH;

    try {
      while (targetClass != null) {
        Field[] fields = targetClass.getDeclaredFields();
        AccessibleObject.setAccessible(fields, true);

        for (int i = 0; i < fields.length; i++) {
          Field field = fields[i];
          int modifiers = field.getModifiers();

          if (!Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)) {
            hash = MULTIPLIER * hash + reflectionHashCode(field.get(obj));
          }
        }
        targetClass = targetClass.getSuperclass();
      }
    } catch (IllegalAccessException exception) {
      // ///CLOVER:OFF
      ReflectionUtils.handleReflectionException(exception);
      // ///CLOVER:ON
    }

    return hash;
  }
Пример #19
0
 /* Check that you aren't exposing java.lang.Class.<init>. */
 private static void setAccessible0(AccessibleObject obj, boolean flag) throws SecurityException {
   if (obj instanceof Constructor && flag == true) {
     Constructor<?> c = (Constructor<?>) obj;
     if (c.getDeclaringClass() == Class.class) {
       throw new SecurityException("Can not make a java.lang.Class" + " constructor accessible");
     }
   }
   obj.override = flag;
 }
Пример #20
0
  public String toString(Object object) {
    if (object == null) {
      return "null";
    }
    if (visited.contains(object)) {
      return "...";
    }
    visited.add(object);
    Class clazz = object.getClass();
    if (clazz == String.class) {
      return (String) object;
    }
    if (clazz.isArray()) {
      String r = clazz.getComponentType() + "[]{";
      for (int i = 0; i < Array.getLength(object); i++) {
        if (i > 0) {
          r += ",";
        }
        Object val = Array.get(object, i);
        if (clazz.getComponentType().isPrimitive()) {
          r += val;
        } else {
          r += toString(val);
        }
      }
      return r + "}";
    }

    String r = clazz.getName();
    do {
      r += "[";
      Field[] fields = clazz.getDeclaredFields();
      AccessibleObject.setAccessible(fields, true);
      for (Field field : fields) {
        if (!Modifier.isStatic(field.getModifiers())) {
          if (!r.endsWith("[")) {
            r += ",";
          }
          r += field.getName() + "=";
          try {
            Class t = field.getType();
            Object val = field.get(object);
            if (t.isPrimitive()) {
              r += val;
            } else {
              r += toString(val);
            }
          } catch (IllegalAccessException e) {
            e.printStackTrace();
          }
        }
      }
      r += "]";
      clazz = clazz.getSuperclass();
    } while (clazz != null);
    return r;
  }
Пример #21
0
  private void initialize() {
    this.type = GenericAssociationInfo.associationTypeOf(accessor);
    this.qualifiedName = QualifiedName.fromAccessor(accessor);
    this.immutable = metaInfo.get(Immutable.class) != null;
    this.aggregated = metaInfo.get(Aggregated.class) != null;

    final Queryable queryable = accessor.getAnnotation(Queryable.class);
    this.queryable = queryable == null || queryable.value();
  }
Пример #22
0
  private void introspect() {
    introspectTypes();

    ElementCollection elementCollectionAnn = _field.getAnnotation(ElementCollection.class);

    if (elementCollectionAnn != null) introspectElementCollection(elementCollectionAnn);

    CollectionTable collectionTableAnn = _field.getAnnotation(CollectionTable.class);

    if (collectionTableAnn != null)
      _collectionTable = new CollectionTableConfig(collectionTableAnn);
    else {
      _collectionTable = new CollectionTableConfig(getRelatedType().getName(), _fieldName);
    }

    /*
    OrderBy orderByAnn = _field.getAnnotation(OrderBy.class);

    if (orderByAnn != null)
      _orderBy = orderByAnn.value();
    */
  }
Пример #23
0
  /**
   * Return information about the scripting variables to be created.
   *
   * @param data the input data
   * @return VariableInfo array of variable information
   */
  @SuppressWarnings("unchecked")
  public VariableInfo[] getVariableInfo(TagData data) {
    // loop through and expose all attributes
    List<VariableInfo> vars = new ArrayList<VariableInfo>();

    try {
      String clazz = data.getAttributeString("className");

      if (clazz == null) {
        clazz = Constants.class.getName();
      }

      Class c = Class.forName(clazz);

      // if no var specified, get all
      if (data.getAttributeString("var") == null) {
        Field[] fields = c.getDeclaredFields();

        AccessibleObject.setAccessible(fields, true);

        for (Field field : fields) {
          String type = field.getType().getName();
          vars.add(
              new VariableInfo(
                  field.getName(),
                  ((field.getType().isArray())
                      ? type.substring(2, type.length() - 1) + "[]"
                      : type),
                  true,
                  VariableInfo.AT_END));
        }
      } else {
        String var = data.getAttributeString("var");
        String type = c.getField(var).getType().getName();
        vars.add(
            new VariableInfo(
                c.getField(var).getName(),
                ((c.getField(var).getType().isArray())
                    ? type.substring(2, type.length() - 1) + "[]"
                    : type),
                true,
                VariableInfo.AT_END));
      }
    } catch (Exception cnf) {
      log.error(cnf.getMessage());
      cnf.printStackTrace();
    }

    return vars.toArray(new VariableInfo[] {});
  }
  /**
   * Returns the {@link Annotation} object if an annotation for the specified type is present on the
   * injection target, otherwise null.
   *
   * <p>If the {@link AccessibleObject} of the injection target is of type {@link Method} or {@link
   * Constructor}, then the {@link Annotation} may be specified on the {@link AccessibleObject} or
   * on the corresponding parameter.
   *
   * @param annotationClass - the Class object corresponding to the annotation type
   * @return annotation for the specified annotation type if present on this element, otherwise null
   * @throws NullPointerException - if the given annotation class is null
   */
  @SuppressWarnings("unchecked")
  public <T> T getAnnotation(final Class<? extends Annotation> annotationClass) {
    final Annotation annotation = accessibleObject.getAnnotation(annotationClass);
    if (annotation != null) {
      return (T) annotation;
    }

    for (final Annotation parameterAnnotation : parameterAnnotations) {
      if (parameterAnnotation.annotationType() == annotationClass) {
        return (T) parameterAnnotation;
      }
    }

    return null;
  }
  /**
   * Compares the declared primitives of two instances of a class
   *
   * @param <T> type of the instances
   * @param cls type to compare the declared fields for
   * @param instance1 first instance to test
   * @param instance2 second instance to test
   * @return a list of differing primitives
   * @throws IllegalAccessException
   * @throws IllegalArgumentException
   */
  public static <T> ArrayList<Field> compareDeclaredPrimitives(
      Class<? extends T> cls, T instance1, T instance2)
      throws IllegalArgumentException, IllegalAccessException {
    ArrayList<Field> differingFields = new ArrayList<Field>();
    Field[] fields = cls.getDeclaredFields();
    AccessibleObject.setAccessible(fields, true);

    for (Field field : fields) {
      if (field.getType().isPrimitive()
          && !isPrimitiveFieldContentTheSame(instance1, instance2, field)) {
        differingFields.add(field);
      }
    }

    return differingFields;
  }
  /**
   * Returns an array of all annotations present on the injection target.
   *
   * <p>If the {@link AccessibleObject} of the injection target is of type {@link Method} or {@link
   * Constructor}, then the {@link Annotation} of the {@link AccessibleObject} and the corresponding
   * parameter are returned.
   *
   * @return Array of all annotations present on the injection target
   */
  public Annotation[] getAnnotations() {
    final Annotation[] accessibleObjectAnnotations = accessibleObject.getAnnotations();
    final Annotation[] annotations =
        new Annotation[accessibleObjectAnnotations.length + parameterAnnotations.length];

    System.arraycopy(
        accessibleObjectAnnotations, 0, annotations, 0, accessibleObjectAnnotations.length);
    System.arraycopy(
        parameterAnnotations,
        0,
        annotations,
        accessibleObjectAnnotations.length,
        parameterAnnotations.length);

    return annotations;
  }
Пример #27
0
  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }

    AssociationModel that = (AssociationModel) o;

    if (!accessor.equals(that.accessor)) {
      return false;
    }

    return true;
  }
Пример #28
0
 private static <T extends Annotation> AnnotationMetadata<T> randomAnnotation(
     Class<T> annotationClass, Map<String, Object> properties) {
   Map<String, Object> allProps = new LinkedHashMap<String, Object>();
   Map<String, Object> defaults =
       hasAnnotationType ? getAnnotationDefaults(annotationClass) : new HashMap<String, Object>();
   Method[] mm = annotationClass.getDeclaredMethods();
   AccessibleObject.setAccessible(mm, true);
   for (Method method : mm) {
     String name = method.getName();
     if (properties.containsKey(name)) allProps.put(name, properties.get(name));
     else {
       Object o = defaults.get(name);
       if (o == null) o = getTypeDefaults(method.getReturnType());
       allProps.put(name, o);
     }
   }
   return new AnnotationMetadata<T>(annotationClass, allProps);
 }
Пример #29
0
  /**
   * Main method that does processing and exposes Constants in specified scope
   *
   * @return int
   * @throws JspException if processing fails
   */
  @Override
  public int doStartTag() throws JspException {
    // Using reflection, get the available field names in the class
    Class c = null;
    int toScope = PageContext.PAGE_SCOPE;

    if (scope != null) {
      toScope = getScope(scope);
    }

    try {
      c = Class.forName(clazz);
    } catch (ClassNotFoundException cnf) {
      log.error("ClassNotFound - maybe a typo?");
      throw new JspException(cnf.getMessage());
    }

    try {
      // if var is null, expose all variables
      if (var == null) {
        Field[] fields = c.getDeclaredFields();

        AccessibleObject.setAccessible(fields, true);

        for (Field field : fields) {
          pageContext.setAttribute(field.getName(), field.get(this), toScope);
        }
      } else {
        try {
          Object value = c.getField(var).get(this);
          pageContext.setAttribute(c.getField(var).getName(), value, toScope);
        } catch (NoSuchFieldException nsf) {
          log.error(nsf.getMessage());
          throw new JspException(nsf);
        }
      }
    } catch (IllegalAccessException iae) {
      log.error("Illegal Access Exception - maybe a classloader issue?");
      throw new JspException(iae);
    }

    // Continue processing this page
    return (SKIP_BODY);
  }
  /**
   * Construct a variable
   *
   * @param aType the type
   * @param aName the name
   * @param aValue the value
   */
  public Variable(Class<?> aType, String aName, Object aValue) {
    type = aType;
    name = aName;
    value = aValue;
    fields = new ArrayList<Field>();

    // find all fields if we have a class type except we don't expand strings and null values

    if (!type.isPrimitive() && !type.isArray() && !type.equals(String.class) && value != null) {
      // get fields from the class and all superclasses
      for (Class<?> c = value.getClass(); c != null; c = c.getSuperclass()) {
        Field[] fs = c.getDeclaredFields();
        AccessibleObject.setAccessible(fs, true);

        // get all nonstatic fields
        for (Field f : fs) if ((f.getModifiers() & Modifier.STATIC) == 0) fields.add(f);
      }
    }
  }