Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / odk / examples / DevelopersGuide / Config / ConfigExamples.java
blob79ff21da3809479762f0c0cac343dc0aae43856e
1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * the BSD license.
7 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
29 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
31 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
32 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *************************************************************************/
36 // Import everything we use
38 import com.sun.star.beans.XPropertySet;
39 import com.sun.star.beans.XMultiPropertySet;
40 import com.sun.star.beans.XHierarchicalPropertySet;
41 import com.sun.star.beans.XMultiHierarchicalPropertySet;
42 import com.sun.star.beans.XPropertyState;
43 import com.sun.star.beans.XMultiPropertyStates;
45 import com.sun.star.configuration.XTemplateInstance;
47 import com.sun.star.container.XNameAccess;
48 import com.sun.star.container.XNameReplace;
49 import com.sun.star.container.XNameContainer;
50 import com.sun.star.container.XNamed;
51 import com.sun.star.container.XChild;
52 import com.sun.star.container.XHierarchicalNameAccess;
53 import com.sun.star.container.XHierarchicalName;
55 import com.sun.star.lang.XComponent;
56 import com.sun.star.lang.XMultiComponentFactory;
57 import com.sun.star.lang.XSingleServiceFactory;
58 import com.sun.star.lang.XMultiServiceFactory;
59 import com.sun.star.lang.XServiceInfo;
60 import com.sun.star.lang.EventObject;
62 import com.sun.star.uno.UnoRuntime;
63 import com.sun.star.uno.XComponentContext;
64 import com.sun.star.uno.XInterface;
65 import com.sun.star.uno.AnyConverter;
67 import com.sun.star.util.XChangesBatch;
68 import com.sun.star.util.XChangesNotifier;
69 import com.sun.star.util.XChangesListener;
70 import com.sun.star.util.ChangesEvent;
71 // Config examples
73 /* These examples show how to use the following features of the Config API:
75 o Accessing data
76 o Updating data
77 o Updating properties in groups
78 o Adding and removing items in sets
79 o Resetting data to their defaults
81 Each example is in a separate method call.
83 public class ConfigExamples
85 // The ComponentContext interface of the remote component context
86 private final XComponentContext mxContext;
88 // The MultiComponentFactory interface of the ServiceManager
89 private final XMultiComponentFactory mxServiceManager;
91 // The MultiServiceFactory interface of the ConfigurationProvider
92 private XMultiServiceFactory mxProvider = null;
94 public static void main( String args[] )
96 try {
97 // get the remote office component context
98 com.sun.star.uno.XComponentContext xContext =
99 com.sun.star.comp.helper.Bootstrap.bootstrap();
101 if( xContext != null )
102 System.out.println("Connected to a running office ...");
103 else
104 System.out.println( "ERROR: Cannot connect - no remote component context available." );
106 // Create an instance of the class and call its run method
107 ConfigExamples aExample = new ConfigExamples(xContext);
108 aExample.run( );
110 // if you own the service manager dispose it here
111 // to ensure that the default provider is properly disposed and flushed
112 System.exit(0);
114 catch( Exception e )
116 e.printStackTrace();
117 System.exit(-1);
121 /** Create a ConfigExamples instance supplying a service factory
123 public ConfigExamples(XComponentContext xContext)
125 mxContext = xContext;
126 mxServiceManager = xContext.getServiceManager();
129 /** Run the examples with a default ConfigurationProvider
131 public void run()
132 throws com.sun.star.uno.Exception
134 mxProvider = createProvider();
136 runExamples( );
138 // we are using the default ConfigurationProvider, so we must not dispose it
139 mxProvider = null;
142 /** Run the examples with a given ConfigurationProvider
144 public void runExamples( )
146 if (checkProvider(mxProvider))
148 System.out.println("\nStarting examples.");
150 readDataExample();
152 browseDataExample();
154 updateGroupExample();
156 resetGroupExample();
158 updateSetExample();
160 System.out.println("\nAll Examples completed.");
162 else
163 System.out.println("ERROR: Cannot run examples without ConfigurationProvider.");
167 /** Do some simple checks, if there is a valid ConfigurationProvider
169 public static boolean checkProvider(XMultiServiceFactory xProvider)
171 // check the provider we have
172 if (xProvider == null)
174 System.out.println("No provider available. Cannot access configuration data.");
175 return false;
181 // check the provider implementation
182 XServiceInfo xProviderServices =
183 UnoRuntime.queryInterface( XServiceInfo.class, xProvider );
185 if (xProviderServices == null ||
186 !xProviderServices.supportsService("com.sun.star.configuration.ConfigurationProvider"))
188 System.out.println("WARNING: The provider is not a com.sun.star.configuration.ConfigurationProvider");
191 if (xProviderServices != null)
193 System.out.println("Using provider implementation: " + xProviderServices.getImplementationName());
196 return true;
198 catch (com.sun.star.uno.RuntimeException e)
200 System.err.println("ERROR: Failure while checking the provider services.");
201 e.printStackTrace();
202 return false;
206 /** Get the provider we have
208 public XMultiServiceFactory getProvider( )
210 return mxProvider;
213 /** Create a default configuration provider
215 public XMultiServiceFactory createProvider( )
216 throws com.sun.star.uno.Exception
218 final String sProviderService = "com.sun.star.configuration.ConfigurationProvider";
220 // create the provider and return it as a XMultiServiceFactory
221 XMultiServiceFactory xProvider = UnoRuntime.queryInterface(XMultiServiceFactory.class,
222 mxServiceManager.createInstanceWithContext(sProviderService,
223 mxContext));
225 return xProvider;
228 /** Create a specified read-only configuration view
230 public Object createConfigurationView( String sPath )
231 throws com.sun.star.uno.Exception
233 XMultiServiceFactory xProvider = getProvider();
235 // The service name: Need only read access:
236 final String sReadOnlyView = "com.sun.star.configuration.ConfigurationAccess";
238 // creation arguments: nodepath
239 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue();
240 aPathArgument.Name = "nodepath";
241 aPathArgument.Value = sPath;
243 Object[] aArguments = new Object[1];
244 aArguments[0] = aPathArgument;
246 // create the view
247 Object xViewRoot = xProvider.createInstanceWithArguments(sReadOnlyView, aArguments);
249 return xViewRoot;
252 /** Create a specified updatable configuration view
254 Object createUpdatableView( String sPath )
255 throws com.sun.star.uno.Exception
257 XMultiServiceFactory xProvider = getProvider();
259 // The service name: Need update access:
260 final String cUpdatableView = "com.sun.star.configuration.ConfigurationUpdateAccess";
262 // creation arguments: nodepath
263 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue();
264 aPathArgument.Name = "nodepath";
265 aPathArgument.Value = sPath;
267 Object[] aArguments = new Object[1];
268 aArguments[0] = aPathArgument;
270 // create the view
271 Object xViewRoot = xProvider.createInstanceWithArguments(cUpdatableView, aArguments);
273 return xViewRoot;
276 /** This method demonstrates read access to data
278 protected void readDataExample ()
282 System.out.println("\n--- starting example: read grid option settings --------------------");
283 Object aData = readGridConfiguration( );
284 System.out.println("Read grid options: " + aData);
287 catch ( Exception e )
289 e.printStackTrace();
293 /** This method demonstrates browsing access to data
295 protected void browseDataExample ()
299 System.out.println("\n--- starting example: browse filter configuration ------------------");
300 printRegisteredFilters( );
302 catch ( Exception e )
304 e.printStackTrace();
308 /** This method demonstrates update access to group data
310 protected void updateGroupExample ()
314 System.out.println("\n--- starting example: update group data --------------");
315 editGridOptions( );
317 catch ( Exception e )
319 e.printStackTrace();
323 /** This method demonstrates resetting data to its default state
325 protected void resetGroupExample ()
329 System.out.println("\n--- starting example: reset group data -----------------------------");
330 Object aOldData = readGridConfiguration( );
331 resetGridConfiguration( );
332 Object aNewData = readGridConfiguration( );
333 System.out.println("Before reset: user grid options: " + aOldData);
334 System.out.println("After reset: default grid options: " + aNewData);
336 catch ( Exception e )
338 e.printStackTrace();
342 /** This method demonstrates update access to set data
344 protected void updateSetExample ()
348 System.out.println("\n--- starting example: update set data ---------------");
349 storeSampleDataSource( );
351 catch ( Exception e )
353 e.printStackTrace();
357 // READ example
358 /// class to hold information about grid settings
359 private static class GridOptions
361 private boolean visible;
362 private int resolution_x;
363 private int resolution_y;
364 private int subdivision_x;
365 private int subdivision_y;
367 @Override
368 public String toString() {
369 StringBuffer aBuffer = new StringBuffer();
370 aBuffer.append("[ Grid is "); aBuffer.append(visible ? "VISIBLE" : "HIDDEN");
371 aBuffer.append("; resolution = (" + resolution_x + "," + resolution_y + ")");
372 aBuffer.append("; subdivision = (" + subdivision_x + "," + subdivision_y + ")");
373 aBuffer.append(" ]");
374 return aBuffer.toString();
378 /// This method reads information about grid settings
379 protected GridOptions readGridConfiguration()
380 throws com.sun.star.uno.Exception
382 // The path to the root element
383 final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid";
385 // create the view
386 Object xViewRoot = createConfigurationView(cGridOptionsPath);
388 // the result structure
389 GridOptions options = new GridOptions();
391 // accessing a single nested value
392 XHierarchicalPropertySet xProperties =
393 UnoRuntime.queryInterface(XHierarchicalPropertySet.class, xViewRoot);
395 Object aVisible = xProperties.getHierarchicalPropertyValue("Option/VisibleGrid");
396 options.visible = ((Boolean) aVisible).booleanValue();
398 // accessing a nested object and its subproperties
399 Object xSubdivision = xProperties.getHierarchicalPropertyValue("Subdivision");
401 XMultiPropertySet xSubdivProperties =
402 UnoRuntime.queryInterface(XMultiPropertySet.class, xSubdivision);
404 // variables for multi-element access
405 String[] aElementNames = new String[] { "XAxis", "YAxis" };
407 Object[] aElementValues = xSubdivProperties.getPropertyValues(aElementNames);
409 options.subdivision_x = ((Integer) aElementValues[0]).intValue();
410 options.subdivision_y = ((Integer) aElementValues[1]).intValue();
412 // accessing deeply nested subproperties
413 Object xResolution = xProperties.getHierarchicalPropertyValue("Resolution");
415 XMultiHierarchicalPropertySet xResolutionProperties =
416 UnoRuntime.queryInterface(XMultiHierarchicalPropertySet.class, xResolution);
418 aElementNames[0] = "XAxis/Metric";
419 aElementNames[1] = "YAxis/Metric";
421 aElementValues = xResolutionProperties.getHierarchicalPropertyValues(aElementNames);
423 options.resolution_x = ((Integer) aElementValues[0]).intValue();
424 options.resolution_y = ((Integer) aElementValues[1]).intValue();
426 // all options have been retrieved - clean up and return
427 // we are done with the view - dispose it
429 UnoRuntime.queryInterface(XComponent.class, xViewRoot).dispose();
431 return options;
434 // BROWSE example
435 /// Interface to process information when browsing the configuration tree
436 public interface IConfigurationProcessor
438 /// process a value item
439 void processValueElement( String sPath_, Object aValue_ );
440 /// process a structural item
441 void processStructuralElement( String sPath_, XInterface xElement_);
444 /// Internal method to recursively browse a structural element in preorder
445 public void browseElementRecursively( XInterface xElement, IConfigurationProcessor aProcessor )
446 throws com.sun.star.uno.Exception
448 // First process this as an element (preorder traversal)
449 XHierarchicalName xElementPath =
450 UnoRuntime.queryInterface(XHierarchicalName.class, xElement);
452 String sPath = xElementPath.getHierarchicalName();
454 aProcessor.processStructuralElement( sPath, xElement);
456 // now process this as a container
457 XNameAccess xChildAccess =
458 UnoRuntime.queryInterface(XNameAccess.class, xElement);
460 // get a list of child elements
461 String[] aElementNames = xChildAccess.getElementNames();
463 // and process them one by one
464 for(int i=0; i< aElementNames.length; ++i)
466 Object aChild = xChildAccess.getByName( aElementNames[i] );
467 // is it a structural element (object) ...
468 if ( AnyConverter.isObject(aChild) && !AnyConverter.isArray(aChild) )
470 // then get an interface
471 XInterface xChildElement = UnoRuntime.queryInterface(XInterface.class, aChild);
473 // and continue processing child elements recursively
474 browseElementRecursively( xChildElement, aProcessor );
476 // ... or is it a simple value
477 else
479 // Build the path to it from the path of
480 // the element and the name of the child
481 String sChildPath;
482 sChildPath =
483 xElementPath.composeHierarchicalName(aElementNames[i]);
485 // and process the value
486 aProcessor.processValueElement( sChildPath, aChild );
491 /** Method to browse the part rooted at sRootPath
492 of the configuration that the Provider provides.
494 All nodes will be processed by the IConfigurationProcessor passed.
496 public void browseConfiguration( String sRootPath, IConfigurationProcessor aProcessor )
497 throws com.sun.star.uno.Exception
499 // create the root element
500 XInterface xViewRoot = (XInterface)createConfigurationView( sRootPath );
502 // now do the processing
503 browseElementRecursively( xViewRoot, aProcessor );
505 // we are done with the view - dispose it
506 // This assumes that the processor
507 // does not keep a reference to the elements in processStructuralElement
509 UnoRuntime.queryInterface(XComponent.class,xViewRoot).dispose();
510 xViewRoot = null;
513 /** Method to browse the filter configuration.
515 Information about installed filters will be printed.
517 public void printRegisteredFilters()
518 throws com.sun.star.uno.Exception
520 final String sFilterKey = "/org.openoffice.TypeDetection.Filter/Filters";
522 // browse the configuration, dumping filter information
523 browseConfiguration( sFilterKey,
524 new IConfigurationProcessor () {
525 /// prints Path and Value of properties
526 public void processValueElement( String sPath_, Object aValue_ ) {
527 if (AnyConverter.isArray(aValue_))
529 final Object [] aArray = (Object [])aValue_;
531 System.out.print("\tValue: " + sPath_ + " = { ");
532 for (int i=0; i<aArray.length; ++i)
534 if (i != 0) System.out.print(", ");
535 System.out.print(aArray[i]);
537 System.out.println(" }");
539 else
540 System.out.println("\tValue: " + sPath_ + " = " + aValue_);
543 /// prints the Filter entries
544 public void processStructuralElement( String sPath_, XInterface xElement_) {
545 // get template information, to detect instances of the 'Filter' template
546 XTemplateInstance xInstance =
547 UnoRuntime.queryInterface( XTemplateInstance .class,xElement_);
549 // only select the Filter entries
550 if (xInstance != null && xInstance.getTemplateName().endsWith("Filter")) {
551 XNamed xNamed = UnoRuntime.queryInterface(XNamed.class,xElement_);
552 System.out.println("Filter " + xNamed.getName() + " (" + sPath_ + ")");
555 } );
558 // GROUP UPDATE example
560 /** This method simulates editing configuration data using a GridEditor dialog class
562 public void editGridOptions( )
563 throws com.sun.star.uno.Exception
565 // The path to the root element
566 final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid";
568 // create the view
569 Object xViewRoot = createUpdatableView( cGridOptionsPath );
571 // the 'editor'
572 GridOptionsEditor dialog = new GridOptionsEditor();
574 // set up the initial values and register listeners
575 // get a data access interface, to supply the view with a model
576 XMultiHierarchicalPropertySet xProperties =
577 UnoRuntime.queryInterface(XMultiHierarchicalPropertySet.class, xViewRoot);
579 dialog.setModel( xProperties );
581 // get a listener object (probably an adapter) that notifies
582 // the dialog of external changes to its model
583 XChangesListener xListener = dialog.createChangesListener( );
585 XChangesNotifier xNotifier =
586 UnoRuntime.queryInterface(XChangesNotifier.class, xViewRoot);
588 xNotifier.addChangesListener( xListener );
590 // trigger the listener
591 changeSomeData( cGridOptionsPath + "/Subdivision" );
593 if (dialog.execute() == GridOptionsEditor.SAVE_SETTINGS)
595 // changes have been applied to the view here
596 XChangesBatch xUpdateControl =
597 UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot);
601 xUpdateControl.commitChanges();
603 catch (Exception e)
605 dialog.informUserOfError( e );
609 // all changes have been handled - clean up and return
610 // listener is done now
611 xNotifier.removeChangesListener( xListener );
613 // we are done with the view - dispose it
614 UnoRuntime.queryInterface(XComponent.class, xViewRoot).dispose();
617 /** A class that changes some grid options settings
619 The interface of this class is chose to resemble a possible UI dialog class
621 private class GridOptionsEditor {
622 /// the data this editor edits
623 XMultiHierarchicalPropertySet mxModel;
625 public static final int CANCELED = 0;
626 public static final int SAVE_SETTINGS = 1;
628 // sets a model and updates the display
629 public void setModel(XMultiHierarchicalPropertySet xModel) {
630 mxModel = xModel;
631 updateDisplay();
634 // this method 'runs' the 'dialog'
635 public int execute() {
638 System.out.println("-- GridEditor executing --");
639 // simulate a user action changing some data
640 toggleVisibility();
641 System.out.println("-- GridEditor done --");
642 return SAVE_SETTINGS;
644 catch (Exception e)
646 informUserOfError(e);
647 return CANCELED;
651 // this method is called to report an error during dialog execution to the user
652 public void informUserOfError(Exception e) {
653 System.err.println("ERROR in GridEditor:");
654 e.printStackTrace();
657 /// this method is called to allow the dialog to get feedback about changes occurring elsewhere
658 public XChangesListener createChangesListener() {
659 if (mxModel == null) return null;
661 return (new XChangesListener () {
662 public void changesOccurred( ChangesEvent event ) {
663 System.out.println("GridEditor - Listener received changes event containing " +
664 event.Changes.length + " change(s).");
665 updateDisplay();
668 public void disposing(EventObject event) {
669 System.out.println("GridEditor - Listener received disposed event: releasing model");
670 setModel(null);
674 /// this method is called when data has changed to display the updated data
675 private void updateDisplay() {
676 if (mxModel != null)
677 System.out.println("Grid options editor: data=" + readModel());
678 else
679 System.out.println("Grid options editor: no model set");
682 // this method is used to read all relevant data from the model
683 private GridOptions readModel()
687 String [] aOptionNames = new String [5];
688 aOptionNames[0] = "Option/VisibleGrid";
689 aOptionNames[1] = "Subdivision/XAxis";
690 aOptionNames[2] = "Subdivision/YAxis";
691 aOptionNames[3] = "Resolution/XAxis/Metric";
692 aOptionNames[4] = "Resolution/YAxis/Metric";
694 Object [] aValues = mxModel.getHierarchicalPropertyValues(aOptionNames);
696 GridOptions result = new GridOptions();
697 result.visible = ((Boolean)aValues[0]).booleanValue();
698 result.subdivision_x = ((Integer)aValues[1]).intValue();
699 result.subdivision_y = ((Integer)aValues[2]).intValue();
700 result.resolution_x = ((Integer)aValues[3]).intValue();
701 result.resolution_y = ((Integer)aValues[4]).intValue();
703 return result;
705 catch (Exception e)
707 informUserOfError(e);
708 return null;
712 // this method executes an edit
713 private void toggleVisibility()
717 XHierarchicalPropertySet xHPS =
718 UnoRuntime.queryInterface(XHierarchicalPropertySet.class, mxModel);
720 final String sSetting = "Option/VisibleGrid";
722 System.out.println("GridEditor: toggling Visibility");
724 Boolean bOldValue = (Boolean)xHPS.getHierarchicalPropertyValue(sSetting);
726 Boolean bNewValue = Boolean.valueOf( ! bOldValue.booleanValue() );
728 xHPS.setHierarchicalPropertyValue(sSetting,bNewValue);
730 catch (Exception e)
732 informUserOfError(e);
737 /** This method creates an extra updatable view to change some data
738 and trigger the listener of the GridEditor
740 void changeSomeData(String xKey)
744 Object xOtherViewRoot = createUpdatableView(xKey);
746 XNameReplace aReplace = UnoRuntime.queryInterface(XNameReplace.class, xOtherViewRoot);
748 String aItemNames [] = aReplace.getElementNames();
749 for (int i=0; i < aItemNames.length; ++i) {
750 Object aItem = aReplace.getByName( aItemNames [i] );
751 // replace integers by a 'complement' value
752 if ( AnyConverter.isInt(aItem) )
754 int nOld = AnyConverter.toInt(aItem);
755 int nNew = 9999 - nOld;
757 System.out.println("Replacing integer value: " + aItemNames [i]);
758 aReplace.replaceByName( aItemNames [i], Integer.valueOf( nNew ) );
761 // and booleans by their negated value
762 else if ( AnyConverter.isBoolean(aItem) )
764 boolean bOld = AnyConverter.toBoolean(aItem);
765 boolean bNew = ! bOld;
767 System.out.println("Replacing boolean value: " + aItemNames [i]);
768 aReplace.replaceByName( aItemNames [i], Boolean.valueOf( bNew ) );
772 // commit the changes
773 XChangesBatch xUpdateControl =
774 UnoRuntime.queryInterface(XChangesBatch.class,xOtherViewRoot);
776 xUpdateControl.commitChanges();
778 // we are done with the view - dispose it
779 UnoRuntime.queryInterface(XComponent.class, xOtherViewRoot).dispose();
781 catch (Exception e)
783 System.err.println("Could not change some data in a different view. An exception occurred:");
784 e.printStackTrace();
788 // GROUP RESET EXAMPLE
789 /// This method resets the grid settings to their default values
790 protected void resetGridConfiguration()
791 throws com.sun.star.uno.Exception
793 // The path to the root element
794 final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid";
796 // create the view
797 Object xViewRoot = createUpdatableView(cGridOptionsPath);
799 // resetting a single nested value
800 XHierarchicalNameAccess xHierarchicalAccess =
801 UnoRuntime.queryInterface(XHierarchicalNameAccess.class, xViewRoot);
803 // get using absolute name
804 Object xOptions = xHierarchicalAccess.getByHierarchicalName(cGridOptionsPath + "/Option");
806 XPropertyState xOptionState =
807 UnoRuntime.queryInterface(XPropertyState.class, xOptions);
809 xOptionState.setPropertyToDefault("VisibleGrid");
811 // resetting more deeply nested values
812 Object xResolutionX = xHierarchicalAccess.getByHierarchicalName("Resolution/XAxis");
813 Object xResolutionY = xHierarchicalAccess.getByHierarchicalName("Resolution/YAxis");
815 XPropertyState xResolutionStateX =
816 UnoRuntime.queryInterface(XPropertyState.class, xResolutionX);
817 XPropertyState xResolutionStateY =
818 UnoRuntime.queryInterface(XPropertyState.class, xResolutionY);
820 xResolutionStateX.setPropertyToDefault("Metric");
821 xResolutionStateY.setPropertyToDefault("Metric");
823 // resetting multiple sibling values
824 Object xSubdivision = xHierarchicalAccess.getByHierarchicalName("Subdivision");
826 XMultiPropertyStates xSubdivisionStates =
827 UnoRuntime.queryInterface(XMultiPropertyStates.class, xSubdivision);
829 xSubdivisionStates.setAllPropertiesToDefault();
831 // commit the changes
832 XChangesBatch xUpdateControl =
833 UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot);
835 xUpdateControl.commitChanges();
837 // we are done with the view - dispose it
838 UnoRuntime.queryInterface(XComponent.class, xViewRoot).dispose();
842 // SET UPDATE EXAMPLE
843 private static boolean SET_EXAMPLE_BROKEN_IN_THIS_RELEASE = true;
845 /** This method stores a sample data source given some connection data.
847 ATTENTION: This example requires an older version of the
848 org.openoffice.Office.DataAccess schema.
849 It does not work with the current schema.
850 Because of this, the method currenty does nothing.
851 You can still use the techniques shown in the example code.
853 void storeSampleDataSource()
854 throws com.sun.star.uno.Exception
856 if (SET_EXAMPLE_BROKEN_IN_THIS_RELEASE)
858 System.out.println("- DISABLED: (the existing example does not work with this version) -");
859 return; // this function does not work
862 String sSampleDataSourceName = "SampleTextDatabase";
864 String sSampleDataSourceURL = "sdbc:flat:$(userurl)/database/SampleTextDatabase";
866 com.sun.star.beans.NamedValue [] aSettings = new com.sun.star.beans.NamedValue [2];
867 aSettings[0] = new com.sun.star.beans.NamedValue("HeaderLine",Boolean.TRUE);
868 aSettings[1] = new com.sun.star.beans.NamedValue("FieldDelimiter",";");
870 String [] aTableFilter = new String[] { "table.txt", "othertable.txt" };
872 storeDataSource(sSampleDataSourceName,sSampleDataSourceURL,"",false,0,aSettings,aTableFilter);
875 /// This method stores a data source given some connection data
876 void storeDataSource(
877 String sDataSourceName,
878 String sDataSourceURL,
879 String sUser,
880 boolean bNeedsPassword,
881 int nTimeout,
882 com.sun.star.beans.NamedValue [] aDriverSettings,
883 String [] aTableFilter
885 throws com.sun.star.uno.Exception
887 // create the view and get the data source element
888 Object xDataSource = createDataSourceDescription(getProvider(),sDataSourceName);
890 // set the values
891 XPropertySet xDataSourceProperties =
892 UnoRuntime.queryInterface(XPropertySet.class, xDataSource);
894 xDataSourceProperties.setPropertyValue("URL", sDataSourceURL );
895 xDataSourceProperties.setPropertyValue("User", sUser );
896 xDataSourceProperties.setPropertyValue("IsPasswordRequired", Boolean.valueOf( bNeedsPassword ) );
897 xDataSourceProperties.setPropertyValue("LoginTimeout", Integer.valueOf( nTimeout ) );
899 if ( aTableFilter != null )
900 xDataSourceProperties.setPropertyValue("TableFilter", aTableFilter );
902 // store the driver-specific settings
903 if (aDriverSettings != null)
905 Object xSettingsSet = xDataSourceProperties.getPropertyValue("DataSourceSettings");
906 storeSettings( xSettingsSet, aDriverSettings);
909 // save the data and dispose the view
910 // recover the view root
911 Object xViewRoot = getViewRoot(xDataSource);
913 // commit the changes
914 XChangesBatch xUpdateControl =
915 UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot);
917 xUpdateControl.commitChanges();
919 // now clean up
920 UnoRuntime.queryInterface(XComponent.class, xViewRoot).dispose();
923 /** This method gets the DataSourceDescription for a data source.
924 It either gets the existing entry or creates a new instance.
926 Object createDataSourceDescription(XMultiServiceFactory xProvider, String sDataSourceName )
927 throws com.sun.star.uno.Exception
929 // The service name: Need an update access:
930 final String cUpdatableView = "com.sun.star.configuration.ConfigurationUpdateAccess";
932 // The path to the DataSources set node
933 final String cDataSourcesPath = "/org.openoffice.Office.DataAccess/DataSources";
935 // creation arguments: nodepath
936 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue();
937 aPathArgument.Name = "nodepath";
938 aPathArgument.Value = cDataSourcesPath ;
940 Object[] aArguments = new Object[1];
941 aArguments[0] = aPathArgument;
943 // create the view
944 Object xViewRoot =
945 xProvider.createInstanceWithArguments(cUpdatableView, aArguments);
947 XNameAccess xSetOfDataSources =
948 UnoRuntime.queryInterface(XNameAccess.class,xViewRoot);
950 Object xDataSourceDescriptor = null; // the result
951 if ( xSetOfDataSources .hasByName( sDataSourceName ))
953 // the element is there
956 // the view should point to the element directly, so we need to extend the path
957 XHierarchicalName xComposePath = UnoRuntime.queryInterface(XHierarchicalName.class, xSetOfDataSources );
959 String sElementPath = xComposePath.composeHierarchicalName( sDataSourceName );
961 // use the name of the element now
962 aPathArgument.Value = sElementPath;
964 // create another view now
965 Object[] aDeepArguments = new Object[1];
966 aDeepArguments[0] = aPathArgument;
968 // create the view
969 xDataSourceDescriptor =
970 xProvider.createInstanceWithArguments(cUpdatableView, aDeepArguments);
972 if ( xDataSourceDescriptor != null) // all went fine
974 // dispose the other view
975 UnoRuntime.queryInterface(XComponent.class, xViewRoot).dispose();
976 xViewRoot = null;
979 catch (Exception e)
981 // something went wrong, we retry with a new element
982 System.err.println("WARNING: An exception occurred while creating a view for an existing data source: " + e);
983 xDataSourceDescriptor = null;
987 // do we have a result element yet ?
988 if ( xDataSourceDescriptor == null)
990 // get the container
991 XNameContainer xSetUpdate =
992 UnoRuntime.queryInterface(XNameContainer.class, xViewRoot);
994 // create a new detached set element (instance of DataSourceDescription)
995 XSingleServiceFactory xElementFactory =
996 UnoRuntime.queryInterface(XSingleServiceFactory.class, xSetUpdate);
998 // the new element is the result !
999 xDataSourceDescriptor = xElementFactory.createInstance();
1001 // insert it - this also names the element
1002 xSetUpdate.insertByName( sDataSourceName , xDataSourceDescriptor );
1005 return xDataSourceDescriptor ;
1008 /// this method stores a number of settings in a set node containing DataSourceSetting objects
1009 void storeSettings(Object xSettingsSet, com.sun.star.beans.NamedValue [] aSettings )
1010 throws com.sun.star.uno.Exception
1012 if (aSettings == null)
1013 return;
1015 // get the settings set as a container
1016 XNameContainer xSettingsContainer =
1017 UnoRuntime.queryInterface( XNameContainer.class, xSettingsSet);
1019 // and get a factory interface for creating the entries
1020 XSingleServiceFactory xSettingsFactory =
1021 UnoRuntime.queryInterface(XSingleServiceFactory.class, xSettingsSet);
1023 // now insert the individual settings
1024 for (int i = 0; i < aSettings.length; ++i) {
1025 // create a DataSourceSetting object
1026 XPropertySet xSetting = UnoRuntime.queryInterface( XPropertySet.class, xSettingsFactory.createInstance() );
1028 // can set the value before inserting
1029 xSetting.setPropertyValue( "Value", aSettings[i].Value );
1031 // and now insert or replace as appropriate
1032 if (xSettingsContainer.hasByName( aSettings[i].Name ))
1033 xSettingsContainer.replaceByName( aSettings[i].Name, xSetting );
1034 else
1035 xSettingsContainer.insertByName( aSettings[i].Name, xSetting );
1039 // HELPER FUNCTIONS
1041 /// This method get the view root node given an interface to any node in the view
1042 public static Object getViewRoot(Object xElement)
1044 Object xResult = xElement;
1046 // set the result to its parent until that would be null
1047 Object xParent;
1050 XChild xParentAccess =
1051 UnoRuntime.queryInterface(XChild.class,xResult);
1053 if (xParentAccess != null)
1054 xParent = xParentAccess.getParent();
1055 else
1056 xParent = null;
1058 if (xParent != null)
1059 xResult = xParent;
1061 while (xParent != null);
1063 return xResult;
1066 // workaround methods for unimplemented functionality
1068 /// WORKAROUND: does the same as xNamedItem.setName(sNewName) should do
1069 void renameSetItem(XNamed xNamedItem, String sNewName)
1070 throws com.sun.star.uno.Exception
1072 XChild xChildItem = UnoRuntime.queryInterface(XChild.class, xNamedItem);
1074 XNameContainer xParentSet = UnoRuntime.queryInterface( XNameContainer.class, xChildItem.getParent() );
1076 String sOldName = xNamedItem.getName();
1078 // now rename the item
1079 xParentSet.removeByName(sOldName);
1080 xParentSet.insertByName(sNewName,xNamedItem);
1083 /// WORKAROUND: does the same as xChildItem.setParent( xNewParent ) should do
1084 void moveSetItem(XChild xChildItem, XNameContainer xNewParent)
1085 throws com.sun.star.uno.Exception
1087 XNamed xNamedItem = UnoRuntime.queryInterface(XNamed.class, xChildItem);
1089 XNameContainer xOldParent = UnoRuntime.queryInterface( XNameContainer.class, xChildItem.getParent() );
1091 String sItemName = xNamedItem.getName();
1093 // now rename the item
1094 xOldParent.removeByName(sItemName);
1095 xNewParent.insertByName(sItemName,xChildItem);
1099 // ------- the end -----------
1102 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */