Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Highlighted
Developer
Posts: 50
Registered: ‎12-23-2009
My Device: Not Specified

The design of the project supporting multiple API based on preprocessor derictives

[ Edited ]

Hi all!

I have a project that have to support multiple API of the BB OS.

I investigated a bit how it should be designed and want to summarize.

Hope someone will find this useful.

I wrote a short list of principles with examples to show in future to my

co-workers. But first, I would like to hear some feedback from knowledgeable

people. Please kindly disregard my poor english Smiley Happy.  

So please point me if I'm mistaken somewhere or if I skipped something,

or maybe some places should be clarified.

 

 

1. Separate API-dependent code from API-independent. API-independent code 

should call API-dependent one via fixed interface. Instances of the objects

that implements API-specific logic should be created using 'abstract factory'

pattern:

abstract factory.png

 

Here is example of abstract factory implementation:

 

abstract class AbstractFactory {

    static public AbstractFactory getInstance() {
        // #ifdef BB42
        return new ClassFactory42();
        // #endif

        // #ifdef BB43
        return new ClassFactory43();
        // #endif

         ...
    }
    
    abstract public AddressBookManager getAddressBookManager();
    abstract public NetworkManager getNetworkManager();
    abstract public DataStore getDataStore();
}

abstract class AddressBookManager {
    ...
}
abstract class NetworkManager {
    ...
}
abstract class DataStore {
    ...
}

Here are directives BB42, BB43... specify target API version.

 

2. Include in build all API-specific implementations that uses API lower or equal to current API version. This rule will allow to prevent code duplication by using class inheritance. For example we have to support BB OS 4.2 and 4.3, so it's better to inherit 4.3 implementation from 4.2 one and just to overload those methods that really changed:

 

class ClassFactory42 extends AbstractFactory {
    public AdressBookManager getAdressBookManager() {
        return new AdressBookManager42();
    }
    public NetworkManager getNetworkManager() {
        return new NetworkManager42();
    }
    public DataStore getDataStore() {
        return new DataStore42();
    }
}

class ClassFactory43 extends ClassFactory42 {
    public NetworkManager getNetworkManager() {
        return new NetworkManager43();
    }

// other implementations didn't change
} //////////////////// class NetworkManager42 extends NetworkManager { HttpResponse processRequest(Request request) { ... } boolean isNetworkAvailable() { ... } private char[] readResponse() { ... } } class NetworkManager43 extends NetworkManager42 { boolean isNetworkAvailable() { ... } // other methods didn't change }

 

3. Exclude from build implementations that uses API version which is greater than target API version. Implementations that uses API greater than target one will rather compile with error (smth like "class not found"). So we need to remove them from build using preprocessor directives. At the same time we have to provide p. 2.

    Let's assume that target OS version is 4.5. We should include in build implementations that uses API versions 4.2, 4.3, 4.5 and exclude API 4.6+.

    RAPC preprocessor allows to use just simpliest directives #ifdef <DIRECTIVE>, #ifndef <DIRECTIVE>, #else, #endif. So including/excluding of API-specific implementations can be provided via additional directives. (Note: if you use third-party preprocessor that can calculate expressions, there is a simplier solution, something like this:

 

// #if CURRENT_VERSION >= 4.5
class ClassFactory45 {
    ...
}
// #endif

).

    Lets specify directives that reflects minimal API version needed to build code enclosed with these directives. For example, for code that uses API 4.2 there will be MINIMAL_API_42 directive, for code using API 4.5 there will be MINIMAL_API_45 directive. So for target OS 4.5 the next directives should be specified:

BB45: MIN_BB42, MIN_BB43, MIN_BB45.

These directives should be used in the following manner:

 

NetworkManager42.java
//#preprocessor

//#ifdef MIN_BB42
class NetworkManager42 extends NetworkManager {
    ...
}

//#endif

NetworkManager43.java
//#preprocessor

//#ifdef MIN_BB43
class NetworkManager43 extends NetworkManager42 {
    ...
}

//#endif

NetworkManager47.java
//#preprocessor

//#ifdef MIN_BB47
class NetworkManager47 extends NetworkManager43 {
    ...
}

//#endif

    In the previous example API 4.7 will be excluded from compilation. But other implementations will be included. Here are some more examples of additional directives:

TatgetAPI=4.2 : specify MIN_BB42

TatgetAPI=4.3 : MIN_BB42, MIN_BB43

TargetAPI=4.5: MIN_BB42, MIN_BB43, MIN_BB45

TargetAPI=4.6: MIN_BB42, MIN_BB43, MIN_BB45, MIN_BB46

...

 

 

 

Thanks in advance.

Nikolay.

Developer
Posts: 50
Registered: ‎12-23-2009
My Device: Not Specified

Re: The design of the project supporting multiple API based on preprocessor derictives

something wrong with the image. Here is link to image hosting using of abstract factory image

New Contributor
Posts: 5
Registered: ‎04-28-2011
My Device: 8520
My Carrier: Vodacom

Re: The design of the project supporting multiple API based on preprocessor derictives

I am tring to use the 

 

// #if CURRENT_VERSION >= 4.5

 

but the compiler is compiler is trowingth exeption 


#endif' without '#ifdef

 

I have taken note of "(Note: if you use third-party preprocessor that can calculate expressions"

 

how do i get the third-party preprocessor that can calculate expressions ?

Developer
Posts: 4,764
Registered: ‎07-21-2008
My Device: Not Specified

Re: The design of the project supporting multiple API based on preprocessor derictives