From dceffbc8e8c5b7a5d3e4796c23a2755400306d4e Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 30 May 2008 04:02:59 +0000 Subject: [PATCH] Recommit to recover history on files modified integrating libero --- .../compiere/model/MReplicationStrategy.java | 104 +++ .../oracle/views/RV_OPENITEMTODATE.sql | 56 ++ .../postgresql/views/RV_OPENITEMTODATE.sql | 56 ++ .../org/adempiere/server/JAXPParserMaker.java | 106 +++ .../server/SimpleMessageToTopic.java | 124 ++++ .../server/rpl/IImportProcessor.java | 57 ++ .../org/adempiere/server/rpl/XMLHelper.java | 140 ++++ .../server/rpl/imp/FileImportProcessor.java | 89 +++ .../server/rpl/imp/ImportHelper.java | 604 ++++++++++++++++++ .../server/rpl/imp/ModelImporter.java | 154 +++++ .../server/rpl/imp/TopicImportProcessor.java | 130 ++++ .../server/rpl/imp/TopicListener.java | 278 ++++++++ .../compiere/server/ReplicationProcessor.java | 168 +++++ 13 files changed, 2066 insertions(+) create mode 100644 base/src/org/compiere/model/MReplicationStrategy.java create mode 100644 db/ddlutils/oracle/views/RV_OPENITEMTODATE.sql create mode 100644 db/ddlutils/postgresql/views/RV_OPENITEMTODATE.sql create mode 100644 serverRoot/src/main/server/org/adempiere/server/JAXPParserMaker.java create mode 100644 serverRoot/src/main/server/org/adempiere/server/SimpleMessageToTopic.java create mode 100644 serverRoot/src/main/server/org/adempiere/server/rpl/IImportProcessor.java create mode 100644 serverRoot/src/main/server/org/adempiere/server/rpl/XMLHelper.java create mode 100644 serverRoot/src/main/server/org/adempiere/server/rpl/imp/FileImportProcessor.java create mode 100644 serverRoot/src/main/server/org/adempiere/server/rpl/imp/ImportHelper.java create mode 100644 serverRoot/src/main/server/org/adempiere/server/rpl/imp/ModelImporter.java create mode 100644 serverRoot/src/main/server/org/adempiere/server/rpl/imp/TopicImportProcessor.java create mode 100644 serverRoot/src/main/server/org/adempiere/server/rpl/imp/TopicListener.java create mode 100644 serverRoot/src/main/server/org/compiere/server/ReplicationProcessor.java diff --git a/base/src/org/compiere/model/MReplicationStrategy.java b/base/src/org/compiere/model/MReplicationStrategy.java new file mode 100644 index 0000000000..01c859d1ec --- /dev/null +++ b/base/src/org/compiere/model/MReplicationStrategy.java @@ -0,0 +1,104 @@ +package org.compiere.model; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.logging.Level; + +import org.compiere.util.CLogger; +import org.compiere.util.DB; + +/** + * @author Trifon N. Trifonov + */ +public class MReplicationStrategy extends X_AD_ReplicationStrategy { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** Static Logger */ + private static CLogger s_log = CLogger.getCLogger (MReplicationStrategy.class); + + + public MReplicationStrategy(Properties ctx, int AD_ReplicationStrategy_ID, String trxName) { + super(ctx, AD_ReplicationStrategy_ID, trxName); + } + + public X_AD_ReplicationTable[] getReplicationTables() { + List resultList = new ArrayList(); + + StringBuffer sql = new StringBuffer("SELECT * ") + .append(" FROM ").append(X_AD_ReplicationTable.Table_Name) + .append(" WHERE ").append(X_AD_ReplicationTable.COLUMNNAME_AD_ReplicationStrategy_ID).append("=?") // #1 + .append(" AND IsActive = ?") // #2 +// .append(" ORDER BY ").append(orderBy) + ; + PreparedStatement pstmt = null; + X_AD_ReplicationTable rplTable = null; + try { + pstmt = DB.prepareStatement (sql.toString(), get_TrxName()); + pstmt.setInt(1, getAD_ReplicationStrategy_ID()); + pstmt.setString(2, "Y"); + ResultSet rs = pstmt.executeQuery (); + while ( rs.next() ) { + rplTable = new X_AD_ReplicationTable (getCtx(), rs, get_TrxName()); + resultList.add(rplTable); + } + rs.close (); + pstmt.close (); + pstmt = null; + } catch (SQLException e) { + s_log.log(Level.SEVERE, sql.toString(), e); + } finally { + try { + if (pstmt != null) pstmt.close (); + pstmt = null; + } catch (Exception e) { pstmt = null; } + } + + X_AD_ReplicationTable[] result = (X_AD_ReplicationTable[])resultList.toArray( new X_AD_ReplicationTable[0]); + return result; + } + + public X_AD_ReplicationDocument[] getReplicationDocuments() { + List resultList = new ArrayList(); + + StringBuffer sql = new StringBuffer("SELECT * ") + .append(" FROM ").append(X_AD_ReplicationDocument.Table_Name) + .append(" WHERE ").append(X_AD_ReplicationDocument.COLUMNNAME_AD_ReplicationStrategy_ID).append("=?") // #1 + .append(" AND IsActive = ?") // #2 +// .append(" ORDER BY ").append(orderBy) + ; + PreparedStatement pstmt = null; + X_AD_ReplicationDocument rplDocument = null; + try { + pstmt = DB.prepareStatement (sql.toString(), get_TrxName()); + pstmt.setInt(1, getAD_ReplicationStrategy_ID()); + pstmt.setString(2, "Y"); + ResultSet rs = pstmt.executeQuery (); + while ( rs.next() ) { + rplDocument = new X_AD_ReplicationDocument (getCtx(), rs, get_TrxName()); + resultList.add(rplDocument); + } + rs.close (); + pstmt.close (); + pstmt = null; + } catch (SQLException e) { + s_log.log(Level.SEVERE, sql.toString(), e); + } finally { + try { + if (pstmt != null) pstmt.close (); + pstmt = null; + } catch (Exception e) { pstmt = null; } + } + + X_AD_ReplicationDocument[] result = (X_AD_ReplicationDocument[])resultList.toArray( new X_AD_ReplicationDocument[0]); + return result; + } + +} diff --git a/db/ddlutils/oracle/views/RV_OPENITEMTODATE.sql b/db/ddlutils/oracle/views/RV_OPENITEMTODATE.sql new file mode 100644 index 0000000000..2d543a8be1 --- /dev/null +++ b/db/ddlutils/oracle/views/RV_OPENITEMTODATE.sql @@ -0,0 +1,56 @@ +CREATE OR REPLACE VIEW RV_OPENITEMTODATE +(AD_ORG_ID, AD_CLIENT_ID, DOCUMENTNO, C_INVOICE_ID, C_ORDER_ID, + C_BPARTNER_ID, ISSOTRX, DATEINVOICED, DATEACCT, NETDAYS, + DUEDATE, DAYSDUE, DISCOUNTDATE, DISCOUNTAMT, GRANDTOTAL, + --PAIDAMT, OPENAMT, + C_CURRENCY_ID, C_CONVERSIONTYPE_ID, C_PAYMENTTERM_ID, + ISPAYSCHEDULEVALID, C_INVOICEPAYSCHEDULE_ID, INVOICECOLLECTIONTYPE, C_CAMPAIGN_ID, C_PROJECT_ID, + C_ACTIVITY_ID) +AS +SELECT i.AD_Org_ID, i.AD_Client_ID, + i.DocumentNo, i.C_Invoice_ID, i.C_Order_ID, i.C_BPartner_ID, i.IsSOTrx, + i.DateInvoiced, i.DateAcct, + p.NetDays, + paymentTermDueDate(i.C_PaymentTerm_ID, i.DateInvoiced) AS DueDate, + paymentTermDueDays(i.C_PaymentTerm_ID, i.DateInvoiced, getdate()) AS DaysDue, + addDays(i.DateInvoiced,p.DiscountDays) AS DiscountDate, + ROUND(i.GrandTotal*p.Discount/100,2) AS DiscountAmt, + i.GrandTotal, + --invoicePaid(i.C_Invoice_ID, i.C_Currency_ID, 1) AS PaidAmt, + --invoiceOpen(i.C_Invoice_ID,0) AS OpenAmt, + i.C_Currency_ID, i.C_ConversionType_ID, + i.C_PaymentTerm_ID, + i.IsPayScheduleValid, cast(null as number) AS C_InvoicePaySchedule_ID, i.InvoiceCollectionType, + i.C_Campaign_ID, i.C_Project_ID, i.C_Activity_ID +FROM RV_C_Invoice i + INNER JOIN C_PaymentTerm p ON (i.C_PaymentTerm_ID=p.C_PaymentTerm_ID) +WHERE -- i.IsPaid='N' + --invoiceOpen(i.C_Invoice_ID,0) <> 0 AND + i.IsPayScheduleValid<>'Y' + AND i.DocStatus<>'DR' +UNION +SELECT i.AD_Org_ID, i.AD_Client_ID, + i.DocumentNo, i.C_Invoice_ID, i.C_Order_ID, i.C_BPartner_ID, i.IsSOTrx, + i.DateInvoiced, i.DateAcct, + daysBetween(ips.DueDate,i.DateInvoiced) AS NetDays, + ips.DueDate, + daysBetween(getdate(),ips.DueDate) AS DaysDue, + ips.DiscountDate, + ips.DiscountAmt, + ips.DueAmt AS GrandTotal, +-- invoicePaid(i.C_Invoice_ID, i.C_Currency_ID, 1) AS PaidAmt, +-- invoiceOpen(i.C_Invoice_ID, ips.C_InvoicePaySchedule_ID) AS OpenAmt, + i.C_Currency_ID, i.C_ConversionType_ID, + i.C_PaymentTerm_ID, + i.IsPayScheduleValid, ips.C_InvoicePaySchedule_ID, i.InvoiceCollectionType, + i.C_Campaign_ID, i.C_Project_ID, i.C_Activity_ID +FROM RV_C_Invoice i + INNER JOIN C_InvoicePaySchedule ips ON (i.C_Invoice_ID=ips.C_Invoice_ID) +WHERE -- i.IsPaid='N' + --invoiceOpen(i.C_Invoice_ID,ips.C_InvoicePaySchedule_ID) <> 0 AND + i.IsPayScheduleValid='Y' + AND i.DocStatus<>'DR' + AND ips.IsValid='Y'; + + + diff --git a/db/ddlutils/postgresql/views/RV_OPENITEMTODATE.sql b/db/ddlutils/postgresql/views/RV_OPENITEMTODATE.sql new file mode 100644 index 0000000000..9f6210e819 --- /dev/null +++ b/db/ddlutils/postgresql/views/RV_OPENITEMTODATE.sql @@ -0,0 +1,56 @@ +CREATE OR REPLACE VIEW RV_OPENITEMTODATE +(AD_ORG_ID, AD_CLIENT_ID, DOCUMENTNO, C_INVOICE_ID, C_ORDER_ID, + C_BPARTNER_ID, ISSOTRX, DATEINVOICED, DATEACCT, NETDAYS, + DUEDATE, DAYSDUE, DISCOUNTDATE, DISCOUNTAMT, GRANDTOTAL, + --PAIDAMT, OPENAMT, + C_CURRENCY_ID, C_CONVERSIONTYPE_ID, C_PAYMENTTERM_ID, + ISPAYSCHEDULEVALID, C_INVOICEPAYSCHEDULE_ID, INVOICECOLLECTIONTYPE, C_CAMPAIGN_ID, C_PROJECT_ID, + C_ACTIVITY_ID) +AS +SELECT i.AD_Org_ID, i.AD_Client_ID, + i.DocumentNo, i.C_Invoice_ID, i.C_Order_ID, i.C_BPartner_ID, i.IsSOTrx, + i.DateInvoiced, i.DateAcct, + p.NetDays, + paymentTermDueDate(i.C_PaymentTerm_ID, i.DateInvoiced) AS DueDate, + paymentTermDueDays(i.C_PaymentTerm_ID, i.DateInvoiced, getdate()) AS DaysDue, + addDays(i.DateInvoiced,p.DiscountDays) AS DiscountDate, + ROUND(i.GrandTotal*p.Discount/100,2) AS DiscountAmt, + i.GrandTotal, + --invoicePaid(i.C_Invoice_ID, i.C_Currency_ID, 1) AS PaidAmt, + --invoiceOpen(i.C_Invoice_ID,0) AS OpenAmt, + i.C_Currency_ID, i.C_ConversionType_ID, + i.C_PaymentTerm_ID, + i.IsPayScheduleValid, cast(null as numeric) AS C_InvoicePaySchedule_ID, i.InvoiceCollectionType, + i.C_Campaign_ID, i.C_Project_ID, i.C_Activity_ID +FROM RV_C_Invoice i + INNER JOIN C_PaymentTerm p ON (i.C_PaymentTerm_ID=p.C_PaymentTerm_ID) +WHERE -- i.IsPaid='N' + --invoiceOpen(i.C_Invoice_ID,0) <> 0 AND + i.IsPayScheduleValid<>'Y' + AND i.DocStatus<>'DR' +UNION +SELECT i.AD_Org_ID, i.AD_Client_ID, + i.DocumentNo, i.C_Invoice_ID, i.C_Order_ID, i.C_BPartner_ID, i.IsSOTrx, + i.DateInvoiced, i.DateAcct, + daysBetween(ips.DueDate,i.DateInvoiced) AS NetDays, + ips.DueDate, + daysBetween(getdate(),ips.DueDate) AS DaysDue, + ips.DiscountDate, + ips.DiscountAmt, + ips.DueAmt AS GrandTotal, + --invoicePaid(i.C_Invoice_ID, i.C_Currency_ID, 1) AS PaidAmt, + --invoiceOpen(i.C_Invoice_ID, ips.C_InvoicePaySchedule_ID) AS OpenAmt, + i.C_Currency_ID, i.C_ConversionType_ID, + i.C_PaymentTerm_ID, + i.IsPayScheduleValid, ips.C_InvoicePaySchedule_ID, i.InvoiceCollectionType, + i.C_Campaign_ID, i.C_Project_ID, i.C_Activity_ID +FROM RV_C_Invoice i + INNER JOIN C_InvoicePaySchedule ips ON (i.C_Invoice_ID=ips.C_Invoice_ID) +WHERE -- i.IsPaid='N' + --invoiceOpen(i.C_Invoice_ID,ips.C_InvoicePaySchedule_ID) <> 0 AND + i.IsPayScheduleValid='Y' + AND i.DocStatus<>'DR' + AND ips.IsValid='Y'; + + + diff --git a/serverRoot/src/main/server/org/adempiere/server/JAXPParserMaker.java b/serverRoot/src/main/server/org/adempiere/server/JAXPParserMaker.java new file mode 100644 index 0000000000..2a92a36d4b --- /dev/null +++ b/serverRoot/src/main/server/org/adempiere/server/JAXPParserMaker.java @@ -0,0 +1,106 @@ +/********************************************************************** +* This file is part of Adempiere ERP Bazaar * +* http://www.adempiere.org * +* * +* Copyright (C) Trifon Trifonov. * +* Copyright (C) Contributors * +* * +* This program is free software; you can redistribute it and/or * +* modify it under the terms of the GNU General Public License * +* as published by the Free Software Foundation; either version 2 * +* of the License, or (at your option) any later version. * +* * +* 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., 51 Franklin Street, Fifth Floor, Boston, * +* MA 02110-1301, USA. * +* * +* Contributors: * +* - Trifon Trifonov (trifonnt@users.sourceforge.net) * +* * +* Sponsors: * +* - E-evolution (http://www.e-evolution.com) * +***********************************************************************/ +package org.adempiere.server; + +import javax.xml.parsers.*; +import org.w3c.dom.*; +import org.xml.sax.*; +import java.io.*; + +/** + * + * @author Trifon N. Trifonov + * + */ +public class JAXPParserMaker { + + public static StringBuffer text = new StringBuffer("") + .append("") + .append(" ") + .append(" GardenWorld") + .append(" ") + .append(" ") + .append(" 0") + .append(" ") + .append(" SYSTEM") + .append(" ") + .append(" ") + .append(" C&W-test05") + .append(" C&W Construction-05") + .append(" ") + .append(" Standard") + .append(" ") + .append(" GardenWorld") + .append(" ") + .append(" ") + .append(" 04/11/2001 09:11:36") + .append(" ") + .append(" SuperUser") + .append(" ") + .append(" SYSTEM") + .append(" ") + .append(" ") + .append(" 11/17/2007 01:49:50") + .append(" ") + .append(" System") + .append(" ") + .append(" SYSTEM") + .append(" ") + .append(" ") + .append("") + ; + + public static void main(String[] args) { + + try { + DocumentBuilderFactory builderFactory = DocumentBuilderFactory + .newInstance(); + DocumentBuilder parser = builderFactory.newDocumentBuilder(); + + try { + // Read the entire document into memory + Document document = parser.parse( new InputSource(new StringReader( text.toString() ) ) ); + + System.out.println( "Document = " + document); + // work with the document... + } catch (SAXException e) { + System.err.println(e); + } catch (IOException e) { + System.err.println(e); + } + + + } catch (ParserConfigurationException e) { + System.err.println("You need to install a JAXP aware parser."); + } + + } + +} + diff --git a/serverRoot/src/main/server/org/adempiere/server/SimpleMessageToTopic.java b/serverRoot/src/main/server/org/adempiere/server/SimpleMessageToTopic.java new file mode 100644 index 0000000000..b43b19f7d4 --- /dev/null +++ b/serverRoot/src/main/server/org/adempiere/server/SimpleMessageToTopic.java @@ -0,0 +1,124 @@ +/********************************************************************** + * This file is part of Adempiere ERP Bazaar * + * http://www.adempiere.org * + * * + * Copyright (C) Trifon Trifonov. * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - Trifon Trifonov (trifonnt@users.sourceforge.net) * + * * + * Sponsors: * + * - E-evolution (http://www.e-evolution.com/) * + **********************************************************************/ +package org.adempiere.server; + +import org.apache.activemq.ActiveMQConnectionFactory; + +import javax.jms.Connection; +import javax.jms.Session; +import javax.jms.Destination; +import javax.jms.MessageProducer; +import javax.jms.DeliveryMode; +import javax.jms.TextMessage; + +public class SimpleMessageToTopic { + + private static final String TOPIC_NAME = "ExampleTopic"; + + private static StringBuffer text = new StringBuffer("") + .append("") + .append(" ") + .append(" GardenWorld") + .append(" ") + .append(" ") + .append(" 0") + .append(" ") + .append(" SYSTEM") + .append(" ") + .append(" ") + .append(" C&W-test06") + .append(" C&W Construction-06") + .append(" ") + .append(" Standard") + .append(" ") + .append(" GardenWorld") + .append(" ") + .append(" ") + .append(" 04/11/2001 09:11:36") + .append(" ") + .append(" SuperUser") + .append(" ") + .append(" SYSTEM") + .append(" ") + .append(" ") + .append(" 11/17/2007 01:49:50") + .append(" ") + .append(" System") + .append(" ") + .append(" SYSTEM") + .append(" ") + .append(" ") + .append("") + ; + + + + public static void main(String[] args) { + runTool("localhost", 61616); + } + + public static void runTool(String host, int port) { + try { + // Create a ConnectionFactory + ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory( + "tcp://"+host+":"+port); + + // Create a Connection + Connection connection = connectionFactory.createConnection(); + connection.setClientID("GardenWorld"); + connection.start(); + + // Create a Session + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Create the destination (Topic or Queue) + Destination destination = session.createTopic(TOPIC_NAME); + + // Create a MessageProducer from the Session to the Topic or Queue + MessageProducer producer = session.createProducer(destination); + producer.setTimeToLive(10000); + producer.setDeliveryMode(DeliveryMode.PERSISTENT); + + // Create a message + + TextMessage message = session.createTextMessage(text.toString()); + + // Tell the producer to send the message + System.out.println("Sent message"); + producer.send(message); + + // Clean up + session.close(); + connection.close(); + } catch (Exception e) { + System.out.println("Caught: " + e); + e.printStackTrace(); + } + } +} diff --git a/serverRoot/src/main/server/org/adempiere/server/rpl/IImportProcessor.java b/serverRoot/src/main/server/org/adempiere/server/rpl/IImportProcessor.java new file mode 100644 index 0000000000..7afc009a6f --- /dev/null +++ b/serverRoot/src/main/server/org/adempiere/server/rpl/IImportProcessor.java @@ -0,0 +1,57 @@ +/********************************************************************** +* This file is part of Adempiere ERP Bazaar * +* http://www.adempiere.org * +* * +* Copyright (C) Trifon Trifonov. * +* Copyright (C) Contributors * +* * +* This program is free software; you can redistribute it and/or * +* modify it under the terms of the GNU General Public License * +* as published by the Free Software Foundation; either version 2 * +* of the License, or (at your option) any later version. * +* * +* 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., 51 Franklin Street, Fifth Floor, Boston, * +* MA 02110-1301, USA. * +* * +* Contributors: * +* - Trifon Trifonov (trifonnt@users.sourceforge.net) * +* * +* Sponsors: * +* - E-evolution (http://www.e-evolution.com) * +***********************************************************************/ +package org.adempiere.server.rpl; + +import java.util.Properties; + +import org.compiere.server.ReplicationProcessor; + +/** + * Interface for Import processor + * @author Trifon Trifonov + * + */ +public interface IImportProcessor { + + /** + * @param ctx + * @param expProcessor + * @param trxName + * @return void + * @throws Exception + */ + public void process(Properties ctx, ReplicationProcessor replicationProcessor, String trxName) throws Exception; + + /** + * + * @throws Exception + */ + public void stop() throws Exception; + +} diff --git a/serverRoot/src/main/server/org/adempiere/server/rpl/XMLHelper.java b/serverRoot/src/main/server/org/adempiere/server/rpl/XMLHelper.java new file mode 100644 index 0000000000..fc894d6dd0 --- /dev/null +++ b/serverRoot/src/main/server/org/adempiere/server/rpl/XMLHelper.java @@ -0,0 +1,140 @@ +/********************************************************************** +* This file is part of Adempiere ERP Bazaar * +* http://www.adempiere.org * +* * +* Copyright (C) Trifon Trifonov. * +* Copyright (C) Contributors * +* * +* This program is free software; you can redistribute it and/or * +* modify it under the terms of the GNU General Public License * +* as published by the Free Software Foundation; either version 2 * +* of the License, or (at your option) any later version. * +* * +* 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., 51 Franklin Street, Fifth Floor, Boston, * +* MA 02110-1301, USA. * +* * +* Contributors: * +* - Trifon Trifonov (trifonnt@users.sourceforge.net) * +* * +* Sponsors: * +* - E-evolution (http://www.e-evolution.com) * +***********************************************************************/ +package org.adempiere.server.rpl; + +import java.io.File; +import java.io.IOException; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Utility class which helps with XML processing. + * + * @author Trifon Trifonov + * @version $Id$ + */ +public class XMLHelper { + + private static XPath xPath = XPathFactory.newInstance().newXPath(); + + public static Element getElement(String xPathExpression, Node node) + throws XPathExpressionException { + return (Element) xPath.evaluate(xPathExpression, node, + XPathConstants.NODE); + } + + public static Node getNode(String xPathExpression, Node node) + throws XPathExpressionException { + return (Node) xPath + .evaluate(xPathExpression, node, XPathConstants.NODE); + } + + public static NodeList getNodeList(String xPathExpression, Node node) + throws XPathExpressionException { + return (NodeList) xPath.evaluate(xPathExpression, node, + XPathConstants.NODESET); + } + + public static Double getNumber(String xPathExpression, Node node) + throws XPathExpressionException { + return (Double) xPath.evaluate(xPathExpression, node, + XPathConstants.NUMBER); + } + + public static String getString(String xPathExpression, Node node) + throws XPathExpressionException { + return (String) xPath.evaluate(xPathExpression, node, + XPathConstants.STRING); + } + + public static Boolean getBoolean(String xPathExpression, Node node) + throws XPathExpressionException { + return (Boolean) xPath.evaluate(xPathExpression, node, + XPathConstants.BOOLEAN); + } + + + + public static Document createDocumentFromFile(String pathToXmlFile) + throws ParserConfigurationException, SAXException, IOException { + // path to file is global + String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; + String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; + // String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; + + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + // validate against XML Schema in dbsql2xml.xsd + // documentBuilderFactory.setNamespaceAware(true); + + //INFO change validation to true. Someday when xsd file is complete... + documentBuilderFactory.setValidating(false); + documentBuilderFactory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); + // documentBuilderFactory.setAttribute(JAXP_SCHEMA_SOURCE, new File(pathToXsdFile)); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + Document document = documentBuilder.parse(new File(pathToXmlFile)); + + return document; + } + + public static Document createDocumentFromString(String str) + throws ParserConfigurationException, SAXException, IOException { + // path to file is global +// String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; +// String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; + // String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; + + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + // validate against XML Schema in dbsql2xml.xsd + // documentBuilderFactory.setNamespaceAware(true); + + //INFO change validation to true. Someday when xsd file is complete... + documentBuilderFactory.setValidating(false); +// documentBuilderFactory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); + // documentBuilderFactory.setAttribute(JAXP_SCHEMA_SOURCE, new File(pathToXsdFile)); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + Document document = documentBuilder.parse( new InputSource(new StringReader( str ) ) ); + + return document; + } + +} diff --git a/serverRoot/src/main/server/org/adempiere/server/rpl/imp/FileImportProcessor.java b/serverRoot/src/main/server/org/adempiere/server/rpl/imp/FileImportProcessor.java new file mode 100644 index 0000000000..39daeeebe6 --- /dev/null +++ b/serverRoot/src/main/server/org/adempiere/server/rpl/imp/FileImportProcessor.java @@ -0,0 +1,89 @@ +/********************************************************************** + * This file is part of Adempiere ERP Bazaar * + * http://www.adempiere.org * + * * + * Copyright (C) Trifon Trifonov. * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - Trifon Trifonov (trifonnt@users.sourceforge.net) * + * * + * Sponsors: * + * - E-evolution (http://www.e-evolution.com/) * + **********************************************************************/ +package org.adempiere.server.rpl.imp; + +import java.util.Properties; + +import org.adempiere.server.rpl.IImportProcessor; +import org.adempiere.server.rpl.XMLHelper; +import org.eevolution.model.MIMPProcessor; +import org.eevolution.model.X_IMP_ProcessorParameter; +import org.compiere.server.ReplicationProcessor; +import org.compiere.util.CLogger; +import org.w3c.dom.Document; + +/** + * + * @author Trifon N. Trifonov + * @version $Id:$ + */ +public class FileImportProcessor implements IImportProcessor { + + /** Logger */ + protected CLogger log = CLogger.getCLogger (FileImportProcessor.class); + + public void process(Properties ctx, ReplicationProcessor replicationProcessor, String trxName) + throws Exception { + + MIMPProcessor impProcessor = replicationProcessor.getMImportProcessor(); + + X_IMP_ProcessorParameter[] processorParameters = impProcessor.getIMP_ProcessorParameters(trxName); + + String fileName = null; + if (processorParameters != null && processorParameters.length > 0) { + for (int i = 0; i < processorParameters.length; i++) { + log.info("ProcesParameter Value = " + processorParameters[i].getValue()); + log.info("ProcesParameter ParameterValue = " + processorParameters[i].getParameterValue()); + if (processorParameters[i].getValue().equals("fileName")) { + fileName = processorParameters[i].getParameterValue(); + } else { + // Some other mandatory parameter here + } + } + } + + if (fileName == null || fileName.length() == 0) { + throw new Exception("Missing IMP_ProcessorParameter with key 'fileName'!"); + } + + Document documentToBeImported = XMLHelper.createDocumentFromFile(fileName); + StringBuffer result = new StringBuffer(); + + ImportHelper impHelper = new ImportHelper( ctx ); + impHelper.importXMLDocument(result, documentToBeImported, trxName ); + +// addLog(0, null, null, Msg.getMsg(ctx, "ImportModelProcessResult") + "\n" + result.toString()); + } + + public void stop() throws Exception { + // do nothing! + + } + +} diff --git a/serverRoot/src/main/server/org/adempiere/server/rpl/imp/ImportHelper.java b/serverRoot/src/main/server/org/adempiere/server/rpl/imp/ImportHelper.java new file mode 100644 index 0000000000..45f086e62a --- /dev/null +++ b/serverRoot/src/main/server/org/adempiere/server/rpl/imp/ImportHelper.java @@ -0,0 +1,604 @@ +/********************************************************************** + * This file is part of Adempiere ERP Bazaar * + * http://www.adempiere.org * + * * + * Copyright (C) Trifon Trifonov. * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - Trifon Trifonov (trifonnt@users.sourceforge.net) * + * * + * Sponsors: * + * - E-evolution (http://www.e-evolution.com/) * + **********************************************************************/ +package org.adempiere.server.rpl.imp; + +import java.math.BigDecimal; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Properties; +import java.util.logging.Level; + +import javax.xml.xpath.XPathExpressionException; + +import org.adempiere.server.rpl.XMLHelper; +import org.compiere.model.MClient; +import org.compiere.model.MColumn; +import org.eevolution.model.MEXPFormat; +import org.eevolution.model.MEXPFormatLine; +import org.compiere.model.MTable; +import org.compiere.model.PO; +import org.compiere.model.X_AD_Client; +import org.eevolution.model.X_EXP_FormatLine; +import org.compiere.util.CLogger; +import org.compiere.util.DB; +import org.compiere.util.DisplayType; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * @author Trifon N. Trifonov + */ +public class ImportHelper { + + /** Instance Logger */ + private CLogger log = CLogger.getCLogger(ImportHelper.class); + + /** Static Logger */ + private static CLogger s_log = CLogger.getCLogger(ImportHelper.class); + + /** Date Time Format */ + private SimpleDateFormat m_dateTimeFormat = null; + + /** Date Format */ + private SimpleDateFormat m_dateFormat = null; + + /** Custom Date Format */ + private SimpleDateFormat m_customDateFormat = null; + + /** Context */ + private Properties ctx = null; + + public ImportHelper(Properties ctx) { + this.ctx = ctx; + // Construct DateFromat and DateTimeFormat + m_dateTimeFormat = DisplayType.getDateFormat(DisplayType.DateTime, Env.getLanguage(ctx)); + m_dateFormat = DisplayType.getDateFormat(DisplayType.Date, Env.getLanguage(ctx)); + } + + /** + * @param ctx + * @param result + * @param documentToBeImported + * @param trxName + * @throws Exception + * @throws SQLException + * @throws XPathExpressionException + */ + public void importXMLDocument(StringBuffer result, Document documentToBeImported, String trxName) + throws Exception, SQLException, XPathExpressionException + { + //Element rootNode = importedDocument.getFirstChild(); + Element rootElement = documentToBeImported.getDocumentElement(); + //NodeList nl = rootElement.getChildNodes(); + // iterate over all address nodes and find the one that has the correct addressee + //for (int i = 0; i < nl.getLength(); i++) { /* */ } + + // Find which Export format to Load... + String AD_Client_Value = null; + //AD_Client_Value = XMLHelper.getString("@AD_Client_Value", rootNode); + AD_Client_Value = rootElement.getAttribute("AD_Client_Value"); + log.info("AD_Client_Value = " + AD_Client_Value); + if (AD_Client_Value == null || "".equals(AD_Client_Value)) { + throw new Exception(Msg.getMsg(ctx, "XMLClientValueMandatory")); + } + String version = null; + version = rootElement.getAttribute("Version"); + log.info("Version = " + version); + if (version == null || "".equals(version)) { + throw new Exception(Msg.getMsg(ctx, "XMLVersionAttributeMandatory")); + } + + MClient client = null; + client = getAD_ClientByValue(ctx, AD_Client_Value, trxName); + if (client == null) { + throw new Exception(Msg.getMsg(ctx, "XMLClientNotFound")); + } + log.info(client.toString()); + + String EXP_Format_Value = null; + EXP_Format_Value = rootElement.getNodeName(); + log.info("EXP_Format_Value = " + EXP_Format_Value); + + MEXPFormat expFormat = null; + expFormat = MEXPFormat.getFormatByValueAD_Client_IDAndVersion(ctx, EXP_Format_Value, client.getAD_Client_ID(), version, trxName); + if (expFormat == null || expFormat.getEXP_Format_ID() == 0) { + // Fall back to SYSTEM Client. + // Try to search Export format defined for SYSTEM Client!!! + MClient systemClient = null; + systemClient = MClient.get(ctx, 0); + if (systemClient == null) { + throw new Exception(Msg.getMsg(ctx, "XMLClientNotFound")); + } + log.info(systemClient.toString()); + expFormat = MEXPFormat.getFormatByValueAD_Client_IDAndVersion(ctx, EXP_Format_Value, systemClient.getAD_Client_ID(), version, trxName); + } + if (expFormat == null || expFormat.getEXP_Format_ID() == 0) { + throw new Exception(Msg.getMsg(ctx, "EXPFormatNotFound")); + } + log.info("expFormat = " + expFormat.toString()); + + PO po = importElement(ctx, result, rootElement, expFormat, trxName); + + // Here must invoke other method else we get cycle... + boolean resultSave = po.saveReplica(true); + result.append("ResultSave=").append(resultSave).append("; "); + if (resultSave) { + // Success in save + } else { + // Failed in save + throw new Exception(Msg.getMsg(ctx, "EXPFormatFailedSave")); + } + } + + /** + * @param result + * @param rootElement + * @param expFormat + * @throws Exception + * @throws XPathExpressionException + */ + @SuppressWarnings("unchecked") + private PO importElement(Properties ctx, StringBuffer result, Element rootElement, + MEXPFormat expFormat, String trxName) throws Exception, XPathExpressionException + { + // get AD_Table ID from export Format. + int AD_Table_ID = expFormat.getAD_Table_ID(); + + // Load appropriate Model class... + MTable table = MTable.get(ctx, AD_Table_ID); + log.info("Table = " + table); + + int record_ID = 0; + // Find Record_ID by ???Value??? In fact by Columns set as Part Of Unique Index in Export Format! + record_ID = getID(ctx, expFormat, rootElement, rootElement.getNodeName(), trxName); + log.info("record_ID = " + record_ID); + + PO po = table.getPO(record_ID, trxName); + log.info("PO.toString() = " + po.toString()); + + if (po.get_KeyColumns().length > 1 || po.get_KeyColumns().length < 1) { + throw new Exception(Msg.getMsg(ctx, "EDIMultiColumnNotSupported")); + } + + StringBuffer orderBy = new StringBuffer(X_EXP_FormatLine.COLUMNNAME_IsMandatory).append(" DESC ") + .append(", ").append(X_EXP_FormatLine.COLUMNNAME_Position) + ; + MEXPFormatLine[] formatLines = expFormat.getFormatLinesOrderedBy(orderBy.toString()); + if (formatLines == null || formatLines.length < 1) { + throw new Exception(Msg.getMsg(ctx, "EXPFormatNoLines")); + } + Object value = null; + // Iterate all Export Format Lines (even this marked as part of unique index) + // and set value of column! + for (int i = 0; i < formatLines.length; i++) { + log.info("=================== Beginnig of Format Line ==============================="); + log.info("formatLines["+i+"]=[" + formatLines[i].toString() + "]"); + + if (MEXPFormatLine.TYPE_XMLElement.equals(formatLines[i].getType())) { + // XML Element + value = XMLHelper.getString(formatLines[i].getValue(), rootElement); + log.info("value=[" + value + "]"); + + } else if (MEXPFormatLine.TYPE_ReferencedEXPFormat.equals(formatLines[i].getType())) { + // Referenced Export Format +/* + + 0 + + SYSTEM + + + ... + */ + + MEXPFormat referencedExpFormat = new MEXPFormat(ctx, formatLines[i].getEXP_EmbeddedFormat_ID(), trxName); + log.info("referencedExpFormat = " + referencedExpFormat); + + int refRecord_ID = 0; + // Find Record_ID by ???Value??? In fact by Columns set as Part Of Unique Index in Export Format! + String xPath = null; + //xPath = ""+rootElement.getNodeName() + "/" + formatLines[i].getValue() + ""; // Do not work + xPath = "" + formatLines[i].getValue() + ""; // + + log.info("SEARCH FOR XML Element = " + xPath); + Element referencedNode = XMLHelper.getElement(xPath, rootElement); + + //NodeList nodeList = XMLHelper.getNodeList(xPath, rootElement); + //referencedNode = (Element)nodeList.item(0); + + log.info("referencedNode = " + referencedNode); + + refRecord_ID = getID(ctx, referencedExpFormat, referencedNode, formatLines[i].getValue(), trxName); + log.info("refRecord_ID = " + refRecord_ID); + + value = new Integer(refRecord_ID); + log.info("value=[" + value + "]"); + } else if (MEXPFormatLine.TYPE_EmbeddedEXPFormat.equals(formatLines[i].getType())) { + boolean resSave = false; + if (po.get_ID() == 0) { + resSave = po.saveReplica(true); + result.append("ResultSave-MasterPO=").append(resSave).append("; "); + log.info("ResultSave-MasterPO = " + resSave); + } else { + resSave = true; + } + if (resSave) { + // Success in save + } else { + throw new Exception("Failed to save Master PO"); + } + // Embedded Export Format +/* + GardenWorls + ... + ... <-- MUST save Master Record here! Else we can't set orderLine.setC_Order_ID(..) + ... + ... + */ + MEXPFormat referencedExpFormat = new MEXPFormat(ctx, formatLines[i].getEXP_EmbeddedFormat_ID(), trxName); + log.info("embeddedExpFormat = " + referencedExpFormat); + + NodeList nodeList = XMLHelper.getNodeList("/"+rootElement.getNodeName() + "/" + formatLines[i].getValue(), rootElement); + for (int j = 0; j < nodeList.getLength(); j++) { + Element referencedElement = (Element)nodeList.item(j); + log.info("EmbeddedEXPFormat - referencedElement.getNodeName = " + referencedElement.getNodeName()); + + PO embeddedPo = null; + // Import embedded PO + log.info("=== BEGIN RECURSION CALL ==="); + embeddedPo = importElement(ctx, result, referencedElement, referencedExpFormat, trxName); + log.info("embeddedPo = " + embeddedPo); + + //embeddedPo.set_CustomColumn(po.get_KeyColumns()[0], po.get_ID()); + //log.info("embeddedPo.set"+po.get_KeyColumns()[0]+" = [" + po.get_ID()+"]"); + + boolean rSave = embeddedPo.saveReplica(true); + result.append("ResultSave-EmbeddedPO=").append(rSave).append("; "); + } + + } else if (MEXPFormatLine.TYPE_XMLAttribute.equals(formatLines[i].getType())) { + // XML Attribute + value = XMLHelper.getString("@" + formatLines[i].getValue(), rootElement); + log.info("value=[" + value + "]"); + } else { + // Export Format Line is not one of two possible values...ERROR + throw new Exception(Msg.getMsg(ctx, "EXPFormatLineNonValidType")); + } + if (value == null) { + + } else { +/* if (column.getColumnName().equals("AD_Client_ID")) { + //Env.setContext(Env.getCtx(), "#AD_Client_ID", value.toString()); + } + if (column.getColumnName().equals("AD_Org_ID")) { + //Env.setContext(Env.getCtx(), "#AD_Org_ID", value.toString()); + } */ + if ( MEXPFormatLine.TYPE_EmbeddedEXPFormat.equals(formatLines[i].getType()) ) { + // do nothing + } else { + MColumn column = MColumn.get(ctx, formatLines[i].getAD_Column_ID()); + log.info("column=[" + column + "]"); + + // Clazz + Class clazz = DisplayType.getClass(column.getAD_Reference_ID(), true); + // Handle Posted + if (column.getColumnName().equalsIgnoreCase("Posted") + || column.getColumnName().equalsIgnoreCase("Processed") + || column.getColumnName().equalsIgnoreCase("Processing")) + { + clazz = Boolean.class; + } else if (column.getColumnName().equalsIgnoreCase("Record_ID")) + { + clazz = Integer.class; + } else if (column.getColumnName().equalsIgnoreCase("AD_Language") + || column.getColumnName().equalsIgnoreCase("EntityType")) + { + clazz = String.class; + } + log.info("clazz = " + clazz.getName()); + // Handle Date and Time + value = handleDateTime(value, column, formatLines[i]); + + log.info("formatLinesType = " + formatLines[i].getType()); + if (MEXPFormatLine.TYPE_EmbeddedEXPFormat.equals( formatLines[i].getType() ) ) { + // DO NOTHING + throw new Exception("We can't be here!!!"); + } else { + if (column.getAD_Reference_ID() == DisplayType.DateTime + || column.getAD_Reference_ID() == DisplayType.Date + ) + { + // + po.set_ValueOfColumn(formatLines[i].getAD_Column_ID(), value); + log.info("Set value of column ["+column.getColumnName()+"]=["+value+"]"); + } else if (column.getAD_Reference_ID() == DisplayType.ID + || column.getAD_Reference_ID() == DisplayType.Integer + || column.getAD_Reference_ID() == DisplayType.Search + || column.getAD_Reference_ID() == DisplayType.TableDir + || column.getAD_Reference_ID() == DisplayType.Table + ) + { + // + int intValue = Integer.parseInt(value.toString()); + value = new Integer( intValue ); + log.info("Abut to set int value of column ["+column.getColumnName()+"]=["+value+"]"); + po.set_ValueOfColumn(formatLines[i].getAD_Column_ID(), intValue); + log.info("Set int value of column ["+column.getColumnName()+"]=["+value+"]"); + } else if (column.getAD_Reference_ID() == DisplayType.Amount + || column.getAD_Reference_ID() == DisplayType.Number + || column.getAD_Reference_ID() == DisplayType.CostPrice + || column.getAD_Reference_ID() == DisplayType.Quantity + ) + { + // + double doubleValue = Double.parseDouble(value.toString()); + value = new BigDecimal(doubleValue); + //value = new Double( doubleValue ); + log.info("About to set BigDecimal value of column ["+column.getColumnName()+"]=["+value+"]"); + po.set_ValueOfColumn(formatLines[i].getAD_Column_ID(), value); + log.info("Set BigDecimal value of column ["+column.getColumnName()+"]=["+value+"]"); + } + else if(column.getAD_Reference_ID() == DisplayType.YesNo) + { + po.set_ValueOfColumn(formatLines[i].getAD_Column_ID(), value); + } + else { + // + try { + log.info("About to set value of column ["+column.getColumnName()+"]=["+value+"]"); + po.set_ValueOfColumn(formatLines[i].getAD_Column_ID(), clazz.cast(value)); + log.info("Set value of column ["+column.getColumnName()+"]=["+value+"]"); + } catch (ClassCastException ex) { + ex.printStackTrace(); + throw new Exception(ex); + } + + //po.set_ValueOfColumn(formatLines[i].getAD_Column_ID(), value); + } + result.append(column.getColumnName()).append("=").append(value).append("; "); + } + } + } + + } + + return po; + } + + public static MClient getAD_ClientByValue(Properties ctx, String value, String trxName) + throws SQLException + { + MClient result = null; + + StringBuffer sql = new StringBuffer("SELECT AD_Client_ID ") + .append(" FROM ").append(X_AD_Client.Table_Name) + .append(" WHERE ").append(X_AD_Client.COLUMNNAME_Value).append(" = ?") + // .append(" AND IsActive = ?") + ; + //s_log.info(sql.toString()); + s_log.info("Client_Value =[" + value + "]"); + + PreparedStatement pstmt = null; + try { + pstmt = DB.prepareStatement(sql.toString(), trxName); + pstmt.setString(1, value); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) { + int AD_Client_ID = rs.getInt(1); + s_log.info("AD_Client_ID = " + AD_Client_ID); + result = new MClient(ctx, AD_Client_ID, trxName); + } + rs.close(); + pstmt.close(); + pstmt = null; + } catch (SQLException e) { + s_log.log(Level.SEVERE, sql.toString(), e); + throw e; + } finally { + try { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } catch (Exception e) { + pstmt = null; + } + } + + return result; + } + + public int getID(Properties ctx, MEXPFormat expFormat, Element rootElement, String rootNodeName, String trxName) throws Exception { + int result = 0; + + if (expFormat == null || rootElement == null || rootNodeName == null) { + throw new IllegalArgumentException("expFormat, rootNode and RootnodeName can't be null!"); + } + log.info("expFormat = " + expFormat); + log.info("rootNode.getNodeName() = " + rootElement.getNodeName()); + log.info("rootNodeName = " + rootNodeName); + if (rootElement.getParentNode() != null) { + log.info("rootNode.ParentName = " + rootElement.getParentNode().getNodeName()); + } + + // get AD_Table ID from export Format. + int AD_Table_ID = expFormat.getAD_Table_ID(); + + // Load appropriate Model class... + MTable table = MTable.get(ctx, AD_Table_ID); + log.info("Table = " + table); + + //Select * FROM table.getTableName() WHERE Value or ANY IDENTIFIER column + StringBuffer sql = new StringBuffer("SELECT * ") + .append(" FROM ").append(table.getTableName()) + .append(" WHERE ") + ; + // Get list with all Unique columns! + MEXPFormatLine[] uniqueFormatLines = expFormat.getUniqueColumns(); + if (uniqueFormatLines == null || uniqueFormatLines.length < 1) { + throw new Exception(Msg.getMsg(ctx, "EXPFormatLineNoUniqueColumns")); + } + Object[] values = new Object[uniqueFormatLines.length]; + for (int i = 0; i < uniqueFormatLines.length; i++) { + log.info("--- iterate unique column with index = ["+i+"]"); + MColumn column = MColumn.get(ctx, uniqueFormatLines[i].getAD_Column_ID()); + log.info("column = ["+column+"]"); + + if (MEXPFormatLine.TYPE_XMLElement.equals(uniqueFormatLines[i].getType())) { + // XML Element + //values[i] = XMLHelper.getString("/"+rootElement.getNodeName() + "/" + uniqueFormatLines[i].getValue(), rootElement); + String xPath = null; + //xPath = "/"+rootNodeName + "/" + uniqueFormatLines[i].getValue(); -- works + //xPath = "/"+ uniqueFormatLines[i].getValue(); // do not work + xPath = ""+ uniqueFormatLines[i].getValue(); + + values[i] = XMLHelper.getString(xPath, rootElement); + //log.info("xml PATH =" + rootElement.getNodeName() + "." + xPath ); + log.info("values[" + i + "]=" + values[i]); + + } else if (MEXPFormatLine.TYPE_ReferencedEXPFormat.equals(uniqueFormatLines[i].getType())) { + // Referenced Export Format + log.info("referencedExpFormat.EXP_EmbeddedFormat_ID = " + uniqueFormatLines[i].getEXP_EmbeddedFormat_ID()); + MEXPFormat referencedExpFormat = new MEXPFormat(ctx, uniqueFormatLines[i].getEXP_EmbeddedFormat_ID(), trxName); + log.info("referencedExpFormat = " + referencedExpFormat); + /* + + + 0 + + SYSTEM + + + ... + + */ + int record_ID = 0; + // Find Record_ID by ???Value??? In fact by Columns set as Part Of Unique Index in Export Format! + Element referencedNode = ((Element) rootElement.getElementsByTagName(uniqueFormatLines[i].getValue()).item(0)); + log.info("referencedNode = " + referencedNode); + + record_ID = getID(ctx, referencedExpFormat, referencedNode, uniqueFormatLines[i].getValue(), trxName); + log.info("record_ID = " + record_ID); + + values[i] = new Integer(record_ID); + } else { + // Export Format Line is not one of two possible values...ERROR + throw new Exception(Msg.getMsg(ctx, "EXPFormatLineNonValidType")); + } + if (i == 0) { + sql.append(" ").append(column.getColumnName()).append(" = ? "); + } else { + sql.append(" AND ").append(column.getColumnName()).append(" = ? "); + } + + } + log.info("sql = " + sql.toString()); + + PreparedStatement pstmt = null; + try { + pstmt = DB.prepareStatement (sql.toString(), trxName); + for (int i = 0; i < uniqueFormatLines.length; i++) { + MColumn col = MColumn.get(ctx, uniqueFormatLines[i].getAD_Column_ID()); + + if (col.getAD_Reference_ID() == DisplayType.DateTime + || col.getAD_Reference_ID() == DisplayType.Date + ) + { + + Timestamp value = (Timestamp)handleDateTime(values[i], col , uniqueFormatLines[i]); + pstmt.setTimestamp(i+1, value); + } + else + { + pstmt.setObject(i+1, values[i]); + log.info("pstmt.setObject["+(i+1)+"] = [" + values[i]+"]"); + } + + } + ResultSet rs = pstmt.executeQuery(); + if ( rs.next() ) { + result = rs.getInt(1); + } + rs.close (); + pstmt.close (); + pstmt = null; + } catch (SQLException e) { + s_log.log(Level.SEVERE, sql.toString(), e); + throw e; + } finally { + try { + if (pstmt != null) pstmt.close (); + pstmt = null; + } catch (Exception e) { pstmt = null; } + } + log.info("result = " + result); + return result; + } + + private Object handleDateTime(Object value, MColumn column, MEXPFormatLine formatLine) throws ParseException { + String valueString = null; + valueString = value.toString(); // We are sure that value is not null + Object result = value; + + if (column.getAD_Reference_ID() == DisplayType.Date) { + if (valueString != null) { + if (formatLine.getDateFormat() != null && !"".equals(formatLine.getDateFormat())) { + m_customDateFormat = new SimpleDateFormat( formatLine.getDateFormat() ); // "MM/dd/yyyy"; MM/dd/yyyy hh:mm:ss + result = new Timestamp(m_customDateFormat.parse(valueString).getTime()); + log.info("Custom Date Format; Parsed value = " + result.toString()); + } else { + result = new Timestamp(m_dateFormat.parse(valueString).getTime()); + log.info("Custom Date Format; Parsed value = " + result.toString()); + } + + } + } else if (column.getAD_Reference_ID() == DisplayType.DateTime) { + if (valueString != null) { + if (formatLine.getDateFormat() != null && !"".equals(formatLine.getDateFormat())) { + m_customDateFormat = new SimpleDateFormat( formatLine.getDateFormat() ); // "MM/dd/yyyy" + result = new Timestamp(m_customDateFormat.parse(valueString).getTime()); + log.info("Custom Date Format; Parsed value = " + result.toString()); + } else { + result = new Timestamp(m_dateTimeFormat.parse(valueString).getTime()); + log.info("Custom Date Format; Parsed value = " + result.toString()); + } + } + } + + return result; + } + +} diff --git a/serverRoot/src/main/server/org/adempiere/server/rpl/imp/ModelImporter.java b/serverRoot/src/main/server/org/adempiere/server/rpl/imp/ModelImporter.java new file mode 100644 index 0000000000..aba442b57d --- /dev/null +++ b/serverRoot/src/main/server/org/adempiere/server/rpl/imp/ModelImporter.java @@ -0,0 +1,154 @@ +/********************************************************************** + * This file is part of Adempiere ERP Bazaar * + * http://www.adempiere.org * + * * + * Copyright (C) Trifon Trifonov. * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - Trifon Trifonov (trifonnt@users.sourceforge.net) * + * * + * Sponsors: * + * - E-evolution (http://www.e-evolution.com/) * + **********************************************************************/ +package org.adempiere.server.rpl.imp; + +import java.util.logging.Level; + +import org.adempiere.server.rpl.XMLHelper; +import org.compiere.Adempiere; +import org.compiere.process.ProcessInfo; +import org.compiere.process.ProcessInfoParameter; +import org.compiere.process.SvrProcess; +import org.compiere.util.CLogMgt; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.w3c.dom.Document; + +/** + * + * @author Trifon N. Trifonov + * @author victor.perez@e-evolution.com + * FB [1963487 ] Is necessary new process to export and import with an Export + * @see http://sourceforge.net/tracker/?func=detail&atid=879335&aid=1963487&group_id=176962 + * @version $Id:$ + */ +public class ModelImporter extends SvrProcess { + + /** Client Parameter */ + protected int p_AD_Client_ID = 0; + + /** Document Type Parameter */ + protected int p_C_DocType_ID = 0; + + /** Record ID */ + protected int p_Record_ID = 0; + /** EXP_Format_ID */ + protected int p_EXP_Format_ID = 0; + /** File Name **/ + protected String p_FileName = ""; + + /** Table ID */ + int AD_Table_ID = 0; + + + /** + * Get Parameters + */ + protected void prepare() { + + p_Record_ID = getRecord_ID(); + if (p_AD_Client_ID == 0) + p_AD_Client_ID = Env.getAD_Client_ID(getCtx()); + AD_Table_ID = getTable_ID(); + + StringBuffer sb = new StringBuffer("AD_Table_ID=").append(AD_Table_ID); + sb.append("; Record_ID=").append(getRecord_ID()); + // Parameter + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) { + String name = para[i].getParameterName(); + if (para[i].getParameter() == null) + ; + else if (name.equals("EXP_Format_ID")) + p_EXP_Format_ID = para[i].getParameterAsInt(); + else if (name.equals("FileName")) + p_FileName = (String)para[i].getParameter(); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + + if(p_EXP_Format_ID == 0) + p_EXP_Format_ID = p_Record_ID; + if(p_FileName == null) + { + // Load XML file and parse it + String fileNameOr = org.compiere.util.Ini.findAdempiereHome() + + System.getProperty("file.separator") + + "data" + + System.getProperty("file.separator") + + "ExportFile.xml"; + p_FileName = fileNameOr; + } + + log.info(sb.toString()); + } + + /** + * Process + * + * @return info + */ + protected String doIt() throws Exception + { + StringBuffer result = new StringBuffer(""); + + // Load XML file and parse it + /*String fileNameOr = org.compiere.util.Ini.findAdempiereHome() + + System.getProperty("file.separator") + + "data" + + System.getProperty("file.separator"); + + String pathToXmlFile = fileNameOr+"XmlExport-test.xml"; + Document documentToBeImported = XMLHelper.createDocumentFromFile(pathToXmlFile);*/ + Document documentToBeImported = XMLHelper.createDocumentFromFile(p_FileName); + + ImportHelper impHelper = new ImportHelper(getCtx()); + impHelper.importXMLDocument(result, documentToBeImported, get_TrxName()); + + addLog(0, null, null, Msg.getMsg(getCtx(), "ImportModelProcessResult") + "\n" + result.toString()); + return result.toString(); + } + + public static void main(String[] args) + { + CLogMgt.setLoggerLevel(Level.INFO, null); + CLogMgt.setLevel(Level.INFO); + + Adempiere.startupEnvironment(false); + ProcessInfo pi = new ProcessInfo("Test Import Model", 1000000); + pi.setAD_Client_ID(11); + pi.setAD_User_ID(100); + + ModelImporter modelImporter = new ModelImporter(); + modelImporter.startProcess(Env.getCtx(), pi, null); + + System.out.println("Process=" + pi.getTitle() + " Error="+pi.isError() + " Summary=" + pi.getSummary()); + } + +} \ No newline at end of file diff --git a/serverRoot/src/main/server/org/adempiere/server/rpl/imp/TopicImportProcessor.java b/serverRoot/src/main/server/org/adempiere/server/rpl/imp/TopicImportProcessor.java new file mode 100644 index 0000000000..e3ac6c0916 --- /dev/null +++ b/serverRoot/src/main/server/org/adempiere/server/rpl/imp/TopicImportProcessor.java @@ -0,0 +1,130 @@ +/********************************************************************** + * This file is part of Adempiere ERP Bazaar * + * http://www.adempiere.org * + * * + * Copyright (C) Trifon Trifonov. * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - Trifon Trifonov (trifonnt@users.sourceforge.net) * + * * + * Sponsors: * + * - E-evolution (http://www.e-evolution.com/) * + **********************************************************************/ +package org.adempiere.server.rpl.imp; + +import java.util.Properties; + +import org.adempiere.server.rpl.IImportProcessor; +import org.eevolution.model.MIMPProcessor; +import org.eevolution.model.X_IMP_ProcessorParameter; +import org.compiere.server.ReplicationProcessor; +import org.compiere.util.CLogger; + +/** + * Aim of this class is to import records from JMS Server. + * + * @author Trifon N. Trifonov + * @version $Id:$ + */ +public class TopicImportProcessor implements IImportProcessor { + + /** Logger */ + protected CLogger log = CLogger.getCLogger (TopicImportProcessor.class); + + /** + * Topic Listener + */ + private TopicListener topicListener = null; + + + public void process(Properties ctx, ReplicationProcessor replicationProcessor, String trxName) + throws Exception { + + log.info("replicationProcessor = " + replicationProcessor); + log.info("replicationProcessor.getMImportProcessor() = " + replicationProcessor.getMImportProcessor()); + + MIMPProcessor impProcessor = replicationProcessor.getMImportProcessor(); + + X_IMP_ProcessorParameter[] processorParameters = impProcessor.getIMP_ProcessorParameters(trxName); + + String host = impProcessor.getHost(); + int port = impProcessor.getPort(); + String account = impProcessor.getAccount(); + String password = impProcessor.getPasswordInfo(); + + // mandatory parameters! + String topicName = null; + String protocol = null; + boolean isDurableSubscription = true; + String subscriptionName = null; + String options = null; + String clientID = null; + + if (processorParameters != null && processorParameters.length > 0) { + for (int i = 0; i < processorParameters.length; i++) { + log.info("ProcesParameter Value = " + processorParameters[i].getValue()); + log.info("ProcesParameter ParameterValue = " + processorParameters[i].getParameterValue()); + if (processorParameters[i].getValue().equals("topicName")) { + topicName = processorParameters[i].getParameterValue(); + } else if (processorParameters[i].getValue().equals("protocol")) { + protocol = processorParameters[i].getParameterValue(); + } else if (processorParameters[i].getValue().equals("isDurableSubscription")) { + isDurableSubscription = Boolean.parseBoolean( processorParameters[i].getParameterValue() ); + } else if (processorParameters[i].getValue().equals("subscriptionName")) { + subscriptionName = processorParameters[i].getParameterValue(); + } else if (processorParameters[i].getValue().equals("clientID")) { + clientID = processorParameters[i].getParameterValue(); + } else { + // Some other mandatory parameter here + } + } + } + + if (topicName == null || topicName.length() == 0) { + throw new Exception("Missing "+X_IMP_ProcessorParameter.Table_Name+" with key 'topicName'!"); + } + if (protocol == null || protocol.length() == 0) { + throw new Exception("Missing "+X_IMP_ProcessorParameter.Table_Name+" with key 'protocol'!"); + } + if (isDurableSubscription && subscriptionName == null || subscriptionName.length() == 0) { + throw new Exception("Missing "+X_IMP_ProcessorParameter.Table_Name+" with key 'subscriptionName'!"); + } + if (clientID == null || clientID.length() == 0) { + throw new Exception("Missing "+X_IMP_ProcessorParameter.Table_Name+" with key 'clientID'!"); + } + + topicListener = new TopicListener(ctx, replicationProcessor, protocol, host, port + , isDurableSubscription, subscriptionName, topicName, clientID + , account, password, options, trxName); + + topicListener.run(); + log.info("Started topicListener = " + topicListener); + } + + public void stop() throws Exception { + + if ( topicListener != null ) { + topicListener.stop(); + log.info("Stoped topicListener." ); + } + + } + + +} diff --git a/serverRoot/src/main/server/org/adempiere/server/rpl/imp/TopicListener.java b/serverRoot/src/main/server/org/adempiere/server/rpl/imp/TopicListener.java new file mode 100644 index 0000000000..f88f558eac --- /dev/null +++ b/serverRoot/src/main/server/org/adempiere/server/rpl/imp/TopicListener.java @@ -0,0 +1,278 @@ +/********************************************************************** + * This file is part of Adempiere ERP Bazaar * + * http://www.adempiere.org * + * * + * Copyright (C) Trifon Trifonov. * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - Trifon Trifonov (trifonnt@users.sourceforge.net) * + * * + * Sponsors: * + * - E-evolution (http://www.e-evolution.com/) * + **********************************************************************/ +package org.adempiere.server.rpl.imp; + +import java.util.Properties; + +import javax.jms.Connection; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageListener; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.jms.Topic; + +import org.adempiere.server.rpl.XMLHelper; +import org.apache.activemq.ActiveMQConnectionFactory; +import org.eevolution.model.MIMPProcessorLog; +import org.compiere.server.ReplicationProcessor; +import org.compiere.util.CLogger; +import org.w3c.dom.Document; + +/** + * Listen for JMS Messages + * @author Trifon N. Trifonov + */ +public class TopicListener implements MessageListener { + + /** + * Connection to JMS Server + */ + private Connection conn; + + /** + * JMS Session + */ + private Session session; + + /** + * JMS Topic + */ + private Topic topic; + +// private String url="tcp://localhost:61616?jms.dispatchAsync=true&jms.useAsyncSend=true&jms.optimizeAcknowledge=true&jms.disableTimeStampsByDefault=true&jms.optimizedMessageDispatch=true&wireFormat.cacheEnabled=false&wireFormat.tightEncodingEnabled=false"; + private String url="tcp://localhost:61616"; + + /** + * host where JMS server is running + */ + private String host = "localhost"; + + /** + * port of JMS Server + */ + private int port = 61616; + + /** + * Network protocol + */ + private String protocol = "tcp"; + + /** + * Context + */ + private Properties ctx = null; + + /** + * Transaction name + */ + private String trxName = null; + + /** + * Topic Name + */ + private String topicName = null; + + /** + * Replication processor + */ + private ReplicationProcessor replicationProcessor = null; + + /** Logger */ + protected CLogger log = CLogger.getCLogger (TopicListener.class); + + /** + * Is Durable Subscription + */ + private boolean isDurableSubscription = false; + + /** + * Subscription Name + */ + private String subscriptionName = null; + + /** + * JMS Connection ClientID + */ + private String clientID = null; + + /** + * String User Name + */ + private String userName = null; + + /** + * Password + */ + private String password = null; + + + /** + * + */ + public TopicListener(Properties ctx, ReplicationProcessor replicationProcessor, String protocol, String host, int port + , boolean isDurableSubscription, String subscriptionName, String topicName + , String clientID, String userName, String password + , String options, String trxName) { + if ( host != null && !host.equals("") ) { + this.host = host; + } + + if ( port > 0 ) { + this.port = port; + } + + if ( protocol != null && !protocol.equals("") ) { + this.protocol = protocol; + } + + this.topicName = topicName; + + this.setUrl(this.protocol + "://" + this.host + ":" + this.port); + + this.ctx = ctx; + + this.trxName = trxName; + + this.replicationProcessor = replicationProcessor; + + this.isDurableSubscription = isDurableSubscription; + + this.subscriptionName = subscriptionName; + + this.clientID = clientID; + + this.userName = userName; + + this.password = password; + + } + + public void run() throws JMSException { + ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory( url ); + log.finest("ActiveMQConnectionFactory = " + factory); + + if (userName !=null && password != null) { + conn = factory.createConnection(userName, password); + } else { + conn = factory.createConnection(); + } + + log.finest("conn = " + conn ); + + conn.setClientID( clientID ); + + session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); // TODO - could be parameter + log.finest("session = " + session ); + + log.finest("topicName = " + topicName ); + log.finest("subscriptionName = " + subscriptionName); + + topic = session.createTopic( topicName ); + log.finest("topic = " + topic ); + + MessageConsumer consumer = null; + if (isDurableSubscription) { + // http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/com.ibm.websphere.pmc.express.doc/tasks/tjn0012_.html + // The subscriptionName assigned to a durable subscription must be unique within a given client ID. + consumer = session.createDurableSubscriber( topic, subscriptionName ); + } else { + consumer = session.createConsumer( topic ); + } + + log.finest("consumer = " + consumer ); + + consumer.setMessageListener( this ); + + conn.start(); + log.finest("Waiting for JMS messages..."); + // + MIMPProcessorLog pLog = new MIMPProcessorLog(replicationProcessor.getMImportProcessor(), "Connected to JMS Server. Waiting for messages!"); + StringBuffer logReference = new StringBuffer("topicName = ").append(topicName) + .append(", subscriptionName = ").append( subscriptionName ) + ; + pLog.setReference( logReference.toString() ); + boolean resultSave = pLog.save(); + log.finest("Result Save = " + resultSave); + } + + /** + * + */ + public void onMessage(Message message) { + if ( message instanceof TextMessage ) { + + try { + TextMessage txtMessage = (TextMessage) message; + + String text = txtMessage.getText(); + //log.finest("Received message: \n" + text ); + + Document documentToBeImported = XMLHelper.createDocumentFromString( text ); + StringBuffer result = new StringBuffer(); + + ImportHelper impHelper = new ImportHelper( ctx ); + + impHelper.importXMLDocument(result, documentToBeImported, trxName ); + + // + MIMPProcessorLog pLog = new MIMPProcessorLog(replicationProcessor.getMImportProcessor(), "Imported Document!"); + //pLog.setReference("topicName = " + topicName ); + if (text.length() > 2000 ) { + pLog.setTextMsg( text.substring(0, 1999) ); + } else { + pLog.setTextMsg( text); + } + + boolean resultSave = pLog.save(); + log.finest("Result Save = " + resultSave); + + } catch (Exception e) { + replicationProcessor.setProcessRunning(false); + + e.printStackTrace(); + } + + } else { + log.finest("Received NO TEXT Message: " ); + // Received non text message!!! + } + } + + public void setUrl(String url) { + this.url = url; + } + + public void stop() throws JMSException { + // Close JMS Connection + log.finest("Closing JMS Connection!"); + conn.close(); + } +} diff --git a/serverRoot/src/main/server/org/compiere/server/ReplicationProcessor.java b/serverRoot/src/main/server/org/compiere/server/ReplicationProcessor.java new file mode 100644 index 0000000000..ed05b69289 --- /dev/null +++ b/serverRoot/src/main/server/org/compiere/server/ReplicationProcessor.java @@ -0,0 +1,168 @@ +/********************************************************************** + * This file is part of Adempiere ERP Bazaar * + * http://www.adempiere.org * + * * + * Copyright (C) Trifon Trifonov. * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - Trifon Trifonov (trifonnt@users.sourceforge.net) * + * * + * Sponsors: * + * - E-evolution (http://www.e-evolution.com/) * + **********************************************************************/ +package org.compiere.server; + +import java.sql.Timestamp; + +import org.adempiere.server.rpl.IImportProcessor; +import org.compiere.model.MClient; +import org.eevolution.model.MIMPProcessor; +import org.eevolution.model.MIMPProcessorLog; +import org.eevolution.model.X_IMP_Processor_Type; +import org.compiere.util.TimeUtil; + +/** + * + * @author Trifon N. Trifonov + * + */ +public class ReplicationProcessor extends AdempiereServer { + + /** Last Summary */ + private StringBuffer m_summary = new StringBuffer(); + + /** Client info */ + private MClient m_client = null; + + private MIMPProcessor mImportProcessor = null; + + /** + * flag showing if process is working! + */ + private boolean isProcessRunning = false; + + + protected ReplicationProcessor(MIMPProcessor model, int initialNap) { + super (model, initialNap); + mImportProcessor = model; + m_client = MClient.get(mImportProcessor.getCtx(), mImportProcessor.getAD_Client_ID()); + } + + protected ReplicationProcessor(MIMPProcessor model) { + super (model, 30); + mImportProcessor = model; + m_client = MClient.get(mImportProcessor.getCtx(), mImportProcessor.getAD_Client_ID()); + } + + @SuppressWarnings("unchecked") + @Override + protected void doWork() { + if (isProcessRunning) { + // process is already started successfully! + + } else { + // process is not started! + + m_summary = new StringBuffer(); + String trxName = mImportProcessor.get_TrxName(); + if ( trxName == null || "".equals(trxName) ) { +// trxName = "ImportProcessor-" + System.currentTimeMillis(); + } + log.fine("trxName = " + trxName); + log.fine("ImportProcessor = " + mImportProcessor); + + int IMP_ProcessorType_ID = 0; + IMP_ProcessorType_ID = mImportProcessor.getIMP_Processor_Type_ID(); + X_IMP_Processor_Type impProcessor_Type = new X_IMP_Processor_Type(mImportProcessor.getCtx(), IMP_ProcessorType_ID, trxName ); + log.fine("impProcessor_Type = " + impProcessor_Type); // TODO --- REMOVE + + String javaClass = impProcessor_Type.getJavaClass(); + IImportProcessor importProcessor = null; + try { + Class clazz = Class.forName(javaClass); + importProcessor = (IImportProcessor)clazz.newInstance(); + + importProcessor.process(mImportProcessor.getCtx(), this, trxName ); + + } catch (Exception e) { + isProcessRunning = false; + log.fine("ReplicationProcessor caught an exception !!!" ); + e.printStackTrace(); + + log.severe( e.getMessage() ); + + MIMPProcessorLog pLog = new MIMPProcessorLog(mImportProcessor, e.getMessage() ); + pLog.setReference("#" + String.valueOf(p_runCount) + " - " + TimeUtil.formatElapsed(new Timestamp(p_startWork))); + boolean resultSave = pLog.save(); + + try { + importProcessor.stop(); + } catch (Exception e1) { + e1.printStackTrace(); + MIMPProcessorLog pLog2 = new MIMPProcessorLog(mImportProcessor, e1.getMessage() ); + + boolean resultSave2 = pLog2.save(); + } + } + + // + int no = mImportProcessor.deleteLog(); + m_summary.append("Logs Records deleted=").append(no).append("; "); + // + MIMPProcessorLog pLog = new MIMPProcessorLog(mImportProcessor, m_summary.toString()); + pLog.setReference("#" + String.valueOf(p_runCount) + " - " + TimeUtil.formatElapsed(new Timestamp(p_startWork))); + boolean resultSave = pLog.save(); + } + } + + @Override + public String getServerInfo() + { + return "#" + p_runCount + " - Last=" + m_summary.toString(); + } + + /** + * @return the isProcessRunning + */ + public boolean isProcessRunning() { + return isProcessRunning; + } + + /** + * @param isProcessRunning the isProcessRunning to set + */ + public void setProcessRunning(boolean isProcessRunning) { + this.isProcessRunning = isProcessRunning; + } + + /** + * @return the mImportProcessor + */ + public MIMPProcessor getMImportProcessor() { + return mImportProcessor; + } + + /** + * @param importProcessor the mImportProcessor to set + */ + public void setMImportProcessor(MIMPProcessor importProcessor) { + mImportProcessor = importProcessor; + } + +}