Package org.apache.empire.db.codegen

Source Code of org.apache.empire.db.codegen.WriterService

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.empire.db.codegen;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.DataType;
import org.apache.empire.db.DBColumn;
import org.apache.empire.db.DBRecord;
import org.apache.empire.db.DBRowSet;
import org.apache.empire.db.DBTable;
import org.apache.empire.db.DBTableColumn;
import org.apache.empire.db.DBView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This class is used by the velocity templates.
*/
public class WriterService {

  private static final Logger log = LoggerFactory.getLogger(WriterService.class);

  private final CodeGenConfig config;
  private final Set<String> dbrecMethodNames;
 
  public WriterService(CodeGenConfig config)
  {
    this.dbrecMethodNames = loadDBRecordMethodNames();
    this.config = config;
  }
 
  /**
   * Some g/setters like getState() can conflict with DBRecord
   * methods. To check for conflicts, we'll need to know
   * the method names.
   * @return the DBRecord method's names
   */
  private Set<String> loadDBRecordMethodNames()
  {
    Method[] dbrecMethods = DBRecord.class.getMethods();
    Set<String> names = new HashSet<String>(dbrecMethods.length);
    for(Method method : dbrecMethods)
    {
      names.add(method.getName());
    }
    return names;
  }
 
  /**
   * Returns the instance name of a table
   */
  public String getTableName(DBTable t) {
    return StringUtils.toString(config.getTableNamePrefix(), "")
       + deriveAttributeName(t.getName());
  }
 
  /**
   * Returns the instance name of a view
   */
  public String getViewName(DBView v) {
    return StringUtils.toString(config.getViewNamePrefix(), "")
       + deriveAttributeName(v.getName());
  }
 
  /**
   * Returns the instance name of a rowset
   */
  public String getRowsetName(DBRowSet r) {
    // use same as table
    return StringUtils.toString(config.getTableNamePrefix(), "")
        + deriveAttributeName(r.getName());
  }
 
  /**
   * Returns the instance name of a column
   */
  public String getColumnName(DBColumn c) {
    return StringUtils.toString(config.getColumnNamePrefix(), "")
       + deriveAttributeName(c.getName());
  }

  /**
   * Returns the java table class name for a given table name.
   */
  public String getTableClassName(String tableName)
  {
    return StringUtils.toString(config.getTableClassPrefix(), "")
      + deriveClassName(tableName)
      + StringUtils.toString(config.getTableClassSuffix(),"");
  }

  /**
   * Returns the java table class name for a given view name.
   */
  public String getViewClassName(String viewName)
  {
    return StringUtils.toString(config.getViewClassPrefix(), "")
      + deriveClassName(viewName)
      + StringUtils.toString(config.getViewClassSuffix(), "");
  }
 
  /**
   * Returns the java record class name for a given table name.
   *
   * @param tableName the table name
   */
  public String getRecordClassName(String tableName)
  {
    return deriveClassName(tableName) + "Record";
  }

  /**
   * Returns the "getter" name for a given DBColumn.
   * @param column the column
   */
  public String getAccessorName(DBColumn column)
  {
    return deriveAccessorName(column.getName(), getJavaType(column));
  }

  /**
   * Returns the "setter" name for a given DBColumn
   * @param column the column
   */
  public String getMutatorName(DBColumn column)
  {
    return deriveMutatorName(column.getName(), getJavaType(column));
  }
 
  /**
   * Returns the attribute name for a given DBColumn
  public String getAttributeName(DBColumn c)
  {
    return deriveAttributeName(c.getName());
  }
   */

  /**
   * Returns whether the given table uses BigDecimal class or not. Velocity
   * uses this information to generate the neccessary import expression.
   *
   * @param table the table to inspect
   */
  public boolean hasBigDecimalField(DBTable table)
  { 
    for (DBColumn column : table.getColumns())
    {
      if (getJavaType(column) == BigDecimal.class)
      {
        return true;
      }
    }
    return false;
  }

  /**
   * Returns whether the given table uses Date class or not. Velocity
   * uses this information to generate the neccessary import expression.
   *
   * @param table the table to inspect
   */
  public boolean hasDateField(DBTable table)
  {
    for (DBColumn column : table.getColumns())
    {
      if (getJavaType(column) == Date.class)
      {
        return true;
      }
    }
    return false;
  }

  /**
   * Returns whether the given table has a locking column or not.
   *
   * @param table the table to inspect
   */
  public boolean hasLockingColumn(DBTable table)
  {
    return table.getTimestampColumn() != null;
  }

