/********************************************************************** * 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) * * - Antonio CaƱaveral, e-Evolution * * * * Sponsors: * * - E-evolution (http://www.e-evolution.com/) * *********************************************************************/ package org.adempiere.process.rpl.exp; import java.sql.SQLException; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.HashMap; import java.util.Properties; import java.util.logging.Level; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.adempiere.process.rpl.IExportProcessor; import org.compiere.model.MClient; import org.compiere.model.MColumn; import org.compiere.model.MEXPFormat; import org.compiere.model.MEXPFormatLine; import org.compiere.model.MEXPProcessor; import org.compiere.model.MEXPProcessorType; import org.compiere.model.MReplicationStrategy; import org.compiere.model.MTable; import org.compiere.model.PO; import org.compiere.model.Query; import org.compiere.model.X_EXP_FormatLine; import org.compiere.util.CLogger; import org.compiere.util.DisplayType; import org.compiere.util.Msg; import org.compiere.util.Trx; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Text; /** * @author Trifon N. Trifonov * @author Antonio CaƱaveral, e-Evolution *
  • [ 2195016 ] Implementation delete records messages *
  • https://sourceforge.net/p/adempiere/bugs/1556/ * @author victor.perez@e-evolution.com, e-Evolution *
  • [ 2195090 ] Stabilization of replication *
  • https://sourceforge.net/p/adempiere/bugs/2294/ *
  • BF [2947622] The replication ID (Primary Key) is not working *
  • https://sourceforge.net/p/adempiere/bugs/2308/ * */ public class ExportHelper { /** Logger */ private static final CLogger log = CLogger.getCLogger(ExportHelper.class); /** XML Document */ private Document outDocument = null; /** Custom Date Format */ private SimpleDateFormat m_customDateFormat = null; /** Client */ private int m_AD_Client_ID = -1; /** Replication Strategy */ MReplicationStrategy m_rplStrategy = null; public ExportHelper(MClient client, MReplicationStrategy rplStrategy) { m_AD_Client_ID = client.getAD_Client_ID(); m_rplStrategy = rplStrategy; } public ExportHelper(Properties ctx , int AD_Client_ID) { m_AD_Client_ID = AD_Client_ID; } /** * Process - Generate Export Format * @return info */ public String exportRecord (PO po, Integer ReplicationMode , String ReplicationType, Integer ReplicationEvent) throws Exception { MClient client = MClient.get (po.getCtx(), m_AD_Client_ID); if (log.isLoggable(Level.INFO)) { log.info("Client = " + client.toString()); log.info("po.getAD_Org_ID() = " + po.getAD_Org_ID()); log.info("po.get_TrxName() = " + po.get_TrxName()); } if (po.get_TrxName() == null || po.get_TrxName().equals("")) { po.set_TrxName("exportRecord"); } if (log.isLoggable(Level.INFO)) log.info("Table = " + po.get_TableName()); if (po.get_KeyColumns().length < 1) { throw new Exception(Msg.getMsg (po.getCtx(), "ExportNoneColumnKeyNotSupported"));//TODO: Create Mesagge. } // TODO - get proper Export Format! String version = "3.2.0"; //int EXP_Format_ID = 1000006; MEXPFormat exportFormat = null; //exportFormat = new MFormat(po.getCtx(), EXP_Format_ID, po.get_TrxName()); exportFormat = MEXPFormat.getFormatByAD_Client_IDAD_Table_IDAndVersion(po.getCtx(), m_AD_Client_ID, po.get_Table_ID(), version, po.get_TrxName()); if (log.isLoggable(Level.FINE)) log.fine("exportFormat = " + exportFormat); if (exportFormat == null || exportFormat.getEXP_Format_ID() == 0) { // Fall back to System Client MClient systemClient = MClient.get (po.getCtx(), 0); if (log.isLoggable(Level.INFO)) log.info(systemClient.toString()); exportFormat = MEXPFormat.getFormatByAD_Client_IDAD_Table_IDAndVersion(po.getCtx(), 0, po.get_Table_ID(), version, po.get_TrxName()); if (exportFormat == null || exportFormat.getEXP_Format_ID() == 0) { throw new Exception(Msg.getMsg(po.getCtx(), "EXPFormatNotFound")); } } outDocument = createNewDocument(); HashMap variableMap = new HashMap(); Element rootElement = outDocument.createElement(exportFormat.getValue()); if (exportFormat.getDescription() != null && !"".equals(exportFormat.getDescription())) { rootElement.appendChild(outDocument.createComment(exportFormat.getDescription())); } rootElement.setAttribute("AD_Client_Value", client.getValue()); rootElement.setAttribute("Version", exportFormat.getVersion()); rootElement.setAttribute("ReplicationMode", ReplicationMode.toString()); rootElement.setAttribute("ReplicationType", ReplicationType); rootElement.setAttribute("ReplicationEvent", ReplicationEvent.toString()); outDocument.appendChild(rootElement); generateExportFormat(rootElement, exportFormat, po, po.get_ID(), variableMap); MEXPProcessor mExportProcessor = null; mExportProcessor = new MEXPProcessor (po.getCtx(), m_rplStrategy.getEXP_Processor_ID(), po.get_TrxName() ); if (log.isLoggable(Level.FINE)) log.fine("ExportProcessor = " + mExportProcessor); int EXP_ProcessorType_ID = 0; EXP_ProcessorType_ID = mExportProcessor.getEXP_Processor_Type_ID(); MEXPProcessorType expProcessor_Type = new MEXPProcessorType(po.getCtx(), EXP_ProcessorType_ID, po.get_TrxName() ); String javaClass = expProcessor_Type.getJavaClass(); try { Class clazz = Class.forName(javaClass); IExportProcessor exportProcessor = (IExportProcessor)clazz.getDeclaredConstructor().newInstance(); exportProcessor.process(po.getCtx(), mExportProcessor, outDocument, Trx.get( po.get_TrxName(), false )); } catch (Exception e) { log.severe(e.toString()); throw e; } return outDocument.toString(); } /** * Process - Generate Export Format * @param * * @return Document */ public Document exportRecord (MEXPFormat exportFormat, String where , Integer ReplicationMode , String ReplicationType, Integer ReplicationEvent) throws Exception { MClient client = MClient.get (exportFormat.getCtx(), m_AD_Client_ID); MTable table = MTable.get(exportFormat.getCtx(), exportFormat.getAD_Table_ID()); if (log.isLoggable(Level.INFO)) log.info("Table = " + table); Collection records = new Query(exportFormat.getCtx(),table.getTableName(), exportFormat.getWhereClause(), exportFormat.get_TrxName()) .setOnlyActiveRecords(true) .list(); for (PO po : records) { if (log.isLoggable(Level.INFO)) log.info("Client = " + client.toString()); if (log.isLoggable(Level.FINEST)){ log.finest("po.getAD_Org_ID() = " + po.getAD_Org_ID()); log.finest("po.get_TrxName() = " + po.get_TrxName()); } if (po.get_TrxName() == null || po.get_TrxName().equals("")) { po.set_TrxName("exportRecord"); } if (po.get_KeyColumns().length < 1) { throw new Exception(Msg.getMsg (po.getCtx(), "ExportNoneColumnKeyNotSupported"));//TODO: Create Mesagge. } outDocument = createNewDocument(); HashMap variableMap = new HashMap(); Element rootElement = outDocument.createElement(exportFormat.getValue()); if (exportFormat.getDescription() != null && !"".equals(exportFormat.getDescription())) { rootElement.appendChild(outDocument.createComment(exportFormat.getDescription())); } rootElement.setAttribute("AD_Client_Value", client.getValue()); rootElement.setAttribute("Version", exportFormat.getVersion()); rootElement.setAttribute("ReplicationMode", ReplicationMode.toString()); rootElement.setAttribute("ReplicationType", ReplicationType); rootElement.setAttribute("ReplicationEvent", ReplicationEvent.toString()); outDocument.appendChild(rootElement); generateExportFormat(rootElement, exportFormat, po, po.get_ID(), variableMap); }// finish record read return outDocument; } /* * Trifon Generate Export Format process; RESULT = * * 101 * */ private void generateExportFormat(Element rootElement, MEXPFormat exportFormat, PO masterPO, int masterID, HashMap variableMap) throws SQLException, Exception { Collection formatLines = exportFormat.getFormatLines(); @SuppressWarnings("unused") boolean elementHasValue = false; //for (int i = 0; i < formatLines.length; i++) { for (MEXPFormatLine formatLine : formatLines) { if ( formatLine.getType().equals(X_EXP_FormatLine.TYPE_XMLElement) ) { // process single XML Attribute // Create new element Element newElement = outDocument.createElement(formatLine.getValue()); if (log.isLoggable(Level.INFO)) log.info("Format Line Search key: "+ formatLine.getValue()); if (formatLine.getAD_Column_ID() == 0) { throw new Exception(Msg.getMsg (masterPO.getCtx(), "EXPColumnMandatory")); } MColumn column = MColumn.get(masterPO.getCtx(), formatLine.getAD_Column_ID()); if (column == null) { throw new Exception(Msg.getMsg (masterPO.getCtx(), "EXPColumnMandatory")); } if ( column.isVirtualColumn() ) { log.info("This is Virtual Column!"); } else { } //log.info("["+column.getColumnName()+"]"); Object value = masterPO.get_Value(column.getColumnName()); String valueString = null; if (value != null) { valueString = value.toString(); } else { // Could remove this exception and create empty XML Element when column do not have value. if (formatLine.isMandatory()) { //throw new Exception(Msg.getMsg (masterPO.getCtx(), "EXPFieldMandatory")); } } 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" valueString = m_customDateFormat.format(Timestamp.valueOf (valueString)); newElement.setAttribute("DateFormat", m_customDateFormat.toPattern()); // Add "DateForamt attribute" } else { newElement.setAttribute("DateFormat", valueString); } } } 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" valueString = m_customDateFormat.format(Timestamp.valueOf (valueString)); newElement.setAttribute("DateFormat", m_customDateFormat.toPattern()); // Add "DateForamt attribute" } else { newElement.setAttribute("DateFormat", valueString); } } } if (log.isLoggable(Level.INFO)) log.info("EXP Field - column=["+column.getColumnName()+"]; value=" + value); if (valueString != null && !"".equals(valueString) && !"null".equals(valueString)) { Text newText = outDocument.createTextNode(valueString); newElement.appendChild(newText); rootElement.appendChild(newElement); elementHasValue = true; } else { // Empty field. if (formatLine.isMandatory()) { Text newText = outDocument.createTextNode(""); newElement.appendChild(newText); rootElement.appendChild(newElement); elementHasValue = true; } } } else if ( formatLine.getType().equals(X_EXP_FormatLine.TYPE_XMLAttribute) ) { // process single XML Attribute if (formatLine.getAD_Column_ID() == 0) { throw new Exception(Msg.getMsg (masterPO.getCtx(), "EXPColumnMandatory")); } MColumn column = MColumn.get(masterPO.getCtx(), formatLine.getAD_Column_ID()); if (column == null) { throw new Exception(Msg.getMsg (masterPO.getCtx(), "EXPColumnMandatory")); } if ( column.isVirtualColumn() ) { log.info("This is Virtual Column!"); } else { } //log.info("["+column.getColumnName()+"]"); Object value = masterPO.get_Value(column.getColumnName()); String valueString = null; if (value != null) { valueString = value.toString(); } else { if (formatLine.isMandatory()) { throw new Exception(Msg.getMsg (masterPO.getCtx(), "EXPFieldMandatory")); } } /* if (column.getAD_Reference_ID() == DisplayType.Date) { if (valueString != null) { if (formatLines[i].getDateFormat() != null && !"".equals(formatLines[i].getDateFormat())) { m_customDateFormat = new SimpleDateFormat( formatLines[i].getDateFormat() ); // "MM/dd/yyyy" //Date date = m_customDateFormat.parse ( valueString ); valueString = m_customDateFormat.format(Timestamp.valueOf (valueString)); } else { valueString = m_dateFormat.format (Timestamp.valueOf (valueString)); } } } else if (column.getAD_Reference_ID() == DisplayType.DateTime) { if (valueString != null) { if (formatLines[i].getDateFormat() != null && !"".equals(formatLines[i].getDateFormat())) { m_customDateFormat = new SimpleDateFormat( formatLines[i].getDateFormat() ); // "MM/dd/yyyy" //Date date = m_customDateFormat.parse ( valueString ); valueString = m_customDateFormat.format(Timestamp.valueOf (valueString)); } else { valueString = m_dateTimeFormat.format (Timestamp.valueOf (valueString)); } } }*/ if (log.isLoggable(Level.INFO)) log.info("EXP Field - column=["+column.getColumnName()+"]; value=" + value); if (valueString != null && !"".equals(valueString) && !"null".equals(valueString)) { rootElement.setAttribute(formatLine.getValue(), valueString); elementHasValue = true; } else { // Empty field. } } else if ( formatLine.getType().equals(X_EXP_FormatLine.TYPE_EmbeddedEXPFormat) ) { // process Embedded Export Format int embeddedFormat_ID = formatLine.getEXP_EmbeddedFormat_ID(); //get from cache MEXPFormat embeddedFormat = MEXPFormat.get(masterPO.getCtx(), embeddedFormat_ID, masterPO.get_TrxName()); MTable tableEmbedded = MTable.get(masterPO.getCtx(), embeddedFormat.getAD_Table_ID()); if (log.isLoggable(Level.INFO)) log.info("Table Embedded = " + tableEmbedded); final StringBuilder whereClause = new StringBuilder(masterPO.get_KeyColumns()[0] +"=?"); if (embeddedFormat.getWhereClause() != null & !"".equals(embeddedFormat.getWhereClause())) { whereClause.append(" AND ").append(embeddedFormat.getWhereClause()); } Collection instances = new Query(masterPO.getCtx(), tableEmbedded.getTableName(), whereClause.toString(), masterPO.get_TrxName()).setClient_ID().setParameters( new Object[] { masterID }).list(); for (PO instance : instances) { Element embeddedElement = outDocument.createElement(formatLine.getValue()); if (formatLine.getDescription() != null && !"".equals(formatLine.getDescription())) { embeddedElement.appendChild(outDocument.createComment(formatLine.getDescription())); } generateExportFormat(embeddedElement, embeddedFormat, instance, instance.get_ID(), variableMap); rootElement.appendChild(embeddedElement); } } else if ( formatLine.getType().equals(X_EXP_FormatLine.TYPE_ReferencedEXPFormat) ) { // process Referenced Export Format int embeddedFormat_ID = formatLine.getEXP_EmbeddedFormat_ID(); //get from cache MEXPFormat embeddedFormat = MEXPFormat.get(masterPO.getCtx(), embeddedFormat_ID, masterPO.get_TrxName()); MTable tableEmbedded = MTable.get(masterPO.getCtx(), embeddedFormat.getAD_Table_ID()); if (log.isLoggable(Level.INFO)) log.info("Table Embedded = " + tableEmbedded); final StringBuilder whereClause = new StringBuilder(tableEmbedded.getTableName() + "_ID =?"); if (embeddedFormat.getWhereClause() != null & !"".equals(embeddedFormat.getWhereClause())) { whereClause.append(" AND ").append(embeddedFormat.getWhereClause()); } String columnName = ""; if(formatLine.getAD_Reference_ID()== DisplayType.Table || formatLine.getAD_Reference_ID()==DisplayType.Search) { MColumn column = MColumn.get(masterPO.getCtx(), formatLine.getAD_Column_ID()); columnName = column.getColumnName(); } else { columnName = tableEmbedded.getTableName() + "_ID"; } Object value = masterPO.get_Value(columnName); if (value == null) { continue; } Collection instances = new Query(masterPO.getCtx(),tableEmbedded.getTableName(), whereClause.toString(),masterPO.get_TrxName()) .setClient_ID() .setParameters(value) .list(); for (PO instance : instances) { Element embeddedElement = outDocument.createElement(formatLine.getValue()); if (formatLine.getDescription() != null && !"".equals(formatLine.getDescription())) { embeddedElement.appendChild(outDocument.createComment(formatLine.getDescription())); } generateExportFormat(embeddedElement, embeddedFormat, instance, instance.get_ID(), variableMap); rootElement.appendChild(embeddedElement); } } else { throw new Exception(Msg.getMsg (masterPO.getCtx(), "EXPUnknownLineType")); } } } /** * @param variableMap * @param variableName */ @SuppressWarnings("unused") private void increaseVariable(HashMap variableMap, String variableName) { if (variableName != null && !"".equals(variableName) ) { Integer var = variableMap.get(variableName); if (var == null) { var = Integer.valueOf(0); } int intValue = var.intValue(); intValue++; variableMap.put(variableName, Integer.valueOf(intValue)); } } /** * Utility method which is responsible to create new XML Document * * @return Document * @throws ParserConfigurationException */ // create new Document Document createNewDocument() throws ParserConfigurationException { Document result = null; DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); result = documentBuilder.newDocument(); return result; } }