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

📄 esintrospector.java

📁 RESIN 3.2 最新源码
💻 JAVA
字号:
/* * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the *   Free SoftwareFoundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.es.wrapper;import com.caucho.server.util.CauchoSystem;import com.caucho.util.WeakLruCache;import java.beans.BeanInfo;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.MethodDescriptor;import java.beans.PropertyDescriptor;import java.lang.ref.SoftReference;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;    /** * Analyzes the class from a JavaScript perspective. * * <p>Each class Foo searches for its "FooEcmaWrap" to see if there are * any method changes. */public class ESIntrospector {  /**   * Cache of analyzed classes to avoid duplication.   */  static WeakLruCache<Class,SoftReference<ESBeanInfo>> _beanMap =    new WeakLruCache<Class,SoftReference<ESBeanInfo>>(256);    static Integer NULL = new Integer(0);  final static int METHOD = 1;  final static int PROPERTY = 2;  final static int MASK = 3;  static String []path = new String[] {"", "com.caucho.eswrap"};  /**   * Analyzes the class, returning the calculated ESBeanInfo.   *   * @param cl the class to be analyzed.   * @return the analyzed bean info.   */  public static ESBeanInfo getBeanInfo(Class cl)    throws IntrospectionException  {    ESBeanInfo info;    SoftReference<ESBeanInfo> infoRef = _beanMap.get(cl);          info = infoRef != null ? infoRef.get() : null;    if (info != null)      return info;    info = new ESBeanInfo(cl);    getMethods(info, cl);    _beanMap.put(cl, new SoftReference<ESBeanInfo>(info));        return info;  }  /**   * Analyzes a Java method, converting it to any equivalent JavaScript   * properties.   *   * <pre>   * keys()         -> for (item in obj) {   * getFoo()       -> obj.foo   * getFoo(int)    -> obj.foo[i]   * getFoo(String) -> obj.foo["name"]   * remove(String) -> delete obj.foo   * </pre>   *   * @param info the bean info to be filled   * @param cl the bean's class   * @param md the method descriptor   * @param overwrite if true, this overwrites any previous definition   */  private static void    analyzeProperty(ESBeanInfo info, Class cl, ESMethodDescriptor md,		    boolean overwrite)    throws IntrospectionException  {    Method method = md.getMethod();    int modifiers = method.getModifiers();    if (! Modifier.isPublic(modifiers))      return;    String name = method.getName();    String propName;    Class returnType = method.getReturnType();    String returnName = returnType.getName();    Class []params = md.getParameterTypes();    if (name.equals("keys") && params.length == 0 &&	(returnName.equals("java.util.Iterator") ||	 (returnName.equals("java.util.Enumeration")))) {      info.iterator = md;    }    else if (name.equals("iterator") && params.length == 0 &&	     (returnName.equals("java.util.Iterator") ||	      (returnName.equals("java.util.Enumeration")))) {      // keys has priority over iterator      if (info.iterator == null)	info.iterator = md;    }    else if (name.startsWith("get") && ! name.equals("get")) {      propName = Introspector.decapitalize(name.substring(3));      // kill match?      if (returnName.equals("void") && params.length < 2) {	// XXX: props.put(propName, BAD);	return;      }      // name keys      if (params.length == 0 &&	  (propName.endsWith("Keys") && ! propName.equals("Keys") ||	   propName.endsWith("Names") && ! propName.equals("Names")) &&	  (returnName.equals("java.util.Iterator") ||	   (returnName.equals("java.util.Enumeration")))) {	if (propName.endsWith("Keys"))	  info.addNamedProp(propName.substring(0, propName.length() - 4),			    null, null, null, md);	else	  info.addNamedProp(propName.substring(0, propName.length() - 5),			    null, null, null, md);      }      // index length      else if (params.length == 0 &&	       (propName.endsWith("Size") && ! propName.equals("Size") ||		propName.endsWith("Length") && ! propName.equals("Length")) &&	       (returnName.equals("int"))) {	info.addProp(propName, null, md, null);	if (propName.endsWith("Size"))	  info.addIndexedProp(propName.substring(0, propName.length() - 4),			      null, null, md);	else	  info.addIndexedProp(propName.substring(0, propName.length() - 6),			      null, null, md);      }      else if (params.length == 0)	info.addProp(propName, null, md, null);      else if (params.length == 1 && 	       params[0].getName().equals("java.lang.String")) {	info.addNamedProp(propName, md, null, null, null);      } else if (params.length == 1 && 	       params[0].getName().equals("int")) {	info.addIndexedProp(propName, md, null, null);      } else if (params.length == 1) {	// xxx: add bad?      }    } else if (name.startsWith("set") && ! name.equals("set")) {      propName = Introspector.decapitalize(name.substring(3));      if (params.length == 0)	return;	  // kill match?      if (! returnType.getName().equals("void") && params.length < 3) {	// XXX: add bad? props.put(propName, NULL);	return;      }      if (params.length == 1)	info.addProp(propName, null, null, md);      else if (params.length == 2 &&	       params[0].getName().equals("java.lang.String")) {	info.addNamedProp(propName, null, md, null, null);      } else if (params.length == 2 && 		 params[0].getName().equals("int")) {	info.addIndexedProp(propName, null, md, null);      } else if (params.length == 2) {	// XXX: props.put(propName, NULL);      }    } else if (name.startsWith("remove") && ! name.equals("remove") ||	       name.startsWith("delete") && ! name.equals("remove")) {      propName = Introspector.decapitalize(name.substring(6));      if (params.length == 0)	return;	  // kill match?      if (! returnType.getName().equals("void") && params.length < 2) {	// XXX: add bad? props.put(propName, NULL);	return;      }      //if (params.length == 0)      //	info.addProp(propName, null, null, md);      if (params.length == 1 &&	  params[0].getName().equals("java.lang.String")) {	info.addNamedProp(propName, null, null, md, null);      }       /*      else if (params.length == 2 && 		 params[0].getName().equals("int")) {	info.addIndexedProp(propName, null, md, null);      } else if (params.length == 2) {	// XXX: props.put(propName, NULL);      }      */    }  }  /**   * Add methods from a FooEcmaWrap class.   */  static void addEcmaMethods(ESBeanInfo info, Class cl, Class wrapCl, int mask)    throws IntrospectionException  {    Method []methods = wrapCl.getDeclaredMethods();    for (int i = 0; i < methods.length; i++) {      int modifiers = methods[i].getModifiers();      if (! Modifier.isStatic(modifiers))	continue;      ESMethodDescriptor md = info.createMethodDescriptor(methods[i], true);      if ((mask & METHOD) != 0)	info.addMethod(md);      if ((mask & PROPERTY) != 0)	analyzeProperty(info, cl, md, true);    }    }  /**   * Search for FooEcmaWrap classes.   *   * @param info the bean info to be filled   * @param cl the bean being analyzed   * @param mask the replacement mask.   */  static void addEcmaWrap(ESBeanInfo info, Class cl, int mask)    throws IntrospectionException  {    String name = cl.getName();    int lastDot = name.lastIndexOf('.');    String prefix = lastDot == -1 ? "" : name.substring(0, lastDot);    String tail = lastDot == -1 ? name : name.substring(lastDot + 1);    ClassLoader loader = cl.getClassLoader();    for (int i = 0; i < path.length; i++) {      String testName;      if (path[i].equals(""))	testName = name + "EcmaWrap";      else	testName = path[i] + "." + name + "EcmaWrap";      try {	Class wrapCl = CauchoSystem.loadClass(testName, false, loader);	if (wrapCl != null) {	  addEcmaMethods(info, cl, wrapCl, mask);	  return;	}      } catch (ClassNotFoundException e) {      }      if (path[i].equals(""))	testName = tail + "EcmaWrap";      else	testName = path[i] + "." + tail + "EcmaWrap";      try {	Class wrapCl = CauchoSystem.loadClass(testName, false, loader);	if (wrapCl != null) {	  addEcmaMethods(info, cl, wrapCl, mask);	  return;	}      } catch (ClassNotFoundException e) {      }    }  }  /**   * Fills information for a FooBeanInfo class.   *   * @param info the result information object   * @param cl the bean class   *   * @return a mask   */  static int getBeanInfo(ESBeanInfo info, Class cl)  {    try {      String name = cl.getName() + "BeanInfo";            Class beanClass = CauchoSystem.loadClass(name, false, cl.getClassLoader());      if (beanClass == null)	return MASK;      BeanInfo beanInfo = (BeanInfo) beanClass.newInstance();      MethodDescriptor []mds = beanInfo.getMethodDescriptors();      if (mds == null)	return MASK;      for (int i = 0; i < mds.length; i++) {	Method method = mds[i].getMethod();	int modifiers = method.getModifiers();	if (! Modifier.isStatic(modifiers) &&	    ! method.getDeclaringClass().isAssignableFrom(cl))	  continue;	info.addMethod(mds[i], true);      }      return MASK & ~METHOD;    } catch (Exception e) {      return MASK;    }  }  static void getPropBeanInfo(ESBeanInfo info, Class cl)  {    try {      String name = cl.getName() + "BeanInfo";      Class beanClass = CauchoSystem.loadClass(name, false, cl.getClassLoader());      if (beanClass == null)	return;      BeanInfo beanInfo = (BeanInfo) beanClass.newInstance();      PropertyDescriptor []props = beanInfo.getPropertyDescriptors();      for (int i = 0; props != null && i < props.length; i++) {        ESMethodDescriptor read;        ESMethodDescriptor write;                read = new ESMethodDescriptor(props[i].getReadMethod(), false, false);        write = new ESMethodDescriptor(props[i].getWriteMethod(),                                       false, false);        info.addProp(props[i].getName(), null, read, write, true);      }    } catch (Exception e) {    }  }  private static void getMethods(ESBeanInfo info, Class cl)    throws IntrospectionException  {    if (! cl.isPrimitive() && ! cl.isArray() &&        cl.getName().indexOf('.') < 0)      info.addNonPkgClass(cl.getName());    getPropBeanInfo(info, cl);    int mask = getBeanInfo(info, cl);    if (mask == 0)      return;    Class []interfaces = cl.getInterfaces();    for (int i = 0; i < interfaces.length; i++) {      ESBeanInfo subInfo = getBeanInfo(interfaces[i]);      if ((mask & METHOD) != 0)	info.addMethods(subInfo);      if ((mask & PROPERTY) != 0)	info.addProps(subInfo);    }    Class superClass = cl.getSuperclass();    if (superClass != null) {      ESBeanInfo subInfo = getBeanInfo(superClass);      if ((mask & METHOD) != 0)	info.addMethods(subInfo);      if ((mask & PROPERTY) != 0)	info.addProps(subInfo);    }    int modifiers = cl.getModifiers();    if (Modifier.isPublic(modifiers)) {      Method []methods = cl.getDeclaredMethods();      int len = methods == null ? 0 : methods.length;      for (int i = 0; i < len; i++) {	ESMethodDescriptor md = info.createMethodDescriptor(methods[i], false);	if ((mask & METHOD) != 0)	  info.addMethod(md);	if ((mask & PROPERTY) != 0)	  analyzeProperty(info, cl, md, false);      }      Field []fields = cl.getDeclaredFields();      for (int i = 0; fields != null && i < fields.length; i++) {	info.addField(fields[i]);      }    }    addEcmaWrap(info, cl, mask);  }}

⌨️ 快捷键说明

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