4 Replies Latest reply on Jun 26, 2007 8:53 PM by David Radunz

    Layering / overloading resources approach

    David Radunz Newbie

      Hi,

      I originally raised this issue in another thread that seems to have been overlooked, probably not the best place to raise it. So I have decided to raise my query again, hopefully not angering anyone in the process.

      What we want to achieve is to be able to layer our JSF projects. Typically we have a "framework", that a "product" extends from and then a "site" may be introduced to capture any site specific customisations to the "product". Each layer ("framework", "product" and "site") will have their own collection of Java beans, XHTML components and XML and property configuration files. All of these should be able to override the previous implementation, whilst at the same time still being able to access them to "extend" them (i.e. Java inheritance and Facelets style XHTML extending).

      Problem: How to layer "Beans", "XHTML components" and "configuration".

      Solution: Beans.

      This is quite easy, and Seam has already provided functionality for this using the @Install annotation. I simply need to annotate the beans at the framework layer with an @Install precedence lower than the "product", and the same with the "product" lower than the "site".

      Solved: Configuration: property files - using Seam's internationalization approach I could layer property files as well as provide internationalization support. Is this the correct approach?

      Unsolved: XML configuration
      Not sure what the solution would be? It seems that multiple pages.xml files can be loaded - but is overriding allowed within pages.xml files?

      Unsolved: XHTML
      Ideally what I would like is to have the following structure:

      /view/product/function/main.xhtml
      /view/product/function/two.xhtml


      And then say, introduce the overloaded version of "main.xhtml":

      /view/site/product/function/main.xhtml
      


      And some how to refer to them both as the same name, either using EL (#{pages.product.function.main}) or using "/product/function/main.xhtml" and overloading some resource loader to scan multiple places for "/product/function/main.xhtml".

      I am still as yet a little unclear as to what the best approach to take is, I can only assume (based on the presence of the @Install annotation) that others have faced the same problem. I am also interested in how you can load resources from JAR files - for the XHTML files as well as standard resources.. Weblets seems a little bit windy to me in this regard.

      I hope I have been clear in what I am asking, if I have not - please let me know.. I would rather clarify than get no response.. I am pulling a few hairs out trying to figure out the best approach on this one.

      Cheers,

      David



        • 1. Re: Layering / overloading resources approach
          David Radunz Newbie

          Hi,

          I was just wondering why no one has answered my question. Is it because I am thinking about this issue the wrong way entirely? Or because no one has encountered it?

          I hope someone can help out,

          Cheers,

          David

          • 2. Re: Layering / overloading resources approach
            Pete Muir Master

             

            "utiba_davidr" wrote:
            I originally raised this issue in another thread that seems to have been overlooked, probably not the best place to raise it. So I have decided to raise my query again, hopefully not angering anyone in the process.


            Yes, new threads are always best for a new topic, otherwise I (at least) get confused about what info relates to what ;)

            Problem: How to layer "Beans", "XHTML components" and "configuration".

            Solution: Beans. This is quite easy, and Seam has already provided functionality for this using the @Install annotation. I simply need to annotate the beans at the framework layer with an @Install precedence lower than the "product", and the same with the "product" lower than the "site".


            Yes.

            Solved: Configuration: property files - using Seam's internationalization approach I could layer property files as well as provide internationalization support. Is this the correct approach?


            I8ln - I would extend the resourceBundle component, and provide a lookup along the lines of check messages_en.site.properties, check messages_en.product.properties etc.


            Unsolved: XML configuration
            Not sure what the solution would be? It seems that multiple pages.xml files can be loaded - but is overriding allowed within pages.xml files?


            Configuration - slightly harder (components.xml is built in deeper) - but as long as its simple using a properties file, with a filter in your ant script (as the seam-gen'd apps do for some properties) should work - then you just need a properties file per site.

            As for pages.xml, you can override - but only in that a page defintion for /foo/bar.xhtml overrides a definition for /foo/* - so not so easy. Again, ant filtering might be best. Or look at overriding the Pages component as that is what parses and manages the pages.xml files.

            Unsolved: XHTML
            I am still as yet a little unclear as to what the best approach to take is, I can only assume (based on the presence of the @Install annotation) that others have faced the same problem. I am also interested in how you can load resources from JAR files - for the XHTML files as well as standard resources.. Weblets seems a little bit windy to me in this regard.


            resource loading - take a look at how we do it for s:selectDate.

            You could consider using ui:include templating with el specifying which file to load (and some sort of check to see if a more specific file exists or not), or better would be overload the Facelets resource resolver.

            I would ask this on the facelets mailing list as well - they are very helpful, and some of them will have done something like this :)

            • 3. Re: Layering / overloading resources approach
              Matt Drees Master

              Hi David,

              I'll be doing similar to this, though on a much smaller scale. I haven't thought yet much about how to handle it, though. If it's not too much trouble, could you post a little about your solution once you've figured it out?

              Thanks
              -Matt

              • 4. Re: Layering / overloading resources approach
                David Radunz Newbie

                Hey,

                Thanks heaps for this. I believe overloading the ResourceResolver is the best option for layering XHTML files. With a method simmilar to:

                public URL resolveUrl(String resource) {
                 String[] locations = {"", "/true/umarket", "/umarket"};
                
                 URL url = null;
                 for (String resourcePrefix: locations) {
                 url = getClass().getClassLoader().getResource(resourcePrefix + resource);
                
                 if (url != null)
                 break;
                 }
                
                 if (url == null) {
                 url = super.resolveUrl(resource);
                 }
                
                 return url;
                 }
                
                 ... elsewhere ... for the request ...
                
                 resolveUrl("/agent/list_agents.wt");


                This will traverse the class path, scanning under 3 prefixes. Of course I will make the prefixes configurable (perhaps inside the MANIFEST.MF of each XHTML jar file).

                As for laying the pages/components xml files - I will have to wait until I have time to play around to see what works best there. Thanks for letting me know that worst case scenario I can overload the Pages component.

                Cheers,

                David