Hi all, If the problem is the EO references in the qualifier then you may try converting the EOQualifier to a schema based qualifier. The EOEntity has a schemaBasedQualifier() method to hay converts EO references to key-value qualifier using the foreign keys.
Regards, Ricardo Sent from my iPhone > On Nov 11, 2024, at 6:32 AM, Samuel Pelletier via Webobjects-dev > <webobjects-dev@lists.apple.com> wrote: > Hi, > > I found a bug in the NSArray handling in the encoder, here is my class with a > fix, do not use the previous version. > > Samuel > > >> Le 9 nov. 2024 à 10:11, Samuel Pelletier via Webobjects-dev >> <webobjects-dev@lists.apple.com> a écrit : >> >> Hi, >> >> Last week I encountered a problem very similar to a previous OC case... I >> have a report page with some user defined filter that use EOs and do the >> fetch in background. Creating a snapshot of all possible parameter seems a >> fragile solution since it required a very good discipline to make sure the >> problem does not coma back... Having a way to archive or serialize an >> EOQualifier with no exigent context dependency seems a bette solution. >> >> After some digging in Wonder sources and list archive, I found >> EOKeyValueArchiving but never found a complete working code using EOs. It >> seems there is no basic implementation of delegate and support classes in >> WOnder or elsewhere to make this works. I wrote those classes that convert >> any EO to EOGlobalID on archiving and EOGlobalID back to EO using the >> specified EditingContext when unarchiving. >> >> Here si the recipe and my utility classe source for anyone that may need it. >> I can prepare a pull request to add it to Wonder if others can confirm there >> is nothing already in place that do that. >> >> Regards >> >> Samuel >> >> >> public class RapportRendementMatiere extends BaseRapportComponent { >> ... >> private KAKeyValueArchive filtersArchive = new KAKeyValueArchive(); >> >> public actionStartingTheFetch() { >> // build the qualifier array qualifiers in the request using Eos and >> archive it. >> filtersArchive.archiveObject(new ERXAndQualifier(qualifiers), >> "qualifier"); >> // Add some other values that may require access to session or other >> EOs >> filtersArchive.archiveObject(dateDebutToFind(), "dateDebut"); >> filtersArchive.archiveObject(rapportMachines(), "rapportMachines"); >> >> // Start background thread (could use ERX tasks or any other means here... >> new Thread(new Runnable() { >> @Override >> public void run() { >> ERXApplication._startRequest(); >> try { >> EOEditingContext ec = ERXEC.newEditingContext(); >> fetchRapport(ec); >> etat = Etat.Affiche; >> } finally { >> ERXApplication._endRequest(); >> } >> } >> }).start(); >> } >> >> public void fetchRapport(EOEditingContext ec) { >> // In background thread... >> filtersArchive.setEditingContext(ec); >> EOQualifier qualifier = filtersArchive.unarchiveObject("qualifier"); >> if (qualifier != null) { >> // use the qualifier >> } >> >> // get the date that was in session >> LocalDate dateDebut = filtersArchive.unarchiveObject("dateDebut"); >> >> // get array of EOs >> NSArray<Machine> rapportMachines = >> filtersArchive.unarchiveObject("rapportMachines"); >> ... >> } >> } >> >> >> >> >> Utility class source > > package com.kaviju.commons.model; > > import com.webobjects.eocontrol.EOEditingContext; > import com.webobjects.eocontrol.EOGenericRecord; > import com.webobjects.eocontrol.EOGlobalID; > import com.webobjects.eocontrol.EOKeyValueArchiver; > import com.webobjects.eocontrol.EOKeyValueArchiving; > import com.webobjects.eocontrol.EOKeyValueUnarchiver; > import com.webobjects.foundation.NSArray; > import com.webobjects.foundation.NSKeyValueCoding; > import com.webobjects.foundation.NSMutableArray; > > import er.extensions.foundation.ERXValueUtilities; > > public class KAKeyValueArchive { > static { > EOKeyValueArchiving.Support.setSupportForClass(new > KAKeyValueArchiverEoSupport(), EOGenericRecord.class); > } > > private KAKeyValueArchiver archiver; > > public KAKeyValueArchive() { > archiver = new KAKeyValueArchiver(); > archiver.setDelegate(new ArchiverDelegate()); > } > > public void archiveObject(Object object, String key) { > object = object != null ? object : NSKeyValueCoding.NullValue; > archiver.encodeObject(object, key); > } > > public KAKeyValueUnarchiver unarchiverWithEditingContext(EOEditingContext > ec) { > return new KAKeyValueUnarchiver(this, ec); > } > > // EOKeyValueArchiver n'encode pas les NSArray correctement... > public static class KAKeyValueArchiver extends EOKeyValueArchiver { > @SuppressWarnings({ "unchecked", "rawtypes" }) > @Override > protected void _encodeArrayForKey(NSArray objects, String key) { > int count = objects.count(); > if (count > 0) { > NSMutableArray<Object> array = new NSMutableArray<>(count); > for (int i = 0; i < count; i++) { > KAKeyValueArchiver nestedCoder = new KAKeyValueArchiver(); > nestedCoder.setDelegate(delegate()); > > Object object = objects.objectAtIndex(i); > nestedCoder.encodeObject(object, "dictionary"); > > array.addObject(nestedCoder.dictionary().objectForKey("dictionary")); > } > this._propertyList.setObjectForKey(array, key); > } else { > this._propertyList.setObjectForKey(objects, key); > } > } > } > > public static class KAKeyValueUnarchiver { > private KAKeyValueArchive archive; > private EOKeyValueUnarchiver unarchiver; > > public KAKeyValueUnarchiver(KAKeyValueArchive archive) { > this.archive = archive; > } > > public KAKeyValueUnarchiver(KAKeyValueArchive archive, > EOEditingContext ec) { > this.archive = archive; > setEditingContext(ec); > } > > public void setEditingContext(EOEditingContext ec) { > unarchiver = new > EOKeyValueUnarchiver(archive.archiver.dictionary()); > unarchiver.setDelegate(new UnarchiverDelegate(ec)); > } > > @SuppressWarnings({ "unchecked" }) > public <T extends Object> T unarchiveObject(String key) { > Object value = unarchiver.decodeObjectForKey(key); > if (ERXValueUtilities.isNull(value)) { > return null; > } > return (T)value; > } > } > > public static class KAKeyValueArchiverEoSupport extends > EOKeyValueArchiving.Support { > > @Override > public void encodeWithKeyValueArchiver(Object paramObject, > EOKeyValueArchiver param1eoKeyValueArchiver) { > param1eoKeyValueArchiver.encodeReferenceToObject(paramObject, > "eo"); > } > > @Override > public Object decodeObjectWithKeyValueUnarchiver(EOKeyValueUnarchiver > param1eoKeyValueUnarchiver) { > return > param1eoKeyValueUnarchiver.decodeObjectReferenceForKey("eo"); > } > } > > public static class ArchiverDelegate implements > EOKeyValueArchiver.Delegate { > > @Override > public Object referenceToEncodeForObject(EOKeyValueArchiver > paramEOKeyValueArchiver, Object paramObject) { > if (paramObject instanceof EOGenericRecord) { > return ((EOGenericRecord)paramObject).__globalID(); > } > return paramObject; > } > } > > public static class UnarchiverDelegate implements > EOKeyValueUnarchiver.Delegate { > private final EOEditingContext ec; > > public UnarchiverDelegate(EOEditingContext ec) { > this.ec = ec; > } > > @Override > public Object unarchiverObjectForReference(EOKeyValueUnarchiver > param1eoKeyValueUnarchiver, Object paramObject) { > if (paramObject instanceof EOGlobalID) { > return ec.faultForGlobalID((EOGlobalID) paramObject, ec); > } > return paramObject; > } > } > } > > _______________________________________________ > Do not post admin requests to the list. They will be ignored. > Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/webobjects-dev/rparada%40mac.com > > This email sent to rpar...@mac.com _______________________________________________ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com