Save This Page
Home » glassfish-v2ur2-b04-src » javax » el » [javadoc | source]
    1   /*
    2    * The contents of this file are subject to the terms
    3    * of the Common Development and Distribution License
    4    * (the "License").  You may not use this file except
    5    * in compliance with the License.
    6    *
    7    * You can obtain a copy of the license at
    8    * glassfish/bootstrap/legal/CDDLv1.0.txt or
    9    * https://glassfish.dev.java.net/public/CDDLv1.0.html.
   10    * See the License for the specific language governing
   11    * permissions and limitations under the License.
   12    *
   13    * When distributing Covered Code, include this CDDL
   14    * HEADER in each file and include the License file at
   15    * glassfish/bootstrap/legal/CDDLv1.0.txt.  If applicable,
   16    * add the following below this CDDL HEADER, with the
   17    * fields enclosed by brackets "[]" replaced with your
   18    * own identifying information: Portions Copyright [yyyy]
   19    * [name of copyright owner]
   20    *
   21    * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
   22    */ 
   23   
   24   package javax.el;
   25   
   26   import java.util.Iterator;
   27   import java.beans.FeatureDescriptor;
   28   
   29   /**
   30    * Enables customization of variable and property resolution behavior for EL
   31    * expression evaluation.
   32    *
   33    * <p>While evaluating an expression, the <code>ELResolver</code> associated
   34    * with the {@link ELContext} is consulted to do the initial resolution of 
   35    * the first variable of an expression. It is also consulted when a 
   36    * <code>.</code> or <code>[]</code> operator is encountered, except for the
   37    * last such operator in a method expression, in which case the resultion
   38    * rules are hard coded.</p>
   39    *
   40    * <p>For example, in the EL expression <code>${employee.lastName}</code>, 
   41    * the <code>ELResolver</code> determines what object <code>employee</code>
   42    * refers to, and what it means to get the <code>lastName</code> property on 
   43    * that object.</p>
   44    *
   45    * <p>Most methods in this class accept a <code>base</code> 
   46    * and <code>property</code> parameter. In the case of variable resolution
   47    * (e.g. determining what <code>employee</code> refers to in 
   48    * <code>${employee.lastName}</code>), the <code>base</code> parameter will 
   49    * be <code>null</code> and the <code>property</code> parameter will always 
   50    * be of type <code>String</code>. In this case, if the <code>property</code>
   51    * is not a <code>String</code>, the behavior of the <code>ELResolver</code>
   52    * is undefined.</p>
   53    *
   54    * <p>In the case of property resolution, the <code>base</code> parameter
   55    * identifies the base object and the <code>property</code> object identifies
   56    * the property on that base. For example, in the expression
   57    * <code>${employee.lastName}</code>, <code>base</code> is the result of the
   58    * variable resolution for <code>employee</code> and <code>property</code>
   59    * is the string <code>"lastName"</code>.  In the expression
   60    * <code>${y[x]}</code>, <code>base</code> is the result of the variable
   61    * resolution for <code>y</code> and <code>property</code> is the result of
   62    * the variable resolution for <code>x</code>.</p>
   63    *
   64    * <p>Though only a single <code>ELResolver</code> is associated with an
   65    * <code>ELContext</code>, there are usually multiple resolvers considered
   66    * for any given variable or property resolution. <code>ELResolver</code>s
   67    * are combined together using {@link CompositeELResolver}s, to define
   68    * rich semantics for evaluating an expression.</p>
   69    *
   70    * <p>For the {@link #getValue}, {@link #getType}, {@link #setValue} and
   71    * {@link #isReadOnly} methods, an <code>ELResolver</code> is not
   72    * responsible for resolving all possible (base, property) pairs. In fact,
   73    * most resolvers will only handle a <code>base</code> of a single type.
   74    * To indicate that a resolver has successfully resolved a particular
   75    * (base, property) pair, it must set the <code>propertyResolved</code>
   76    * property of the <code>ELContext</code> to <code>true</code>. If it could 
   77    * not handle the given pair, it must leave this property alone. The caller
   78    * must ignore the return value of the method if <code>propertyResolved</code>
   79    * is <code>false</code>.</p>
   80    *
   81    * <p>The {@link #getFeatureDescriptors} and {@link #getCommonPropertyType}
   82    * methods are primarily designed for design-time tool support, but must
   83    * handle invocation at runtime as well. The 
   84    * {@link java.beans.Beans#isDesignTime} method can be used to determine 
   85    * if the resolver is being consulted at design-time or runtime.</p>
   86    *
   87    * @see CompositeELResolver
   88    * @see ELContext#getELResolver
   89    * @since JSP 2.1
   90    */
   91   public abstract class ELResolver {
   92       
   93       // --------------------------------------------------------- Constants
   94   
   95       /**
   96        * <p>The attribute name of the named attribute in the
   97        * <code>FeatureDescriptor</code> that specifies the runtime type of
   98        * the variable or property.</p>
   99        */
  100   
  101       public static final String TYPE = "type";
  102   
  103       /**
  104        * <p>The attribute name of the named attribute in the
  105        * <code>FeatureDescriptor</code> that specifies whether the
  106        * variable or property can be resolved at runtime.</p>
  107        */
  108   
  109       public static final String RESOLVABLE_AT_DESIGN_TIME = "resolvableAtDesignTime";
  110   
  111       /**
  112        * Attempts to resolve the given <code>property</code> object on the given
  113        * <code>base</code> object.
  114        *
  115        * <p>If this resolver handles the given (base, property) pair, 
  116        * the <code>propertyResolved</code> property of the 
  117        * <code>ELContext</code> object must be set to <code>true</code>
  118        * by the resolver, before returning. If this property is not 
  119        * <code>true</code> after this method is called, the caller should ignore 
  120        * the return value.</p>
  121        *
  122        * @param context The context of this evaluation.
  123        * @param base The base object whose property value is to be returned,
  124        *     or <code>null</code> to resolve a top-level variable.
  125        * @param property The property or variable to be resolved.
  126        * @return If the <code>propertyResolved</code> property of 
  127        *     <code>ELContext</code> was set to <code>true</code>, then
  128        *     the result of the variable or property resolution; otherwise
  129        *     undefined.
  130        * @throws NullPointerException if context is <code>null</code>
  131        * @throws PropertyNotFoundException if the given (base, property) pair
  132        *     is handled by this <code>ELResolver</code> but the specified
  133        *     variable or property does not exist or is not readable.
  134        * @throws ELException if an exception was thrown while performing
  135        *     the property or variable resolution. The thrown exception
  136        *     must be included as the cause property of this exception, if
  137        *     available.
  138        */
  139       public abstract Object getValue(ELContext context,
  140                                       Object base,
  141                                       Object property);
  142   
  143       /**
  144        * For a given <code>base</code> and <code>property</code>, attempts to
  145        * identify the most general type that is acceptable for an object to be 
  146        * passed as the <code>value</code> parameter in a future call 
  147        * to the {@link #setValue} method.
  148        *
  149        * <p>If this resolver handles the given (base, property) pair, 
  150        * the <code>propertyResolved</code> property of the 
  151        * <code>ELContext</code> object must be set to <code>true</code>
  152        * by the resolver, before returning. If this property is not 
  153        * <code>true</code> after this method is called, the caller should ignore 
  154        * the return value.</p>
  155        *
  156        * <p>This is not always the same as <code>getValue().getClass()</code>.
  157        * For example, in the case of an {@link ArrayELResolver}, the
  158        * <code>getType</code> method will return the element type of the 
  159        * array, which might be a superclass of the type of the actual 
  160        * element that is currently in the specified array element.</p>
  161        *
  162        * @param context The context of this evaluation.
  163        * @param base The base object whose property value is to be analyzed,
  164        *     or <code>null</code> to analyze a top-level variable.
  165        * @param property The property or variable to return the acceptable 
  166        *     type for.
  167        * @return If the <code>propertyResolved</code> property of 
  168        *     <code>ELContext</code> was set to <code>true</code>, then
  169        *     the most general acceptable type; otherwise undefined.
  170        * @throws NullPointerException if context is <code>null</code>
  171        * @throws PropertyNotFoundException if the given (base, property) pair
  172        *     is handled by this <code>ELResolver</code> but the specified
  173        *     variable or property does not exist or is not readable.
  174        * @throws ELException if an exception was thrown while performing
  175        *     the property or variable resolution. The thrown exception
  176        *     must be included as the cause property of this exception, if
  177        *     available.
  178        */
  179       public abstract Class<?> getType(ELContext context,
  180                                     Object base,
  181                                     Object property);
  182   
  183       /**
  184        * Attempts to set the value of the given <code>property</code> 
  185        * object on the given <code>base</code> object.
  186        *
  187        * <p>If this resolver handles the given (base, property) pair, 
  188        * the <code>propertyResolved</code> property of the 
  189        * <code>ELContext</code> object must be set to <code>true</code>
  190        * by the resolver, before returning. If this property is not 
  191        * <code>true</code> after this method is called, the caller can
  192        * safely assume no value has been set.</p>
  193        *
  194        * @param context The context of this evaluation.
  195        * @param base The base object whose property value is to be set,
  196        *     or <code>null</code> to set a top-level variable.
  197        * @param property The property or variable to be set.
  198        * @param value The value to set the property or variable to.
  199        * @throws NullPointerException if context is <code>null</code>
  200        * @throws PropertyNotFoundException if the given (base, property) pair
  201        *     is handled by this <code>ELResolver</code> but the specified
  202        *     variable or property does not exist.
  203        * @throws PropertyNotWritableException if the given (base, property)
  204        *     pair is handled by this <code>ELResolver</code> but the specified
  205        *     variable or property is not writable.
  206        * @throws ELException if an exception was thrown while attempting to
  207        *     set the property or variable. The thrown exception
  208        *     must be included as the cause property of this exception, if
  209        *     available.
  210        */
  211       public abstract void setValue(ELContext context,
  212                                     Object base,
  213                                     Object property,
  214                                     Object value);
  215   
  216       /**
  217        * For a given <code>base</code> and <code>property</code>, attempts to
  218        * determine whether a call to {@link #setValue} will always fail.
  219        *
  220        * <p>If this resolver handles the given (base, property) pair, 
  221        * the <code>propertyResolved</code> property of the 
  222        * <code>ELContext</code> object must be set to <code>true</code>
  223        * by the resolver, before returning. If this property is not 
  224        * <code>true</code> after this method is called, the caller should ignore 
  225        * the return value.</p>
  226        *
  227        * @param context The context of this evaluation.
  228        * @param base The base object whose property value is to be analyzed,
  229        *     or <code>null</code> to analyze a top-level variable.
  230        * @param property The property or variable to return the read-only status
  231        *     for.
  232        * @return If the <code>propertyResolved</code> property of 
  233        *     <code>ELContext</code> was set to <code>true</code>, then
  234        *     <code>true</code> if the property is read-only or
  235        *     <code>false</code> if not; otherwise undefined.
  236        * @throws NullPointerException if context is <code>null</code>
  237        * @throws PropertyNotFoundException if the given (base, property) pair
  238        *     is handled by this <code>ELResolver</code> but the specified
  239        *     variable or property does not exist.
  240        * @throws ELException if an exception was thrown while performing
  241        *     the property or variable resolution. The thrown exception
  242        *     must be included as the cause property of this exception, if
  243        *     available.
  244        */
  245       public abstract boolean isReadOnly(ELContext context,
  246                                          Object base,
  247                                          Object property);
  248   
  249       /**
  250        * Returns information about the set of variables or properties that 
  251        * can be resolved for the given <code>base</code> object. One use for
  252        * this method is to assist tools in auto-completion.
  253        *
  254        * <p>If the <code>base</code> parameter is <code>null</code>, the 
  255        * resolver must enumerate the list of top-level variables it can 
  256        * resolve.</p>
  257        *
  258        * <p>The <code>Iterator</code> returned must contain zero or more 
  259        * instances of {@link java.beans.FeatureDescriptor}, in no guaranteed 
  260        * order. In the case of primitive types such as <code>int</code>, the 
  261        * value <code>null</code> must be returned. This is to prevent the 
  262        * useless iteration through all possible primitive values. A 
  263        * return value of <code>null</code> indicates that this resolver does 
  264        * not handle the given <code>base</code> object or that the results 
  265        * are too complex to represent with this method and the 
  266        * {@link #getCommonPropertyType} method should be used instead.</p>
  267        *
  268        * <p>Each <code>FeatureDescriptor</code> will contain information about
  269        * a single variable or property. In addition to the standard
  270        * properties, the <code>FeatureDescriptor</code> must have two
  271        * named attributes (as set by the <code>setValue</code> method):
  272        * <ul>
  273        *   <li>{@link #TYPE} - The value of this named attribute must be 
  274        *       an instance of <code>java.lang.Class</code> and specify the 
  275        *       runtime type of the variable or property.</li>
  276        *   <li>{@link #RESOLVABLE_AT_DESIGN_TIME} - The value of this 
  277        *       named attribute must be an instance of 
  278        *       <code>java.lang.Boolean</code> and indicates whether it is safe 
  279        *       to attempt to resolve this property at design-time. For 
  280        *       instance, it may be unsafe to attempt a resolution at design 
  281        *       time if the <code>ELResolver</code> needs access to a resource 
  282        *       that is only available at runtime and no acceptable simulated 
  283        *       value can be provided.</li>
  284        * </ul></p>
  285        *
  286        * <p>The caller should be aware that the <code>Iterator</code> 
  287        * returned might iterate through a very large or even infinitely large 
  288        * set of properties. Care should be taken by the caller to not get 
  289        * stuck in an infinite loop.</p>
  290        *
  291        * <p>This is a "best-effort" list.  Not all <code>ELResolver</code>s
  292        * will return completely accurate results, but all must be callable
  293        * at both design-time and runtime (i.e. whether or not
  294        * <code>Beans.isDesignTime()</code> returns <code>true</code>),
  295        * without causing errors.</p>
  296        *
  297        * <p>The <code>propertyResolved</code> property of the 
  298        * <code>ELContext</code> is not relevant to this method.
  299        * The results of all <code>ELResolver</code>s are concatenated
  300        * in the case of composite resolvers.</p>
  301        * 
  302        * @param context The context of this evaluation.
  303        * @param base The base object whose set of valid properties is to
  304        *     be enumerated, or <code>null</code> to enumerate the set of
  305        *     top-level variables that this resolver can evaluate.
  306        * @return An <code>Iterator</code> containing zero or more (possibly
  307        *     infinitely more) <code>FeatureDescriptor</code> objects, or 
  308        *     <code>null</code> if this resolver does not handle the given 
  309        *     <code>base</code> object or that the results are too complex to 
  310        *     represent with this method
  311        * @see java.beans.FeatureDescriptor
  312        */
  313       public abstract Iterator<FeatureDescriptor> getFeatureDescriptors(
  314                                                      ELContext context,
  315                                                      Object base);
  316   
  317       /**
  318        * Returns the most general type that this resolver accepts for the
  319        * <code>property</code> argument, given a <code>base</code> object.
  320        * One use for this method is to assist tools in auto-completion.
  321        *
  322        * <p>This assists tools in auto-completion and also provides a 
  323        * way to express that the resolver accepts a primitive value, 
  324        * such as an integer index into an array. For example, the 
  325        * {@link ArrayELResolver} will accept any <code>int</code> as a 
  326        * <code>property</code>, so the return value would be 
  327        * <code>Integer.class</code>.</p>
  328        *
  329        * @param context The context of this evaluation.
  330        * @param base The base object to return the most general property
  331        *     type for, or <code>null</code> to enumerate the set of
  332        *     top-level variables that this resolver can evaluate.
  333        * @return <code>null</code> if this <code>ELResolver</code> does not
  334        *     know how to handle the given <code>base</code> object; otherwise
  335        *     <code>Object.class</code> if any type of <code>property</code>
  336        *     is accepted; otherwise the most general <code>property</code>
  337        *     type accepted for the given <code>base</code>.
  338        */
  339       public abstract Class<?> getCommonPropertyType(ELContext context,
  340                                                   Object base);
  341                       
  342   }

Save This Page
Home » glassfish-v2ur2-b04-src » javax » el » [javadoc | source]