  /**
   * Returns the corresponding java type of the given empire DataType.
   *
   * @param column the column to get the type for
   */
  public Class<?> getJavaType(DBColumn column)
  {
    DataType type = getDataType(column);
    // We added the attribute of original datatype to AUTOINC columns
    // in CodeGenParser.addColumn(). Now we need to use it so that
    // the g/setters deal with the right Java type.
   
    // If the original data type was not set as an attribute for some
    // reason this will just fall through to the bottom and
    // return "Byte[]", so no problem.
    if (DataType.AUTOINC.equals(type) && null != column.getAttribute("AutoIncDataType"))
    {
      type = (DataType)column.getAttribute("AutoIncDataType");
    }
   
    // TODO might be better to add this to the enum
    // TODO use primitives for non-nullable columns?
    switch(type){
    case INTEGER:
      return Long.class;
    case TEXT:
      return String.class;
    case DATE:
      return Date.class;
    case DATETIME:
      return Date.class;
    case CHAR:
      return String.class;
    case FLOAT:
      return Double.class;
    case DECIMAL:
      return BigDecimal.class;
    case BOOL:
      return Boolean.class;
    case CLOB:
      return String.class;
    case BLOB:
      return Byte[].class;
    case UNKNOWN:
      return Byte[].class;
    default:
      log.warn("SQL column type " + type.toString() + " not supported, falling back to byte array.");
      return Byte[].class;
    }
  }

  /**
   * Returns the empire DataType of the given DBColumn.
   */
  public DataType getDataType(DBColumn c)
  {
    DBTableColumn dbC = (DBTableColumn) c;
    return dbC.getDataType();
  }

  /**
   * Returns the default value of the given DBColumn.
   */
  public String getDefaultValue(DBColumn c)
  {
    DBTableColumn dbC = (DBTableColumn) c;
    Object val = dbC.getDefaultValue();
    if (val == null)
    {
      return "null";
    }

    return "\"" + val + "\"";
  }
 
 
  /**
   * Derives a java class name from a database table name.
   */
  private String deriveClassName(String name)
  {
    // PreserverCharacterCase
    if (config.isPreserverCharacterCase()) {
      return name;
    }
    // Build camel case string
    StringBuilder sb = new StringBuilder();
    sb.append(Character.toUpperCase(name.charAt(0)));
    // Tables might already be camel case. Let's skip this if no '_' anywhere.
    /*
    if(name.substring(1).indexOf('_') <= 0)
    {
      if(name.length() > 1)
        sb.append(name.substring(1).toLowerCase());
      return sb.toString();
    }
    */
    boolean nextCharacterUppercase = false;
    for (int i = 1; i < name.length(); i++)
    {
      char c = name.charAt(i);
      if (c == '_') {
        nextCharacterUppercase = true;
        continue;
      }
      if (nextCharacterUppercase)
        sb.append(Character.toUpperCase(c));
      else
        sb.append(Character.toLowerCase(c));
      nextCharacterUppercase = false;
    }
    return sb.toString();
  }

  /**
   * Derives the accessor method name based on the attribute name.
   *
   * @param attribute
   * @param isBoolean
   * @return
   */
  private String deriveAccessorName(String attribute, Class<?> type)
  {
    return deriveRecordMethodName(attribute, type, true);
  }
 
  /**
   * We need to alter both getter and setter if the method name will
   * conflict with existing methods DBRecord. This will check both
   * so that getter and setter have matching suffixes if one or
   * the other conflicts with an existing method.
   */
  private String deriveRecordMethodName(String attribute, Class<?> type, boolean isGetter) {
    attribute = deriveAttributeName(attribute);
    StringBuilder attributeName = new StringBuilder();
    attributeName.append(Character.toUpperCase(attribute.charAt(0)));
   
    // convert the method's name to CamelCase
    boolean nextCharacterUppercase = false;
    for (int i = 1; i < attribute.length(); i++)
    {
      char c = attribute.charAt(i);
      if (c == '_') {
        nextCharacterUppercase = true;
        continue;
      }
      if (nextCharacterUppercase)
        attributeName.append(Character.toUpperCase(c));
      else
        attributeName.append(Character.toLowerCase(c));
      nextCharacterUppercase = false;
    }
   
    StringBuilder sbGet = new StringBuilder(getGetterPrefix(type));
    sbGet.append(attributeName);
   
    StringBuilder sbSet = new StringBuilder("set");
    sbSet.append(attributeName);
    attributeName = isGetter ? sbGet : sbSet;
    if(dbrecMethodNames.contains(sbGet.toString()) || dbrecMethodNames.contains(sbSet.toString()))
    {
      // Any change will resolve the conflict.
      attributeName.append("Column");
    }
    return attributeName.toString();
  }
 
  private String getGetterPrefix(Class<?> type){
    if (type == boolean.class || type == Boolean.class)
    {
      return "is";
    }
    else
    {
      return "get";
    }
  }

  /**
   * Derives the mutator method name based on the attribute name.
   *
   * @param attribute
   * @return
   */
  private String deriveMutatorName(String attribute, Class<?> type)
  {
    return deriveRecordMethodName(attribute, type, false);
  }
 
  /**
   * Derives the attribute name based on the column name.
   *
   * @param attribute
   * @return
   */
  private String deriveAttributeName(String column)
  {
    return column.replace(' ', '_');
  }

}
TOP

Related Classes of org.apache.empire.db.codegen.WriterService

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.