This commit is contained in:
2024-11-30 19:03:49 +08:00
commit 1e6763c160
3806 changed files with 737676 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javax.servlet.jsp.el;
/**
* Represents any of the exception conditions that arise during the operation
* evaluation of the evaluator.
*
* @since 2.0
* @deprecated As of JSP 2.1, replaced by javax.el.ELException
*/
@SuppressWarnings("dep-ann") // TCK signature test fails with annotation
public class ELException extends Exception {
private static final long serialVersionUID = 1L;
/**
* Creates an ELException with no detail message.
**/
public ELException() {
super();
}
/**
* Creates an ELException with the provided detail message.
*
* @param pMessage
* the detail message
**/
public ELException(String pMessage) {
super(pMessage);
}
/**
* Creates an ELException with the given root cause.
*
* @param pRootCause
* the originating cause of this exception
**/
public ELException(Throwable pRootCause) {
super(pRootCause);
}
// -------------------------------------
/**
* Creates an ELException with the given detail message and root cause.
*
* @param pMessage
* the detail message
* @param pRootCause
* the originating cause of this exception
**/
public ELException(String pMessage, Throwable pRootCause) {
super(pMessage, pRootCause);
}
// -------------------------------------
/**
* Returns the root cause.
*
* @return the root cause of this exception
*/
public Throwable getRootCause() {
return getCause();
}
}

View File

@@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javax.servlet.jsp.el;
/**
* Represents a parsing error encountered while parsing an EL expression.
*
* @since 2.0
* @deprecated As of JSP 2.1, replaced by javax.el.ELException
*/
@SuppressWarnings("dep-ann") // TCK signature test fails with annotation
public class ELParseException extends ELException {
private static final long serialVersionUID = 1L;
//-------------------------------------
/**
* Creates an ELParseException with no detail message.
*/
public ELParseException ()
{
super ();
}
//-------------------------------------
/**
* Creates an ELParseException with the provided detail message.
*
* @param pMessage the detail message
**/
public ELParseException (String pMessage)
{
super (pMessage);
}
//-------------------------------------
}

View File

@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javax.servlet.jsp.el;
/**
* <p>The abstract class for a prepared expression.</p>
*
* <p>An instance of an Expression can be obtained via from an
* ExpressionEvaluator instance.</p>
*
* <p>An Expression may or not have done a syntactic parse of the expression.
* A client invoking the evaluate() method should be ready for the case
* where ELParseException exceptions are raised. </p>
*
* @since 2.0
* @deprecated As of JSP 2.1, replaced by javax.el.ValueExpression
*/
@SuppressWarnings("dep-ann") // TCK signature test fails with annotation
public abstract class Expression {
/**
* Evaluates an expression that was previously prepared. In some
* implementations preparing an expression involves full syntactic
* validation, but others may not do so. Evaluating the expression may
* raise an ELParseException as well as other ELExceptions due to
* run-time evaluation.
*
* @param vResolver A VariableResolver instance that can be used at
* runtime to resolve the name of implicit objects into Objects.
* @return The result of the expression evaluation.
*
* @exception ELException Thrown if the expression evaluation failed.
*/
public abstract Object evaluate( VariableResolver vResolver )
throws ELException;
}

View File

