JDeveloper: access resources from the applications jar or classpath in the Model or ViewController

This bog describes how to read resources, which are part of the applications classpath and are deployed with the application.

Use Case
You want to read a resource e.g. a property file in the model layer or the view layer or an image which is part of the deployed application. As you don’t know where exactly the application is deployed, you can’t use the normal java.io.* classes as they require an absolute path to the file to read.

Implementation
In the Sample which is provided with this blog (see the link at the end of the blog) we read a properties file ‘model.properties’ in the model layer and make the values abailable via a service method in the application module. In the view layer we similar read another properties file ‘view.properties’ which we access through a bean method.

The UI consists of only one page which has two panelForms. Each has an inputText component where you can enter the key of the property you want to read, a button to activate a method to read the property and an outputText to show the result.

Running application

Running application

Model project resources:

# Model resources
ModuleName=BARTPAppModule
CreationDate=2012-08-01
EmptyKey=

ViewController project resources:

## Properties file for hte view controller
ViewControllerName=Hallo ik bin ein Berliner
CreateDate=2012-08-02

After entering a key value we get the values displayed:

Running application after getting some values

Running application after getting some values

Let’s start with the implementation in the model layer. In the application module implementation class we add a service method which is implemented as singleton (for the module), meaning that the resource is only loaded once and stored in the application module. Activation and passivation don’t need to be handled here, as the resource is read again after each activation as the local variable mModelProperties will be null after an activation.

public class BARFPAppModuleImpl extends ApplicationModuleImpl implements BARFPAppModule {
    private static ADFLogger _logger = ADFLogger.createADFLogger(BARFPAppModuleImpl.class);
    private static String PROPERTY_FILE = "de/hahn/blog/accessresourcesfrompath/model/resources/model.properties";
    Properties mModelProperties = null;

    /**
     * Returns the value of a property read from the model property file
     * @param key of the property to retrieve
     * @return value of the key or null if not found
     */
    public String getModelResource(String key) {
        // read property file only once
        if (mModelProperties == null) {
            initProperties();
        }

        return mModelProperties.getProperty(key);
    }

    /**
     * load the properties from the resource file
     */
    private void initProperties() {
        InputStream asStream = this.getClass().getClassLoader().getResourceAsStream(PROPERTY_FILE);
        if (asStream == null) {
            _logger.severe("Could not load property file: '" + PROPERTY_FILE + "'");
            mModelProperties = new Properties();
            return;
        }

        mModelProperties = new Properties();
        try {
            mModelProperties.load(asStream);
        } catch (IOException e) {
            e.printStackTrace();
            _logger.warning("Can't load properties: " + e.getMessage());
        }
        _logger.info("Model properties loaded!");
    }
...
}

The essential part is to use the class loader to read the resource as stream (line 24). The class loader allows us to read resources from the class path itself without knowing the absolute path in the file system. You only need to know the package structure and replace the ‘.’ which delimit the packages with the ‘/’. The class loader can then access all folders relative from its own load point. For more information check ClassLoader java doc.
The rest of the implementation is easy now. The same technique is used in the bean of the view controller project. Here we implement the method in a bean which we call on the click of a button ‘getViewReource’.

public class ResourceReaderBean {
    private static ADFLogger _logger =
        ADFLogger.createADFLogger(ResourceReaderBean.class);
    private Properties mViewProperties = null;
    private static String PROPERTY_FILE =
        "de/hahn/blog/accessresourcesfrompath/view/resource/view.properties";

    private void initProperties() {
        // instead of using the de.hahn.testproxy.backingbeans.test.properties you have to use de/hahn/testproxy/backingbeans/test.properties
        InputStream asStream =
            this.getClass().getClassLoader().getResourceAsStream(PROPERTY_FILE);
        if (asStream == null) {
            // file not found
            _logger.info("File not found: '" + PROPERTY_FILE + "'");
            return;
        }
        mViewProperties = new Properties();
        try {
            mViewProperties.load(asStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (!mViewProperties.isEmpty()) {
            _logger.info("Properties loaded: " + mViewProperties.toString());
        }

    }

    public void getViewResourceListner(ActionEvent actionEvent) {
        String value = "";
        // read property file only once
        if (mViewProperties == null)
            initProperties();

        BindingContainer bindingContainer =
            BindingContext.getCurrent().getCurrentBindingsEntry();
        AttributeBinding attrKey =
            (AttributeBinding)bindingContainer.getControlBinding("ViewResourceKey1");
        String key = (String)attrKey.getInputValue();
        if (mViewProperties != null && key != null) {
            String val = mViewProperties.getProperty(key);
            AttributeBinding attrValue =
                (AttributeBinding)bindingContainer.getControlBinding("ViewResourceValue1");
            attrValue.setInputValue(val);
        }
    }
...
}

The key to load from the resource is read from the binding variable ‘ViewResourceKey1′, the returned value is put back into the binding variable ‘ViewResourceValue1′. Both are defined in the variables section of the pageDef of the ShowProperty.jspx page.

You can download the sample from here BlogAccessResourcesFromPath.zip.
The sample was built with JDev 11.1.1.6.0 and uses the HR schema.

About these ads

One thought on “JDeveloper: access resources from the applications jar or classpath in the Model or ViewController

  1. I found this very useful. I was trying to access an XML file from an ADF library jar that had been added to the ViewController project, using ServletContext.getResourceAsStream(“WEB-INF/.xml”). This would work only for files in the consuming application. Using getClass().getClassLoader().getResourceAsStream() I was able to read files from the ADF library jar.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s