1. Added basic priority support for extensions. 2. Factor out the discovery of model class and instantiation of model po as extension.
This commit is contained in:
parent
bc72f1c6fe
commit
4709b790a6
|
@ -9,5 +9,15 @@
|
||||||
<extension-point id="org.compiere.db.AdempiereDatabase" name="Adempiere Database Interface" schema="schema/org.compiere.db.AdempiereDatabase.exsd"/>
|
<extension-point id="org.compiere.db.AdempiereDatabase" name="Adempiere Database Interface" schema="schema/org.compiere.db.AdempiereDatabase.exsd"/>
|
||||||
<extension-point id="org.compiere.interfaces.Server" name="Server Interface" schema="schema/org.compiere.interfaces.Server.exsd"/>
|
<extension-point id="org.compiere.interfaces.Server" name="Server Interface" schema="schema/org.compiere.interfaces.Server.exsd"/>
|
||||||
<extension-point id="org.compiere.interfaces.Status" name="Status interface" schema="schema/org.compiere.interfaces.Status.exsd"/>
|
<extension-point id="org.compiere.interfaces.Status" name="Status interface" schema="schema/org.compiere.interfaces.Status.exsd"/>
|
||||||
|
<extension-point id="org.adempiere.base.IModelFactory" name="Model Factory" schema="schema/org.adempiere.base.IModelFactory.exsd"/>
|
||||||
|
<extension
|
||||||
|
id="org.adempiere.base.DefaultModelFactory"
|
||||||
|
name="Default model factory"
|
||||||
|
point="org.adempiere.base.IModelFactory">
|
||||||
|
<factory
|
||||||
|
class="org.adempiere.base.DefaultModelFactory"
|
||||||
|
priority="0">
|
||||||
|
</factory>
|
||||||
|
</extension>
|
||||||
|
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!-- Schema file written by PDE -->
|
||||||
|
<schema targetNamespace="org.adempiere.base" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.schema plugin="org.adempiere.base" id="org.adempiere.base.IModelFactory" name="Model Factory"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
[Enter description of this extension point.]
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<element name="extension">
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.element />
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
<complexType>
|
||||||
|
<choice>
|
||||||
|
<element ref="factory"/>
|
||||||
|
</choice>
|
||||||
|
<attribute name="point" type="string" use="required">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="id" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="name" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.attribute translatable="true"/>
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<element name="factory">
|
||||||
|
<complexType>
|
||||||
|
<attribute name="priority" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="class" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.attribute kind="java" basedOn=":org.adempiere.base.IModelFactory"/>
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.section type="since"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
[Enter the first release in which this extension point appears.]
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.section type="examples"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
[Enter extension point usage example here.]
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.section type="apiinfo"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
[Enter API information here.]
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.section type="implementation"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
[Enter information about supplied implementation of this extension point.]
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
|
||||||
|
</schema>
|
|
@ -0,0 +1,325 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||||
|
* See the GNU General Public License for more details. *
|
||||||
|
* You should have received a copy of the GNU General Public License along *
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||||
|
* For the text or an alternative of this public license, you may reach us *
|
||||||
|
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||||
|
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||||
|
* Contributor(s): Carlos Ruiz - globalqss *
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.adempiere.base;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.compiere.model.MEntityType;
|
||||||
|
import org.compiere.model.MTable;
|
||||||
|
import org.compiere.model.PO;
|
||||||
|
import org.compiere.util.CCache;
|
||||||
|
import org.compiere.util.CLogger;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
import org.compiere.util.Util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default model factory implementation base on legacy code in MTable.
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @author hengsin
|
||||||
|
*/
|
||||||
|
public class DefaultModelFactory implements IModelFactory {
|
||||||
|
|
||||||
|
private static CCache<String,Class<?>> s_classCache = new CCache<String,Class<?>>("PO_Class", 20);
|
||||||
|
private final static CLogger s_log = CLogger.getCLogger(DefaultModelFactory.class);
|
||||||
|
|
||||||
|
/** Packages for Model Classes */
|
||||||
|
private static final String[] s_packages = new String[] {
|
||||||
|
|
||||||
|
"org.compiere.model", "org.compiere.wf",
|
||||||
|
"org.compiere.print", "org.compiere.impexp",
|
||||||
|
"compiere.model", // globalqss allow compatibility with other plugins
|
||||||
|
"adempiere.model", // Extensions
|
||||||
|
"org.adempiere.model"
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Special Classes */
|
||||||
|
private static final String[] s_special = new String[] {
|
||||||
|
"AD_Element", "org.compiere.model.M_Element",
|
||||||
|
"AD_Registration", "org.compiere.model.M_Registration",
|
||||||
|
"AD_Tree", "org.compiere.model.MTree_Base",
|
||||||
|
"R_Category", "org.compiere.model.MRequestCategory",
|
||||||
|
"GL_Category", "org.compiere.model.MGLCategory",
|
||||||
|
"K_Category", "org.compiere.model.MKCategory",
|
||||||
|
"C_ValidCombination", "org.compiere.model.MAccount",
|
||||||
|
"C_Phase", "org.compiere.model.MProjectTypePhase",
|
||||||
|
"C_Task", "org.compiere.model.MProjectTypeTask"
|
||||||
|
// AD_Attribute_Value, AD_TreeNode
|
||||||
|
};
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.adempiere.base.IModelFactory#getClass(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Class<?> getClass(String tableName) {
|
||||||
|
// Not supported
|
||||||
|
if (tableName == null || tableName.endsWith("_Trl"))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
//check cache
|
||||||
|
Class<?> cache = s_classCache.get(tableName);
|
||||||
|
if (cache != null)
|
||||||
|
{
|
||||||
|
//Object.class indicate no generated PO class for tableName
|
||||||
|
if (cache.equals(Object.class))
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTable table = MTable.get(Env.getCtx(), tableName);
|
||||||
|
String entityType = table.getEntityType();
|
||||||
|
|
||||||
|
// Import Tables (Name conflict)
|
||||||
|
// Import Tables doesn't manage model M classes, just X_
|
||||||
|
if (tableName.startsWith("I_"))
|
||||||
|
{
|
||||||
|
MEntityType et = MEntityType.get(Env.getCtx(), entityType);
|
||||||
|
String etmodelpackage = et.getModelPackage();
|
||||||
|
if (etmodelpackage == null || MEntityType.ENTITYTYPE_Dictionary.equals(entityType))
|
||||||
|
etmodelpackage = "org.compiere.model"; // fallback for dictionary or empty model package on entity type
|
||||||
|
Class<?> clazz = getPOclass(etmodelpackage + ".X_" + tableName, tableName);
|
||||||
|
if (clazz != null)
|
||||||
|
{
|
||||||
|
s_classCache.put(tableName, clazz);
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
s_log.warning("No class for table: " + tableName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special Naming
|
||||||
|
for (int i = 0; i < s_special.length; i++)
|
||||||
|
{
|
||||||
|
if (s_special[i++].equals(tableName))
|
||||||
|
{
|
||||||
|
Class<?> clazz = getPOclass(s_special[i], tableName);
|
||||||
|
if (clazz != null)
|
||||||
|
{
|
||||||
|
s_classCache.put(tableName, clazz);
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//begin [ 1784588 ] Use ModelPackage of EntityType to Find Model Class - vpj-cd
|
||||||
|
if (!MEntityType.ENTITYTYPE_Dictionary.equals(entityType))
|
||||||
|
{
|
||||||
|
MEntityType et = MEntityType.get(Env.getCtx(), entityType);
|
||||||
|
String etmodelpackage = et.getModelPackage();
|
||||||
|
if (etmodelpackage != null)
|
||||||
|
{
|
||||||
|
Class<?> clazz = null;
|
||||||
|
clazz = getPOclass(etmodelpackage + ".M" + Util.replace(tableName, "_", ""), tableName);
|
||||||
|
if (clazz != null) {
|
||||||
|
s_classCache.put(tableName, clazz);
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
clazz = getPOclass(etmodelpackage + ".X_" + tableName, tableName);
|
||||||
|
if (clazz != null) {
|
||||||
|
s_classCache.put(tableName, clazz);
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
s_log.warning("No class for table with it entity: " + tableName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end [ 1784588 ]
|
||||||
|
|
||||||
|
// Strip table name prefix (e.g. AD_) Customizations are 3/4
|
||||||
|
String className = tableName;
|
||||||
|
int index = className.indexOf('_');
|
||||||
|
if (index > 0)
|
||||||
|
{
|
||||||
|
if (index < 3) // AD_, A_
|
||||||
|
className = className.substring(index+1);
|
||||||
|
/* DELETEME: this part is useless - teo_sarca, [ 1648850 ]
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String prefix = className.substring(0,index);
|
||||||
|
if (prefix.equals("Fact")) // keep custom prefix
|
||||||
|
className = className.substring(index+1);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
// Remove underlines
|
||||||
|
className = Util.replace(className, "_", "");
|
||||||
|
|
||||||
|
// Search packages
|
||||||
|
for (int i = 0; i < s_packages.length; i++)
|
||||||
|
{
|
||||||
|
StringBuffer name = new StringBuffer(s_packages[i]).append(".M").append(className);
|
||||||
|
Class<?> clazz = getPOclass(name.toString(), tableName);
|
||||||
|
if (clazz != null)
|
||||||
|
{
|
||||||
|
s_classCache.put(tableName, clazz);
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Adempiere Extension
|
||||||
|
Class<?> clazz = getPOclass("adempiere.model.X_" + tableName, tableName);
|
||||||
|
if (clazz != null)
|
||||||
|
{
|
||||||
|
s_classCache.put(tableName, clazz);
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
//hengsin - allow compatibility with compiere plugins
|
||||||
|
//Compiere Extension
|
||||||
|
clazz = getPOclass("compiere.model.X_" + tableName, tableName);
|
||||||
|
if (clazz != null)
|
||||||
|
{
|
||||||
|
s_classCache.put(tableName, clazz);
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default
|
||||||
|
clazz = getPOclass("org.compiere.model.X_" + tableName, tableName);
|
||||||
|
if (clazz != null)
|
||||||
|
{
|
||||||
|
s_classCache.put(tableName, clazz);
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Object.class to indicate no PO class for tableName
|
||||||
|
s_classCache.put(tableName, Object.class);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get PO class
|
||||||
|
* @param className fully qualified class name
|
||||||
|
* @param tableName Optional. If specified, the loaded class will be validated for that table name
|
||||||
|
* @return class or null
|
||||||
|
*/
|
||||||
|
private Class<?> getPOclass (String className, String tableName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class<?> clazz = Class.forName(className);
|
||||||
|
// Validate if the class is for specified tableName
|
||||||
|
if (tableName != null)
|
||||||
|
{
|
||||||
|
String classTableName = clazz.getField("Table_Name").get(null).toString();
|
||||||
|
if (!tableName.equals(classTableName))
|
||||||
|
{
|
||||||
|
s_log.finest("Invalid class for table: " + className+" (tableName="+tableName+", classTableName="+classTableName+")");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Make sure that it is a PO class
|
||||||
|
Class<?> superClazz = clazz.getSuperclass();
|
||||||
|
while (superClazz != null)
|
||||||
|
{
|
||||||
|
if (superClazz == PO.class)
|
||||||
|
{
|
||||||
|
s_log.fine("Use: " + className);
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
superClazz = superClazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
s_log.finest("Not found: " + className);
|
||||||
|
return null;
|
||||||
|
} // getPOclass
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PO getPO(String tableName, int Record_ID, String trxName) {
|
||||||
|
Class<?> clazz = getClass(tableName);
|
||||||
|
if (clazz == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean errorLogged = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Constructor<?> constructor = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
constructor = clazz.getDeclaredConstructor(new Class[]{Properties.class, int.class, String.class});
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
String msg = e.getMessage();
|
||||||
|
if (msg == null)
|
||||||
|
msg = e.toString();
|
||||||
|
s_log.warning("No transaction Constructor for " + clazz + " (" + msg + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
PO po = (PO)constructor.newInstance(new Object[] {Env.getCtx(), new Integer(Record_ID), trxName});
|
||||||
|
return po;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
if (e.getCause() != null)
|
||||||
|
{
|
||||||
|
Throwable t = e.getCause();
|
||||||
|
s_log.log(Level.SEVERE, "(id) - Table=" + tableName + ",Class=" + clazz, t);
|
||||||
|
errorLogged = true;
|
||||||
|
if (t instanceof Exception)
|
||||||
|
s_log.saveError("Error", (Exception)e.getCause());
|
||||||
|
else
|
||||||
|
s_log.saveError("Error", "Table=" + tableName + ",Class=" + clazz);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, "(id) - Table=" + tableName + ",Class=" + clazz, e);
|
||||||
|
errorLogged = true;
|
||||||
|
s_log.saveError("Error", "Table=" + tableName + ",Class=" + clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!errorLogged)
|
||||||
|
s_log.log(Level.SEVERE, "(id) - Not found - Table=" + tableName
|
||||||
|
+ ", Record_ID=" + Record_ID);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PO getPO(String tableName, ResultSet rs, String trxName) {
|
||||||
|
Class<?> clazz = getClass(tableName);
|
||||||
|
if (clazz == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean errorLogged = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Constructor<?> constructor = clazz.getDeclaredConstructor(new Class[]{Properties.class, ResultSet.class, String.class});
|
||||||
|
PO po = (PO)constructor.newInstance(new Object[] {Env.getCtx(), rs, trxName});
|
||||||
|
return po;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, "(rs) - Table=" + tableName + ",Class=" + clazz, e);
|
||||||
|
errorLogged = true;
|
||||||
|
s_log.saveError("Error", "Table=" + tableName + ",Class=" + clazz);
|
||||||
|
}
|
||||||
|
if (!errorLogged)
|
||||||
|
s_log.log(Level.SEVERE, "(rs) - Not found - Table=" + tableName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 2010 Heng Sin Low *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||||
|
* See the GNU General Public License for more details. *
|
||||||
|
* You should have received a copy of the GNU General Public License along *
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.adempiere.base;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import org.compiere.model.PO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model factory interface, extracted from legacy code in MTable.
|
||||||
|
* @author hengsin
|
||||||
|
*/
|
||||||
|
public interface IModelFactory {
|
||||||
|
/**
|
||||||
|
* Get Persistence Class for Table
|
||||||
|
* @param tableName table name
|
||||||
|
* @return class or null
|
||||||
|
*/
|
||||||
|
public Class<?> getClass (String tableName);
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Get PO Class Instance
|
||||||
|
* @param tableName
|
||||||
|
* @param Record_ID record
|
||||||
|
* @param trxName
|
||||||
|
* @return PO for Record or null
|
||||||
|
*/
|
||||||
|
public PO getPO (String tableName, int Record_ID, String trxName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get PO Class Instance
|
||||||
|
* @param tableName
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return PO for Record or null
|
||||||
|
*/
|
||||||
|
public PO getPO (String tableName, ResultSet rs, String trxName);
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 2010 Heng Sin Low *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||||
|
* See the GNU General Public License for more details. *
|
||||||
|
* You should have received a copy of the GNU General Public License along *
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.adempiere.base.equinox;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IConfigurationElement;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
|
import org.eclipse.osgi.service.datalocation.Location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ExtensionPriorityManager {
|
||||||
|
private Properties priorityMap = new Properties();
|
||||||
|
|
||||||
|
private static final ExtensionPriorityManager instance = new ExtensionPriorityManager();
|
||||||
|
|
||||||
|
private ExtensionPriorityManager() {
|
||||||
|
Location location = Platform.getInstanceLocation();
|
||||||
|
URL url = location.getURL();
|
||||||
|
File file = new File(url.getPath(), "extensions-priorty.properties");
|
||||||
|
if (file.exists() && file.canRead()) {
|
||||||
|
try {
|
||||||
|
priorityMap.load(new FileInputStream(file));
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param element
|
||||||
|
* @return priority of extension
|
||||||
|
*/
|
||||||
|
public int getPriority(IConfigurationElement element) {
|
||||||
|
int priority = 0;
|
||||||
|
String id = element.getDeclaringExtension().getUniqueIdentifier();
|
||||||
|
if (id != null) {
|
||||||
|
String p = priorityMap.getProperty(id);
|
||||||
|
if (p != null) {
|
||||||
|
try {
|
||||||
|
priority = Integer.parseInt(p);
|
||||||
|
return priority;
|
||||||
|
} catch (NumberFormatException e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String p = element.getAttribute("priority");
|
||||||
|
if (p != null) {
|
||||||
|
try {
|
||||||
|
priority = Integer.parseInt(p);
|
||||||
|
return priority;
|
||||||
|
} catch (NumberFormatException e) {}
|
||||||
|
}
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ExtensionPriorityManager singleton instance
|
||||||
|
*/
|
||||||
|
public static ExtensionPriorityManager getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,20 +17,20 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package org.compiere.model;
|
package org.compiere.model;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.adempiere.base.IModelFactory;
|
||||||
|
import org.adempiere.base.Service;
|
||||||
import org.adempiere.model.GenericPO;
|
import org.adempiere.model.GenericPO;
|
||||||
import org.compiere.util.CCache;
|
import org.compiere.util.CCache;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
import org.compiere.util.Env;
|
|
||||||
import org.compiere.util.Util;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persistent Table Model
|
* Persistent Table Model
|
||||||
|
@ -52,12 +52,12 @@ public class MTable extends X_AD_Table
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -2367316254623142732L;
|
private static final long serialVersionUID = -2367316254623142732L;
|
||||||
|
|
||||||
public final static int MAX_OFFICIAL_ID = 999999;
|
public final static int MAX_OFFICIAL_ID = 999999;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Table from Cache
|
* Get Table from Cache
|
||||||
* @param ctx context
|
* @param ctx context
|
||||||
|
@ -92,9 +92,9 @@ public class MTable extends X_AD_Table
|
||||||
while (it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
MTable retValue = it.next();
|
MTable retValue = it.next();
|
||||||
if (tableName.equalsIgnoreCase(retValue.getTableName())
|
if (tableName.equalsIgnoreCase(retValue.getTableName())
|
||||||
&& retValue.getCtx() == ctx
|
&& retValue.getCtx() == ctx
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ public class MTable extends X_AD_Table
|
||||||
{
|
{
|
||||||
pstmt = null;
|
pstmt = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retValue != null)
|
if (retValue != null)
|
||||||
{
|
{
|
||||||
Integer key = new Integer (retValue.getAD_Table_ID());
|
Integer key = new Integer (retValue.getAD_Table_ID());
|
||||||
|
@ -136,7 +136,7 @@ public class MTable extends X_AD_Table
|
||||||
}
|
}
|
||||||
return retValue;
|
return retValue;
|
||||||
} // get
|
} // get
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Table Name
|
* Get Table Name
|
||||||
* @param ctx context
|
* @param ctx context
|
||||||
|
@ -147,39 +147,16 @@ public class MTable extends X_AD_Table
|
||||||
{
|
{
|
||||||
return MTable.get(ctx, AD_Table_ID).getTableName();
|
return MTable.get(ctx, AD_Table_ID).getTableName();
|
||||||
} // getTableName
|
} // getTableName
|
||||||
|
|
||||||
|
|
||||||
/** Cache */
|
/** Cache */
|
||||||
private static CCache<Integer,MTable> s_cache = new CCache<Integer,MTable>("AD_Table", 20);
|
private static CCache<Integer,MTable> s_cache = new CCache<Integer,MTable>("AD_Table", 20);
|
||||||
private static CCache<String,Class<?>> s_classCache = new CCache<String,Class<?>>("PO_Class", 20);
|
|
||||||
|
|
||||||
/** Static Logger */
|
/** Static Logger */
|
||||||
private static CLogger s_log = CLogger.getCLogger (MTable.class);
|
private static CLogger s_log = CLogger.getCLogger (MTable.class);
|
||||||
|
|
||||||
/** Packages for Model Classes */
|
|
||||||
private static final String[] s_packages = new String[] {
|
|
||||||
|
|
||||||
"org.compiere.model", "org.compiere.wf",
|
|
||||||
"org.compiere.print", "org.compiere.impexp",
|
|
||||||
"compiere.model", // globalqss allow compatibility with other plugins
|
|
||||||
"adempiere.model", // Extensions
|
|
||||||
"org.adempiere.model"
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Special Classes */
|
|
||||||
private static final String[] s_special = new String[] {
|
|
||||||
"AD_Element", "org.compiere.model.M_Element",
|
|
||||||
"AD_Registration", "org.compiere.model.M_Registration",
|
|
||||||
"AD_Tree", "org.compiere.model.MTree_Base",
|
|
||||||
"R_Category", "org.compiere.model.MRequestCategory",
|
|
||||||
"GL_Category", "org.compiere.model.MGLCategory",
|
|
||||||
"K_Category", "org.compiere.model.MKCategory",
|
|
||||||
"C_ValidCombination", "org.compiere.model.MAccount",
|
|
||||||
"C_Phase", "org.compiere.model.MProjectTypePhase",
|
|
||||||
"C_Task", "org.compiere.model.MProjectTypeTask"
|
|
||||||
// AD_Attribute_Value, AD_TreeNode
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Persistence Class for Table
|
* Get Persistence Class for Table
|
||||||
* @param tableName table name
|
* @param tableName table name
|
||||||
|
@ -187,194 +164,17 @@ public class MTable extends X_AD_Table
|
||||||
*/
|
*/
|
||||||
public static Class<?> getClass (String tableName)
|
public static Class<?> getClass (String tableName)
|
||||||
{
|
{
|
||||||
// Not supported
|
List<IModelFactory> factoryList = Service.list(IModelFactory.class);
|
||||||
if (tableName == null || tableName.endsWith("_Trl"))
|
if (factoryList == null)
|
||||||
return null;
|
return null;
|
||||||
|
for(IModelFactory factory : factoryList) {
|
||||||
//check cache
|
Class<?> clazz = factory.getClass(tableName);
|
||||||
Class<?> cache = s_classCache.get(tableName);
|
|
||||||
if (cache != null)
|
|
||||||
{
|
|
||||||
//Object.class indicate no generated PO class for tableName
|
|
||||||
if (cache.equals(Object.class))
|
|
||||||
return null;
|
|
||||||
else
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
MTable table = MTable.get(Env.getCtx(), tableName);
|
|
||||||
String entityType = table.getEntityType();
|
|
||||||
|
|
||||||
// Import Tables (Name conflict)
|
|
||||||
// Import Tables doesn't manage model M classes, just X_
|
|
||||||
if (tableName.startsWith("I_"))
|
|
||||||
{
|
|
||||||
MEntityType et = MEntityType.get(Env.getCtx(), entityType);
|
|
||||||
String etmodelpackage = et.getModelPackage();
|
|
||||||
if (etmodelpackage == null || MEntityType.ENTITYTYPE_Dictionary.equals(entityType))
|
|
||||||
etmodelpackage = "org.compiere.model"; // fallback for dictionary or empty model package on entity type
|
|
||||||
Class<?> clazz = getPOclass(etmodelpackage + ".X_" + tableName, tableName);
|
|
||||||
if (clazz != null)
|
if (clazz != null)
|
||||||
{
|
|
||||||
s_classCache.put(tableName, clazz);
|
|
||||||
return clazz;
|
return clazz;
|
||||||
}
|
|
||||||
s_log.warning("No class for table: " + tableName);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special Naming
|
|
||||||
for (int i = 0; i < s_special.length; i++)
|
|
||||||
{
|
|
||||||
if (s_special[i++].equals(tableName))
|
|
||||||
{
|
|
||||||
Class<?> clazz = getPOclass(s_special[i], tableName);
|
|
||||||
if (clazz != null)
|
|
||||||
{
|
|
||||||
s_classCache.put(tableName, clazz);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//begin [ 1784588 ] Use ModelPackage of EntityType to Find Model Class - vpj-cd
|
|
||||||
if (!MEntityType.ENTITYTYPE_Dictionary.equals(entityType))
|
|
||||||
{
|
|
||||||
MEntityType et = MEntityType.get(Env.getCtx(), entityType);
|
|
||||||
String etmodelpackage = et.getModelPackage();
|
|
||||||
if (etmodelpackage != null)
|
|
||||||
{
|
|
||||||
Class<?> clazz = null;
|
|
||||||
clazz = getPOclass(etmodelpackage + ".M" + Util.replace(tableName, "_", ""), tableName);
|
|
||||||
if (clazz != null) {
|
|
||||||
s_classCache.put(tableName, clazz);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
clazz = getPOclass(etmodelpackage + ".X_" + tableName, tableName);
|
|
||||||
if (clazz != null) {
|
|
||||||
s_classCache.put(tableName, clazz);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
s_log.warning("No class for table with it entity: " + tableName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//end [ 1784588 ]
|
|
||||||
|
|
||||||
// Strip table name prefix (e.g. AD_) Customizations are 3/4
|
|
||||||
String className = tableName;
|
|
||||||
int index = className.indexOf('_');
|
|
||||||
if (index > 0)
|
|
||||||
{
|
|
||||||
if (index < 3) // AD_, A_
|
|
||||||
className = className.substring(index+1);
|
|
||||||
/* DELETEME: this part is useless - teo_sarca, [ 1648850 ]
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String prefix = className.substring(0,index);
|
|
||||||
if (prefix.equals("Fact")) // keep custom prefix
|
|
||||||
className = className.substring(index+1);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
// Remove underlines
|
|
||||||
className = Util.replace(className, "_", "");
|
|
||||||
|
|
||||||
// Search packages
|
|
||||||
for (int i = 0; i < s_packages.length; i++)
|
|
||||||
{
|
|
||||||
StringBuffer name = new StringBuffer(s_packages[i]).append(".M").append(className);
|
|
||||||
Class<?> clazz = getPOclass(name.toString(), tableName);
|
|
||||||
if (clazz != null)
|
|
||||||
{
|
|
||||||
s_classCache.put(tableName, clazz);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Adempiere Extension
|
|
||||||
Class<?> clazz = getPOclass("adempiere.model.X_" + tableName, tableName);
|
|
||||||
if (clazz != null)
|
|
||||||
{
|
|
||||||
s_classCache.put(tableName, clazz);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
//hengsin - allow compatibility with compiere plugins
|
|
||||||
//Compiere Extension
|
|
||||||
clazz = getPOclass("compiere.model.X_" + tableName, tableName);
|
|
||||||
if (clazz != null)
|
|
||||||
{
|
|
||||||
s_classCache.put(tableName, clazz);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default
|
|
||||||
clazz = getPOclass("org.compiere.model.X_" + tableName, tableName);
|
|
||||||
if (clazz != null)
|
|
||||||
{
|
|
||||||
s_classCache.put(tableName, clazz);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Object.class to indicate no PO class for tableName
|
|
||||||
s_classCache.put(tableName, Object.class);
|
|
||||||
return null;
|
return null;
|
||||||
} // getClass
|
} // getClass
|
||||||
|
|
||||||
/**
|
|
||||||
* Get PO class
|
|
||||||
* @param className fully qualified class name
|
|
||||||
* @return class or null
|
|
||||||
* @deprecated Use {@link #getPOclass(String, String)}
|
|
||||||
*/
|
|
||||||
private static Class<?> getPOclass (String className)
|
|
||||||
{
|
|
||||||
return getPOclass(className, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get PO class
|
|
||||||
* @param className fully qualified class name
|
|
||||||
* @param tableName Optional. If specified, the loaded class will be validated for that table name
|
|
||||||
* @return class or null
|
|
||||||
*/
|
|
||||||
private static Class<?> getPOclass (String className, String tableName)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Class<?> clazz = Class.forName(className);
|
|
||||||
// Validate if the class is for specified tableName
|
|
||||||
if (tableName != null)
|
|
||||||
{
|
|
||||||
String classTableName = clazz.getField("Table_Name").get(null).toString();
|
|
||||||
if (!tableName.equals(classTableName))
|
|
||||||
{
|
|
||||||
s_log.finest("Invalid class for table: " + className+" (tableName="+tableName+", classTableName="+classTableName+")");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Make sure that it is a PO class
|
|
||||||
Class<?> superClazz = clazz.getSuperclass();
|
|
||||||
while (superClazz != null)
|
|
||||||
{
|
|
||||||
if (superClazz == PO.class)
|
|
||||||
{
|
|
||||||
s_log.fine("Use: " + className);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
superClazz = superClazz.getSuperclass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
s_log.finest("Not found: " + className);
|
|
||||||
return null;
|
|
||||||
} // getPOclass
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Standard Constructor
|
* Standard Constructor
|
||||||
* @param ctx context
|
* @param ctx context
|
||||||
|
@ -396,7 +196,7 @@ public class MTable extends X_AD_Table
|
||||||
setIsSecurityEnabled (false);
|
setIsSecurityEnabled (false);
|
||||||
setIsView (false); // N
|
setIsView (false); // N
|
||||||
setReplicationType (REPLICATIONTYPE_Local);
|
setReplicationType (REPLICATIONTYPE_Local);
|
||||||
}
|
}
|
||||||
} // MTable
|
} // MTable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -409,10 +209,10 @@ public class MTable extends X_AD_Table
|
||||||
{
|
{
|
||||||
super(ctx, rs, trxName);
|
super(ctx, rs, trxName);
|
||||||
} // MTable
|
} // MTable
|
||||||
|
|
||||||
/** Columns */
|
/** Columns */
|
||||||
private MColumn[] m_columns = null;
|
private MColumn[] m_columns = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Columns
|
* Get Columns
|
||||||
* @param requery requery
|
* @param requery requery
|
||||||
|
@ -455,7 +255,7 @@ public class MTable extends X_AD_Table
|
||||||
list.toArray (m_columns);
|
list.toArray (m_columns);
|
||||||
return m_columns;
|
return m_columns;
|
||||||
} // getColumns
|
} // getColumns
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Column
|
* Get Column
|
||||||
* @param columnName (case insensitive)
|
* @param columnName (case insensitive)
|
||||||
|
@ -474,7 +274,7 @@ public class MTable extends X_AD_Table
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
} // getColumn
|
} // getColumn
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table has a single Key
|
* Table has a single Key
|
||||||
* @return true if table has single key column
|
* @return true if table has single key column
|
||||||
|
@ -484,7 +284,7 @@ public class MTable extends X_AD_Table
|
||||||
String[] keys = getKeyColumns();
|
String[] keys = getKeyColumns();
|
||||||
return keys.length == 1;
|
return keys.length == 1;
|
||||||
} // isSingleKey
|
} // isSingleKey
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Key Columns of Table
|
* Get Key Columns of Table
|
||||||
* @return key columns
|
* @return key columns
|
||||||
|
@ -506,7 +306,7 @@ public class MTable extends X_AD_Table
|
||||||
retValue = list.toArray(retValue);
|
retValue = list.toArray(retValue);
|
||||||
return retValue;
|
return retValue;
|
||||||
} // getKeyColumns
|
} // getKeyColumns
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Get PO Class Instance
|
* Get PO Class Instance
|
||||||
* @param Record_ID record
|
* @param Record_ID record
|
||||||
|
@ -521,62 +321,34 @@ public class MTable extends X_AD_Table
|
||||||
log.log(Level.WARNING, "(id) - Multi-Key " + tableName);
|
log.log(Level.WARNING, "(id) - Multi-Key " + tableName);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Class<?> clazz = getClass(tableName);
|
|
||||||
if (clazz == null)
|
PO po = null;
|
||||||
|
List<IModelFactory> factoryList = Service.list(IModelFactory.class);
|
||||||
|
if (factoryList != null)
|
||||||
{
|
{
|
||||||
//log.log(Level.WARNING, "(id) - Class not found for " + tableName);
|
for(IModelFactory factory : factoryList)
|
||||||
//return null;
|
|
||||||
log.log(Level.INFO, "Using GenericPO for " + tableName);
|
|
||||||
GenericPO po = new GenericPO(tableName, getCtx(), new Integer(Record_ID), trxName);
|
|
||||||
return po;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean errorLogged = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Constructor<?> constructor = null;
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
constructor = clazz.getDeclaredConstructor(new Class[]{Properties.class, int.class, String.class});
|
po = factory.getPO(tableName, Record_ID, trxName);
|
||||||
}
|
if (po != null)
|
||||||
catch (Exception e)
|
{
|
||||||
{
|
if (po.get_ID() != Record_ID && Record_ID > 0)
|
||||||
String msg = e.getMessage();
|
po = null;
|
||||||
if (msg == null)
|
else
|
||||||
msg = e.toString();
|
break;
|
||||||
log.warning("No transaction Constructor for " + clazz + " (" + msg + ")");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PO po = (PO)constructor.newInstance(new Object[] {getCtx(), new Integer(Record_ID), trxName});
|
|
||||||
if (po != null && po.get_ID() != Record_ID && Record_ID > 0)
|
|
||||||
return null;
|
|
||||||
return po;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
if (e.getCause() != null)
|
|
||||||
{
|
|
||||||
Throwable t = e.getCause();
|
|
||||||
log.log(Level.SEVERE, "(id) - Table=" + tableName + ",Class=" + clazz, t);
|
|
||||||
errorLogged = true;
|
|
||||||
if (t instanceof Exception)
|
|
||||||
log.saveError("Error", (Exception)e.getCause());
|
|
||||||
else
|
|
||||||
log.saveError("Error", "Table=" + tableName + ",Class=" + clazz);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log.log(Level.SEVERE, "(id) - Table=" + tableName + ",Class=" + clazz, e);
|
|
||||||
errorLogged = true;
|
|
||||||
log.saveError("Error", "Table=" + tableName + ",Class=" + clazz);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!errorLogged)
|
|
||||||
log.log(Level.SEVERE, "(id) - Not found - Table=" + tableName
|
if (po == null)
|
||||||
+ ", Record_ID=" + Record_ID);
|
{
|
||||||
return null;
|
po = new GenericPO(tableName, getCtx(), new Integer(Record_ID), trxName);
|
||||||
|
if (po.get_ID() != Record_ID && Record_ID > 0)
|
||||||
|
po = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return po;
|
||||||
} // getPO
|
} // getPO
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get PO Class Instance
|
* Get PO Class Instance
|
||||||
* @param rs result set
|
* @param rs result set
|
||||||
|
@ -586,32 +358,24 @@ public class MTable extends X_AD_Table
|
||||||
public PO getPO (ResultSet rs, String trxName)
|
public PO getPO (ResultSet rs, String trxName)
|
||||||
{
|
{
|
||||||
String tableName = getTableName();
|
String tableName = getTableName();
|
||||||
Class<?> clazz = getClass(tableName);
|
|
||||||
if (clazz == null)
|
PO po = null;
|
||||||
|
List<IModelFactory> factoryList = Service.list(IModelFactory.class);
|
||||||
|
if (factoryList != null)
|
||||||
{
|
{
|
||||||
//log.log(Level.SEVERE, "(rs) - Class not found for " + tableName);
|
for(IModelFactory factory : factoryList) {
|
||||||
//return null;
|
po = factory.getPO(tableName, rs, trxName);
|
||||||
log.log(Level.INFO, "Using GenericPO for " + tableName);
|
if (po != null)
|
||||||
GenericPO po = new GenericPO(tableName, getCtx(), rs, trxName);
|
break;
|
||||||
return po;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean errorLogged = false;
|
if (po == null)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
Constructor<?> constructor = clazz.getDeclaredConstructor(new Class[]{Properties.class, ResultSet.class, String.class});
|
po = new GenericPO(tableName, getCtx(), rs, trxName);
|
||||||
PO po = (PO)constructor.newInstance(new Object[] {getCtx(), rs, trxName});
|
|
||||||
return po;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
return po;
|
||||||
log.log(Level.SEVERE, "(rs) - Table=" + tableName + ",Class=" + clazz, e);
|
|
||||||
errorLogged = true;
|
|
||||||
log.saveError("Error", "Table=" + tableName + ",Class=" + clazz);
|
|
||||||
}
|
|
||||||
if (!errorLogged)
|
|
||||||
log.log(Level.SEVERE, "(rs) - Not found - Table=" + tableName);
|
|
||||||
return null;
|
|
||||||
} // getPO
|
} // getPO
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -624,7 +388,7 @@ public class MTable extends X_AD_Table
|
||||||
{
|
{
|
||||||
return getPO(whereClause, null, trxName);
|
return getPO(whereClause, null, trxName);
|
||||||
} // getPO
|
} // getPO
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get PO class instance
|
* Get PO class instance
|
||||||
* @param whereClause
|
* @param whereClause
|
||||||
|
@ -642,46 +406,38 @@ public class MTable extends X_AD_Table
|
||||||
if (info == null) return null;
|
if (info == null) return null;
|
||||||
StringBuffer sqlBuffer = info.buildSelect();
|
StringBuffer sqlBuffer = info.buildSelect();
|
||||||
sqlBuffer.append(" WHERE ").append(whereClause);
|
sqlBuffer.append(" WHERE ").append(whereClause);
|
||||||
String sql = sqlBuffer.toString();
|
String sql = sqlBuffer.toString();
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pstmt = DB.prepareStatement (sql, trxName);
|
pstmt = DB.prepareStatement (sql, trxName);
|
||||||
if (params != null && params.length > 0)
|
if (params != null && params.length > 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < params.length; i++)
|
for (int i = 0; i < params.length; i++)
|
||||||
{
|
{
|
||||||
pstmt.setObject(i+1, params[i]);
|
pstmt.setObject(i+1, params[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResultSet rs = pstmt.executeQuery ();
|
rs = pstmt.executeQuery ();
|
||||||
if (rs.next ())
|
if (rs.next ())
|
||||||
{
|
{
|
||||||
po = getPO(rs, trxName);
|
po = getPO(rs, trxName);
|
||||||
}
|
}
|
||||||
rs.close ();
|
|
||||||
pstmt.close ();
|
|
||||||
pstmt = null;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
log.log(Level.SEVERE, sql, e);
|
log.log(Level.SEVERE, sql, e);
|
||||||
log.saveError("Error", e);
|
log.saveError("Error", e);
|
||||||
}
|
}
|
||||||
try
|
finally
|
||||||
{
|
{
|
||||||
if (pstmt != null)
|
DB.close(rs, pstmt);
|
||||||
pstmt.close ();
|
|
||||||
pstmt = null;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
pstmt = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return po;
|
return po;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Before Save
|
* Before Save
|
||||||
* @param newRecord new
|
* @param newRecord new
|
||||||
|
@ -694,7 +450,7 @@ public class MTable extends X_AD_Table
|
||||||
//
|
//
|
||||||
return true;
|
return true;
|
||||||
} // beforeSave
|
} // beforeSave
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After Save
|
* After Save
|
||||||
* @param newRecord new
|
* @param newRecord new
|
||||||
|
@ -720,11 +476,11 @@ public class MTable extends X_AD_Table
|
||||||
seq.setName(getTableName());
|
seq.setName(getTableName());
|
||||||
seq.save();
|
seq.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
} // afterSave
|
} // afterSave
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get SQL Create
|
* Get SQL Create
|
||||||
* @return create table DDL
|
* @return create table DDL
|
||||||
|
@ -759,7 +515,7 @@ public class MTable extends X_AD_Table
|
||||||
if (constraint != null && constraint.length() > 0)
|
if (constraint != null && constraint.length() > 0)
|
||||||
constraints.append(", ").append(constraint);
|
constraints.append(", ").append(constraint);
|
||||||
}
|
}
|
||||||
// Multi Column PK
|
// Multi Column PK
|
||||||
if (!hasPK && hasParents)
|
if (!hasPK && hasParents)
|
||||||
{
|
{
|
||||||
StringBuffer cols = new StringBuffer();
|
StringBuffer cols = new StringBuffer();
|
||||||
|
@ -781,7 +537,7 @@ public class MTable extends X_AD_Table
|
||||||
.append(")");
|
.append(")");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
} // getSQLCreate
|
} // getSQLCreate
|
||||||
|
|
||||||
// globalqss
|
// globalqss
|
||||||
/**
|
/**
|
||||||
* Grant independence to GenerateModel from AD_Table_ID
|
* Grant independence to GenerateModel from AD_Table_ID
|
||||||
|
@ -808,14 +564,14 @@ public class MTable extends X_AD_Table
|
||||||
}
|
}
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create query to retrieve one or more PO.
|
* Create query to retrieve one or more PO.
|
||||||
* @param whereClause
|
* @param whereClause
|
||||||
* @param trxName
|
* @param trxName
|
||||||
* @return Query
|
* @return Query
|
||||||
*/
|
*/
|
||||||
public Query createQuery(String whereClause, String trxName)
|
public Query createQuery(String whereClause, String trxName)
|
||||||
{
|
{
|
||||||
return new Query(this.getCtx(), this, whereClause, trxName);
|
return new Query(this.getCtx(), this, whereClause, trxName);
|
||||||
}
|
}
|
||||||
|
@ -830,5 +586,5 @@ public class MTable extends X_AD_Table
|
||||||
sb.append (get_ID()).append ("-").append (getTableName()).append ("]");
|
sb.append (get_ID()).append ("-").append (getTableName()).append ("]");
|
||||||
return sb.toString ();
|
return sb.toString ();
|
||||||
} // toString
|
} // toString
|
||||||
|
|
||||||
} // MTable
|
} // MTable
|
|
@ -116,9 +116,9 @@ public abstract class PO
|
||||||
private static DocWorkflowMgr s_docWFMgr = null;
|
private static DocWorkflowMgr s_docWFMgr = null;
|
||||||
|
|
||||||
/** User Maintained Entity Type */
|
/** User Maintained Entity Type */
|
||||||
static protected final String ENTITYTYPE_UserMaintained = "U";
|
static public final String ENTITYTYPE_UserMaintained = "U";
|
||||||
/** Dictionary Maintained Entity Type */
|
/** Dictionary Maintained Entity Type */
|
||||||
static protected final String ENTITYTYPE_Dictionary = "D";
|
static public final String ENTITYTYPE_Dictionary = "D";
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Create New Persistent Object
|
* Create New Persistent Object
|
||||||
|
|
|
@ -139,7 +139,7 @@ public class CLogFile extends Handler
|
||||||
{
|
{
|
||||||
fileName += File.separator;
|
fileName += File.separator;
|
||||||
if (isClient)
|
if (isClient)
|
||||||
fileName += "client";
|
fileName += "client.";
|
||||||
else
|
else
|
||||||
fileName += (CLogMgt.getRootLoggerName() +".");
|
fileName += (CLogMgt.getRootLoggerName() +".");
|
||||||
m_fileNameDate = getFileNameDate(System.currentTimeMillis());
|
m_fileNameDate = getFileNameDate(System.currentTimeMillis());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
bin.includes = feature.xml
|
bin.includes = feature.xml
|
||||||
root=file:build.xml,file:setup.ini
|
root=file:build.xml,file:setup.ini,file:extensions-priorty.properties
|
||||||
root.folder.data=data
|
root.folder.data=data
|
||||||
root.folder.setup=setup
|
root.folder.setup=setup
|
||||||
#linux
|
#linux
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
#format is extension id=priority, for e.g com.foo.MyModelFactory=10
|
||||||
|
#Higher priority value take precedence over lower value, system extensions have priority value 0
|
Loading…
Reference in New Issue