implementation module htmlRefFormlib // Reference types that allow destructive sharing of model data types. // These can be guarded by consistency checking functions. // In addition, it handles version management of the shared data. // (c) MJP 2006 import StdList, StdString import htmlExceptions, htmlFormlib :: Ref2 a = Ref2 String instance == (Ref2 a) where (==) (Ref2 file1) (Ref2 file2) = file1 == file2 invokeRefEditor :: !((InIDataId b) *HSt -> (Form d,*HSt)) !(InIDataId b) !*HSt -> (!Form b,!*HSt) invokeRefEditor editor (init,formid) hst # (idata,hst) = editor (init,formid) hst = ({idata & value = formid.ival},hst) // iData for destructively shared model data: universalRefEditor :: !Lifespan !(InIDataId (Ref2 a)) !(a -> Judgement) !*HSt -> (!Form a,!*HSt) | iData a universalRefEditor lifespan (init,formid=:{ival=Ref2 filename}) invariant hst | filename == "" = mkEditForm (Init,xtFormId "ure_TEMP" createDefault) hst # (dbf,hst) = myDatabase Init filename (0,createDefault) hst // create / read out current value in file file # (dbversion,dbvalue) = dbf.value // version number and value stored in database # (versionf,hst) = myVersion Init filename dbversion hst // create / read out version number expected by this application # version = versionf.value // current version number assumed in this application | init == Init && isMember formid.mode [Display,NoForm] // we only want to read, no version conflict = myEditor Init filename dbvalue hst // synchronize with latest value | dbversion > version // we have a version conflict and want to write # (_,hst) = ExceptionStore ((+) (Just (filename, "Ref Your screen data is out of date; I have retrieved the latest data."))) hst // Raise exception # (_,hst) = myVersion Set filename dbversion hst // synchronize with new version = myEditor Set filename dbvalue hst // return current version stored in database # (valuef,hst) = myEditor Init filename dbvalue hst // editor is in sync; create / read out current value # exception = invariant valuef.value // check invariants // check invariants | isJust exception // we want to write, but invariants don't hold # (_,hst) = ExceptionStore ((+) exception) hst // report them = (valuef,hst) // return wrong value such that it can be improved # (versionf,hst) = myVersion Set filename (dbversion + 1) hst // increment version number # (_,hst) = myDatabase Set filename (dbversion + 1,valuef.value) hst // update database file = ({valuef & changed = True},hst) where myDatabase init filename cntvalue hst // write the database = mkEditForm (init, if (lifespan == TxtFile) xpFormId xdbFormId filename cntvalue) hst myVersion init filename cnt hst // track version number = mkEditForm (init,reuseFormId formid cnt <@ ("vrs_r_" +++ filename) <@ NoForm) hst myEditor init filename value hst // copy of database information = mkShowHideForm (init,reuseFormId formid value <@ "copy_r_" +++ filename) hst