FR [ 2848449 ] ModelClassGenerator: Implement model getters

https://sourceforge.net/tracker/?func=detail&atid=879335&aid=2848449&group_id=176962
This commit is contained in:
teo_sarca 2009-09-06 11:07:15 +00:00
parent 8659c3db52
commit 2faf40dba9
3 changed files with 201 additions and 110 deletions

View File

@ -34,13 +34,10 @@ import java.util.logging.Level;
import org.adempiere.exceptions.DBException; import org.adempiere.exceptions.DBException;
import org.compiere.Adempiere; import org.compiere.Adempiere;
import org.compiere.model.MEntityType;
import org.compiere.model.MTable;
import org.compiere.util.CLogMgt; import org.compiere.util.CLogMgt;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.DisplayType; import org.compiere.util.DisplayType;
import org.compiere.util.Env;
/** /**
* Generate Model Classes extending PO. * Generate Model Classes extending PO.
@ -53,12 +50,15 @@ import org.compiere.util.Env;
* <li>BF [ 1781629 ] Don't use Env.NL in model class/interface generators * <li>BF [ 1781629 ] Don't use Env.NL in model class/interface generators
* <li>FR [ 1781630 ] Generated class/interfaces have a lot of unused imports * <li>FR [ 1781630 ] Generated class/interfaces have a lot of unused imports
* <li>BF [ 1781632 ] Generated class/interfaces should be UTF-8 * <li>BF [ 1781632 ] Generated class/interfaces should be UTF-8
* <li>better formating of generated source * <li>FR [ xxxxxxx ] better formating of generated source
* <li>[ 1787876 ] ModelClassGenerator: list constants should be ordered * <li>FR [ 1787876 ] ModelClassGenerator: list constants should be ordered
* <li>FR [ 1803309 ] Model generator: generate get method for Search cols * <li>FR [ 1803309 ] Model generator: generate get method for Search cols
* <li>FR [ 1990848 ] Generated Models: remove hardcoded field length * <li>FR [ 1990848 ] Generated Models: remove hardcoded field length
* <li>FR [ 2343096 ] Model Generator: Improve Reference Class Detection * <li>FR [ 2343096 ] Model Generator: Improve Reference Class Detection
* <li>BF [ 2780468 ] ModelClassGenerator: not generating methods for Created* * <li>BF [ 2780468 ] ModelClassGenerator: not generating methods for Created*
* <li>--
* <li>FR [ 2848449 ] ModelClassGenerator: Implement model getters
* https://sourceforge.net/tracker/?func=detail&atid=879335&aid=2848449&group_id=176962
* @author Victor Perez, e-Evolution * @author Victor Perez, e-Evolution
* <li>FR [ 1785001 ] Using ModelPackage of EntityType to Generate Model Class * <li>FR [ 1785001 ] Using ModelPackage of EntityType to Generate Model Class
*/ */
@ -96,9 +96,6 @@ public class ModelClassGenerator
/** Package Name */ /** Package Name */
private String packageName = ""; private String packageName = "";
/** EntityType */
private static final MEntityType[] entityTypes = MEntityType.getEntityTypes(Env.getCtx());
/** /**
* Add Header info to buffer * Add Header info to buffer
@ -314,7 +311,8 @@ public class ModelClassGenerator
columnName, isUpdateable, isMandatory, columnName, isUpdateable, isMandatory,
displayType, AD_Reference_Value_ID, fieldLength, displayType, AD_Reference_Value_ID, fieldLength,
defaultValue, ValueMin, ValueMax, VFormat, defaultValue, ValueMin, ValueMax, VFormat,
Callout, Name, Description, virtualColumn, IsEncrypted, IsKey) Callout, Name, Description, virtualColumn, IsEncrypted, IsKey,
AD_Table_ID)
); );
// //
if (seqNo == 1 && IsIdentifier) { if (seqNo == 1 && IsIdentifier) {
@ -366,7 +364,8 @@ public class ModelClassGenerator
int displayType, int AD_Reference_ID, int fieldLength, int displayType, int AD_Reference_ID, int fieldLength,
String defaultValue, String ValueMin, String ValueMax, String VFormat, String defaultValue, String ValueMin, String ValueMax, String VFormat,
String Callout, String Name, String Description, String Callout, String Name, String Description,
boolean virtualColumn, boolean IsEncrypted, boolean IsKey) boolean virtualColumn, boolean IsEncrypted, boolean IsKey,
int AD_Table_ID)
{ {
Class<?> clazz = ModelInterfaceGenerator.getClass(columnName, displayType, AD_Reference_ID); Class<?> clazz = ModelInterfaceGenerator.getClass(columnName, displayType, AD_Reference_ID);
String dataType = ModelInterfaceGenerator.getDataTypeName(clazz, displayType); String dataType = ModelInterfaceGenerator.getDataTypeName(clazz, displayType);
@ -393,64 +392,21 @@ public class ModelClassGenerator
// 1) Must understand which class to reference // 1) Must understand which class to reference
if (DisplayType.isID(displayType) && !IsKey) if (DisplayType.isID(displayType) && !IsKey)
{ {
if (displayType == DisplayType.TableDir String fieldName = ModelInterfaceGenerator.getFieldName(columnName);
|| (displayType == DisplayType.Search && AD_Reference_ID == 0)) String referenceClassName = ModelInterfaceGenerator.getReferenceClassName(AD_Table_ID, columnName, displayType, AD_Reference_ID);
//
if (fieldName != null && referenceClassName != null)
{ {
//begin [ 1785001 ] Using ModelPackage of EntityType to Generate Model Class - vpj-cd sb.append(NL)
String tableName = columnName.substring(0, columnName.length()-3); .append("\tpublic "+referenceClassName+" get").append(fieldName).append("() throws RuntimeException").append(NL)
String referenceClassName = "I_"+columnName.substring(0, columnName.length()-3); .append(" {").append(NL)
.append("\t\treturn ("+referenceClassName+")MTable.get(getCtx(), "+referenceClassName+".Table_Name)").append(NL)
MTable table = MTable.get(Env.getCtx(), tableName); .append("\t\t\t.getPO(get"+columnName+"(), get_TrxName());")
if (table != null) /**/
{ .append("\t}").append(NL)
String entityType = table.getEntityType(); ;
if (!"D".equals(entityType))
{
for (int i = 0; i < entityTypes.length; i++)
{
if (entityTypes[i].getEntityType().equals(entityType))
{
String modelpackage = entityTypes[i].getModelPackage();
if (modelpackage != null)
{
referenceClassName = modelpackage+".I_"+columnName.substring(0, columnName.length()-3);
break;
}
}
}
}
//end [ 1785001 ]
sb.append(NL)
.append("\tpublic "+referenceClassName+" get").append(tableName).append("() throws RuntimeException ").append(NL)
.append(" {").append(NL)
// TODO - here we can implement Lazy loading or Cache of class
.append(" Class<?> clazz = MTable.getClass("+referenceClassName+".Table_Name);").append(NL)
.append(" ").append(referenceClassName).append(" result = null;").append(NL)
.append(" try {").append(NL)
.append(" Constructor<?> constructor = null;").append(NL)
// .append(" try {").append(NL)
.append(" constructor = clazz.getDeclaredConstructor(new Class[]{Properties.class, int.class, String.class});").append(NL)
// .append(" } catch (NoSuchMethodException e) {").append(NL)
// .append(" log.warning(\"No transaction Constructor for \" + clazz + \" Exception[\" + e.toString() + \"]\");").append(NL)
// .append(" }").append(NL)
// TODO - here we can implement Lazy loading or Cache of record. Like in Hibernate, objects can be loaded on demand or when master object is loaded.
.append(" result = ("+referenceClassName+")constructor.newInstance(new Object[] {getCtx(), new Integer(get"+columnName+"()), get_TrxName()});").append(NL)
.append(" } catch (Exception e) {").append(NL)
.append(" log.log(Level.SEVERE, \"(id) - Table=\" + Table_Name + \",Class=\" + clazz, e);").append(NL)
.append(" log.saveError(\"Error\", \"Table=\" + Table_Name + \",Class=\" + clazz);").append(NL)
.append(" throw new RuntimeException( e );").append(NL)
.append(" }").append(NL)
.append(" return result;").append(NL)
.append(" }").append(NL)
;
}
// Add imports: // Add imports:
addImportClass(java.lang.reflect.Constructor.class);
addImportClass(java.util.logging.Level.class);
addImportClass(clazz); addImportClass(clazz);
} else {
// TODO - Handle other types
//sb.append("\tpublic I_"+columnName+" getI_").append(columnName).append("(){return null; };");
} }
} }

