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

📄 valuestack.java

📁 webwork source
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
   public String toString() {
      String str = "Value stack\n";
      str += "===========\n";
      for (int i = 0; i < valueList.size(); i++) {
         Object val = valueList.get(i);
         str += val == null ? "null\n" : val.toString() + "\n";
      }
      str += "===========\n";
      return str;
   }

   /**
    * Get the parser associated with this ValueStack
    *
    * @return   the Parser for this ValueStack
    */
   private Parser getParser(String expression) {
      if (parser == null) {
         parser = new Parser(new StringReader(expression));
         parser.setValueStack(this);
      } else {
         parser.ReInit(new StringReader(expression));
      }
      return parser;
   }

   /**
    * Get a method with a given name.
    *
    * @param   cl  the class of the method
    * @param   name  the name of the method
    * @return     the wanted method
    * @exception   IntrospectionException
    */
   protected MethodInfo[] getMethod(Class cl, String name)
         throws IntrospectionException {
      Map methods = (Map) classes.get(cl);
      if (methods == null) {
         // Get methods that can be invoked for this class
         methods = new HashMap();

         // Find get methods for properties
         BeanInfo bi = Introspector.getBeanInfo(cl);
         PropertyDescriptor[] pd = bi.getPropertyDescriptors();
         for (int i = 0; i < pd.length; ++i) {
            Method method = pd[i].getReadMethod();

            // Check if readable property
            if (method != null) {
               if (!Modifier.isPublic(cl.getModifiers())) {
                  // Find a method in an interface that *is* public
                  Class[] interfaces = bi.getBeanDescriptor().getBeanClass().getInterfaces();
                  for (int j = 0; j < interfaces.length; j++) {
                     try {
                        //log.debug("Try "+interfaces[j]);
                        method = interfaces[j].getMethod(method.getName(), new Class[0]);
                        break;
                     } catch (Exception e) {
                        // Ignore
                     }
                  }

                  // We're in trouble! Try to sneak through security
                  if (method.equals(pd[i].getReadMethod())) {
                     AccessibleObject.setAccessible(new AccessibleObject[]{method}, true);
                  }
               }

               // Save method in map
               //log.debug( "GET_METHOD: class: " + cl + " method: " + method.getName());
               methods.put(pd[i].getName(), new MethodInfo[]{new MethodInfo(method)});
            }
         }

         // Find param methods
         Method[] getters = cl.getMethods();
         for (int i = 0; i < getters.length; i++) {
            Method method = getters[i];
            if (!method.getName().startsWith("set") && !method.getReturnType().equals(Void.TYPE)) {
               // Valid method
               // Check if public
               if (!Modifier.isPublic(cl.getModifiers())) {
                  // Find a method in an interface that *is* public
                  Class[] interfaces = cl.getInterfaces();
                  for (int j = 0; j < interfaces.length; j++) {
                     try {
                        method = interfaces[j].getMethod(method.getName(), method.getParameterTypes());
                        break;
                     } catch (Exception e) {
                        // Ignore
                     }
                  }

                  // We're in trouble! Try to sneak through security
                  if (method.equals(getters[i])) {
                     AccessibleObject.setAccessible(new AccessibleObject[]{method}, true);
                  }
               }

               // Get name
               String methodName = method.getName();
               if (methodName.startsWith("get"))
                  methodName = Introspector.decapitalize(methodName.substring(3));
               else if (methodName.startsWith("is"))
                  methodName = Introspector.decapitalize(methodName.substring(2));

               // Save method in map
               MethodInfo[] current = (MethodInfo[]) methods.get(methodName);
               MethodInfo[] newlist;
               if (current == null) {
                  newlist = new MethodInfo[]{new MethodInfo(method)};
               } else {
                  newlist = new MethodInfo[current.length + 1];
                  System.arraycopy(current, 0, newlist, 0, current.length);
                  newlist[current.length] = new MethodInfo(method);
               }
               methods.put(methodName, newlist);
               //log.debug( "GET_METHOD: class: " + cl + " method: " + method.getName());
            }
         }

         // Add map to class map
         // RO: Use clone to avoid synchronization
         Map newClassMap = (Map) ((HashMap) classes).clone();
         newClassMap.put(cl, methods);
         classes = newClassMap;
         //log.debug("Added "+cl+" to class map:"+methods);
      }

      // Get named method/property getter
      MethodInfo[] nameMethods = (MethodInfo[]) methods.get(name);

      //log.debug("Got "+cl+" "+name+":"+m);
      return nameMethods;
   }

   protected MethodInfo findMethod(MethodInfo[] m, Object[] params) {
      if (m.length == 1)
         return m[0];

      MethodInfo oneMatch = null;
      List match = null;
      int noOfArgument = params.length;

      // Do not create the ArrayList when it is not necessary (the most common case!)
      for (int i = 0; i < m.length; i++) {
         if (m[i].getNrOfParameters() == noOfArgument)
         {
            if (oneMatch == null)
               oneMatch = m[i];
            else
            {
               if (match == null)
               {
                  match = new ArrayList();
                  match.add(oneMatch);
               }
               match.add(m[i]);
            }
         }
      }

      // If there is no list then there is either 1 match or 0 matches.
      // Just return the oneMatch variable then
      if (match == null)
         return oneMatch;

      //log.debug("No of match for: " + m[0].getName() + " , " + noOfArgument + ", " + match.size());

      MethodInfo exact = null;
      List close = new ArrayList();
      List convert = new ArrayList();

      for (Iterator i = match.iterator(); i.hasNext();) {
         MethodInfo current = (MethodInfo) i.next();
         Class[] paramClass = current.getParameterTypes();
         boolean exactMatch = true;
         boolean closeMatch = true;
         boolean convertable = true;

         for (int j = 0; j < paramClass.length; j++) {
            Class p = params[j].getClass();
            //log.debug("Argument: " + j + " , parameterClass: " + paramClass[j].getName()
            //+ " , argumentClass: " + p.getName());
            if (paramClass[j].getName().equals(p.getName())) {
               continue;
            } else if (paramClass[j].isAssignableFrom(p)) {
               exactMatch = false;
               continue;
            } else {
               exactMatch = false;
               closeMatch = false;
               try {
                  // Get property editor
                  PropertyEditor pe = BeanUtil.getPropertyEditor(paramClass[j]);
                  if (pe == null) {
                  	convertable = false;
                  }
                  else {
                     // Convert value
                     BeanUtil.getAsValue(pe, params[j].toString());
                  }
               } catch (Exception e) {
                  convertable = false;
               }

               if (!convertable)
                  break;
            }
         }

         if (exactMatch) {
            exact = current;
            break;
         } else if (closeMatch) {
            close.add(current);
         } else if (convertable) {
            convert.add(current);
         }

      }

      if (exact != null)
         return exact;
      else if (close.size() > 0)
         return (MethodInfo) close.get(0);
      else if (convert.size() > 0)
         return (MethodInfo) convert.get(0);
      else
         return null;

   }

   /**
   * Class that holds information about a method and the parameter types
   * that the method accepts, and the number of parameters
   */
   private static class MethodInfo
   {
      Method _method;
      Class[] _parameterTypes;
      int _nrOfParameters;

      public MethodInfo(Method method)
      {
         _method = method;
         _parameterTypes = method.getParameterTypes();
         _nrOfParameters = _parameterTypes.length;
      }

      public Method getMethod()
      {
         return _method;
      }

      public Class[] getParameterTypes()
      {
         return _parameterTypes;
      }

      public int getNrOfParameters()
      {
         return _nrOfParameters;
      }
   }

   protected Object getParameter(String aName)
   {
      return ActionContext.getParameters().get(aName);
   }

   // Inner classes -------------------------------------------------
   // Value providers that want to use lazy evaluation should use this
   // interface
   public interface ValueHolder {
      // Public -----------------------------------------------------
      public Object getValue();
   }

}

⌨️ 快捷键说明

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