Filewatcher File Search
FTP Search
  
Directory (beta)
  
Content Search (beta)
   
pkg://jakarta-commons-el-1.0-2jpp_3fc.src.rpm:632472/commons-el-1.0-src.tar.gz  info  downloads

commons-el-1.0-src/004075500723740000012000000000000767411774200145505ustar00luehestaff00003710000056commons-el-1.0-src/RELEASE-NOTES.txt010064400723740000012000000007520767021124500172450ustar00luehestaff00003710000056$Id: RELEASE-NOTES.txt,v 1.1 2003/06/06 22:16:05 luehe Exp $

                          Commons EL Package
                              Version 1.0
                             Release Notes

Introduction
------------

This is the first release of the commons-el package, which provides an
implementation of the standard interfaces and abstract classes of the
javax.servlet.jsp.el package, which is part of the JSP 2.0
specification.

Bug Status
----------

There are no outstanding bugs.
commons-el-1.0-src/LICENSE.txt010064400723740000012000000053730761760370000163670ustar00luehestaff00003710000056/*
 * $Header: /home/cvs/jakarta-commons/el/LICENSE.txt,v 1.1.1.1 2003/02/04 00:22:24 luehe Exp $
 * $Revision: 1.1.1.1 $
 * $Date: 2003/02/04 00:22:24 $
 *
 * ====================================================================
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Commons", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */
commons-el-1.0-src/PROPOSAL.html010064400723740000012000000067750764167263100167060ustar00luehestaff00003710000056<html>
<head>
<title>Proposal for JSP 2.0 Expression Language Interpreter Package</title>
</head>
<body bgcolor="white">

<div align="center">
<h1>Proposal for <em>JSP 2.0 Expression Language Interpreter</em> Package</h1>
</div>

<h3>(0) Rationale</h3>

<p>The JSP Standard Tag Library (JSTL), version 1.0, introduced the
concept of an Expression Language (EL), whose main goal is to provide
page authors with an easy way to access and manipulate application
data without requiring the use of scriptlets

<p>JSP 2.0 adopted the EL specification from JSTL, and expanded its
scope: EL expressions are no longer limited to JSTL action attributes,
but may be used in any standard or custom action attribute declared to
accept a runtime expression. In addition, EL expressions may now also
be used directly in template text outside of any actions. JSP 2.0 also
added an important feature to the EL specification: EL functions,
which allow page authors to invoke static methods in Java classes from
EL expressions. Additionally, JSP 2.0 allows programmatic access and
customization of the EL evaluator through a set of standard interfaces
and abstract classes.

<p>Currently, there are a number of projects (including Tomcat 5 and Java
Server Faces) that leverage the EL implementation of the Standard
Taglib. In addition, there seems to be interest in leveraging the EL
in the context of scripting workflow activities using custom tag
libraries.

<p>In order to make the EL implementation available to Tomcat 5, the
Tomcat team defined a new "ant" target for the Standard Taglib that
builds just the EL portion and packages it in a JAR file
(&quot;jsp20el.jar&quot;) which is stored in Tomcat's common/lib
directory. This approach has always been considered an interim
solution only, until the EL implementation would move from the
Standard Taglib to a more visible location such as jakarta-commons.

<h3>(1) Scope of the package</h3>

The package shall provide an implementation of the Expression Language
specification which is part of the JSP 2.0 standard.

<h3>(1.5) Interaction with other packages</h3>

The package shall provide an implementation of the standard interfaces
and abstract classes of the javax.servlet.jsp.el package, which is
defined in the JSP 2.0 specification.

<h3>(2) Identify the initial source for the package</h3>

The initial codebase will be taken from the Standard Taglib project
hosted at jakarta-taglibs. The source of the Standard Taglib is
available as part of the <a href="http://jakarta.apache.org/builds/jakarta-taglibs/nightly/src/">jakarta-taglibs nightly source distribution</a>.

<h3>(2.1) Identify the base name for the package</h3>

The base name of the package shall be org.apache.commons.el

<h3>(2.2) Identify the coding conventions for this package</h3>

The package follows <a href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">Sun's Java coding conventions</a>.

<h3>(3) Identify any Jakarta-Commons resources to be created</h3>

<h3>(3.1) Mailing list</h3>

The package shall use the jakarta-commons mailing list.

<h3>(3.2) CVS repositories</h3>

The package shall use a root branch of the jakarta-commons CVS.

<h3>(3.3) Bugzilla</h3>

The package shall be listed as the "EL" component under the "Commons"
project in Bugzilla.

<h3>(3.4) Jyve FAQ (when available)</h3>

n/a

<h3>(4) Initial Committers</h3>

<ul>
  <li>Shawn Bayern</li>
  <li>Nathan Abramson</li>
  <li>Pierre Delisle</li>
  <li>Hans Bergsten</li>
  <li>Justyna Horwat</li>
  <li>Craig R. McClanahan</li>
  <li>Jan Luehe</li>
</ul>

</body>
</html>
commons-el-1.0-src/build.properties010075500723740000012000000004630764210442600177560ustar00luehestaff00003710000056# The home directory for the Servlet 2.4 and JSP 2.0 classes distribution
api.home = ../../jakarta-servletapi-5

# The directory containing your binary distribution of JUnit, 
# version 3.7 or later
junit.home = ../../junit3.7

# The pathname of the "junit.jar" JAR file
junit.jar = ${junit.home}/junit.jar
commons-el-1.0-src/STATUS.html010064400723740000012000000044350767020354200164520ustar00luehestaff00003710000056<html>
<head>
<title>Status File for Jakarta Commons "EL" Component</title>
<head>
<body bgcolor="white">

<div align="center">
<h1>The Jakarta Commons <em>EL</em> Component</h1>
$Id: STATUS.html,v 1.1 2003/06/06 21:28:02 luehe Exp $<br />
<a href="#Introduction">[Introduction]</a>
<a href="#Dependencies">[Dependencies]</a>
<a href="#Release Info">[Release Info]</a>
<a href="#Committers">[Committers]</a>
<a href="#Action Items">[Action Items]</a>
<br /><br />
</div>


<a name="Introduction"></a>
<h3>1.  INTRODUCTION</h3>

<p> The commons-el package provides an implementation of the standard interfaces and abstract classes of the javax.servlet.jsp.el package, which is part of the JSP 2.0 specification.
</p>

<p>The classes that are now released as commons-el used to be part of the JSTL 1.0 reference implementation. JSTL 1.0 originally introduced the concept of an Expression Language (EL). The EL has since been integrated into the JSP 2.0 specification, which also added new features to it, such as EL Functions.
</p>


<a name="Dependencies"></a>
<h3>2.  DEPENDENCIES</h3>

<p>The <em>EL</em> component is dependent upon the following external
components for compilation:</p>
<ul>
<li><a href="http://java.sun.com/j2se">Java Development Kit</a>
    (Version 1.3 or later)</li>
<li><a href="http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jspapi">JSP 2.0 API</a></li>
<li><a href="http://jakarta.apache.org/tomcat/tomcat-5.0-doc/servletapi/index.html">Servlet 2.4 API</a></li>
</ul>


<a name="Release Info"></a>
<h3>3.  RELEASE INFO</h3>

<table border="1">
  <tr>
    <th width="50%">Version</th>
    <th width="50%">Release Date</th>
  </tr>
  <tr>
    <td><a href='http://jakarta.apache.org/builds/jakarta-commons/release/commons-el/v1.0'>
        commons-el-1.0</td>
    <td>7-Jun-2003</td>
  </tr>
</table>

<p>Planned Next Release:  TBD</p>


<a name="Committers"></a>
<h3>4.  COMMITTERS</h3>

<ul>
  <li>Shawn Bayern</li>
  <li>Nathan Abramson</li>
  <li>Pierre Delisle</li>
  <li>Hans Bergsten</li>
  <li>Mark Roth</li>
  <li>Craig R. McClanahan</li>
  <li>Kin-Man Chung</li>
  <li>Jan Luehe</li>
</ul>


<a name="Action Items"></a>
<h3>5.  ACTION ITEMS</h3>

<p>TO DO List:</p>

<table border="1">
  <tr>
    <th width="80%">Action Item</th>
    <th width="20%">Volunteer</th>
  </tr>
</table>

</body>
</html>
commons-el-1.0-src/src/004075500723740000012000000000000767411766600153445ustar00luehestaff00003710000056commons-el-1.0-src/src/conf/004075500723740000012000000000000767411766600162715ustar00luehestaff00003710000056commons-el-1.0-src/src/conf/MANIFEST.MF010064400723740000012000000004240767020366300177050ustar00luehestaff00003710000056Extension-Name: org.apache.commons.el
Specification-Title: Jakarta Commons EL
Specification-Vendor: Apache Software Foundation
Specification-Version: 2.0
Implementation-Title: org.apache.commons.el
Implementation-Vendor: Apache Software Foundation
Implementation-Version: 1.0
commons-el-1.0-src/src/java/004075500723740000012000000000000767411766600162655ustar00luehestaff00003710000056commons-el-1.0-src/src/java/org/004075500723740000012000000000000767411766600170545ustar00luehestaff00003710000056commons-el-1.0-src/src/java/org/apache/004075500723740000012000000000000767411766700202765ustar00luehestaff00003710000056commons-el-1.0-src/src/java/org/apache/commons/004075500723740000012000000000000767411766700217515ustar00luehestaff00003710000056commons-el-1.0-src/src/java/org/apache/commons/el/004075500723740000012000000000000767411767500223505ustar00luehestaff00003710000056commons-el-1.0-src/src/java/org/apache/commons/el/ArithmeticOperator.java010064400723740000012000000101500767411577100270050ustar00luehestaff00003710000056/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 

package org.apache.commons.el;

import javax.servlet.jsp.el.ELException;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 *
 * <p>This is the superclass for all binary arithmetic operators
 * 
 * @author Nathan Abramson - Art Technology Group
 * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: luehe $
 **/

