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

📄 subclasser.java

📁 一个跟踪调试jdbc的工具包。通过把jdbc做一个封装
💻 JAVA
字号:
/*
 *
 * ====================================================================
 *
 * The P6Spy Software License, Version 1.1
 *
 * This license is derived and fully compatible with the Apache Software
 * license, see http://www.apache.org/LICENSE.txt
 *
 * Copyright (c) 2001-2002 Andy Martin, Ph.D. and Jeff Goke
 * 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:
 * "The original concept and code base for P6Spy was conceived
 * and developed by Andy Martin, Ph.D. who generously contribued
 * the first complete release to the public under this license.
 * This product was due to the pioneering work of Andy
 * that began in December of 1995 developing applications that could
 * seamlessly be deployed with minimal effort but with dramatic results.
 * This code is maintained and extended by Jeff Goke and with the ideas
 * and contributions of other P6Spy contributors.
 * (http://www.p6spy.com)"
 * Alternately, this acknowlegement may appear in the software itself,
 * if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "P6Spy", "Jeff Goke", and "Andy Martin" must not be used
 * to endorse or promote products derived from this software without
 * prior written permission. For written permission, please contact
 * license@p6spy.com.
 *
 * 5. Products derived from this software may not be called "P6Spy"
 * nor may "P6Spy" appear in their names without prior written
 * permission of Jeff Goke and Andy Martin.
 *
 * 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.
 */

/**
 * Description: Creates a subclass from the specifed DataSource to wrap in
 *		the p6spy functionality
 *
 * $Author: aarvesen $
 * $Revision: 1.2 $
 * $Date: 2003/12/01 00:40:18 $
 *
 * $Id: Subclasser.java,v 1.2 2003/12/01 00:40:18 aarvesen Exp $
 * $Log: Subclasser.java,v $
 * Revision 1.2  2003/12/01 00:40:18  aarvesen
 * fixed parent package bug
 * added new constructor
 * filled in main method
 *
 * Revision 1.1  2003/08/06 19:52:11  aarvesen
 * Class to generate subclasses of DataSources that wrap with P6Spy
 *
 */
package com.p6spy.engine.common;

import javax.sql.DataSource;
import java.io.*;
import java.lang.reflect.*;

public class Subclasser {
  public static String DELIMITER = System.getProperty("file.separator");
  public static String NEWLINE   = System.getProperty("line.separator");
  public static String INDENT    = "  ";
  public static String DEFAULT_PACKAGE = "com.p6spy.engine.subclass";

  protected Class parentClass; 

  protected String outputDir;
  protected String packageName;
  protected String outputName;

  public Subclasser() {
  } 

  public Subclasser(String className) throws ClassNotFoundException {
    this(P6Util.forName(className));
  } 

  public Subclasser(Class c) {
    setParentClass(c);
  } 


  /*
   * Simple invocation method: java -cp  p6spy.jar com.p6spy.engine.common.Subclasser some_class_file
   */
  public static void main(String[] args) {
    int size = args.length;
    for (int i = 0; i < size; i++) {
      try {
	Subclasser sub = new Subclasser(args[i]);
	sub.createSubClass();	
      } catch (Exception e) {
	e.printStackTrace();
      }
    }
  }

  public void createSubClass() throws Exception {
    // take the parent class.  It's a data source,
    // emit a new subclass with just the pieces that you care
    // about written over

    // do a brief sanity check
    if (parentClass == null) {
      throw new Exception("Parent Class must not be null");
    }

    if (! DataSource.class.isAssignableFrom(parentClass)) {
      throw new Exception("Parent Class " + parentClass.getName() + " is not an instanceof javax.sql.DataSource");
    }

    // okay, ready to go.
    // get the output file...
    File output = getOutputFile();
    if (output.getParent() != null) {
      output.getParentFile().mkdirs();
    }
    output.createNewFile();

    FileWriter writer = new FileWriter(output);

    writer.write(writeHeader());
    writer.write(writeConstructors());
    writer.write(overrideConnection());
    writer.write(writeFooter());
    writer.flush();
    writer.close();

    // done!

  }

  /*---------------------------------------------------------------------*\
   *                      getters and setters
  \*---------------------------------------------------------------------*/    

  public Class getParentClass() {
    return parentClass;
  }
  public void setParentClass(Class c) {
    parentClass = c;
  }

  public String getParentPackage() {
    String rv = null;
    if (parentClass != null) {
      Package pack = parentClass.getPackage();

      // had some problems with the AntClassLoader not
      // defining the package information
      if (pack != null) {
	rv = pack.getName();
      } else {
	rv = packageName(parentClass.getName());
      }
    }

    return rv;
  }

  public File getOutputFile() {
    String dir = getOutputDir();
    String fullDir = packToDir(getOutputPackage());
    String name = getOutputName();

    if (dir != "") {
      fullDir = dir + DELIMITER + fullDir;
    }

    return new File(fullDir, name + ".java");
  }

  public String getOutputDir() {
    if (outputDir == null) {
      outputDir = "scratch";
    }
    return outputDir;
  }

  public void setOutputDir(String value) {
    outputDir = value;
  }

  public String getOutputPackage() {
    if (packageName == null) {
      packageName = DEFAULT_PACKAGE;
    }
    return packageName;
  }

  public void setOutputPackage(String value) {
    packageName= value;
  }

