Chapter 3. Configuring Pustefix

Table of Contents

3.1. Overview
3.2. Customization tools
3.3. Global configuration files
3.3.1. XML property files syntax
3.3.2. Factory loader configuration (factory.xml)
3.3.3. Global properties (pustefix.xml)
3.3.4. Global projects configuration (projects.xml)
3.4. Project configuration files
3.4.1. Project descriptor (project.xml)
3.4.2. Page Configuration (depend.xml)
3.4.3. ContextXMLService configuration file
3.4.4. DirectOutputService configuration file
3.4.5. WebServices
3.4.6. Configuration Fragments
3.5. Spring configuration and customization
3.5.1. Customizing the Spring configuration

3.1. Overview

Starting a new project in your Pustefix environment requires (besides developing the business logic and the UI) that you edit a bunch of configuration files.

Three different types of config files exist:

  1. Global configuration files: These files are all located in projects/common/conf. They define global options which apply to all projects in the environment.

  2. Project specific configuration files: These files are located within the conf directory of each project directory. They define options which only apply to the corresponding project.

  3. build.properties file: This optional configuration file may contain properties that are used by Ant as if they were specified on the command line when calling Ant.

3.2. Customization tools

Virtually all configuration files used by Pustefix support a mechanism called "customization". You may use this customization support to use different portions of a configuration file depending on the environment being used when building the project. For this task, the customization tools provide a choose tag which is similar to the choose tag provided by XSLT.


<choose>
  <when test="XPathExpression">
    <!-- Configuration code -->
  </when>
  <when test="XPathExpression">
    <!-- Configuration code -->
  </when>
  <otherwise>
    <!-- Configuration code -->
  </otherwise>
</choose>

    

At least one when tag has to be specified. Further when tags and the otherwise are optional. However, if specified, the otherwise tag has to be the last one.

The XPath expressions may contain references to the variables

  • mode: Set to the property makemode specified when running Ant. If no explicit makemode is specified prod is used.

  • uid: The name of the user that executed Ant.

  • fqdn: The fully qualified domain name of the machine the build process was run on.

  • machine: The host name of the machine the build process was run on.

  • __antprop_*: All properties defined within Ant's build.xml file are provided as variables with the prefix __antprop_.

It is an error to reference a variable that is not defined. Therefore you might use the special XPath function pfx:isSet('variableName') to check if a variable with a certain name is defined.

3.3. Global configuration files

All global configuration files are located in projects/common/conf. There are

  • buildtime.properties: This file is automatically generated each time Ant runs. It contains all properties defined in Ant's build.xml file as well as some special properties (like the "makemode"). It is used by Pustefix's customization tools, which allow to check for the properties defined there. You cannot modify this file, as all changes will be overwritten the next time Ant is run. If you want to define your own properties for the customization process, use Ant properties as they will be automatically included. See Section 3.2, “Customization tools” for details.

  • factory.xml: Configuration for factory loader.

  • pfixlog.xml: log4j configuration file. This file uses the standard log4j syntax, however the syntax is extended by the customization tags, which for this configuration file are locate in the namespace http://www.schlund.de/pustefix/customize.

  • projects.xml: Global project settings which are shared by all projects.

  • pustefix.xml: Contains global properties using the XML properties syntax.

  • userdata.xml: Used by the Pustefix CMS to store user accounts.

3.3.1. XML property files syntax

Some parts of the Pustefix frameworks are configured using Java properties. To ease this configuration Pustefix provides you with a special XML format which is read instead of the usual Java property file format. This format provides some customization mechanism to allow configuration options to depend on settings like the makemode or the machine the application is being built on.

The structure of a standard .xml property file is very easy:

  
  <properties
    xmlns="http://www.pustefix-framework.org/2008/namespace/properties-config"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.pustefix-framework.org/2008/namespace/properties-config http://www.pustefix-framework.org/2008/namespace/properties-config.xsd">
    
    <prop name="statuscodefactory.messagefile">common/dyntxt/statusmessages.xml</prop>
  </properties>
  
        

The prop tag is the most primitive way to enter a single property. The example above would simply result in the java property statuscodefactory.messagefile=common/dyntxt/statusmessages.xml. Pustefix allows to customize the creation of the property files using the mechanism described in Section 3.2, “Customization tools”.

You may reference customization variables in property values using the syntax ${variableName}. For example ${fqdn} will be replaced by the fully qualified domain name of the machine.

3.3.2. Factory loader configuration (factory.xml)

This property file is located in projects/common/conf/factory.xml and used by a ServletContextListener whenever the servletcontainer starts up to initialize services that are used by all the other projects. The syntax of this file is described in Section 3.3.1, “XML property files syntax”.

[Warning]Deprecated

It is not recommended to configure services as true, classloader-wide, singletons in factory.xml. We currently support it for backwards compatibility, but support will be dropped in the near future. We recommend that services are configured using Spring.

3.3.3. Global properties (pustefix.xml)

The syntax of the common/conf/pustefix.xml file complies to the description in Section 3.3.1, “XML property files syntax”. The properties defined here are merged with the properties defined for a specific servlet. However, there are some properties with a special meaning.

Exception processing is configured via prop elements whose names comply to following syntax: exception.TYPE.[page|forward|processor] For one single TYPE, there may be only one occurrence of page, forward and processor.

TYPE is a fully qualified class name of a valid exception class, for which the handling should be configured at this point. In this case it specifically means, that the specified class must be a descendant of java.lang.Throwable, as the catch-block that handles the exceptions which are specified here, catches Throwable.

If an exception occurs during exception processing, or during processing of the page the request got forwarded to, no further exception handling will take place. Therefore the code that processes exceptions and the code that drives pages to which requests get forwarded, in case of exceptions, should be robust. Otherwise the whole exception-handling thing would be quite useless, wouldn't it?

Table 3.1. Exception processor properties
Attribute Description
file Mandatory. Path to the file that contains the tags to be included (relative to docroot).
section Optional. Type of the section that shall be included. If more than one section of the specified type exists in the file, the content of all this sections is included. For a DirectOutputServlet configuration only directoutputpagerequests and properties are valid.
refid Optional. Include a section identified by the specified id. The refid specified here must match the id attribute of exactly one section in the specified file.
xpath Optional. A XPath expression specifying the node-set to be included. The prefixes to be used for XML namespaces are "fr" for the namespace of the fragments file tags and "pr" for the namespace of the DirectOutputServlet configuration tags.

3.3.4. Global projects configuration (projects.xml)

The projects.xml file contains global settings for Apache HTTPd, Tomcat and Pustefix itself.


