Userguide

Intro

There exists different views toward a framework. At first steps the framework is introduced to application developers showing howto create a dyncamically loadable application, that will be startet using the Starter-app part of the framework.

Here I'd like to focus and explain the internal view. What needs to be done to customize the starter or how can I create a new system service ...

If you're looking for more complex samples, take a look at VdrAssistant. Even if you don't care about the usecase of the app - it shows nearly every technique that is possible with SR-JRC and shows the key features, that make SR-JRC framework different!

All system services can be managed by the desktop application, so each service can be startet or stopped and the list shows the actual state.

Setup

The Application-Starter is highly configurable, customizable but before starting over to configuration I'd like to explain, how things work together.

Base of configuration is a XML-file, the so called ApplicationContext. This context has been taken from springframework and looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 ...
<beans>
Notate a configuration by XML is nothing special. Thats what other DI-implementation could bet. Only the very flexible placeholder-manager makes this variant of configuration unbeatable!

Placeholder Management

A placeholder from ApplicationContext is like a java variable, which means, the value will be determined at runtime at processing definitions from ApplicationContext.

This technique has been taken from springframework too, but I extended the flexibility by one level. A placeholder usage from ApplicationContext looks like:

<bean id="dsConfig" class="de.schwarzrot.app.config.DSConfig">
    <property name="defaultAutoCommit" value="false" />
    <property name="dsUser" value="${de/schwarzrot/app/config/SystemDefault/dsUser}" />
    <property name="dsPassword" value="${de/schwarzrot/app/config/SystemDefault/dsPassword}" />
</bean>
which means, a placeholder looks like a bash variable: ${...}. From ApplicationContext the name of a placeholder will be taken as java resource path, which could be resolved using different levels ...

First the ApplicationContext needs to know, who is responsable to resolve the placeholders:

<bean id="placeHolderConfigurer" class="de.schwarzrot.data.access.pref.PreferencesConfigurer">
    <property name="locations" value="de/schwarzrot/app/base/vdrassistant.properties" />
    <property name="searchSystemEnvironment" value="true" />
    <property name="systemPropertiesMode" value="2" />
    <property name="applicationName" value="VDRAssistant" />
    <property name="schemaName" value="va" />
</bean>

resolve by application properties

The placeholder-resolver takes a path of a properties file as parameter. This file is the first level of placeholder resolution. This file is part of the framework and offers some reasonable defaults, like the database type.

But a DataSource needs a username and password to connect a database. No framework can imagine the values, a potential user will use at database creation time. So these values can be considered of being wrong.

So the application needs the possibility to overwrite placeholder values.

resolve by java preferences

Java preferences are very handy to save local, user dependant settings, that could not or should not be stored into a database.

Preferences distinct between system and user preferences. Any desktop application should consider system preferences as readonly. To change a system preferences the application must run at privileged level (i.e. use a superuser authorization) like an installer.

To cut off the dualism of the preferences from application, SR-JRC introduces an abstraction level, which handles the dualism internally that way, that on reading a preferences it reads user-preferences. Only if no user-preferences exists for the given key, the system preference will be read.

resolve by system properties

Some placeholders makes sense to get overwritten at runtime by passing parameters to the JVM of the application starter. That's what system properties are for. Other values should be protected against overriding the value by usage of system properties.

For that purpose the placeholder-manager gets a parameter "systemPropertiesMode":

  • 0 == Never - means this value can't be changed by system properties
  • 1 == Default - means values from system properties will be used as default, so this value will be taken into account, when no other level of resolution leads to a valid value.
  • 2 == Override - no matter whether other resolutions lead to a valid value, the value from system properties will be used.