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

📄 mapgenerator.java

📁 人力资源管理系统主要包括:人员管理、招聘管理、培训管理、奖惩管理和薪金管理五大管理模块。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
//$Id: MapGenerator.java,v 1.1 2003/05/26 06:40:07 maxcsaucdk Exp $package net.sf.hibernate.tool.class2hbm;import java.io.BufferedReader;import java.io.FileWriter;import java.io.InputStreamReader;import java.io.Reader;import java.io.StreamTokenizer;import java.io.Writer;import java.lang.reflect.Constructor;import java.util.Hashtable;import java.util.Vector;import net.sf.hibernate.PersistentEnum;import net.sf.hibernate.type.Type;import net.sf.hibernate.type.TypeFactory;import net.sf.hibernate.util.StringHelper;/** * <P> MapGenerator provides a mechanism to produce a Hibernate XML * OR-Mapping from compiled classes. It does this using Java reflection to * find <b>properties</b> to be persisted in the classes, and using the * types of the properties to further guide the reflection. * <P> The usual way to use MapGenerator is to place your compiled * classes on the classpath, and start Java in the MapGenerator * static main() method. As arguments you can either supply all of the * classes to be processed, or the single argument <code>--interact</code> * which will provide an interactive prompt/response console. Using this * mode you can set the UID property name for each class using the * <code>uid=XXX</code> command where XXX is the UID property name. Other * command alternatives are simply a fully qualified class name, or the * command <code>done</code> which emits the XML and terminates. * * <P> MapGenerator will reject classes that are not * <b>hibernate perisitable</b>. To be hibernate persistable a class must * not be a primitive type, an array, an interface, or a nested class, and * it must have a default (zero argument) constructor. * * <P> MapGenerator will climb the superclass chain of all added * classes attempting to add as many hibernate perisitable superclasses * as possible to the same database table. The search stops as soon as a * property is found that has a name appearing on the list of candidate * UID names, and has type String, Long, or long. * * <P> Properties are discovered when there are two methods in the class, * a setter and a getter, where the type of the setter's single argument is * the same as the return type of the zero argument getter, and the setter * returns <code>void</code>. Furthermore, the setter's name must start with * the string "set" and either the getter's name starts with "get" or the * getter's name starts with "is" and the type of the property is * <code>boolean</code>. In either case, the remainder of their names must * match. This matching portion is the name of the property, except that the * initial character of the property name is made lower case if the second * letter is lower case. * * <P> The rules for determing the database type of each property are as * follows. If the Java type is Hibernate.basic(), then the property is a * simple column of that type. For hibernate.type.Type custom types and * PersistentEnum a simple column is used as well. If the property type * is an array, then a Hibernate array is used, and MapGenerator * attempts to reflect on the array element type. If the property has * type java.util.List, java.util.Map, or java.util.Set, then the * corresponding Hibernate types are used, but MapGenerator cannot * further process the insides of these types. If the property's type is * any other class, MapGenerator defers the decision on the database * representation until all classes have been processed (i.e., until * <code>done</code> is typed at the interactive prompt. At this point, if * the class was discovered through the superclass search described above, * then the property is an association (many-to-one). If the class has any * properties, then it is a component. Otherwise it is serializable, or * not persistable. * * * @version 	1.x * @author		<a href="mailto:doug.currie@alum.mit.edu">e</a> */public class MapGenerator {		private static String defaultKeys[] = { "uid", "UID", "id", "ID", "key", "KEY", "pk", "PK" };		private ClassLoader classLoader;	private boolean verbose = true;		public static void main(String[] args) {				Writer outputWriter=null;		int len = args.length;		if( len == 0 ) {			System.out.println( "<!-- No args provided, no classes reflected! -->" );		}		else if( len == 1 && "--interact".equals(args[0]) ){			MapGenerator map = new MapGenerator( null, ClassLoader.getSystemClassLoader() );			map.interact();		}		else {			//MapGenerator map = new MapGenerator( args );			MapGenerator map = new MapGenerator( null, ClassLoader.getSystemClassLoader() );			for( int i=0; i<len; i++ ) {				if(args[i].startsWith("--")) {										/* Shouldn't all of these options be else if? (Everman) */					if(args[i].startsWith("--setUID=")) {						map.setUID( args[i].substring(9) );					}					else if(args[i].startsWith("--addUID=")) {						map.addUID( args[i].substring(9) );					}					else if(args[i].startsWith("--depth=")) {						try {							map.maxDepth = Integer.parseInt( args[i].substring(8) );						}						catch( NumberFormatException e ) {							System.err.println("<!-- Can't set maxDepth "							+ e.getMessage() + "-->");						}					}					else if(args[i].equals("--quiet")) {						map.verbose = false;					}					else if(args[i].startsWith("--output=")) {						outputWriter = makeWriter( args[i].substring(9) );					}										//Next option added by Eric Everman 5-16-2002					//See protected abstractClasses for details					else if(args[i].startsWith("--abstract=")) {						map.abstractClasses.put(args[i].substring(11), StringHelper.EMPTY_STRING);					}				}				else {					map.addClass( args[i], true ); // ignore verbose here?				}			}			map.writeXML(outputWriter);		}	}		public void writeXML(Writer outputWriter) {		String xml = getXML();		if( outputWriter != null ) {			try { outputWriter.write( xml ); outputWriter.flush(); }			catch( Exception e ) { outputWriter = null; }		}		if( verbose == true || outputWriter == null ) {			System.out.println( xml );		}	}		private static FileWriter makeWriter( String fileName ) {		try {			FileWriter fw = new FileWriter( fileName );			return fw;		}		catch(Exception e) {			System.err.println("<!-- Error making FileWriter " + e.getMessage() + "-->");			//e.printStackTrace();			return null;		}	}		/** how low will you go? the depth of component nesting followed	 */	protected int maxDepth = 0;		/** candidate UID property names; presence of one of these with a	 *  supported type (String, Long, long) will stop	 *  the reflect code from chasing the superclass chain any further	 *  except to find additional properties (not classes)	 */	protected String[] niceKeys = defaultKeys;		/** the XML we make; this buffer is shared by all string emitters	 *  created by this MapGenerator instance	 */	protected StringBuffer buf;		/** a cache of seen reflected classes; Class -> ReflectedClass	 *  <br>also necessary to avoid infinite regress	 */	protected Hashtable rClasses;		/**	 * <p>A list of class names which are treated as 'abstract' in that they are not	 * allowed to be root classes.  Classes added to this list will have their	 * properties (and their superclass properties) mapped to any subclasses	 * extending the base classes listed here.	 *	 * Documentation notes:	 * --abstract=<fully.qualified.class.name>	 * use to add a class which will have its properties persisted only by its	 * subclasses.  Multiple --abstract entries can be used, but they must all	 * come before any class names to be mapped.  Classes listed by this option	 * do not need to actually be abstract in the Java language sense.	 *	 *	 * <p>Note that the name abstract is somewhat misleading as abstract classes	 * can otherwise be handled as a top level class by Hibernate.	 *	 * @author Eric Everman 5-16-2002	 */	protected Hashtable abstractClasses = new Hashtable(5);		/** a cache of emitted components for the current property; Class -> Integer	 *  <br>also necessary to avoid infinite regress by tracking	 *  the depth of data recursion	 */	protected Hashtable cycleBuster;		/** just to prevent duplicate table names; String -> Integer	 */	private Hashtable usedTableNames;		/** just to prevent duplicate column names; String -> Integer	 */	private Hashtable usedColumnNames;		/** the top level collections; <br> currently just a placeholder	 *  because top level collections are not supported	 */	private Vector entities;		/** the top level (most souper) ReflectedClasses;	 *  <br>these are the classes eventually dumped as <class> in the XML	 */	private Vector roots;		private char[] prefix = StringHelper.repeat("\t", 100).toCharArray();		/** the only MapGenerator constructor	 *	 * @param className an array of fully specified class names to add, or null	 */	public MapGenerator( String[] className, ClassLoader loader ) {		setClassLoader(loader);		reset();		if( className != null ) {			int len = className.length;			for( int i=0; i<len; i++ ) {				addClass( className[i], true );			}		}	}		private String interact_usage = "usage: class.name | uid=<newUID> | done";		/** won't somebody please make a GUI?	 */	private void interact() {		Reader r = new BufferedReader(new InputStreamReader(System.in));		StreamTokenizer st = new StreamTokenizer(r);		st.wordChars( 33, 126 );		System.out.println(interact_usage);		System.out.print("? ");		boolean allIsWell = true;		while( allIsWell ) {			int tt;			try {				tt = st.nextToken();			}			catch( Exception e ) {				System.out.println("IOException; done");				tt = StreamTokenizer.TT_EOF;			}			switch( tt ) {				case StreamTokenizer.TT_EOF: allIsWell = false; break;				case StreamTokenizer.TT_EOL: st.eolIsSignificant(false); break;				case StreamTokenizer.TT_NUMBER:				System.out.println("number!? ");				System.out.println(interact_usage);				System.out.print("? ");				break;				case StreamTokenizer.TT_WORD:				String name = st.sval;				if( "done".equals(name) ) {					allIsWell = false;				}				else if( name.startsWith("uid=") ) {					String uid = name.substring(4);					System.out.print("niceKey(" + uid + ")=>" ); // debug					addUID( uid );					for( int i=0; i<niceKeys.length; i++ ) {						System.out.print(" ");						System.out.print(niceKeys[i]);					}					System.out.print("\n? ");				}				else {					System.out.println("addClass(" + name + ")"); // debug					addClass( name, true );					System.out.print("? ");				}				break;				default: /* ignore */ break;			}		}		System.out.println( getXML() );	}		/**	 * start over	 */	public void reset() {		this.buf = new StringBuffer();		this.roots = new Vector();		this.entities = new Vector();		this.rClasses = new Hashtable();		this.usedTableNames = new Hashtable();		buf.append("<?xml version=\"1.0\"?>\n")		.append("<!DOCTYPE hibernate-mapping PUBLIC\n")		.append("\t\"-//Hibernate/Hibernate Mapping DTD//EN\"\n")		.append("\t\"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd\">\n");	}		/**	 * add a class to the map and reflect upon it	 * @param className a fully qualified class name in the class path	 * @param verbose squawk (as a comment into the final XML) if	 *                  there are problems with this class	 */	public void addClass( String className, boolean verbose ) {		Class clazz = checkClassNamed( className, verbose );		if( clazz != null ) {			ReflectedClass rc = reallyAdd( clazz, verbose );			if( rc == null && verbose ) {				buf.append("<!-- ")				.append(clazz.getName())				.append(" cannot be added, no UID found! -->\n");			}		}	}		/**	 * set the list of candidate UIDs to a single name	 * @param uid the new candidate UID	 */	public void setUID( String uid ) {		String[] uida = { uid };		niceKeys = uida;	}		/**	 * add a new name to the front of the list of candidate UIDs

⌨️ 快捷键说明

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