public abstract class ArithmeticOperator
  extends BinaryOperator
{
  //-------------------------------------
  /**
   *
   * Applies the operator to the given value
   **/
  public Object apply (Object pLeft,
		       Object pRight,
		       Logger pLogger)
    throws ELException
  {
    return Coercions.applyArithmeticOperator (pLeft, pRight, this, pLogger);
  }

  //-------------------------------------
  /**
   *
   * Applies the operator to the given double values, returning a double
   **/
  public abstract double apply (double pLeft, double pRight);
  
  //-------------------------------------
  /**
   *
   * Applies the operator to the given double values, returning a double
   **/
  public abstract long apply (long pLeft, long pRight);
  
  //-------------------------------------

    /**
     *
     * Applies the operator to the given BigDecimal values, returning a
     * BigDecimal.
     **/
    public abstract BigDecimal apply(BigDecimal pLeft, BigDecimal pRight);

    //-------------------------------------

    /**
     *
     * Applies the operator to the given BigInteger values, returning a
     * BigInteger.
     **/
    public abstract BigInteger apply(BigInteger pLeft, BigInteger pRight);

    //-------------------------------------
}
commons-el-1.0-src/src/java/org/apache/commons/el/AndOperator.java010064400723740000012000000107000761760370000254060ustar00luehestaff00003710000056/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 

package org.apache.commons.el;

import javax.servlet.jsp.el.ELException;

/**
 *
 * <p>The implementation of the and operator
 * 
 * @author Nathan Abramson - Art Technology Group
 * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: luehe $
 **/

public class AndOperator
  extends BinaryOperator
{
  //-------------------------------------
  // Singleton
  //-------------------------------------

  public static final AndOperator SINGLETON =
    new AndOperator ();

  //-------------------------------------
  /**
   *
   * Constructor
   **/
  public AndOperator ()
  {
  }

  //-------------------------------------
  // Expression methods
  //-------------------------------------
  /**
   *
   * Returns the symbol representing the operator
   **/
  public String getOperatorSymbol ()
  {
    return "and";
  }

  //-------------------------------------
  /**
   *
   * Applies the operator to the given value
   **/
  public Object apply (Object pLeft,
		       Object pRight,
		       Logger pLogger)
    throws ELException
  {
    // Coerce the values to booleans
    boolean left = 
      Coercions.coerceToBoolean (pLeft, pLogger).booleanValue ();
    boolean right = 
      Coercions.coerceToBoolean (pRight, pLogger).booleanValue ();

    return PrimitiveObjects.getBoolean (left && right);
  }

  //-------------------------------------
  /**
   *
   * Returns true if evaluation is necessary given the specified Left
   * value.  The And/OrOperators make use of this
   **/
  public boolean shouldEvaluate (Object pLeft)
  {
    return
      (pLeft instanceof Boolean) &&
      ((Boolean) pLeft).booleanValue () == true;
  }

  //-------------------------------------
  /**
   *
   * Returns true if the operator expects its arguments to be coerced
   * to Booleans.  The And/Or operators set this to true.
   **/
  public boolean shouldCoerceToBoolean ()
  {
    return true;
  }

  //-------------------------------------
}
commons-el-1.0-src/src/java/org/apache/commons/el/BeanInfoManager.java010064400723740000012000000307550761760370000261600ustar00luehestaff00003710000056/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 

package org.apache.commons.el;

import java.beans.BeanInfo;
import java.beans.EventSetDescriptor;
import java.beans.IndexedPropertyDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.jsp.el.ELException;

/**
 *
 * <p>Manages the BeanInfo for one class - contains the BeanInfo, and
 * also a mapping from property name to BeanInfoProperty.  There are
 * also static methods for accessing the BeanInfoManager for a class -
 * those mappings are cached permanently so that once the
 * BeanInfoManager is calculated, it doesn't have to be calculated
 * again.
 * 
 * @author Nathan Abramson - Art Technology Group
 * @version $Change: 181181 $$DateTime: 2001/06/26 09:55:09 $$Author: luehe $
 **/

public class BeanInfoManager
{
  //-------------------------------------
  // Properties
  //-------------------------------------
  // property beanClass

  Class mBeanClass;
  public Class getBeanClass ()
  { return mBeanClass; }

  //-------------------------------------
  // Member variables
  //-------------------------------------

  // The BeanInfo
  BeanInfo mBeanInfo;

  // Mapping from property name to BeanInfoProperty
  Map mPropertyByName;

  // Mapping from property name to BeanInfoIndexedProperty
  Map mIndexedPropertyByName;

  // Mapping from event set name to event set descriptor
  Map mEventSetByName;

  // Flag if this is initialized
  boolean mInitialized;

  // The global mapping from class to BeanInfoManager
  static Map mBeanInfoManagerByClass = new HashMap ();

  //-------------------------------------
  /**
   *
   * Constructor
   **/
  BeanInfoManager (Class pBeanClass)
  {
    mBeanClass = pBeanClass;
  }

  //-------------------------------------
  /**
   *
   * Returns the BeanInfoManager for the specified class
   **/
  public static BeanInfoManager getBeanInfoManager (Class pClass)
  {
    BeanInfoManager ret = (BeanInfoManager) 
      mBeanInfoManagerByClass.get (pClass);
    if (ret == null) {
      ret = createBeanInfoManager (pClass);
    }
    return ret;
  }

  //-------------------------------------
  /**
   *
   * Creates and registers the BeanInfoManager for the given class if
   * it isn't already registered.
   **/
  static synchronized BeanInfoManager createBeanInfoManager (Class pClass)
  {
    // Because this method is synchronized statically, the
    // BeanInfoManager is not initialized at this time (otherwise it
    // could end up being a bottleneck for the entire system).  It is
    // put into the map in an uninitialized state.  The first time
    // someone tries to use it, it will be initialized (with proper
    // synchronizations in place to make sure it is only initialized
    // once).

    BeanInfoManager ret = (BeanInfoManager) 
      mBeanInfoManagerByClass.get (pClass);
    if (ret == null) {
      ret = new BeanInfoManager (pClass);
      mBeanInfoManagerByClass.put (pClass, ret);
    }
    return ret;
  }

  //-------------------------------------
  /**
   *
   * Returns the BeanInfoProperty for the specified property in the
   * given class, or null if not found.
   **/
  public static BeanInfoProperty getBeanInfoProperty
    (Class pClass,
     String pPropertyName,
     Logger pLogger)
    throws ELException
  {
    return getBeanInfoManager (pClass).getProperty (pPropertyName, pLogger);
  }

  //-------------------------------------
  /**
   *
   * Returns the BeanInfoIndexedProperty for the specified property in
   * the given class, or null if not found.
   **/
  public static BeanInfoIndexedProperty getBeanInfoIndexedProperty
    (Class pClass,
     String pIndexedPropertyName,
     Logger pLogger)
    throws ELException
  {
    return getBeanInfoManager 
      (pClass).getIndexedProperty (pIndexedPropertyName, pLogger);
  }

  //-------------------------------------
  /**
   *
   * Makes sure that this class has been initialized, and synchronizes
   * the initialization if it's required.
   **/
  void checkInitialized (Logger pLogger)
    throws ELException
  {
    if (!mInitialized) {
      synchronized (this) {
	if (!mInitialized) {
	  initialize (pLogger);
	  mInitialized = true;
	}
      }
    }
  }

  //-------------------------------------
  /**
   *
   * Initializes by mapping property names to BeanInfoProperties
   **/
  void initialize (Logger pLogger)
    throws ELException
  {
    try {
      mBeanInfo = Introspector.getBeanInfo (mBeanClass);

      mPropertyByName = new HashMap ();
      mIndexedPropertyByName = new HashMap ();
      PropertyDescriptor [] pds = mBeanInfo.getPropertyDescriptors ();
      for (int i = 0; pds != null && i < pds.length; i++) {
	// Treat as both an indexed property and a normal property
	PropertyDescriptor pd = pds [i];
	if (pd instanceof IndexedPropertyDescriptor) {
	  IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
	  Method readMethod = getPublicMethod (ipd.getIndexedReadMethod ());
	  Method writeMethod = getPublicMethod (ipd.getIndexedWriteMethod ());
	  BeanInfoIndexedProperty property = new BeanInfoIndexedProperty
	    (readMethod,
	     writeMethod,
	     ipd);

	  mIndexedPropertyByName.put (ipd.getName (), property);
	}

	Method readMethod = getPublicMethod (pd.getReadMethod ());
	Method writeMethod = getPublicMethod (pd.getWriteMethod ());
	BeanInfoProperty property = new BeanInfoProperty
	  (readMethod,
	   writeMethod,
	   pd);

	mPropertyByName.put (pd.getName (), property);
      }

      mEventSetByName = new HashMap ();
      EventSetDescriptor [] esds = mBeanInfo.getEventSetDescriptors ();
      for (int i = 0; esds != null && i < esds.length; i++) {
	EventSetDescriptor esd = esds [i];
	mEventSetByName.put (esd.getName (), esd);
      }
    }
    catch (IntrospectionException exc) {
      if (pLogger.isLoggingWarning ()) {
	pLogger.logWarning
	  (Constants.EXCEPTION_GETTING_BEANINFO,
	   exc,
	   mBeanClass.getName ());
      }
    }
  }

  //-------------------------------------
  /**
   *
   * Returns the BeanInfo for the class
   **/
  BeanInfo getBeanInfo (Logger pLogger)
    throws ELException
  {
    checkInitialized (pLogger);
    return mBeanInfo;
  }

  //-------------------------------------
  /**
   *
   * Returns the BeanInfoProperty for the given property name, or null
   * if not found.
   **/
  public BeanInfoProperty getProperty (String pPropertyName,
				       Logger pLogger)
    throws ELException
  {
    checkInitialized (pLogger);
    return (BeanInfoProperty) mPropertyByName.get (pPropertyName);
  }

