jclassdependency.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 372 行

JAVA
372
字号
/* * Copyright (c) 1998-2008 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 Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.bytecode;import com.caucho.loader.*;import com.caucho.util.*;import com.caucho.vfs.*;import java.security.MessageDigest;import java.lang.annotation.*;import java.lang.reflect.*;import java.util.*;import java.util.logging.Level;import java.util.logging.Logger;/** * Representing a class that might change. */public class JClassDependency implements PersistentDependency {  private final static Logger log = Log.open(JClassDependency.class);    private final String _className;  private boolean _checkFields = true;  private boolean _checkStatic = true;  private boolean _checkProtected = true;  private boolean _checkPrivate = true;  private boolean _isDigestModified;  /**   * Creates the class dependency.   */  public JClassDependency(JClass cl)  {    _className = cl.getName();  }  /**   * Create a new dependency with a given digest.   *   * @param cl the source class   * @param digest the MD5 digest   */  public JClassDependency(JClass cl, String digest)  {    _className = cl.getName();    String newDigest = getDigest();    if (! newDigest.equals(digest)) {      if (log.isLoggable(Level.FINE))        log.fine(_className + " digest is modified.");      _isDigestModified = true;    }  }  /**   * Create a new dependency with a given digest.   *   * @param cl the source class   * @param digest the MD5 digest   */  public JClassDependency(String className, String digest)  {    _className = className;        String newDigest = getDigest();    if (! newDigest.equals(digest)) {      if (log.isLoggable(Level.FINE))        log.fine(_className + " digest is modified.");      _isDigestModified = true;    }  }    /**   * Returns true if the underlying resource has changed.   */  public boolean isModified()  {    return _isDigestModified;  }    /**   * Log the reason for modification   */  public boolean logModified(Logger log)  {    if (isModified()) {      log.info(_className + " is modified");      return true;    }    else      return false;  }  /**   * Calculates a MD5 digest of the class.   */  public String getDigest()  {    try {      if (_className == null || "".equals(_className))	return "";            DynamicClassLoader loader	= (DynamicClassLoader) Thread.currentThread().getContextClassLoader();      ClassLoader tmpLoader = loader.getNewTempClassLoader();            Class cl = Class.forName(_className, false, tmpLoader);            if (cl == null)        return "";      MessageDigest digest = MessageDigest.getInstance("MD5");      addDigest(digest, cl.getName());      addDigest(digest, cl.getModifiers());      Class superClass = cl.getSuperclass();      if (superClass != null)        addDigest(digest, superClass.getName());      Class []interfaces = cl.getInterfaces();      for (int i = 0; i < interfaces.length; i++)        addDigest(digest, interfaces[i].getName());      Field []fields = cl.getDeclaredFields();      Arrays.sort(fields, new FieldComparator());      if (_checkFields) {        for (Field field : fields) {          if (Modifier.isPrivate(field.getModifiers())	      && ! _checkPrivate)            continue;          if (Modifier.isProtected(field.getModifiers())	      && ! _checkProtected)            continue;                    addDigest(digest, field.getName());          addDigest(digest, field.getModifiers());          addDigest(digest, field.getType().getName());	  addDigest(digest, field.getAnnotations());        }      }      Method []methods = cl.getDeclaredMethods();      Arrays.sort(methods, new MethodComparator());            for (int i = 0; i < methods.length; i++) {        Method method = methods[i];        if (Modifier.isPrivate(method.getModifiers()) && ! _checkPrivate)          continue;        if (Modifier.isProtected(method.getModifiers()) && ! _checkProtected)          continue;        if (Modifier.isStatic(method.getModifiers()) && ! _checkStatic)          continue;                  addDigest(digest, method.getName());        addDigest(digest, method.getModifiers());        addDigest(digest, method.getName());        Class []param = method.getParameterTypes();        for (int j = 0; j < param.length; j++)          addDigest(digest, param[j].getName());        addDigest(digest, method.getReturnType().getName());        Class []exn = method.getExceptionTypes();        for (int j = 0; j < exn.length; j++)          addDigest(digest, exn[j].getName());		addDigest(digest, method.getAnnotations());      }            byte []digestBytes = new byte[256];            int len = digest.digest(digestBytes, 0, digestBytes.length);            return digestToBase64(digestBytes, len);    } catch (Exception e) {      log.log(Level.FINER, e.toString(), e);      return "";    }  }  /**   * Returns a string which will recreate the dependency.   */  public String getJavaCreateString()  {    return ("new com.caucho.bytecode.JClassDependency(\"" +            _className + "\", \"" + getDigest() + "\")");  }    /**   * Adds the annotations to the digest using a UTF8 encoding.   */  private static void addDigest(MessageDigest digest, Annotation []annList)  {    if (annList == null)      return;    for (Annotation ann : annList)      addDigest(digest, ann);  }    /**   * Adds the annotations to the digest using a UTF8 encoding.   */  private static void addDigest(MessageDigest digest, Annotation ann)  {    addDigest(digest, ann.annotationType().getName());  }    /**   * Adds the int to the digest.   */  private static void addDigest(MessageDigest digest, int v)  {    digest.update((byte) (v >> 24));    digest.update((byte) (v >> 16));    digest.update((byte) (v >> 8));    digest.update((byte) v);  }    /**   * Adds the string to the digest using a UTF8 encoding.   */  private static void addDigest(MessageDigest digest, String string)  {    if (string == null)      return;        int len = string.length();    for (int i = 0; i < len; i++) {      int ch = string.charAt(i);      if (ch < 0x80)        digest.update((byte) ch);      else if (ch < 0x800) {        digest.update((byte) (0xc0 + (ch >> 6)));        digest.update((byte) (0x80 + (ch & 0x3f)));      }      else {        digest.update((byte) (0xe0 + (ch >> 12)));        digest.update((byte) (0x80 + ((ch >> 6) & 0x3f)));        digest.update((byte) (0x80 + (ch & 0x3f)));      }    }  }    private String digestToBase64(byte []digest, int len)  {    CharBuffer cb = CharBuffer.allocate();    Base64.encode(cb, digest, 0, len);    return cb.close();  }  public boolean isEqual(Object o)  {    if (o == this)      return true;        if (! (o instanceof JClassDependency))      return false;    JClassDependency depend = (JClassDependency) o;    return _className.equals(depend._className);  }  static class FieldComparator implements Comparator<Field> {    public int compare(Field a, Field b)    {      if (a == b)	return 0;      else if (a == null)	return -1;      else if (b == null)	return 1;      else if (a.equals(b))	return 0;      int cmp = a.getName().compareTo(b.getName());      if (cmp != 0)	return cmp;            cmp = a.getDeclaringClass().getName().compareTo(b.getDeclaringClass().getName());      if (cmp != 0)	return cmp;            return a.getType().getName().compareTo(b.getType().getName());    }  }  static class MethodComparator implements Comparator<Method> {    public int compare(Method a, Method b)    {      if (a == b)	return 0;      else if (a == null)	return -1;      else if (b == null)	return 1;      else if (a.equals(b))	return 0;      int cmp = a.getName().compareTo(b.getName());      if (cmp != 0)	return cmp;      Class []paramA = a.getParameterTypes();      Class []paramB = b.getParameterTypes();      if (paramA.length < paramB.length)	return -1;      else if (paramB.length < paramA.length)	return 1;      for (int i = 0; i < paramA.length; i++) {	cmp = paramA[i].getName().compareTo(paramB[i].getName());	if (cmp != 0)	  return cmp;      }            cmp = a.getDeclaringClass().getName().compareTo(b.getDeclaringClass().getName());      if (cmp != 0)	return cmp;            return a.getReturnType().getName().compareTo(b.getReturnType().getName());    }  }}

⌨️ 快捷键说明

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