SeamFramework.orgCommunity Documentation
The main namespace is urn:java:ee
. This namespace contains built-in
tags and types from core packages. The built-in tags are:
Beans
modifies
replaces
parameters
value
key
entry
e
(alias for entry)
v
(alias for value)
k
(alias for key)
array
int
short
long
byte
char
double
float
boolean
as well as classes from the following packages:
java.lang
java.util
javax.annotation
javax.inject
javax.enterprise.inject
javax.enterprise.context
javax.enterprise.event
javax.decorator
javax.interceptor
org.jboss.weld.extensions.core
org.jboss.weld.extensions.unwraps
org.jboss.weld.extensions.resourceLoader
Other namespaces are specified using the following syntax:
xmlns:my="urn:java:com.mydomain.package1:com.mydomain.package2"
This maps the namespace my
to the packages
com.mydomain.package1
and
com.mydomain.package2
. These packages are searched in
order to resolve elements in this namespace.
For example, you have a class com.mydomain.package2.Report
.
To configure a Report
bean you would use
<my:Report>
. Methods and fields on the bean are resolved
from the same namespace as the bean itself. It is possible to distinguish between
overloaded methods by specifying the parameter types, for more information see
Configuring Methods.
By default configuring a bean via XML creates a new bean; however there
may be cases where you want to modify an existing bean rather than
adding a new one. The <s:replaces>
and
<s:modifies>
tags allow you to do this.
The <s:replaces>
tag prevents the existing bean from being
installed, and registers a new one with the given configuration. The
<s:modifies>
tag does the same, except that it merges
the annotations on the bean with the annotations defined in XML. Where the
same annotation is specified on both the class and in XML the annotation in
XML takes precidence. This has almost the same effect as modifiying an existing
bean, except it is possible to install multiple beans that modify the same class.
<my:Report>
<s:modifies>
<my:NewQualifier/>
</my:Report>
<my:ReportDatasource>
<s:replaces>
<my:NewQualifier/>
</my:ReportDatasource>
The first entry above adds a new bean with an extra qualifier, in addition
to the qualifiers already present, and prevents the existing
Report
bean from being installed.
The second prevents the existing bean from being installed, and registers a new bean with a single qualifier.
Annotations are resolved in the same way as normal classes. Conceptually, annotations are applied to the object their parent element resolves to. It is possible to set the value of annotation members using the xml attribute that corresponds to the member name. For example:
public @interface OtherQualifier {
String value1();
int value2();
QualifierEnum value();
}
<test:QualifiedBean1>
<test:OtherQualifier value1="AA" value2="1">A</my:OtherQualifier>
</my:QualifiedBean1>
<test:QualifiedBean2>
<test:OtherQualifier value1="BB" value2="2" value="B" />
</my:QualifiedBean2>
The value
member can be set using the inner text of the node, as seen
in the first example. Type conversion is performed automatically.
It is currently not possible set array annotation members.
It is possible to both apply qualifiers to and set the initial value of a field. Fields reside in the same namespace as the declaring bean, and the element name must exactly match the field name. For example if we have the following class:
class RobotFactory {
Robot robot;
}
The following xml will add the @Produces
annotation to the
robot
field:
<my:RobotFactory>
<my:robot>
<s:Produces/>
</my:robot>
</my:RobotFactory/>
Inital field values can be set three different ways as shown below:
<r:MyBean company="Red Hat Inc" />
<r:MyBean>
<r:company>Red Hat Inc</r:company>
</r:MyBean>
<r:MyBean>
<r:company>
<s:value>Red Hat Inc<s:value>
<r:SomeQualifier/>
</r:company>
</r:MyBean>
The third form is the only one that also allows you to add annotations such as qualifiers to the field.
It is possible to set Map
,Array
and
Collection
field values. Some examples:
<my:ArrayFieldValue>
<my:intArrayField>
<s:value>1</s:value>
<s:value>2</s:value>
</my:intArrayField>
<my:classArrayField>
<s:value>java.lang.Integer</s:value>
<s:value>java.lang.Long</s:value>
</my:classArrayField>
<my:stringArrayField>
<s:value>hello</s:value>
<s:value>world</s:value>
</my:stringArrayField>
</my:ArrayFieldValue>
<my:MapFieldValue>
<my:map1>
<s:entry><s:key>1</s:key><s:value>hello</s:value></s:entry>
<s:entry><s:key>2</s:key><s:value>world</s:value></s:entry>
</my:map1>
<my:map2>
<s:e><s:k>1</s:k><s:v>java.lang.Integer</s:v></s:e>
<s:e><s:k>2</s:k><s:v>java.lang.Long</s:v></s:e>
</my:map2>
</my:MapFieldValue>
Type conversion is done automatically for all primitives and primitive wrappers,
Date
, Calendar
,Enum
and
Class
fields.
The use of EL to set field values is also supported:
<m:Report>
<m:name>#{reportName}</m:name>
<m:parameters>
<s:key>#{paramName}</s:key>
<s:value>#{paramValue}</s:key>
</m:parameters>
</m:Report>
Internally, field values are set by wrapping the InjectionTarget
for a bean. This means that the expressions are evaluated once, at bean
creation time.
Inline beans allow you to set field values to another bean that is declared inline inside the field declaration.
This allows for the configuration of complex types with nestled classes. Inline beans can be declared inside both
<s:value>
and <s:key>
elements, and may be used in both collections
and simple field values. Inline beans must not have any qualifier annotations declared on the bean; instead Seam Config
assigns them an artificial qualifier. Inline beans may have any scope, however the default Dependent
scope
is recommended.
<my:Knight>
<my:sword>
<value>
<my:Sword type="sharp"/>
</value>
</my:sword>
<my:horse>
<value>
<my:Horse>
<my:name>
<value>billy</value>
</my:name>
<my:shoe>
<Inject/>
</my:shoe>
</my:Horse>
</value>
</my:horse>
</my:Knight>
It is also possible to configure methods in a similar way to configuring fields:
class MethodBean {
public int doStuff() {
return 1;
}
public int doStuff(MethodValueBean bean) {
return bean.value + 1;
}
public void doStuff(MethodValueBean[][] beans) {
/*do stuff */
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:s="urn:java:ee"
xmlns:my="urn:java:org.jboss.seam.config.xml.test.method">
<my:MethodBean>
<my:doStuff>
<s:Produces/>
</my:doStuff>
<my:doStuff>
<s:Produces/>
<my:Qualifier1/>
<s:parameters>
<my:MethodValueBean>
<my:Qualifier2/>
</my:MethodValueBean>
</s:parameters>
</my:doStuff>
<my:doStuff>
<s:Produces/>
<my:Qualifier1/>
<s:parameters>
<s:array dimensions="2">
<my:Qualifier2/>
<my:MethodValueBean/>
</s:array>
</s:parameters>
</my:doStuff>
</my:MethodBean>
</beans>
In this example, MethodBean
has three methods. They are all named doStuff
.
The first <test:doStuff>
entry in the XML file configures the method that takes no arguments. The
<s:Produces>
element makes it into a producer method.
The next entry in the file configures the method that takes a
MethodValueBean
as a parameter and the final entry
configures a method that takes a two dimensional array ofMethodValueBean
s as a parameter. For both of these methods, a qualifier was added to the method parameter and they were made into producer methods.
Method parameters are specified inside the <s:parameters>
element. If these parameters have annotation children they are taken to be annotations on
the parameter.
The corresponding Java declaration for the XML above would be:
class MethodBean {
@Produces
public int doStuff() {/*method body */}
@Produces
@Qualifier1
public int doStuff(@Qualifier2 MethodValueBean param) {/*method body */}
@Produces
@Qualifier1
public int doStuff(@Qualifier2 MethodValueBean[][] param) {/*method body */}
}
Array parameters can be represented using the <s:array>
element,
with a child element to represent the type of the array. E.g.
int method(MethodValueBean[] param);
could be configured via xml using
the following:
<my:method>
<s:array>
<my:MethodValueBean/>
</s:array>
</my:method>
If a class has a field and a method of the same name then by default the
field will be resolved. The exception is if the element has a child
<parameters>
element, in which case it is resolved
as a method.
It is also possible to configure the bean constructor in a similar manner. This is done with a
<s:parameters>
element directly on the bean element. The constructor is
resolved in the same way methods are resolved. This constructor will automatically have the
@Inject
annotation applied to it. Annotations can be applied to the constructor
parameters in the same manner as method parameters.
<my:MyBean>
<s:parameters>
<s:Integer>
<my:MyQualifier/>
</s:Integer>
</s:parameters>
</my:MyBean>
The example above is equivalent to the following java:
class MyBean {
@Inject
MyBean(@MyQualifier Integer count)
{
...
}
}
It is possible to limit which bean types are available to inject into a given injection point:
class SomeBean
{
public Object someField;
}
<my:SomeBean>
<my:someField>
<s:Inject/>
<s:Exact>com.mydomain.InjectedBean</s:Exact>
</my:someField>
</my:SomeBean>
In the example above, only beans that are assignable to InjectedBean will be eligable for injection into the field.
This also works for parameter injection points. This functionallity is part of Seam Solder, and the
@Exact
annotation can be used directly in java.
It is possible to make existing annotations into qualifiers, stereotypes or interceptor bindings.
This configures a stereotype annotation SomeStereotype
that has a single interceptor
binding and is named:
<my:SomeStereotype>
<s:Stereotype/>
<my:InterceptorBinding/>
<s:Named/>
</my:SomeStereotype>
This configures a qualifier annotation:
<my:SomeQualifier>
<s:Qualifier/>
</my:SomeQualifier>
This configures an interceptor binding:
<my:SomeInterceptorBinding>
<s:InterceptorBinding/>
</my:SomeInterceptorBinding>
Seam XML supports configuration of virtual producer fields. These allow for configuration of resource producer fields, Weld Extensions generic bean and constant values directly via XML. For example:
<s:EntityManager>
<s:Produces/>
<sPersistenceContext unitName="customerPu" />
</s:EntityManager>
<s:String>
<s:Produces/>
<my:VersionQualifier />
<value>Version 1.23</value>
</s:String>
The first example configures a resource producer field. The second configures a bean
of type String, with the qualifier @VersionQualifier
and the value
'Version 1.23'
. The corresponding java for the above XML is:
class SomeClass
{
@Produces
@PersistenceContext(unitName="customerPu")
EntityManager field1;
@Produces
@VersionQualifier
String field2 = "Version 1.23";
}
Although these look superficially like normal bean declarations, the <Produces>
declaration means it is treated as a producer field instead of a normal bean.
For further information, look at the units tests in the Seam Config distribution. Also see the XML based metadata chapter in the JSR-299 Public Review Draft, which is where this feature was originally proposed.