<global-config xmlns="http://www.pustefix-framework.org/2008/namespace/project-config">
  
  <!-- prefix to namespace url mappings to be used in pages xml -->
  <namespaces>
    <namespace-declaration prefix="pfx" url="http://www.schlund.de/pustefix/core"/>
    <namespace-declaration prefix="ixsl" url="http://www.w3.org/1999/XSL/Transform"/>
  </namespaces>
  
  <http-server>
    <tomcat>
      <minprocessors>100</minprocessors>
      <maxprocessors>500</maxprocessors>
      <connectorport>8009</connectorport>
      <debug>0</debug>
      <loglevel>info</loglevel>
      <jkhost>${fqdn}</jkhost>
      <!-- This is only for mod_jk A matching sample workers.prop file will be generated, but may need -->
      <!-- additional customization. Clustering will not work out of the box. -->
      <jkmount>router</jkmount>
      <defaulthost>sample1.${fqdn}</defaulthost>
      <jvmroute>foo</jvmroute>
    </tomcat>
    <apache>
      <logdir>pfixroot:/servletconf/log</logdir>
    </apache>
  </http-server>
  
  <application>
    <static>
      <path>common/img</path>
      <path>core/img</path>
      <path>core/script</path>
    </static>
  </application>
  
</global-config>

     

The namespaces section declares namespace prefixes, which are available when editing include parts in the Pustefix CMS. You can set the exclude-result-prefix to true in order to exclude the namespace declaration from XHTML output sent to the browser.

The http-server section specifies various settings for Apache Tomcat and Apache HTTPd. Usually you do not have to change these settings.

The application section is used to specify pathnames which contain static resources which should be made available to all projects.

3.4. Project configuration files

For each project in your Pustefix environment you need to create a definition file that contains all the information about your project (including references to other project-specific configuration files). This file has to be named project.xml and must be placed in the conf subdirectory of the project. It can be accompanied by a Spring bean definition file that must be called spring.xml. This file may contain arbitrary definitions for beans that will be created within the Spring ApplicationContext automatically created for the web application.

All other configuration files can theoretically have arbitrary names, however we strongly recommend using the naming convention used in this reference documentation.

3.4.1. Project descriptor (project.xml)

The project.xml file contains references to all services and resources used by this project.


<project-config xmlns="http://www.pustefix-framework.org/2008/namespace/project-config">
  
  <project>
    <!-- Short project name, should equal the name 
         of the project directory                  --> 
    <name>projectname</name>
    <!-- Description shown in Pustefix CMS -->
    <description>Description for this project</description>
    <!-- 
      add
    <enabled>false</enabled>
      to make disregard this project when building the
      server configuration 
    -->
  </project>
  
  <editor>
    <!-- Set this to false to make the project disappear
         in the Pustefix CMS                             -->
    <enabled>true</enabled>
    <!-- Location of the Pustefix CMS, does not need to
         be changed usually                             -->
    <location>http://cms.${fqdn}/</location>
  </editor>
  
  <xml-generator>
    <!-- Path to the configuration file of 
         the TargetGenerator for this project -->
    <config-file>pfixroot:/projectname/conf/depend.xml</config-file>
  </xml-generator>
  
  <http-server>
    
    <!-- IP address and port Apache HTTPd (not Tomcat!) will
         listen on for HTTP connections                      -->
    <http-port>
      <address>${fqdn}</address>
    </http-port>
    
    <!-- IP address and port Apache HTTPd (not Tomcat!) will
         listen on for HTTPS connections                     -->
    <https-port>
      <address>${fqdn}</address>
      <ssl-key>pfixroot:/projectname/conf/server.key</ssl-key>
      <ssl-crt>pfixroot:/projectname/conf/server.crt</ssl-crt>
    </https-port>
    
    <!-- Name of the virtual host for this project -->
    <server-name>projectname.${fqdn}</server-name>
    <!-- Alias for the virtual host for this project -->
    <server-alias>projectname.${machine}</server-alias>
    
    <apache>
      <literal>
        <!-- Stuff that is copied to the Apache configuration -->
      </literal>
    </apache>
    
    <tomcat>
      <!-- Set this to true to enable extra context instances 
           for the virtual host created for this project      -->
      <enable-extra-webapps>false</enable-extra-webapps>
    </tomcat>
    
  </http-server>
  
  <application>
    
    <!-- Path that static resources will be delivered from -->
    <docroot-path>pfixroot:/sample1/htdocs</docroot-path>
    
    <!-- URI requests to / are redirected to -->
    <default-path>/xml/config</default-path>
    
    <!-- Only one context-xml-service may be specified per project -->
    <context-xml-service>
      <!-- URI the service will be available at -->
      <path>/xml/config</path>
      <!-- Path to the configuration file for the service -->
      <config-file>pfixroot:/projectname/conf/config.conf.xml</config-file>
    </context-xml-service>
    
    <direct-output-service>
      <!-- URI the service will be available at -->
      <path>/xml/download</path>
      <!-- Path to the configuration file for the service -->
      <config-file>pfixroot:/projectname/conf/direct.conf.xml</config-file>
    </direct-output-service>
    
    <!-- Extra paths for static resources -->
    <static>
      <path>sample1/img</path>
    </static>
    
    <!--  Custom Deplyment descriptor code
    <web-xml>
      <jee:web-app xmlns:jee="http://java.sun.com/xml/ns/javaee">
        <choose>
          <when test="$mode='test'">
            <jee:display-name>foo</jee:display-name>
          </when>
        </choose>
      </jee:web-app>
    </web-xml>
    -->
    
  </application>
  
</project-config>


      

As you can see, the configuration file consists of different sections: One for information about the project, one for configuring the Pustefix CMS, one for the server configuration and one for the application itself. The application consists of services and static resources. Please note that only one context-xml-service is allowed per project.

3.4.2. Page Configuration (depend.xml)

The depend.xml configuration file serves two purposes: First, it is used to create the hierarchical page structure of the project by defining a tree of pages. Then, it is used to define the internal structure of the pages by defining, for every single page, the tree of transformations that need to be applied to certain files to get the final stylesheet (which is the representation of the page in Pustefix). For an overview over the transformation aspect of the whole framework, please go here.

To make life a little easier, you can use convenience tags that are automatically transformed by the runtime system when the file is loaded.

Structure of the depend.xml

The structure of the config file is show below:

<make project="MyProject" lang="en" themes="ThemeA ThemeB ... default">
  <navigation>
    <page name="foo" handler="/xml/static" accesskey="F">
      <page name="sub_foo1" handler="/xml/static"/>
      <page name="sub_foo2" handler="/xml/static"/>
    </page>
    <page name="bar" handler="/xml/config">...</page>
    
    <!-- Configuration fragements are supported as well -->
    <config-include file="myproject/conf/myfile.xml" section="navigation"/>
  </navigation>

  <!--
    The global section allows to set default values for ALL pages defined via the
    standardpage tag (see below). It's possible to set default params, and runtime
    stylesheets (see here). It's also possible to add more runtime stylesheets or
    overwrite params in the standardpage tag for a single page.
  -->
  <global>
    <param name="AName" value="AValue"/>
    <include stylesheet="path/to/AStyleSheet"/>
    <!-- Stylesheets from module jars can be directly included by setting the module attribute. -->
    <!-- <include stylesheet="path/to/AStyleSheetFromModule" module="modulename"/> -->
  </global>

  <config-include file="myproject/conf/myfile.xml" section="targets"/>

  <!--
    The only other tags allowed besides the navigation tag are target, global,
    standardmaster, standardmetatags and standardpage. The latter three are only
    convenience tags that can be expressed fully in terms of target tags
    (Expanding those tags is one of the duties of the runtime transformation of
    the depend.xml file mentioned above).
  -->
  <target name="a_target_name.xsl" type="[xsl|xml]">...</target>
  <target name="another_target_name.xml" type="[xsl|xml]">...</target>...
  <standardmaster name="..."/>
  <standardmetatags name="..."/>
  <standardpage name="a_name" master="..."
                metatags="..." themes="..." variant="..."
                xml="a_base_xml_file.xml">
    ...
  </standardpage>
</make>

The <make/> tag

The <make> tag is the root element of the depend.xml

Table 3.2. Attributes of the <make> tag
Attribute Mandatory? Description
project mandatory The name of the project. This is the same as the corresponding entry in the project.xml.in file.
lang mandatory The default language of the project. This is the same as the value of the lang node's name attribute used in include parts.
themes optional

The attribute is a space separated list of theme names. It acts as a fallback queue of product branch names that should be checked in include parts to decide which branch to use. The least specific theme is always the "default" theme and therefore "default" should be the last theme in the list. The last theme in the list is used when a non-existing include part is created in the Pustefix CMS, so you can omit the "default" theme from the end of the list if you want to use another theme for newly created include parts. However the "default" theme will still be used as a fallback for existing include parts when no other matching theme variant of the include part exists. You should have at least a product branch named "default" in every include part to make sure to always have a valid fallback.

If it's not given, it defaults (in our example where the project name is "MyProject") to "MyProject default".

Note that this attribute only defines a global value, each target can define it's own themes list (see below for targets and their attributes).

The allowed characters for themes are: a-zA-Z0-9_+-

The <page/> tag

The <page> tag defines all available pages.

Table 3.3. Attributes of the <page> tag
Attribute Mandatory? Description
name mandatory The name of the page. This name is used throughout Pustefix to reference the page (e.g. when creating internal links and in other config files). The allowed characters for page names are: a-zA-Z0-9_+-
handler mandatory This attribute tells the system which servlet is used to handle requests for this page. You can think of the handler attribute as a project wide servlet "name" as defined in the project definition
accesskey optional This attribute defines a default access key that will be used by the pfx:button tag for the links it generates.

Target definition

The <target> tag is used to specify the XSL transformations in Pustefix. In most cases, you will not have to use the rather complex <target>, but use the convinience tags described in the section called “Standard page definition”, the section called “Standard master target definition” and the section called “Standard metatags target definition”.

Section 2.3.1, “XSL Targets” provides more information on the concept of targets in Pustefix.

<target name="baz.xsl" type="xsl" page="foo" variant="bar" themes="Theme_A Theme_B ... default">
  <!--
    depxml and depxsl reference other targets by their name attribute
    that serve as the XML resp. XSL input used to create this target
    via a XSL transformation. If for a given name attribute of either
    depxml or depxsl no other target definition is found, the transformation
    parent is supposed to be a leaf target and the name attribute is 
    interpreted as a path relative to the docroot.
  -->
  <depxml name="foo/xsl/bar.xsl"/>
  <depxsl name="foo/xsl/baz.xsl"/>

  <!--
    Additional dependencies
  -->
  <depaux name="foo/xsl/snarf.xsl"/>
  <depaux name="foo/xsl/fubar.xsl"/>

  <!--
    param tags supply XSL transformation parameters that are used when the target is generated.
  -->
  <param name="AName" value="AValue"/>
</target>

The <target> tag supports the following attributes:

Table 3.4. Attributes of the <target> tag
Attribute Mandatory? Description
name mandatory The name of the target. This name must be unique for the whole project (not the whole environment!)
type mandatory Must be xsl for a target that should be "compiled" into a templates object. Must be xml for every target that is used as input for a transformation.
themes optional This is just a local overwrite to the global themes attribute as explained on this page
page optional It must be set for any top level target (that means a target that is not itself used to generate other targets) that should be accessible via the page name. Note: having a non-toplevel target with a page attribute is considered an error.
variant optional It makes only sense when also a page attribute is set. This attribute will discriminate between targets that should be associated with the same page, but represent a differnt variant of this page.
Adding dependencies

<depaux> tags create user defined dependencies on the files they reference in their name attribute. Whenever the target generation system is asked for a target, all its dependencies are checked whether their modification time is older than the creation time of the target. Dependencies include by design the depxml and depxsl targets (which may be files in the case of a leaf target or another virtual target that returns its own creation time as the modification time) and all include files from which include parts are taken during the transformation of the target.

If any of these files or targets has been changed after the target was built, it is taken care of that the target is rebuild.

<depaux> just adds more dependencies "by hand" that are not automatically detected. In the example above, the file referenced is a XSLT stylesheets that's included via xsl:include into the foo.xsl stylesheet. Such external dependencies are not currently recognized automatically.

E.g. if you use a foo/xsl/fubar.xsl stylesheet that serves as a library of templates you want to include into foo.xsl, you need to add the following line to the target definition of foo.xsl to make the system recognize changes to foo/xsl/fubar.xsl.

<depaux name="foo/xsl/fubar.xsl"/>

Standard page definition

The standardpage tag is a convenience tag that encapsulates the typical definition of a complete page in the Pustefix system.