  //-------------------------------------
  /**
   *
   * Returns the BeanInfoIndexedProperty for the given property name,
   * or null if not found.
   **/
  public BeanInfoIndexedProperty getIndexedProperty 
    (String pIndexedPropertyName,
     Logger pLogger)
    throws ELException
  {
    checkInitialized (pLogger);
    return (BeanInfoIndexedProperty) 
      mIndexedPropertyByName.get (pIndexedPropertyName);
  }

  //-------------------------------------
  /**
   *
   * Returns the EventSetDescriptor for the given event set name, or
   * null if not found.
   **/
  public EventSetDescriptor getEventSet (String pEventSetName,
					 Logger pLogger)
    throws ELException
  {
    checkInitialized (pLogger);
    return (EventSetDescriptor) mEventSetByName.get (pEventSetName);
  }

  //-------------------------------------
  // Finding the public version of a method - if a PropertyDescriptor
  // is obtained for a non-public class that implements a public
  // interface, the read/write methods will be for the class, and
  // therefore inaccessible.  To correct this, a version of the same
  // method must be found in a superclass or interface.
  //-------------------------------------
  /**
   *
   * Returns a publicly-accessible version of the given method, by
   * searching for a public declaring class.
   **/
  static Method getPublicMethod (Method pMethod)
  {
    if (pMethod == null) {
      return null;
    }

    // See if the method is already available from a public class
    Class cl = pMethod.getDeclaringClass ();
    if (Modifier.isPublic (cl.getModifiers ())) {
      return pMethod;
    }

    // Otherwise, try to find a public class that declares the method
    Method ret = getPublicMethod (cl, pMethod);
    if (ret != null) {
      return ret;
    }
    else {
      return pMethod;
    }
  }

  //-------------------------------------
  /**
   *
   * If the given class is public and has a Method that declares the
   * same name and arguments as the given method, then that method is
   * returned.  Otherwise the superclass and interfaces are searched
   * recursively.
   **/
  static Method getPublicMethod (Class pClass,
				 Method pMethod)
  {
    // See if this is a public class declaring the method
    if (Modifier.isPublic (pClass.getModifiers ())) {
      try {
        Method m;
        try {
	  m = pClass.getDeclaredMethod (pMethod.getName (),
					     pMethod.getParameterTypes ());
        } catch (java.security.AccessControlException ex) {
	  // kludge to accommodate J2EE RI's default settings
	  // TODO: see if we can simply replace
          //       getDeclaredMethod() with getMethod() ...?
          m = pClass.getMethod(pMethod.getName (),
                                             pMethod.getParameterTypes ());
        }
	if (Modifier.isPublic (m.getModifiers ())) {
	  return m;
	}
      }
      catch (NoSuchMethodException exc) {}
    }

    // Search the interfaces
    {
      Class [] interfaces = pClass.getInterfaces ();
      if (interfaces != null) {
	for (int i = 0; i < interfaces.length; i++) {
	  Method m = getPublicMethod (interfaces [i], pMethod);
	  if (m != null) {
	    return m;
	  }
	}
      }
    }

    // Search the superclass
    {
      Class superclass = pClass.getSuperclass ();
      if (superclass != null) {
	Method m = getPublicMethod (superclass, pMethod);
	if (m != null) {
	  return m;
	}
      }
    }

    return null;
  }

  //-------------------------------------
}
 see
 * <http://wwwcommons-el-1.0-src/src/java/org/apache/commons/el/ArraySuffix.java010064400723740000012000000223750764210442600254450ustar00luehestaff00003710000056/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 

package org.apache.commons.el;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import javax.servlet.jsp.el.VariableResolver;
import javax.servlet.jsp.el.ELException;
import javax.servlet.jsp.el.FunctionMapper;

/**
 *
 * <p>Represents an operator that obtains a Map entry, an indexed
 * value, a property value, or an indexed property value of an object.
 * The following are the rules for evaluating this operator:
 *
 * <ul><pre>
 * Evaluating a[b] (assuming a.b == a["b"])
 *   a is null
 *     return null
 *   b is null
 *     return null
 *   a is Map
 *     !a.containsKey (b)
 *       return null
 *     a.get(b) == null
 *       return null
 *     otherwise
 *       return a.get(b)
 *   a is List or array
 *     coerce b to int (using coercion rules)
 *     coercion couldn't be performed
 *       error
 *     a.get(b) or Array.get(a, b) throws ArrayIndexOutOfBoundsException or IndexOutOfBoundsException
 *       return null
 *     a.get(b) or Array.get(a, b) throws other exception
 *       error
 *     return a.get(b) or Array.get(a, b)
 * 
 *   coerce b to String
 *   b is a readable property of a
 *     getter throws an exception
 *       error
 *     otherwise
 *       return result of getter call
 *
 *   otherwise
 *     error
 * </pre></ul>
 * 
 * @author Nathan Abramson - Art Technology Group
 * @author Shawn Bayern
 * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: luehe $
 **/

public class ArraySuffix
  extends ValueSuffix
{
  //-------------------------------------
  // Constants
  //-------------------------------------

  // Zero-argument array
  static Object [] sNoArgs = new Object [0];

  //-------------------------------------
  // Properties
  //-------------------------------------
  // property index

  Expression mIndex;
  public Expression getIndex ()
  { return mIndex; }
  public void setIndex (Expression pIndex)
  { mIndex = pIndex; }

  //-------------------------------------
  /**
   *
   * Constructor
   **/
  public ArraySuffix (Expression pIndex)
  {
    mIndex = pIndex;
  }

  //-------------------------------------
  /**
   *
   * Gets the value of the index
   **/
  Object evaluateIndex (VariableResolver pResolver,
			FunctionMapper functions,
			Logger pLogger)
    throws ELException
  {
    return mIndex.evaluate (pResolver, functions, pLogger);
  }

  //-------------------------------------
  /**
   *
   * Returns the operator symbol
   **/
  String getOperatorSymbol ()
  {
    return "[]";
  }

  //-------------------------------------
  // ValueSuffix methods
  //-------------------------------------
  /**
   *
   * Returns the expression in the expression language syntax
   **/
  public String getExpressionString ()
  {
    return "[" + mIndex.getExpressionString () + "]";
  }

  //-------------------------------------
  /**
   *
   * Evaluates the expression in the given context, operating on the
   * given value.
   **/
  public Object evaluate (Object pValue,
			  VariableResolver pResolver,
			  FunctionMapper functions,
			  Logger pLogger)
    throws ELException
  {
    Object indexVal;
    String indexStr;
    BeanInfoProperty property;
    BeanInfoIndexedProperty ixproperty;

    // Check for null value
    if (pValue == null) {
      if (pLogger.isLoggingWarning ()) {
	pLogger.logWarning 
	  (Constants.CANT_GET_INDEXED_VALUE_OF_NULL,
	   getOperatorSymbol ());
      }
      return null;
    }

    // Evaluate the index
    else if ((indexVal = evaluateIndex (pResolver, functions, pLogger))
								== null) {
      if (pLogger.isLoggingWarning ()) {
	pLogger.logWarning
	  (Constants.CANT_GET_NULL_INDEX,
	   getOperatorSymbol ());
      }
      return null;
    }

    // See if it's a Map
    else if (pValue instanceof Map) {
      Map val = (Map) pValue;
      return val.get (indexVal);
    }

    // See if it's a List or array
    else if (pValue instanceof List ||
	     pValue.getClass ().isArray ()) {
      Integer indexObj = Coercions.coerceToInteger (indexVal, pLogger);
      if (indexObj == null) {
	if (pLogger.isLoggingError ()) {
	  pLogger.logError
	    (Constants.BAD_INDEX_VALUE,
	     getOperatorSymbol (),
	     indexVal.getClass ().getName ());
	}
	return null;
      }
      else if (pValue instanceof List) {
	try {
	  return ((List) pValue).get (indexObj.intValue ());
	}
	catch (ArrayIndexOutOfBoundsException exc) {
	  if (pLogger.isLoggingWarning ()) {
	    pLogger.logWarning
	      (Constants.EXCEPTION_ACCESSING_LIST,
	       exc,
	       indexObj);
	  }
	  return null;
	}
	catch (IndexOutOfBoundsException exc) {
	  if (pLogger.isLoggingWarning ()) {
	    pLogger.logWarning
	      (Constants.EXCEPTION_ACCESSING_LIST,
	       exc,
	       indexObj);
	  }
	  return null;
	}
	catch (Exception exc) {
	  if (pLogger.isLoggingError ()) {
	    pLogger.logError
	      (Constants.EXCEPTION_ACCESSING_LIST,
	       exc,
	       indexObj);
	  }
	  return null;
	}
      }
      else {
	try {
	  return Array.get (pValue, indexObj.intValue ());
	}
	catch (ArrayIndexOutOfBoundsException exc) {
	  if (pLogger.isLoggingWarning ()) {
	    pLogger.logWarning
	      (Constants.EXCEPTION_ACCESSING_ARRAY,
	       exc,
	       indexObj);
	  }
	  return null;
	}
	catch (IndexOutOfBoundsException exc) {
	  if (pLogger.isLoggingWarning ()) {
	    pLogger.logWarning
	      (Constants.EXCEPTION_ACCESSING_ARRAY,
	       exc,
	       indexObj);
	  }
	  return null;
	}
	catch (Exception exc) {
	  if (pLogger.isLoggingError ()) {
	    pLogger.logError
	      (Constants.EXCEPTION_ACCESSING_ARRAY,
	       exc,
	       indexObj);
	  }
	  return null;
	}
      }
    }

    // Coerce to a String for property access

    else if ((indexStr = Coercions.coerceToString (indexVal, pLogger)) == 
	     null) {
      return null;
    }

    // Look for a JavaBean property
    else if ((property = BeanInfoManager.getBeanInfoProperty
	      (pValue.getClass (),
	       indexStr,
	       pLogger)) != null &&
	     property.getReadMethod () != null) {
      try {
	return property.getReadMethod ().invoke (pValue, sNoArgs);
      }
      catch (InvocationTargetException exc) {
	if (pLogger.isLoggingError ()) {
	  pLogger.logError
	    (Constants.ERROR_GETTING_PROPERTY,
	     exc.getTargetException (),
	     indexStr,
	     pValue.getClass ().getName ());
	}
	return null;
      }
      catch (Exception exc) {
	if (pLogger.isLoggingError ()) {
	  pLogger.logError
	    (Constants.ERROR_GETTING_PROPERTY,
	     exc,
	     indexStr,
	     pValue.getClass ().getName ());
	}
	return null;
      }
    }

    else {
      if (pLogger.isLoggingError ()) {
	pLogger.logError
	  (Constants.CANT_FIND_INDEX,
	   indexVal,
	   pValue.getClass ().getName (),
	   getOperatorSymbol ());
      }
      return null;
    }
  }

  //-------------------------------------
}
ollowing conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    noticcommons-el-1.0-src/src/java/org/apache/commons/el/BeanInfoIndexedProperty.java010064400723740000012000000105310761760370000277210ustar00luehestaff00003710000056/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 