View File

@ -45,6 +45,7 @@ import java.util.logging.Level;
import org.adempiere.exceptions.DBException; import org.adempiere.exceptions.DBException;
import org.compiere.Adempiere; import org.compiere.Adempiere;
import org.compiere.model.MEntityType; import org.compiere.model.MEntityType;
import org.compiere.model.MQuery;
import org.compiere.model.MTable; import org.compiere.model.MTable;
import org.compiere.util.CLogMgt; import org.compiere.util.CLogMgt;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
@ -63,8 +64,13 @@ import org.compiere.util.Env;
* <li>better formating of generated source * <li>better formating of generated source
* <li>BF [ 1787833 ] ModelInterfaceGenerator: don't write timestamp * <li>BF [ 1787833 ] ModelInterfaceGenerator: don't write timestamp
* <li>FR [ 1803309 ] Model generator: generate get method for Search cols * <li>FR [ 1803309 ] Model generator: generate get method for Search cols
* <li>BF [ 1817768 ] Isolate hardcoded table direct columns
* https://sourceforge.net/tracker/?func=detail&atid=879332&aid=1817768&group_id=176962
* <li>FR [ 2343096 ] Model Generator: Improve Reference Class Detection * <li>FR [ 2343096 ] Model Generator: Improve Reference Class Detection
* <li>BF [ 2528434 ] ModelInterfaceGenerator: generate getters for common fields * <li>BF [ 2528434 ] ModelInterfaceGenerator: generate getters for common fields
* <li>--
* <li>FR [ 2848449 ] ModelClassGenerator: Implement model getters
* https://sourceforge.net/tracker/?func=detail&atid=879335&aid=2848449&group_id=176962
* @author Victor Perez, e-Evolution * @author Victor Perez, e-Evolution
* <li>FR [ 1785001 ] Using ModelPackage of EntityType to Generate Model Class * <li>FR [ 1785001 ] Using ModelPackage of EntityType to Generate Model Class
*/ */
@ -97,11 +103,6 @@ public class ModelInterfaceGenerator
/** Logger */ /** Logger */
private static CLogger log = CLogger.getCLogger(ModelInterfaceGenerator.class); private static CLogger log = CLogger.getCLogger(ModelInterfaceGenerator.class);
/** EntityType */
private static final MEntityType[] entityTypes = MEntityType.getEntityTypes(Env.getCtx());
public ModelInterfaceGenerator(int AD_Table_ID, String directory, String packageName) { public ModelInterfaceGenerator(int AD_Table_ID, String directory, String packageName) {
this.packageName = packageName; this.packageName = packageName;
// create column access methods // create column access methods
@ -275,7 +276,7 @@ public class ModelInterfaceGenerator
isUpdateable, isMandatory, displayType, isUpdateable, isMandatory, displayType,
AD_Reference_Value_ID, fieldLength, defaultValue, AD_Reference_Value_ID, fieldLength, defaultValue,
ValueMin, ValueMax, VFormat, Callout, Name, ValueMin, ValueMax, VFormat, Callout, Name,
Description, virtualColumn, IsEncrypted, IsKey)); Description, virtualColumn, IsEncrypted, IsKey, AD_Table_ID));
} }
} }
catch (SQLException e) catch (SQLException e)
@ -316,7 +317,7 @@ public class ModelInterfaceGenerator
int displayType, int AD_Reference_ID, int fieldLength, int displayType, int AD_Reference_ID, int fieldLength,
String defaultValue, String ValueMin, String ValueMax, String defaultValue, String ValueMin, String ValueMax,
String VFormat, String Callout, String Name, String Description, String VFormat, String Callout, String Name, String Description,
boolean virtualColumn, boolean IsEncrypted, boolean IsKey) boolean virtualColumn, boolean IsEncrypted, boolean IsKey, int AD_Table_ID)
{ {
Class<?> clazz = getClass(columnName, displayType, AD_Reference_ID); Class<?> clazz = getClass(columnName, displayType, AD_Reference_ID);
String dataType = getDataTypeName(clazz, displayType); String dataType = getDataTypeName(clazz, displayType);
@ -351,41 +352,13 @@ public class ModelInterfaceGenerator
if (isGenerateModelGetter(columnName) && DisplayType.isID(displayType) && !IsKey) if (isGenerateModelGetter(columnName) && DisplayType.isID(displayType) && !IsKey)
{ {
if (displayType == DisplayType.TableDir String fieldName = getFieldName(columnName);
|| (displayType == DisplayType.Search && AD_Reference_ID == 0)) String referenceClassName = getReferenceClassName(AD_Table_ID, columnName, displayType, AD_Reference_ID);
//
if (fieldName != null && referenceClassName != null)
{ {
String referenceClassName = "I_"+columnName.substring(0, columnName.length()-3); sb.append("\n")
//begin [ 1785001 ] Using ModelPackage of EntityType to Generate Model Class - vpj-cd .append("\tpublic "+referenceClassName+" get").append(fieldName).append("() throws RuntimeException;");
String tableName = columnName.substring(0, columnName.length()-3);
MTable table = MTable.get(Env.getCtx(), tableName);
if (table != null)
{
String entityType = table.getEntityType();
if (!"D".equals(entityType))
{
for (int i = 0; i < entityTypes.length; i++)
{
if (entityTypes[i].getEntityType().equals(entityType))
{
String modelpackage = entityTypes[i].getModelPackage();
if (modelpackage != null)
{
referenceClassName = modelpackage+".I_"+columnName.substring(0, columnName.length()-3);
break;
}
}
}
}
//end [ 1785001 ]
sb.append("\n")
.append("\tpublic "+referenceClassName+" get").append(tableName).append("() throws RuntimeException;")
;
}
} else {
// TODO - Handle other types
//sb.append("\tpublic I_"+columnName+" getI_").append(columnName).append("(){return null; };");
} }
} }
addImportClass(clazz); addImportClass(clazz);
@ -571,7 +544,7 @@ public class ModelInterfaceGenerator
* @param columnName * @param columnName
* @return true if a setter method should be generated * @return true if a setter method should be generated
*/ */
public boolean isGenerateSetter(String columnName) public static boolean isGenerateSetter(String columnName)
{ {
return return
!"AD_Client_ID".equals(columnName) !"AD_Client_ID".equals(columnName)
@ -586,9 +559,9 @@ public class ModelInterfaceGenerator
/** /**
* @param columnName * @param columnName
* @return true if a model getter method should be generated * @return true if a model getter method (method that is returning referenced PO) should be generated
*/ */
public boolean isGenerateModelGetter(String columnName) public static boolean isGenerateModelGetter(String columnName)
{ {
return return
!"AD_Client_ID".equals(columnName) !"AD_Client_ID".equals(columnName)
@ -598,6 +571,166 @@ public class ModelInterfaceGenerator
; ;
} }
/**
*
* @param AD_Table_ID
* @param toEntityType
* @return true if a model getter method (method that is returning referenced PO) should be generated
*/
public static boolean isGenerateModelGetterForEntity(int AD_Table_ID, String toEntityType)
{
final String fromEntityType = DB.getSQLValueString(null, "SELECT EntityType FROM AD_Table where AD_Table_ID=?", AD_Table_ID);
final MEntityType fromEntity = MEntityType.get(Env.getCtx(), fromEntityType);
final MEntityType toEntity = MEntityType.get(Env.getCtx(), toEntityType);
return
// Same entities
fromEntityType.equals(toEntityType)
// Both are system entities
|| (fromEntity.isSystemMaintained() && toEntity.isSystemMaintained())
// Not Sys Entity referencing a Sys Entity
|| (!fromEntity.isSystemMaintained() && toEntity.isSystemMaintained())
;
}
/**
* Get EntityType Model Package.
* @author Victor Perez - [ 1785001 ] Using ModelPackage of EntityType to Generate Model Class
* @param entityType
* @return
*/
public static String getModelPackage(String entityType)
{
if ("D".equals(entityType))
return null;
for (MEntityType entity : MEntityType.getEntityTypes(Env.getCtx()))
{
if (entity.getEntityType().equals(entityType))
{
return entity.getModelPackage();
}
}
return null;
}
public static String getFieldName(String columnName)
{
String fieldName;
if (columnName.endsWith("_ID_To"))
fieldName = columnName.substring(0, columnName.length() - 6) + "_To";
else
fieldName = columnName.substring(0, columnName.length() - 3);
return fieldName;
}
public static String getReferenceClassName(int AD_Table_ID, String columnName, int displayType, int AD_Reference_ID)
{
String referenceClassName = null;
//
if (displayType == DisplayType.TableDir
|| (displayType == DisplayType.Search && AD_Reference_ID == 0))
{
String refTableName = MQuery.getZoomTableName(columnName); // teo_sarca: BF [ 1817768 ] Isolate hardcoded table direct columns
referenceClassName = "I_"+refTableName;
MTable table = MTable.get(Env.getCtx(), refTableName);
if (table != null)
{
String entityType = table.getEntityType();
String modelpackage = getModelPackage(entityType) ;
if (modelpackage != null)
{
referenceClassName = modelpackage+"."+referenceClassName;
}
if (!isGenerateModelGetterForEntity(AD_Table_ID, entityType))
{
referenceClassName = null;
}
}
else
{
throw new RuntimeException("No table found for "+refTableName);
}
}
else if (displayType == DisplayType.Table
|| (displayType == DisplayType.Search && AD_Reference_ID > 0))
{
// TODO: HARDCODED: do not generate model getter for Fact_Acct.Account_ID
if (AD_Table_ID == 270 && columnName.equals("Account_ID"))
return null;
// TODO: HARDCODED: do not generate model getter for GL_DistributionLine.Account_ID
if (AD_Table_ID == 707 && columnName.equals("Account_ID"))
return null;
//
final String sql = "SELECT t.TableName, t.EntityType, ck.AD_Reference_ID"
+" FROM AD_Ref_Table rt"
+" INNER JOIN AD_Table t ON (t.AD_Table_ID=rt.AD_Table_ID)"
+" INNER JOIN AD_Column ck ON (ck.AD_Table_ID=rt.AD_Table_ID AND ck.AD_Column_ID=rt.AD_Key)"
+" WHERE rt.AD_Reference_ID=?"
;
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, AD_Reference_ID);
rs = pstmt.executeQuery();
if (rs.next())
{
final String refTableName = rs.getString(1);
final String entityType = rs.getString(2);
final int refDisplayType = rs.getInt(3);
if (refDisplayType == DisplayType.ID)
{
referenceClassName = "I_"+refTableName;
String modelpackage = getModelPackage(entityType);
if (modelpackage != null)
{
referenceClassName = modelpackage+"."+referenceClassName;
}
if (!isGenerateModelGetterForEntity(AD_Table_ID, entityType))
{
referenceClassName = null;
}
}
}
}
catch (SQLException e)
{
throw new DBException(e, sql);
}
finally
{
DB.close(rs, pstmt);
rs = null; pstmt = null;
}
}
else if (displayType == DisplayType.Location)
{
referenceClassName = "I_C_Location";
}
else if (displayType == DisplayType.Locator)
{
referenceClassName = "I_M_Locator";
}
else if (displayType == DisplayType.Account)
{
referenceClassName = "I_C_ValidCombination";
}
else if (displayType == DisplayType.PAttribute)
{
referenceClassName = "I_M_AttributeSetInstance";
}
else
{
// TODO - Handle other types
//sb.append("\tpublic I_"+columnName+" getI_").append(columnName).append("(){return null; };");
}
//
return referenceClassName;
}
/** /**
* String representation * String representation
* *

View File

@ -226,6 +226,8 @@ public class MQuery implements Serializable
return "C_BPartner_Location_ID"; return "C_BPartner_Location_ID";
if (columnName.equals("Account_ID")) if (columnName.equals("Account_ID"))
return "C_ElementValue_ID"; return "C_ElementValue_ID";
if (columnName.equals("C_LocFrom_ID") || columnName.equals("C_LocTo_ID"))
return "C_Location_ID";
// Fix "*_To" columns // Fix "*_To" columns
if (columnName.toUpperCase().endsWith("TO_ID")) { if (columnName.toUpperCase().endsWith("TO_ID")) {
return columnName.substring(0, columnName.length()-5)+"_ID"; return columnName.substring(0, columnName.length()-5)+"_ID";
@ -233,7 +235,7 @@ public class MQuery implements Serializable
if (columnName.toUpperCase().endsWith("_TO_ID")) { if (columnName.toUpperCase().endsWith("_TO_ID")) {
return columnName.substring(0, columnName.length()-6)+"_ID"; return columnName.substring(0, columnName.length()-6)+"_ID";
} }
if (columnName.equals("AD_OrgBP_ID")) if (columnName.equals("AD_OrgBP_ID") || columnName.equals("AD_OrgTrx_ID"))
return "AD_Org_ID"; return "AD_Org_ID";
// See also GridTab.validateQuery // See also GridTab.validateQuery
// //