The preceding examples demonstrated how Nucleus can create and initialize components from properties files. While this is itself a powerful function, the true power of Nucleus is its ability to allow components to point to each other through configuration files.

The easiest way to get components to point to each other is through properties. For example, say that a Weather component is 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;
  }
}

For this example, we need an instance of Weather in Nucleus, called /services/Weather. This means that 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. Note that, as with any Nucleus component, you can create /services/Weather either with the ATG Control Center’s Generic Component Wizard, or by writing a properties file like this:

$class=Weather
currentWeather=sunny

Now modify the Person component to contain a property that points to the Weather:

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, the Person component must be modified so that it has a weather property that points to the weather component:

$class=Person
name=Stephen
age=20
weather=Weather

If you have included the Person component as an initial service (as described in the Starting a Nucleus Component section in this chapter), then, when you start your application, the Person component will be created and initialized. Its name and age properties will be set from the values found in the properties file. But to set the weather property, Nucleus must resolve the name Weather. In doing so, Nucleus ends up creating the Weather component and initializing that component before assigning it to the Person property. The output should look something like this:

constructing Person
setting age to 20
constructing Weather
setting currentWeather to sunny
setting weather to sunny
setting name to Stephen

The first two lines of the output show that Nucleus has created the /services/Person component and has 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 attempts to create one from the configuration file found in 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 has been created and initialized, Nucleus can go on to 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 put a “nesting limit” on the number of components that may refer to each other through properties. For example, component 1 may refer to component 2, may refer to component 3, etc. Nucleus also allows circular references. For example, component 1 may have a property that points to component 2, which may have a property that points back to component 1. In fact, component 1 may have a property that points back to itself. Nucleus handles these circular cases without spiraling into infinite loops.

Application errors can sometimes occur, however, 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 ATG platform will print 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 may 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.

 
loading table of contents...