package org.apache.commons.el;

import java.beans.IndexedPropertyDescriptor;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

/**
 *
 * <p>This contains the information for one indexed property in a
 * BeanInfo - IndexedPropertyDescriptor, read method, and write
 * method.  This class is necessary because the read/write methods in
 * the IndexedPropertyDescriptor may not be accessible if the bean
 * given to the introspector is not a public class.  In this case, a
 * publicly accessible version of the method must be found by
 * searching for a public superclass/interface that declares the
 * method (this searching is done by the BeanInfoManager).
 * 
 * @author Nathan Abramson - Art Technology Group
 * @version $Change: 181181 $$DateTime: 2001/06/26 09:55:09 $$Author: luehe $
 **/

public class BeanInfoIndexedProperty
{
  //-------------------------------------
  // Properties
  //-------------------------------------
  // property readMethod

  Method mReadMethod;
  public Method getReadMethod ()
  { return mReadMethod; }

  //-------------------------------------
  // property writeMethod

  Method mWriteMethod;
  public Method getWriteMethod ()
  { return mWriteMethod; }

  //-------------------------------------
  // property propertyDescriptor

  IndexedPropertyDescriptor mIndexedPropertyDescriptor;
  public IndexedPropertyDescriptor getIndexedPropertyDescriptor ()
  { return mIndexedPropertyDescriptor; }

  //-------------------------------------
  /**
   *
   * Constructor
   **/
  public BeanInfoIndexedProperty 
    (Method pReadMethod,
     Method pWriteMethod,
     IndexedPropertyDescriptor pIndexedPropertyDescriptor)
  {
    mReadMethod = pReadMethod;
    mWriteMethod = pWriteMethod;
    mIndexedPropertyDescriptor = pIndexedPropertyDescriptor;
  }

  //-------------------------------------
}
commons-el-1.0-src/src/java/org/apache/commons/el/BeanInfoProperty.java010064400723740000012000000103060761760370000264200ustar00luehestaff00003710000056/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 

package org.apache.commons.el;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

/**
 *
 * <p>This contains the information for one property in a BeanInfo -
 * PropertyDescriptor, read method, and write method.  This class is
 * necessary because the read/write methods in the PropertyDescriptor
 * may not be accessible if the bean given to the introspector is not
 * a public class.  In this case, a publicly accessible version of the
 * method must be found by searching for a public superclass/interface
 * that declares the method (this searching is done by the
 * BeanInfoManager).
 * 
 * @author Nathan Abramson - Art Technology Group
 * @version $Change: 181181 $$DateTime: 2001/06/26 09:55:09 $$Author: luehe $
 **/

public class BeanInfoProperty
{
  //-------------------------------------
  // Properties
  //-------------------------------------
  // property readMethod

  Method mReadMethod;
  public Method getReadMethod ()
  { return mReadMethod; }

  //-------------------------------------
  // property writeMethod

  Method mWriteMethod;
  public Method getWriteMethod ()
  { return mWriteMethod; }

  //-------------------------------------
  // property propertyDescriptor

  PropertyDescriptor mPropertyDescriptor;
  public PropertyDescriptor getPropertyDescriptor ()
  { return mPropertyDescriptor; }

  //-------------------------------------
  /**
   *
   * Constructor
   **/
  public BeanInfoProperty (Method pReadMethod,
			   Method pWriteMethod,
			   PropertyDescriptor pPropertyDescriptor)
  {
    mReadMethod = pReadMethod;
    mWriteMethod = pWriteMethod;
    mPropertyDescriptor = pPropertyDescriptor;
  }

  //-------------------------------------
}
hout
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    noticcommons-el-1.0-src/src/java/org/apache/commons/el/BinaryOperator.java010064400723740000012000000076530761760370000261450ustar00luehestaff00003710000056/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 

package org.apache.commons.el;

import javax.servlet.jsp.el.ELException;

/**
 *
 * <p>This is the superclass for all binary operators
 * 
 * @author Nathan Abramson - Art Technology Group
 * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: luehe $
 **/

public abstract class BinaryOperator
{
  //-------------------------------------
  /**
   *
   * Constructor
   **/
  public BinaryOperator ()
  {
  }

  //-------------------------------------
  // Expression methods
  //-------------------------------------
  /**
   *
   * Returns the symbol representing the operator
   **/
  public abstract String getOperatorSymbol ();

  //-------------------------------------
  /**
   *
   * Applies the operator to the given pair of values
   **/
  public abstract Object apply (Object pLeft,
				Object pRight,
				Logger pLogger)
    throws ELException;

  //-------------------------------------
  /**
   *
   * Returns true if evaluation is necessary given the specified Left
   * value.  The And/OrOperators make use of this
   **/
  public boolean shouldEvaluate (Object pLeft)
  {
    return true;
  }

  //-------------------------------------
  /**
   *
   * Returns true if the operator expects its arguments to be coerced
   * to Booleans.  The And/Or operators set this to true.
   **/
  public boolean shouldCoerceToBoolean ()
  {
    return false;
  }

  //-------------------------------------
}
commons-el-1.0-src/src/java/org/apache/commons/el/BinaryOperatorExpression.java010064400723740000012000000133240764210442600302140ustar00luehestaff00003710000056/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 

package org.apache.commons.el;

import java.util.List;
import java.util.Map;
import javax.servlet.jsp.el.ELException;
import javax.servlet.jsp.el.VariableResolver;
import javax.servlet.jsp.el.FunctionMapper;

/**
 *
 * <p>An expression representing a binary operator on a value
 * 
 * @author Nathan Abramson - Art Technology Group
 * @author Shawn Bayern
 * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: luehe $
 **/

public class BinaryOperatorExpression
  extends Expression
{
  //-------------------------------------
  // Properties
  //-------------------------------------
  // property expression

  Expression mExpression;
  public Expression getExpression ()
  { return mExpression; }
  public void setExpression (Expression pExpression)
  { mExpression = pExpression; }

  //-------------------------------------
  // property operators

  List mOperators;
  public List getOperators ()
  { return mOperators; }
  public void setOperators (List pOperators)
  { mOperators = pOperators; }

  //-------------------------------------
  // property expressions

  List mExpressions;
  public List getExpressions ()
  { return mExpressions; }
  public void setExpressions (List pExpressions)
  { mExpressions = pExpressions; }

  //-------------------------------------
  /**
   *
   * Constructor
   **/
  public BinaryOperatorExpression (Expression pExpression,
				   List pOperators,
				   List pExpressions)
  {
    mExpression = pExpression;
    mOperators = pOperators;
    mExpressions = pExpressions;
  }

  //-------------------------------------
  // Expression methods
  //-------------------------------------
  /**
   *
   * Returns the expression in the expression language syntax
   **/
  public String getExpressionString ()
  {
    StringBuffer buf = new StringBuffer ();
    buf.append ("(");
    buf.append (mExpression.getExpressionString ());
    for (int i = 0; i < mOperators.size (); i++) {
      BinaryOperator operator = (BinaryOperator) mOperators.get (i);
      Expression expression = (Expression) mExpressions.get (i);
      buf.append (" ");
      buf.append (operator.getOperatorSymbol ());
      buf.append (" ");
      buf.append (expression.getExpressionString ());
    }
    buf.append (")");

    return buf.toString ();
  }

  //-------------------------------------
  /**
   *
   * Evaluates to the literal value
   **/
  public Object evaluate (VariableResolver pResolver,
			  FunctionMapper functions,
			  Logger pLogger)
    throws ELException
  {
    Object value = mExpression.evaluate (pResolver, functions, pLogger);
    for (int i = 0; i < mOperators.size (); i++) {
      BinaryOperator operator = (BinaryOperator) mOperators.get (i);

      // For the And/Or operators, we need to coerce to a boolean
      // before testing if we shouldEvaluate
      if (operator.shouldCoerceToBoolean ()) {
	value = Coercions.coerceToBoolean (value, pLogger);
      }

      if (operator.shouldEvaluate (value)) {
	Expression expression = (Expression) mExpressions.get (i);
	Object nextValue = expression.evaluate (pResolver,
						functions,
						pLogger);

	value = operator.apply (value, nextValue, pLogger);
      }
    }
    return value;
  }

  //-------------------------------------
}
ior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``commons-el-1.0-src/src/java/org/apache/commons/el/BooleanLiteral.java010064400723740000012000000074550761760370000261010ustar00luehestaff00003710000056/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 

package org.apache.commons.el;

/**
 *
 * <p>An expression representing a boolean literal value
 * 
 * @author Nathan Abramson - Art Technology Group
 * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: luehe $
 **/

