1 /************************************************************************* 2 * 3 * The Contents of this file are made available subject to the terms of 4 * the BSD license. 5 * 6 * Copyright 2000, 2010 Oracle and/or its affiliates. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 30 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 31 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 *************************************************************************/ 34 35 // Import everything we use 36 37 import com.sun.star.beans.XPropertySet; 38 import com.sun.star.beans.XMultiPropertySet; 39 import com.sun.star.beans.XHierarchicalPropertySet; 40 import com.sun.star.beans.XMultiHierarchicalPropertySet; 41 import com.sun.star.beans.XPropertyState; 42 import com.sun.star.beans.XMultiPropertyStates; 43 44 import com.sun.star.bridge.XUnoUrlResolver; 45 46 import com.sun.star.configuration.XTemplateInstance; 47 48 import com.sun.star.container.XNameAccess; 49 import com.sun.star.container.XNameReplace; 50 import com.sun.star.container.XNameContainer; 51 import com.sun.star.container.XNamed; 52 import com.sun.star.container.XChild; 53 import com.sun.star.container.XHierarchicalNameAccess; 54 import com.sun.star.container.XHierarchicalName; 55 56 import com.sun.star.lang.XComponent; 57 import com.sun.star.lang.XMultiComponentFactory; 58 import com.sun.star.lang.XSingleServiceFactory; 59 import com.sun.star.lang.XMultiServiceFactory; 60 import com.sun.star.lang.XMultiComponentFactory; 61 import com.sun.star.lang.XServiceInfo; 62 import com.sun.star.lang.EventObject; 63 64 import com.sun.star.uno.UnoRuntime; 65 import com.sun.star.uno.XComponentContext; 66 import com.sun.star.uno.XInterface; 67 import com.sun.star.uno.XNamingService; 68 import com.sun.star.uno.AnyConverter; 69 70 import com.sun.star.util.XChangesBatch; 71 import com.sun.star.util.XChangesNotifier; 72 import com.sun.star.util.XChangesListener; 73 import com.sun.star.util.ChangesEvent; 74 /** Config examples 75 @author Joerg Barfurth 76 */ 77 78 /* These examples show how to use the following features of the Config API: 79 80 o Accessing data 81 o Updating data 82 o Updating properties in groups 83 o Adding and removing items in sets 84 o Resetting data to their defaults 85 86 Each example is in a separate method call. 87 */ 88 public class ConfigExamples 89 { 90 // The ComponentContext interface of the remote component context 91 private XComponentContext mxContext = null; 92 93 // The MultiComponentFactory interface of the ServiceManager 94 private XMultiComponentFactory mxServiceManager = null; 95 96 // The MultiServiceFactory interface of the ConfigurationProvider 97 private XMultiServiceFactory mxProvider = null; 98 99 public static void main( String args[] ) 100 { 101 try { 102 // get the remote office component context 103 com.sun.star.uno.XComponentContext xContext = 104 com.sun.star.comp.helper.Bootstrap.bootstrap(); 105 106 if( xContext != null ) 107 System.out.println("Connected to a running office ..."); 108 else 109 System.out.println( "ERROR: Cannot connect - no remote component context available." ); 110 111 // Create an instance of the class and call it's run method 112 ConfigExamples aExample = new ConfigExamples(xContext); 113 aExample.run( ); 114 115 // if you own the service manager dispose it here 116 // to ensure that the default provider is properly disposed and flushed 117 System.exit(0); 118 } 119 catch( Exception e ) 120 { 121 e.printStackTrace(); 122 System.exit(-1); 123 } 124 } 125 126 /** Create a ConfigExamples instance supplying a service factory 127 */ 128 public ConfigExamples(XComponentContext xContext) 129 { 130 mxContext = xContext; 131 mxServiceManager = xContext.getServiceManager(); 132 } 133 134 /** Run the examples with a default ConfigurationProvider 135 */ 136 public void run() 137 throws com.sun.star.uno.Exception 138 { 139 mxProvider = createProvider(); 140 141 runExamples( ); 142 143 // we are using the default ConfigurationProvider, so we must not dispose it 144 mxProvider = null; 145 } 146 147 /** Run the examples with a given ConfigurationProvider 148 */ 149 public void runExamples( ) 150 { 151 if (checkProvider(mxProvider)) 152 { 153 System.out.println("\nStarting examples."); 154 155 readDataExample(); 156 157 browseDataExample(); 158 159 updateGroupExample(); 160 161 resetGroupExample(); 162 163 updateSetExample(); 164 165 System.out.println("\nAll Examples completed."); 166 } 167 else 168 System.out.println("ERROR: Cannot run examples without ConfigurationProvider."); 169 170 } 171 172 /** Do some simple checks, if tehre is a valid ConfigurationProvider 173 */ 174 public static boolean checkProvider(XMultiServiceFactory xProvider) 175 { 176 // check the provider we have 177 if (xProvider == null) 178 { 179 System.out.println("No provider available. Cannot access configuration data."); 180 return false; 181 182 } 183 184 try 185 { 186 // check the provider implementation 187 XServiceInfo xProviderServices = 188 (XServiceInfo) UnoRuntime.queryInterface( XServiceInfo.class, xProvider ); 189 190 if (xProviderServices == null || 191 !xProviderServices.supportsService("com.sun.star.configuration.ConfigurationProvider")) 192 { 193 System.out.println("WARNING: The provider is not a com.sun.star.configuration.ConfigurationProvider"); 194 } 195 196 if (xProviderServices != null) 197 { 198 System.out.println("Using provider implementation: " + xProviderServices.getImplementationName()); 199 } 200 201 return true; 202 } 203 catch (com.sun.star.uno.RuntimeException e) 204 { 205 System.err.println("ERROR: Failure while checking the provider services."); 206 e.printStackTrace(); 207 return false; 208 } 209 } 210 211 /** Get the provider we have 212 */ 213 public XMultiServiceFactory getProvider( ) 214 { 215 return mxProvider; 216 } 217 218 /** Create a default configuration provider 219 */ 220 public XMultiServiceFactory createProvider( ) 221 throws com.sun.star.uno.Exception 222 { 223 final String sProviderService = "com.sun.star.configuration.ConfigurationProvider"; 224 225 // create the provider and return it as a XMultiServiceFactory 226 XMultiServiceFactory xProvider = (XMultiServiceFactory) 227 UnoRuntime.queryInterface(XMultiServiceFactory.class, 228 mxServiceManager.createInstanceWithContext(sProviderService, 229 mxContext)); 230 231 return xProvider; 232 } 233 234 /** Create a specified read-only configuration view 235 */ 236 public Object createConfigurationView( String sPath ) 237 throws com.sun.star.uno.Exception 238 { 239 XMultiServiceFactory xProvider = getProvider(); 240 241 // The service name: Need only read access: 242 final String sReadOnlyView = "com.sun.star.configuration.ConfigurationAccess"; 243 244 // creation arguments: nodepath 245 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue(); 246 aPathArgument.Name = "nodepath"; 247 aPathArgument.Value = sPath; 248 249 Object[] aArguments = new Object[1]; 250 aArguments[0] = aPathArgument; 251 252 // create the view 253 Object xViewRoot = xProvider.createInstanceWithArguments(sReadOnlyView, aArguments); 254 255 return xViewRoot; 256 } 257 258 /** Create a specified updatable configuration view 259 */ 260 Object createUpdatableView( String sPath ) 261 throws com.sun.star.uno.Exception 262 { 263 XMultiServiceFactory xProvider = getProvider(); 264 265 // The service name: Need update access: 266 final String cUpdatableView = "com.sun.star.configuration.ConfigurationUpdateAccess"; 267 268 // creation arguments: nodepath 269 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue(); 270 aPathArgument.Name = "nodepath"; 271 aPathArgument.Value = sPath; 272 273 Object[] aArguments = new Object[1]; 274 aArguments[0] = aPathArgument; 275 276 // create the view 277 Object xViewRoot = xProvider.createInstanceWithArguments(cUpdatableView, aArguments); 278 279 return xViewRoot; 280 } 281 282 /** This method demonstrates read access to data 283 */ 284 protected void readDataExample () 285 { 286 try 287 { 288 System.out.println("\n--- starting example: read grid option settings --------------------"); 289 Object aData = readGridConfiguration( ); 290 System.out.println("Read grid options: " + aData); 291 292 } 293 catch ( Exception e ) 294 { 295 e.printStackTrace(); 296 } 297 } 298 299 /** This method demonstrates browsing access to data 300 */ 301 protected void browseDataExample () 302 { 303 try 304 { 305 System.out.println("\n--- starting example: browse filter configuration ------------------"); 306 printRegisteredFilters( ); 307 } 308 catch ( Exception e ) 309 { 310 e.printStackTrace(); 311 } 312 } 313 314 /** This method demonstrates update access to group data 315 */ 316 protected void updateGroupExample () 317 { 318 try 319 { 320 System.out.println("\n--- starting example: update group data --------------"); 321 editGridOptions( ); 322 } 323 catch ( Exception e ) 324 { 325 e.printStackTrace(); 326 } 327 } 328 329 /** This method demonstrates resetting data to its default state 330 */ 331 protected void resetGroupExample () 332 { 333 try 334 { 335 System.out.println("\n--- starting example: reset group data -----------------------------"); 336 Object aOldData = readGridConfiguration( ); 337 resetGridConfiguration( ); 338 Object aNewData = readGridConfiguration( ); 339 System.out.println("Before reset: user grid options: " + aOldData); 340 System.out.println("After reset: default grid options: " + aNewData); 341 } 342 catch ( Exception e ) 343 { 344 e.printStackTrace(); 345 } 346 } 347 348 /** This method demonstrates update access to set data 349 */ 350 protected void updateSetExample () 351 { 352 try 353 { 354 System.out.println("\n--- starting example: update set data ---------------"); 355 storeSampleDataSource( ); 356 } 357 catch ( Exception e ) 358 { 359 e.printStackTrace(); 360 } 361 } 362 363 // READ example 364 /// class to hold information about grid settings 365 public static class GridOptions 366 { 367 public boolean visible; 368 public int resolution_x; 369 public int resolution_y; 370 public int subdivision_x; 371 public int subdivision_y; 372 373 public String toString() { 374 StringBuffer aBuffer = new StringBuffer(); 375 aBuffer.append("[ Grid is "); aBuffer.append(visible ? "VISIBLE" : "HIDDEN"); 376 aBuffer.append("; resolution = (" + resolution_x + "," + resolution_y + ")"); 377 aBuffer.append("; subdivision = (" + subdivision_x + "," + subdivision_y + ")"); 378 aBuffer.append(" ]"); 379 return aBuffer.toString(); 380 } 381 }; 382 383 /// This method reads information about grid settings 384 protected GridOptions readGridConfiguration() 385 throws com.sun.star.uno.Exception 386 { 387 // The path to the root element 388 final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid"; 389 390 // create the view 391 Object xViewRoot = createConfigurationView(cGridOptionsPath); 392 393 // the result structure 394 GridOptions options = new GridOptions(); 395 396 // accessing a single nested value 397 XHierarchicalPropertySet xProperties = 398 (XHierarchicalPropertySet)UnoRuntime.queryInterface(XHierarchicalPropertySet.class, xViewRoot); 399 400 Object aVisible = xProperties.getHierarchicalPropertyValue("Option/VisibleGrid"); 401 options.visible = ((Boolean) aVisible).booleanValue(); 402 403 // accessing a nested object and its subproperties 404 Object xSubdivision = xProperties.getHierarchicalPropertyValue("Subdivision"); 405 406 XMultiPropertySet xSubdivProperties = 407 (XMultiPropertySet)UnoRuntime.queryInterface(XMultiPropertySet.class, xSubdivision); 408 409 // variables for multi-element access 410 String[] aElementNames = new String[2]; 411 412 aElementNames[0] = "XAxis"; 413 aElementNames[1] = "YAxis"; 414 415 Object[] aElementValues = xSubdivProperties.getPropertyValues(aElementNames); 416 417 options.subdivision_x = ((Integer) aElementValues[0]).intValue(); 418 options.subdivision_y = ((Integer) aElementValues[1]).intValue(); 419 420 // accessing deeply nested subproperties 421 Object xResolution = xProperties.getHierarchicalPropertyValue("Resolution"); 422 423 XMultiHierarchicalPropertySet xResolutionProperties = 424 (XMultiHierarchicalPropertySet) 425 UnoRuntime.queryInterface(XMultiHierarchicalPropertySet.class, xResolution); 426 427 aElementNames[0] = "XAxis/Metric"; 428 aElementNames[1] = "YAxis/Metric"; 429 430 aElementValues = xResolutionProperties.getHierarchicalPropertyValues(aElementNames); 431 432 options.resolution_x = ((Integer) aElementValues[0]).intValue(); 433 options.resolution_y = ((Integer) aElementValues[1]).intValue(); 434 435 // all options have been retrieved - clean up and return 436 // we are done with the view - dispose it 437 438 ((XComponent)UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose(); 439 440 return options; 441 } 442 443 // BROWSE example 444 /// Interface to procees information when browsing the configuration tree 445 public static interface IConfigurationProcessor 446 { 447 /// process a value item 448 public abstract void processValueElement( String sPath_, Object aValue_ ); 449 /// process a structural item 450 public abstract void processStructuralElement( String sPath_, XInterface xElement_); 451 }; 452 453 /// Internal method to recursively browse a structural element in preorder 454 public void browseElementRecursively( XInterface xElement, IConfigurationProcessor aProcessor ) 455 throws com.sun.star.uno.Exception 456 { 457 // First process this as an element (preorder traversal) 458 XHierarchicalName xElementPath = 459 (XHierarchicalName) UnoRuntime.queryInterface(XHierarchicalName.class, xElement); 460 461 String sPath = xElementPath.getHierarchicalName(); 462 463 aProcessor.processStructuralElement( sPath, xElement); 464 465 // now process this as a container 466 XNameAccess xChildAccess = 467 (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class, xElement); 468 469 // get a list of child elements 470 String[] aElementNames = xChildAccess.getElementNames(); 471 472 // and process them one by one 473 for(int i=0; i< aElementNames.length; ++i) 474 { 475 Object aChild = xChildAccess.getByName( aElementNames[i] ); 476 AnyConverter aAnyConv = new AnyConverter(); 477 // is it a structural element (object) ... 478 if ( aAnyConv.isObject(aChild) && !aAnyConv.isArray(aChild) ) 479 { 480 // then get an interface 481 XInterface xChildElement = (XInterface)UnoRuntime.queryInterface(XInterface.class, aChild); 482 483 // and continue processing child elements recursively 484 browseElementRecursively( xChildElement, aProcessor ); 485 } 486 // ... or is it a simple value 487 else 488 { 489 // Build the path to it from the path of 490 // the element and the name of the child 491 String sChildPath; 492 sChildPath = 493 xElementPath.composeHierarchicalName(aElementNames[i]); 494 495 // and process the value 496 aProcessor.processValueElement( sChildPath, aChild ); 497 } 498 } 499 } 500 501 /** Method to browse the part rooted at sRootPath 502 of the configuration that the Provider provides. 503 504 All nodes will be processed by the IConfigurationProcessor passed. 505 */ 506 public void browseConfiguration( String sRootPath, IConfigurationProcessor aProcessor ) 507 throws com.sun.star.uno.Exception 508 { 509 // create the root element 510 XInterface xViewRoot = (XInterface)createConfigurationView( sRootPath ); 511 512 // now do the processing 513 browseElementRecursively( xViewRoot, aProcessor ); 514 515 // we are done with the view - dispose it 516 // This assumes that the processor 517 // does not keep a reference to the elements in processStructuralElement 518 519 ((XComponent) UnoRuntime.queryInterface(XComponent.class,xViewRoot)).dispose(); 520 xViewRoot = null; 521 } 522 523 /** Method to browse the filter configuration. 524 525 Information about installed filters will be printed. 526 */ 527 public void printRegisteredFilters() 528 throws com.sun.star.uno.Exception 529 { 530 final String sProviderService = "com.sun.star.configuration.ConfigurationProvider"; 531 final String sFilterKey = "/org.openoffice.TypeDetection.Filter/Filters"; 532 533 // browse the configuration, dumping filter information 534 browseConfiguration( sFilterKey, 535 new IConfigurationProcessor () { 536 /// prints Path and Value of properties 537 public void processValueElement( String sPath_, Object aValue_ ) { 538 if (new AnyConverter().isArray(aValue_)) 539 { 540 final Object [] aArray = (Object [])aValue_; 541 542 System.out.print("\tValue: " + sPath_ + " = { "); 543 for (int i=0; i<aArray.length; ++i) 544 { 545 if (i != 0) System.out.print(", "); 546 System.out.print(aArray[i]); 547 } 548 System.out.println(" }"); 549 } 550 else 551 System.out.println("\tValue: " + sPath_ + " = " + aValue_); 552 } 553 554 /// prints the Filter entries 555 public void processStructuralElement( String sPath_, XInterface xElement_) { 556 // get template information, to detect instances of the 'Filter' template 557 XTemplateInstance xInstance = 558 ( XTemplateInstance )UnoRuntime.queryInterface( XTemplateInstance .class,xElement_); 559 560 // only select the Filter entries 561 if (xInstance != null && xInstance.getTemplateName().endsWith("Filter")) { 562 XNamed xNamed = (XNamed)UnoRuntime.queryInterface(XNamed.class,xElement_); 563 System.out.println("Filter " + xNamed.getName() + " (" + sPath_ + ")"); 564 } 565 } 566 } ); 567 } 568 569 // GROUP UPDATE example 570 571 /** This method simulates editing configuration data using a GridEditor dialog class 572 */ 573 public void editGridOptions( ) 574 throws com.sun.star.uno.Exception 575 { 576 // The path to the root element 577 final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid"; 578 579 // create the view 580 Object xViewRoot = createUpdatableView( cGridOptionsPath ); 581 582 // the 'editor' 583 GridOptionsEditor dialog = new GridOptionsEditor(); 584 585 // set up the initial values and register listeners 586 // get a data access interface, to supply the view with a model 587 XMultiHierarchicalPropertySet xProperties = 588 (XMultiHierarchicalPropertySet) 589 UnoRuntime.queryInterface(XMultiHierarchicalPropertySet.class, xViewRoot); 590 591 dialog.setModel( xProperties ); 592 593 // get a listener object (probably an adapter) that notifies 594 // the dialog of external changes to its model 595 XChangesListener xListener = dialog.createChangesListener( ); 596 597 XChangesNotifier xNotifier = 598 (XChangesNotifier)UnoRuntime.queryInterface(XChangesNotifier.class, xViewRoot); 599 600 xNotifier.addChangesListener( xListener ); 601 602 // trigger the listener 603 changeSomeData( cGridOptionsPath + "/Subdivision" ); 604 605 if (dialog.execute() == GridOptionsEditor.SAVE_SETTINGS) 606 { 607 // changes have been applied to the view here 608 XChangesBatch xUpdateControl = 609 (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot); 610 611 try 612 { 613 xUpdateControl.commitChanges(); 614 } 615 catch (Exception e) 616 { 617 dialog.informUserOfError( e ); 618 } 619 } 620 621 // all changes have been handled - clean up and return 622 // listener is done now 623 xNotifier.removeChangesListener( xListener ); 624 625 // we are done with the view - dispose it 626 ((XComponent)UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose(); 627 } 628 629 /** A class that changes some grid options settings 630 631 The interface of this class is chose to resemble a possible UI dialog class 632 */ 633 private class GridOptionsEditor { 634 /// the data this editor edits 635 XMultiHierarchicalPropertySet mxModel; 636 637 public static final int CANCELED = 0; 638 public static final int SAVE_SETTINGS = 1; 639 640 // sets a model and updates the display 641 public void setModel(XMultiHierarchicalPropertySet xModel) { 642 mxModel = xModel; 643 updateDisplay(); 644 } 645 646 // this method 'runs' the 'dialog' 647 public int execute() { 648 try 649 { 650 System.out.println("-- GridEditor executing --"); 651 // simulate a user action changing some data 652 toggleVisibility(); 653 System.out.println("-- GridEditor done --"); 654 return SAVE_SETTINGS; 655 } 656 catch (Exception e) 657 { 658 informUserOfError(e); 659 return CANCELED; 660 } 661 } 662 663 /// this method is called to report an error during dialog execution to the zuser 664 public void informUserOfError(Exception e) { 665 System.err.println("ERROR in GridEditor:"); 666 e.printStackTrace(); 667 } 668 669 /// this method is called to allow the dialog to get feedback about changes occurring elsewhere 670 public XChangesListener createChangesListener() { 671 if (mxModel == null) return null; 672 673 return (new XChangesListener () { 674 public void changesOccurred( ChangesEvent event ) { 675 System.out.println("GridEditor - Listener received changes event containing " + 676 event.Changes.length + " change(s)."); 677 updateDisplay(); 678 } 679 680 public void disposing(EventObject event) { 681 System.out.println("GridEditor - Listener received disposed event: releasing model"); 682 setModel(null); 683 } 684 }); 685 } 686 /// this method is called when data has changed to display the updated data 687 private void updateDisplay() { 688 if (mxModel != null) 689 System.out.println("Grid options editor: data=" + readModel()); 690 else 691 System.out.println("Grid options editor: no model set"); 692 } 693 694 // this method is used to read all relevant data from the model 695 private GridOptions readModel() 696 { 697 try 698 { 699 String [] aOptionNames = new String [5]; 700 aOptionNames[0] = "Option/VisibleGrid"; 701 aOptionNames[1] = "Subdivision/XAxis"; 702 aOptionNames[2] = "Subdivision/YAxis"; 703 aOptionNames[3] = "Resolution/XAxis/Metric"; 704 aOptionNames[4] = "Resolution/YAxis/Metric"; 705 706 Object [] aValues = mxModel.getHierarchicalPropertyValues(aOptionNames); 707 708 GridOptions result = new GridOptions(); 709 result.visible = ((Boolean)aValues[0]).booleanValue(); 710 result.subdivision_x = ((Integer)aValues[1]).intValue(); 711 result.subdivision_y = ((Integer)aValues[2]).intValue(); 712 result.resolution_x = ((Integer)aValues[3]).intValue(); 713 result.resolution_y = ((Integer)aValues[4]).intValue(); 714 715 return result; 716 } 717 catch (Exception e) 718 { 719 informUserOfError(e); 720 return null; 721 } 722 } 723 724 // this method executes an edit 725 private void toggleVisibility() 726 { 727 try 728 { 729 XHierarchicalPropertySet xHPS = 730 (XHierarchicalPropertySet)UnoRuntime.queryInterface(XHierarchicalPropertySet.class, mxModel); 731 732 final String sSetting = "Option/VisibleGrid"; 733 734 System.out.println("GridEditor: toggling Visibility"); 735 736 Boolean bOldValue = (Boolean)xHPS.getHierarchicalPropertyValue(sSetting); 737 738 Boolean bNewValue = new Boolean( ! bOldValue.booleanValue() ); 739 740 xHPS.setHierarchicalPropertyValue(sSetting,bNewValue); 741 } 742 catch (Exception e) 743 { 744 informUserOfError(e); 745 } 746 } 747 } 748 749 /** This method creates an extra updatable view to change some data 750 and trigger the listener of the GridEditor 751 */ 752 void changeSomeData(String xKey) 753 { 754 try 755 { 756 Object xOtherViewRoot = createUpdatableView(xKey); 757 758 XNameReplace aReplace = (XNameReplace)UnoRuntime.queryInterface(XNameReplace.class, xOtherViewRoot); 759 760 String aItemNames [] = aReplace.getElementNames(); 761 for (int i=0; i < aItemNames.length; ++i) { 762 Object aItem = aReplace.getByName( aItemNames [i] ); 763 AnyConverter aAnyConv = new AnyConverter(); 764 // replace integers by a 'complement' value 765 if ( aAnyConv.isInt(aItem) ) 766 { 767 int nOld = aAnyConv.toInt(aItem); 768 int nNew = 9999 - nOld; 769 770 System.out.println("Replacing integer value: " + aItemNames [i]); 771 aReplace.replaceByName( aItemNames [i], new Integer( nNew ) ); 772 } 773 774 // and booleans by their negated value 775 else if ( aAnyConv.isBoolean(aItem) ) 776 { 777 boolean bOld = aAnyConv.toBoolean(aItem); 778 boolean bNew = ! bOld; 779 780 System.out.println("Replacing boolean value: " + aItemNames [i]); 781 aReplace.replaceByName( aItemNames [i], new Boolean( bNew ) ); 782 } 783 } 784 785 // commit the changes 786 XChangesBatch xUpdateControl = 787 (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class,xOtherViewRoot); 788 789 xUpdateControl.commitChanges(); 790 791 // we are done with the view - dispose it 792 ((XComponent)UnoRuntime.queryInterface(XComponent.class, xOtherViewRoot)).dispose(); 793 } 794 catch (Exception e) 795 { 796 System.err.println("Could not change some data in a different view. An exception occurred:"); 797 e.printStackTrace(); 798 } 799 } 800 801 // GROUP RESET EXAMPLE 802 /// This method resets the grid settings to their default values 803 protected void resetGridConfiguration() 804 throws com.sun.star.uno.Exception 805 { 806 // The path to the root element 807 final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid"; 808 809 // create the view 810 Object xViewRoot = createUpdatableView(cGridOptionsPath); 811 812 // resetting a single nested value 813 XHierarchicalNameAccess xHierarchicalAccess = 814 (XHierarchicalNameAccess)UnoRuntime.queryInterface(XHierarchicalNameAccess.class, xViewRoot); 815 816 // get using absolute name 817 Object xOptions = xHierarchicalAccess.getByHierarchicalName(cGridOptionsPath + "/Option"); 818 819 XPropertyState xOptionState = 820 (XPropertyState)UnoRuntime.queryInterface(XPropertyState.class, xOptions); 821 822 xOptionState.setPropertyToDefault("VisibleGrid"); 823 824 // resetting more deeply nested values 825 Object xResolutionX = xHierarchicalAccess.getByHierarchicalName("Resolution/XAxis"); 826 Object xResolutionY = xHierarchicalAccess.getByHierarchicalName("Resolution/YAxis"); 827 828 XPropertyState xResolutionStateX = 829 (XPropertyState)UnoRuntime.queryInterface(XPropertyState.class, xResolutionX); 830 XPropertyState xResolutionStateY = 831 (XPropertyState)UnoRuntime.queryInterface(XPropertyState.class, xResolutionY); 832 833 xResolutionStateX.setPropertyToDefault("Metric"); 834 xResolutionStateY.setPropertyToDefault("Metric"); 835 836 // resetting multiple sibling values 837 Object xSubdivision = xHierarchicalAccess.getByHierarchicalName("Subdivision"); 838 839 XMultiPropertyStates xSubdivisionStates = 840 (XMultiPropertyStates)UnoRuntime.queryInterface(XMultiPropertyStates.class, xSubdivision); 841 842 xSubdivisionStates.setAllPropertiesToDefault(); 843 844 // commit the changes 845 XChangesBatch xUpdateControl = 846 (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot); 847 848 xUpdateControl.commitChanges(); 849 850 // we are done with the view - dispose it 851 ((XComponent)UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose(); 852 } 853 854 855 // SET UPDATE EXAMPLE 856 private static boolean SET_EXAMPLE_BROKEN_IN_THIS_RELEASE = true; 857 858 /** This method stores a sample data source given some connection data. 859 860 ATTENTION: This example requires an older version of the 861 org.openoffice.Office.DataAccess schema. 862 It does not work with the current schema. 863 Because of this, the method currenty does nothing. 864 You can still use the techniques shown in the example code. 865 */ 866 void storeSampleDataSource() 867 throws com.sun.star.uno.Exception 868 { 869 if (SET_EXAMPLE_BROKEN_IN_THIS_RELEASE) 870 { 871 System.out.println("- DISABLED: (the existing example does not work with this version) -"); 872 return; // this function does not work 873 } 874 875 String sSampleDataSourceName = "SampleTextDatabase"; 876 877 String sSampleDataSourceURL = "sdbc:flat:$(userurl)/database/SampleTextDatabase"; 878 // String sSampleDataSourceURL = "sdbc:flat:file:///usr/local/database/SampleTextDatabase"; 879 // String sSampleDataSourceURL = "sdbc:flat:file:///C:/data/database/SampleTextDatabase"; 880 881 com.sun.star.beans.NamedValue [] aSettings = new com.sun.star.beans.NamedValue [2]; 882 aSettings[0] = new com.sun.star.beans.NamedValue("HeaderLine",new Boolean(true)); 883 aSettings[1] = new com.sun.star.beans.NamedValue("FieldDelimiter",";"); 884 885 String [] aTableFilter = new String[2]; 886 aTableFilter[0] = "table.txt"; 887 aTableFilter[1] = "othertable.txt"; 888 889 storeDataSource(sSampleDataSourceName,sSampleDataSourceURL,"",false,0,aSettings,aTableFilter); 890 } 891 892 /// This method stores a data source given some connection data 893 void storeDataSource( 894 String sDataSourceName, 895 String sDataSourceURL, 896 String sUser, 897 boolean bNeedsPassword, 898 int nTimeout, 899 com.sun.star.beans.NamedValue [] aDriverSettings, 900 String [] aTableFilter 901 ) 902 throws com.sun.star.uno.Exception 903 { 904 // create the view and get the data source element 905 Object xDataSource = createDataSourceDescription(getProvider(),sDataSourceName); 906 907 // set the values 908 XPropertySet xDataSourceProperties = 909 (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, xDataSource); 910 911 xDataSourceProperties.setPropertyValue("URL", sDataSourceURL ); 912 xDataSourceProperties.setPropertyValue("User", sUser ); 913 xDataSourceProperties.setPropertyValue("IsPasswordRequired", new Boolean( bNeedsPassword ) ); 914 xDataSourceProperties.setPropertyValue("LoginTimeout", new Integer( nTimeout ) ); 915 916 if ( aTableFilter != null ) 917 xDataSourceProperties.setPropertyValue("TableFilter", aTableFilter ); 918 919 // store the driver-specific settings 920 if (aDriverSettings != null) 921 { 922 Object xSettingsSet = xDataSourceProperties.getPropertyValue("DataSourceSettings"); 923 storeSettings( xSettingsSet, aDriverSettings); 924 } 925 926 // save the data and dispose the view 927 // recover the view root 928 Object xViewRoot = getViewRoot(xDataSource); 929 930 // commit the changes 931 XChangesBatch xUpdateControl = 932 (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot); 933 934 xUpdateControl.commitChanges(); 935 936 // now clean up 937 ((XComponent) UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose(); 938 } 939 940 /** This method gets the DataSourceDescription for a data source. 941 It either gets the existing entry or creates a new instance. 942 */ 943 Object createDataSourceDescription(XMultiServiceFactory xProvider, String sDataSourceName ) 944 throws com.sun.star.uno.Exception 945 { 946 // The service name: Need an update access: 947 final String cUpdatableView = "com.sun.star.configuration.ConfigurationUpdateAccess"; 948 949 // The path to the DataSources set node 950 final String cDataSourcesPath = "/org.openoffice.Office.DataAccess/DataSources"; 951 952 // creation arguments: nodepath 953 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue(); 954 aPathArgument.Name = "nodepath"; 955 aPathArgument.Value = cDataSourcesPath ; 956 957 Object[] aArguments = new Object[1]; 958 aArguments[0] = aPathArgument; 959 960 // create the view 961 Object xViewRoot = 962 xProvider.createInstanceWithArguments(cUpdatableView, aArguments); 963 964 XNameAccess xSetOfDataSources = 965 (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class,xViewRoot); 966 967 Object xDataSourceDescriptor = null; // the result 968 if ( xSetOfDataSources .hasByName( sDataSourceName )) 969 { 970 // the element is there 971 try 972 { 973 // the view should point to the element directly, so we need to extend the path 974 XHierarchicalName xComposePath = (XHierarchicalName) 975 UnoRuntime.queryInterface(XHierarchicalName.class, xSetOfDataSources ); 976 977 String sElementPath = xComposePath.composeHierarchicalName( sDataSourceName ); 978 979 // use the name of the element now 980 aPathArgument.Value = sElementPath; 981 982 // create another view now 983 Object[] aDeepArguments = new Object[1]; 984 aDeepArguments[0] = aPathArgument; 985 986 // create the view 987 xDataSourceDescriptor = 988 xProvider.createInstanceWithArguments(cUpdatableView, aDeepArguments); 989 990 if ( xDataSourceDescriptor != null) // all went fine 991 { 992 // dispose the other view 993 ((XComponent)UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose(); 994 xViewRoot = null; 995 } 996 } 997 catch (Exception e) 998 { 999 // something went wrong, we retry with a new element 1000 System.err.println("WARNING: An exception occurred while creating a view for an existing data source: " + e); 1001 xDataSourceDescriptor = null; 1002 } 1003 } 1004 1005 // do we have a result element yet ? 1006 if ( xDataSourceDescriptor == null) 1007 { 1008 // get the container 1009 XNameContainer xSetUpdate = 1010 (XNameContainer)UnoRuntime.queryInterface(XNameContainer.class, xViewRoot); 1011 1012 // create a new detached set element (instance of DataSourceDescription) 1013 XSingleServiceFactory xElementFactory = 1014 (XSingleServiceFactory)UnoRuntime.queryInterface(XSingleServiceFactory.class, xSetUpdate); 1015 1016 // the new element is the result ! 1017 xDataSourceDescriptor = xElementFactory.createInstance(); 1018 1019 // insert it - this also names the element 1020 xSetUpdate.insertByName( sDataSourceName , xDataSourceDescriptor ); 1021 } 1022 1023 return xDataSourceDescriptor ; 1024 } 1025 1026 /// this method stores a number of settings in a set node containing DataSourceSetting objects 1027 void storeSettings(Object xSettingsSet, com.sun.star.beans.NamedValue [] aSettings ) 1028 throws com.sun.star.uno.Exception 1029 { 1030 if (aSettings == null) 1031 return; 1032 1033 // get the settings set as a container 1034 XNameContainer xSettingsContainer = 1035 (XNameContainer) UnoRuntime.queryInterface( XNameContainer.class, xSettingsSet); 1036 1037 // and get a factory interface for creating the entries 1038 XSingleServiceFactory xSettingsFactory = 1039 (XSingleServiceFactory) UnoRuntime.queryInterface(XSingleServiceFactory.class, xSettingsSet); 1040 1041 // now insert the individual settings 1042 for (int i = 0; i < aSettings.length; ++i) { 1043 // create a DataSourceSetting object 1044 XPropertySet xSetting = (XPropertySet) 1045 UnoRuntime.queryInterface( XPropertySet.class, xSettingsFactory.createInstance() ); 1046 1047 // can set the value before inserting 1048 xSetting.setPropertyValue( "Value", aSettings[i].Value ); 1049 1050 // and now insert or replace as appropriate 1051 if (xSettingsContainer.hasByName( aSettings[i].Name )) 1052 xSettingsContainer.replaceByName( aSettings[i].Name, xSetting ); 1053 else 1054 xSettingsContainer.insertByName( aSettings[i].Name, xSetting ); 1055 } 1056 } 1057 1058 // HELPER FUNCTIONS 1059 1060 /// This method get the view root node given an interface to any node in the view 1061 public static Object getViewRoot(Object xElement) 1062 { 1063 Object xResult = xElement; 1064 1065 // set the result to its parent until that would be null 1066 Object xParent; 1067 do 1068 { 1069 XChild xParentAccess = 1070 (XChild) UnoRuntime.queryInterface(XChild.class,xResult); 1071 1072 if (xParentAccess != null) 1073 xParent = xParentAccess.getParent(); 1074 else 1075 xParent = null; 1076 1077 if (xParent != null) 1078 xResult = xParent; 1079 } 1080 while (xParent != null); 1081 1082 return xResult; 1083 } 1084 1085 // workaround methods for unimplemented functionality 1086 1087 /// WORKAROUND: does the same as xNamedItem.setName(sNewName) should do 1088 void renameSetItem(XNamed xNamedItem, String sNewName) 1089 throws com.sun.star.uno.Exception 1090 { 1091 XChild xChildItem = (XChild) 1092 UnoRuntime.queryInterface(XChild.class, xNamedItem); 1093 1094 XNameContainer xParentSet = (XNameContainer) 1095 UnoRuntime.queryInterface( XNameContainer.class, xChildItem.getParent() ); 1096 1097 String sOldName = xNamedItem.getName(); 1098 1099 // now rename the item 1100 xParentSet.removeByName(sOldName); 1101 xParentSet.insertByName(sNewName,xNamedItem); 1102 } 1103 1104 /// WORKAROUND: does the same as xChildItem.setParent( xNewParent ) should do 1105 void moveSetItem(XChild xChildItem, XNameContainer xNewParent) 1106 throws com.sun.star.uno.Exception 1107 { 1108 XNamed xNamedItem = (XNamed) 1109 UnoRuntime.queryInterface(XNamed.class, xChildItem); 1110 1111 XNameContainer xOldParent = (XNameContainer) 1112 UnoRuntime.queryInterface( XNameContainer.class, xChildItem.getParent() ); 1113 1114 String sItemName = xNamedItem.getName(); 1115 1116 // now rename the item 1117 xOldParent.removeByName(sItemName); 1118 xNewParent.insertByName(sItemName,xChildItem); 1119 } 1120 1121 1122 // ------- the end ----------- 1123 } 1124