AskPythia - How-to...

This section takes a deeper look at the source code of AskPythia and explains how the library may be extended to add support for another Device Description Repository (DDR).

The source code of the library is available at:
http://dev.w3.org/2009/mobileok-authoring/common/ddrsimpleapi/

The PHP documentation created from the source code is embedded in the PHP documentation of the mobileOK content authoring library, available at:
http://dev.w3.org/2009/mobileok-authoring/doc/phpdoc/

Components

AskPythia may be divided into three components:

AskPythia is a conforming implementation of the DDR Simple API. In particular, the different exceptions defined in the specification are thrown as required.

Interface

The interface subfolder contains the definitions of all the interfaces and classes defined in the DDR Simple API standard.

Evidence
An evidence represents information used to identify the device that sent a given request. See Evidence.
PropertyName
The name of a Property together with its namespace. See PropertyName.
PropertyRef
The name of a Property together with its Aspect together with the namespace they are in. See PropertyRef.
PropertyValue
PropertyValue models a PropertyRef together with its value. See PropertyValue.
PropertyValues
A set of PropertyValue. See PropertyValues.
Service
The Service interface is the core of the DDR Simple API. The Service is the Swiss army knife of the library. Among others, it provides the factory methods needed to create instances of the other classes and query methods to retrieve device properties. See Service.
ServiceFactory
This class can build a service with the supplied default namespace and configuration. See ServiceFactory
SystemException, DDRException and exceptions that derivate from these classes
DDR Simple API exceptions can be thrown as a consequence of error conditions that can occur during the execution of API calls. See Exceptions

Using interfaces makes it easy to switch from one implementation to another.

Here is a class diagram of the classes and interfaces:

As method overloading is forbidden in PHP, overloaded methods of the DDR Simple API are suffixed by the first letter of the class of each of the arguments it expects. This naming convention is consistent with the WSDL representation mentioned in the DDR Simple API (see Other Representations of the DDR Simple API).

Abstract implementation

Most of the interfaces defined in the DDR Simple API do not need to depend on any particular DDR. Thus, the basic subfolder contains a generic implementation of these interfaces, namely BasicEvidence, BasicPropertyName, BasicPropertyRef, BasicPropertyValue and BasicPropertyValues. These generic implementations may be re-used as they stand in concrete implementations of the API on top of some DDR.

BasicService is an abstract class implementation of the Service interface. Its factory methods create instances of the basic classes mentioned above. Its query methods all rely on an abstract and private getPropertyValues method that is expected to return all known property values for the given Evidence. The BasicService class may be extended in concrete implementations of the API to be able to focus on the device lookup algorithm without having to spend time on the remaining methods. See How to extend the library below.

Here is a class diagram that details how the basic classes relate to the DDR Simple API interfaces:

Implementation on top of WURFL

The WURFL subfolder contains the implementation of the DDR Simple API on top of WURFL.

This implementation makes use of the abstract implementation and merely consists of two classes:

  • WURFLService implements the Service interface and extends BasicService. Most of the code in this class implements the device lookup algorithm.
  • WURFLDevice represents a device as a User-Agent string and a set of PropertyValue. The class is used internally and is not exposed to the rest of the application.

Note: the WURFLPrepareDatabase class, defined in the same folder, is used to prepare the WURFL database for its consumption by WURFLService. It is not used in AskPythia once the WURFL database has been converted.

How to extend the library

Why extend the library?

AskPythia was specifically created to be extended with additional concrete implementations on top of various Device Description Repositories. The generic goal is to promote the DDR Simple API standard and improve interoperability between DDRs. The implementation on top of WURFL is provided as a working example. It may not suit all needs (e.g. not all the device capabilities defined in WURFL are supported).

Extensions to AskPythia that add support for other DDRs (or improve support for WURFL) are strongly encouraged.

Using the abstract implementation

Implementations that choose to extend the abstract implementation only need to provide an extension of the BasicService class with concrete code for the two abstract methods defined in BasicService.

The initializeProperties method

initializeProperties should initialize the list of properties supported by the implementation. This list is expected to follow the format of a tree array where the first level is the vocabulary IRI, the second level contains the local property names supported within each vocabulary, and the third level contains an array of parameters that define the local properties. Implementations may complete the array with more specific parameters according to needs, aspects is the only mandatory parameter and must contain the list of aspects the property may apply to. The first aspect in the list must be the default aspect for the property.

Example:

array(
    'http://example.org' => array(
        'coolCapability' => array(
            'aspects' => array('defaultAspect', 'otherAspect')
        ),
        'otherCoolCapability' => array(
            'aspects' => array('webBrowser')
        ),
    ),
    'http://example.com' => array(
        'veryCoolCapability' => array(
            'aspects' => array('device')
        ),
    ),
)

This list of properties is used internally to set the appropriate aspect when it is not explicitly precised in a request to retrieve device properties.

The getPropertyValues method

getPropertyValues is the core of the implementation. It should identify the device based on the evidence provided and retrieve its properties as a PropertyValues list.

This method is called whenever a query method of the BasicService class is called. If an application needs to access the properties of a device more than once, it is good advice to cache the device properties in the concrete implementation of the BasicService not to have to lookup the device in the underlying DDR each time.

Using the interfaces

Extensions may directly implement the DDR Simple API interfaces. This method is not recommended because it is more complex for no concrete added benefit.

Exception management

The abstract implementation performs as many checks as possible on the arguments it receives and throws exceptions where appropriate and in accordance with the DDR Simple API standard. The performance of the library largely depends on the implemented device lookup algorithm. Checks should not have any noticiable impact on the performance of the library.

Contact: François Daoust <fd@w3.org>