public class BooleanLiteral
  extends Literal
{
  //-------------------------------------
  // Member variables
  //-------------------------------------

  public static final BooleanLiteral TRUE = new BooleanLiteral ("true");
  public static final BooleanLiteral FALSE = new BooleanLiteral ("false");

  //-------------------------------------
  /**
   *
   * Constructor
   **/
  public BooleanLiteral (String pToken)
  {
    super (getValueFromToken (pToken));
  }

  //-------------------------------------
  /**
   *
   * Parses the given token into the literal value
   **/
  static Object getValueFromToken (String pToken)
  {
    return
      ("true".equals (pToken)) ?
      Boolean.TRUE :
      Boolean.FALSE;
  }

  //-------------------------------------
  // Expression methods
  //-------------------------------------
  /**
   *
   * Returns the expression in the expression language syntax
   **/
  public String getExpressionString ()
  {
    return (getValue () == Boolean.TRUE) ? "true" : "false";
  }

  //-------------------------------------
}
commons-el-1.0-src/src/java/org/apache/commons/el/Coercions.java010064400723740000012000001060350767367360200251350ustar00luehestaff00003710000056/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 

package org.apache.commons.el;

import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.math.BigInteger;
import java.math.BigDecimal;
import javax.servlet.jsp.el.ELException;

/**
 *
 * <p>This class contains the logic for coercing data types before
 * operators are applied to them.
 *
 * <p>The following is the list of rules applied for various type
 * conversions.
 *
 * <ul><pre>
 * Applying arithmetic operator
 *   Binary operator - A {+,-,*} B
 *     if A and B are null
 *       return 0
 *     if A or B is BigDecimal, coerce both to BigDecimal and then:
 *       if operator is +, return <code>A.add(B)</code>
 *       if operator is -, return <code>A.subtract(B)</code>
 *       if operator is *, return <code>A.multiply(B)</code>
 *     if A or B is Float, Double, or String containing ".", "e", or "E"
 *       if A or B is BigInteger, coerce both A and B to BigDecimal and apply operator
 *       coerce both A and B to Double and apply operator
 *     if A or B is BigInteger, coerce both to BigInteger and then:
 *       if operator is +, return <code>A.add(B)</code>
 *       if operator is -, return <code>A.subtract(B)</code>
 *       if operator is *, return <code>A.multiply(B)</code>
 *     otherwise
 *       coerce both A and B to Long
 *       apply operator
 *     if operator results in exception (such as divide by 0), error
 * 
 *   Binary operator - A {/,div} B
 *     if A and B are null
 *       return 0
 *     if A or B is a BigDecimal or BigInteger, coerce both to BigDecimal and
 *      return <code>A.divide(B, BigDecimal.ROUND_HALF_UP)</code>
 *     otherwise
 *       coerce both A and B to Double
 *       apply operator
 *     if operator results in exception (such as divide by 0), error
 * 
 *   Binary operator - A {%,mod} B
 *     if A and B are null
 *       return 0
 *     if A or B is BigDecimal, Float, Double, or String containing ".", "e" or "E"
 *       coerce both to Double
 *       apply operator
 *     if A or B is BigInteger, coerce both to BigInteger and return
 *      <code>A.remainder(B)</code>
 *     otherwise
 *       coerce both A and B to Long
 *       apply operator
 *     if operator results in exception (such as divide by 0), error
 * 
 *   Unary minus operator - -A
 *     if A is null
 *       return 0
 *     if A is BigInteger or BigDecimal, return <code>A.negate()</code>
 *     if A is String
 *       if A contains ".", "e", or "E"
 *         coerce to Double, apply operator
 *       otherwise
 *         coerce to a Long and apply operator
 *     if A is Byte,Short,Integer,Long,Float,Double
 *       retain type, apply operator
 *     if operator results in exception, error
 *     otherwise
 *       error
 *
 * Applying "empty" operator - empty A
 *   if A is null
 *     return true
 *   if A is zero-length String
 *     return true
 *   if A is zero-length array
 *     return true
 *   if A is List and ((List) A).isEmpty()
 *     return true
 *   if A is Map and ((Map) A).isEmpty()
 *     return true
 *   if A is Collection an ((Collection) A).isEmpty()
 *     return true
 *   otherwise
 *     return false
 * 
 * Applying logical operators
 *   Binary operator - A {and,or} B
 *     coerce both A and B to Boolean, apply operator
 *   NOTE - operator stops as soon as expression can be determined, i.e.,
 *     A and B and C and D - if B is false, then only A and B is evaluated
 *   Unary not operator - not A
 *     coerce A to Boolean, apply operator
 * 
 * Applying relational operator
 *   A {<,>,<=,>=,lt,gt,lte,gte} B
 *     if A==B
 *       if operator is >= or <=
 *         return true
 *       otherwise
 *         return false
 *     if A or B is null
 *       return false
 *     if A or B is BigDecimal, coerce both A and B to BigDecimal and use the
 *      return value of <code>A.compareTo(B)</code>
 *     if A or B is Float or Double
 *       coerce both A and B to Double
 *       apply operator
 *     if A or B is BigInteger, coerce both A and B to BigInteger and use the
 *      return value of <code>A.compareTo(B)</code>
 *     if A or B is Byte,Short,Character,Integer,Long
 *       coerce both A and B to Long
 *       apply operator
 *     if A or B is String
 *       coerce both A and B to String, compare lexically
 *     if A is Comparable
 *       if A.compareTo (B) throws exception
 *         error
 *       otherwise
 *         use result of A.compareTo(B)
 *     if B is Comparable
 *       if B.compareTo (A) throws exception
 *         error
 *       otherwise
 *         use result of B.compareTo(A)
 *     otherwise
 *       error
 * 
 * Applying equality operator
 *   A {==,!=} B
 *     if A==B
 *       apply operator
 *     if A or B is null
 *       return false for ==, true for !=
 *     if A or B is BigDecimal, coerce both A and B to BigDecimal and then:
 *       if operator is == or eq, return <code>A.equals(B)</code>
 *       if operator is != or ne, return <code>!A.equals(B)</code>
 *     if A or B is Float or Double
 *       coerce both A and B to Double
 *       apply operator
 *     if A or B is BigInteger, coerce both A and B to BigInteger and then:
 *       if operator is == or eq, return <code>A.equals(B)</code>
 *       if operator is != or ne, return <code>!A.equals(B)</code>
 *     if A or B is Byte,Short,Character,Integer,Long
 *       coerce both A and B to Long
 *       apply operator
 *     if A or B is Boolean
 *       coerce both A and B to Boolean
 *       apply operator
 *     if A or B is String
 *       coerce both A and B to String, compare lexically
 *     otherwise
 *       if an error occurs while calling A.equals(B)
 *         error
 *       apply operator to result of A.equals(B)
 * 
 * coercions
 * 
 *   coerce A to String
 *     A is String
 *       return A
 *     A is null
 *       return ""
 *     A.toString throws exception
 *       error
 *     otherwise
 *       return A.toString
 * 
 *   coerce A to Number type N
 *     A is null or ""
 *       return 0
 *     A is Character
 *       convert to short, apply following rules
 *     A is Boolean
 *       error
 *     A is Number type N
 *       return A
 *     A is Number, coerce quietly to type N using the following algorithm
 *         If N is BigInteger
 *             If A is BigDecimal, return <code>A.toBigInteger()</code>
 *             Otherwise, return <code>BigInteger.valueOf(A.longValue())</code>
 *        if N is BigDecimal
 *             If A is a BigInteger, return <code>new BigDecimal(A)</code>
 *             Otherwise, return <code>new BigDecimal(A.doubleValue())</code>
 *        If N is Byte, return <code>new Byte(A.byteValue())</code>
 *        If N is Short, return <code>new Short(A.shortValue())</code>
 *        If N is Integer, return <code>new Integer(A.integerValue())</code>
 *        If N is Long, return <code>new Long(A.longValue())</code>
 *        If N is Float, return <code>new Float(A.floatValue())</code>
 *        If N is Double, return <code>new Double(A.doubleValue())</code>
 *        otherwise ERROR
 *     A is String
 *       If N is BigDecimal then:
 *            If <code>new BigDecimal(A)</code> throws an exception then ERROR
 *            Otherwise, return <code>new BigDecimal(A)</code>
 *       If N is BigInteger then:
 *            If <code>new BigInteger(A)</code> throws an exception, then ERROR
 *            Otherwise, return <code>new BigInteger(A)</code>
 *       new <code>N.valueOf(A)</code> throws exception
 *         error
 *       return <code>N.valueOf(A)</code>
 *     otherwise
 *       error
 * 
 *   coerce A to Character should be
 *     A is null or ""
 *       return (char) 0
 *     A is Character
 *       return A
 *     A is Boolean
 *       error
 *     A is Number with less precision than short
 *       coerce quietly - return (char) A
 *     A is Number with greater precision than short
 *       coerce quietly - return (char) A
 *     A is String
 *       return A.charAt (0)
 *     otherwise
 *       error
 * 
 *   coerce A to Boolean
 *     A is null or ""
 *       return false
 *     A is Boolean
 *       return A
 *     A is String
 *       Boolean.valueOf(A) throws exception
 *         error
 *       return Boolean.valueOf(A)
 *     otherwise
 *       error
 * 
 *   coerce A to any other type T
 *     A is null
 *       return null
 *     A is assignable to T
 *       coerce quietly
 *     A is String
 *       T has no PropertyEditor
 *         if A is "", return null
 *         otherwise error
 *       T's PropertyEditor throws exception
 *         if A is "", return null
 *         otherwise error
 *       otherwise
 *         apply T's PropertyEditor
 *     otherwise
 *       error
 * </pre></ul>
 *
 * @author Nathan Abramson - Art Technology Group
 * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: luehe $
 **/

