/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// 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
	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 a given ConfigurationProvider
    */
	public void runExamples( )
	{
        if (checkProvider(mxProvider))
        {
            System.out.println("\nStarting examples.");

            readDataExample();

            browseDataExample();

            updateGroupExample();

            resetGroupExample();

            updateSetExample();

            System.out.println("\nAll Examples completed.");
        }
        else
            System.out.println("ERROR: Cannot run examples without ConfigurationProvider.");

	}

    /** Do some simple checks, if there 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 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
     */
    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;
    }

	/** 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 update access to group data
	 */
	protected void updateGroupExample ()
	{
		try
		{
            System.out.println("\n--- starting example: update group data --------------");
            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 update access to set data
	 */
	protected void updateSetExample ()
	{
		try
		{
            System.out.println("\n--- starting example: update set data ---------------");
            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 process 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 view
        Object xViewRoot = createUpdatableView( cGridOptionsPath );

        // 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 user
        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);

            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 currently 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.
    */
    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 ;

        Object[] aArguments = new Object[1];
        aArguments[0] = aPathArgument;

        // create the view
        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
            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
                Object[] aDeepArguments = new Object[1];
                aDeepArguments[0] = aPathArgument;

                // create the view
                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 -----------
}
