Documentation/DevGuide/Universal Content Broker

Capabilities
The Universal Content Broker (UCB) is a key part of the LibreOffice architecture. In general, the UCB provides a standard interface for generalized access to different data sources and functions for querying, modifying, and creating data contents. The LibreOffice document types are all handled by the UCB. In addition, it is used for help files, directory trees and resource links.

The advantage of delegating resource access to the UCB is, that document, folder and link handling can always be the same from the developer's perspective.It does not matter if you are storing in a file system, on an FTPWebDAV server, or in a document management system.

However, the UCB does not have to be used directly if you want to load and save LibreOffice documents.The com.sun.star.frame.Desktop service provides the necessary functions, hiding the comparably low-level UCB calls. See Handling Documents. The UCB allows you to administer files in a directory tree or read your own document stream, regardless of where the directory tree or the stream is located.

Architecture
Conceptually, the UCB can be pictured as an object system that consists of a core and a set of Universal Content Providers (UCPs). The UCPs are designed to mask the differences between access protocols, enabling developers to focus on the essentials of integrating resources through the UCB interface, instead of the complexities of an underlying protocol. To this end, each UCP implements an interface that facilitates access to a particular data source through a Uniform Resource Identifier (URI). When a client requests a particular resource, it addresses the UCB that calls a qualified UCP, based on the URI that is associated with the content.

As a rule, all data content is encapsulated in content objects. Each content object implements a standard set of interfaces, that includes functions for querying the content type and a select set of commands that can be run on the respective content, such as " ", " ", and " ".

Each content object also has a set of attributes that can be read and set by an application, that include the title, the media type (MIME type), and different flags. The UCB API defines a set of standard commands and properties. There is a set of mandatory properties and commands that must be supported by any content implementation, as well as optional commands and properties with predefined semantics. The illustration below shows the relationship between the UCB, UCPs and UCB content objects.



When a client requests a particular content, it addresses the UCB and passes on the corresponding URI. The UCB analyzes the URI and then calls the corresponding UCP which creates an object for the requested resource.

For example, when an application requests a particular document, the URI of the document is passed to the Universal Content Broker. The UCB analyzes the URI and delegates it to the appropriate UCP. The UCP creates a content object for the requested resource and returns it to the UCB, which returns it to the application. The application now opens the content object or query, or set property values by executing the appropriate command.

Services and Interfaces
Each UCB content implements the service com.sun.star.ucb.Content. The UCB content service interfaces include:


 * com.sun.star.ucb.XContent
 * com.sun.star.beans.XPropertyContainer
 * com.sun.star.container.XChild (optional)
 * com.sun.star.ucb.XCommandProcessor
 * com.sun.star.ucb.XCommandProcessor2 (optional)
 * com.sun.star.ucb.XContentCreator (optional)

The interface com.sun.star.ucb.XContent provides access to a content's type and identifier. The com.sun.star.ucb.XCommandProcessor executes commands at the content object, such as opening a content that provides access to the content's data stream or its children, and setting and getting property values. The interface com.sun.star.beans.XPropertyContainer adds new properties to a content or removes properties that were previously added using this interface. The properties added are always made persistent.

The com.sun.star.ucb.XContentCreator interface is for creating new resources, such as a new folder in the local file system. Not all content implementation can create new resources, therefore this interface is optional. The optional interface com.sun.star.container.XChild provides access to the content object's parent content object. Not all data sources represented by content implementations are organized hierarchically, therefore a parent cannot always be specified.

Some content commands defined by the UCB API are listed in the following table:

Some interesting content properties defined by the UCB API:

Every UCP implements the service com.sun.star.ucb.ContentProvider. The UCP core interface is com.sun.star.ucb.XContentProvider. This interface facilitates the creation of content objects based on a given content identifier.

A UCB implements the service com.sun.star.ucb.UniversalContentBroker. The UCB core interfaces are com.sun.star.ucb.XContentProvider and com.sun.star.ucb.XContentProviderManager. The com.sun.star.ucb.XContentProvider interface implementation delegates requests to create content objects to the content provider registered for the supplied content identifier. The com.sun.star.ucb.XContentProviderManager interface is used to query the UCPs registered with a given UCB, and to register and remove UCPs.

Content Providers
The current implementation of the Universal Content Broker in a LibreOffice installation supplies UCPs for the following data sources:

Appendix C Universal Content Providers describes all the above content providers in more detail. The reference documentation for the commands and other features of these UCPs are located in the SDK or the ucb project on ucb.openoffice.org. Additionally, the ucb project offers information about other UCPs for LibreOffice, for example, a UCP for document management systems.

Using the UCB API
This section explains how to use the API of the Universal Content Broker.

Instantiating the UCB
The following steps have to be performed before a process can use the UCB:


 * Create and set the UNO service manager.
 * Create an instance of the UNO service com.sun.star.ucb.UniversalContentBroker, passing the keys identifying a predefined UCB configuration to.

There are several predefined UCB configurations. Each configuration contains data that describes a set of UCPs. All UCPs contained in a configuration are registered at the UCB that is created using this configuration. A UCB configuration is identified by two keys that are strings. The standard configuration is " " and " ", which generally allows access to all UCPs available in a local installation.

For information about other configurations, refer to Configuration.

Accessing a UCB Content
Each UCB content can be identified using a URL that points to a folder or a document content in the data source you want to work with. To create a content object for a given URL:


 * 1) Obtain access to the UCB.
 * 2) Let the UCB create a content identifier object for the requested URL using   at the com.sun.star.ucb.XContentIdentifierFactory of the UCB.
 * 3) Let the UCB create a content object for the content identifier using   at the com.sun.star.ucb.XContentProvider interface of the UCB.

The UCB selects a UCP according to the URL contained in the identifier object and dispatches the  call to it. The UCP creates the content implementation object and returns it to the UCB, which passes it on to the caller.

Creating a UCB content from a given URL:

Executing Content Commands
Each UCB content is able to execute commands. When the content object is created, commands are executed using its com.sun.star.ucb.XCommandProcessor interface. The com.sun.star.ucb.XCommandProcessor:execute method at this interface expects a com.sun.star.ucb.Command, which is a struct containing the command name, command arguments and a handle:

Refer to Appendix C Universal Content Providers for a complete list of predefined commands, the description of the UNO service com.sun.star.ucb.Content and the UCP reference that comes with the SDK. For the latest information, visit ucb.openoffice.org.

If executing a command cannot proceed because of an error condition, the following occurs. If the execute call was supplied with a com.sun.star.ucb.XCommandEnvironment that contains a com.sun.star.task.XInteractionHandler, this interaction handler is used to resolve the problem. If no interaction handler is supplied by passing null to the  method, or it cannot resolve the problem, an exception describing the error condition is thrown.

The following method  executes a command at a UCB content:

Obtaining Content Properties
A UCB content maintains a set of properties. It supports the command " ", that obtains one or more property values from a content. This command takes a sequence of com.sun.star.beans.Property and returns an implementation of the interface com.sun.star.sdbc.XRow that is similar to a row of a JDBC resultset. To obtain property values from a UCB content:


 * 1) Define a sequence of properties you want to obtain the values for.
 * 2) Let the UCB content execute the command " ".
 * 3) Obtain the property values from the returned row object.

The following example demonstrates the use of content properties. Note that the method  is used from the example above to execute the " " command that takes a command name and creates a com.sun.star.ucb.Command struct from it:

The returned row for the content above has two columns Title and IsFolder, and could contain the following data. The column values are retrieved using the getXXX methods of the com.sun.star.sdbc.XRow interface. The command " " always returns a single row for contents.

Setting Content Properties
A UCB content maintains a set of properties. It supports the command " ", that is used to set one or more property values of a content. This command takes a sequence of com.sun.star.beans.PropertyValue and returns void. To set property values of a UCB content:


 * ::Define a sequence of property values you want to set.
 * ::Let the UCB content execute the command " ".

Note that the command is not aborted if one or more of the property values cannot be set, because the requested property is not supported by the content or because it is read-only. Currently, there is no other method to check if a property value was set successfully other than to obtain the property value after a set-operation. This may change when status information could be returned by the command " ".

Setting property values of a UCB content:

Accessing the Children of a Folder
A UCB content that is a folder, that is, the value of the required property  is true, supports the command " ". This command takes an argument of type com.sun.star.ucb.OpenCommandArgument2. The value returned is an implementation of the service com.sun.star.ucb.DynamicResultSet. This  holds the children of the folder and is a result set that can notify registered listeners about changes. To retrieve data from it, call  at its com.sun.star.ucb.XDynamicResultSet interface. The static result set is a com.sun.star.sdbc.XResultSet that can be seen as a table, where each row contains a child content of the folder. Use the appropriate methods of com.sun.star.sdbc.XResultSet to navigate through the rows:

The child contents are accessed by traveling to the appropriate row and using the interface com.sun.star.ucb.XContentAccess, which is implemented by the returned result set:

You may supply a sequence of com.sun.star.beans.Property as part of the argument of the " " command. In this case, the result set contains one column for each property value that is requested. The property values are accessed by traveling to the appropriate row and calling methods of the interface com.sun.star.sdbc.XRow. Refer to the documentation of com.sun.star.ucb.OpenCommandArgument2 for more information about other parameters that can be passed to the " " command.

To access the children of a UCB content:

Accessing the children of a UCB folder content:
 * 1) Fill the com.sun.star.ucb.OpenCommandArgument2 structure according to your requirements.
 * 2) Let the UCB content execute the " " command.
 * 3) Access the children and the requested property values using the returned dynamic result set.

