All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jakarta.el.StaticFieldELResolver Maven / Gradle / Ivy

/*
 * Copyright (c) 2012, 2022 Oracle and/or its affiliates and others.
 * All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package jakarta.el;

import static java.lang.reflect.Modifier.isPublic;
import static java.lang.reflect.Modifier.isStatic;
import static jakarta.el.ELUtil.getExceptionMessageString;

import java.beans.FeatureDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Iterator;

/**
 * An {@link ELResolver} for resolving static fields, enum constants and static methods. Also handles constructor calls
 * as a special case.
 * 
 * 

* The resolver handles base objects of the type {@link ELClass}, which is usually generated by a Jakarta Expression * Language implementation. * * @see ELClass * @since Jakarta Expression Language 3.0 */ public class StaticFieldELResolver extends ELResolver { /** *

* Returns the value of a static field. *

*

* If the base object is an instance of ELClass and the property is String, the * propertyResolved property of the ELContext object must be set to true by this * resolver, before returning. If this property is not true after this method is called, the caller should * ignore the return value. *

* * If the property is a public static field of class specified in ELClass, return the value of the static * field. An Enum constant is a public static field of an Enum object, and is a special case of this. * * @param context The context of this evaluation. * @param base An ELClass. * @param property A static field name. * * @return If the propertyResolved property of ELContext was set to true, then * the static field value. * * @throws NullPointerException if context is null. * @throws PropertyNotFoundException if the specified class does not exist, or if the field is not a public static filed * of the class, or if the field is inaccessible. */ @Override public Object getValue(ELContext context, Object base, Object property) { if (context == null) { throw new NullPointerException(); } if (base instanceof ELClass && property instanceof String) { Class klass = ((ELClass) base).getKlass(); String fieldName = (String) property; try { context.setPropertyResolved(base, property); Field field = klass.getField(fieldName); int mod = field.getModifiers(); if (isPublic(mod) && isStatic(mod)) { return field.get(null); } } catch (NoSuchFieldException ex) { } catch (IllegalAccessException ex) { } throw new PropertyNotFoundException(getExceptionMessageString(context, "staticFieldReadError", new Object[] { klass.getName(), fieldName })); } return null; } /** *

* Attempts to write to a static field. *

*

* If the base object is an instance of ELClassand the property is String, a * PropertyNotWritableException will always be thrown, because writing to a static field is not allowed. * * @param context The context of this evaluation. * @param base An ELClass * @param property The name of the field * @param value The value to set the field of the class to. * @throws NullPointerException if context is null * @throws PropertyNotWritableException if base object instance of ELClassand property * instance of String */ @Override public void setValue(ELContext context, Object base, Object property, Object value) { if (context == null) { throw new NullPointerException(); } if (base instanceof ELClass && property instanceof String) { Class klass = ((ELClass) base).getKlass(); String fieldName = (String) property; throw new PropertyNotWritableException( getExceptionMessageString(context, "staticFieldWriteError", new Object[] { klass.getName(), fieldName })); } } /** * Invokes a public static method or the constructor for a class. * *

* If the base object is an instance of ELClass and the method is a String, the * propertyResolved property of the ELContext object must be set to true by the * resolver, before returning. If this property is not true after this method is called, the caller should * ignore the return value. * *

* Invoke the public static method specified by method. * *

* The process involved in the method selection is the same as that used in {@link BeanELResolver}. * *

* As a special case, if the name of the method is "<init>", the constructor for the class will be invoked. * * @param base An ELClass * @param methodName When coerced to a String, the simple name of the method. * @param paramTypes An array of Class objects identifying the method's formal parameter types, in declared order. Use * an empty array if the method has no parameters. Can be null, in which case the method's formal parameter * types are assumed to be unknown. * @param params The parameters to pass to the method, or null if no parameters. * @return The result of the method invocation (null if the method has a void return type). * @throws MethodNotFoundException if no suitable method can be found. * @throws ELException if an exception was thrown while performing (base, method) resolution. The thrown exception must * be included as the cause property of this exception, if available. If the exception thrown is an * InvocationTargetException, extract its cause and pass it to the ELException * constructor. */ @Override public Object invoke(ELContext context, Object base, Object methodName, Class[] paramTypes, Object[] params) { if (context == null) { throw new NullPointerException(); } if (!(base instanceof ELClass && methodName instanceof String)) { return null; } Class klass = ((ELClass) base).getKlass(); String name = (String) methodName; Object ret; if ("".equals(name)) { Constructor constructor = ELUtil.findConstructor(klass, paramTypes, params); ret = ELUtil.invokeConstructor(context, constructor, params); } else { Method method = ELUtil.findMethod(klass, base, name, paramTypes, params, true); ret = ELUtil.invokeMethod(context, method, null, params); } context.setPropertyResolved(base, methodName); return ret; } /** * Returns the type of a static field. * *

* If the base object is an instance of ELClassand the property is a String, the * propertyResolved property of the ELContext object must be set to true by the * resolver, before returning. If this property is not true after this method is called, the caller can * safely assume no value has been set. * * @param context The context of this evaluation. * @param base An ELClass. * @param property The name of the field. * @return If the propertyResolved property of ELContext was set to true, then * null; otherwise undefined. * @throws NullPointerException if context is null. * @throws PropertyNotFoundException if field is not a public static filed of the class, or if the field is * inaccessible. */ @Override public Class getType(ELContext context, Object base, Object property) { if (context == null) { throw new NullPointerException(); } if (base instanceof ELClass && property instanceof String) { Class klass = ((ELClass) base).getKlass(); String fieldName = (String) property; try { context.setPropertyResolved(true); Field field = klass.getField(fieldName); int mod = field.getModifiers(); if (isPublic(mod) && isStatic(mod)) { // Resolver is read-only so need to return null if field is // resolved. return null; } } catch (NoSuchFieldException ex) { } throw new PropertyNotFoundException(getExceptionMessageString(context, "staticFieldReadError", new Object[] { klass.getName(), fieldName })); } return null; } /** *

* Inquires whether the static field is writable. *

*

* If the base object is an instance of ELClassand the property is a String, the * propertyResolved property of the ELContext object must be set to true by the * resolver, before returning. If this property is not true after this method is called, the caller can * safely assume no value has been set. *

* *

* Always returns a true because writing to a static field is not allowed. *

* * @param context The context of this evaluation. * @param base An ELClass. * @param property The name of the bean. * @return true * @throws NullPointerException if context is null. */ @Override public boolean isReadOnly(ELContext context, Object base, Object property) { if (context == null) { throw new NullPointerException(); } if (base instanceof ELClass && property instanceof String) { ((ELClass) base).getKlass(); context.setPropertyResolved(true); } return true; } /** * Returns the properties that can be resolved. Always returns null, since there is no reason to iterate * through a list of one element: field name. * * @param context The context of this evaluation. * @param base An ELClass. * @return null. * * @deprecated This method will be removed without replacement in EL 6.0 */ @Deprecated(forRemoval = true, since = "5.0") @Override public Iterator getFeatureDescriptors(ELContext context, Object base) { return null; } /** * Returns the type of the property. Always returns String.class, since a field name is a String. * * @param context The context of this evaluation. * @param base An ELClass. * @return String.class. */ @Override public Class getCommonPropertyType(ELContext context, Object base) { return String.class; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy