Standalone using Spring

TODO: This description is out-of-date. Update it!

Danube can be invoked as standalone server using the Spring Framework for configuration. Class StartLocalServer loads the server.xml configuration file from the current directory or one specified using the -d option. Then if extra parameters are set they are used as the names of beans that will be expected to be of Service interface type, and methods create() and start() will be invoked for each of them. If no arguments are passed then a bean assigned with the name server will be used.

Here is an sample configuration file used for a Spring WebFlow and Velocity integration example:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<!--
 * Copyright (c) 2005-2006 Creative Sphere Limited.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the LGPL licence
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/copyleft/lesser.html
 *
 * Contributors:
 *
 *   Creative Sphere - initial API and implementation
-->
<beans>
    <!--
     * Here we are setting up the framework mechanism.
     * First, there must be a bean called "server" of Service type. We are using ServerSocketService
     * Then it needs to know what is processing requests. HttpServerConnectionHandler is used for it.
     * HttpServerConnectionHandler has one, 'context', prefix defined to reference our 'application'.
     * For 'application', an ApplicationSeparator is used. ApplicationSeparator is just loading another context
     * to pass control to it.
    -->

    <!--
     * This is our service. It is named "Danube", runs on port 8080, has initial socket timeout of 1000ms and
     * uses httpServerConnectionHandler for processing requests.
    -->
    <bean name="server" class="org.abstracthorizon.danube.service.ServerSocketService">
        <property name="name"><value>Danube</value></property>
        <property name="port"><value>8080</value></property>
        <property name="serverSocketTimeout"><value>1000</value></property>
        <property name="newSocketTimeout"><value>60000</value></property>
        <property name="connectionHandler"><ref bean="httpServerConnectionHandler" /></property>
    </bean>

    <!--
     * This handler checks for 'context' prefix "/velocity-example" and if request is passed to that path
     * it is then handled by 'application' "webflow-velocity-example"
     * More contexts can be added to this bean.
    -->
    <bean name="httpServerConnectionHandler" class="org.abstracthorizon.danube.http.HTTPServerConnectionHandler">
    <property name="components">
        <list>
            <bean class="org.abstracthorizon.danube.http.matcher.Prefix">
                <property name="prefix"><value>/velocity-example</value></property>
                <property name="connectionHandler"><ref bean="webflow-velocity-example"/></property>
            </bean>
        </list>
    </property>
    </bean>

    <!--
     * This is not application (connection) handler - but simple 'connector' from this xml definition file to
     * another. It defines another Spring application context and name of the bean to pass control (handling of the request) to.
     * In this case application context is defined under bean named "webflow-velocity-application-context" and name of the bean to be used from
     * it is "web-application".
    -->
    <bean name="webflow-velocity-example" class="org.abstracthorizon.danube.http.spring.ApplicationSeparator" init-method="init">
        <property name="applicationContext"><ref bean="webflow-velocity-application-context"/></property>
        <property name="beanName"><value>web-application</value></property>
    </bean>

    <!--
     * This is ResourceXmlApplicationContext application context set up. It is same as simple
     * Spring FileSystemXmlApplicationContext which loades resources from the directories (paths)
     * xml definition files residing in. It reads the file from given resource in constructor.
    -->
    <bean name="webflow-velocity-application-context" class="org.abstracthorizon.danube.http.spring.ResourceXmlApplicationContext">
        <constructor-arg><value>.</value></constructor-arg>
        <constructor-arg><value>web-application.xml</value></constructor-arg>
    </bean>
</beans>


Definitions found here correspod to what was explained in the previous chapter (Standalone configuration ) except that there is one more new class: ApplicationSeparator . It is used instead of the include statement. This class is actually a ConnectionHandler and it needs applicationContext and beanName as properties. It extracts a bean with a given name from a given application context and assumes it too is of the ConnectionHandler inteface type and passes control to it. With that, a class configuration of different "application contexts" can be defined in different xml files, for example.

In this case, the example's context is defined using a webflow-velocity-application-context bean that is really a FileSystemXmlApplicationContext which loads definitions from a file with the name "web-application.xml". Note: for this example to work the current directory must be the one that contains both "server.xml" and "web-application.xml" files.

And here is the content of the "web-application.xml" file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<!--
 * Copyright (c) 2005-2006 Creative Sphere Limited.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the LGPL licence
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/copyleft/lesser.html
 *
 * Contributors:
 *
 *   Creative Sphere - initial API and implementation
-->
<beans>
    <!--
     * This file defines the beans 'application'.
     * First bean's name in here is specified in "server.xml" and has to be of "ConnectionHandler" type.
     * When server gets request with 'context' path prefix (as specified in "server.xml") then control is
     * passed in here.
     * First bean, then, references components defined for this application. Rest of the file defines those
     * components or auxiliary beans.
    -->

    <!--
     * This bean defines beans application context.
     * It references MVC controller defined at the "/guess.do" path.
    -->
    <bean name="web-application" class="org.abstracthorizon.danube.http.HTTPContext">
        <property name="components">
            <list>
                <bean class="org.abstracthorizon.danube.http.matcher.Prefix">
                    <property name="prefix"><value>/guess.do</value></property>
                    <property name="connectionHandler"><ref bean="guess.do"/></property>
                </bean>
            </list>
        </property>
    </bean>

    <!--
     * This is MVC controller that has Spring WebFlow as a controller and Velocity as a view adapter.
    -->
    <bean name="guess.do" class="org.abstracthorizon.danube.http.HTTPMVCConnectionHandler">
        <property name="controller"><ref bean="webFlowController" /></property>
        <property name="view"><ref bean="velocityViewAdapter" /></property>
    </bean>

    <!--
     * This is WebFlow controller. Flow locator is defined through flow registry bean and
     * "bean-explorer-flow" is set as defualt flow id
    -->
    <bean name="webFlowController" class="org.abstracthorizon.danube.webflow.DanubeFlowController">
        <property name="flowLocator"><ref bean="flowRegistry" /></property>
        <property name="defaultFlowId"><value>guess-flow</value></property>
    </bean>

    <!--
     * Flow registry defines where flow definitions are to be read from.
    -->
    <bean id="flowRegistry" class="org.springframework.webflow.registry.XmlFlowRegistryFactoryBean">
      <property name="flowLocations" value="guess-flow.xml"/>
    </bean>

    <!--
     * This is Velocity view adapter.
     * It defines directory "templates" as location of templates.
    -->
    <bean id="velocityViewAdapter" class="org.abstracthorizon.danube.velocity.spring.VelocityViewAdapter" init-method="init">
        <property name="templatesLocation"><value>templates</value></property>
    </bean>


    <!--
     * This part of the file defines WebFlow's controllers as defined in the given flow(s) ====================================================================-
    -->

    <!--
     * This controller is responsible for obtaining the name of the player
    -->
    <bean id="NameController" class="org.springframework.webflow.action.FormAction">
        <property name="formObjectName"><value>nameForm</value></property>
        <property name="formObjectClass"><value>org.abstracthorizon.danube.example.webflowvelocity.NameForm</value></property>
        <property name="formObjectScope"><value>FLOW</value></property>
    </bean>

    <!--
     * This controller is used for guessing process
    -->
    <bean id="GuessController" class="org.abstracthorizon.danube.example.webflowvelocity.GuessController">
        <property name="formObjectName"><value>guessForm</value></property>
        <property name="formObjectClass"><value>org.abstracthorizon.danube.example.webflowvelocity.GuessForm</value></property>
    </bean>
</beans>