Reading a Document Content
A UCB content that is a document, that is, the value of the required property  is , supports the command " ". The command takes an argument of type com.sun.star.ucb.OpenCommandArgument2. Note that this command with the same argument type is also used to access the children of a folder. As seen in the examples, the argument's  member controls access to the children or the data stream, or both for contents that support both. If you are interested in the data stream, ignore the command's return value, which will presumably be a null value.

The caller must implement a data sink and supply this implementation as " " command arguments to get access to the data stream of a document. These data sinks are called back by the implementation when the " " command is executed. There are two different interfaces for data sinks to choose from, com.sun.star.io.XActiveDataSink and com.sun.star.io.XOutputStream.


 * : If this type of data sink is supplied, the caller of the command is active. It consists of the following methods:

The implementation of the command supplies an implementation of the interface com.sun.star.io.XInputStream to the given data sink using  and return. Once the execute-call has returned, the caller accesses the input stream calling  and read the data using that stream, through   or.


 * : If this type of data sink is supplied, the caller of the command is passive. The data sink is called back through the following methods of :

The implementation of the command writes all data to the output stream calling  and closes it through   after all data was successfully written. Only then will the open command return.

The type to use depends on the logic of the client application. If the application is designed so that it passively processes the data supplied by an com.sun.star.io.XOutputStream using an output stream as sink is advantageous, because many content providers implement this case efficiently without buffering any data. If the application is designed so that it actively reads the data, use an com.sun.star.io.XActiveDataSink, then any necessary buffering takes place in the implementation of the open command.

The following example shows a possible implementation of an com.sun.star.io.XActiveDataSink and its usage with the " " command:

Now this data sink implementation can be used with the "open" command. After opening the document content,  returns the input stream containing the document data. The actual byte content is read using  in the following fragment:

Storing a Document Content
A UCB content that is a document, that is, the value of the required property  is true, supports the command " ". This command is used to overwrite the document's data stream. The command requires an argument of type com.sun.star.ucb.InsertCommandArgument and returns void. The caller supplies the implementation of an com.sun.star.io.XInputStream with the command argument. This stream contains the data to be written. An additional flag indicating if an existing content and its data should be overwritten is supplied with the command argument. Implementations that are not able to detect if there are previous data may ignore this parameter and will always write the new data.

Setting or storing the content data stream of a UCB document content is shown below:

Managing Contents
You can create, delete, copy, move and link UCB content.

Creating
A UCB content that implements the interface com.sun.star.ucb.XContentCreator acts as a factory for new resources. For example, a file system folder can be a creator for other file system folders and files.

A new content object created by the com.sun.star.ucb.XContentCreator implementation can be considered as an empty hull for a content object of a special type. This new content object has to be filled with some property values to become fully functional. For example, a file system folder could require a name, represented by the property  in the UCB. The interface com.sun.star.ucb.XContentCreator offers ways to determine what contents can be created and what properties need to be set. Information can be obtained on the general type, such as,  , or  , of the objects. After the required property values are set, the creation process needs to be committed by using the command " ". Note that this command is always executed by the new content, not by the content creator, because the creator is not necessarily the parent of the new content. The flag  in the " " argument com.sun.star.ucb.InsertCommandArgument usually is , because the caller does not want to destroy an already existing resource. The " " command implementation makes the new content persistent in the appropriate storage medium.

To create a new resource:


 * 1) Obtain the interface com.sun.star.ucb.XContentCreator from a suitable UCB content.
 * 2) Call   at the content creator. Supply information on the type of content to create with the arguments. The argument expected is a com.sun.star.ucb.ContentInfo struct.
 * 3) Obtain and set the property values that are mandatory for the content just created.
 * 4) Let the new content execute the command " " to complete the creation process.

Creating a new resource:

Appendix C Universal Content Providers discusses the creation of contents for all available UCPs. The table below shows a number of com.sun.star.ucb.ContentInfo types for creatable contents. Additionally, you can ask the content creator for its creatable contents using com.sun.star.ucb.XContentCreator:queryCreatableContentsInfo. The UCB reference in the SDK and on ucb.openoffice.org offers comprehensive information about creatable contents.

Deleting
Executing the command " " on a UCB content destroys the resource it represents. This command takes a boolean parameter. If it is set to true, the resource is immediately, destroyed physically.

If  is passed to this command, the caller wants to delete the resource "logically". This means that the resource is restored or physically destroyed later. A soft-deleted content needs to support the command " ". This command brings it back to life. The implementation of the delete command can ignore the parameter and may opt to always destroy the resource physically.

Deleting a resource:

