⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 valuestack.java

📁 webwork source
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
* WebWork, Web Application Framework
*
* Distributable under Apache license.
* See terms of license at opensource.org
*/
package webwork.util;

import webwork.action.ActionContext;
import webwork.expr.Parser;

import java.beans.*;
import java.io.StringReader;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *	Value stack. A VS is used by the WebWork system as a way to make findInContext
 * values available by using the push and pop methods. They can then
 * be accessed by using the find* methods.
 *
 *	@author Rickard 謆erg (rickard@middleware-company.com)
 * @author Maurice C. Parker (maurice@vineyardenterprise.com)
 *	@version $Revision: 1.55 $
 */
public class ValueStack{
   // Static  -------------------------------------------------------
   public static final String STACK_NAME = "webwork.result";
   protected static Map classes = new HashMap(); // Method cache
   private static Log log = LogFactory.getLog(ServletValueStack.class);

   /**
    * Clear the method cache. This must be called if the
    * application is restarted.
    *
    */
   public static void clearMethods() {
      classes = new HashMap();
   }

   // Attributes ----------------------------------------------------
   private List valueList = Collections.EMPTY_LIST;
   private Parser parser;

   // Constructor ---------------------------------------------------
   public ValueStack() {
   }

   // Public --------------------------------------------------------
   /**
    * Push a value onto the value stack.
    *
    * @param   value  the value
    */
   public void pushValue(Object value) {
      if (valueList == Collections.EMPTY_LIST) {
         valueList = new ArrayList();
      }

      valueList.add(value);

//     log.debug("Push to value stack:" + value);
//     log.debug(toString());
//     new Throwable().printStackTrace();
   }


   /**
    * Pop a value from the value stack.
    *
    * @return  the popped value
    */
   public Object popValue() {
      if (valueList == Collections.EMPTY_LIST)
          return null;

     try {
         return valueList.remove(valueList.size() - 1);
      } catch (IndexOutOfBoundsException e) {
         return null;
      } finally {
//         log.debug("Pop from value stack:");
//         log.debug(toString());
//         new Throwable().printStackTrace();
      }
   }

   public Iterator iterator() {
       return valueList.iterator();
   }

   /**
    * Returns the size of the value stack.
    *
    * @return size of value stack
    */
   public int size() {
      return valueList.size();
   }

   /**
    * Returns TRUE is the value stack is empty.
    *
    * @return true is value stack is empty
    */
   public boolean isEmpty() {
      return size() == 0;
   }

   /**
    * Resolve a WebWork expression statement.
    *
    * @param   expression
    * @return  the boolean result of the expression
    */
   public boolean test(String expression) {
      if (expression==null) {
         throw new NullPointerException("Expression cannot be null.");
      }
      boolean answer = false;
      try
      {
         SimpleTest simpleTest = SimpleTest.getSimpleTest(expression);
         if (simpleTest != null)
         {
            answer = simpleTest.test(this, null, null);
         }
         else
         {
            Parser p = getParser(expression);
            answer = p.test();
         }
      } catch (Throwable pe) {
            log.error("An error occurred while parsing the expression: \"" + expression + "\", throwable: ", pe);
            throw new IllegalArgumentException("\n\nAn error occurred while parsing the expression: \n    \"" +
            expression + "\"\n" +
            pe.getMessage());
      }
      return answer;
   }

    // SK
    /** Find a value by id. This method can be overridden by subclasses to
     *  have some context concept to evaluate @identified expressions.
     */
    protected Object findInContext(String id) {
    	return null;
    }

   /**
    * Find a value for a given name.
    *
    * @param   query
    * @return  the object corresponding to the query
    */
   public Object findValue(String query)
         throws IllegalArgumentException {
      Query q;
      if (query == null || query.length()==0 || (query.length()==1 && query.charAt(0)=='.'))
         q = Query.CURRENT;
      else
      {
         // The query segments and the current segment
         q = Query.getQuery(query);
      }
      return findValue(q);
   }

   public Object findValue(Query q)
         throws IllegalArgumentException {
      // The query segments and the current segment
      QuerySegment[] segments = q.getSegments();
//      if (log.isDebugEnabled()) {
//         log.debug("findValue() for: " + q);
//      }

      QuerySegment segment = segments[0];
      int segmentIdx = 1;

      // The current stack pointer, and the current object,
      int stackIdx = 0;
      Object value;
      
      /////////////////////////////////////////////////////////////////////////
      // evaluate the first element of the expression to see where to
      // get the requested value.  These should be quick and easy objects
      // to find or create.
      /////////////////////////////////////////////////////////////////////////
      switch (segment.getType()) {

         // get the top value off of the stack
         case QuerySegment.CURRENT:

            if (valueList.size() < 1)
               return null;
            // set up the stack, pointer, and current value
            value = valueList.get(valueList.size()-1);
            if (value instanceof ValueHolder)
               value = ((ValueHolder) value).getValue();

            // always have the next segment ready to go
            segment = segments[segmentIdx++];

            // if we don't need to get other values then return the value
            if (segment == null)
               return value;

            // The stackIdx is already zero so we will not try to search the stack
            break;

            // return the id since it is the actual string
         case QuerySegment.STRING:
            return segment.getId();

            // the integer is the first value and only value in the segment
         case QuerySegment.NUMBER:
            return segment.getValues().get(0);

            // get an attribute
         case QuerySegment.ATTRIBUTE:

            // get the attribute
	     // SK
	     value=findInContext(segment.getId());
	     // /SK

            if (value == null) {
//               if (log.isDebugEnabled()) {
//                  log.debug("value for [" + q + "] is null.");
//               }

               return null;

               //throw new IllegalArgumentException("No such attribute: " + token.image);
            }
            // get the real value
            if (value instanceof ValueHolder)
               value = ((ValueHolder) value).getValue();

            // always have the next segment ready to go
            segment = segments[segmentIdx++];

            // if we don't need to search through this attribute simply return it
            if (segment == null)
               return value;

            // The stackIdx is already zero so we will not try to search the stack

            break;

            // return the http request parameter
         case QuerySegment.PARAMETER:
	     // SK
            return getParameter(segment.getId());
	     // /SK
            // the reserved keyword "true"
         case QuerySegment.TRUE:
            return Boolean.TRUE;

            // the reserved keyword "false"
         case QuerySegment.FALSE:
            return Boolean.FALSE;

            // the reserved keyword "null"
         case QuerySegment.NULL:
            return null;

            // get the root object off of the bottom of the stack
         case QuerySegment.ROOT:
            if (valueList.size() < 1)
               return null;

            // The stackIdx is already zero so we will not try to search the stack
            // set up the stack pointer, and current value
            value = valueList.get(0);

            // always have the next segment ready to go

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -