Return-Path: Delivered-To: apmail-xml-cocoon-dev-archive@xml.apache.org Received: (qmail 72434 invoked by uid 500); 8 Dec 2002 04:52:05 -0000 Mailing-List: contact cocoon-dev-help@xml.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: list-post: Reply-To: cocoon-dev@xml.apache.org Delivered-To: mailing list cocoon-dev@xml.apache.org Received: (qmail 72422 invoked from network); 8 Dec 2002 04:52:05 -0000 Date: Sat, 7 Dec 2002 20:52:18 -0800 Subject: Re: [Proposal] Implementing XMLForm with Flow Content-Type: text/plain; delsp=yes; charset=US-ASCII; format=flowed Mime-Version: 1.0 (Apple Message framework v548) From: Ovidiu Predescu To: cocoon-dev@xml.apache.org Content-Transfer-Encoding: 7bit In-Reply-To: <3DF16740.4020700@verizon.net> Message-Id: X-Mailer: Apple Mail (2.548) X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N Brilliant example Chris, I love it!! This shows exactly what can be built with continuations and tail-recursive functions. On Friday, Dec 6, 2002, at 19:13 US/Pacific, Christopher Oliver wrote: > Um, I think Daniel basically answered this question a long time ago: > http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=102052662705449&w=2. > > Sorry, I don't have an actual implementation, but I think it's clear > that the corresponding flow code would be much more readable than the > action code in the XML form howto (namely something like below). That > is the whole point of the flow layer - that you don't have to write > state-machine code as in XMLForm actions. Compare the flow version to > the original XMLForm action code reproduced below, and judge for > yourself. > > // display form, wait for submission, and > // apply validations; repeat until no violations > function sendView(form, view, uri) { > form.clearViolations(); > if (uri == undefined) { > uri = view + ".xml"; > } > sendPageAndWait(uri, {id: view}); > form.populate(cocoon.request); > if (form.violations != null) { > sendView(form, view, uri); > } > } The recursive call to sendView here is what is called a tail-recursive call. This type of calls are optimized by Christopher's modified engine to avoid eating stack space, a common technique in functional languages. They behave as a simple goto to the beginning of the function. > function createForm() { > // create the Form object > // ... > } > > function howToWizard() { > // different form views > // participating in the wizard > var VIEW_START = "start"; > var VIEW_REGISTRATION = "registration"; > var VIEW_INTEREST = "interest"; > var VIEW_GARDENING = "organicGardening"; > var VIEW_COOKING = "cooking"; > var VIEW_SMALLHOLDING = "smallholdingManagement"; > var VIEW_CONFIRM = "confirm"; > var VIEW_END = "end"; > > var form = createForm(); > var jBean = form.getModel(); > sendView(form, VIEW_START); > sendView(form, VIEW_REGISTRATION); > sendView(form, VIEW_INTEREST); > if (jBean.organicGardening) { > sendView(form, VIEW_GARDENING); > } else if (jBean.cooking) { > sendView(form, VIEW_COOKING); > } else if (jBean.smallholdingManagement) { > sendView(form, VIEW_SMALLHOLDING); > } > sendView(form, VIEW_CONFIRM); > sendView(form, VIEW_END); > } Which shows exactly why continuations provide such a simple way of programming complex applications! Best regards, Ovidiu > ------------------------------------------------------------ > > From HowToWizardAction.java: > > .... > > // apply control flow rules > if ( formView.equals ( VIEW_REGISTRATION ) ) > { > if ( command.equals( CMD_NEXT ) ) > { > return page( VIEW_INTEREST ); > } } > else if ( formView.equals ( VIEW_INTEREST ) ) > { > if ( command.equals( CMD_NEXT ) ) > { > if ( jBean.getOrganicGardening() == true ) > { > return page( VIEW_GARDENING ); > } > else if ( jBean.getCooking() == true ) > { > return page( VIEW_COOKING ); > } > else if ( jBean.getSmallholdingManagement() == true ) > { > return page( VIEW_SMALLHOLDING ); > } > //else if ( getForm().get > return page( VIEW_CONFIRM ); > } > if ( command.equals( CMD_PREV ) ) > { > return page( VIEW_REGISTRATION ); > } > } > else if ( formView.equals ( VIEW_GARDENING ) ) > { > if ( command.equals ( CMD_NEXT ) ) > { > if ( jBean.getCooking() == true ) > { > return page( VIEW_COOKING ); > } > else if ( jBean.getSmallholdingManagement() == true ) > { > return page( VIEW_SMALLHOLDING ); > } return page( VIEW_CONFIRM ); > } > else if( command.equals( CMD_PREV ) ) > { > return page( VIEW_INTEREST ); > } > } > else if ( formView.equals ( VIEW_COOKING ) ) > { > if ( command.equals ( CMD_NEXT ) ) > { > if ( jBean.getSmallholdingManagement() == true ) > { > return page( VIEW_SMALLHOLDING ); > } return page( VIEW_CONFIRM ); > } > else if ( command.equals( CMD_PREV ) ) > { if ( jBean.getOrganicGardening() == true ) > { > return page( VIEW_GARDENING ); > } > return page( VIEW_INTEREST ); > } > } > else if ( formView.equals ( VIEW_SMALLHOLDING ) ) > { > if ( command.equals( CMD_NEXT ) ) > { > return page( VIEW_CONFIRM ); > } > else if ( command.equals( CMD_PREV ) ) > { > if ( jBean.getCooking() == true ) > { > return page( VIEW_COOKING ); > } > else if ( jBean.getOrganicGardening() == true ) > { > return page( VIEW_GARDENING ); > } > return page( VIEW_INTEREST ); > } > } > else if ( formView.equals ( VIEW_CONFIRM ) ) > { > if ( command.equals( CMD_NEXT ) ) > { > return page( VIEW_END ); > } > else if( command.equals( CMD_PREV ) ) > { > if ( jBean.getOrganicGardening() == true ) > { > return page( VIEW_GARDENING ); > } return page( VIEW_INTEREST ); > } > } > } > > Ivelin Ivanov wrote: > >> Sorry I wasn't clear before. >> I know you can call Java from the flow. >> The question is how to use the flow in a way which significantly >> reduces >> code >> while making the maintenance easier and improving the readability. >> >> Try to beat the existing XMLForm wizard demo. >> If you succeed, it will be great ! >> >> Fingers crossed, >> >> Ivelin >> >> >> ----- Original Message ----- >> From: "Ugo Cei" >> To: >> Sent: Thursday, December 05, 2002 2:36 AM >> Subject: Re: [Proposal] Implementing XMLForm with Flow >> >> >> >>> Ivelin Ivanov wrote: >>> >>>> I hope you are the last hero trying to confront this monster. >>>> >>>> The discussion how to combine the two has been going on forever, >>>> but we >>>> >> have >> >>>> not come to an agreement. >>>> >>> I'm currently recovering the previous threads from the archive and >>> reading them. >>> >>> >>>> I would gladly offer my tactical guidance for your effort. >>>> >>> Thank you. >>> >>> >>>> If I was to do this with Actions, I could use well known and >>>> >> standardized >> >>>> Java APIs - JWSP or JDBC. >>>> >>> But, as Ovidiu pointed out, you can! >>> >>> var schemaFactory = >>> >>> Packages.org.apache.cocoon.components.validation.SchemaFactory.lookup >>> ("http://www.ascc.net/xml/schematron"); >>> var is = new Packages.org.xml.sax.InputSource >>> ("flows/newuser-schema.xml"); >>> var schema = schemaFactory.compileSchema(is); >>> var validator = schema.newValidator(); >>> validator.setProperty("http://xml.apache.org/cocoon/validator/phase", >>> "NewUser"); >>> violations = validator.validate(userBean); >>> >>> This is just a quick hack I put together looking at the code for the >>> AbstractXMLFormAction and Form, but it works. I just need to define >>> some >>> symbolic constants for the namespaces and find a way to access a >>> SourceResolver from JavaScript to make it pretty. >>> >>> Anyway, if you prefer to write complex business logic in Java (and >>> I'd >>> agree wholeheartedly with that), you can encapsulate it in a Java >>> method >>> that returns a boolean or an index to drive the flow that will be >>> implemented by an if/then/else or a switch in JavaScript. >>> >>> What do we gain by this? We remove flow logic from the sitemap in the >>> form of actions and put it in the flowscript, where it belongs >>> (IMHO). >>> >>> Ugo >>> >>> -- >>> Ugo Cei - http://www.beblogging.com/blog/ >>> >>> >>> --------------------------------------------------------------------- >>> To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org >>> For additional commands, email: cocoon-dev-help@xml.apache.org >>> >>> >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org >> For additional commands, email: cocoon-dev-help@xml.apache.org >> >> >> > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org > For additional commands, email: cocoon-dev-help@xml.apache.org > --------------------------------------------------------------------- To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org For additional commands, email: cocoon-dev-help@xml.apache.org