Re: Passing EOQualifier to a background thread
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