Package org.beangle.model.comment

Source Code of org.beangle.model.comment.SqlCommentGenerator

/* Copyright c 2005-2012.
* Licensed under GNU  LESSER General Public License, Version 3.
* http://www.gnu.org/licenses
*/
package org.beangle.model.comment;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.beangle.collection.CollectUtils;
import org.beangle.lang.StrUtils;
import org.beangle.model.persist.DefaultTableNamingStrategy;

import com.sun.javadoc.AnnotationDesc;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.DocErrorReporter;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.RootDoc;

/**
* 扫描@Entity头和字段的注释,生成sql语句
*
* @author chaostone
* @version $Id: ListTags.java Jul 30, 2011 12:42:54 AM chaostone $
*/

public class SqlCommentGenerator {

  private static final String CONFIG = "config";
  private static final String SQLFILE = "file";

  private static DefaultTableNamingStrategy strategy;
  private static Set<String> primaryTypes = CollectUtils.newHashSet("String", "int", "long", "float",
      "double", "boolean");
  // reserved types
  private static Set<String> collectionTypes = CollectUtils.newHashSet("Set", "Map", "List");

  public static boolean start(RootDoc root) throws IOException {
    ClassDoc[] classes = root.classes();

    // out files
    String commentFileName = getFileOption(root.options());
    String commentLogFileName = System.getProperty("java.io.tmpdir") + "/comment_log.txt";
    BufferedWriter out = new BufferedWriter(new FileWriter(commentFileName));
    BufferedWriter log = new BufferedWriter(new FileWriter(commentLogFileName));

    // nocomment
    int nocomment = 0;
    StringBuilder nocomments = new StringBuilder();

    for (int i = 0; i < classes.length; i++) {
      if (!isEntity(classes[i])) continue;
      ClassDoc classDoc = classes[i];

      // generate table name
      String tableName = getTableName(classDoc);
      if (null == tableName) {
        System.out.println("Cannot find tablenam for " + classDoc.qualifiedName());
        continue;
      }
      // find table comment
      String tableComment = processComment(classDoc.commentText());
      if (null != tableComment) {
        out.write("\ncomment on table " + tableName + " is '" + tableComment + "';\n");
      } else {
        nocomments.append(classDoc.qualifiedName()).append('\n');
        nocomment++;
      }

      // process classDoc and it's superClassDoc
      while (null != classDoc) {
        if (classDoc.simpleTypeName().equals("Object")) break;
        FieldDoc[] fields = classDoc.fields(false);
        for (int j = 0; j < fields.length; j++) {
          FieldDoc field = fields[j];
          if (field.isTransient() || field.isStatic() || field.isEnum()) continue;
          String simpleTypeName = field.type().simpleTypeName();

          String columnComment = processComment(fields[j].commentText());
          if (null != columnComment) {
            if (collectionTypes.contains(simpleTypeName)) {
              String joinTable = collectionTable(classDoc, tableName, field);
              if (null != joinTable) {
                out.write("\ncomment on table " + joinTable + " is '" + tableComment + "-"
                    + columnComment + "';\n");
              }
            } else {
              String columnName = getColumnName(fields[j]);
              if (isEntity(field)) {
                columnName = columnName + "_id";
                columnComment = columnComment + "ID";
              }
              out.write("comment on column " + tableName + "." + columnName + " is '"
                  + columnComment + "';\n");
            }
          } else {
            if (null != fields[j].position() && fields[j].position().column() > 0) {
              nocomments.append(classDoc.qualifiedName()).append('.').append(fields[j].name())
                  .append('\n');
              nocomment++;
            }
          }
        }
        classDoc = (null == classDoc.superclassType()) ? null : classDoc.superclassType()
            .asClassDoc();
      }
    }

    // summary
    if (nocomment > 0) log.write("Find " + nocomment + " properties without comment.\n");
    else log.write("Congratulations! All entity properties have valid comment.\n");
    log.write(nocomments.toString());

    // cleanup
    out.close();
    log.close();
    System.out.println("Generated comment sqlfile:" + commentFileName);
    System.out.println("Generated comment logfile:" + commentLogFileName);
    return true;
  }

  private static String processComment(String comment) {
    if (StringUtils.isEmpty(comment)) return null;
    int newlineIndex = comment.indexOf('\n');
    if (newlineIndex > 0) {
      comment = comment.substring(0, newlineIndex);
    }
    return comment.trim();
  }

