2 Replies Latest reply on Dec 25, 2009 12:03 PM by speedys

    How can i bind loaded stylesheet from db to my application?

    speedys

      Hi @,


      i have a question?
      We are working on a seam application. In this application the user have the possibility to login and to customize the configured application theme to change template stylesheets. To realise this task, i use to write a servlet that hold stylesheet data from database and write its content into outputstream:


      ...
      <head>
         <link type="text/css" href="http://mydomain.com/myservlet?theme=blue" rel="StyleSheet"/>
      </head>
      ...
      



      So, my question is: How can i bind stylesheet data to my application dynamically using seam?

        • 1. Re: How can i bind loaded stylesheet from db to my application?
          mikkus70

          There are several ways you can do this. The first one is to just use the servlet you already had and simply put it inside your war. In this case, however it is harder to put Seam to work within your servlet (although it can be done via the API).


          Another solution is to publish your CSS in the document store and link to it. I haven't tested it but it should work. However, I dislike this solution because document stores are conversation-based (whereas the user stylesheet would probably be used throughout the entire session) and therefore you would be hitting the DB to retrieve the CSS on every conversation boundary.


          The solution I personally like the best is a resource adapter, which is a class that extends AbstractResource. It has the advantage of not being limited to the conversation scope.


          The following resource class creates a simple resource adapter that serves the CSS in the /yourappname/seam/resource/stylesheets/* relative URL. In this example, StylesheetSelector is a regular Seam component (likely session-scoped) that somehow resolves the CSS string content (by querying the database based on the current user or any other mechanism).


          @Name("cssResource")
          @Scope(ScopeType.APPLICATION)
          @BypassInterceptors
          public class CssResource extends AbstractResource {
          
               @Override
               public void getResource(final HttpServletRequest request,
                         final HttpServletResponse response) throws ServletException, IOException {
                    
                    new ContextualHttpServletRequest(request) {
          
                         @Override
                         public void process() throws IOException {
                              doWork(request, response);
                         }
                    }.run();
               }
          
               @Override
               public String getResourcePath() {
                    return "/stylesheets";
               }
               
               private void doWork(HttpServletRequest request, HttpServletResponse response) {
                    try {
                         response.setContentType("text/css");
                         response.getWriter().append(((StylesheetSelector)Component.getInstance("stylesheetSelector")).getUserStylesheet());
                         response.flushBuffer();
                    } catch (IOException e) {
                         e.printStackTrace();
                    }
               }
          }
          



          You can then use the dynamic stylesheet in your pages or templates via:


          <link type="text/css" href="/yourappname/seam/resource/stylesheets/anything" rel="StyleSheet"/>
          



          Of course, this is just an example, if you foresee that many users will use the same stylesheet (not all will probably customize theirs), probably you want to use an application-scoped cache to store stylesheets, instead of storing them in user sessions.

          • 2. Re: How can i bind loaded stylesheet from db to my application?
            speedys

            Hi Emir, your suggestion worked great. Thank you so much!  :)


            Concerning the caching, it's true, we want to use an application-scoped cache in order to store stylesheets because many users will use the same stylesheet definitions. But at this moment now, we don't really care about caching, it will be handled as soon as possible we finish implementing this task.


            thx