Enterprise Java

Comparing OpenDDR to WURFL

Web content delivered to mobile devices usually benefits from being tailored to take into account a range of factors such as screen size, markup language support and image format support. Such information is stored in “Device Description Repositories” (DDRs).

Both WURFL and OpenDDR projects provide an API to access the DDRs, in order to ease and promote the development of Web content that adapts to its Delivery Context.

WURFL recently changed its license to AGPL (Affero GPL) v3. Meaning that it is not free to use commercially anymore. Consequently some free open source alternatives have recently started to show up. OpenDDR is one of them.

In this post I will share my findings on how the OpenDDR Java API compares to WURFL.

Add dependencies to project

This section describes how to add WURFL and OpenDDR to a Maven project. WURFL

WURFL is really straightforward since it is available on Maven central repository. All you have to do is to include the dependency on your project:

<dependency>
    <groupId>net.sourceforge.wurfl</groupId>
    <artifactId>wurfl</artifactId>
    <version>1.2.2</version><!-- the last free version -->
</dependency>

OpenDDR

OpenDDR on the other hand is quite difficult to configure. Follow these steps to include OpenDDR in your project:

  1. Download OpenDDR-Simple-API zip.
  2. Unzip it and create a new Java project on Eclipse based on the resulting folder.
  3. Export OpenDDR-Simple-API JAR using Eclipse File >> Export..., include only the content of the src folder excluding oddr.properties file.
  4. Install the resulting JAR and DDR-Simple-API.jar from the lib folder into your local Maven repository
    mvn install:install-file -DgroupId=org.w3c.ddr.simple -DartifactId=DDR-Simple-API -Dversion=2008-03-30 -Dpackaging=jar -Dfile=DDR-Simple-API.jar -DgeneratePom=true -DcreateChecksum=true
    mvn install:install-file -DgroupId=org.openddr.simpleapi.oddr -DartifactId=OpenDDR -Dversion=1.0.0.6 -Dpackaging=jar -Dfile=OpenDDR-1.0.0.6.jar -DgeneratePom=true -DcreateChecksum=true
    
  5. Add the dependencies to your project pom.xml file:
    <dependency>
        <groupId>org.w3c.ddr.simple</groupId>
        <artifactId>DDR-Simple-API</artifactId>
        <version>2008-03-30</version>
    </dependency>
    <dependency>
        <groupId>org.openddr.simpleapi.oddr</groupId>
        <artifactId>OpenDDR</artifactId>
        <version>1.0.0.6</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-jexl</artifactId>
        <version>2.1.1</version>
    </dependency>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.6</version>
    </dependency>
    

Load repository/capabilities file

This section describes how to load WURFL and OpenDDR repository file(s) and import it in your project. WURFL

Copy wurfl-2.1.1.xml.gz file (the last free version) into your project src/main/resources folder and import it using:

WURFLHolder wurflHolder = new CustomWURFLHolder(getClass().getResource("/wurfl-2.1.1.xml.gz").toString());

OpenDDR

Copy oddr.properties from the OpenDDR-Simple-API src folder and all the files inside OpenDDR-Simple-API resources folder into your project src/main/resources folder. Import them using:

Service identificationService = null;
try {
    Properties initializationProperties = new Properties();
    initializationProperties.load(getClass().getResourceAsStream("/oddr.properties"));
    identificationService = ServiceFactory
            .newService("org.openddr.simpleapi.oddr.ODDRService",
                    initializationProperties.getProperty(ODDRService.ODDR_VOCABULARY_IRI),
                    initializationProperties);
} catch (IOException e) {
    LOGGER.error(e.getMessage(), e);
} catch (InitializationException e) {
    LOGGER.error(e.getMessage(), e);
} catch (NameException e) {
    LOGGER.error(e.getMessage(), e);
}

Using the API

This section describes how use WURFL and OpenDDR Java APIs to access the device capabilities. WURFL

WURFL API is very easy to use and has the big advantage of having a fall-back hierarchy inferring capabilities for devices not yet in its repository file.

Device device = wurflHolder.getWURFLManager().getDeviceForRequest(getContext().getRequest());
int resolutionWidth = Integer.valueOf(device.getCapability("resolution_width"));
int resolutionHeight = Integer.valueOf(device.getCapability("resolution_height"));

There’s no need to validate device.getCapability("resolution_width") against null value when no data is available.

OpenDDR

OpenDDR is quite the opposite. Very cumbersome and does not have a fall-back hierarchy, forcing the developer to validate each property value.

PropertyRef displayWidthRef;
PropertyRef displayHeightRef;

try {
    displayWidthRef = identificationService.newPropertyRef("displayWidth");
    displayHeightRef = identificationService.newPropertyRef("displayHeight");
} catch (NameException ex) {
    throw new RuntimeException(ex);
}

PropertyRef[] propertyRefs = new PropertyRef[] { displayWidthRef, displayHeightRef };
Evidence e = new ODDRHTTPEvidence();
e.put("User-Agent", getContext().getRequest().getHeader("User-Agent"));

int maxImageWidth = 320; // A default value
int maxImageHeight = 480; // A default value
try {
    PropertyValues propertyValues = identificationService.getPropertyValues(e, propertyRefs);
    PropertyValue displayWidth = propertyValues.getValue(displayWidthRef);
    PropertyValue displayHeight = propertyValues.getValue(displayHeightRef);

    if (displayWidth.exists()) {
        maxImageWidth = displayWidth.getInteger();
    }
    if (displayHeight.exists()) {
        maxImageHeight = displayHeight.getInteger();
    }
} catch (Exception ex) {
    throw new RuntimeException(ex);
}

Results

The following table shows the results of tests run against an application for server-side image adaptation using both WURFL and OpenDDR.
These tests were performed on real devices and pages were served as XHTML BASIC (same as XHTML MP).

PlatformDevicePropertyWURFL max_image_width (1) / max_image_heightWURFL resolution_width / resolution_heightOpenDDR displayWidth / displayHeight
N/AFirefox desktopwidth650640Not supported
height600480Not supported
iOSiPhone 4Swidth320320320
height480480480
AndroidHTC One Vwidth320540Not supported
height400960Not supported
HTC Herowidth300320320
height460480480
Windows Phone 7.5Nokia Lumia 710width600640480
height600480800
BlackBerryBlackBerry Bold 9900width228480640
height280640480
Symbian S60Nokia E52 (Webkit)width234240240
height280320320
Nokia E52 (Opera Mobile)width240240Not supported
height280320Not supported
Windows Mobile 6.1HTC Touch HD T8282width440480480
height700800800

(1) max_image_width capability is very handy:

Width of the images viewable (usable) width expressed in pixels. This capability refers to the image when used in “mobile mode”, i.e. when the page is served as XHTML MP, or it uses meta-tags such as “viewport”, “handheldfriendly”, “mobileoptimised” to disable “web rendering” and force a mobile user-experience.

Note: The color #9f9 highlights the results that performed better. Pros and Cons

ProsCons
WURFL
  • A Device Hierarchy that yields a high-chance that the value of capabilities is inferred correctly even when the device is not yet recognized.
  • Lots and lots of capabilities.
  • Easier to configure.
  • Cleaner API.
OpenDDR
  • Free to use, even commercially.
  • Growing community.

Related Posts

Reference: Comparing Device Description Repositories from our JCG partner Samuel Santos at the Samaxes blog.

Samuel Santos

Java and Open Source evangelist, JUG leader and Web advocate for web standards and semantic technologies.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
dubBike
dubBike
12 years ago

Have you tried comparing it to Deviceatlas?

Back to top button