Reading Configuration Data

From Apache OpenOffice Wiki
< Documentation‎ | DevGuide
Revision as of 12:37, 15 February 2008 by Ccornell (Talk | contribs)

Jump to: navigation, search



ConfigurationAccess services

The com.sun.star.configuration.ConfigurationAccess service is used to navigate through the configuration hierarchy and reading values. It also provides information about a node and its context.

The following example shows how to collect or display information about a part of the hierarchy. For processing elements and values, our example uses its own callback Java interface IConfigurationProcessor:

 // Interface to process information when browsing the configuration tree
 public interface IConfigurationProcessor {
     // process a value item
     public abstract void processValueElement(String sPath_, Object aValue_);
     // process a structural item
     public abstract void processStructuralElement(String sPath_, XInterface xElement_);
 };

Then, we define a recursive browser function:

 // Internal method to browse a structural element recursively in preorder
 public void browseElementRecursively(XInterface xElement, IConfigurationProcessor aProcessor)
         throws com.sun.star.uno.Exception {
     // First process this as an element (preorder traversal)
     XHierarchicalName xElementPath = (XHierarchicalName) UnoRuntime.queryInterface(
         XHierarchicalName.class, xElement);
 
     String sPath = xElementPath.getHierarchicalName();
     
     //call configuration processor object
     aProcessor.processStructuralElement(sPath, xElement);
     
     // now process this as a container of named elements
     XNameAccess xChildAccess =
         (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class, xElement);
     
     // get a list of child elements
     String[] aElementNames = xChildAccess.getElementNames();
     
     // and process them one by one
     for (int i=0; i< aElementNames.length; ++i) {
         Object aChild = xChildAccess.getByName(aElementNames[i]);
         
         // is it a structural element (object) ...
         if ( aChild instanceof XInterface ) {
             // then get an interface 
             XInterface xChildElement = (XInterface)aChild;
         
             // and continue processing child elements recursively
             browseElementRecursively(xChildElement, aProcessor);
         }
         // ... or is it a simple value
         else {
             // Build the path to it from the path of 
             // the element and the name of the child
             String sChildPath;
             sChildPath = xElementPath.composeHierarchicalName(aElementNames[i]);
             
             // and process the value
             aProcessor.processValueElement(sChildPath, aChild);
         }
     }
 }

Now a driver procedure is defined which uses our previously defined routine createConfigurationView() to create a view, and then starts processing:

 /** Method to browse the part rooted at sRootPath 
     of the configuration that the Provider provides.
 
     All nodes will be processed by the IConfigurationProcessor passed.
  */
 public void browseConfiguration(String sRootPath, IConfigurationProcessor aProcessor)
         throws com.sun.star.uno.Exception {
 
     // create the root element
     XInterface xViewRoot = (XInterface)createConfigurationView(sRootPath);
     
     // now do the processing
     browseElementRecursively(xViewRoot, aProcessor);
     
     // we are done with the view - dispose it 
     // This assumes that the processor 
     // does not keep a reference to the elements in processStructuralElement
     
     ((XComponent) UnoRuntime.queryInterface(XComponent.class,xViewRoot)).dispose();
     xViewRoot = null;
 }

Finally, as an example of how to put the code to use, the following is code to print the currently registered file filters:

 /** Method to browse the filter configuration.
 
     Information about installed filters will be printed.
  */
 public void printRegisteredFilters() throws com.sun.star.uno.Exception {
     final String sProviderService = "com.sun.star.configuration.ConfigurationProvider";
     final String sFilterKey = "/org.openoffice.Office.TypeDetection/Filters";
     
     // browse the configuration, dumping filter information
     browseConfiguration( sFilterKey, 
         new IConfigurationProcessor () { // anonymous implementation of our custom interface
             // prints Path and Value of properties
             public void processValueElement(String sPath_, Object aValue_) {
                 System.out.println("\tValue: " + sPath_ + " = " + aValue_);
             }
             // prints the Filter entries
             public void processStructuralElement( String sPath_, XInterface xElement_) {
                 // get template information, to detect instances of the 'Filter' template
                 XTemplateInstance xInstance = 
                     ( XTemplateInstance )UnoRuntime.queryInterface( XTemplateInstance .class,xElement_);
                 
                 // only select the Filter entries 
                 if (xInstance != null && xInstance.getTemplateName().endsWith("Filter")) {
                     XNamed xNamed = (XNamed)UnoRuntime.queryInterface(XNamed.class,xElement_);
                     System.out.println("Filter " + xNamed.getName() + " (" + sPath_ + ")");
                 }
             }   
         } 
     );
 }

For access to sub-nodes, a com.sun.star.configuration.ConfigurationAccess supports container interfaces com.sun.star.container.XNameAccess and com.sun.star.container.XChild. These interfaces access the immediate child nodes in the hierarchy , as well as com.sun.star.container.XHierarchicalNameAccess for direct access to items that are nested deeply.