@@ -0,0 +1,115 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javax.servlet.jsp.el;
/**
* <p>
* The abstract base class for an expression-language evaluator. Classes that
* implement an expression language expose their functionality via this abstract
* class.
* </p>
* <p>
* An instance of the ExpressionEvaluator can be obtained via the JspContext /
* PageContext
* </p>
* <p>
* The parseExpression() and evaluate() methods must be thread-safe. That is,
* multiple threads may call these methods on the same ExpressionEvaluator
* object simultaneously. Implementations should synchronize access if they
* depend on transient state. Implementations should not, however, assume that
* only one object of each ExpressionEvaluator type will be instantiated; global
* caching should therefore be static.
* </p>
* <p>
* Only a single EL expression, starting with '${' and ending with '}', can be
* parsed or evaluated at a time. EL expressions cannot be mixed with static
* text. For example, attempting to parse or evaluate "
* <code>abc${1+1}def${1+1}ghi</code>" or even "<code>${1+1}${1+1}</code>" will
* cause an <code>ELException</code> to be thrown.
* </p>
* <p>
* The following are examples of syntactically legal EL expressions:
* </p>
* <ul>
* <li><code>${person.lastName}</code></li>
* <li><code>${8 * 8}</code></li>
* <li><code>${my:reverse('hello')}</code></li>
* </ul>
*
* @since 2.0
* @deprecated As of JSP 2.1, replaced by javax.el.ExpressionFactory
*/
@SuppressWarnings("dep-ann")
// TCK signature test fails with annotation
public abstract class ExpressionEvaluator {
/**
* Prepare an expression for later evaluation. This method should perform
* syntactic validation of the expression; if in doing so it detects errors,
* it should raise an ELParseException.
*
* @param expression
* The expression to be evaluated.
* @param expectedType
* The expected type of the result of the evaluation
* @param fMapper
* A FunctionMapper to resolve functions found in the expression.
* It can be null, in which case no functions are supported for
* this invocation. The ExpressionEvaluator must not hold on to
* the FunctionMapper reference after returning from
* <code>parseExpression()</code>. The <code>Expression</code>
* object returned must invoke the same functions regardless of
* whether the mappings in the provided
* <code>FunctionMapper</code> instance change between calling
* <code>ExpressionEvaluator.parseExpression()</code> and
* <code>Expression.evaluate()</code>.
* @return The Expression object encapsulating the arguments.
* @exception ELException
* Thrown if parsing errors were found.
*/
public abstract Expression parseExpression(String expression,
@SuppressWarnings("rawtypes")// TCK signature fails with generics
Class expectedType, FunctionMapper fMapper) throws ELException;
/**
* Evaluates an expression. This method may perform some syntactic
* validation and, if so, it should raise an ELParseException error if it
* encounters syntactic errors. EL evaluation errors should cause an
* ELException to be raised.
*
* @param expression
* The expression to be evaluated.
* @param expectedType
* The expected type of the result of the evaluation
* @param vResolver
* A VariableResolver instance that can be used at runtime to
* resolve the name of implicit objects into Objects.
* @param fMapper
* A FunctionMapper to resolve functions found in the expression.
* It can be null, in which case no functions are supported for
* this invocation.
* @return The result of the expression evaluation.
* @exception ELException
* Thrown if the expression evaluation failed.
*/
public abstract Object evaluate(
String expression,
@SuppressWarnings("rawtypes")// TCK signature fails with generics
Class expectedType, VariableResolver vResolver,
FunctionMapper fMapper) throws ELException;
}

View File

@@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javax.servlet.jsp.el;
/**
* <p>The interface to a map between EL function names and methods.</p>
*
* <p>Classes implementing this interface may, for instance, consult tag library
* information to resolve the map. </p>
*
* @since 2.0
* @deprecated As of JSP 2.1, replaced by javax.el.FunctionMapper
*/
@SuppressWarnings("dep-ann") // TCK signature test fails with annotation
public interface FunctionMapper {
/**
* Resolves the specified local name and prefix into a Java.lang.Method.
* Returns null if the prefix and local name are not found.
*
* @param prefix the prefix of the function, or "" if no prefix.
* @param localName the short name of the function
* @return the result of the method mapping. Null means no entry found.
**/
public java.lang.reflect.Method resolveFunction(String prefix,
String localName);
}

View File

