summaryrefslogtreecommitdiff
path: root/odk/examples/DevelopersGuide/Config/ConfigExamples.java
diff options
context:
space:
mode:
Diffstat (limited to 'odk/examples/DevelopersGuide/Config/ConfigExamples.java')
-rw-r--r--odk/examples/DevelopersGuide/Config/ConfigExamples.java1202
1 files changed, 1202 insertions, 0 deletions
diff --git a/odk/examples/DevelopersGuide/Config/ConfigExamples.java b/odk/examples/DevelopersGuide/Config/ConfigExamples.java
new file mode 100644
index 000000000000..a88127ef1053
--- /dev/null
+++ b/odk/examples/DevelopersGuide/Config/ConfigExamples.java
@@ -0,0 +1,1202 @@
+/*************************************************************************
+ *
+ * The Contents of this file are made available subject to the terms of
+ * the BSD license.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Sun Microsystems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *************************************************************************/
+
+// Import everything we use
+
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.XMultiPropertySet;
+import com.sun.star.beans.XHierarchicalPropertySet;
+import com.sun.star.beans.XMultiHierarchicalPropertySet;
+import com.sun.star.beans.XPropertyState;
+import com.sun.star.beans.XMultiPropertyStates;
+
+import com.sun.star.bridge.XUnoUrlResolver;
+
+import com.sun.star.configuration.XTemplateInstance;
+
+import com.sun.star.container.XNameAccess;
+import com.sun.star.container.XNameReplace;
+import com.sun.star.container.XNameContainer;
+import com.sun.star.container.XNamed;
+import com.sun.star.container.XChild;
+import com.sun.star.container.XHierarchicalNameAccess;
+import com.sun.star.container.XHierarchicalName;
+
+import com.sun.star.lang.XComponent;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lang.EventObject;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import com.sun.star.uno.XNamingService;
+import com.sun.star.uno.AnyConverter;
+
+import com.sun.star.util.XChangesBatch;
+import com.sun.star.util.XChangesNotifier;
+import com.sun.star.util.XChangesListener;
+import com.sun.star.util.ChangesEvent;
+/** Config examples
+ @author Joerg Barfurth
+ */
+
+/* These examples show how to use the following features of the Config API:
+
+ o Accessing data
+ o Updating data synchronously and asynchronously
+ o Updating properties in groups
+ o Adding and removing items in sets
+ o Resetting data to their defaults
+
+ Each example is in a separate method call.
+*/
+public class ConfigExamples
+{
+ // The ComponentContext interface of the remote component context
+ private XComponentContext mxContext = null;
+
+ // The MultiComponentFactory interface of the ServiceManager
+ private XMultiComponentFactory mxServiceManager = null;
+
+ // The MultiServiceFactory interface of the ConfigurationProvider
+ private XMultiServiceFactory mxProvider = null;
+
+ public static void main( String args[] )
+ {
+ try {
+ // get the remote office component context
+ com.sun.star.uno.XComponentContext xContext =
+ com.sun.star.comp.helper.Bootstrap.bootstrap();
+
+ if( xContext != null )
+ System.out.println("Connected to a running office ...");
+ else
+ System.out.println( "ERROR: Cannot connect - no remote component context available." );
+
+ // Create an instance of the class and call it's run method
+ ConfigExamples aExample = new ConfigExamples(xContext);
+ aExample.run( );
+
+ // if you own the service manager dispose it here
+ // to ensure that the default provider is properly disposed and flushed
+ System.exit(0);
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ System.exit(-1);
+ }
+ }
+
+ /** Create a ConfigExamples instance supplying a service factory
+ */
+ public ConfigExamples(XComponentContext xContext)
+ {
+ mxContext = xContext;
+ mxServiceManager = xContext.getServiceManager();
+ }
+
+ /** Run the examples with a default ConfigurationProvider
+ */
+ public void run()
+ throws com.sun.star.uno.Exception
+ {
+ mxProvider = createProvider();
+
+ runExamples( );
+
+ // we are using the default ConfigurationProvider, so we must not dispose it
+ mxProvider = null;
+ }
+
+ /** Run the examples with an AdministrationProvider
+ */
+ public void runForAdmin(Object [] aAdminArgs)
+ throws com.sun.star.uno.Exception
+ {
+ mxProvider = createAdminProvider(aAdminArgs);
+
+ runExamples( );
+
+ // this is not the default ConfigurationProvider, so we can dispose it
+ ((XComponent)UnoRuntime.queryInterface( XComponent.class, mxProvider )).dispose();
+ mxProvider = null;
+ }
+
+ /** Run the examples with a given ConfigurationProvider
+ */
+ public void runExamples( )
+ {
+ if (checkProvider(mxProvider))
+ {
+ System.out.println("\nStarting examples.");
+
+ readDataExample();
+
+ browseDataExample();
+
+ updateGroupSyncExample();
+
+ resetGroupExample();
+
+ updateSetAsyncExample();
+
+ System.out.println("\nAll Examples completed.");
+ }
+ else
+ System.out.println("ERROR: Cannot run examples without ConfigurationProvider.");
+
+ }
+
+ /** Do some simple checks, if tehre is a valid ConfigurationProvider
+ */
+ public static boolean checkProvider(XMultiServiceFactory xProvider)
+ {
+ // check the provider we have
+ if (xProvider == null)
+ {
+ System.out.println("No provider available. Cannot access configuration data.");
+ return false;
+
+ }
+
+ try
+ {
+ // check the provider implementation
+ XServiceInfo xProviderServices =
+ (XServiceInfo) UnoRuntime.queryInterface( XServiceInfo.class, xProvider );
+
+ if (xProviderServices == null ||
+ !xProviderServices.supportsService("com.sun.star.configuration.ConfigurationProvider"))
+ {
+ System.out.println("WARNING: The provider is not a com.sun.star.configuration.ConfigurationProvider");
+ }
+
+ if (xProviderServices != null)
+ {
+ System.out.println("Using provider implementation: " + xProviderServices.getImplementationName());
+ }
+
+ return true;
+ }
+ catch (com.sun.star.uno.RuntimeException e)
+ {
+ System.err.println("ERROR: Failure while checking the provider services.");
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /** Get the provider we have
+ */
+ public XMultiServiceFactory getProvider( )
+ {
+ return mxProvider;
+ }
+
+ /** Create a default configuration provider
+ */
+ public XMultiServiceFactory createProvider( )
+ throws com.sun.star.uno.Exception
+ {
+ final String sProviderService = "com.sun.star.configuration.ConfigurationProvider";
+
+ // create the provider and return it as a XMultiServiceFactory
+ XMultiServiceFactory xProvider = (XMultiServiceFactory)
+ UnoRuntime.queryInterface(XMultiServiceFactory.class,
+ mxServiceManager.createInstanceWithContext(sProviderService,
+ mxContext));
+
+ return xProvider;
+ }
+
+ /** Create an administration provider
+
+ @param aAdminArguments
+ An array of extra arguments to be used to create the provider
+ */
+ public XMultiServiceFactory createAdminProvider(Object[] aAdminArguments)
+ throws com.sun.star.uno.Exception
+ {
+ final String sAdminService = "com.sun.star.configuration.AdministrationProvider";
+
+ // create the provider and remember it as a XMultiServiceFactory
+ XMultiServiceFactory xAdminProvider = (XMultiServiceFactory)
+ UnoRuntime.queryInterface(XMultiServiceFactory.class,
+ mxServiceManager.createInstanceWithArgumentsAndContext(
+ sAdminService, aAdminArguments, mxContext));
+
+ return xAdminProvider;
+ }
+
+ /** Create a specified read-only configuration view
+ */
+ public Object createConfigurationView( String sPath )
+ throws com.sun.star.uno.Exception
+ {
+ XMultiServiceFactory xProvider = getProvider();
+
+ // The service name: Need only read access:
+ final String sReadOnlyView = "com.sun.star.configuration.ConfigurationAccess";
+
+ // creation arguments: nodepath
+ com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue();
+ aPathArgument.Name = "nodepath";
+ aPathArgument.Value = sPath;
+
+ Object[] aArguments = new Object[1];
+ aArguments[0] = aPathArgument;
+
+ // create the view
+ Object xViewRoot = xProvider.createInstanceWithArguments(sReadOnlyView, aArguments);
+
+ return xViewRoot;
+ }
+
+ /** Create a specified updatable configuration view using default synchronicity
+ */
+ Object createUpdatableView( String sPath )
+ throws com.sun.star.uno.Exception
+ {
+ XMultiServiceFactory xProvider = getProvider();
+
+ // The service name: Need update access:
+ final String cUpdatableView = "com.sun.star.configuration.ConfigurationUpdateAccess";
+
+ // creation arguments: nodepath
+ com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue();
+ aPathArgument.Name = "nodepath";
+ aPathArgument.Value = sPath;
+
+ Object[] aArguments = new Object[1];
+ aArguments[0] = aPathArgument;
+
+ // create the view
+ Object xViewRoot = xProvider.createInstanceWithArguments(cUpdatableView, aArguments);
+
+ return xViewRoot;
+ }
+
+ /** Create a specified updatable configuration view
+ */
+ Object createUpdatableView( String sPath, boolean bAsync )
+ throws com.sun.star.uno.Exception
+ {
+ XMultiServiceFactory xProvider = getProvider();
+
+ // The service name: Need update access:
+ final String cUpdatableView = "com.sun.star.configuration.ConfigurationUpdateAccess";
+
+ // creation arguments: nodepath
+ com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue();
+ aPathArgument.Name = "nodepath";
+ aPathArgument.Value = sPath;
+
+ // creation arguments: commit mode - write-through or write-back
+ com.sun.star.beans.PropertyValue aModeArgument = new com.sun.star.beans.PropertyValue();
+ aModeArgument.Name = "lazywrite";
+ aModeArgument.Value = new Boolean(bAsync);
+
+ Object[] aArguments = new Object[2];
+ aArguments[0] = aPathArgument;
+ aArguments[1] = aModeArgument;
+
+ // create the view
+ Object xViewRoot = xProvider.createInstanceWithArguments(cUpdatableView, aArguments);
+
+ return xViewRoot;
+ }
+
+ /** This method demonstrates read access to data
+ */
+ protected void readDataExample ()
+ {
+ try
+ {
+ System.out.println("\n--- starting example: read grid option settings --------------------");
+ Object aData = readGridConfiguration( );
+ System.out.println("Read grid options: " + aData);
+
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /** This method demonstrates browsing access to data
+ */
+ protected void browseDataExample ()
+ {
+ try
+ {
+ System.out.println("\n--- starting example: browse filter configuration ------------------");
+ printRegisteredFilters( );
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /** This method demonstrates synchronous update access to group data
+ */
+ protected void updateGroupSyncExample ()
+ {
+ try
+ {
+ System.out.println("\n--- starting example: update group data synchronously --------------");
+ editGridOptions( );
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /** This method demonstrates resetting data to its default state
+ */
+ protected void resetGroupExample ()
+ {
+ try
+ {
+ System.out.println("\n--- starting example: reset group data -----------------------------");
+ Object aOldData = readGridConfiguration( );
+ resetGridConfiguration( );
+ Object aNewData = readGridConfiguration( );
+ System.out.println("Before reset: user grid options: " + aOldData);
+ System.out.println("After reset: default grid options: " + aNewData);
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /** This method demonstrates asynchronous update access to set data
+ */
+ protected void updateSetAsyncExample ()
+ {
+ try
+ {
+ System.out.println("\n--- starting example: update set data asynchronously ---------------");
+ storeSampleDataSource( );
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+// READ example
+ /// class to hold information about grid settings
+ public static class GridOptions
+ {
+ public boolean visible;
+ public int resolution_x;
+ public int resolution_y;
+ public int subdivision_x;
+ public int subdivision_y;
+
+ public String toString() {
+ StringBuffer aBuffer = new StringBuffer();
+ aBuffer.append("[ Grid is "); aBuffer.append(visible ? "VISIBLE" : "HIDDEN");
+ aBuffer.append("; resolution = (" + resolution_x + "," + resolution_y + ")");
+ aBuffer.append("; subdivision = (" + subdivision_x + "," + subdivision_y + ")");
+ aBuffer.append(" ]");
+ return aBuffer.toString();
+ }
+ };
+
+ /// 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
+ 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
+ Object xSubdivision = xProperties.getHierarchicalPropertyValue("Subdivision");
+
+ XMultiPropertySet xSubdivProperties =
+ (XMultiPropertySet)UnoRuntime.queryInterface(XMultiPropertySet.class, xSubdivision);
+
+ // variables for multi-element access
+ String[] aElementNames = new String[2];
+
+ aElementNames[0] = "XAxis";
+ aElementNames[1] = "YAxis";
+
+ Object[] aElementValues = xSubdivProperties.getPropertyValues(aElementNames);
+
+ options.subdivision_x = ((Integer) aElementValues[0]).intValue();
+ options.subdivision_y = ((Integer) aElementValues[1]).intValue();
+
+ // accessing deeply nested subproperties
+ 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;
+ }
+
+// BROWSE example
+ /// Interface to procees information when browsing the configuration tree
+ public static 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_);
+ };
+
+ /// Internal method to recursively browse a structural element 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();
+
+ aProcessor.processStructuralElement( sPath, xElement);
+
+ // now process this as a container
+ 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] );
+ AnyConverter aAnyConv = new AnyConverter();
+ // is it a structural element (object) ...
+ if ( aAnyConv.isObject(aChild) && !aAnyConv.isArray(aChild) )
+ {
+ // then get an interface
+ XInterface xChildElement = (XInterface)UnoRuntime.queryInterface(XInterface.class, 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 );
+ }
+ }
+ }
+
+ /** 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;
+ }
+
+ /** 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.TypeDetection.Filter/Filters";
+
+ // browse the configuration, dumping filter information
+ browseConfiguration( sFilterKey,
+ new IConfigurationProcessor () {
+ /// prints Path and Value of properties
+ public void processValueElement( String sPath_, Object aValue_ ) {
+ if (new AnyConverter().isArray(aValue_))
+ {
+ final Object [] aArray = (Object [])aValue_;
+
+ System.out.print("\tValue: " + sPath_ + " = { ");
+ for (int i=0; i<aArray.length; ++i)
+ {
+ if (i != 0) System.out.print(", ");
+ System.out.print(aArray[i]);
+ }
+ System.out.println(" }");
+ }
+ else
+ 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_ + ")");
+ }
+ }
+ } );
+ }
+
+// GROUP UPDATE example
+
+ /** This method simulates editing configuration data using a GridEditor dialog class
+ */
+ public void editGridOptions( )
+ throws com.sun.star.uno.Exception
+ {
+ // The path to the root element
+ final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid";
+
+ // create the SYNCHRONOUS view for better error handling
+ Object xViewRoot = createUpdatableView( cGridOptionsPath, false);
+
+ // the 'editor'
+ GridOptionsEditor dialog = new GridOptionsEditor();
+
+ // set up the initial values and register listeners
+ // get a data access interface, to supply the view with a model
+ XMultiHierarchicalPropertySet xProperties =
+ (XMultiHierarchicalPropertySet)
+ UnoRuntime.queryInterface(XMultiHierarchicalPropertySet.class, xViewRoot);
+
+ dialog.setModel( xProperties );
+
+ // get a listener object (probably an adapter) that notifies
+ // the dialog of external changes to its model
+ XChangesListener xListener = dialog.createChangesListener( );
+
+ XChangesNotifier xNotifier =
+ (XChangesNotifier)UnoRuntime.queryInterface(XChangesNotifier.class, xViewRoot);
+
+ xNotifier.addChangesListener( xListener );
+
+ // trigger the listener
+ changeSomeData( cGridOptionsPath + "/Subdivision" );
+
+ if (dialog.execute() == GridOptionsEditor.SAVE_SETTINGS)
+ {
+ // changes have been applied to the view here
+ XChangesBatch xUpdateControl =
+ (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot);
+
+ try
+ {
+ xUpdateControl.commitChanges();
+ }
+ catch (Exception e)
+ {
+ dialog.informUserOfError( e );
+ }
+ }
+
+ // all changes have been handled - clean up and return
+ // listener is done now
+ xNotifier.removeChangesListener( xListener );
+
+ // we are done with the view - dispose it
+ ((XComponent)UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose();
+ }
+
+ /** A class that changes some grid options settings
+
+ The interface of this class is chose to resemble a possible UI dialog class
+ */
+ private class GridOptionsEditor {
+ /// the data this editor edits
+ XMultiHierarchicalPropertySet mxModel;
+
+ public static final int CANCELED = 0;
+ public static final int SAVE_SETTINGS = 1;
+
+ // sets a model and updates the display
+ public void setModel(XMultiHierarchicalPropertySet xModel) {
+ mxModel = xModel;
+ updateDisplay();
+ }
+
+ // this method 'runs' the 'dialog'
+ public int execute() {
+ try
+ {
+ System.out.println("-- GridEditor executing --");
+ // simulate a user action changing some data
+ toggleVisibility();
+ System.out.println("-- GridEditor done --");
+ return SAVE_SETTINGS;
+ }
+ catch (Exception e)
+ {
+ informUserOfError(e);
+ return CANCELED;
+ }
+ }
+
+ /// this method is called to report an error during dialog execution to the zuser
+ public void informUserOfError(Exception e) {
+ System.err.println("ERROR in GridEditor:");
+ e.printStackTrace();
+ }
+
+ /// this method is called to allow the dialog to get feedback about changes occurring elsewhere
+ public XChangesListener createChangesListener() {
+ if (mxModel == null) return null;
+
+ return (new XChangesListener () {
+ public void changesOccurred( ChangesEvent event ) {
+ System.out.println("GridEditor - Listener received changes event containing " +
+ event.Changes.length + " change(s).");
+ updateDisplay();
+ }
+
+ public void disposing(EventObject event) {
+ System.out.println("GridEditor - Listener received disposed event: releasing model");
+ setModel(null);
+ }
+ });
+ }
+ /// this method is called when data has changed to display the updated data
+ private void updateDisplay() {
+ if (mxModel != null)
+ System.out.println("Grid options editor: data=" + readModel());
+ else
+ System.out.println("Grid options editor: no model set");
+ }
+
+ // this method is used to read all relevant data from the model
+ private GridOptions readModel()
+ {
+ try
+ {
+ String [] aOptionNames = new String [5];
+ aOptionNames[0] = "Option/VisibleGrid";
+ aOptionNames[1] = "Subdivision/XAxis";
+ aOptionNames[2] = "Subdivision/YAxis";
+ aOptionNames[3] = "Resolution/XAxis/Metric";
+ aOptionNames[4] = "Resolution/YAxis/Metric";
+
+ Object [] aValues = mxModel.getHierarchicalPropertyValues(aOptionNames);
+
+ GridOptions result = new GridOptions();
+ result.visible = ((Boolean)aValues[0]).booleanValue();
+ result.subdivision_x = ((Integer)aValues[1]).intValue();
+ result.subdivision_y = ((Integer)aValues[2]).intValue();
+ result.resolution_x = ((Integer)aValues[3]).intValue();
+ result.resolution_y = ((Integer)aValues[4]).intValue();
+
+ return result;
+ }
+ catch (Exception e)
+ {
+ informUserOfError(e);
+ return null;
+ }
+ }
+
+ // this method executes an edit
+ private void toggleVisibility()
+ {
+ try
+ {
+ XHierarchicalPropertySet xHPS =
+ (XHierarchicalPropertySet)UnoRuntime.queryInterface(XHierarchicalPropertySet.class, mxModel);
+
+ final String sSetting = "Option/VisibleGrid";
+
+ System.out.println("GridEditor: toggling Visibility");
+
+ Boolean bOldValue = (Boolean)xHPS.getHierarchicalPropertyValue(sSetting);
+
+ Boolean bNewValue = new Boolean( ! bOldValue.booleanValue() );
+
+ xHPS.setHierarchicalPropertyValue(sSetting,bNewValue);
+ }
+ catch (Exception e)
+ {
+ informUserOfError(e);
+ }
+ }
+ }
+
+ /** This method creates an extra updatable view to change some data
+ and trigger the listener of the GridEditor
+ */
+ void changeSomeData(String xKey)
+ {
+ try
+ {
+ Object xOtherViewRoot = createUpdatableView(xKey, false);
+
+ XNameReplace aReplace = (XNameReplace)UnoRuntime.queryInterface(XNameReplace.class, xOtherViewRoot);
+
+ String aItemNames [] = aReplace.getElementNames();
+ for (int i=0; i < aItemNames.length; ++i) {
+ Object aItem = aReplace.getByName( aItemNames [i] );
+ AnyConverter aAnyConv = new AnyConverter();
+ // replace integers by a 'complement' value
+ if ( aAnyConv.isInt(aItem) )
+ {
+ int nOld = aAnyConv.toInt(aItem);
+ int nNew = 9999 - nOld;
+
+ System.out.println("Replacing integer value: " + aItemNames [i]);
+ aReplace.replaceByName( aItemNames [i], new Integer( nNew ) );
+ }
+
+ // and booleans by their negated value
+ else if ( aAnyConv.isBoolean(aItem) )
+ {
+ boolean bOld = aAnyConv.toBoolean(aItem);
+ boolean bNew = ! bOld;
+
+ System.out.println("Replacing boolean value: " + aItemNames [i]);
+ aReplace.replaceByName( aItemNames [i], new Boolean( bNew ) );
+ }
+ }
+
+ // commit the changes
+ XChangesBatch xUpdateControl =
+ (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class,xOtherViewRoot);
+
+ xUpdateControl.commitChanges();
+
+ // we are done with the view - dispose it
+ ((XComponent)UnoRuntime.queryInterface(XComponent.class, xOtherViewRoot)).dispose();
+ }
+ catch (Exception e)
+ {
+ System.err.println("Could not change some data in a different view. An exception occurred:");
+ e.printStackTrace();
+ }
+ }
+
+// GROUP RESET EXAMPLE
+ /// This method resets the grid settings to their default values
+ protected void resetGridConfiguration()
+ 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 = createUpdatableView(cGridOptionsPath);
+
+ // resetting a single nested value
+ XHierarchicalNameAccess xHierarchicalAccess =
+ (XHierarchicalNameAccess)UnoRuntime.queryInterface(XHierarchicalNameAccess.class, xViewRoot);
+
+ // get using absolute name
+ Object xOptions = xHierarchicalAccess.getByHierarchicalName(cGridOptionsPath + "/Option");
+
+ XPropertyState xOptionState =
+ (XPropertyState)UnoRuntime.queryInterface(XPropertyState.class, xOptions);
+
+ xOptionState.setPropertyToDefault("VisibleGrid");
+
+ // resetting more deeply nested values
+ Object xResolutionX = xHierarchicalAccess.getByHierarchicalName("Resolution/XAxis");
+ Object xResolutionY = xHierarchicalAccess.getByHierarchicalName("Resolution/YAxis");
+
+ XPropertyState xResolutionStateX =
+ (XPropertyState)UnoRuntime.queryInterface(XPropertyState.class, xResolutionX);
+ XPropertyState xResolutionStateY =
+ (XPropertyState)UnoRuntime.queryInterface(XPropertyState.class, xResolutionY);
+
+ xResolutionStateX.setPropertyToDefault("Metric");
+ xResolutionStateY.setPropertyToDefault("Metric");
+
+ // resetting multiple sibling values
+ Object xSubdivision = xHierarchicalAccess.getByHierarchicalName("Subdivision");
+
+ XMultiPropertyStates xSubdivisionStates =
+ (XMultiPropertyStates)UnoRuntime.queryInterface(XMultiPropertyStates.class, xSubdivision);
+
+ xSubdivisionStates.setAllPropertiesToDefault();
+
+ // commit the changes
+ XChangesBatch xUpdateControl =
+ (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot);
+
+ xUpdateControl.commitChanges();
+
+ // we are done with the view - dispose it
+ ((XComponent)UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose();
+ }
+
+
+// SET UPDATE EXAMPLE
+ private static boolean SET_EXAMPLE_BROKEN_IN_THIS_RELEASE = true;
+
+ /** This method stores a sample data source given some connection data.
+
+ ATTENTION: This example requires an older version of the
+ org.openoffice.Office.DataAccess schema.
+ It does not work with the current schema.
+ Because of this, the method currenty does nothing.
+ You can still use the techniques shown in the example code.
+ */
+ void storeSampleDataSource()
+ throws com.sun.star.uno.Exception
+ {
+ if (SET_EXAMPLE_BROKEN_IN_THIS_RELEASE)
+ {
+ System.out.println("- DISABLED: (the existing example does not work with this version) -");
+ return; // this function does not work
+ }
+
+ String sSampleDataSourceName = "SampleTextDatabase";
+
+ String sSampleDataSourceURL = "sdbc:flat:$(userurl)/database/SampleTextDatabase";
+ // String sSampleDataSourceURL = "sdbc:flat:file:///usr/local/database/SampleTextDatabase";
+ // String sSampleDataSourceURL = "sdbc:flat:file:///C:/data/database/SampleTextDatabase";
+
+ com.sun.star.beans.NamedValue [] aSettings = new com.sun.star.beans.NamedValue [2];
+ aSettings[0] = new com.sun.star.beans.NamedValue("HeaderLine",new Boolean(true));
+ aSettings[1] = new com.sun.star.beans.NamedValue("FieldDelimiter",";");
+
+ String [] aTableFilter = new String[2];
+ aTableFilter[0] = "table.txt";
+ aTableFilter[1] = "othertable.txt";
+
+ storeDataSource(sSampleDataSourceName,sSampleDataSourceURL,"",false,0,aSettings,aTableFilter);
+ }
+
+ /// This method stores a data source given some connection data
+ void storeDataSource(
+ String sDataSourceName,
+ String sDataSourceURL,
+ String sUser,
+ boolean bNeedsPassword,
+ int nTimeout,
+ com.sun.star.beans.NamedValue [] aDriverSettings,
+ String [] aTableFilter
+ )
+ throws com.sun.star.uno.Exception
+ {
+ // create the view and get the data source element
+ Object xDataSource = createDataSourceDescription(getProvider(),sDataSourceName);
+
+ // set the values
+ XPropertySet xDataSourceProperties =
+ (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, xDataSource);
+
+ xDataSourceProperties.setPropertyValue("URL", sDataSourceURL );
+ xDataSourceProperties.setPropertyValue("User", sUser );
+ xDataSourceProperties.setPropertyValue("IsPasswordRequired", new Boolean( bNeedsPassword ) );
+ xDataSourceProperties.setPropertyValue("LoginTimeout", new Integer( nTimeout ) );
+
+ if ( aTableFilter != null )
+ xDataSourceProperties.setPropertyValue("TableFilter", aTableFilter );
+
+ // store the driver-specific settings
+ if (aDriverSettings != null)
+ {
+ Object xSettingsSet = xDataSourceProperties.getPropertyValue("DataSourceSettings");
+ storeSettings( xSettingsSet, aDriverSettings);
+ }
+
+ // save the data and dispose the view
+ // recover the view root
+ Object xViewRoot = getViewRoot(xDataSource);
+
+ // commit the changes
+ XChangesBatch xUpdateControl =
+ (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot);
+
+ xUpdateControl.commitChanges();
+
+ // now clean up
+ ((XComponent) UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose();
+ }
+
+ /** This method gets the DataSourceDescription for a data source.
+ It either gets the existing entry or creates a new instance.
+
+ The method attempts to keep the view used as small as possible. In particular there
+ is no view created, that contains data for all data source that are registered.
+ */
+ Object createDataSourceDescription(XMultiServiceFactory xProvider, String sDataSourceName )
+ throws com.sun.star.uno.Exception
+ {
+ // The service name: Need an update access:
+ final String cUpdatableView = "com.sun.star.configuration.ConfigurationUpdateAccess";
+
+ // The path to the DataSources set node
+ final String cDataSourcesPath = "/org.openoffice.Office.DataAccess/DataSources";
+
+ // creation arguments: nodepath
+ com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue();
+ aPathArgument.Name = "nodepath";
+ aPathArgument.Value = cDataSourcesPath ;
+
+ // creation arguments: commit mode
+ com.sun.star.beans.PropertyValue aModeArgument = new com.sun.star.beans.PropertyValue();
+ aModeArgument.Name = "lazywrite";
+ aModeArgument.Value = new Boolean( true );
+
+ // creation arguments: depth
+ com.sun.star.beans.PropertyValue aDepthArgument = new com.sun.star.beans.PropertyValue();
+ aDepthArgument.Name = "depth";
+ aDepthArgument.Value = new Integer( 1 );
+
+ Object[] aArguments = new Object[3];
+ aArguments[0] = aPathArgument;
+ aArguments[1] = aModeArgument;
+ aArguments[2] = aDepthArgument;
+
+ // create the view: asynchronously updatable, with depth 1
+ Object xViewRoot =
+ xProvider.createInstanceWithArguments(cUpdatableView, aArguments);
+
+ XNameAccess xSetOfDataSources =
+ (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class,xViewRoot);
+
+ Object xDataSourceDescriptor = null; // the result
+ if ( xSetOfDataSources .hasByName( sDataSourceName ))
+ {
+ // the element is there, but it is loaded only with depth zero !
+ try
+ {
+ // the view should point to the element directly, so we need to extend the path
+ XHierarchicalName xComposePath = (XHierarchicalName)
+ UnoRuntime.queryInterface(XHierarchicalName.class, xSetOfDataSources );
+
+ String sElementPath = xComposePath.composeHierarchicalName( sDataSourceName );
+
+ // use the name of the element now
+ aPathArgument.Value = sElementPath;
+
+ // create another view now (without depth limit)
+ Object[] aDeepArguments = new Object[2];
+ aDeepArguments[0] = aPathArgument;
+ aDeepArguments[1] = aModeArgument;
+
+ // create the view: asynchronously updatable, with unlimited depth
+ xDataSourceDescriptor =
+ xProvider.createInstanceWithArguments(cUpdatableView, aDeepArguments);
+
+ if ( xDataSourceDescriptor != null) // all went fine
+ {
+ // dispose the other view
+ ((XComponent)UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose();
+ xViewRoot = null;
+ }
+ }
+ catch (Exception e)
+ {
+ // something went wrong, we retry with a new element
+ System.err.println("WARNING: An exception occurred while creating a view for an existing data source: " + e);
+ xDataSourceDescriptor = null;
+ }
+ }
+
+ // do we have a result element yet ?
+ if ( xDataSourceDescriptor == null)
+ {
+ // get the container
+ XNameContainer xSetUpdate =
+ (XNameContainer)UnoRuntime.queryInterface(XNameContainer.class, xViewRoot);
+
+ // create a new detached set element (instance of DataSourceDescription)
+ XSingleServiceFactory xElementFactory =
+ (XSingleServiceFactory)UnoRuntime.queryInterface(XSingleServiceFactory.class, xSetUpdate);
+
+ // the new element is the result !
+ xDataSourceDescriptor = xElementFactory.createInstance();
+
+ // insert it - this also names the element
+ xSetUpdate.insertByName( sDataSourceName , xDataSourceDescriptor );
+ }
+
+ return xDataSourceDescriptor ;
+ }
+
+ /// this method stores a number of settings in a set node containing DataSourceSetting objects
+ void storeSettings(Object xSettingsSet, com.sun.star.beans.NamedValue [] aSettings )
+ throws com.sun.star.uno.Exception
+ {
+ if (aSettings == null)
+ return;
+
+ // get the settings set as a container
+ XNameContainer xSettingsContainer =
+ (XNameContainer) UnoRuntime.queryInterface( XNameContainer.class, xSettingsSet);
+
+ // and get a factory interface for creating the entries
+ XSingleServiceFactory xSettingsFactory =
+ (XSingleServiceFactory) UnoRuntime.queryInterface(XSingleServiceFactory.class, xSettingsSet);
+
+ // now insert the individual settings
+ for (int i = 0; i < aSettings.length; ++i) {
+ // create a DataSourceSetting object
+ XPropertySet xSetting = (XPropertySet)
+ UnoRuntime.queryInterface( XPropertySet.class, xSettingsFactory.createInstance() );
+
+ // can set the value before inserting
+ xSetting.setPropertyValue( "Value", aSettings[i].Value );
+
+ // and now insert or replace as appropriate
+ if (xSettingsContainer.hasByName( aSettings[i].Name ))
+ xSettingsContainer.replaceByName( aSettings[i].Name, xSetting );
+ else
+ xSettingsContainer.insertByName( aSettings[i].Name, xSetting );
+ }
+ }
+
+// HELPER FUNCTIONS
+
+ /// This method get the view root node given an interface to any node in the view
+ public static Object getViewRoot(Object xElement)
+ {
+ Object xResult = xElement;
+
+ // set the result to its parent until that would be null
+ Object xParent;
+ do
+ {
+ XChild xParentAccess =
+ (XChild) UnoRuntime.queryInterface(XChild.class,xResult);
+
+ if (xParentAccess != null)
+ xParent = xParentAccess.getParent();
+ else
+ xParent = null;
+
+ if (xParent != null)
+ xResult = xParent;
+ }
+ while (xParent != null);
+
+ return xResult;
+ }
+
+// workaround methods for unimplemented functionality
+
+ /// WORKAROUND: does the same as xNamedItem.setName(sNewName) should do
+ void renameSetItem(XNamed xNamedItem, String sNewName)
+ throws com.sun.star.uno.Exception
+ {
+ XChild xChildItem = (XChild)
+ UnoRuntime.queryInterface(XChild.class, xNamedItem);
+
+ XNameContainer xParentSet = (XNameContainer)
+ UnoRuntime.queryInterface( XNameContainer.class, xChildItem.getParent() );
+
+ String sOldName = xNamedItem.getName();
+
+ // now rename the item
+ xParentSet.removeByName(sOldName);
+ xParentSet.insertByName(sNewName,xNamedItem);
+ }
+
+ /// WORKAROUND: does the same as xChildItem.setParent( xNewParent ) should do
+ void moveSetItem(XChild xChildItem, XNameContainer xNewParent)
+ throws com.sun.star.uno.Exception
+ {
+ XNamed xNamedItem = (XNamed)
+ UnoRuntime.queryInterface(XNamed.class, xChildItem);
+
+ XNameContainer xOldParent = (XNameContainer)
+ UnoRuntime.queryInterface( XNameContainer.class, xChildItem.getParent() );
+
+ String sItemName = xNamedItem.getName();
+
+ // now rename the item
+ xOldParent.removeByName(sItemName);
+ xNewParent.insertByName(sItemName,xChildItem);
+ }
+
+
+// ------- the end -----------
+}