These interfaces are uniformly supported by all structural configuration items. Therefore, they are utilized by code that browses a sub-tree of the configuration in a generic manner.

Parts of the hierarchy where the structure is known statically can also be viewed as representing a complex object composed of properties, that are composed of sub-properties themselves. This model is supported by the interface com.sun.star.beans.XPropertySet for child access and com.sun.star.beans.XHierarchicalPropertySet for access to deeply nested properties within such parts of the hierarchy. Due to the static nature of property sets, this model does not carry over to set nodes that are dynamic in nature and do not support the associated interfaces.

For effective access to multiple properties, the corresponding com.sun.star.beans.XMultiPropertySet and com.sun.star.beans.XMultiHierarchicalPropertySet interfaces are supported.

Template:Documentation/Note

Typically, these interfaces are used to access a known set of preferences. The following example reads grid option settings from the OpenOffice.org Calc configuration into this structure:

 class GridOptions
 {
     public boolean visible;
     public int resolution_x;
     public int resolution_y;
     public int subdivision_x;
     public int subdivision_y;
 };

These data may be read by a procedure such as the following. It demonstrates different approaches to read data:

 // This method reads information about grid settings
 protected GridOptions readGridConfiguration() throws com.sun.star.uno.Exception {
     // The path to the root element 
     final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid";
     
     // create the view
     Object xViewRoot = createConfigurationView(cGridOptionsPath);
     
     // the result structure
     GridOptions options = new GridOptions();
     
     // accessing a single nested value
     // the item /org.openoffice.Office.Calc/Grid/Option/VisibleGrid is a boolean data item
     XHierarchicalPropertySet xProperties = 
         (XHierarchicalPropertySet)UnoRuntime.queryInterface(XHierarchicalPropertySet.class, xViewRoot);
     
     Object aVisible = xProperties.getHierarchicalPropertyValue("Option/VisibleGrid");
     options.visible = ((Boolean) aVisible).booleanValue();
     
     // accessing a nested object and its subproperties
     // the item /org.openoffice.Office.Calc/Grid/Subdivision has sub-properties XAxis and YAxis
     Object xSubdivision = xProperties.getHierarchicalPropertyValue("Subdivision");
     
     XMultiPropertySet xSubdivProperties = (XMultiPropertySet)UnoRuntime.queryInterface(
         XMultiPropertySet.class, xSubdivision);
     
     // String array containing property names of sub-properties
     String[] aElementNames = new String[2];
     
     aElementNames[0] = "XAxis";
     aElementNames[1] = "YAxis";
     
     // getPropertyVAlues() returns an array of any objects according to the input array aElementNames
     Object[] aElementValues = xSubdivProperties.getPropertyValues(aElementNames);
     
     options.subdivision_x = ((Integer) aElementValues[0]).intValue();
     options.subdivision_y = ((Integer) aElementValues[1]).intValue();
     
     // accessing deeply nested subproperties
     // the item /org.openoffice.Office.Calc/Grid/Resolution has sub-properties
     // XAxis/Metric and YAxis/Metric
     Object xResolution = xProperties.getHierarchicalPropertyValue("Resolution");
     
     XMultiHierarchicalPropertySet xResolutionProperties = (XMultiHierarchicalPropertySet)
         UnoRuntime.queryInterface(XMultiHierarchicalPropertySet.class, xResolution);
     
     aElementNames[0] = "XAxis/Metric";
     aElementNames[1] = "YAxis/Metric";
     
     aElementValues = xResolutionProperties.getHierarchicalPropertyValues(aElementNames);
     
     options.resolution_x = ((Integer) aElementValues[0]).intValue();
     options.resolution_y = ((Integer) aElementValues[1]).intValue();
     
     // all options have been retrieved - clean up and return
     // we are done with the view - dispose it 
     
     ((XComponent)UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose();
     
     return options;
 }

A com.sun.star.configuration.ConfigurationAccess also supports the interfaces com.sun.star.container.XNamed, com.sun.star.container.XHierarchicalName and com.sun.star.beans.XPropertySetInfo to retrieve information about the node, as well as interface com.sun.star.container.XChild to get the parent within the hierarchy. To monitor changes to specific items, register listeners at the interfaces com.sun.star.container.XContainer and com.sun.star.beans.XPropertySet.

The exact set of interfaces supported depends on the role of the node in the hierarchy. For example, a set node does not support com.sun.star.beans.XPropertySet and related interfaces, but it supports com.sun.star.configuration.XTemplateContainer to get information about the template that specifies the schema of elements. The root object of a configuration view does not support com.sun.star.container.XChild, but it supports com.sun.star.util.XChangesNotifier to monitor all changes in the whole view.

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools