openxava / documentation / Lesson 13: @DefaultValueCalculator from file

Course: 1. Getting started | 2. Basic domain model (1) | 3. Basic domain model (2) | 4. Refining the user interface | 5. Agile development6. Mapped superclass inheritance | 7. Entity inheritance | 8. View inheritance | 9. Java properties | 10. Calculated properties | 11. @DefaultValueCalculator in collections | 12. @Calculation and collections totals | 13. @DefaultValueCalculator from file | 14. Manual schema evolution | 15. Multi user default value calculation | 16. Synchronize persistent and computed properties | 17. Logic from database  | 18. Validating with @EntityValidator 19. Validation alternatives  | 20. Validation on remove  21. Custom Bean Validation annotation  | 22. REST service call from validation  | 23. Attributes in annotations  | 24. Refining the standard behavior | 25. Behavior & business logic | 26. References & collections | A. Architecture & philosophy | B. Java Persistence API | C. Annotations | D. Automated testing

Table of contents

Lesson 13: DefaultValueCalculator from file
Default value from a properties file
Summary
We have set persistent properties with @Calculation and defined total properties for our application. We will now see how to set default values from an external file.

If you don't like videos follow the instructions below.

Default value from a properties file

It's useful for the user to have the default value populated for the vatPercentage. You could use calculator (with @DefaultValueCalculator) that returns a fixed value, but in that case changing the default value means changing your source code. Otherwise you could read the default value from the database (using JPA from your calculator), but in that case changing the default value means updating a database table.
Another option is to store this configuration value in a properties file, a plain file with key=value pairs. In this case changing the default value for vatPercentage is just a matter of editing a plain file with a text editor.
Let's implement the properties file option. Create a file named invoicing.properties in the invoicing/src/main/resources folder with the next content:
defaultVatPercentage=21
Though you can use the java.util.Properties class from Java to read this file we prefer to create a custom class to read these properties. We are going to call this class InvoicingPreferences and we'll put it in a new package named com.yourcompany.invoicing.util. You have the code here:
package com.yourcompany.invoicing.util; // in 'util' package

import java.io.*;
import java.math.*;
import java.util.*;
 
import org.apache.commons.logging.*;
import org.openxava.util.*;
 
public class InvoicingPreferences {
 
    private final static String FILE_PROPERTIES="invoicing.properties";
    private static Log log = LogFactory.getLog(InvoicingPreferences.class);
    private static Properties properties; // We store the properties here
 
    private static Properties getProperties() {
        if (properties == null) { // We use lazy initialization
            PropertiesReader reader = // PropertiesReader is a utility class from OpenXava
                new PropertiesReader( InvoicingPreferences.class, FILE_PROPERTIES);
            try {
                properties = reader.get();
            }
            catch (IOException ex) {
                log.error( XavaResources.getString( // To read a i18n message
                    "properties_file_error", FILE_PROPERTIES), ex);
                properties = new Properties();
            }
        }
        return properties;
    }
 
    public static BigDecimal getDefaultVatPercentage() { // The only public method
        return new BigDecimal(getProperties().getProperty("defaultVatPercentage"));
    }
}
As you can see InvoicingPreferences is a class with one static method, getDefaultVatPercentage(). The advantage of using this utility class over reading directly the properties file is that if you change the way the preferences are obtained, for example reading from a database or an LDAP directory, you only have to change this class in your entire application.
You can use this class from the default calculator for the vatPercentage property. See the calculator in the next code:
package com.yourcompany.invoicing.calculators; // In 'calculators' package

import org.openxava.calculators.*; // To use ICalculator
import com.yourcompany.invoicing.util.*; // To use InvoicingPreferences
 
public class VatPercentageCalculator implements ICalculator {
 
    public Object calculate() throws Exception {
        return InvoicingPreferences.getDefaultVatPercentage();
    }
}
As you see, it just returns the defaultVatPercentage from InvoicingPreferences. Now, you can use this calculator in the definition of vatPercentage property in CommercialDocument:
@DefaultValueCalculator(VatPercentageCalculator.class)
BigDecimal vatPercentage;
With this code when the user clicks to create a new invoice, the vatPercentage field will be filled with 21 or whatever other value you put in invoicing.properties.


Summary

In this lesson you have learned how to use an external file from which we can establish default values to configure the properties that we will use in the business logic of our application, allowing us to abstract from having to modify the code when we want to modify these properties.

Download source code of this lesson

Any problem with this lesson? Ask in the forum Everything fine? Go to Lesson 14