From be842f4126310745b64c02f683e2f29bc6274c1c Mon Sep 17 00:00:00 2001 From: Pavel Shevchenko Date: Wed, 1 Feb 2023 12:39:12 +0100 Subject: [PATCH 1/2] Fix timezone logging --- Audit trail.mpr | Bin 14733312 -> 14741504 bytes .../audittrail/log/CreateLogObject.java | 88 ++++++++++-------- .../test_crm/tests/TestAuditInheritance.java | 22 ++++- 3 files changed, 68 insertions(+), 42 deletions(-) diff --git a/Audit trail.mpr b/Audit trail.mpr index 7b748e1b9a6a22a1b62696851193a441b4f14b44..fa3bc347b02cdb3ab973d0bf1ab7df4c9167b77e 100644 GIT binary patch delta 2919 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 diff --git a/javasource/audittrail/log/CreateLogObject.java b/javasource/audittrail/log/CreateLogObject.java index 4ef1328..d4716f8 100644 --- a/javasource/audittrail/log/CreateLogObject.java +++ b/javasource/audittrail/log/CreateLogObject.java @@ -11,6 +11,7 @@ import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -83,6 +84,7 @@ public static IMendixObject createAuditLogItems(final IMendixObject auditableObj + auditableObject.getId().toLong() + "), state: " + auditableObject.getState() + "/" + logType); final IContext sudoContext = Core.createSystemContext(); + sudoContext.getSession().setTimeZone(getTimeZone(context)); final IMendixObject logObject = Core.instantiate(sudoContext, Log.getType()); IMendixIdentifier userObjectId = null; @@ -190,6 +192,13 @@ public static IMendixObject createAuditLogItems(final IMendixObject auditableObj } } + private static String getTimeZone(final IContext context) { + final TimeZone tz = context.getSession().getTimeZone(); + if (tz != null) return tz.getID(); + if (Constants.getServerTimeZone() == null || Constants.getServerTimeZone().isEmpty()) return "GMT"; + return Constants.getServerTimeZone(); + } + private static int createLogLines(final IMendixObject inputObject, final IMendixObject logObject, final IContext sudoContext, final IContext currentContext, final TypeOfLog logType, final String skipAssociation) throws CoreException { boolean isNew = false; @@ -248,10 +257,11 @@ else if (member instanceof MendixObjectReferenceSet) private static List createSingleLogLine(final IMendixObject logObject, final IMendixObjectMember member, final String memberType, final boolean isNew, final IContext context) throws CoreException { - final String oldValue = getMemberValueString(member, false, context), newValue = getMemberValueString(member, true, context); + final String oldValue = getMemberValueString(member, false, context); + final String newValue = getMemberValueString(member, true, context); - final boolean newOrChangedObject = !oldValue.equals(newValue) || isNew; - if (!Constants.getIncludeOnlyChangedAttributes() || newOrChangedObject) { + final boolean newOrChangedAttribute = isNew || !oldValue.equals(newValue); + if (newOrChangedAttribute || !Constants.getIncludeOnlyChangedAttributes()) { final IMendixObject logLine = Core.instantiate(context, LogLine.getType()); logLine.setValue(context, LogLine.MemberNames.Member.toString(), member.getName()); @@ -264,7 +274,7 @@ private static List createSingleLogLine(final IMendixObject logOb else logLine.setValue(context, LogLine.MemberNames.OldValue.toString(), oldValue); - if (newOrChangedObject) + if (newOrChangedAttribute) incNumberOfChangedMembers(logObject, context, context, isNew, member.getName()); return Collections.singletonList(logLine); @@ -428,52 +438,48 @@ private static List createReferenceSetLogLine(final IMendixObject } private static String getMemberValueString(final IMendixObjectMember member, final boolean fromCache, final IContext context) { - Object value = null; - - if (fromCache == true) { - // Values from cache - value = member.getValue(context); - } else { - // Values form DB - value = member.getOriginalValue(context); + final Object value = (fromCache) ? member.getValue(context) : member.getOriginalValue(context); + + if (value == null) { + return ""; } - if (value != null) { - if (value instanceof Date) { - return parseDate((Date) value, context); - } else if (value instanceof BigDecimal) { - return String.valueOf(((BigDecimal) value).stripTrailingZeros()).trim(); - } else if (value instanceof String) { - return (String) value; - } else { - return String.valueOf(value).trim(); - } + if (value instanceof Date) { + return parseDate((Date) value, context); } - - return ""; + + if (value instanceof BigDecimal) { + return String.valueOf(((BigDecimal) value).stripTrailingZeros()).trim(); + } + + if (value instanceof String) { + return (String) value; + } + + return String.valueOf(value).trim(); } private static String parseDate(final Date date, final IContext context) { - String dateOutput = ""; - if (date != null) { - final DateFormat dateFormat = new SimpleDateFormat(Constants.getLogLineDateFormat()); - if (Constants.getLogServerTimeZoneDateNotation()) { - final TimeZone zone = TimeZone.getTimeZone(Constants.getServerTimeZone()); - dateFormat.setTimeZone(zone); - dateOutput = dateFormat.format(date) + " (UTC) "; - } + if (date == null) { + return ""; + } - if (Constants.getLogSessionTimeZoneDateNotation() && context.getSession() != null - && context.getSession().getTimeZone() != null) { - if (!"".equals(dateOutput)) - dateOutput += " / "; + List dateFormats = new LinkedList(); - final TimeZone zone = context.getSession().getTimeZone(); - dateFormat.setTimeZone(zone); - dateOutput += dateFormat.format(date) + " (" + zone.getDisplayName() + ") "; - } + if (Constants.getLogServerTimeZoneDateNotation()) { + dateFormats.add(dateInZone(date, TimeZone.getTimeZone(Constants.getServerTimeZone()))); + } + + if (Constants.getLogSessionTimeZoneDateNotation() && context.getSession() != null && context.getSession().getTimeZone() != null) { + dateFormats.add(dateInZone(date, context.getSession().getTimeZone())); } - return dateOutput; + return dateFormats.stream().collect(Collectors.joining(" / ")); + } + + private static String dateInZone(final Date date, final TimeZone zone) { + final DateFormat dateFormat = new SimpleDateFormat(Constants.getLogLineDateFormat()); + dateFormat.setTimeZone(zone); + return dateFormat.format(date) + " (" + zone.getID() + ")"; } } diff --git a/javasource/test_crm/tests/TestAuditInheritance.java b/javasource/test_crm/tests/TestAuditInheritance.java index 22329cd..4d1f91e 100644 --- a/javasource/test_crm/tests/TestAuditInheritance.java +++ b/javasource/test_crm/tests/TestAuditInheritance.java @@ -1,7 +1,10 @@ package test_crm.tests; import java.util.Arrays; +import java.util.Calendar; import java.util.Collections; +import java.util.Date; +import java.util.TimeZone; import com.mendix.core.CoreException; import com.mendix.systemwideinterfaces.core.IMendixObject; @@ -17,6 +20,7 @@ import static test_crm.proxies.Company.MemberNames.CompanyNr; import static test_crm.proxies.Company.MemberNames.Dec; +import static test_crm.proxies.Company.MemberNames.Founded; import static test_crm.proxies.Company.MemberNames.Name; import static test_crm.proxies.Company.MemberNames.Number; import static test_crm.proxies.Company.MemberNames.InternNr; @@ -53,10 +57,14 @@ public void testChangeRecord() throws CoreException { company.setName(NAME2); company.setDec(new java.math.BigDecimal("0.00000000")); // should not be considered changed + company.setFounded(FOUNDED_DATE); company.commit(); // Assert log was created - final ExpectedLog expectedLog = createExpectedLog(TypeOfLog.Change, company).changeAttribute(Name, NAME, NAME2); + final ExpectedLog expectedLog = + createExpectedLog(TypeOfLog.Change, company) + .changeAttribute(Name, NAME, NAME2) + .changeAttribute(Founded, "", "11/04/1991 (UTC)"); final ActualLog actualLog = ActualLog.getLastLog(context, company.getMendixObject().getId().toLong()); @@ -175,17 +183,29 @@ private ExpectedLog createExpectedLog(final TypeOfLog typeOfLog, final Company c .addAttribute(Name, NAME).addAttribute(CompanyNr, COMPANY_NR) .addAttribute(InternNr, company.getInternNr()) .addAttribute(Dec, 0).addAttribute(Number, 0) + .addAttribute(Founded, "") .addReferences(Company_Group, context, MemberType.ReferenceSet, groupObjects); } else { return new ExpectedLog(typeOfLog, Company.entityName, admin, initialDate, Company.entityName) .keepAttribute(Name, NAME).keepAttribute(CompanyNr, COMPANY_NR) .keepAttribute(InternNr, company.getInternNr()) .keepAttribute(Dec, 0).keepAttribute(Number, 0) + .keepAttribute(Founded, "") .keepReferences(Company_Group, context, MemberType.ReferenceSet, groupObjects); } } + private static Date createDate() { + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.YEAR, 1991); + calendar.set(Calendar.MONTH, 10); + calendar.set(Calendar.DATE, 4); + calendar.set(Calendar.HOUR, 2); + return calendar.getTime(); + } + private static final String NAME = "Company"; private static final String NAME2 = "Company2"; private static final String COMPANY_NR = "123"; + private static final Date FOUNDED_DATE = createDate(); } From ef2fb1e7287ab0f1557fbb98f385146481493277 Mon Sep 17 00:00:00 2001 From: Pavel Shevchenko Date: Wed, 1 Feb 2023 13:41:19 +0100 Subject: [PATCH 2/2] Update default values in readme --- Audit trail.mpr | Bin 14741504 -> 14741504 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Audit trail.mpr b/Audit trail.mpr index fa3bc347b02cdb3ab973d0bf1ab7df4c9167b77e..12fae105b4bd49fc3802f5e451c7a12031462743 100644 GIT binary patch delta 923 zcmXAlSyPn-06@R%1@y|QB`t19n;ME3qFI(inNa~50+HZJys4M6(p<0&qm%7vR$qIW zMSIc$SKBPwlak7Is&9Jet?38&P)t3XnKN_VPG{6LvU8a2<70(8CRD`=w<0kaA#ur& zOv#dwGD;FMTCycaawSjlr9j5WSUEzDlyOohN6FE0j2tWDWr9qUNitcAWQr8aadNzz zAScR6GF7I@bU9f{WQNR?Qkf-XGFwiOa+xC)GFRrwsWM+qlhb8^oFQk*LaCIqq)N_~ zb7Ya6D~shksh0EQ0=ZCXq*m(WB3U9AOT8?W25FQgxkQ@fQduS~(kjbk_|IjsLfT}d zB;|5hC97qPq@-Q0kSk@aTqRe_HL_0D%eAsWHp(X1EFH2%u9NHK2Dwpgl1|wwH%ph? zBFe3@O>UFhl9I`zlDP-U!+~Yd^pZvGb2}Q!QjKjJ=FRCy)@^LA zDy`g7mfW1GXxmh=wyiYPn5tf}t~R-{eZiryxFzb%pEx!M3T6c(f*^>O1$p70Ez!Z) z;jphYnxDVF;J+6Czx9Owv_?&_C1KO@XjeuMvz@z0Dyn*yIb44YnfZoD!Hsh>o$#$B^kD+wbo_rNsDGRQC13V<|)^##4iyN zLqueIo7>1;*j$pk-&Y^}2^>3oc+PpwdA>dEQD;W`5M3i7s?DNmy6_LnJJgZrE;0flFOw+X3G^a zN3N8)a+Ord)pCtoD^*f0^Q1;$iX49Sl*N#>6N4$kv@4#-j;XdU3pLX<$d`;j>?Df zk$fzl$fxp|d@f(eG5J!ylCNbz2IU+1R=$((<+%JHC*()@Nq&}JB_*SWt;{)A9u6#xic9L&RIaOOnz6iTersv->P6F=>uSno z*Va$n&|1|trL3i5^1_WP)-Gd7k_9t8Q5f_M-FDWyR{_-8{j5c?B+zPqQdleZdMqZ5Fe2&?n)d;jqOby-<3F+7OPBl?n!J(3lDW9vNCqJ{XJ)M|EBK2 GsOVoVc6+G+