[Logo] RSF Discussions Forum
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
Messages posted by: antranig  XML
Profile for antranig -> Messages posted by antranig [643] Go to Page: Previous  1, 2, 3  ...  41, 42, 43
Author Message
The key to passing things between views is in your other question, on ViewParameters. A ViewParameters object summarises all the state that is held in a particular URL (there is one-to-one conversion from one to the other, generally done by BasicViewParametersParser, but you won't need to bother with this unless you want something special).

So, for your case for example, you would define

class MyViewParameters extends SimpleViewParameters {
public int myval;

public StringList getAttributeFields() {
StringList togo = super.getAttributeFields().copy();
togo.add("myval");
}

public ViewParameters copyBase() {
MyViewParameters togo = (MyViewParameters)super.copyBase();
togo.myval = myval;
return myval;
}

}


You then construct a new ViewParameters object to be the last argument of the UIInternalLink constructor. The ViewProducer for view "newviewid" then registers itself as accepting MyViewParameter objects by returning an example from its getViewParameters method.

The copyBase() method is necessary for the framework but can be useful for you as well - ViewParameters objects could get bigger, and you can often be making up a whole batch of links that are the same apart from just one field - so in the loop I wrote in the message earlier, you might have a call to copyBase() to make the new ViewParameters for each link rather than constructing one from scractch each time round the loop.

Sorry that the ViewParameters derivation process isn't quite as slick as it should be, this is all pending a cleanup somewhere around 0.7 time when ViewParameters will just be a "holder" for a completely free object you define yourself. For now your own fields get "mixed in" rather with the housekeeping fields in the base class.

Note that i) you don't need to make "myval" a pea-like field if you don't want to, getters and setters work just fine too ii) you can precompute the "attributeFields" list if you're worried about efficiency.

Note that you get reasonable type conversion for ViewParameters fields for free - the system knows how to deal with most sensible primitive types and leaf types by itself so you don't get messed up with all the grotty bits of URL parsing and conversions.
Replicators (and Switches) are only needed when using XML producers, you can ignore them - in Java, just use a "for" loop!

In IKAT, "repeated" components are signalled by putting colons into the ids of the thing being repeated. You're nearly right with your template, only since it is the link you want repeating and not the div, you want the colon id in the link.

So what you actually want is this:

<div class="navIntraTool" >
<a href="overview.html" rsf:id="navlink:">Nav1</a> (spacer between links)
<a href="overview.html" rsf:id="navlink:">Nav2</a>
</div>

(It's a good idea that whenever you have something that you may repeat, to have at least TWO examples of it in the template, for a start it gives you somewhere to put any spacing material. There is also an annoying bug with rendering repeated single components in 0.6.0, fixed in 0.6.1)

Then in your producer, just keep emitting as many UIInternalLink objects as you need, with the "navlink:" ID. For example,

for (int i = 0; i < links.size(); ++ i) {
//... make viewparams here
UIInternalLink.make(parent, "navlink:", "Link text "+i, viewparams);
}

If you leave "Link text" as null, you will get whatever is in the template.

Due to IKAT magic, you will also get the "glue" (spacer between links) repeated for free
Steve - glad you're having fun! Fun is what's about... or at the least, the absence of not having fun

Regards your "bean" question - the answer is, "it's all in the bean". Whatever strange resolution behaviour you want for the bean marked "bean" must be in the class you get when you try to load it from the context. So if you want it to optionally load a Jython module when someone tries to get the "value" property, then write one that does this - RSF features the marvellous OLI (one-line-interface) BeanLocator
Code:
 public interface BeanLocator {
   public Object locateBean(String path);
 }
 


Any bean found implementing this interface (or java.util.Map) will be navigable by EL to the next path segment, which is a nice and cheap way of getting "interesting" behaviour into your bean model.

If you use this approach, you could use the BeanUtil.navigate method to automate the process of reflecting over your Jython bean inside the BeanLocator implementation.

Yet another option is to use Spring AOP to make make your bean "Bean" a proxy for the Jython bean - you would do this by using a Spring LazyInitTargetSource to hold the reference to the "real" bean and fit a Spring ProxyFactoryBean at the path "bean".

BUT - all of this might actually be unnecessary depending on exactly what you want to achieve - since it might all "just work" depending on exactly what kind of "switching" you want to achieve. When you say "go the normal rounds of looking for a Bean mapped to "bean"", what might you be expecting to find there? If all you might ever want to find is your Jython bean, you might just map it there as a Spring FactoryBean and be done with it.

This is all part of the magic capabilities you get from merging Spring with request-scope programming, and might be all you need - give me some more details and/or some sample code and I can help you out.
Very good questions! You're right, now I look the docs on this area are either relatively old [ViewParameters] or nonexistent (serialization - apart from a note in the middle of HibernateCookbook_2). I'll write up a proper FAQ entry and a couple of pages to go with it over the afternoon, but here are some quick answers for you:

i) Producers are serialized by "default serialization" as far as possible - that is the field names correspond DIRECTLY to the field names of the respective components. Polymorphism in the is handled by the "type" attribute (low-level function of the SAXalizer). The value of the "type" attribute is either a fully qualified Java class name, or (if you want to go to the trouble), a "type nickname" which is registered with the ClassNameManager inside PonderUtilCore. The convention for all components it that the type nickname is the lower-cased version of the classname with the "UI" prefix missing.

