📄 finderrenderer.java
字号:
package net.sf.hibernate.tool.hbm2java;import java.io.PrintWriter;import java.io.StringWriter;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;/** * <p>Title: Basic Finder Generator for Hibernate 2</p> * <p>Description: Generate basic finders for hibernate properties. * This requires two things in the hbm.xml files. * * The first is an indication of which fields you want to generate finders for. * You indicate that with a meta block inside a property tag such as * * <property name="name" column="name" type="string"> * <meta attribute="finder-method">findByName</meta> * </property> * * The finder method name will be the text enclosed in the meta tags. * * If you want to generate a finder based on a join you can do something like this: * * <set name="games" inverse="true" lazy="true" table="GamePlayers"> * <meta attribute="foreign-finder-name">findSavedGames</meta> * <meta attribute="foreign-finder-field">save</meta> * <meta attribute="foreign-join-field">players</meta> * <key column="playerID"/> * <many-to-many class="com.whatever.Game" column="gameID"/> * </set> * * Where foreign-finder-name will be the name of the finder when generated, foreign-finder-field is the field in * the foreign class that you will want as a paramter to the finder (the criteria in the query) and foreign-join-field * is the field in teh foreign class that joins to this object (in case there are more than one collection of these * objects in the foreign class). * * After you've defined your finders, the second thing to do is to create a config file for hbm2java of the format: * * <codegen> * <generate renderer="net.sf.hibernate.tool.hbm2java.BasicRenderer"/> * <generate suffix="Finder" renderer="net.sf.hibernate.tool.hbm2java.FinderRenderer"/> * </codegen> * * And then use the param to hbm2java --config=xxx.xml where xxx.xml is the config file you * just created. * * An optional parameter is meta tag at the class level of the format: * * <meta attribute="session-method">com.whatever.SessionTable.getSessionTable().getSession();</meta> * * Which would be the way in which you get sessions if you use the Thread Local Session pattern * like I do. * </p> * <p>Copyright: Copyright (c) 2003</p> * @author Matt Hall (matt2k(at)users.sf.net) * @author Max Rydahl Andersen (small adjustments and bugfixes) * @version 1.0 */public class FinderRenderer extends AbstractRenderer { private static final String MT_FINDERMETHOD = "finder"; private static final String MT_FOREIGNFINDERMETHOD = "foreign-finder-name"; private static final String MT_FOREIGNFINDERFIELD = "foreign-finder-field"; private static final String MT_FOREIGNJOINFIELD = "foreign-join-field"; private static Log log = LogFactory.getLog(FinderRenderer.class); /** * Render finder classes. *@param classMapping *@param class2classmap *@param mainwriter *@exception Exception */ public void render(String savedToPackage, String savedToClass, ClassMapping classMapping, Map class2classmap, PrintWriter mainwriter) throws Exception { genPackageDelaration(savedToPackage, classMapping, mainwriter); mainwriter.println(); // switch to another writer to be able to insert the actually // used imports when whole class has been rendered. StringWriter strWriter = new StringWriter(); PrintWriter writer = new PrintWriter(strWriter); writer.println("/** Automatically generated Finder class for " + savedToClass + ".\n" +
" * @author Hibernate FinderGenerator " +
" **/"); String classScope = "public"; writer.print(classScope + " class " + savedToClass); // always implements Serializable writer.print(" implements Serializable"); writer.println(" {"); writer.println(); // switch to another writer to be able to insert the // veto- and changeSupport fields StringWriter strPropWriter = new StringWriter(); PrintWriter propWriter = new PrintWriter(strPropWriter); doFinders(classMapping, class2classmap, propWriter); propWriter.println("}"); writer.print(strPropWriter.toString()); // finally write the imports doImports(classMapping, mainwriter); mainwriter.print(strWriter.toString()); } /** * Create finders for properties that have the <meta atttribute="finder-method"> * finderName</meta> block defined. Also, create a findAll(Session) method. * *@param classMapping *@param class2classmap *@param writer */ public void doFinders(ClassMapping classMapping, Map class2classmap, PrintWriter writer) { // Find out of there is a system wide way to get sessions defined String sessionMethod = classMapping.getMetaAsString("session-method").trim(); // fields for (Iterator fields = classMapping.getFields().iterator(); fields.hasNext(); ) { Field field = (Field) fields.next(); if (field.getMeta(MT_FINDERMETHOD) != null) { String finderName = field.getMetaAsString(MT_FINDERMETHOD); if ("".equals(sessionMethod)) { // Make the method signature require a session to be passed in writer.println(" public static List " + finderName + "(Session session, " + getTrueTypeName(field, class2classmap) + " " + field.getName() + ") " + "throws SQLException, HibernateException {"); } else { // Use the session method to get the session to execute the query writer.println(" public static List " + finderName + "(" + getTrueTypeName(field, class2classmap) + " " + field.getName() + ") " + "throws SQLException, HibernateException {"); writer.println(" Session session = " + sessionMethod); } writer.println(" List finds = session.find(\"from " + classMapping.getName() + " as " + classMapping.getName().toLowerCase() + " where " + classMapping.getName().toLowerCase() + "." + field.getName() + "=?\", " + getFieldAsObject(false, field) + ", " + getFieldAsHibernateType(false, field) + ");"); writer.println(" return finds;"); writer.println(" }"); writer.println(); } else if (field.getMeta(MT_FOREIGNFINDERMETHOD) != null) { String finderName = field.getMetaAsString(MT_FOREIGNFINDERMETHOD); String fieldName = field.getMetaAsString(MT_FOREIGNFINDERFIELD); String joinFieldName = field.getMetaAsString(MT_FOREIGNJOINFIELD); // Build the query QueryBuilder qb = new QueryBuilder(); qb.setLocalClass(classMapping); qb.setForeignClass(field.getForeignClass(), class2classmap, joinFieldName); ClassMapping foreignClass = (ClassMapping) class2classmap.get(field.getForeignClass().getFullyQualifiedName()); if (foreignClass == null) { // Can't find the class, return log.error("Could not find the class "+field.getForeignClass().getName()); return; } Field foreignField = null; for (Iterator foreignFields = foreignClass.getFields().iterator(); foreignFields.hasNext();) { Field f = (Field) foreignFields.next(); if (f.getName().equals(fieldName)) { foreignField = f; } } if (foreignField != null) { qb.addCritera(foreignClass, foreignField, "="); } else { // Can't find the field, return log.error("Could not find the field "+fieldName+" that was supposed to be in class " +field.getForeignClass().getName()); return; } MethodSignatureBuilder msb = new MethodSignatureBuilder(finderName, "List", "public static"); if ("".equals(sessionMethod)) { // Make the method signature require a session to be passed in msb.addParam("Session session");/* writer.println(" public static List " + finderName + "(Session session, " + getTrueTypeName(foreignField, class2classmap) + " " + foreignField.getName() + ") " + "throws SQLException, HibernateException {");*/ } else { // Use the session method to get the session to execute the query/* writer.println(" public static List " + finderName + "(" + getTrueTypeName(foreignField, class2classmap) + " " + foreignField.getName() + ") " + "throws SQLException, HibernateException {"); writer.println(" Session session = " + sessionMethod);*/ } // Always need the object we're basing the query on msb.addParam(classMapping.getName() + " " + classMapping.getName().toLowerCase()); // And the foreign class field msb.addParam(getTrueTypeName(foreignField, class2classmap) + " " + foreignField.getName()); msb.addThrows("SQLException"); msb.addThrows("HibernateException"); writer.println(" "+msb.buildMethodSignature()); if (!"".equals(sessionMethod)) { writer.println(" Session session = " + sessionMethod); } writer.println(" List finds = session.find(\"" + qb.getQuery() + "\", " + qb.getParamsAsString() + ", " + qb.getParamTypesAsString() + ");"); writer.println(" return finds;"); writer.println(" }"); writer.println(); } } // Create the findAll() method if ("".equals(sessionMethod)) { writer.println(" public static List findAll" + "(Session session) " + "throws SQLException, HibernateException {"); } else { writer.println(" public static List findAll() " + "throws SQLException, HibernateException {"); writer.println(" Session session = " + sessionMethod); } writer.println(" List finds = session.find(\"from " + classMapping.getName() + " in class " + classMapping.getPackageName() + "." + classMapping.getName() + "\");"); writer.println(" return finds;"); writer.println(" }"); writer.println(); } static Map primitiveToObject = new HashMap(); { primitiveToObject.put("char", "Character"); primitiveToObject.put("byte", "Byte"); primitiveToObject.put("short", "Short"); primitiveToObject.put("int", "Integer"); primitiveToObject.put("long", "Long"); primitiveToObject.put("boolean", "Boolean"); primitiveToObject.put("float", "Float"); primitiveToObject.put("double", "Double"); } /** * Generate the imports for the finder class. * *@param classMapping *@param writer */ public void doImports(ClassMapping classMapping, PrintWriter writer) { // imports is not included from the class it self as this is a separate generated class. /* classMapping.getImports().add("java.io.Serializable"); for (Iterator imports = classMapping.getImports().iterator(); imports.hasNext(); ) { writer.println("import " + imports.next() + ";"); }*/ // Imports for finders writer.println("import java.io.Serializable;"); writer.println("import java.util.List;"); writer.println("import java.sql.SQLException;"); writer.println(); // * import is bad style. But better than importing classing that we don't necesarrily uses... writer.println("import net.sf.hibernate.*;"); writer.println("import net.sf.hibernate.type.Type;");// writer.println("import net.sf.hibernate.Hibernate;");// writer.println("import net.sf.hibernate.HibernateException;"); writer.println(); } /** * Gets the fieldAsObject attribute of the FinderRenderer object * *@param prependThis *@param field *@return */ public static String getFieldAsObject(boolean prependThis, Field field) { ClassName type = field.getClassType(); if (type != null && type.isPrimitive() && !type.isArray()) { String typeName = (String) primitiveToObject.get(type.getName()); typeName = "new " + typeName + "( "; typeName += prependThis ? "this." : ""; return typeName + field.getName() + " )"; } return field.getName(); } /** * Coversion map for field types to Hibernate types, might be good to move * this to some other more general class */ static Map hibType = new HashMap(); { hibType.put("char", "Hibernate.CHARACTER"); hibType.put("byte", "Hibernate.BYTE"); hibType.put("short", "Hibernate.SHORT"); hibType.put("int", "Hibernate.INTEGER"); hibType.put("long", "Hibernate.LONG"); hibType.put("Integer", "Hibernate.INTEGER"); hibType.put("boolean", "Hibernate.BOOLEAN"); hibType.put("float", "Hibernate.FLOAT"); hibType.put("double", "Hibernate.DOUBLE"); hibType.put("String", "Hibernate.STRING"); } /** * Return the hibernate type string for the given field * *@param prependThis *@param field *@return */ public static String getFieldAsHibernateType(boolean prependThis, Field field) { ClassName type = field.getClassType(); String hibTypeString = (String) hibType.get(type.getName()); if (hibType != null) { return hibTypeString; } else { return "Hibernate.OBJECT"; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -