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

Reply via email to