@@ -0,0 +1,609 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javax.servlet.jsp.el;
import java.beans.FeatureDescriptor;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.Vector;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.PropertyNotWritableException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.PageContext;
/**
*
* @since 2.1
*/
public class ImplicitObjectELResolver extends ELResolver {
private static final String[] SCOPE_NAMES = new String[] {
"applicationScope", "cookie", "header", "headerValues",
"initParam", "pageContext", "pageScope", "param", "paramValues",
"requestScope", "sessionScope" };
private static final int APPLICATIONSCOPE = 0;
private static final int COOKIE = 1;
private static final int HEADER = 2;
private static final int HEADERVALUES = 3;
private static final int INITPARAM = 4;
private static final int PAGECONTEXT = 5;
private static final int PAGESCOPE = 6;
private static final int PARAM = 7;
private static final int PARAM_VALUES = 8;
private static final int REQUEST_SCOPE = 9;
private static final int SESSION_SCOPE = 10;
public ImplicitObjectELResolver() {
super();
}
@Override
public Object getValue(ELContext context, Object base, Object property) {
Objects.requireNonNull(context);
if (base == null && property != null) {
int idx = Arrays.binarySearch(SCOPE_NAMES, property.toString());
if (idx >= 0) {
PageContext page = (PageContext) context
.getContext(JspContext.class);
context.setPropertyResolved(base, property);
switch (idx) {
case APPLICATIONSCOPE:
return ScopeManager.get(page).getApplicationScope();
case COOKIE:
return ScopeManager.get(page).getCookie();
case HEADER:
return ScopeManager.get(page).getHeader();
case HEADERVALUES:
return ScopeManager.get(page).getHeaderValues();
case INITPARAM:
return ScopeManager.get(page).getInitParam();
case PAGECONTEXT:
return ScopeManager.get(page).getPageContext();
case PAGESCOPE:
return ScopeManager.get(page).getPageScope();
case PARAM:
return ScopeManager.get(page).getParam();
case PARAM_VALUES:
return ScopeManager.get(page).getParamValues();
case REQUEST_SCOPE:
return ScopeManager.get(page).getRequestScope();
case SESSION_SCOPE:
return ScopeManager.get(page).getSessionScope();
}
}
}
return null;
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" }) // TCK signature test fails with generics
public Class getType(ELContext context, Object base, Object property) {
Objects.requireNonNull(context);
if (base == null && property != null) {
int idx = Arrays.binarySearch(SCOPE_NAMES, property.toString());
if (idx >= 0) {
context.setPropertyResolved(base, property);
}
}
return null;
}
@Override
public void setValue(ELContext context, Object base, Object property,
Object value) {
Objects.requireNonNull(context);
if (base == null && property != null) {
int idx = Arrays.binarySearch(SCOPE_NAMES, property.toString());
if (idx >= 0) {
context.setPropertyResolved(base, property);
throw new PropertyNotWritableException();
}
}
}
@Override
public boolean isReadOnly(ELContext context, Object base, Object property) {
Objects.requireNonNull(context);
if (base == null && property != null) {
int idx = Arrays.binarySearch(SCOPE_NAMES, property.toString());
if (idx >= 0) {
context.setPropertyResolved(base, property);
return true;
}
}
return false;
}
@Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
List<FeatureDescriptor> feats = new ArrayList<>(SCOPE_NAMES.length);
FeatureDescriptor feat;
for (int i = 0; i < SCOPE_NAMES.length; i++) {
feat = new FeatureDescriptor();
feat.setDisplayName(SCOPE_NAMES[i]);
feat.setExpert(false);
feat.setHidden(false);
feat.setName(SCOPE_NAMES[i]);
feat.setPreferred(true);
feat.setValue(RESOLVABLE_AT_DESIGN_TIME, Boolean.TRUE);
feat.setValue(TYPE, String.class);
feats.add(feat);
}
return feats.iterator();
}
@Override
public Class<String> getCommonPropertyType(ELContext context, Object base) {
if (base == null) {
return String.class;
}
return null;
}
private static class ScopeManager {
private static final String MNGR_KEY = ScopeManager.class.getName();
private final PageContext page;
private Map<String,Object> applicationScope;
private Map<String,Cookie> cookie;
private Map<String,String> header;
private Map<String,String[]> headerValues;
private Map<String,String> initParam;
private Map<String,Object> pageScope;
private Map<String,String> param;
private Map<String,String[]> paramValues;
private Map<String,Object> requestScope;
private Map<String,Object> sessionScope;
public ScopeManager(PageContext page) {
this.page = page;
}
public static ScopeManager get(PageContext page) {
ScopeManager mngr = (ScopeManager) page.getAttribute(MNGR_KEY);
if (mngr == null) {
mngr = new ScopeManager(page);
page.setAttribute(MNGR_KEY, mngr);
}
return mngr;
}
public Map<String,Object> getApplicationScope() {
if (this.applicationScope == null) {
this.applicationScope = new ScopeMap<Object>() {
@Override
protected void setAttribute(String name, Object value) {
page.getServletContext().setAttribute(name, value);
}
@Override
protected void removeAttribute(String name) {
page.getServletContext().removeAttribute(name);
}
@Override
protected Enumeration<String> getAttributeNames() {
return page.getServletContext().getAttributeNames();
}
@Override
protected Object getAttribute(String name) {
return page.getServletContext().getAttribute(name);
}
};
}
return this.applicationScope;
}
public Map<String,Cookie> getCookie() {
if (this.cookie == null) {
this.cookie = new ScopeMap<Cookie>() {
@Override
protected Enumeration<String> getAttributeNames() {
Cookie[] c = ((HttpServletRequest) page.getRequest())
.getCookies();
if (c != null) {
Vector<String> v = new Vector<>();
for (int i = 0; i < c.length; i++) {
v.add(c[i].getName());
}
return v.elements();
}
return null;
}
@Override
protected Cookie getAttribute(String name) {
Cookie[] c = ((HttpServletRequest) page.getRequest())
.getCookies();
if (c != null) {
for (int i = 0; i < c.length; i++) {
if (name.equals(c[i].getName())) {
return c[i];
}
}
}
return null;
}
};
}
return this.cookie;
}
public Map<String,String> getHeader() {
if (this.header == null) {
this.header = new ScopeMap<String>() {
@Override
protected Enumeration<String> getAttributeNames() {
return ((HttpServletRequest) page.getRequest())
.getHeaderNames();
}
@Override
protected String getAttribute(String name) {
return ((HttpServletRequest) page.getRequest())
.getHeader(name);
}
};
}
return this.header;
}
public Map<String,String[]> getHeaderValues() {
if (this.headerValues == null) {
this.headerValues = new ScopeMap<String[]>() {
@Override
protected Enumeration<String> getAttributeNames() {
return ((HttpServletRequest) page.getRequest())
.getHeaderNames();
}
@Override
protected String[] getAttribute(String name) {
Enumeration<String> e =
((HttpServletRequest) page.getRequest())
.getHeaders(name);
if (e != null) {
List<String> list = new ArrayList<>();
while (e.hasMoreElements()) {
list.add(e.nextElement());
}
return list.toArray(new String[list.size()]);
}
return null;
}
};
}
return this.headerValues;
}
public Map<String,String> getInitParam() {
if (this.initParam == null) {
this.initParam = new ScopeMap<String>() {
@Override
protected Enumeration<String> getAttributeNames() {
return page.getServletContext().getInitParameterNames();
}
@Override
protected String getAttribute(String name) {
return page.getServletContext().getInitParameter(name);
}
};
}
return this.initParam;
}
public PageContext getPageContext() {
return this.page;
}
public Map<String,Object> getPageScope() {
if (this.pageScope == null) {
this.pageScope = new ScopeMap<Object>() {
@Override
protected void setAttribute(String name, Object value) {
page.setAttribute(name, value);
}
@Override
protected void removeAttribute(String name) {
page.removeAttribute(name);
}
@Override
protected Enumeration<String> getAttributeNames() {
return page.getAttributeNamesInScope(
PageContext.PAGE_SCOPE);
}
@Override
protected Object getAttribute(String name) {
return page.getAttribute(name);
}
};
}
return this.pageScope;
}
public Map<String,String> getParam() {
if (this.param == null) {
this.param = new ScopeMap<String>() {
@Override
protected Enumeration<String> getAttributeNames() {
return page.getRequest().getParameterNames();
}
@Override
protected String getAttribute(String name) {
return page.getRequest().getParameter(name);
}
};
}
return this.param;
}
public Map<String,String[]> getParamValues() {
if (this.paramValues == null) {
this.paramValues = new ScopeMap<String[]>() {
@Override
protected String[] getAttribute(String name) {
return page.getRequest().getParameterValues(name);
}
@Override
protected Enumeration<String> getAttributeNames() {
return page.getRequest().getParameterNames();
}
};
}
return this.paramValues;
}
public Map<String,Object> getRequestScope() {
if (this.requestScope == null) {
this.requestScope = new ScopeMap<Object>() {
@Override
protected void setAttribute(String name, Object value) {
page.getRequest().setAttribute(name, value);
}
@Override
protected void removeAttribute(String name) {
page.getRequest().removeAttribute(name);
}
@Override
protected Enumeration<String> getAttributeNames() {
return page.getRequest().getAttributeNames();
}
@Override
protected Object getAttribute(String name) {
return page.getRequest().getAttribute(name);
}
};
}
return this.requestScope;
}
public Map<String,Object> getSessionScope() {
if (this.sessionScope == null) {
this.sessionScope = new ScopeMap<Object>() {
@Override
protected void setAttribute(String name, Object value) {
((HttpServletRequest) page.getRequest()).getSession()
.setAttribute(name, value);
}
@Override
protected void removeAttribute(String name) {
HttpSession session = page.getSession();
if (session != null) {
session.removeAttribute(name);
}
}
@Override
protected Enumeration<String> getAttributeNames() {
HttpSession session = page.getSession();
if (session != null) {
return session.getAttributeNames();
}
return null;
}
@Override
protected Object getAttribute(String name) {
HttpSession session = page.getSession();
if (session != null) {
return session.getAttribute(name);
}
return null;
}
};
}
return this.sessionScope;
}
}
private abstract static class ScopeMap<V> extends AbstractMap<String,V> {
protected abstract Enumeration<String> getAttributeNames();
protected abstract V getAttribute(String name);
@SuppressWarnings("unused")
protected void removeAttribute(String name) {
throw new UnsupportedOperationException();
}
@SuppressWarnings("unused")
protected void setAttribute(String name, Object value) {
throw new UnsupportedOperationException();
}
@Override
public final Set<Map.Entry<String,V>> entrySet() {
Enumeration<String> e = getAttributeNames();
Set<Map.Entry<String, V>> set = new HashSet<>();
if (e != null) {
while (e.hasMoreElements()) {
set.add(new ScopeEntry(e.nextElement()));
}
}
return set;
}
@Override
public final int size() {
int size = 0;
Enumeration<String> e = getAttributeNames();
if (e != null) {
while (e.hasMoreElements()) {
e.nextElement();
size++;
}
}
return size;
}
@Override
public final boolean containsKey(Object key) {
if (key == null) {
return false;
}
Enumeration<String> e = getAttributeNames();
if (e != null) {
while (e.hasMoreElements()) {
if (key.equals(e.nextElement())) {
return true;
}
}
}
return false;
}
private class ScopeEntry implements Map.Entry<String,V> {
private final String key;
public ScopeEntry(String key) {
this.key = key;
}
@Override
public String getKey() {
return this.key;
}
@Override
public V getValue() {
return getAttribute(this.key);
}
@Override
public V setValue(Object value) {
if (value == null) {
removeAttribute(this.key);
} else {
setAttribute(this.key, value);
}
return null;
}
@Override
public boolean equals(Object obj) {
return (obj != null && this.hashCode() == obj.hashCode());
}
@Override
public int hashCode() {
return this.key.hashCode();
}
}
@Override
public final V get(Object key) {
if (key != null) {
return getAttribute((String) key);
}
return null;
}
@Override
public final V put(String key, V value) {
Objects.requireNonNull(key);
if (value == null) {
this.removeAttribute(key);
} else {
this.setAttribute(key, value);
}
return null;
}
@Override
public final V remove(Object key) {
Objects.requireNonNull(key);
this.removeAttribute((String) key);
return null;
}
}
}

