Previous examples show how Nucleus creates and initializes components from properties files. Nucleus also allows components to point to each other through configuration file properties.
For example, a Weather
component might be defined in Nucleus, and the Person
component needs a pointer to that Weather
. The Weather
class might look like this:
public class Weather { String currentWeather; public Weather () { System.out.println ("constructing Weather"); } public String getCurrentWeather () { return currentWeather; } public void setCurrentWeather (String currentWeather) { System.out.println ("setting currentWeather to " + currentWeather); this.currentWeather = currentWeather; } }
This example requires instantiation of a Nucleus Weather
component, /services/Weather
. You should compile the Weather
Java class and create a Weather
class component with a Weather.properties
file in the same directory as Person.properties
. The properties file might look like this:
$class=Weather
currentWeather=sunny
Next, modify the Person
class so it defines a property that is set to a Weather
component:
public class Person { String name; int age; Weather weather; public Person () { System.out.println ("constructing Person"); } public String getName () { return name; } public void setName (String name) { System.out.println ("setting name to " + name); this.name = name; } public int getAge () { return age; } public void setAge (int age) { System.out.println ("setting age to " + age); this.age = age; } public Weather getWeather () { return weather; } public void setWeather (Weather weather) { System.out.println ("setting weather to " + weather.getCurrentWeather()); this.weather = weather; } }
Finally, modify the Person
component’s properties file so it has a weather
property that points to the weather
component:
$class=Person
name=Stephen
age=20
weather=Weather
If you include the Person
component as an initial service (described in the earlier section Starting a Nucleus Component), when you start your application, the Person
component is created and initialized. Its name
and age
properties are set from the values found in the properties file. In order to set the weather
property, Nucleus resolves the name Weather
by creating and initializing the Weather
component before assigning it to the Person
property. The output should look something like this:
constructing Person setting name to Stephen setting age to 20 constructing Weather setting currentWeather to sunny setting weather to sunny
The first two lines of the output show that Nucleus created the /services/Person
component and set the age
property. Then Nucleus attempts to set the weather
property. In doing so, it searches for the component named Weather
. This is a relative name, and so it is resolved relative to the current context /services
, resulting in /services/Weather
.
Nucleus searches its existing components and, finding that there is no /services/Weather
, it tries to create one from the configuration file services/Weather.properties
. This causes Nucleus to construct an instance of the Weather
class and initialize its currentWeather
property, thereby resulting in the third and fourth lines of output.
Now that a /services/Weather
component is created and initialized, Nucleus can initialize the rest of the Person
component, by setting its weather
and name
properties. This results in the last two lines of output.
Nucleus does not limit the number of components that refer to each other through properties. For example, component 1 can refer to component 2, which refers to component 3, and so on. Nucleus can even resolve circular references without spiraling into infinite loops. For example, component 1 might have a property that points to component 2, which has a property that points back to component 1. However, you should try to avoid circular references as they can result in deadlocks. See Enabling Deadlock Detection for information about avoiding deadlocks.
Application errors can also occur if you reference a property of a component before that component is completely configured. To diagnose this type of error, set the loggingInfo
property of the /
Nucleus service to true
, and the Oracle ATG Web Commerce platform prints information messages for this situation.
Arrays of components can also be specified in the same way that other array values are specified: as a comma-separated list. For example, the Person
component might have a property called cityWeathers
that contains an array of Weather
components:
public Weather [] getCityWeathers ();
public void setCityWeathers (Weather [] cityWeathers);
This property might be initialized in the configuration file like this:
cityWeathers=\ /services/weather/cities/atlanta,\ /services/weather/cities/boston,\ /services/weather/cities/tampa,\ /services/weather/cities/phoenix
Nucleus handles this by finding each of the components in the list, arranging the found components into a 4-element array, then assigning that array to the cityWeathers
property of the Person
component.