public class Coercions
{
   private static final Number ZERO = new Integer(0);
  //-------------------------------------
  /**
   *
   * Coerces the given value to the specified class.
   **/
  public static Object coerce (Object pValue,
			       Class pClass,
			       Logger pLogger)
    throws ELException
  {
    if (pClass == String.class) {
      return coerceToString (pValue, pLogger);
    }
    else if (isNumberClass (pClass)) {
      return coerceToPrimitiveNumber (pValue, pClass, pLogger);
    }
    else if (pClass == Character.class ||
	     pClass == Character.TYPE) {
      return coerceToCharacter (pValue, pLogger);
    }
    else if (pClass == Boolean.class ||
	     pClass == Boolean.TYPE) {
      return coerceToBoolean (pValue, pLogger);
    }
    else {
      return coerceToObject (pValue, pClass, pLogger);
    }
  }

  //-------------------------------------
  /**
   *
   * Returns true if the given class is Byte, Short, Integer, Long,
   * Float, Double, BigInteger, or BigDecimal
   **/
  static boolean isNumberClass (Class pClass)
  {
    return
      pClass == Byte.class ||
      pClass == Byte.TYPE ||
      pClass == Short.class ||
      pClass == Short.TYPE ||
      pClass == Integer.class ||
      pClass == Integer.TYPE ||
      pClass == Long.class ||
      pClass == Long.TYPE ||
      pClass == Float.class ||
      pClass == Float.TYPE ||
      pClass == Double.class ||
      pClass == Double.TYPE ||
      pClass == BigInteger.class ||
      pClass == BigDecimal.class;
  }

  //-------------------------------------
  /**
   *
   * Coerces the specified value to a String
   **/
  public static String coerceToString (Object pValue,
				       Logger pLogger)
    throws ELException
  {
    if (pValue == null) {
      return "";
    }
    else if (pValue instanceof String) {
      return (String) pValue;
    }
    else {
      try {
	return pValue.toString ();
      }
      catch (Exception exc) {
	if (pLogger.isLoggingError ()) {
	  pLogger.logError (Constants.TOSTRING_EXCEPTION,
			    exc,
			    pValue.getClass ().getName ());
	}
	return "";
      }
    }
  }

  //-------------------------------------
  /**
   *
   * Coerces a value to the given primitive number class
   **/
  public static Number coerceToPrimitiveNumber (Object pValue,
						Class pClass,
						Logger pLogger)
    throws ELException
  {
    if (pValue == null ||
	"".equals (pValue)) {
      return coerceToPrimitiveNumber (ZERO, pClass);
    }
    else if (pValue instanceof Character) {
      char val = ((Character) pValue).charValue ();
      return coerceToPrimitiveNumber (new Short((short) val), pClass);
    }
    else if (pValue instanceof Boolean) {
      if (pLogger.isLoggingError ()) {
	pLogger.logError (Constants.BOOLEAN_TO_NUMBER,
			  pValue,
			  pClass.getName ());
      }
      return coerceToPrimitiveNumber (ZERO, pClass);
    }
    else if (pValue.getClass () == pClass) {
      return (Number) pValue;
    }
    else if (pValue instanceof Number) {
      return coerceToPrimitiveNumber ((Number) pValue, pClass);
    }
    else if (pValue instanceof String) {
      try {
	return coerceToPrimitiveNumber ((String) pValue, pClass);
      }
      catch (Exception exc) {
	if (pLogger.isLoggingError ()) {
	  pLogger.logError
	    (Constants.STRING_TO_NUMBER_EXCEPTION,
	     (String) pValue,
	     pClass.getName ());
	}
	return coerceToPrimitiveNumber (ZERO, pClass);
      }
    }
    else {
      if (pLogger.isLoggingError ()) {
	pLogger.logError
	  (Constants.COERCE_TO_NUMBER,
	   pValue.getClass ().getName (),
	   pClass.getName ());
      }
      return coerceToPrimitiveNumber (0, pClass);
    }
  }

  //-------------------------------------
  /**
   *
   * Coerces a value to an Integer, returning null if the coercion
   * isn't possible.
   **/
  public static Integer coerceToInteger (Object pValue,
					 Logger pLogger)
    throws ELException
  {
    if (pValue == null) {
      return null;
    }
    else if (pValue instanceof Character) {
      return PrimitiveObjects.getInteger 
	((int) (((Character) pValue).charValue ()));
    }
    else if (pValue instanceof Boolean) {
      if (pLogger.isLoggingWarning ()) {
	pLogger.logWarning (Constants.BOOLEAN_TO_NUMBER,
			    pValue,
			    Integer.class.getName ());
      }
      return PrimitiveObjects.getInteger
	(((Boolean) pValue).booleanValue () ? 1 : 0);
    }
    else if (pValue instanceof Integer) {
      return (Integer) pValue;
    }
    else if (pValue instanceof Number) {
      return PrimitiveObjects.getInteger (((Number) pValue).intValue ());
    }
    else if (pValue instanceof String) {
      try {
	return Integer.valueOf ((String) pValue);
      }
      catch (Exception exc) {
	if (pLogger.isLoggingWarning ()) {
	  pLogger.logWarning
	    (Constants.STRING_TO_NUMBER_EXCEPTION,
	     (String) pValue,
	     Integer.class.getName ());
	}
	return null;
      }
    }
    else {
      if (pLogger.isLoggingWarning ()) {
	pLogger.logWarning
	  (Constants.COERCE_TO_NUMBER,
	   pValue.getClass ().getName (),
	   Integer.class.getName ());
      }
      return null;
    }
  }

  //-------------------------------------
  /**
   *
   * Coerces a long to the given primitive number class
   **/
  static Number coerceToPrimitiveNumber (long pValue,
					 Class pClass)
    throws ELException
  {
    if (pClass == Byte.class || pClass == Byte.TYPE) {
      return PrimitiveObjects.getByte ((byte) pValue);
    }
    else if (pClass == Short.class || pClass == Short.TYPE) {
      return PrimitiveObjects.getShort ((short) pValue);
    }
    else if (pClass == Integer.class || pClass == Integer.TYPE) {
      return PrimitiveObjects.getInteger ((int) pValue);
    }
    else if (pClass == Long.class || pClass == Long.TYPE) {
      return PrimitiveObjects.getLong (pValue);
    }
    else if (pClass == Float.class || pClass == Float.TYPE) {
      return PrimitiveObjects.getFloat ((float) pValue);
    }
    else if (pClass == Double.class || pClass == Double.TYPE) {
      return PrimitiveObjects.getDouble ((double) pValue);
    }
    else {
      return PrimitiveObjects.getInteger (0);
    }
  }

  //-------------------------------------
  /**
   *
   * Coerces a double to the given primitive number class
   **/
  static Number coerceToPrimitiveNumber (double pValue,
					 Class pClass)
    throws ELException
  {
    if (pClass == Byte.class || pClass == Byte.TYPE) {
      return PrimitiveObjects.getByte ((byte) pValue);
    }
    else if (pClass == Short.class || pClass == Short.TYPE) {
      return PrimitiveObjects.getShort ((short) pValue);
    }
    else if (pClass == Integer.class || pClass == Integer.TYPE) {
      return PrimitiveObjects.getInteger ((int) pValue);
    }
    else if (pClass == Long.class || pClass == Long.TYPE) {
      return PrimitiveObjects.getLong ((long) pValue);
    }
    else if (pClass == Float.class || pClass == Float.TYPE) {
      return PrimitiveObjects.getFloat ((float) pValue);
    }
    else if (pClass == Double.class || pClass == Double.TYPE) {
      return PrimitiveObjects.getDouble (pValue);
    }
    else {
      return PrimitiveObjects.getInteger (0);
    }
  }

  //-------------------------------------
  /**
   *
   * Coerces a Number to the given primitive number class
   **/
  static Number coerceToPrimitiveNumber (Number pValue,
					 Class pClass)
    throws ELException
  {
    if (pClass == Byte.class || pClass == Byte.TYPE) {
      return PrimitiveObjects.getByte (pValue.byteValue ());
    }
    else if (pClass == Short.class || pClass == Short.TYPE) {
      return PrimitiveObjects.getShort (pValue.shortValue ());
    }
    else if (pClass == Integer.class || pClass == Integer.TYPE) {
      return PrimitiveObjects.getInteger (pValue.intValue ());
    }
    else if (pClass == Long.class || pClass == Long.TYPE) {
      return PrimitiveObjects.getLong (pValue.longValue ());
    }
    else if (pClass == Float.class || pClass == Float.TYPE) {
      return PrimitiveObjects.getFloat (pValue.floatValue ());
    }
    else if (pClass == Double.class || pClass == Double.TYPE) {
      return PrimitiveObjects.getDouble (pValue.doubleValue ());
    }
    else if (pClass == BigInteger.class) {
        if (pValue instanceof BigDecimal)
            return ((BigDecimal) pValue).toBigInteger();
        else
            return BigInteger.valueOf(pValue.longValue());
    }
    else if (pClass == BigDecimal.class) {
        if (pValue instanceof BigInteger)
            return new BigDecimal((BigInteger) pValue);
        else
            return new BigDecimal(pValue.doubleValue());
    }
    else {
      return PrimitiveObjects.getInteger (0);
    }
  }

  //-------------------------------------
  /**
   *
   * Coerces a String to the given primitive number class
   **/
  static Number coerceToPrimitiveNumber (String pValue,
					 Class pClass)
    throws ELException
  {
    if (pClass == Byte.class || pClass == Byte.TYPE) {
      return Byte.valueOf (pValue);
    }
    else if (pClass == Short.class || pClass == Short.TYPE) {
      return Short.valueOf (pValue);
    }
    else if (pClass == Integer.class || pClass == Integer.TYPE) {
      return Integer.valueOf (pValue);
    }
    else if (pClass == Long.class || pClass == Long.TYPE) {
      return Long.valueOf (pValue);
    }
    else if (pClass == Float.class || pClass == Float.TYPE) {
      return Float.valueOf (pValue);
    }
    else if (pClass == Double.class || pClass == Double.TYPE) {
      return Double.valueOf (pValue);
    }
    else if (pClass == BigInteger.class) {
        return new BigInteger(pValue);
    }
    else if (pClass == BigDecimal.class) {
        return new BigDecimal(pValue);
    }
    else {
      return PrimitiveObjects.getInteger (0);
    }
  }