  private static String collectionTable(ClassDoc classDoc, String tableName, FieldDoc fieldDoc) {
    String joinTable = null;
    AnnotationDesc[] anns = fieldDoc.annotations();
    if (null != anns && anns.length > 0) {
      boolean find = false;
      for (AnnotationDesc anno : anns) {
        if ("ManyToMany".equals(anno.annotationType().name())) {
          find = true;
          AnnotationDesc.ElementValuePair[] pairs = anno.elementValues();
          if (null != pairs && pairs.length > 0) {
            for (AnnotationDesc.ElementValuePair pair : pairs) {
              if (pair.element().name().equals("mappedBy")) {
                find = false;
                break;
              }
            }
          }
        }
        if ("JoinTable".equals(anno.annotationType().name())) {
          AnnotationDesc.ElementValuePair[] pairs = anno.elementValues();
          if (null != pairs && pairs.length > 0) {
            for (AnnotationDesc.ElementValuePair pair : pairs) {
              if (pair.element().name().equals("name")) {
                joinTable = pair.value().value().toString();
                break;
              }
            }
          }
        }
      }
      if (find && null == joinTable) {
        joinTable = strategy.collectionToTableName(classDoc.qualifiedName(), tableName,
            fieldDoc.name());
      }
    }
    return joinTable;
  }

  private static boolean isEntity(ClassDoc classDoc) {
    AnnotationDesc[] anns = classDoc.annotations();
    if (null == anns || anns.length == 0) return false;
    for (AnnotationDesc anno : anns) {
      if ("Entity".equals(anno.annotationType().name())) return true;
    }
    return false;
  }

  private static boolean isEntity(FieldDoc fieldDoc) {
    String className = fieldDoc.type().qualifiedTypeName();
    if (StringUtils.startsWith(className, "java.")) return false;
    if (primaryTypes.contains(className)) return false;
    AnnotationDesc[] anns = fieldDoc.annotations();
    if (null != anns && anns.length > 0) {
      for (AnnotationDesc anno : anns) {
        if ("Enumerated".equals(anno.annotationType().name())
            || "Embedded".equals(anno.annotationType().name())) return false;
      }
    }
    return true;
  }

  private static String getTableName(ClassDoc classDoc) {
    AnnotationDesc[] anns = classDoc.annotations();
    if (null != anns && anns.length >= 0) {
      for (AnnotationDesc anno : anns) {
        if ("Table".equals(anno.annotationType().name())) {
          AnnotationDesc.ElementValuePair[] pairs = anno.elementValues();
          if (null != pairs && pairs.length > 0) {
            for (AnnotationDesc.ElementValuePair pair : pairs) {
              if (pair.element().name().equals("name")) return pair.value().value().toString();
            }
          }
        }
      }
    }
    return strategy.classToTableName(classDoc.qualifiedName());
  }

  private static String getColumnName(FieldDoc fieldDoc) {
    AnnotationDesc[] anns = fieldDoc.annotations();
    if (null != anns && anns.length >= 0) {
      for (AnnotationDesc anno : anns) {
        if ("Column".equals(anno.annotationType().name())) {
          AnnotationDesc.ElementValuePair[] pairs = anno.elementValues();
          if (null != pairs && pairs.length > 0) {
            for (AnnotationDesc.ElementValuePair pair : pairs) {
              if (pair.element().name().equals("name")) return pair.value().value().toString();
            }
          }
        }
      }
    }
    return StrUtils.unCamel(fieldDoc.name(), '_', true);
  }

  /**
   * Doclet method called by Javadoc to recognize
   * custom parameters.
   */
  public static int optionLength(String option) {
    if (option.equals("-" + CONFIG)) return 2;
    if (option.equals("-" + SQLFILE)) return 2;
    else return 0;
  }

  public static boolean validOptions(String options[][], DocErrorReporter reporter) throws IOException {
    System.out.println("start valid options...");
    strategy = new DefaultTableNamingStrategy();
    for (int i = 0; i < options.length; i++) {
      String[] opt = options[i];
      if (opt[0].equals("-file")) {
        FileUtils.touch(new File(opt[1]));
      } else if (opt[0].equals("-config")) {
        String fileName = opt[1];
        if (null == fileName) continue;
        File file = new File(fileName);
        if (!file.exists()) {
          reporter.printError("config file [" + fileName + "] not exists.");
          return false;
        } else {
          ((DefaultTableNamingStrategy) strategy).addConfig(file.toURI().toURL());
        }
      }
    }
    Enumeration<URL> urls = Thread.currentThread().getContextClassLoader()
        .getResources("/META-INF/beangle/table.properties");
    while (urls.hasMoreElements()) {
      strategy.addConfig(urls.nextElement());
    }
    if (strategy.getPatterns().isEmpty()) {
      reporter.printError("Cannot find table.properties in classpath or options. Using -config /your/path/to/table.properties");
      return false;
    } else {
      System.out.println(strategy);
      return true;
    }
  }

  private static String getFileOption(String[][] options) {
    String tagName = null;
    for (int i = 0; i < options.length; i++) {
      String[] opt = options[i];
      if (opt[0].equals("-file")) {
        tagName = opt[1];
      }
    }
    if (null == tagName) tagName = System.getProperty("java.io.tmpdir") + "/comment.sql";
    return tagName;
  }
}
TOP

Related Classes of org.beangle.model.comment.SqlCommentGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.