View File

@@ -0,0 +1,238 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javax.servlet.jsp.el;
import java.beans.FeatureDescriptor;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import javax.el.ELClass;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.ImportHandler;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.PageContext;
/**
*
* @since 2.1
*/
public class ScopedAttributeELResolver extends ELResolver {
// Indicates if a performance short-cut is available
private static final Class<?> AST_IDENTIFIER_KEY;
static {
Class<?> key = null;
try {
key = Class.forName("org.apache.el.parser.AstIdentifier");
} catch (Exception e) {
// Ignore: Expected if not running on Tomcat. Not a problem since
// this just allows a short-cut.
}
AST_IDENTIFIER_KEY = key;
}
@Override
public Object getValue(ELContext context, Object base, Object property) {
Objects.requireNonNull(context);
Object result = null;
if (base == null) {
context.setPropertyResolved(base, property);
if (property != null) {
String key = property.toString();
PageContext page = (PageContext) context.getContext(JspContext.class);
result = page.findAttribute(key);
if (result == null) {
boolean resolveClass = true;
// Performance short-cut available when running on Tomcat
if (AST_IDENTIFIER_KEY != null) {
// Tomcat will set this key to Boolean.TRUE if the
// identifier is a stand-alone identifier (i.e.
// identifier) rather than part of an AstValue (i.e.
// identifier.something). Imports do not need to be
// checked if this is a stand-alone identifier
Boolean value = (Boolean) context.getContext(AST_IDENTIFIER_KEY);
if (value != null && value.booleanValue()) {
resolveClass = false;
}
}
// This might be the name of an imported class
ImportHandler importHandler = context.getImportHandler();
if (importHandler != null) {
Class<?> clazz = null;
if (resolveClass) {
clazz = importHandler.resolveClass(key);
}
if (clazz != null) {
result = new ELClass(clazz);
}
if (result == null) {
// This might be the name of an imported static field
clazz = importHandler.resolveStatic(key);
if (clazz != null) {
try {
result = clazz.getField(key).get(null);
} catch (IllegalArgumentException | IllegalAccessException |
NoSuchFieldException | SecurityException e) {
// Most (all?) of these should have been
// prevented by the checks when the import
// was defined.
}
}
}
}
}
}
}
return result;
}
@Override
public Class<Object> getType(ELContext context, Object base, Object property) {
Objects.requireNonNull(context);
if (base == null) {
context.setPropertyResolved(base, property);
return Object.class;
}
return null;
}
@Override
public void setValue(ELContext context, Object base, Object property, Object value) {
Objects.requireNonNull(context);
if (base == null) {
context.setPropertyResolved(base, property);
if (property != null) {
String key = property.toString();
PageContext page = (PageContext) context.getContext(JspContext.class);
int scope = page.getAttributesScope(key);
if (scope != 0) {
page.setAttribute(key, value, scope);
} else {
page.setAttribute(key, value);
}
}
}
}
@Override
public boolean isReadOnly(ELContext context, Object base, Object property) {
Objects.requireNonNull(context);
if (base == null) {
context.setPropertyResolved(base, property);
}
return false;
}
@Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
PageContext ctxt = (PageContext) context.getContext(JspContext.class);
List<FeatureDescriptor> list = new ArrayList<>();
Enumeration<String> e;
Object value;
String name;
e = ctxt.getAttributeNamesInScope(PageContext.PAGE_SCOPE);
while (e.hasMoreElements()) {
name = e.nextElement();
value = ctxt.getAttribute(name, PageContext.PAGE_SCOPE);
FeatureDescriptor descriptor = new FeatureDescriptor();
descriptor.setName(name);
descriptor.setDisplayName(name);
descriptor.setExpert(false);
descriptor.setHidden(false);
descriptor.setPreferred(true);
descriptor.setShortDescription("page scoped attribute");
descriptor.setValue("type", value.getClass());
descriptor.setValue("resolvableAtDesignTime", Boolean.FALSE);
list.add(descriptor);
}
e = ctxt.getAttributeNamesInScope(PageContext.REQUEST_SCOPE);
while (e.hasMoreElements()) {
name = e.nextElement();
value = ctxt.getAttribute(name, PageContext.REQUEST_SCOPE);
FeatureDescriptor descriptor = new FeatureDescriptor();
descriptor.setName(name);
descriptor.setDisplayName(name);
descriptor.setExpert(false);
descriptor.setHidden(false);
descriptor.setPreferred(true);
descriptor.setShortDescription("request scope attribute");
descriptor.setValue("type", value.getClass());
descriptor.setValue("resolvableAtDesignTime", Boolean.FALSE);
list.add(descriptor);
}
if (ctxt.getSession() != null) {
e = ctxt.getAttributeNamesInScope(PageContext.SESSION_SCOPE);
while (e.hasMoreElements()) {
name = e.nextElement();
value = ctxt.getAttribute(name, PageContext.SESSION_SCOPE);
FeatureDescriptor descriptor = new FeatureDescriptor();
descriptor.setName(name);
descriptor.setDisplayName(name);
descriptor.setExpert(false);
descriptor.setHidden(false);
descriptor.setPreferred(true);
descriptor.setShortDescription("session scoped attribute");
descriptor.setValue("type", value.getClass());
descriptor.setValue("resolvableAtDesignTime", Boolean.FALSE);
list.add(descriptor);
}
}
e = ctxt.getAttributeNamesInScope(PageContext.APPLICATION_SCOPE);
while (e.hasMoreElements()) {
name = e.nextElement();
value = ctxt.getAttribute(name, PageContext.APPLICATION_SCOPE);
FeatureDescriptor descriptor = new FeatureDescriptor();
descriptor.setName(name);
descriptor.setDisplayName(name);
descriptor.setExpert(false);
descriptor.setHidden(false);
descriptor.setPreferred(true);
descriptor.setShortDescription("application scoped attribute");
descriptor.setValue("type", value.getClass());
descriptor.setValue("resolvableAtDesignTime", Boolean.FALSE);
list.add(descriptor);
}
return list.iterator();
}
@Override
public Class<String> getCommonPropertyType(ELContext context, Object base) {
if (base == null) {
return String.class;
}
return null;
}
}