<standardpage name="BazPage" master="AName" metatags="AName" xml="MyProject/xml/FooBase.xml" themes="Theme_A Theme_B ... default" variant="foo">
  <!--
    Note: All the child nodes are optional (and in fact usually not needed)
  -->
  <include stylesheet="MyProject/xsl/runtime.xsl"/>
  <!-- Stylesheets from module jars can be directly included by setting the module attribute. -->
  <!-- <include stylesheet="xsl/runtimeFromModule.xsl" module="modulename"/> -->
  <param name="fubar" value="bar"/>
</standardpage>

The <standardpage> tag supports the following attributes:

Table 3.5. Attributes of the <target> tag
Attribute Mandatory? Description
name mandatory The name of the page. This must be a name already defined in a page tag in the navigation tree.
xml mandatory The name of a xml target to use as input for the "metatags transformation". Often this is a leaf target and one of the projects structural xml files.
module optional The name of the module from which the xml file should be loaded.
themes optional This attribute is a local overwrite of the global themes attribute explained here.
variant optional This attribute allows you to define variants of the same page. It's only possible to define variants of pages when there's already a "root" page, in other words a standardpage definition without the variant attribute. Variants also influence the local themes (in fact the visible aspect of variants is implemented in terms of themes).
master optional Default is to use the default definition of the master stylesheet (standardmaster without a name attribute).
metatags optional Default is to use the default definition of the metatags stylesheet (standardmetatags without a name attribute).

After performing the transformation of the depend.xml on loading (automatically done by the runtime system system) this becomes

<target name="BazPage::foo.xsl" type="xsl" themes="foo Target_A Target_B ... default" page="BazPage" variant="foo">
  <!--
    For every target that is only used in the generation of one single page
    (if you look at the example given here, this is true for the generated
    targets BazPage.xml and BazPage.xsl) you must give a parameter called page
    with the name of the resulting page as the value for the standard XSLT tags
    to be able to work correctly. They need this information e.g. to create links
    to other pages and many other things. While the standardpage tag does this
    automatically for you make sure that you don't forget it for target structures
    you define yourself.

    If the master attribute is not given, the depxsl will be master.xsl
  -->
  <depxml name="BazPage::foo.xml"/>
  <depxsl name="master-AName.xsl"/>
  <param name="page" value="BazPage"/>

  <!--
    parameters given to the standardpage tag are supplied to the first of the two
    transformations. The outputencoding parameter is inserted by the build system.
    Refrain from supplying this parameter on your own, unless you really know what
    you do. Changing the encoding should be done in the project.xml file.
  -->
  <param name="fubar" value="bar"/>
  <param name="outputencoding" value="UTF-8"/>

  <!--
    All include tags given are runtime stylesheets, given to the transformation via
    the parameter stylesheets_to_include (as a space separated list if multiple
    include tags are given). Note that the needed depaux nodes are inserted automatically.
  -->
  <param name="stylesheets_to_include" value="MyProject/xsl/runtime.xsl"/>
  <depaux name="/path/to/pustefix/projects/MyProject/xsl/runtime.xsl"/>
</target>

<target name="BazPage::foo.xml" type="xml" themes="foo Themes_A Themes_B ... default">

  <!--
    If the metatags attribute has not been given, the depxsl value is metatags.xsl  
  -->  
  <depxml name="MyProject/xml/FooBase.xml"/>
  <depxsl name="metatags-AName.xsl"/>

  <param name="fubar" value="bar"/>
  <param name="page" value="BazPage"/>
</target>

Standard master target definition

The standardmaster tag is a convenience tag that encapsulates the typical target definition of the master.xsl stylesheet.

<standardmaster name="AName">
  <!-- The name attribute is optional -->
  <include stylesheet="MyProject/xsl/skin.xsl"/>
  <!-- Stylesheets from module jars can be directly included by setting the module attribute. -->
  <!-- <include stylesheet="xsl/skinFromModule.xsl" module="modulename"/> -->
  <param name="AName" value="AValue"/>
</standardmaster>

After performing the transformation of depend.xml when the runtime system loads the file this becomes:

<target name="master-AName.xsl" type="xsl">
  <!--
    If the name attribute of the standardmaster tag has not been given,
    the value for the target's name attribute will be master.xsl.
  -->
  <depxml name="core/xsl/master.xsl"/>
  <depxsl name="core/xsl/customizemaster.xsl"/>
  <depaux name="/path/to/pustefix/projects/core/xsl/default_copy.xsl"/>
  <depaux name="/path/to/pustefix/projects/core/xsl/include.xsl"/>
  <depaux name="/path/to/pustefix/projects/core/xsl/utils.xsl"/>
  <depaux name="/path/to/pustefix/projects/core/xsl/navigation.xsl"/>
  <depaux name="/path/to/pustefix/projects/core/xsl/forminput.xsl"/>
  <depaux name="/path/to/pustefix/projects/sample1/conf/depend.xml"/>
  <param name="AName" value="AValue"/>
  <param name="docroot" value="/path/to/pustefix/projects"/>
  <param name="product" value="MyProject"/>
  <param name="lang" value="en"/>
</target>

Standard metatags target definition

The standardmetatags tag is a convenience tag that encapsulates the typical target definition of the metatags.xsl stylesheet.

<standardmetatags name="AName">
  <!-- The name attribute is optional -->
  <include stylesheet="MyProject/xsl/metatags.xsl"/>
  <!-- Stylesheets from module jars can be directly included by setting the module attribute. -->
  <!-- <include stylesheet="xsl/metatagsFromModule.xsl" module="modulename"/> -->
  <param name="AName" value="AValue"/>
</standardmetatags>

After performing the transformation of depend.xml when the runtime system loads the file this becomes:

<target name="metatags-AName.xsl" type="xsl">
  <!--
    If the name attribute of the standardmetatags tag has not been given,
    the value of the name attribute here becomes metatags.xsl.
  -->

  <depxml name="core/xsl/metatags.xsl"/>
  <depxsl name="core/xsl/customizemaster.xsl"/>
  <depaux name="/path/to/pustefix/projects/core/xsl/default_copy.xsl"/>
  <depaux name="/path/to/pustefix/projects/core/xsl/include.xsl"/>
  <depaux name="/path/to/pustefix/projects/core/xsl/utils.xsl"/>
  <depaux name="/path/to/pustefix/projects/MyProject/conf/depend.xml"/>
  <depaux name="/path/to/pustefix/projects/MyProject/xsl/metatags.xsl"/>
  <param name="stylesheets_to_include" value="MyProject/xsl/metatags.xsl "/>
  <param name="AName" value="AValue"/>
  <param name="docroot" value="/path/to/pustefix/projects"/>
  <param name="product" value="MyProject"/>
  <param name="lang" value="en"/>
</target>

3.4.3. ContextXMLService configuration file

The ContextXMLService handles requests for all pages (where page means some content generated by an XSL transformation). The name of the configuration file is usually service.conf.xml where "service" is replaced by the name from the URI of the service. For example the configuration of the service available at /xml/info should use a configuration file named info.conf.xml.

This service uses a configuration file that has a special syntax. However properties and customization in this file work nearly the same way as explained for the standard property definitions.

  <context-xml-service-config
    xmlns="http://www.pustefix-framework.org/2008/namespace/context-xml-service-config"
  >
    <global-config>
      <force-ssl>false</force-ssl>
        

force-ssl can be set to true in order to enforce a secure connection for all pages of this service. The whole node is optional and defaults to false.

      <defaultstate class="a.state.Class"/>
      <defaultihandlerstate class="another.state.Class"/>
      <!-- optional attribute for both elements: parent-bean-ref="..." -->
        

defaultstate and defaultihandlerstate are both optional. The class attribute must be given. a.state.Class should de a descendant of de.schlund.pfixcore.workflow.app.StaticState and another.state.Class should be a descendant of de.schlund.pfixcore.workflow.app.DefaultIWrapperState (unless you really know what you are doing). They are used to set the defaults for the state tag used when processing the pagerequest tag (see there for more info).

[Note]Note

As Pustefix creates a singleton-scoped Spring bean of the specified class for each page, which uses a default state, you can't inject dependencies using the Spring XML configuration. That's why Pustefix supports the referencing of parent bean definitions using the parent-bean-ref attribute. Thus it's possible to indirectly inject dependencies into the concrete instances by injecting them into the parent bean definition.

    </global-config>
    
    <context defaultpage="APageName" synchronized="true">
        

Attribute Description
defaultpage Either defaultpage attribute or defaultpage element must be set. Must reference a valid pagerequest.
synchronized Optional. Defaults to true. If set to true, only one request per session is handled concurrently. If set to false all requests will be handled concurrently, requiring thread-safe business logic.

      <defaultpage>
        <variant name="VARIANTNAME">PAGENAME</variant>
        ...
        <default>PAGENAME</default>
      </defaultpage>
        

The defaultpage element can be used if you want to define multiple defaultpages for different variants. [Since: 0.13.1]

      <resource class="A_Resource">
      <!-- optional attributes: bean-name="A_Name" scope="prototype|request|session|singleton"/> -->
        

class is mandatory, can be any Java class, that can be created with a default constructor. The scope attribute is optional and defines the scope in which the Spring bean representing the resource is instantiated (session scope by default). The bean-name attribute is optional and specifies the name of the Spring bean that is created for this resource. There may be multiple resource tags given.

        <implements class="A_Interface">
        

The whole implements node is optional. class is mandatory, must be a Java interface implemented by the resource. There may be more than one implements tag for a resource, but each interface must be unique in the whole context. In other words: it's possible for a resource to implement more than one interface, but not possible for one interface to be implemented by two resources used in the same Context definition.

        </implements>
        <properties>
        

The whole node is optional.

          <prop name="A_Name">A_Value</prop>
        

prop is mandatory and can be used multiple times. It's similar to the use as a child of pagerequest/properties, but used here to create properties that are related to a context resource implementation. The resulting property looks like this: context.resourceparameter.A_Resource.A_Name=A_Value Customization tags may be used around a property to make it depend on a certain makemode or other parameters.

        </properties>
      </resource>
    </context>
    
    <interceptors>
      <start>
        <interceptor class="mypackage.MyInterceptor"/>
        <interceptor bean-ref="myInterceptor"/>
      </start>
      <end> ... </end>
      <postrender> ... <postrender>
    </interceptors>
        

Within the interceptors section you can configure ContextInterceptors grouped by the according interception points (for details see Section 5.6, “ContextInterceptors”).

    <scriptedflow name="AName" file="path/to/scriptfile.xml"/>
        

There may be an arbitrary number of scriptedflow tags, but each one must have a unique name. Scripted flows are a special method to control a session and do automatic requests based on initial user input.

    <role name="A_ROLE"/>
    <condition id="A_CONDITION"/>
    <authconstraint id="AN_AUTHCONSTRAINT"/>
        

You can define an arbitrary number of roles, conditions and authconstraints here, for details see Section 6.4, “Authentication and authorization”.

    <pageflow name="AName" final="APageName" stopnext="true|false">
         

There may be multiple pageflow tags defined, but you need at least one (which must be referenced by the defaultflow attribute above). We only describe the normal case without using variants. See here for more information on how to handle variants of pageflows.

Attribute Description
name Mandatory. Must be a unique name.
final Optional, must reference a page with a valid pagerequest definition given in this property file. There may be many pageflows defined for a servlet. A page may well be used in more than one pageflow.
stopnext Optional, defaults to false. If given and true, the pageflow will stop at the next accessible page after the current page even if this page would normally be skipped in the workflow because it doesn't need any input.

      <flowstep name="AnotherPageName" stophere="true|false">
        

Attribute Description
name Mandatory. Must reference a valid pagerequest. Usually there are many flowsteps defined in a pageflow.
stophere Optional, if true the pageflow will stop at this step unconditionally if the submit originated from a step that's before this one in the pageflow. See also the stopnext attribute of the tag which is quivalent to specifying stophere="true" for every single flowstep.

        <oncontinue applyall="true|false">
        

This tag (which is optional) starts a sequence of test/action pairs. The tests are XPath expressions which work on the DOM tree as produced by the flowstep's associated state (note that the navigation is not inserted into the DOM tree at this stage, and the /formresult/formvalues and /formresult/formerrors paths are also not present). The pageflow system calls the tests whenever a state returns a ResultDocument (before it continues with other stuff e.g. a pageflow run). The applyall attribute is optional. If given and true, all actions with matching conditions are executed, if not given or false (the default) only the first action with a matching condition is executed.

          <when test="A_XPath_Expression">
        

The when tag contains the XPath expression to try in it's test attribute. If this attribute is omitted, the whole condition is considered to be true.

            <action type="jumpto" page="APage" pageflow="APageFlow">
        

The action tag denotes the FlowStepAction to execute. The type attribute is mandatory and defines the special action to use. The string jumpto denotes the special FlowStepAction de.schlund.pfixcore.workflow.FlowStepJumpToAction which is used to set the jumptopage (defined via the page attribute) and/or the jumptopageflow (defined via the pageflow attribute).

            </action>
          </when>
          <when test="A_XPath_Expression">
            <action type="A_FlowStepAction" somekey="somevalue">
        

