| Author |
Message |
|
|
New features in 0.6.3:
Main highlights of this release are
* Full support for all HTML controls, including "parachute rendering" between <select> and <input> tags, controlled only by HTML in the template - check the [url="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=ComponentTest"]
ComponentTest sample page[/url] for details.
* Support for non-HTML content types (RSS, AJAX, XUL)
* "Informal flow" system making it easy to build up flow definitions piece by piece rather than centrally in XML
* JSR-168 integration - the same app will run with changes only to pure HTML templates and web.xml-type packaging as portlet or servlet.
* General compatibility shakedown to be compliant with upcoming Spring 2.0 libraries.
* As usual, numerous bug-fixes, better robustness and diagnostics, and performance enhancements.
All info available on the RSF wiki, discussion and support on the forums (here!).
RSF 0.6.4, which is expected to be the last 0.6.x branch of RSF will tidy up some issues with decorators, expand Hibernate-based ORM support, and synchronise with versions 3.x of Hibernate and 2.2.x of Sakai. It may also feature SpringMVC support!
|
 |
|
|
The template is the right place. Your example there won't quite work because you have given them the same id - so there's no way that the renderer could tell the difference.
You could either make one of them prev:enabled, the other prev:disabled, or even make them prev-enabled and prev-disabled.
Since "disabledness" is only a binary thing, and isn't the most utterly portable concept I don't think I'm going to let it interfere at the Component level. Well... perhaps after sleeping on it, perhaps a "DisabledDecorator" actually *is* the right approach. I'll think a bit more about the implications of this... right now I think the "enumerating options in the template" method is the best way.
|
 |
|
|
Yeah, this is a bit of a standing problem with the EL "philosophy" in general. The price you pay for the decoupling of the view, model and controller layers is that agreement between them is now made "in name only" which means that there will indeed be this string checking problem. That is, until someone writes some kind of RSF Eclipse plugin
Although there are some things it's not clear can ever be checked....
The point that RSF EL doesn't allow any logic does make it considerably easier to figure out what's gone wrong however.
If you can think of *any* ideas about what we could do about this, please do post them. As far as I see, it's one of the natural costs of the way RSF is set up.
|
 |
|
|
Yep,
a) this is completely morally wrong, decorators are specced for NON-FUNCTIONAL changes to the component tree, as rendering hints only.
b) this is probably broken, FreeAttr actually had never been tested and I may well have forgotten to add the renderer in the right place.
I'll fix mine if you'll fix yours
|
 |