  //-------------------------------------
  /**
   *
   * Coerces a value to a Character
   **/
  public static Character coerceToCharacter (Object pValue,
					     Logger pLogger)
    throws ELException
  {
    if (pValue == null ||
	"".equals (pValue)) {
      return PrimitiveObjects.getCharacter ((char) 0);
    }
    else if (pValue instanceof Character) {
      return (Character) pValue;
    }
    else if (pValue instanceof Boolean) {
      if (pLogger.isLoggingError ()) {
	pLogger.logError (Constants.BOOLEAN_TO_CHARACTER, pValue);
      }
      return PrimitiveObjects.getCharacter ((char) 0);
    }
    else if (pValue instanceof Number) {
      return PrimitiveObjects.getCharacter 
	((char) ((Number) pValue).shortValue ());
    }
    else if (pValue instanceof String) {
      String str = (String) pValue;
      return PrimitiveObjects.getCharacter (str.charAt (0));
    }
    else {
      if (pLogger.isLoggingError ()) {
	pLogger.logError
	  (Constants.COERCE_TO_CHARACTER,
	   pValue.getClass ().getName ());
      }
      return PrimitiveObjects.getCharacter ((char) 0);
    }
  }

  //-------------------------------------
  /**
   *
   * Coerces a value to a Boolean
   **/
  public static Boolean coerceToBoolean (Object pValue,
					 Logger pLogger)
    throws ELException
  {
    if (pValue == null ||
	"".equals (pValue)) {
      return Boolean.FALSE;
    }
    else if (pValue instanceof Boolean) {
      return (Boolean) pValue;
    }
    else if (pValue instanceof String) {
      String str = (String) pValue;
      try {
	return Boolean.valueOf (str);
      }
      catch (Exception exc) {
	if (pLogger.isLoggingError ()) {
	  pLogger.logError
	    (Constants.STRING_TO_BOOLEAN,
	     exc,
	     (String) pValue);
	}
	return Boolean.FALSE;
      }
    }
    else {
      if (pLogger.isLoggingError ()) {
	pLogger.logError
	  (Constants.COERCE_TO_BOOLEAN,
	   pValue.getClass ().getName ());
      }
      return Boolean.TRUE;
    }
  }

  //-------------------------------------
  /**
   *
   * Coerces a value to the specified Class that is not covered by any
   * of the above cases
   **/
  public static Object coerceToObject (Object pValue,
				       Class pClass,
				       Logger pLogger)
    throws ELException
  {
    if (pValue == null) {
      return null;
    }
    else if (pClass.isAssignableFrom (pValue.getClass ())) {
      return pValue;
    }
    else if (pValue instanceof String) {
      String str = (String) pValue;
      PropertyEditor pe = PropertyEditorManager.findEditor (pClass);
      if (pe == null) {
	if ("".equals (str)) {
	  return null;
	}
	else {
	  if (pLogger.isLoggingError ()) {
	    pLogger.logError
	      (Constants.NO_PROPERTY_EDITOR,
	       str,
	       pClass.getName ());
	  }
	  return null;
	}
      }
      try {
	pe.setAsText (str);
	return pe.getValue ();
      }
      catch (IllegalArgumentException exc) {
	if ("".equals (str)) {
	  return null;
	}
	else {
	  if (pLogger.isLoggingError ()) {
	    pLogger.logError
	      (Constants.PROPERTY_EDITOR_ERROR,
	       exc,
	       pValue,
	       pClass.getName ());
	  }
	  return null;
	}
      }
    }
    else {
      if (pLogger.isLoggingError ()) {
	pLogger.logError
	  (Constants.COERCE_TO_OBJECT,
	   pValue.getClass ().getName (),
	   pClass.getName ());
      }
      return null;
    }
  }

  //-------------------------------------
  // Applying operators
  //-------------------------------------
  /**
   *
   * Performs all of the necessary type conversions, then calls on the
   * appropriate operator.
   **/
  public static Object applyArithmeticOperator 
    (Object pLeft,
     Object pRight,
     ArithmeticOperator pOperator,
     Logger pLogger)
    throws ELException
  {
    if (pLeft == null &&
	pRight == null) {
      if (pLogger.isLoggingWarning ()) {
	pLogger.logWarning
	  (Constants.ARITH_OP_NULL,
	   pOperator.getOperatorSymbol ());
      }
      return PrimitiveObjects.getInteger (0);
    }

    else if (isBigDecimal(pLeft) || isBigDecimal(pRight)) {
        BigDecimal left = (BigDecimal)
            coerceToPrimitiveNumber(pLeft, BigDecimal.class, pLogger);
        BigDecimal right = (BigDecimal)
            coerceToPrimitiveNumber(pRight, BigDecimal.class, pLogger);
        return pOperator.apply(left, right);
    }

    else if (isFloatingPointType(pLeft) ||
        isFloatingPointType(pRight) ||
        isFloatingPointString(pLeft) ||
        isFloatingPointString(pRight)) {
        if (isBigInteger(pLeft) || isBigInteger(pRight)) {
            BigDecimal left = (BigDecimal)
                coerceToPrimitiveNumber(pLeft, BigDecimal.class, pLogger);
            BigDecimal right = (BigDecimal)
                coerceToPrimitiveNumber(pRight, BigDecimal.class, pLogger);
            return pOperator.apply(left, right);
        } else {
            double left =
                coerceToPrimitiveNumber(pLeft, Double.class, pLogger).
                doubleValue();
            double right =
                coerceToPrimitiveNumber(pRight, Double.class, pLogger).
                doubleValue();
            return
                PrimitiveObjects.getDouble(pOperator.apply(left, right));
        }
    }

    else if (isBigInteger(pLeft) || isBigInteger(pRight)) {
        BigInteger left = (BigInteger)
            coerceToPrimitiveNumber(pLeft, BigInteger.class, pLogger);
        BigInteger right = (BigInteger)
            coerceToPrimitiveNumber(pRight, BigInteger.class, pLogger);
        return pOperator.apply(left, right);
    }

    else {
      long left =
	coerceToPrimitiveNumber (pLeft, Long.class, pLogger).
	longValue ();
      long right =
	coerceToPrimitiveNumber (pRight, Long.class, pLogger).
	longValue ();
      return
	PrimitiveObjects.getLong (pOperator.apply (left, right));
    }
  }

  //-------------------------------------
  /**
   *
   * Performs all of the necessary type conversions, then calls on the
   * appropriate operator.
   **/
  public static Object applyRelationalOperator 
    (Object pLeft,
     Object pRight,
     RelationalOperator pOperator,
     Logger pLogger)
    throws ELException
  {
    if (isBigDecimal(pLeft) || isBigDecimal(pRight)) {
        BigDecimal left = (BigDecimal)
            coerceToPrimitiveNumber(pLeft, BigDecimal.class, pLogger);
        BigDecimal right = (BigDecimal)
            coerceToPrimitiveNumber(pRight, BigDecimal.class, pLogger);
        return PrimitiveObjects.getBoolean(pOperator.apply(left, right));
    }

    else if (isFloatingPointType (pLeft) ||
	isFloatingPointType (pRight)) {
      double left =
	coerceToPrimitiveNumber (pLeft, Double.class, pLogger).
	doubleValue ();
      double right =
	coerceToPrimitiveNumber (pRight, Double.class, pLogger).
	doubleValue ();
      return 
	PrimitiveObjects.getBoolean (pOperator.apply (left, right));
    }

    else if (isBigInteger(pLeft) || isBigInteger(pRight)) {
        BigInteger left = (BigInteger)
            coerceToPrimitiveNumber(pLeft, BigInteger.class, pLogger);
        BigInteger right = (BigInteger)
            coerceToPrimitiveNumber(pRight, BigInteger.class, pLogger);
        return PrimitiveObjects.getBoolean(pOperator.apply(left, right));
    }

    else if (isIntegerType (pLeft) ||
	     isIntegerType (pRight)) {
      long left =
	coerceToPrimitiveNumber (pLeft, Long.class, pLogger).
	longValue ();
      long right =
	coerceToPrimitiveNumber (pRight, Long.class, pLogger).
	longValue ();
      return
	PrimitiveObjects.getBoolean (pOperator.apply (left, right));
    }

    else if (pLeft instanceof String ||
	     pRight instanceof String) {
      String left = coerceToString (pLeft, pLogger);
      String right = coerceToString (pRight, pLogger);
      return
	PrimitiveObjects.getBoolean (pOperator.apply (left, right));
    }

    else if (pLeft instanceof Comparable) {
      try {
	int result = ((Comparable) pLeft).compareTo (pRight);
	return
	  PrimitiveObjects.getBoolean 
	  (pOperator.apply (result, -result));
      }
      catch (Exception exc) {
	if (pLogger.isLoggingError ()) {
	  pLogger.logError
	    (Constants.COMPARABLE_ERROR,
	     exc,
	     pLeft.getClass ().getName (),
	     (pRight == null) ? "null" : pRight.getClass ().getName (),
	     pOperator.getOperatorSymbol ());
	}
	return Boolean.FALSE;
      }
    }

    else if (pRight instanceof Comparable) {
      try {
	int result = ((Comparable) pRight).compareTo (pLeft);
	return
	  PrimitiveObjects.getBoolean 
	  (pOperator.apply (-result, result));
      }
      catch (Exception exc) {
	if (pLogger.isLoggingError ()) {
	  pLogger.logError
	    (Constants.COMPARABLE_ERROR,
	     exc,
	     pRight.getClass ().getName (),
	     (pLeft == null) ? "null" : pLeft.getClass ().getName (),
	     pOperator.getOperatorSymbol ());
	}
	return Boolean.FALSE;
      }
    }

    else {
      if (pLogger.isLoggingError ()) {
	pLogger.logError
	  (Constants.ARITH_OP_BAD_TYPE,
	   pOperator.getOperatorSymbol (),
	   pLeft.getClass ().getName (),
	   pRight.getClass ().getName ());
      }
      return Boolean.FALSE;
    }
  }

