Help

Controls

PermLinkWikiLink

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Forum: Seam Users Forum ListTopic List
05. Oct 2008, 22:10 CET | Link

In large enterprise applications it is important to break applications down into decoupled subsystems. To this end it is desireable to compose a seam application from a set of plugins. You could envision the following architecture:

Main Portal-like Application

This is the master web application which contains common horizontal features:

  • the web.xml file
  • master components.xml and pages.xml files
  • home.xhtml
  • login.xhtml
  • menuing
  • themes, tags, and templates
  • admin components
  • etc

All these features would be part of the WAR per usual.

Plugins

From here it would be nice to be able to package a subsystem in a jar and add it to the classpath of the master web application and have the subsystem merged into the master. The subsystem jar would contain the following:

  • java components per usual
  • xhtml facelets files
  • messages.properties
  • page and navigation rules

Some of this is already possible:

  • Obviously it is already possible to package java components in a jar with a seam.properties file
  • Seam will already search the classpath for META-INF/components.xml files and merge them
  • JSF will already search the classpath for META-INF/faces-config.xml files and merge them

But some of it needs a few tweaks:

  • Seam needs to search the classpath for META-INF/pages.xml files and merge them
  1. It does search the classpath for fine-grained viewid.page.xml files, but you will end up with too many of these files
  2. It does allow you to specify medium-grained pages.xml files in the components.xml file, but this requires a change to the master
  3. Here is a link to the JIRA feature request and patch: JBSEAM-3509
  • Seam does have a unified resource bundle but it needs a few configuration enhancements
  1. You can specify a bundle per page, but you also want the master home page menus to have access to the messages as well
  2. You can specifiy multiple bundles in the components.xml file, but this requires a change to the master
  3. Here is a link to the JIRA feature request and patch: JBSEAM-3510
  • Probably the biggest question is how do you access facelets that are packaged in a jar.
  1. This just requires a custom facelets resource resolver and a change to the master web.xml
public class ClasspathResourceResolver extends DefaultResourceResolver
		implements ResourceResolver {
	@Override
	public URL resolveUrl(String resource) {
		URL resourceUrl = super.resolveUrl(resource);
		if (resourceUrl == null) {
			if (resource.startsWith("/")) {
				resource = resource.substring(1);
			}
			resourceUrl = Thread.currentThread().getContextClassLoader()
					.getResource(resource);
		}
		return resourceUrl;
	}
}
	<context-param>
		<param-name>facelets.RESOURCE_RESOLVER</param-name>
		<param-value>net.taylor.jsf.ClasspathResourceResolver</param-value>
	</context-param>

Of cource all of this isn't very useful if you can't access the subsystems from the home page and menus. This can be handled by storing the menus in the database and having each subsystem register its menus on startup by listening for the @Observer(org.jboss.seam.postInitialization) event.

Your menus facelet might look something like this:

    <c:forEach items="#{menubar.menus}" var="menu">
        <rich:dropDownMenu
            value="#{menu.value}">
            <c:forEach items="#{menu.children}" var="item">
                <rich:menuItem
                    value="#{item.value}"
                    rendered="#{item.rendered}"
                    action="#{item.action}">
                </rich:menuItem>
            </c:forEach>
        </rich:dropDownMenu>
    </c:forEach>

Seam Wiki has a plugin concept. This posting adds a few additional ideas to help ensure that a plugin is decoupled from the master app.

3 Replies:
06. Oct 2008, 01:06 CET | Link

John, I suggest you make this into a knowledge base article.

For the message bundle loading issue - I'm not happy with your proposed solution, but I agree it could be better. I'll try to think about a way of doing this that is consistent.

 

Read about how to report a bug.

06. Oct 2008, 17:55 CET | Link

I agree with you regarding the message bundle. I couldn't find a semantically correct way for additively adding elements to a collection in the components.xml file.

Not sure I like this either, but maybe turning it around the other direction, such that you define bundle components and then wire them to the resource loader component. The setter on the bundle component would add itself to the resource loader. Or maybe a create method on the bundle component would add itself to the resource loader.

Let me know if you come up with an approach you like and I'll put it together.

I'll let this topic evolve a bit and then move it to the knowledge base.

06. Oct 2008, 18:26 CET | Link
John Gilbert wrote on Oct 06, 2008 17:55:
I agree with you regarding the message bundle. I couldn't find a semantically correct way for additively adding elements to a collection in the components.xml file. Not sure I like this either, but maybe turning it around the other direction, such that you define bundle components and then wire them to the resource loader component. The setter on the bundle component would add itself to the resource loader. Or maybe a create method on the bundle component would add itself to the resource loader.

I'm much happier with this approach.

 

Read about how to report a bug.