If the type attribute is not jumpto, the value is interpreted as a class of type de.schlund.pfixcore.workflow.FlowStepAction. There can be an arbitrary number of additional attributes (somekey in this example) which are supplied as named parameters to the special FlowStepAction.

            </action>
          </when>
        </oncontinue>
      </flowstep>
    </pageflow>
    
    <pagerequest name="APageName" copyfrom="APageName">
        

Attribute Description
name Mandatory. It must be the name of a page defined in the corresponding depend.xml file.
copyfrom Optional. If given, and set to the name of a valid pagerequest, all configuration from this referenced pagerequest are used for the current page, disregarding all configuration that is made in this pagerequest. It's a plain and simple copy, no extending, no restricting!

      <force-ssl>true|false</force-ssl>
        

The node is optional. If given, and the content is set to true, the page will only run under SSL when jumped to via a link or a submit of form data. If the session currently does not run under SSL, the system will make sure to redirect to a secure session prior to handling the request. After a session is running under SSL, there is no way back (so all other pages will run securely regardless if they have a ssl node or not). You can wrap this tag within a customization element to force use of SSL only in certain modes (e.g. prod mode).

[Note]Note

You can force the servlet as a whole to run only under SSL by specifying the ssl subnode of the servletinfo node.

  <state class="AClassName"/>
  <!-- Alternative usage forms:
    <state class="..." bean-name="..." scope="..."/>
    <state class="..." parent-bean-ref="..."/>
    <state bean-ref="..."/> 
  -->
        

The whole node is optional. If given, the class attribute must be the name of a java class implementing the de.schlund.pfixcore.workflow.ConfigurableState interface. The used State is determined as follows:

  1. If state is given, use the value of it's class attribute. When no scope attribute is present, singleton-scope is used by default.

  2. If the pagerequest has an input child, use the value of the class attribute of the defaultihandlerstate tag explained above if it is given. If this is not given, just use de.schlund.pfixcore.workflow.app.DefaultIWrapperState. Else:

  3. use the value of the class attribute of the defaultstate tag explained above if it is given. If this is not given, just use de.schlund.pfixcore.workflow.app.StaticState.

You can use the scope attribute to specify the scope in which the Spring bean created for this page will be instantiated. You may specify the bean-name attribute to use a fixed name for the automatically created bean. You can use any BSF-supported scripting language for writing your State-implementation, too. Use script:path/to/script for the class attribute. Alternatively you can use an existing Spring bean that implements the de.schlund.workflow.State interface. Use the bean-ref attribute to specify the name of the bean. However the pagerequest may not contain any configuration if you are using a Spring bean.

[Note]Note

If you're referencing a custom Spring bean using bean-ref, Pustefix can't automatically inject the configuration. So if you're bean is extending the DefaultIWrapperState or StaticState it might not work as you expected (or not at all) due to the lack of configuration.

That's why Pustefix supports the referencing of parent bean definitions using the parent-bean-ref attribute. Thus it's possible to indirectly inject dependencies into the concrete instances by injecting them into the parent bean definition. So, despite the fact, that the beans are automatically created by Pustefix, you're able to inject your own dependencies using the Spring XML configuration.

      <finalizer class="AClassName"/>
        

The whole node is optional. It may only be given for a State that is either de.schlund.pfixcore.workflow.app.DefaultIWrapperState or a descendent of it. The class attribute is mandatory and denotes a class implementing de.schlund.pfixcore.workflow.app.ResdocFinalizer.

[Caution]Caution

The use of finalizers is not suggested most of the time! They can completely change the result document and the logic when to trigger the next step in the current page flow. Use them at your own risk. Or better: Don't use them at all.

      <input policy="ANY|ALL|NONE">
        

The whole node is optional. It may only be given for a State that is either de.schlund.pfixcore.workflow.app.DefaultIWrapperState or a descendent of it! policy is optional (default is ANY). The policy decides when a whole page is considered to be accessible:

  • ANY: just one of the associated handlers needs to be active for the page to be accessible.

  • ALL: all the associated handlers must be active for the page to be accessible.

  • NONE: none of the associated handlers needs to be active for the page to be accessible.

If one of the associated handlers returns false on calling prerequisitesMet(), the page is of course still inaccessible.

        <wrapper prefix="AName" class="AClassName" checkactive="true|false"/>
        

[Caution]Caution

Note: The tag name wrapper can also be called interface with the same allowed attributes for backwards compatibility reasons. This ambiguity may be removed in some future version.