  //-------------------------------------
  /**
   *
   * Performs all of the necessary type conversions, then calls on the
   * appropriate operator.
   **/
  public static Object applyEqualityOperator 
    (Object pLeft,
     Object pRight,
     EqualityOperator pOperator,
     Logger pLogger)
    throws ELException
  {
    if (pLeft == pRight) {
      return PrimitiveObjects.getBoolean (pOperator.apply (true, pLogger));
    }

    else if (pLeft == null ||
	     pRight == null) {
      return PrimitiveObjects.getBoolean (pOperator.apply (false, pLogger));
    }

    else if (isBigDecimal(pLeft) || isBigDecimal(pRight)) {
        BigDecimal left = (BigDecimal)
            coerceToPrimitiveNumber(pLeft, BigDecimal.class, pLogger);
        BigDecimal right = (BigDecimal)
            coerceToPrimitiveNumber(pRight, BigDecimal.class, pLogger);
        return PrimitiveObjects.getBoolean(pOperator.apply(left.equals(right), pLogger));
    }

    else if (isFloatingPointType (pLeft) ||
	     isFloatingPointType (pRight)) {
      double left =
	coerceToPrimitiveNumber (pLeft, Double.class, pLogger).
	doubleValue ();
      double right =
	coerceToPrimitiveNumber (pRight, Double.class, pLogger).
	doubleValue ();
      return 
	PrimitiveObjects.getBoolean 
	(pOperator.apply (left == right, pLogger));
    }

    else if (isBigInteger(pLeft) || isBigInteger(pRight)) {
        BigInteger left = (BigInteger)
            coerceToPrimitiveNumber(pLeft, BigInteger.class, pLogger);
        BigInteger right = (BigInteger)
            coerceToPrimitiveNumber(pRight, BigInteger.class, pLogger);
        return PrimitiveObjects.getBoolean(pOperator.apply(left.equals(right), pLogger));
    }

    else if (isIntegerType (pLeft) ||
	     isIntegerType (pRight)) {
      long left =
	coerceToPrimitiveNumber (pLeft, Long.class, pLogger).
	longValue ();
      long right =
	coerceToPrimitiveNumber (pRight, Long.class, pLogger).
	longValue ();
      return
	PrimitiveObjects.getBoolean 
	(pOperator.apply (left == right, pLogger));
    }

    else if (pLeft instanceof Boolean ||
	     pRight instanceof Boolean) {
      boolean left = coerceToBoolean (pLeft, pLogger).booleanValue ();
      boolean right = coerceToBoolean (pRight, pLogger).booleanValue ();
      return
	PrimitiveObjects.getBoolean 
	(pOperator.apply (left == right, pLogger));
    }

    else if (pLeft instanceof String ||
	     pRight instanceof String) {
      String left = coerceToString (pLeft, pLogger);
      String right = coerceToString (pRight, pLogger);
      return
	PrimitiveObjects.getBoolean 
	(pOperator.apply (left.equals (right), pLogger));
    }

    else {
      try {
      return
	PrimitiveObjects.getBoolean
	(pOperator.apply (pLeft.equals (pRight), pLogger));
      }
      catch (Exception exc) {
	if (pLogger.isLoggingError ()) {
	  pLogger.logError
	    (Constants.ERROR_IN_EQUALS,
	     exc,
	     pLeft.getClass ().getName (),
	     pRight.getClass ().getName (),
	     pOperator.getOperatorSymbol ());
	}
	return Boolean.FALSE;
      }
    }
  }

  //-------------------------------------
  /**
   *
   * Returns true if the given Object is of a floating point type
   **/
  public static boolean isFloatingPointType (Object pObject)
  {
    return 
      pObject != null &&
      isFloatingPointType (pObject.getClass ());
  }

  //-------------------------------------
  /**
   *
   * Returns true if the given class is of a floating point type
   **/
  public static boolean isFloatingPointType (Class pClass)
  {
    return
      pClass == Float.class ||
      pClass == Float.TYPE ||
      pClass == Double.class ||
      pClass == Double.TYPE;
  }

  //-------------------------------------
  /**
   *
   * Returns true if the given string might contain a floating point
   * number - i.e., it contains ".", "e", or "E"
   **/
  public static boolean isFloatingPointString (Object pObject)
  {
    if (pObject instanceof String) {
      String str = (String) pObject;
      int len = str.length ();
      for (int i = 0; i < len; i++) {
	char ch = str.charAt (i);
	if (ch == '.' ||
	    ch == 'e' ||
	    ch == 'E') {
	  return true;
	}
      }
      return false;
    }
    else {
      return false;
    }
  }

  //-------------------------------------
  /**
   *
   * Returns true if the given Object is of an integer type
   **/
  public static boolean isIntegerType (Object pObject)
  {
    return 
      pObject != null &&
      isIntegerType (pObject.getClass ());
  }

  //-------------------------------------
  /**
   *
   * Returns true if the given class is of an integer type
   **/
  public static boolean isIntegerType (Class pClass)
  {
    return
      pClass == Byte.class ||
      pClass == Byte.TYPE ||
      pClass == Short.class ||
      pClass == Short.TYPE ||
      pClass == Character.class ||
      pClass == Character.TYPE ||
      pClass == Integer.class ||
      pClass == Integer.TYPE ||
      pClass == Long.class ||
      pClass == Long.TYPE;
  }

  //-------------------------------------

  /**
   * Returns true if the given object is BigInteger.
   * @param pObject - Object to evaluate
   * @return - true if the given object is BigInteger
   */
  public static boolean isBigInteger(Object pObject) {
      return
          pObject != null && pObject instanceof BigInteger;
  }

  /**
   * Returns true if the given object is BigDecimal.
   * @param pObject - Object to evaluate
   * @return - true if the given object is BigDecimal
   */
  public static boolean isBigDecimal(Object pObject) {
      return
          pObject != null && pObject instanceof BigDecimal;
  }
}
tString(pRight)) {
        if (isBigInteger(pLeft) || isBigInteger(pRight)) {
            BigDecimal left = (BigDecimal)
                coerceToPrimitiveNumber(pLeft, BigDecimal.class, pLogger);
            BigDecimal right = (BigDecimal)
                coerceToPrimitiveNumber(pRight, BigDecimal.class, pLogger);
            return pOperator.apply(left, right);
        } else {
            double left =
                coerceToPrimitiveNumber(pLeft, Double.class, pLogger).
    commons-el-1.0-src/src/java/org/apache/commons/el/ComplexValue.java010064400723740000012000000117320764210442600256010ustar00luehestaff00003710000056/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 

package org.apache.commons.el;

import java.util.List;
import javax.servlet.jsp.el.ELException;
import javax.servlet.jsp.el.VariableResolver;
import javax.servlet.jsp.el.FunctionMapper;

/**
 *
 * <p>Represents a dynamic value, which consists of a prefix and an
 * optional set of ValueSuffix elements.  A prefix is something like
 * an identifier, and a suffix is something like a "property of" or
 * "indexed element of" operator.
 * 
 * @author Nathan Abramson - Art Technology Group
 * @author Shawn Bayern
 * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: luehe $
 **/

public class ComplexValue
  extends Expression
{
  //-------------------------------------
  // Properties
  //-------------------------------------
  // property prefix

  Expression mPrefix;
  public Expression getPrefix ()
  { return mPrefix; }
  public void setPrefix (Expression pPrefix)
  { mPrefix = pPrefix; }

  //-------------------------------------
  // property suffixes

  List mSuffixes;
  public List getSuffixes ()
  { return mSuffixes; }
  public void setSuffixes (List pSuffixes)
  { mSuffixes = pSuffixes; }

  //-------------------------------------
  /**
   *
   * Constructor
   **/
  public ComplexValue (Expression pPrefix,
		       List pSuffixes)
  {
    mPrefix = pPrefix;
    mSuffixes = pSuffixes;
  }

  //-------------------------------------
  // Expression methods
  //-------------------------------------
  /**
   *
   * Returns the expression in the expression language syntax
   **/
  public String getExpressionString ()
  {
    StringBuffer buf = new StringBuffer ();
    buf.append (mPrefix.getExpressionString ());

    for (int i = 0; mSuffixes != null && i < mSuffixes.size (); i++) {
      ValueSuffix suffix = (ValueSuffix) mSuffixes.get (i);
      buf.append (suffix.getExpressionString ());
    }

    return buf.toString ();
  }

  //-------------------------------------
  /**
   *
   * Evaluates by evaluating the prefix, then applying the suffixes
   **/
  public Object evaluate (VariableResolver pResolver,
			  FunctionMapper functions,
			  Logger pLogger)
    throws ELException
  {
    Object ret = mPrefix.evaluate (pResolver, functions, pLogger);

    // Apply the suffixes
    for (int i = 0; mSuffixes != null && i < mSuffixes.size (); i++) {
      ValueSuffix suffix = (ValueSuffix) mSuffixes.get (i);
      ret = suffix.evaluate (ret, pResolver, functions, pLogger);
    }

    return ret;
  }

  //-------------------------------------
}
commons-el-1.0-src/src/java/org/apache/commons/el/ConditionalExpression.java010064400723740000012000000124340764210442600275200ustar00luehestaff00003710000056/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES