Reading Configuration Data
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.
In a read-only view, all properties are marked as READONLY in com.sun.star.beans.XPropertySetInfo. Attempts to use setPropertyValue() to change the value of a property fail accordingly. |
Typically, these interfaces are used to access a known set of preferences. The following example reads grid option settings from the Apache OpenOffice 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). |