diff --git a/org.adempiere.base/src/org/adempiere/model/MInfoProcess.java b/org.adempiere.base/src/org/adempiere/model/MInfoProcess.java index 18e1d175d1..30a89218e1 100644 --- a/org.adempiere.base/src/org/adempiere/model/MInfoProcess.java +++ b/org.adempiere.base/src/org/adempiere/model/MInfoProcess.java @@ -58,6 +58,16 @@ public class MInfoProcess extends X_AD_InfoProcess implements IInfoColumn { } + /** + * Copy constructor + * @param copy + */ + public MInfoProcess(MInfoProcess copy) { + this(Env.getCtx(), 0, (String)null); + copyPO(copy); + this.m_viewIDName = copy.m_viewIDName; + } + protected String m_viewIDName; /************************************************************************** diff --git a/org.adempiere.base/src/org/adempiere/model/MInfoRelated.java b/org.adempiere.base/src/org/adempiere/model/MInfoRelated.java index 071b5eafc5..149efce5fb 100644 --- a/org.adempiere.base/src/org/adempiere/model/MInfoRelated.java +++ b/org.adempiere.base/src/org/adempiere/model/MInfoRelated.java @@ -20,6 +20,7 @@ import java.util.logging.Level; import org.compiere.model.MInfoColumn; import org.compiere.model.Query; import org.compiere.model.X_AD_InfoRelated; +import org.compiere.util.Env; public class MInfoRelated extends X_AD_InfoRelated implements IInfoColumn { /** @@ -35,6 +36,15 @@ public class MInfoRelated extends X_AD_InfoRelated implements IInfoColumn { super(ctx, rs, trxName); } + /** + * Copy constructor + * @param copy + */ + public MInfoRelated(MInfoRelated copy) { + this(Env.getCtx(), 0, (String)null); + copyPO(copy); + } + public MInfoColumn getLinkInfoColumn() { if (log.isLoggable(Level.INFO)) log.info("Link Column ID: ----- : " + getRelatedColumn_ID()); diff --git a/org.adempiere.base/src/org/compiere/model/MAttachment.java b/org.adempiere.base/src/org/compiere/model/MAttachment.java index 05d7c5f708..ace7e5b395 100644 --- a/org.adempiere.base/src/org/compiere/model/MAttachment.java +++ b/org.adempiere.base/src/org/compiere/model/MAttachment.java @@ -27,6 +27,7 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.Properties; import java.util.logging.Level; +import java.util.stream.Collectors; import org.adempiere.exceptions.AdempiereException; import org.apache.tools.ant.Project; @@ -136,6 +137,17 @@ public class MAttachment extends X_AD_Attachment initAttachmentStoreDetails(ctx, trxName); } // MAttachment + /** + * Copy constructor + * @param copy + */ + public MAttachment(MAttachment copy) + { + this(Env.getCtx(), 0, (String)null); + copyPO(copy); + this.m_items = copy.m_items != null ? copy.m_items.stream().map(MAttachmentEntry::new).collect(Collectors.toCollection(ArrayList::new)) : null; + } + /** Indicator for no data */ public static final String NONE = "."; /** Indicator for zip data */ diff --git a/org.adempiere.base/src/org/compiere/model/MAttachmentEntry.java b/org.adempiere.base/src/org/compiere/model/MAttachmentEntry.java index 1f8d62d56f..faf01dd641 100644 --- a/org.adempiere.base/src/org/compiere/model/MAttachmentEntry.java +++ b/org.adempiere.base/src/org/compiere/model/MAttachmentEntry.java @@ -21,6 +21,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; import java.util.Random; import java.util.logging.Level; @@ -71,6 +72,17 @@ public class MAttachmentEntry this (name, data, 0); } // MAttachmentItem + /** + * Copy constructor + * @param copy + */ + public MAttachmentEntry(MAttachmentEntry copy) + { + this.m_data = copy.m_data != null ? Arrays.copyOf(copy.m_data, copy.m_data.length) : null; + this.m_index = copy.m_index; + this.m_name = copy.m_name; + } + /** The Name */ private String m_name = "?"; /** The Data */ diff --git a/org.adempiere.base/src/org/compiere/model/MInfoColumn.java b/org.adempiere.base/src/org/compiere/model/MInfoColumn.java index 68ea9b77cc..b49514eaba 100644 --- a/org.adempiere.base/src/org/compiere/model/MInfoColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MInfoColumn.java @@ -72,6 +72,16 @@ public class MInfoColumn extends X_AD_InfoColumn implements IInfoColumn this.setEntityType(targetInfoWindow.getEntityType()); } + /** + * copy constructor + * @param copy + */ + public MInfoColumn(MInfoColumn copy) { + this(Env.getCtx(), 0, (String)null); + copyPO(copy); + this.m_parent = copy.m_parent != null ? new MInfoWindow(copy.m_parent) : null; + } + /** Parent */ private MInfoWindow m_parent = null; @@ -219,17 +229,4 @@ public class MInfoColumn extends X_AD_InfoColumn implements IInfoColumn else return MValRule.get(getCtx(), getAD_Val_Rule_ID()); } - - @Override - protected MInfoColumn clone() { - try { - MInfoColumn ic = (MInfoColumn) super.clone(); - ic.m_parent = null; - return ic; - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } - - } // MInfoColumn diff --git a/org.adempiere.base/src/org/compiere/model/MInfoWindow.java b/org.adempiere.base/src/org/compiere/model/MInfoWindow.java index 7eca0cd6cf..985bd097b8 100644 --- a/org.adempiere.base/src/org/compiere/model/MInfoWindow.java +++ b/org.adempiere.base/src/org/compiere/model/MInfoWindow.java @@ -20,6 +20,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Properties; @@ -68,6 +69,20 @@ public class MInfoWindow extends X_AD_InfoWindow super (ctx, rs, trxName); } // MInfoWindow + /** + * Copy constructor + * @param copy + */ + public MInfoWindow(MInfoWindow copy) + { + this(Env.getCtx(), 0, (String)null); + copyPO(copy); + this.m_validateEachColumn = copy.m_validateEachColumn; + this.m_infocolumns = copy.m_infocolumns != null ? Arrays.stream(copy.m_infocolumns).map(MInfoColumn::new).toArray(MInfoColumn[]::new) : null; + this.m_infoProcess = copy.m_infoProcess != null ? Arrays.stream(copy.m_infoProcess).map(MInfoProcess::new).toArray(MInfoProcess[]::new) : null; + this.m_infoRelated = copy.m_infoRelated != null ? Arrays.stream(copy.m_infoRelated).map(MInfoRelated::new).toArray(MInfoRelated[]::new) : null; + } + public static MInfoWindow get(String tableName, String trxName) { Query query = new Query(Env.getCtx(), MTable.get(Env.getCtx(), MInfoWindow.Table_ID), MInfoWindow.COLUMNNAME_AD_Table_ID+"=? AND IsValid='Y' ", null); MTable table = MTable.get(Env.getCtx(), tableName); diff --git a/org.adempiere.base/src/org/compiere/model/PO.java b/org.adempiere.base/src/org/compiere/model/PO.java index 7d5ee0fe06..51c62db597 100644 --- a/org.adempiere.base/src/org/compiere/model/PO.java +++ b/org.adempiere.base/src/org/compiere/model/PO.java @@ -30,6 +30,7 @@ import java.sql.Savepoint; import java.sql.Timestamp; import java.text.Collator; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; @@ -37,6 +38,7 @@ import java.util.List; import java.util.Properties; import java.util.UUID; import java.util.logging.Level; +import java.util.stream.Collectors; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; @@ -225,7 +227,24 @@ public abstract class PO setAD_Org_ID(AD_Org_ID); } // PO - + /** + * Copy all properties from copy. Method to help the implementation of copy constructor. + * @param copy + */ + protected void copyPO(PO copy) + { + this.m_attachment = copy.m_attachment != null ? new MAttachment(copy.m_attachment) : null; + this.m_attributes = copy.m_attributes != null ? new HashMap(copy.m_attributes) : null; + this.m_createNew = copy.m_createNew; + this.m_custom = copy.m_custom != null ? new HashMap(copy.m_custom) : null; + this.m_IDs = copy.m_IDs != null ? Arrays.copyOf(copy.m_IDs, copy.m_IDs.length) : null; + this.m_KeyColumns = copy.m_KeyColumns != null ? Arrays.copyOf(copy.m_KeyColumns, copy.m_KeyColumns.length) : null; + this.m_lobInfo = copy.m_lobInfo != null ? copy.m_lobInfo.stream().map(PO_LOB::new).collect(Collectors.toCollection(ArrayList::new)) : null; + this.m_newValues = copy.m_newValues != null ? Arrays.copyOf(copy.m_newValues, copy.m_newValues.length) : null; + this.m_oldValues = copy.m_oldValues != null ? Arrays.copyOf(copy.m_oldValues, copy.m_oldValues.length) : null; + this.s_acctColumns = copy.s_acctColumns != null ? copy.s_acctColumns.stream().collect(Collectors.toCollection(ArrayList::new)) : null; + } + /** Logger */ protected transient CLogger log = CLogger.getCLogger (getClass()); /** Static Logger */ @@ -4776,6 +4795,7 @@ public abstract class PO } @Override + @Deprecated protected Object clone() throws CloneNotSupportedException { PO clone = (PO) super.clone(); clone.m_trxName = null; diff --git a/org.adempiere.base/src/org/compiere/model/PO_LOB.java b/org.adempiere.base/src/org/compiere/model/PO_LOB.java index 2802633666..a42085939d 100644 --- a/org.adempiere.base/src/org/compiere/model/PO_LOB.java +++ b/org.adempiere.base/src/org/compiere/model/PO_LOB.java @@ -60,6 +60,19 @@ public class PO_LOB implements Serializable m_value = value; } // PO_LOB + /** + * Copy constructor + * @param copy + */ + public PO_LOB (PO_LOB copy) + { + this.m_columnName = copy.m_columnName; + this.m_displayType = copy.m_displayType; + this.m_tableName = copy.m_tableName; + this.m_value = copy.m_value; + this.m_whereClause = copy.m_whereClause; + } + /** Logger */ protected CLogger log = CLogger.getCLogger (getClass()); /** Table Name */ diff --git a/org.adempiere.base/src/org/compiere/print/MPrintFormat.java b/org.adempiere.base/src/org/compiere/print/MPrintFormat.java index fe01286bc0..5aa03d88d3 100644 --- a/org.adempiere.base/src/org/compiere/print/MPrintFormat.java +++ b/org.adempiere.base/src/org/compiere/print/MPrintFormat.java @@ -101,6 +101,20 @@ public class MPrintFormat extends X_AD_PrintFormat m_items = getItems(); } // MPrintFormat + /** + * Copy constructor + * @param copy + */ + public MPrintFormat(MPrintFormat copy) + { + this(Env.getCtx(), 0, (String)null); + copyPO(copy); + this.m_translationViewLanguage = copy.m_translationViewLanguage; + this.m_items = copy.m_items != null ? Arrays.stream(copy.m_items).map(MPrintFormatItem::new).toArray(MPrintFormatItem[]::new) : null; + this.m_language = copy.m_language != null ? new Language(copy.m_language) : null; + this.m_tFormat = copy.m_tFormat != null ? new MPrintTableFormat(copy.m_tFormat) : null; + } + /** Items */ private MPrintFormatItem[] m_items = null; /** Translation View Language */ @@ -1116,11 +1130,7 @@ public class MPrintFormat extends X_AD_PrintFormat if (pf != null) { - try { - pf = pf.clone(); - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e); - } + pf = new MPrintFormat(pf); } return pf; } // get @@ -1254,6 +1264,7 @@ public class MPrintFormat extends X_AD_PrintFormat } @Override + @Deprecated public MPrintFormat clone() throws CloneNotSupportedException { MPrintFormat clone = (MPrintFormat) super.clone(); clone.m_items = m_items == null ? null : new MPrintFormatItem[m_items.length]; diff --git a/org.adempiere.base/src/org/compiere/print/MPrintFormatItem.java b/org.adempiere.base/src/org/compiere/print/MPrintFormatItem.java index afd5c7b583..20a291a570 100644 --- a/org.adempiere.base/src/org/compiere/print/MPrintFormatItem.java +++ b/org.adempiere.base/src/org/compiere/print/MPrintFormatItem.java @@ -111,6 +111,21 @@ public class MPrintFormatItem extends X_AD_PrintFormatItem super(ctx, rs, trxName); } // MPrintFormatItem + /** + * Copy constructor + * @param copy + */ + public MPrintFormatItem(MPrintFormatItem copy) + { + this(Env.getCtx(), 0, (String)null); + copyPO(copy); + this.m_columnName = copy.m_columnName; + this.m_newTranslationLabel = copy.m_newTranslationLabel; + this.m_translationLabelChanged = copy.m_translationLabelChanged; + this.m_translationLabel = copy.m_translationLabel != null ? new HashMap(copy.m_translationLabel) : null; + this.m_translationSuffix = copy.m_translationSuffix != null ? new HashMap(copy.m_translationSuffix) : null; + } + /** Locally cached column name */ private String m_columnName = null; /** Locally cached label translations */ diff --git a/org.adempiere.base/src/org/compiere/print/MPrintTableFormat.java b/org.adempiere.base/src/org/compiere/print/MPrintTableFormat.java index 50afc0c615..f7dcc79471 100644 --- a/org.adempiere.base/src/org/compiere/print/MPrintTableFormat.java +++ b/org.adempiere.base/src/org/compiere/print/MPrintTableFormat.java @@ -86,6 +86,39 @@ public class MPrintTableFormat extends X_AD_PrintTableFormat super(ctx, rs, trxName); } // MPrintTableFormat + /** + * Copy constructor + * @param copy + */ + public MPrintTableFormat(MPrintTableFormat copy) + { + this(Env.getCtx(), 0, (String)null); + copyPO(copy); + this.standard_Font = copy.standard_Font; + this.funct_Font = copy.funct_Font; + this.functBG_Color = copy.functBG_Color; + this.functFG_Color = copy.functFG_Color; + this.hdrLine_Color = copy.hdrLine_Color; + this.header_Font = copy.header_Font; + this.header_Stroke = copy.header_Stroke; + this.headerBG_Color = copy.headerBG_Color; + this.headerFG_Color = copy.headerFG_Color; + this.lineH_Color = copy.lineH_Color; + this.lineH_Stroke = copy.lineH_Stroke; + this.lineV_Color = copy.lineV_Color; + this.lineV_Stroke = copy.lineV_Stroke; + this.m_image = copy.m_image; + this.m_image_water_mark = copy.m_image_water_mark; + this.pageFooter_Font = copy.pageFooter_Font; + this.pageFooterBG_Color = copy.pageFooterBG_Color; + this.pageFooterFG_Color = copy.pageFooterFG_Color; + this.pageHeader_Font = copy.pageHeader_Font; + this.pageHeaderBG_Color = copy.pageHeaderBG_Color; + this.pageHeaderFG_Color = copy.pageHeaderFG_Color; + this.parameter_Color = copy.parameter_Color; + this.parameter_Font = copy.parameter_Font; + } + /*************************************************************************/ private Font standard_Font = new Font(null); diff --git a/org.adempiere.base/src/org/compiere/process/DocActionTemplate.java b/org.adempiere.base/src/org/compiere/process/DocActionTemplate.java index d5053e8ace..6e6fb75fbc 100644 --- a/org.adempiere.base/src/org/compiere/process/DocActionTemplate.java +++ b/org.adempiere.base/src/org/compiere/process/DocActionTemplate.java @@ -46,7 +46,7 @@ public class DocActionTemplate extends PO implements DocAction */ private DocActionTemplate() { - super(null); + super((Properties)null); } // DocActionTemplate /** * Init PO diff --git a/org.adempiere.base/src/org/compiere/util/Language.java b/org.adempiere.base/src/org/compiere/util/Language.java index 5907e0b1f7..184e9929da 100644 --- a/org.adempiere.base/src/org/compiere/util/Language.java +++ b/org.adempiere.base/src/org/compiere/util/Language.java @@ -357,6 +357,22 @@ public class Language implements Serializable this (name, AD_Language, locale, null, null, null); } // Language + /** + * Copy constructor + * @param copy + */ + public Language(Language copy) + { + this.m_AD_Language = copy.m_AD_Language; + this.m_dateFormat = copy.m_dateFormat; + this.m_dbDateFormat = copy.m_dbDateFormat; + this.m_decimalPoint = copy.m_decimalPoint; + this.m_fromDB = copy.m_fromDB; + this.m_leftToRight = copy.m_leftToRight; + this.m_locale = copy.m_locale; + this.m_mediaSize = copy.m_mediaSize; + this.m_name = copy.m_name; + } /** Name */ private String m_name; diff --git a/org.idempiere.test/src/org/idempiere/test/model/MPrintFormatTest.java b/org.idempiere.test/src/org/idempiere/test/model/MPrintFormatTest.java new file mode 100644 index 0000000000..52c6f568d3 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/model/MPrintFormatTest.java @@ -0,0 +1,67 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * 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: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.compiere.print.MPrintFormat; +import org.compiere.util.Env; +import org.idempiere.test.AbstractTestCase; +import org.junit.jupiter.api.Test; + +/** + * @author hengsin + * + */ +public class MPrintFormatTest extends AbstractTestCase { + + @Test + public void testCopyConstructor() { + int orderHeader = 118; + + MPrintFormat pf = new MPrintFormat(Env.getCtx(), orderHeader, getTrxName()); + MPrintFormat copy = new MPrintFormat(pf); + assertFalse(copy.is_new()); + assertFalse(copy.is_Changed()); + assertNull(copy.get_TrxName()); + assertTrue(copy.get_ID() == pf.get_ID()); + assertTrue(pf.equals(copy)); + int count = pf.get_ColumnCount(); + for(int i = 0; i < count; i++) + assertEquals(pf.get_Value(i), copy.get_Value(i)); + + copy.set_TrxName(getTrxName()); + String copyDescription = copy.getDescription() + " copy"; + copy.setDescription(copyDescription); + assertTrue(copy.is_Changed()); + copy.saveEx(); + + pf.load(getTrxName()); + assertEquals(copyDescription, pf.getDescription()); + } +}