JeeWiz Home  
The Model-Driven System Builder

JeeWiz Architect's Guide
 
Contents  >   7.  Finding Values and Files
 


7.5 component.properties

Each model object can get property values from a 'component.properties' file. This file resides in the meta-class's directory below the template directory.

For example, the Hibernate entity's template directory is jeewiz/resources/hibernate/control/entity, so the J2EE application's component.properties is at jeewiz/resources/hibernate/control/entity/component.properties.

The format of this file is similar to a Java properties file (see the Java java.util.Properties class): each line has a key=value pair (with the value being optional, which will set the key to map to a zero-length value). The name-value pair mapping is set into a default HashMap held for each model object. This means it can be read (via '$object.key').


7.5.1  Rules for component.properties
The rules for component.properties are:
  1. The syntax is one property 'name=value', or #comment, per line - standard Java properties file syntax.
  2. Substitution is allowed using ${x}, where 'x' is a known property or getter. Note that the '{}' braces are required after the $.
  3. If the right-hand side, after the '=', consists solely of a substitution like '${x}' or '${x.y}, then the property becomes a reference to the object 'x'; otherwise, the property is a string value. In particular, this means you can say
    theApplication=${this}
    
    and 'theApplication' will be a reference to the current object rather than just its 'toString()' value. You can then get or set properties on these objects using normal substitution in Velocity or Ant. Getting properties is simple: just say, e.g., '${theApplication.name}'. In Velocity, to set a property that does not have a Java getter, say e.g.
    #set( $x=$theApplication.put( "hasAutoTestMethods", "true" ) )
    
    The '$x=' is just a dummy to satisfy the syntax of the set command. The 'put' method is gives access to the HashMap that is available on each object for extra properties.
  4. One level of object reference is also allowed, as in $object.property. This will look up the property on the object.
  5. Declaration order is observed. This means that references to properties set in previous lines of the same properties file are specifically allowed and will be evaluated as expected.

    This is noteworthy because normally properties in standard Java Property files are evaluated in random order, which can lead to unexpected results. Because your specification order is preserved by JeeWiz, you can set a property based on some calculation, and then later on use that value in another property-setting calculation. For example, the system.properties file for the J2EE model uses sequences like this, which first sets specDir and then uses it to calculate other property values.
    specDir=${assemblyDir}
    source=${specDir}/src
    
    However, you cannot specify the same property twice in the same file and get two calculations done: only the last value for any property is used.
  6. When substitutions are done, the current model object has been instantiated, its values have been set from the XML specification and the '$this' and '$parent' properties have been set.

    This means for example you could use '${name}' to pick out the current object's name, or '${parent.name}' to pick out the parent's name. You can also reference properties defined in the system.properties files from any of the template directories for this build, or any properties defined by the top-level build job.

    For example, jeewiz/resources/java/control/system.properties sets the projectDir and the buildContainerDir properties to the base directory for the build. These values are then used to define the location of a build in jeewiz/resources/java/control/jar_assembly/component.properties, which sets the buildDir property based on buildContainerDir.

    This facility also applies to property-like methods on model objects; these are methods that begin with 'get', take no parameters and are public. For example, fields, methods and classes have a public 'getStaticText()' method. This returns "static " if the object is static or "" if not. This is used in component.properties via '${staticText}' to create declaration snippets.

    We follow the Java Beans convention, that the letter after 'get' in the method is capitalised - getStaticText() rather than getstaticText() - but the property's first character is lower case - staticText rather than StaticText. The case of the first letter is not significant when accessing such properties, so '${StaticText}' has the same effect as '${staticText}'. However, the case of the first letter in the target method is important - upper case is required. The remainder of a property name is case-sensitive: ${statictext} won't find the 'getStaticText()' method because the last 't' is the wrong case.

  7. The values are always set on the current object, even though substitution values may come from a parent object. This means that it is possible to re-use names without conflict, as discussed below. For example, you can say the following:
    src=${src}/${name}
    This sets our source location ${src} to one directory down from the parent's ${src}.
  8. JeeWiz first tries to put the values into attributes on the model object if they exist as properties in the meta-model (or as public setter methods - setProperty( "value" ) - following the JavaBean convention). If the property is not available via a method on the meta-class, the value is put into a HashMap attached to the model object. This approach is consistent with the way properties are read: first a value is retrieved via a getter method on the model oject if one is available; failing that the value is retrieved from the HashMap. Each model object has its own HashMap.
  9. The component.properties that are set is the aggregate of all component.properties files in all models for the current run. For example, say you are doing a JBoss run and building a method. Then the aggregate component.properties file will look for, and use if present, the files in the following order:
       jeewiz/resources/jboss3/control/method/component.properties
       jeewiz/resources/j2ee/control/method/component.properties
       jeewiz/resources/bizobject/control/method/component.properties
       jeewiz/resources/java/control/method/component.properties
    
    This search path will be enlarged if a template.properties diversion is used. For example, say we have a business-method and the bizobject/business-method has a diversion to the method object. Then the stack of aggregated component.properties files would be
       jeewiz/resources/jboss3/control/business-method/component.properties
       jeewiz/resources/j2ee/control/business-method/component.properties
       jeewiz/resources/bizobject/control/business-method/component.properties
       jeewiz/resources/jboss3/control/method/component.properties
       jeewiz/resources/j2ee/control/method/component.properties
       jeewiz/resources/bizobject/control/method/component.properties
       jeewiz/resources/java/control/method/component.properties
    
    The detailed rules for diversions (which apply to component.properties files as well as template files) is given in the section on the template.properties file.

    Note that the order these files are loaded is from the outside inwards (most specialised first). Normally (with the 'name=value' syntax), values are not be overwritten, which means that the most specialised version takes precedence. This means you can override a property setting on a component-by-component basis in your own overriding model.

    If a lower-precedence model really wants to insist on getting a particular value, it can use the 'name==value' ('==' instead of just '='), following the same convention as for loading system.properties.
The recommended way of using component.properties is to define here all substitution values, based on values in the environment, that you might want to use in building the object - in Ant build jobs or Velocity scripts. The Velocity scripts then use these values: it is easier to change all these properties in one place than searching all the Ant and Velocity scripts.

 


Copyright (c) 2001-2008 New Technology/enterprise Ltd.