Copying, Moving and Linking
Copying, moving and creating links to a resource works differently from the other operations available for UCB Contents. There are three UCB Contents involved in these operations, the source object, target folder, and target object. There may even be two content Providers, for example, when moving a file located on an FTP server to the local file system of a workstation. Each implementation of the com.sun.star.ucb.UniversalContentBroker service supports the com.sun.star.ucb.XCommandProcessor interface. This command processor implements the command " " that can be used to copy and move UCB Contents, and create links to UCB Contents. The command takes an argument of type com.sun.star.ucb.GlobalTransferCommandArgument. To copy, move or create a link to a resource, execute the " " command at the UCB.

Copying, moving and creating links to a resource are shown in the following example:

UCB Configuration
This section describes how to configure the Universal Content Broker (UCB). Before a process uses the UCB, it needs to configure the UCB. Configuring the UCB means registering a set of Universal Content Providers (UCPs) at a content broker instance. Only UCPs known to the UCB are used to provide content. Generally we provide two ways to configure a UCB:


 * Create a default UCB with no UCPs registered and register all required UCPs manually.
 * Define a UCB configuration and create a UCB that is automatically configured with the UCPs given in that configuration.

UCP Registration Information
Before registering a content provider, the following information that is provided by the implementer of the UCP is required. The Appendix Universal Content Providers provides these for the currently available UCPs.


 * The UNO service name to instantiate the UCP, for example, "com.sun.star.ucb.FileContentProvider". Each UCP must be implemented and registered as a UNO component. Refer to chapter Writing UNO Components for more information on writing and registering UNO components.
 * An URL template used by the UCB to select the registered UCPs that best fit an incoming URL. See com.sun.star.ucb.XContentIdentifier . This can be the name of an URL scheme, for example, the file that selects the given UCP for all file URLs, or a limited regular expression, such as " That will select the given UCP for all http URLs in the com domain. See the documentation of com.sun.star.ucb.XContentProviderManager:registerContentProvider  for details about these regular expressions.
 * Additional arguments that may be needed by the UCP.

Unconfigured UCBs
A UCB is called unconfigured if it has no content providers, thus it is not able to provide any contents. Each UCB implements the interface com.sun.star.ucb.XContentProviderManager. This interface offers the functionality to register UCPs at runtime.

To create an unconfigured UCB and configure it manually:


 * 1) Create an instance of the UNO service com.sun.star.ucb.UniversalContentBroker.
 * 2) Register the appropriate UCPs using the com.sun.star.ucb.XContentProviderManager interface of the UCB.

contains the following methods:

The  configures a UCB for content providers, obtains com.sun.star.ucb.ContentProviderInfo structs describing the available providers, and the provider that is currently registered for a specific URL schema. The following example uses  to configure an unconfigured UCB for a file content provider.

Unconfigured UCB:

Preconfigured UCBs
A UCB is called preconfigured if it was given a UCB configuration at the time it was instantiated. A UCB configuration contains a set of UCP registration information.

To create a preconfigured UCB:


 * 1) Create an instance of the UNO service com.sun.star.ucb.UniversalContentBroker.
 * 2) Pass the configuration as a parameters to the creation function. The UCB instance returned offers all UCPs defined in the given configuration.

Preconfigured UCB:

A UCB configuration used by a preconfigured UCB describes a set of UCPs available in a configuration. All UCPs contained in a configuration are registered at the UCB that is created using this configuration. A UCB configuration is identified by two keys that are strings. The keys allow some structuring in the configuration files, but they do not have a purpose. See the example file below. The standard configuration is "Local" and "Office", that allows access to all UCPs. The XML sample below shows how these keys are used to organize UCB configurations.

The predefined configurations for LibreOffice are defined in the file /share/config/data/org/openoffice/ucb/Configuration.xcd. This file must be adapted to add configurations or edit existing configurations. The XCD file is used during the LibreOffice build process to generate the appropriate XML file. This XML file is part of a LibreOffice installation and is located in share/config/registry/instance/org/openoffice/ucb/Configuration.xml. The UCB tries to get configuration data from this XML file.

UCB Configuration (org/openoffice/ucb/Configuration.xcd):

Content Provider Proxies
The UNO service implementing a UCP must be instantiated at the time the content provider is registered at the UCB. This is done using com.sun.star.ucb.XContentProviderManager 's  method. In some cases, this can consume resources, because instantiating a UNO service means loading the libraries containing its code. As a convention, each UNO component should reside in its own library.

Therefore, a special UNO service is offered that provides a generic proxy for a UCP. Its purpose is to delay the loading of the real UCP code until it is needed. Generally, this does not happen before the first /  calls are done at the proxy.

Instead of registering the real instantiated UCP at the UCB, a proxy is created for the UCP. The UCP registration information is passed to the proxy. The proxy only uses this information to instantiate the real UCP on demand. There is almost no performance overhead with this mechanism.