  public String getOutputName() {
    if (outputName == null && parentClass != null) {
      outputName = "P6" + baseName(parentClass.getName());
    }
    return outputName;
  }

  public void setOutputName(String value) {
    outputName = value;
  }

  /*---------------------------------------------------------------------*\
   *                     utility methods 
  \*---------------------------------------------------------------------*/    
  /**
   * derive "Foo" from "com.p6spy.package.Foo"
   */
  public String baseName(String clazz) {
    String rv = null;
    int pos = clazz.lastIndexOf(".");
    if (pos != -1) {
      rv = clazz.substring(pos + 1);
    }
    return rv;
  }

  /**
   * derive "com.p6spy.package" from "com.p6spy.package.Foo"
   */
  public String packageName(String clazz) {
    String rv = null;
    int pos = clazz.lastIndexOf(".");
    if (pos != -1) {
      rv = clazz.substring(0, pos);
    }
    return rv;
  }

  /**
   * Change "com.p6spy.package" into "com/p6spy/pacakge" or 
   * "com\p6spy\package" or
   * "com:p6spy:package" or
   * whatever
   */
  public String packToDir(String pack) {
    StringBuffer sb = new StringBuffer();
    int length = pack.length();
    for (int i = 0; i < length; i++) {
      char c = pack.charAt(i);
      if ( c == '.') {
	sb.append(DELIMITER);
      } else {
	sb.append(c);
      }
    }
    return sb.toString();
  }

  /*---------------------------------------------------------------------*\
   *                    heavy lifting here 
  \*---------------------------------------------------------------------*/    
  public String writeHeader() throws Exception {
    StringBuffer sb = new StringBuffer(); 
    String parentPack = getParentPackage();

    //package declaration
    sb.append("// this class generated by " + this.getClass());
    sb.append(NEWLINE);
    sb.append(NEWLINE);
    sb.append("package " + getOutputPackage() + ";");

    // now the nec. imports
    // some of these are just guesses
    sb.append(NEWLINE);
    sb.append(NEWLINE);
    sb.append("import com.p6spy.engine.spy.*;" + NEWLINE);
    sb.append("import java.sql.*;" + NEWLINE);
    sb.append("import javax.sql.*;" + NEWLINE);
    sb.append("import " + parentPack + ".*;" + NEWLINE);

    // now, let's do the class declaration
    sb.append(NEWLINE);
    sb.append(NEWLINE);
    sb.append("public class " + getOutputName() + " extends " + getParentClass().getName() + " {");
    sb.append(NEWLINE);

    return sb.toString();
  }

  public String writeConstructors() throws Exception {
    StringBuffer sb = new StringBuffer();
    Class parent = getParentClass();
    Constructor[] conList = parent.getDeclaredConstructors();
    int length = conList.length;

    if (length == 0) {
      throw new Exception("No constructors found; is " + parent + " an interface?");
    }

    // now, for each constructor, we have to create a new thing.
    for (int i = 0; i < length; i++) {
      Constructor c = conList[i];
      int mods = c.getModifiers();
      Class[] params = c.getParameterTypes();
      Class[] exceps = c.getExceptionTypes();

      sb.append(NEWLINE);

      // create the modifies and name:
      // "public FooClass"
      sb.append(INDENT);
      sb.append(Modifier.toString(mods));
      sb.append(" " + getOutputName());
    
      // now, get all the params, if any
      // " (String p0, int p1)"
      sb.append(" (");
      for (int j = 0; j < params.length; j++) {
	Class param = params[j];
	if (j > 0) {
	  sb.append(", ");
	}
	sb.append(param.getName());
	sb.append(" p" + j);
      }

      sb.append(")");

      // now get all the exceptions
      if (exceps.length > 0) {
	sb.append (" throws ");
	for (int j = 0; j < exceps.length; j++) {
	  Class ex = exceps[j];
	  if (j > 0) {
	    sb.append(", ");
	  }
	  sb.append(ex.getName());
	}
      }

      // finally, close with a brace
      sb.append(" {");
      sb.append(NEWLINE);

    
      // first line is now done - whew!
      // Now, simply call super
      sb.append(INDENT);
      sb.append(INDENT);
      sb.append("super(");
      
      for (int j = 0; j < params.length; j++) {
	Class param = params[j];
	if (j > 0) {
	  sb.append(", ");
	}
	sb.append(" p" + j);
      }
      sb.append(");");

      // now put in the closing brace on the next line
      // and we're done.  Move on to the next constructor, if any
      sb.append(NEWLINE);
      sb.append(INDENT);
      sb.append("}");
    }

    return sb.toString();
  }

  public String overrideConnection() {
    StringBuffer sb = new StringBuffer();
    sb.append(overrideConnection("", ""));
    sb.append(overrideConnection("String username, String password", "username, password"));
    return sb.toString();
  }

  public String overrideConnection(String signature, String names) {
    String value = "" + 

    NEWLINE +

    INDENT + 
    "public Connection getConnection(" + signature + ") throws SQLException {" + 
    NEWLINE +

    INDENT + 
    INDENT + 
     "return P6SpyDriverCore.wrapConnection(super.getConnection(" + names + "));" +
    NEWLINE +

    INDENT + 
    "};" +
    NEWLINE +
    "";

    return value;
  }

  public String writeFooter() {
    return NEWLINE + "}" + NEWLINE;
  }
}

⌨️ 快捷键说明

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