Ok. Model purports url to be of type String, and its java.net.URL. I hacked around that. Still can't get it to avoid trying to set length and other attributes on update. I'm thinking the workaround approach is to never update a given row (ie file), but to delete/insert the object each time into the ec. Painful, but would work around this bug as I've yet to understand how to block the attempt be EOF to update a read-only record. Just shows the level of my ignorance.
On Thu, May 21, 2009 at 2:07 PM, Joe Little <[email protected]> wrote: > Taking the url class out of the model (no code generation for FSItem > or FSFile), I got a different error: > > [2009-5-21 14:2:4 PDT] <WorkerThread0> > <com.webobjects.appserver._private.WOComponentRequestHandler>: > Exception occurred while handling request: > java.lang.IllegalStateException: cannot update read-only key 'length' > on object:{values = {isAbsolute = true; path = "/tmp/mytest"; canRead > = true; exists = true; parent = "/tmp"; name = "mytest"; length = > 10.0; content = <class com.webobjects.foundation.NSData (offset=0, > length=14, data=[84]'T', [101]'e', [115]'s', [116]'t', [32]' ', > [84]'T', [101]'e', [120]'x', [116]'t', [32]' ', [50]'2', [110]'n', > [100]'d', [10]' > ')>; isHidden = false; canonicalPath = "/private/tmp/mytest"; > absolutePath = "/tmp/mytest"; canWrite = true; lastModified = > 1691991456; }; this = "<your.app.eo.FSFile 7a1686 > _EOVectorKeyGlobalID[FSFile (java.lang.String)/tmp/mytest]>"; } of > entity: FSFile in databaseContext > com.webobjects.eoaccess.eodatabasecont...@e92e10 > [2009-5-21 14:2:4 PDT] <WorkerThread0> > java.lang.IllegalStateException: cannot update read-only key 'length' > on object:{values = {isAbsolute = true; path = "/tmp/mytest"; canRead > = true; exists = true; parent = "/tmp"; name = "mytest"; length = > 10.0; content = <class com.webobjects.foundation.NSData (offset=0, > length=14, data=[84]'T', [101]'e', [115]'s', [116]'t', [32]' ', > [84]'T', [101]'e', [120]'x', [116]'t', [32]' ', [50]'2', [110]'n', > [100]'d', [10]' > ')>; isHidden = false; canonicalPath = "/private/tmp/mytest"; > absolutePath = "/tmp/mytest"; canWrite = true; lastModified = > 1691991456; }; this = "<your.app.eo.FSFile 7a1686 > _EOVectorKeyGlobalID[FSFile (java.lang.String)/tmp/mytest]>"; } of > entity: FSFile in databaseContext > com.webobjects.eoaccess.eodatabasecont...@e92e10 > at > com.webobjects.eoaccess.EODatabaseContext._verifyNoChangesToReadonlyEntity(EODatabaseContext.java:4702) > > The model lists length as read-only. The code doesn't attempt to > update that field. I even overrode FSItem to override all setters to > do nothing except for FSFile's setContent(). A saveChanges() on > updates appear to mark that as a changed field and cause the error by > looking at the model before any action is actually attempted by the > underlying adaptor code. > > I guess the question to the list is where is the ReadOnly flag > evaluated and how can I prevent such attributes which are set by the > file operation from being marked as updated in the EO in the first > place? > > > On Thu, May 21, 2009 at 1:38 PM, Joe Little <[email protected]> wrote: >> So, I'm stuck whenever I make any attempt to update an EO via this >> adaptor. The first creation + add content works, but the second >> attempt upon reading the file does work: >> >> FSFile myFile; >> NSData sampleData = new NSData("Test Text\n"); >> >> EOEditingContext ec = session().defaultEditingContext(); >> myFile = (FSFile) EOUtilities.createAndInsertInstance (ec, >> "FSFile"); >> NSLog.out.appendln("myFile class " + >> myFile.getClass().getName()); >> myFile.takeValueForKey ("/tmp/mytest", "absolutePath"); >> >> >> myFile.setContent(sampleData); >> ec.saveChanges(); >> NSLog.out.appendln("test 1: " + myFile.content().stream()); >> myFile = null; >> >> EOQualifier myQual = new EOKeyValueQualifier ("absolutePath", >> EOQualifier.QualifierOperatorEqual, "/tmp/mytest"); >> EOFetchSpecification myFS = new EOFetchSpecification >> ("FSFile", myQual, null); >> myFS.setRefreshesRefetchedObjects(true); >> NSArray myObjects = ec.objectsWithFetchSpecification(myFS); >> if (myObjects.count() == 0) >> return "No file present called /tmp/mytest"; >> else >> { >> myFile = (FSFile) myObjects.objectAtIndex(0); >> NSLog.out.appendln("myFile class " + >> myFile.getClass().getName()); >> NSLog.out.appendln("test 2: " + >> myFile.content()); >> sampleData = new NSData("Test Text 2nd\n"); >> myFile.setContent(sampleData); >> ec.saveChanges(); >> NSLog.out.appendln("test 3: " + >> myFile.content()); >> return myFile.name(); >> } >> >> >> [2009-5-21 13:25:39 PDT] <WorkerThread0> >> <com.webobjects.appserver._private.WOComponentRequestHandler>: >> Exception occurred while handling request: >> java.lang.ClassCastException: java.net.URL >> [2009-5-21 13:25:39 PDT] <WorkerThread0> java.lang.ClassCastException: >> java.net.URL >> at your.app.eo._FSItem.url(_FSItem.java:175) >> >> That is this code bit: >> >> public String url() { >> return (String) storedValueForKey("url"); >> } >> >> Don't know why it even cares about the URL when its updating content. >> Only reference in code is to the defaultModelPath() which I'm not >> loading. Rather, I'm loading my own model since I needed to override >> the class names to get source generation. >> >> I did another change which was to ignore the initial creation (the >> file already exists) and start with the qualifier/fetchspec and >> update. It still reads in fine but the update fails on saveChanges(). >> >> I think it has something to do with this segment, specifically, the >> attempt to get a value from the key "url" but there is no casting >> going on except trying to return String from what is likely null. url >> is a path component, right? >> >> File aFile = (File) someFiles.objectAtIndex(index); >> NSArray someKeys = aRow.allKeys(); >> int keyCount = someKeys.count(); >> >> for (int keyIndex = 0; keyIndex < >> keyCount; keyIndex++) { >> Object aKey = >> someKeys.objectAtIndex(keyIndex); >> EOAttribute anAttribute = >> anEntity.attributeNamed(aKey.toString()); >> if (anAttribute != null) { >> Object aValue = >> aRow.objectForKey(aKey); >> if >> ("content".equals(anAttribute.columnName())) >> { >> try { >> OutputStream out = >> new FileOutputStream(aPath); >> NSData content = >> (NSData) aValue; >> InputStream in = >> content.stream(); >> >> if (null == out) >> throw new >> RuntimeException("The file '" + aPath + "' can not >> be opened."); >> if (null == in) >> throw new >> RuntimeException("There is no content to write."); >> int length = >> in.available(); >> byte buffer[] = new >> byte[length]; >> in.read(buffer); >> out.write(buffer); >> in.close(); >> out.close(); >> } catch (IOException >> ex) { >> >> System.err.println("dictionaryForFileWithAttributes : (" + >> aFile.getName() + ") " + ex); >> } >> } >> >> >> On Thu, May 21, 2009 at 11:36 AM, Joe Little <[email protected]> wrote: >>> Still not resolved are the issues that Chuck and are are trying to >>> address, but here's the diff that at least gets it to NSData and >>> allows content to be updated/inserted. Other stuff in the takeValueFor >>> is breaking, but nothing else is presently read-write. >>> >>> >>> >>> On Thu, May 21, 2009 at 10:04 AM, Joe Little <[email protected]> wrote: >>>> On Thu, May 21, 2009 at 7:39 AM, Anjo Krank <[email protected]> wrote: >>>>> >>>>> Am 20.05.2009 um 22:23 schrieb Chuck Hill: >>>>> >>>>>>>>> It's been ages (6years+) since I tried to create a simple D2W app from >>>>>>>>> that >>>>>>>>> code, but AFAIR, I had no trouble writing to a file. The only downside >>>>>>>>> then >>>>>>>>> was that you don't have working rollback. >>>>> >>>>> So I may have hacked the thing a bit, way back when. There is special >>>>> treatment for some keys in FSAdaptorChannel: >>>>> >>>>> if ("content".equals(columnName)) { >>>>> try { >>>>> String path = aFile.getAbsolutePath(); >>>>> InputStream in = new FileInputStream(path); >>>>> >>>>> if (null == in) >>>>> throw new RuntimeException("The file '" + >>>>> path + "' can not be opened."); >>>>> int length = in.available(); >>>>> if (length == 0) { >>>>> aValue = ""; >>>>> } >>>>> byte buffer[] = new byte[length]; >>>>> in.read(buffer); >>>>> in.close(); >>>>> aValue = new String(buffer); >>>>> } catch (IOException ex) { >>>>> >>>>> System.err.println("dictionaryForFileWithAttributes : (" + >>>>> aFile.getName() >>>>> + ") " + ex); >>>>> } >>>>> >>>>> >>>>> which should also go to insert and update. Also the "content" should be a >>>>> NSData, not a String. In particular it should be an NSData class that can >>>>> handle streams... even better if you had a set-table file subclass that >>>>> would get used and defaulted to ERXFile. The actual imp is left to the >>>>> reader :) >>>>> >>>>> Cheers, Anjo >>>> >>>> Thanks. I'll start to work on editing the source for this and see what >>>> I come up with that works reliably w/o the EOF quirks I'm >>>> experiencing. >>>> >>>>> _______________________________________________ >>>>> Do not post admin requests to the list. They will be ignored. >>>>> Webobjects-dev mailing list ([email protected]) >>>>> Help/Unsubscribe/Update your Subscription: >>>>> http://lists.apple.com/mailman/options/webobjects-dev/jmlittle%40gmail.com >>>>> >>>>> This email sent to [email protected] >>>>> >>>> >>> >> > _______________________________________________ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list ([email protected]) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to [email protected]