The central answer for all RSF XML mapping questions is inside the mappings directory https://saffron.caret.cam.ac.uk/svn/projects/RSFUtil/trunk/src/uk/org/ponder/rsf/mappings/
In particular RSFMappingLoader.java is the central point of coordination. If you want to add your own mappings, just drop any class implementing "MappingLoader" into your Spring context and it will be automatically invoked on startup.

ii) The flow definitions (if you are using any) are actually in standard Spring Web Flow format, which you can consult the main SWF site on http://opensource.atlassian.com/confluence/spring/display/WEBFLOW/Home however note there is only a subset of the features implemented, in particular you may not use any EL expressions in the file. Basically anything which you don't see in the NumberGuess sample is not supported

iii) The most important question is - are you quite sure you want to be using XML-based producers at all? For non-autogenerated apps I would strongly recommend ViewProducers writting in Java (or in your case in Jython - consult the Java version of the Cookbook app for details https://saffron.caret.cam.ac.uk/svn/projects/RSFHibernateCookbook/trunk/javacategory/, since these will in general be faster and more readable. Also this would free you from having to worry about mapping issues.

iv) The only two ViewParameters implementations in RSF indeed are the EntityCentredViewParameters and the SimpleViewParameters - the idea is that every app will certainly want to implement their own - after all who else would decide on URL structure and state but you? RSF makes it easy for you to have completely different URL structure even on a view-by-view basis - the only fixed part is that the first part of the path-info up to the first slash represents the viewID which is the basic index used by RSF. If you want to add new ViewParameters, just derive from ViewParameters, and implement the abstract methods. If you want you can then register the nickname with the mapping system in a MappingLoader, as in the following sample from RSFMappingLoader:

Code:
   public void loadExtendedMappings(SAXalizerMappingContext context) {
     context.classnamemanager.registerClass("entitycentred", EntityCentredViewParameters.class);
 


Yes, there is no requirement to be using Hibernate at the same time as EntityCentredViewParameters. The RSF "OTP" system just expects you to have a set of EL paths that do the mapping correctly, which you could implement in any way you like (for example by implementing java.util.Map or BeanLocator).

For example for an entity "SyllabusWeek" you might define a (request-scope) bean called SyllabusWeek that is a Map for which the key is the ID of the week, so that paths of the form

#{SyllabusWeek.syllabusid}

map onto the required object.

I think this is very cool and finally frees us both from the tyranny of DAOs but also from ORM coupling as well as a number of other evils

Hope this helps - and please let me know what if anything is leading you to use XML view producers since I've always been interested in precisely what the use cases are for these (I in general never expected people to write these by hand).
Good oh - in case you hadn't worked it out, you need to specify these in the project.xml without the tag
<war.bundle>true</war.bundle>
after them.
Actually you can do without all except the Spring jar there at all since that is the only compile-time dependency.
Yeah, you've managed to get the Spring jar into your webapp, always try to make sure not to do that with Sakai

Antranig.
Cool - glad you got it working!

I'm very concerned though that the build hasn't worked right. Could this be a file permissions problem? Maven is often extremely irritating in that if any file operations fail they fail silently. You may have seen that the build procedure for I-SakaiRSFNumberGuess is slightly odd
https://saffron.caret.cam.ac.uk/svn/projects/SakaiRSFNumberGuess/tags/RSF-0.6/maven.xml

in that it
i) invokes war build for RSFNumberGuess
ii) explodes war into its own area
iii) deploys its own artifacts on TOP of exploded image (in particular this should OVERWRITE the old web.xml)
iv) deletes "harmful" jars such as Spring and cglib &c which must not be deployed into a Sakai container
v) finally redeploys the "patched" image.

I did this this way because I wanted to try to exploit the fact that these apps are really the "same" app, with the exception of xml config and deployed Jars, but I think I am stressing the limits of build technology too far with this approach.

If you look at the HibernateCookbook example, you will see a much more straightforward (one-step) build that should not show this problem you are seeing. The downside (certainly for me) is that I have had to FORK the code within this project from the standalone app. I guess the only sensible way round this is to make the standalone app into 2 projects rather than 1 - one that builds an app jar and the other that corresponds to the deploy artifact, but I'm not sure non-Sakai users of RSF would get on with this.

Any ideas you've got about this welcomed, but also it would be great to get to the bottom of why this build isn't working for you. Which version of maven are you using? You're issuing the full build from the Sakai app dir, right? I'm puzzled that you issue the rm -R command, are you getting the "plain" version of the app deployed to tomcat by the build by mistake?

A key variable in the build seems to be ${maven.war.webapp.dir}, is there any chance you've got this set to some strange value?

