file corresponding to the file URL provided in Connector.open() .
There is some level of correlation between the two APIs and so a call to
FileConnection.create() eventually invokes a simple native call
to RFile::Create(RFs, name, file-mode) . In a similar way, a
call to FileConnection.mkDir() eventually invokes a simple native
call to RFs::MkDir(path) . Deleting a file by calling FileCon-
nection.delete() is eventually delegated to a native call to either
RFs.RmDir(path) or RFs.Delete(path) depending on whether
the URI points to a directory or a file, respectively.
The FileConnection methods canRead() , isHidden() ,and
isDirectory() , used to get the readable, hidden and directory at-
tributes, respectively, are performed by first calling RFs::Entry(name,
TEntry) and then calling TEntry::IsReadOnly() , TEntry::Is-
Hidden() or TEntry::IsDir() . Setting file attributes, when applica-
ble, uses RFs.SetAtt() which sets or clears the attributes of a single
file or directory.
FileSystemListener.rootChanged(int state, String
rootName) is invoked when a root on the device has changed
state (for example, a file system root has been added to or removed
from the device). To receive such events, the JSR-75 FileConnec-
tion implementation registers for native file-system events using
RFs::NotifyChange(TNotifyType, TRequestStatus, path)
and pushes the knowledge of those events to Java FileSystemListen-
ers after translating the native event data structure to Java primitive types.
As can be seen from these examples, Java functionality has to be
mapped to native functionality and in JSR-75 FileConnection, it is fairly
straightforward; deleting files or directories and getting and setting file
attributes map closely to the native RFs API.
However, in reality there are more challenges than just mapping
functionality. In Chapter 10, we discussed how the Java ME run-time
environment is subdivided into several layers (see Sections 10.5 and
10.6). We now use JSR-75 to provide a concrete and detailed example of
First, the public Java API is implemented by system Java classes that are
not accessible to Java applications. Those Java classes process information
themselves or delegate it to native code as applicable.
Secondly, jumping from Java code into native code requires a layer of
JNI-like C functions that act as a trampoline from Java to Symbian C++
code. That layer uses the VM-agnostic KJNI API (see Section 10.4).
Thirdly, the insulation of the VM threading model and Symbian OS
asynchronous operations requires an implementation layer of code that
runs in the native Java Event Server (JES) thread and native code that
delegates the execution from the VM thread to the JES thread. This layer