Throughout the examples, there have been two competing ways of declaring components: with and without the use of XML namespaces. The following shows a typical components.xml
file without namespaces. It uses the Seam Components DTD:
<?xml version="1.0" encoding="UTF-8">
<!DOCTYPE components PUBLIC "-//JBoss/Seam Component Configuration DTD 1.2//EN"
"https://jboss.com/products/seam/components-1.2.dtd">
<components>
<component class="org.jboss.seam.core.init">
<property name="debug">true</property>
<property name="jndiPattern">@jndiPattern@</property>
</component>
<component name="org.jboss.sean.core.ejb" installed="@embeddedEjb@" />
</components>
As you can see, this is somewhat verbose. Even worse, the component and attribute names cannot be validated at development time.
The namespaced version looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="https://jboss.com/products/seam/components"
xmlns:core="https://jboss.com/products/seam/core"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"https://jboss.com/products/seam/core
https://jboss.com/products/seam/core-1.2.xsd
https://jboss.com/products/seam/components
https://jboss.com/products/seam/components-1.2.xsd">
<core:init debug="true" jndi-pattern="@jndiPattern@"/>
<core:ejb installed="@embeddedEjb@"/>
</components>
Even though the schema declarations are verbose, the actual XML content is lean and easy to understand. The schemas provide detailed information about each component and the attributes available, allowing XML editors to offer intelligent autocomplete. The use of namespaced elements makes generating and maintaining correct components.xml
files much simpler.
Now, this works great for the built-in Seam components, but what about user components? There are two options. First, Seam supports mixing the two models, allowing the use of the generic <component>
declarations for user components, along with namespaced declarations for built-in components. But even better, Seam allows you to quickly declare namespaces for your own components.
Any Java package can be associated with an XML namespace by annotating the package with the @Namespace
annotation. (Package-level annotations are declared in a file named package-info.java
in the package directory.) Here is an example from the seampay demo:
@Namespace(value="https://jboss.com/products/seam/examples/seampay")
package org.jboss.seam.example.seampay;
import org.jboss.seam.annotations.Namespace;
That is all you need to do to use the namespaced style in components.xml
! Now we can write:
<components xmlns="https://jboss.com/products/seam/components"
xmlns:pay="https://jboss.com/products/seam/examples/seampay"
... >
<pay:payment-home new-instance="#{newPayment}"
created-message="Created a new payment to #{newPayment.payee}" />
<pay:payment name="newPayment"
payee="Somebody"
account="#{selectedAccount}"
payment-date="#{currentDatetime}"
created-date="#{currentDatetime}" />
...
</components>
Or:
<components xmlns="https://jboss.com/products/seam/components"
xmlns:pay="https://jboss.com/products/seam/examples/seampay"
... >
<pay:payment-home>
<pay:new-instance>"#{newPayment}"</pay:new-instance>
<pay:created-message>Created a new payment to #{newPayment.payee}</pay:created-message>
</pay:payment-home>
<pay:payment name="newPayment">
<pay:payee>Somebody"</pay:payee>
<pay:account>#{selectedAccount}</pay:account>
<pay:payment-date>#{currentDatetime}</pay:payment-date>
<pay:created-date>#{currentDatetime}</pay:created-date>
</pay:payment>
...
</components>
These examples illustrate the two usage models of a namespaced element. In the first declaration, the <pay:payment-home>
references the paymentHome
component:
package org.jboss.seam.example.seampay;
...
@Name("paymentHome")
public class PaymentController
extends EntityHome<Payment>
{
...
}
The element name is the hyphenated form of the component name. The attributes of the element are the hyphenated form of the property names.
In the second declaration, the <pay:payment>
element refers to the Payment
class in the org.jboss.seam.example.seampay
package. In this case Payment
is an entity that is being declared as a Seam component:
package org.jboss.seam.example.seampay;
...
@Entity
public class Payment
implements Serializable
{
...
}
If we want validation and autocompletion to work for user-defined components, we will need a schema. Seam does not yet provide a mechanism to automatically generate a schema for a set of components, so it is necessary to generate one manually. The schema definitions for the standard Seam packages can be used for guidance.
The following are the the namespaces used by Seam:
-
components — https://jboss.com/products/seam/components
-
core — https://jboss.com/products/seam/core
-
drools — https://jboss.com/products/seam/drools
-
framework — https://jboss.com/products/seam/framework
-
jms — https://jboss.com/products/seam/jms
-
remoting — https://jboss.com/products/seam/remoting
-
theme — https://jboss.com/products/seam/theme
-
security — https://jboss.com/products/seam/security
-
mail — https://jboss.com/products/seam/mail
-
web — https://jboss.com/products/seam/web