• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Passing EOQualifier to a background thread
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Passing EOQualifier to a background thread


  • Subject: Re: Passing EOQualifier to a background thread
  • From: Samuel Pelletier via Webobjects-dev <email@hidden>
  • Date: Mon, 11 Nov 2024 06:32:11 -0500

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
> <email@hidden> 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      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

References: 
 >Passing EOQualifier to a background thread (From: Samuel Pelletier via Webobjects-dev <email@hidden>)

  • Prev by Date: Re: WOLips development
  • Next by Date: Re: WOLips development
  • Previous by thread: Passing EOQualifier to a background thread
  • Next by thread: WOLips5
  • Index(es):
    • Date
    • Thread