(Unfortunately I didn't write this build script and our Maven expert Andy is off sick at the moment - if we get lost we may well have to wait for him)

Cheers,
Antranig.

PS, reading the XML spec I see that comments within a start tag are indeed illegal, I'll make sure this is removed for the 0.6.1 release.
Ignore that idiotic suggestion, I see from your first log that the app does appear to be deployed correctly, and those messages look exactly like normal startup for the app's web context. I would have expected plenty of noise if something were wrong with that - so the only possible thing missing might be that sakai.rsfdemo.xml hasn't been deployed for some reason?

What build procedure did you use exactly to build/deploy with?
OK, that does sound extremely strange - and as you say, since it usually works for everything, perhaps there's something more basic wrong? This probably sounds stupid, but did you check the build has actually deployed to the right webapps directory?
Again if you're getting stuck, please zip up and mail me your deployed webapp and I will see if I can figure out what has gone wrong with it.

Cheers,
Antranig.
Hi - it's possible I don't have all the packaging necessary to create a fully "registered" tool which I believe needs to be assigned to some kind of category, for example. You should find however the tool shows up in the Admin interface inside "Sites". The route I take is Sites -> (choose your site) ->Pages -> (choose your page) -> Tools -> New Tool - you should see the demo app available from the menu there.

If you can give me any pointers how to package the tool better for Sakai, gratefully received

The other exception you are seeing is perfectly normal - the initial URL with no path is considered "bad" and triggers a redirect onto the default view which the index page - the critical line in all the mess is

2006-04-05 19:22:04,505 INFO (RootHandlerBean.java:130) - <Redirecting to http://localhost:8080/SakaiRSFNumberGuess/faces/index?errortoken=wY0u6r9TRQo_TaIaAhz_xOjf&errorredirect=1>

This redirect happens for any kind of unexpected exception during a render cycle (called a "Level 1" Fault). If a further exception occurs in the default view, you will receive an error page.

You define a view as being the default view by either implementing "DefaultView" in its view producer or setting the "defaultview" field of the view tree.

OK, that's probably more than you wanted to know for now

Hope this helps,
Antranig.
This was caused by trying to deploy the "servlet" build of HelloWorld into a tomcat containing Sakai. In general make sure that any webapps in a Sakai container *avoid* deploying the JAR for Spring into their own lib, otherwise they will blow up on contact. This is a ClassLoader issue that can't be resolved, as a result of having a tomcat-wide application context.

The Sakai builds for RSF tools either delete the Spring jars from their image, or make sure they never get deployed.
After 0.6 when the RSACBridgeProxy was introduced, it suddenly looked like the request container could indeed be (almost) completely flattened, and that there wasn't a very great value to RSAC after all. In 0.6.1 through 0.6.2 beans will be being moved back into application scope again (for example ActionResultInterpreters) which will speed request handling somewhat.

However, in the process of doing this some beans *are* coming to light that really do benefit from a request-scope lifecycle - for example, AutoBaseURLProvider is a bean which is quite awkward to implement at application scope, since it has a dependency on HttpServletRequest which of course is in the request scope and on which any computations it did would need to be redone.

This isn't a massively great example since the computation in this case is only some URL parsing, but I think this generally points the tendency that request-scope beans tend to cluster around the HttpServletRequest, which is a massive "bullet" full of request-scope dependencies. The further away you get (assuming you have a reasonable architecture), the more these dependencies have been abstracted behind reasonable interfaces.

A tricky issue going forwards is the ViewParameters. This is actually due for refactoring in any case (to move the variable part into a framework-dependence-free bean), but the essential problem is that this is *polymorphic* (since it is in general of a different class for each view/request). This makes it somewhat hard to proxy since RSACBridgeProxy couldn't statically know what type of proxy to make. So until we have ViewParameters reform and hide this variable object itself behind an interface in ViewParameters, moving beans back into application scope will be halted wherever there is a ViewParameters.

The bottom line -
i) RSAC beans are probably still quite useful, but not so massively as we first thought,
ii) They will tend to congregate around the "incoming" request-scope dependency (HttpServletRequest for Servlets, PortletRequest for portlets) where there is the greatest "badness" in terms of kitchen-sink type request-scope variability
iii) The most valuable bit of request-scope dependency mapping will probably be where it was at the start, in the incoming EL interpretation layer, which ironically doesn't really use RSAC since it has to do all the hard work of topologically sorting the EL dependencies by itself since they arrive at random.
I'm very pleased to announce a new release, version 0.6 of the RSF framework. This is synchronized with version 1.1 of RSAC.

All project documentation is housed at the main wiki http://www2.caret.cam.ac.uk/rsfwiki, and issues may be reported at the RSF JIRA at http://www.caret.cam.ac.uk/jira/browse/RSF. Many of the wiki pages have blogging controls where you are welcome to append comments - for general questions and comments please use the discussion forums below.

New features in this release include
-- XML templating system with support for looping and branching
-- Full Hibernate integration

See the Roadmap page for further release details.

Enjoy!

Antranig.
 
Profile for antranig -> Messages posted by antranig [643] Go to Page: Previous  1, 2, 3  ...  41, 42, 43
Go to:   
Powered by JForum 2.1.6 © JForum Team