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