|
|
OK, after thinking about this a bit more, this probably *is* the behaviour I'd be expecting
I thought this "ought" to work for at least one POST cycle, but in fact on the very first cycle there is no value in anncid at all. And on second and subsequent cycles the flow token changes, as per the impl of ONE_STEP so the bean contents are simply not found.
In general hidden field hacks like this are against the general idiom of RSF in terms of ways of keeping track of state - you should really be using the standard flow preservation mechanism since these are more configurable by the "end user" (they might actually configure it to use hidden fields if they want to, but you shouldn't make the choice for them).
|
 |
|
|
The docs do warn that two ONESTEP flows cannot be run back-to-back. I recommend making this a GET form (now very straightforward in 0.6.3) - or using a full flow.
By the looks of it you have exposed a bug, though, since this isn't the right "failure" behaviour I'd be expecting I'll look into it later today.
|
 |
|
|
Actually RSF already, deterministally, assigns unique ids to every component it instantiates - take a look at the RSF page on full IDs. This is one of the main successes of the RSF renderer in making pages Javascript-friendly, since it's extremely easy to navigate around the tree of dynamically generated components, which form a kind of hierarchical "file system". Compare this to the idiot system of JSF which essentially assigns them random numbers...
The answer to the other question is that producers that serve a particular function (e.g. producing a syllabus, blog entry &c) will conform to a particular API that the person who specced the function drew up. When I call things "ViewProducers" I'm actually talking about things that implement any kinds of different interfaces, but with the one common feature that they take one argument that is a UIContainer which they fill up with RSF components.
The more advanced answer to your other question is that you can actually even do without these "function specific APIs" in RSF, since it allows not only "traditional Spring" but also request-scope IoC. A request-scope configured producer can simply be written out in a Spring file to accept "any number of additional dependencies" from the environment, and just conform to a plain ComponentProducer interface to its clients. The tradeoff between dependencies-as-arguments and dependencies-as-Spring-deps is a balance of efficiency, flexibility, taste &c. Internally for example the bulk of RSF is written using request-scope IoC, to get the maximum possible flexibility for people who want to reconfigure/replace parts of it, except for some cases that really are utterly performance-critical.
Actually ViewProducers can *well* be the most most performance-critical aspect of an app, which is why the API I provided for them for default has enough arguments that it can usually do something sensible at application-scope. For FlowTalk, for example, which has one ViewProducer running at > 500 lines, with lots of other ones hanging off it (try writing *that* logic in JSPs!!) firing up all of that every request would be a big liability. However, lots of Steve's stuff is at request-scope since sometimes for example he needs results from a previous POST cycle injected in.
|
 |
|
|
Lots of Qs
The 0.7 work isn't terribly "hard", just rather fiddly since there are some assumptions built in around the renderers about stuff like all the template data being available in a single XMLLump[]. I actually had made half a start on this before going to Austin with 0.6 but had to back off when I realised about annoyances such like, for example, each template file having potentially it's own base directory and hence an independent path for resolving relative links! But this stuff should be out by, say, August.
External templates will be "very cool" in that they will be "include-free". Again, trashing all existing templating technologies (!), these are "heavy" in that you have to explicitly write "include" statements at the head of a file that might want to bring in certain template material ahead of time - which means of course it's impossible to change your mind at runtime.
From the *users* of multi-file templates, very little will change - you'll notice in RSF today there is a BasicTemplateResolver, generally a request-scope bean that works out for the current view which template to use. The only different in 0.7 is that this has the capability to return multiple templates rather than one, with the first one in the list being considered the "root template" at which rendering begins, and the others being "optional branches" that *might* contain targets for IKAT branching. Given the IKAT algorithm is completely "implicit" you never actually need to WRITE links from one template to another, just rendering will perform the branch if there "happen to be" good template matches for the current component in the other file - and then return to the calling template afterwards.
So in RSF actually it's not even going to be a *template-level* dependency - external templates will actually introduce no dependencies at all, not even on each other Except of course on the actual String you use for the rsf:id, which is where ALL dependencies in RSF fall on.
So yep, the UI folks can go crazy - and I mean really crazy I'll be showing off the kinds of amazing changes you can pull just with HTML templates at Vancouver, but you can get a sneak preview at the [url="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=ComponentTest"]
Component Test Demo[/url].
So yes, as far as multiple templates are concerned, it's a matter for the runtime to decide where there might be relevant templates - I can imagine that we would supply a "TemplateResolutionService" within Sakai that kept track of a registry of currently available templates for its standard "widgets".
Now, as far as the producers are concerned, yes, these *do* need to be available as bean definitions, but we would just fold these into SakaiRSF as people defined them - each app would keep their own local copies of these defs to avoid polluting the shared area. SakaiRSF currently includes a "skeleton crew" of Sakai-specific RSF beans to deal with stuff like Sites and SitePages which I can imagine is only set to grow explosively.
If you look at the way RSF is structured, this is all completely transparent - for example the Sakai Hibernate demo is sitting on a stack of *five* layered Spring contexts, where SakaiRSF is number 4. Pulling in all the bean definitions is just a matter of making the reference to its internal Spring file from your web.xml.
If people want to make their own widget libraries, this is just a matter of making a JAR with its Spring stuff inside it, and telling people which position in the stack their context should go at (most likely *after* SakaiRSF, but *before* the user's own files).
|
 |
|
|
Howdy Josh! Great to see some action in some of the other forums
Here's some words about RSF components -
The RSF "component" model isn't quite like the one in other frameworks, since the hierarchy starting at UIComponent is extremely "concrete", and really exists only to support different model binding behaviours (of which there isn't a lot of variation possible - you can Input or Output things of "UI type" Boolean, String or list of Strings - or for HTML, also URLs). For anything which isn't "different" in this way you probably don't want to make a new UIComponent at all - the wiki page on Component explains the situation a bit. What you really want to do is string together a set of more primitive RSF UIComponents.
The "real" way to write widgets in RSF is by paired sets of ViewProducers and blocks of HTML template. This way you have cleanly separated out into two pieces, code and HTML, what used to be fused in one nasty lump in taglibs.
ViewProducer docs here: http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=ComponentProducer
The main caveat is that until we have 0.7 (which I'll start on when I get back from Vancouver), all the HTML rendered in a single view must be present in the same HTML template file.
So while you can get developing stuff like wysiwyg editor widgets right now, you have to make sure that all the "optional replacements" are rendered out in the template.
Looks to me that a wysiwyg editor essentially is a UIInput, i.e. a thing which produces a single String value - so you wouldn't create a new component for that. I guess they are configurable in some standard ways (?) so you might need a bunch of UIOutputs to render the options.
The point of RSF is to get as much of the bulk of the "component" out into the HTML template, with just some tiny field adjustments done by the renderer. This is quite different even to the other "pure HTML" frameworks (e.g. Facelets, Wicket, Tapestry) in that they expect to have stuff kept "in the back pocket" to stomp over the template with.
Actually I'd need to see the HTML for the various different kinds of editor since I've never actually seen one Then I could give you some hints as to how to get started with that particular problem.
|
 |
|
|
OK... I think you're going to like this one
What you need is basically a bit of OTP. The different rows need to be bound to some EL paths which will cause the "correct thing" to be written - you could either put the List itself into the bean model, e.g. turn your util.getRoleNames() method into a bean constructing a List which sits in the request scope -
<bean id="roleperms" factory-bean="RoleFactory" factory-method="getRoles"/>
You can then access the individual RolePermission objects under the paths #{roleperms.1}, #{roleperms.2} etc. However this is somewhat unreliable since the roles may well be DIFFERENT on the request cycle when the POST has been handled. This is the sort of thing that JSF is often sloppy about since it relies that some random stuff has been "fossilized" into the Session that will not change until the next cycle comes.
So in fact, you'd probably be better off actually making this a Map, so then you would get to the permissions by #{roleperms.access}, #{roleperms.maintain} etc.
However, even more cool/straightforward might be to just make a "true" OTP exploder, simpler than making a Map you can just make it a BeanLocator or WriteableBeanLocator. Looking at the Sakai APIs though (AuthzGroup, Role, etc. I don't see any standard POJO-type entities that you can punch through to directly. In particular the problem is that Role.getAllowedFunctions() returns a Set, which is a bit hard to address via EL...
|
 |
|
|
The main issue is performance. You can take a look at the RSAC Performance Page which explains what is known about this.
The bottom line is that each request-scope bean takes around 10 microseconds to contruct, which while it isn't terribly much, can mount up after a while if you have enough of them. This was the only reason RSAC was made - it's around 100x faster than Spring at constructing beans, although a bit less flexible.
In general if the performance becomes an issue, you can use the RSACBridgeProxy to bridge a request-scope dependency to application scope and so move your producers back again.
Although I'm a bit suspicious as to why your producers are needing to depend on things in request scope - in general if you want them to access bits of the bean model this should either i) be persistent and so not request-scope, or ii) issued by means of EL bindings. Could you give me some idea of what you are doing?
|
 |
|
|
You're not returning anything from the addAnnouncement method. The first argument to NavigationCase is the "fromOutcome", which will be matched against the return of the Action method, in "JSF-style". To make this work, either supply null as the argument or return "anncadd" from the method.
2nd problem: Its the *view* which needs to implement NavigationCaseReporter, not the action bean - RSF beans never implement anything!
[edited further]
3rd problem: Make sure to declare the JSFNavigationARI in your applicationContext to enable these navigation rules:
<bean id="defaultARI" parent="JSFNavigationARI"/>
[edited again]
This definition can now be omitted, from RSF 0.6.2 onwards (in trunk at rev 1201)
|
 |
|
|
New functionality committed to 0.6.2-dev (at SVN revision 1198) for a more general solution to the ContentType problem - explained in new FAQ item http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=QampA#ref-QampA-7.
Enjoy!
|
 |
|
|
I'll sort out the whole declaration/extention/content-type mess later on this evening. Nothing like user-driven development...
Good grief, you're using XUL already....
|
 |
|
|
|
This is caused by sending a non-RSF POST request through the RSF action cycle. Actually the cycle ends up working "just fine" since the default ARI on a n Action request simply redirects to the same view in a Render cycle, with some error parameters added. For better performance with non-RSF POSTs you should register a HandlerHook and process them yourself.
|
 |
|
|
|
|