There can be many wrapper nodes for a page. Each one references an "atomic" functional entity consisting of an IWrapper java class (usually autogenerated from a .iwrp xml file that defines the type and names of the parameters passed between the UI and the functional entity and an associated IHandler java class that uses the IWrapper to retrieve the passed parameters via typed getter methods. There may be an optional scope attribute, which specifies the scope in which the handler associated with the wrapper will be instantiated.

Attribute Description
prefix Mandatory. The prefix defines a name for the IWrapper and in effect a namespace for the IWrapper's parameters. If the prefix "bar" is defined for an IWrapper that contains a parameter called "Foo", the submitted HTTP parameter must be called bar.Foo.
class Mandatory. Must be the name of a java class implementing de.schlund.pfixcore.generator.IWrapper. This implicitly defines a de.schlund.pfixcore.generator.IHandler, as every IWrapper knows it's associated IHandler and can be queried for it.
checkactive Optional, default is true. The IHandler method isActive() is NOT called on handlers with checkactive set to false. In other words: the handler is ignored when the system tries to find out if the page is accessible or not. See also the comment for the policy attribute above.
[Caution]Caution

Replaces the activeignore attribute since version 0.13.1. You should be aware that setting activeignore to true now complies with setting checkactive to false. Support for the activeignore attribute will be removed in future versions.

      </input>
        

      <process>
        

The process node holds a list of actions, which can be referenced from the UI when submitting forms or using GET requests to transmitt data. These actions group IWrappers into two groups: those that should have their handleSubmittedData() method called, and those that should have their retrieveCurrentStatus() method called when a submit has been handled sucessfully (and the same page is redisplayed). The idea beind the latter is, that sometimes you want to update the submitted form data to some canonical form (e.g. adresses or similar), so you don't want to see the exact same input in the form elements as you have submitted it, but some changed values. In other cases, submitting data to one wrapper may change the values of the form elements of another wrapper - in this case the second wrapper needs to be listed under the <retrieve> node.

        <action name="a_name">
          <submit>
            <wrapper ref="a_prefix_1"/>
            <wrapper ref="a_prefix_2"/>
            ...
          </submit>
          <retrieve>
            <wrapper ref="a_prefix_1"/>
            <wrapper ref="a_prefix_X"/>
            ...
          </retrieve>
        </action>
        <action name="another_name">
        ...
        </action>
      </process>
      
      <output>
        

The whole node is optional. Every page using a State that is itself or a descendant of de.schlund.pfixcore.workflow.app.StaticState can use this. You can have as many resource childnodes as you like.

        <resource node="AName" class="AClassName"/>
        

Attribute Description
class Mandatory (if bean-ref is not present). class is one of the ContextResources defined via implements above.
bean-ref Mandatory (if class is not present). Specifies the bean name of the resource that should be included in the output tree.
node Mandatory. node is the node in the output tree ("/formresult/AName") under which the ContextResource inserts it's data.

      </output>
      
      <properties>
        

The whole node is optional.

        <prop name="APropertyKey">AValue</prop>
        

The node is mandatory and can be used multiple times. It will be transformed into a java property that is associated to the page. There are some props that are already defined for de.schlund.pfixcore.workflow.app.StaticState and descendants. These are listed below

Property Name Property Value Description
mimetype e.g. text/css If given, sets the mimetype of the HttpResponse object to something else than the default text/html. This is most often used for text/css.
responseheader.A_HEADER A_VALUE If given, set the header A_HEADER of the HttpResponse object to A_VALUE. NOTE: the Pustefix system uses a set of default headers that are only used, when no user defined headers are given! The set of default headers is: Expires=Mon, 26 Jul 1997 05:00:00 GMT Cache-Control=private If you want to use some of them in addition to your own headers, you must manually supply them, too.

      </properties>
    </pagerequest>
    
    <config-include file="myproject/conf/myfile.xml" section="pagerequests"/>
        

Includes a part of a config fragments file at this location. See Section 3.4.6, “Configuration Fragments” for details on how to define config fragments.

Attribute Description
file Mandatory. Path to the file that contains the tags to be included (relative to docroot).
section Optional. Type of the section that shall be included. If more than one section of the specified type exists in the file, the content of all this sections is included.
refid Optional. Include a section identified by the specified id. The refid specified here must match the id attribute of exactly one section in the specified file.
xpath Optional. A XPath expression specifying the node-set to be included. The prefixes to be used for XML namespaces are "fr" for the namespace of the fragments file tags and "pr" for the namespace of the ContextXMLServlet configuration tags.

One and only one of the section, refid or xpath attribute has to be specified for each config-include.

    <properties>
      <prop name="AProperty">AValue</prop>
        

Property Name Property Value Description
mimetype e.g. text/css If given, sets the mimetype of the HttpResponse object to something else than the default text/html. This is most often used for text/css.
responseheader.A_HEADER A_VALUE If given, set the header A_HEADER of the HttpResponse object to A_VALUE. Headers set here can be overwritten for specific pages. NOTE: the Pustefix system uses a set of default headers that are only used, when no user defined headers are given! The set of default headers is: Expires=Mon, 26 Jul 1997 05:00:00 GMT Cache-Control=private If you want to use some of them in addition to your own headers, you must manually supply them, too.

You can also specify properties here that are understood by the AbstractPustefixRequestHandler and AbstractPustefixXMLRequestHandler classes.

    </properties>
  </context-xml-service-config>
        

3.4.4. DirectOutputService configuration file

Occasionally you don't want to generate output with an XSLT Transformation, but e.g. deliver binary content directly to the output stream instead. In this case you can use the DirectOutputService. The name of the configuration file is usually service.conf.xml where "service" is replaced by the name from the URI of the service. For example the configuration of the service available at /xml/info should use a configuration file named info.conf.xml.

The service knows about one or many directoutputpagerequests. For the XML/XSLT side of things, they look like normal pages (in fact, the value of the directoutputpagerequest's name attribute must be a page defined in the navigation section of depened.xml. Of course, no target definition has to be given, only the page in the navigation structure must exist). But other than the usual pagerequest, a directoutputpagerequest has an associated directoutputstate whose class attribute is a java class implementing de.schlund.pfixcore.workflow.app.DirectOutputState.

  <direct-output-service-config
    xmlns="http://pustefix.sourceforge.net/2004/properties"
  >    
    <global-config>
      <force-ssl>false</force-ssl>
        

See the comment for the global-config node in Section 3.4.3, “ContextXMLService configuration file”.

    </global-config>
    
    <authconstraint ref="AN_AUTHCONSTRAINT"/>
         

You can reference an authconstraint from the context configuration, which has to be fulfilled to access a page. This default authconstraint can be overridden for single pages. If no default authconstraint is set here, the context's default authconstraint will be used. If no authconstraint is set at all, a page requires no authentication.

    <config-include file="myproject/conf/myfile.xml" section="directoutputpagerequests"/>
         

Includes a part of a config-fragments at this location. See Section 3.4.6, “Configuration Fragments” for details on how to define config fragments.

Attribute Description
file Mandatory. Path to the file that contains the tags to be included (relative to docroot).
section Optional. Type of the section that shall be included. If more than one section of the specified type exists in the file, the content of all this sections is included. For a DirectOutputServlet configuration only directoutputpagerequests and properties are valid.
refid Optional. Include a section identified by the specified id. The refid specified here must match the id attribute of exactly one section in the specified file.
xpath Optional. A XPath expression specifying the node-set to be included. The prefixes to be used for XML namespaces are "fr" for the namespace of the fragments file tags and "d" for the namespace of the DirectOutputService configuration tags.

One and only one of the section, refid or xpath attribute has to be specified for each config-include.

    <directoutputpagerequest name="APageName">
      <directoutputstate class="AClassName"/>
        

The class specified for the directoutputstate must implement the de.schlund.pfixcore.workflow.DirectOutputState interface. The tag may have an optional scope attribute which specifies the scope in which the corresponding state should be instantiated. There may also be an optional bean-name which, if present, will be used as the name of the Spring bean created for this direct output state. Instead of the class attribute, you may specify a bean-ref attribute which has to reference a Spring bean defined in the spring.xml file for this project. In this case, no Spring bean will be created but the existing bean will be used instead.

      <authconstraint ref="AN_AUTHCONSTRAINT"/>
        

You can optionally reference an authconstraint from the context configuration to override the default authconstraint.

      <properties>
        

The whole properties node is optional.

        <prop name="APropertyKey">AValue</prop>
        

The node is mandatory and can be used multiple times. It will be transformed into a java property that is associated to the page. The java property that is constructed will look like this: pagerequest.APpageName.APropertyKey=AValue where APageName is the value of the name attribute.

      </properties>
    </directoutputpagerequest>
  </direct-output-service-config>
        

3.4.5. WebServices

The configuration of AJAX / webservices is described in the corresponding section.

3.4.6. Configuration Fragments

Configuration fragments files contain aggregated configuration directives that are intended to be reused in different configuration files.

<fr:config-fragments
  xmlns:fr="http://pustefix.sourceforge.net/configfragments200609"
  xmlns:c="http://www.pustefix-framework.org/2008/namespace/context-xml-service-config"
  xmlns:d="http://www.pustefix-framework.org/2008/namespace/direct-output-service-config"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://pustefix.sourceforge.net/configfragments200609 http://pustefix.sourceforge.net/configfragments200609.xsd">
  
  <fr:navigation id="nav1">
      

All sections have an optional id that can be used to identifiy the section when more than one section fo the same type is present in one file. The value of the id attribute has to be unique within the whole file.

    <page name="MyPage" handler="/xml/myhandler"/>
      

The structure here is the same as within the navigation tag of the depend.xml file.

  </fr:navigation>
  <fr:targets>
    <standardpage name="MyPage" xml="myproject/xml/mymaster.xml"/>
      

The tags allowed here are the same that are allowed for standardpage or target definitions in the depend.xml file.

  </fr:targets>
  <fr:resources>
    <c:resource class="com.example.MyResourceImpl">
      <pr:implements class="com.example.MyResource"/>
    </c:resource>
      

The tags allowed here are the same that are allowed for the definition of context resources within the context tag of the ContextXMLServlet configuration.

  </fr:resources>
  <fr:interceptors>
    <c:interceptor class="com.example.MyInterceptor"/>
      

The tags allowed here are the same that are allowed within the start, end and postrender interceptor tags of the ContextXMLServlet configuration (for details also see Section 5.6, “ContextInterceptors”).

  </c:interceptors>
  <fr:scriptedflows>
    <c:scriptedflow name="myscript" file="myproject/conf/scriptedflows/myscript.script.xml"/>
      

The tags allowed here are the same that are allowed within the scriptedflows tag of the ContextXMLServlet configuration.

  </fr:scriptedflows>
  <fr:roles>
    <c:role name="MY_ROLE">
      <c:pageaccess names="mypage*"/>
    </c:role>
      

The tags allowed here are the same that are used for role definition in the ContextXMLServlet configuration.

  </fr:roles>
  <fr:pageflows>
    <c:pageflow name="MyFlow">
      <c:flowstep name="MyFirstPage"/>
      <c:flowstep name="MySecondPage"/>
    </c:pageflow>
      

The tags allowed here are the same that are used for the definition of pageflows in the ContextXMLServlet configuration.

  </fr:pageflows>
  <fr:pagerequests>
    <c:pagerequest name="MyPage"/>
      

The tags allowed here are the same that are used for the definition of pagerequets in the ContextXMLServlet configuration.

  </fr:pagerequests>
  <fr:properties>
    <pr:prop name="myproperty">myvalue</pr:prop>
      

The tags allowed here are the same that are allowed within the properties tag of the ContextXMLServlet configuration.

  </fr:properties>
  <fr:directoutputpagerequests>
    <d:directoutputpagerequest name="foo">...</d:directoutputpagerequest>
      

Direct output pagerequests can be defined here. See Section 3.4.4, “DirectOutputService configuration file” for details on this.

  </fr:directoutputpagerequests>
</fr:config-fragments>
        

3.5. Spring configuration and customization

Pustefix is based on Spring MVC and uses its DispatcherServlet to bootstrap the ApplicationContext on webapp startup. It configures its own ApplicationContext implementation by passing the PustefixWebApplicationContext class as contextClass init parameter in the webapp's web.xml configuration file.

The configuration file locations are passed to the DispatcherServlet using the standard contextConfigLocation init parameter. By default Pustefix passes the Pustefix configuration file myproject/conf/project.xml and, if exisiting, the file myproject/conf/spring.xml, which is intended to contain a standard Spring XML bean configuration.

3.5.1. Customizing the Spring configuration

Spring supports the externalization of property values from Spring XML configuration files into separate standard java property files. Pustefix extends this mechanism by adding support for the Pustefix XML property file format, which let's you use the choose/when-customization and buildtime property capabilities known from other Pustefix configuration files, like factory.xml, for Spring properties too.

Therefor Pustefix by default registers a Spring PropertyPlaceholderConfigurer, which looks for a Pustefix XML property file under myproject/conf/spring-properties.xml and a PropertyOverrideConfigurer, which looks under myproject/conf/spring-properties-override.xml.

The following example shows the two ways you can externalize property values:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans">

  <bean id="mybean1" class="mypackage.MyBeanClass">
    <property name="text" value="${default.text}"/>
  </bean>

  <bean id="mybean2" class="mypackage.MyBeanClass">
    <property name="text" value="This is the default text"/>
  </bean>

</beans>

The first bean uses a property placeholder, the second bean already supplies a default value, which should be overwritten by an externalized value.

The following spring-properties.xml file configures the value for the first bean using the Pustefix customization mechanism to provide a mode-dependent value for the property placeholder:

<?xml version="1.0" encoding="UTF-8"?>
<properties 
    xmlns="http://www.pustefix-framework.org/2008/namespace/properties-config" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.pustefix-framework.org/2008/namespace/properties-config ../../core/schema/properties-config.xsd">
    
    <choose>
      <when test="$mode='prod'">
        <property name="default.text">I'm in production mode</property>
      </when>
      <otherwise>
        <property name="default.text">I'm in development mode</property>
      </otherwise>
    </choose>

</properties>

The following spring-properties-override.xml file overrides the value for the second bean by using the format beanName.property as property name. It also shows how you can use the available buildtime properties (like docroot, fqdn, mode) within a property value:

<?xml version="1.0" encoding="UTF-8"?>
<properties 
    xmlns="http://www.pustefix-framework.org/2008/namespace/properties-config" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.pustefix-framework.org/2008/namespace/properties-config ../../core/schema/properties-config.xsd">
    
    <property name="mybean2.text">I'm in ${mode} mode</property>

</properties>

If you want to register your own PropertyPlaceholderConfigurer or PropertyOverrideConfigurer capable of the Pustefix XML property format, e.g. for tests or child ApplicationContexts, you can do so by creating a PustefixPropertiesPersister bean and referencing it from the configurer's propertiesPersister property.