View File

@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javax.servlet.jsp.el;
/**
* <p>
* This class is used to customize the way an ExpressionEvaluator resolves
* variable references at evaluation time. For example, instances of this class
* can implement their own variable lookup mechanisms, or introduce the notion
* of "implicit variables" which override any other variables. An instance of
* this class should be passed when evaluating an expression.
* </p>
* <p>
* An instance of this class includes the context against which resolution will
* happen
* </p>
*
* @since 2.0
* @deprecated As of JSP 2.1, replaced by javax.el.ELResolver
*/
@SuppressWarnings("dep-ann")
// TCK signature test fails with annotation
public interface VariableResolver {
/**
* Resolves the specified variable. Returns null if the variable is not
* found.
*
* @param pName
* the name of the variable to resolve
* @return the result of the variable resolution
* @throws ELException
* if a failure occurred while trying to resolve the given
* variable
*/
public Object resolveVariable(String pName) throws ELException;
}

View File

@@ -0,0 +1,37 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
</head>
<body bgcolor="white">
Classes and interfaces for the JSP 2.0 Expression Language API.
<p>
The JavaServer Pages(tm) (JSP) 2.0 specification provides a portable
API for evaluating "EL Expressions". As of JSP 2.0, EL expressions can
be placed directly in the template text of JSP pages and tag files.
<p>
This package contains a number of classes and interfaces that describe
and define programmatic access to the Expression Language evaluator.
This API can also be used by an implementation of JSP to evaluate the
expressions, but other implementations, like open-coding into Java
bytecodes, are allowed. This package is intended to have no dependencies
on other portions of the JSP 2.0 specification.
</body>
</html>