License X:Forge Tag Reference Request Component SQL Component XSL Component | What is X:Forge?X:Forge is an XML language whose main focus is on dynamic XML generation. X:Forge tags are supposed to be included in XML documents for further processing. The tool was designed as a replacement for XSP, an Apache technology originally used for dynamic generation of XML content in the Cocoon Project. From a higher level view X:Forge is also a framework to design XML-based applications using Avalon's component technology and Inversion of Control pattern. BasicsVersion Information
This documentation applies to version 3.0 of X:Forge, which is not released yet.
However, as it is deemed stable and has more features than 2.0, it is the recommended
version to use and can be downloaded from CVS by checking out with the tag
TechnologyX:Forge is a method to dynamically generate XML content based on runtime parameters (such as client requests and so on) and application logic. The main purpose doesn't differ from technologies such as XSP, but the implementation is peculiar since it's heavily component based. The architecture clearly defines three different environments:
Another major advantage of X:Forge is the capability of accessing (user defined) context elements via a generic broker mechanism. As an example in a typical servlet environment this means that the business logic can have transparent access to the whole servlet environment. Namespaces
Namespace URI of X:Forge itself:
Namespace URI of an automated component that is mapped to the namespace prefix foo:
Namespace URI of an X:Forge context defined in class org.bibop.xml.xforge.helpers.ThreadContext: StructureA typical X:Forge setup consists of the following:
Sample UsageSyntaxThe syntax for X:Forge is pretty straightfoward. There is a separate document that lists all the tags available. Here are two of them:
A typical X:Forge enabled document looks like this: <?xml version="1.0"?> <page xmlns:xf="http://xforge.org/xforge/3.0/"> Hi, I'm the first X:Forge enabled page ever. My first message is: <xf:process using="HelloWorld"/> </page> This will turn out, after processing, in: <?xml version="1.0"?> <page xmlns:xf="http://xforge.org/xforge/3.0/"> Hi, I'm the first X:Forge enabled page ever. My first message is: Hello, World! </page> Now a slightly more complicated example, using runtime parameters: <?xml version="1.0"?> <page xmlns:xf="http://xforge.org/xforge/3.0/"> I'm the smartest X:Forge enabled page ever. My first message is: <xf:process using="HelloWorld"> <xf:parameter name="greeting">Hello XML World!</xf:parameter> </xf:process> </page> It's easy to imagine what the output will be: <?xml version="1.0"?> <page xmlns:xf="http://xforge.org/xforge/3.0/"> I'm the smartest X:Forge enabled page ever. My first message is: Hello XML World! </page> X:Forge calls can of course be nested, allowing dynamic assembly of XML data: <?xml version="1.0"?> <page xmlns:xf="http://xforge.org/xforge/3.0/"> I'm the smartest XForge enabled page ever. My first message is: <xf:process using="HelloWorld"> <xf:parameter name="greeting"> <xf:process using="GreetingsDB"> <xf:parameter name="query">getGreeting</xf:parameter> </xf:process> </xf:parameter> </xf:process> </page> Behind the ScenesWhen the X:Forge implementation (a generic SAX ContentHandler or, in the case of Cocoon 2 a Sitemap transformer) hits a xf:process element it looks in the configuration file to see if there is a configured component for the content of the "using" attribute. The X:Forge component should implement the XForgeComponent interface and encapsulate the business logic into a toSax() method which is responsible for sending SAX events to the designated ContentHandler. The code for the above examples will be something like this: package org.bibop.xml.xforge.components.examples; import org.xml.sax.SAXException; import org.bibop.xml.xforge.components.AbstractXForgeComponent; import java.io.Serializable; public class HelloWorldComponent extends AbstractXForgeComponent { public void toSax () throws SAXException { String hello = "Hello World "; if (this.parameters.containsKey("greeting")) output((String)this.parameters.get("greeting")); else output(hello); } } The compiled class is then declared in the configuration file (actually an Avalon Configuration object) and configured. The configuration file will look like this: <?xml version="1.0" encoding="UTF-8"?> <xforge> <components> <component role="process" class="org.apache.avalon.excalibur.component.DefaultComponentSelector" logger="xforge"> <component-instance name="HelloWorld" class="org.bibop.xml.xforge.components.examples.HelloWorldComponent" logger="test"/> </component> </components> <role-list> <role name="org.apache.avalon.framework.component.ComponentSelector" shorthand="process" default-class="org.apache.avalon.excalibur.component.DefaultComponentSelector"/> </role-list> </xforge> When the "HelloWorld" component is found, an instance is created (or taken from an existing pool depending on the configuration) and its toSax() method is called. The SAX events are then sent to the (user defined) ContentHandler for further processing. The logger attribute here refers to a logger that was defined in another configuration file that follows the Avalon LogKit syntax. X:Forge includes a standard configuration file under org/bibop/xml/xforge/logkit.xconf, which is used by the supplied test application (see README file in root directory of download for details). |