FR [ 2848449 ] ModelClassGenerator: Implement model getters
https://sourceforge.net/tracker/?func=detail&atid=879335&aid=2848449&group_id=176962
This commit is contained in:
parent
8659c3db52
commit
2faf40dba9
|
@ -34,13 +34,10 @@ import java.util.logging.Level;
|
|||
|
||||
import org.adempiere.exceptions.DBException;
|
||||
import org.compiere.Adempiere;
|
||||
import org.compiere.model.MEntityType;
|
||||
import org.compiere.model.MTable;
|
||||
import org.compiere.util.CLogMgt;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.DisplayType;
|
||||
import org.compiere.util.Env;
|
||||
|
||||
/**
|
||||
* 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>FR [ 1781630 ] Generated class/interfaces have a lot of unused imports
|
||||
* <li>BF [ 1781632 ] Generated class/interfaces should be UTF-8
|
||||
* <li>better formating of generated source
|
||||
* <li>[ 1787876 ] ModelClassGenerator: list constants should be ordered
|
||||
* <li>FR [ xxxxxxx ] better formating of generated source
|
||||
* <li>FR [ 1787876 ] ModelClassGenerator: list constants should be ordered
|
||||
* <li>FR [ 1803309 ] Model generator: generate get method for Search cols
|
||||
* <li>FR [ 1990848 ] Generated Models: remove hardcoded field length
|
||||
* <li>FR [ 2343096 ] Model Generator: Improve Reference Class Detection
|
||||
* <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
|
||||
* <li>FR [ 1785001 ] Using ModelPackage of EntityType to Generate Model Class
|
||||
*/
|
||||
|
@ -96,9 +96,6 @@ public class ModelClassGenerator
|
|||
/** Package Name */
|
||||
private String packageName = "";
|
||||
|
||||
/** EntityType */
|
||||
private static final MEntityType[] entityTypes = MEntityType.getEntityTypes(Env.getCtx());
|
||||
|
||||
|
||||
/**
|
||||
* Add Header info to buffer
|
||||
|
@ -314,7 +311,8 @@ public class ModelClassGenerator
|
|||
columnName, isUpdateable, isMandatory,
|
||||
displayType, AD_Reference_Value_ID, fieldLength,
|
||||
defaultValue, ValueMin, ValueMax, VFormat,
|
||||
Callout, Name, Description, virtualColumn, IsEncrypted, IsKey)
|
||||
Callout, Name, Description, virtualColumn, IsEncrypted, IsKey,
|
||||
AD_Table_ID)
|
||||
);
|
||||
//
|
||||
if (seqNo == 1 && IsIdentifier) {
|
||||
|
@ -366,7 +364,8 @@ public class ModelClassGenerator
|
|||
int displayType, int AD_Reference_ID, int fieldLength,
|
||||
String defaultValue, String ValueMin, String ValueMax, 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 = ModelInterfaceGenerator.getClass(columnName, displayType, AD_Reference_ID);
|
||||
String dataType = ModelInterfaceGenerator.getDataTypeName(clazz, displayType);
|
||||
|
@ -393,64 +392,21 @@ public class ModelClassGenerator
|
|||
// 1) Must understand which class to reference
|
||||
if (DisplayType.isID(displayType) && !IsKey)
|
||||
{
|
||||
if (displayType == DisplayType.TableDir
|
||||
|| (displayType == DisplayType.Search && AD_Reference_ID == 0))
|
||||
String fieldName = ModelInterfaceGenerator.getFieldName(columnName);
|
||||
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
|
||||
String tableName = columnName.substring(0, columnName.length()-3);
|
||||
String referenceClassName = "I_"+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(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)
|
||||
;
|
||||
}
|
||||
sb.append(NL)
|
||||
.append("\tpublic "+referenceClassName+" get").append(fieldName).append("() throws RuntimeException").append(NL)
|
||||
.append(" {").append(NL)
|
||||
.append("\t\treturn ("+referenceClassName+")MTable.get(getCtx(), "+referenceClassName+".Table_Name)").append(NL)
|
||||
.append("\t\t\t.getPO(get"+columnName+"(), get_TrxName());")
|
||||
/**/
|
||||
.append("\t}").append(NL)
|
||||
;
|
||||
// Add imports:
|
||||
addImportClass(java.lang.reflect.Constructor.class);
|
||||
addImportClass(java.util.logging.Level.class);
|
||||
addImportClass(clazz);
|
||||
} else {
|
||||
// TODO - Handle other types
|
||||
//sb.append("\tpublic I_"+columnName+" getI_").append(columnName).append("(){return null; };");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ import java.util.logging.Level;
|
|||
import org.adempiere.exceptions.DBException;
|
||||
import org.compiere.Adempiere;
|
||||
import org.compiere.model.MEntityType;
|
||||
import org.compiere.model.MQuery;
|
||||
import org.compiere.model.MTable;
|
||||
import org.compiere.util.CLogMgt;
|
||||
import org.compiere.util.CLogger;
|
||||
|
@ -63,8 +64,13 @@ import org.compiere.util.Env;
|
|||
* <li>better formating of generated source
|
||||
* <li>BF [ 1787833 ] ModelInterfaceGenerator: don't write timestamp
|
||||
* <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>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
|
||||
* <li>FR [ 1785001 ] Using ModelPackage of EntityType to Generate Model Class
|
||||
*/
|
||||
|
@ -97,11 +103,6 @@ public class ModelInterfaceGenerator
|
|||
/** Logger */
|
||||
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) {
|
||||
this.packageName = packageName;
|
||||
// create column access methods
|
||||
|
@ -275,7 +276,7 @@ public class ModelInterfaceGenerator
|
|||
isUpdateable, isMandatory, displayType,
|
||||
AD_Reference_Value_ID, fieldLength, defaultValue,
|
||||
ValueMin, ValueMax, VFormat, Callout, Name,
|
||||
Description, virtualColumn, IsEncrypted, IsKey));
|
||||
Description, virtualColumn, IsEncrypted, IsKey, AD_Table_ID));
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
|
@ -316,7 +317,7 @@ public class ModelInterfaceGenerator
|
|||
int displayType, int AD_Reference_ID, int fieldLength,
|
||||
String defaultValue, String ValueMin, String ValueMax,
|
||||
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);
|
||||
String dataType = getDataTypeName(clazz, displayType);
|
||||
|
@ -351,41 +352,13 @@ public class ModelInterfaceGenerator
|
|||
|
||||
if (isGenerateModelGetter(columnName) && DisplayType.isID(displayType) && !IsKey)
|
||||
{
|
||||
if (displayType == DisplayType.TableDir
|
||||
|| (displayType == DisplayType.Search && AD_Reference_ID == 0))
|
||||
String fieldName = getFieldName(columnName);
|
||||
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);
|
||||
//begin [ 1785001 ] Using ModelPackage of EntityType to Generate Model Class - vpj-cd
|
||||
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; };");
|
||||
sb.append("\n")
|
||||
.append("\tpublic "+referenceClassName+" get").append(fieldName).append("() throws RuntimeException;");
|
||||
}
|
||||
}
|
||||
addImportClass(clazz);
|
||||
|
@ -571,7 +544,7 @@ public class ModelInterfaceGenerator
|
|||
* @param columnName
|
||||
* @return true if a setter method should be generated
|
||||
*/
|
||||
public boolean isGenerateSetter(String columnName)
|
||||
public static boolean isGenerateSetter(String columnName)
|
||||
{
|
||||
return
|
||||
!"AD_Client_ID".equals(columnName)
|
||||
|
@ -586,9 +559,9 @@ public class ModelInterfaceGenerator
|
|||
|
||||
/**
|
||||
* @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
|
||||
!"AD_Client_ID".equals(columnName)
|
||||
|
@ -597,6 +570,166 @@ public class ModelInterfaceGenerator
|
|||
&& !"UpdatedBy".equals(columnName)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @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
|
||||
|
|
|
@ -226,6 +226,8 @@ public class MQuery implements Serializable
|
|||
return "C_BPartner_Location_ID";
|
||||
if (columnName.equals("Account_ID"))
|
||||
return "C_ElementValue_ID";
|
||||
if (columnName.equals("C_LocFrom_ID") || columnName.equals("C_LocTo_ID"))
|
||||
return "C_Location_ID";
|
||||
// Fix "*_To" columns
|
||||
if (columnName.toUpperCase().endsWith("TO_ID")) {
|
||||
return columnName.substring(0, columnName.length()-5)+"_ID";
|
||||
|
@ -233,7 +235,7 @@ public class MQuery implements Serializable
|
|||
if (columnName.toUpperCase().endsWith("_TO_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";
|
||||
// See also GridTab.validateQuery
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue