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 package org.openoffice.test.tools; 24 25 import com.sun.star.beans.PropertyState; 26 import com.sun.star.beans.PropertyValue; 27 import com.sun.star.document.MacroExecMode; 28 import com.sun.star.drawing.XDrawPage; 29 import com.sun.star.drawing.XDrawPageSupplier; 30 import com.sun.star.drawing.XDrawPages; 31 import com.sun.star.drawing.XDrawPagesSupplier; 32 import com.sun.star.frame.XComponentLoader; 33 import com.sun.star.frame.XController; 34 import com.sun.star.frame.XFrame; 35 import com.sun.star.frame.XModel; 36 import com.sun.star.lang.XComponent; 37 import com.sun.star.lang.XMultiServiceFactory; 38 import com.sun.star.lang.XServiceInfo; 39 import com.sun.star.uno.UnoRuntime; 40 import com.sun.star.uno.XInterface; 41 import com.sun.star.util.CloseVetoException; 42 import com.sun.star.util.XCloseable; 43 import com.sun.star.util.XModifiable; 44 import java.util.logging.Level; 45 import java.util.logging.Logger; 46 47 /**************************************************************************/ 48 49 /**************************************************************************/ 50 /** provides a small wrapper around a document 51 */ 52 public class OfficeDocument 53 { 54 /* ================================================================== */ 55 /* ------------------------------------------------------------------ */ OfficeDocument( XMultiServiceFactory orb, XComponent document )56 public OfficeDocument( XMultiServiceFactory orb, XComponent document ) 57 { 58 m_orb = orb; 59 m_documentComponent = document; 60 } 61 62 /* ------------------------------------------------------------------ */ implLoadAsComponent( XMultiServiceFactory orb, String documentOrFactoryURL )63 protected static XComponent implLoadAsComponent( XMultiServiceFactory orb, String documentOrFactoryURL ) throws com.sun.star.uno.Exception 64 { 65 return implLoadAsComponent( orb, documentOrFactoryURL, new PropertyValue[0] ); 66 } 67 68 /* ------------------------------------------------------------------ */ implLoadAsComponent( XMultiServiceFactory orb, String documentOrFactoryURL, final PropertyValue[] i_args )69 protected static XComponent implLoadAsComponent( XMultiServiceFactory orb, String documentOrFactoryURL, final PropertyValue[] i_args ) throws com.sun.star.uno.Exception 70 { 71 XComponentLoader aLoader = UnoRuntime.queryInterface( XComponentLoader.class, 72 orb.createInstance( "com.sun.star.frame.Desktop" ) ); 73 74 XComponent document = UnoRuntime.queryInterface( XComponent.class, 75 aLoader.loadComponentFromURL( documentOrFactoryURL, "_blank", 0, i_args ) 76 ); 77 return document; 78 } 79 80 /* ------------------------------------------------------------------ */ implLoadDocument( XMultiServiceFactory orb, String documentOrFactoryURL )81 private static OfficeDocument implLoadDocument( XMultiServiceFactory orb, String documentOrFactoryURL ) throws com.sun.star.uno.Exception 82 { 83 return implLoadDocument( orb, documentOrFactoryURL, new PropertyValue[0] ); 84 } 85 86 /* ------------------------------------------------------------------ */ implLoadDocument( XMultiServiceFactory orb, String documentOrFactoryURL, final PropertyValue[] i_args )87 private static OfficeDocument implLoadDocument( XMultiServiceFactory orb, String documentOrFactoryURL, final PropertyValue[] i_args ) throws com.sun.star.uno.Exception 88 { 89 XComponent document = implLoadAsComponent( orb, documentOrFactoryURL, i_args ); 90 91 XServiceInfo xSI = UnoRuntime.queryInterface( XServiceInfo.class, document ); 92 if ( xSI.supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) ) 93 return new SpreadsheetDocument( orb, document ); 94 return new OfficeDocument( orb, document ); 95 } 96 97 /* ------------------------------------------------------------------ */ loadDocument( XMultiServiceFactory orb, String documentURL )98 public static OfficeDocument loadDocument( XMultiServiceFactory orb, String documentURL ) throws com.sun.star.uno.Exception 99 { 100 return implLoadDocument( orb, documentURL ); 101 } 102 103 /* ------------------------------------------------------------------ */ blankTextDocument( XMultiServiceFactory orb )104 public static OfficeDocument blankTextDocument( XMultiServiceFactory orb ) throws com.sun.star.uno.Exception 105 { 106 return blankDocument( orb, DocumentType.WRITER ); 107 } 108 109 /* ------------------------------------------------------------------ */ blankXMLForm( XMultiServiceFactory orb )110 public static OfficeDocument blankXMLForm( XMultiServiceFactory orb ) throws com.sun.star.uno.Exception 111 { 112 return blankDocument( orb, DocumentType.XMLFORM ); 113 } 114 115 /* ------------------------------------------------------------------ */ blankDocument( XMultiServiceFactory orb, DocumentType eType )116 public static OfficeDocument blankDocument( XMultiServiceFactory orb, DocumentType eType ) throws com.sun.star.uno.Exception 117 { 118 final PropertyValue[] args = new PropertyValue[] { 119 new PropertyValue( "MacroExecutionMode", -1, MacroExecMode.ALWAYS_EXECUTE, PropertyState.DIRECT_VALUE ) 120 }; 121 return implLoadDocument( orb, getDocumentFactoryURL( eType ), args ); 122 } 123 124 /* ------------------------------------------------------------------ */ close()125 public boolean close() 126 { 127 try 128 { 129 XCloseable closeDoc = UnoRuntime.queryInterface( XCloseable.class, m_documentComponent ); 130 closeDoc.close( true ); 131 return true; 132 } 133 catch ( CloseVetoException e ) 134 { 135 Logger.getLogger( OfficeDocument.class.getName() ).log( Level.SEVERE, "closing the document was vetoed", e ); 136 } 137 return false; 138 } 139 140 /* ================================================================== */ 141 /* ------------------------------------------------------------------ */ getDocument( )142 public XComponent getDocument( ) 143 { 144 return m_documentComponent; 145 } 146 147 /* ------------------------------------------------------------------ */ isModified()148 public boolean isModified() 149 { 150 XModifiable modify = (XModifiable)query( XModifiable.class ); 151 return modify.isModified(); 152 } 153 154 /* ------------------------------------------------------------------ */ query( Class aInterfaceClass )155 public Object query( Class aInterfaceClass ) 156 { 157 return UnoRuntime.queryInterface( aInterfaceClass, m_documentComponent ); 158 } 159 160 /* ------------------------------------------------------------------ */ getOrb( )161 public XMultiServiceFactory getOrb( ) 162 { 163 return m_orb; 164 } 165 166 /* ------------------------------------------------------------------ */ 167 /** retrieves the current view of the document 168 @return 169 the view component, queried for the interface described by aInterfaceClass 170 */ getCurrentView( )171 public OfficeDocumentView getCurrentView( ) 172 { 173 // get the model interface for the document 174 XModel xDocModel = UnoRuntime.queryInterface( XModel.class, m_documentComponent ); 175 // get the current controller for the document - as a controller is tied to a view, 176 // this gives us the currently active view for the document. 177 XController xController = xDocModel.getCurrentController(); 178 179 if ( classify() == DocumentType.CALC ) 180 return new SpreadsheetView( m_orb, this, xController ); 181 182 return new OfficeDocumentView( m_orb, this, xController ); 183 } 184 185 /* ------------------------------------------------------------------ */ 186 /** reloads the document 187 * 188 * The reload is done by dispatching the respective URL at a frame of the document. 189 * As a consequence, if you have references to a view of the document, or any interface 190 * of the document, they will become invalid. 191 * The Model instance itself, at which you called reload, will still be valid, it will 192 * automatically update its internal state after the reload. 193 * 194 * Another consequence is that if the document does not have a view at all, it cannot 195 * be reloaded. 196 */ reload()197 public void reload() throws Exception 198 { 199 OfficeDocumentView view = getCurrentView(); 200 XFrame frame = view.getController().getFrame(); 201 XModel oldModel = frame.getController().getModel(); 202 203 getCurrentView().dispatch( ".uno:Reload" ); 204 205 m_documentComponent = UnoRuntime.queryInterface( XComponent.class, frame.getController().getModel() ); 206 207 XModel newModel = getCurrentView().getController().getModel(); 208 if ( UnoRuntime.areSame( oldModel, newModel ) ) 209 throw new java.lang.IllegalStateException( "reload failed" ); 210 } 211 212 /* ------------------------------------------------------------------ */ 213 /** returns a URL which can be used to create a document of a certain type 214 */ getDocumentFactoryURL( DocumentType eType )215 public static String getDocumentFactoryURL( DocumentType eType ) 216 { 217 if ( eType == DocumentType.WRITER ) 218 return "private:factory/swriter"; 219 if ( eType == DocumentType.CALC ) 220 return "private:factory/scalc"; 221 if ( eType == DocumentType.DRAWING ) 222 return "private:factory/sdraw"; 223 if ( eType == DocumentType.XMLFORM ) 224 return "private:factory/swriter?slot=21053"; 225 if ( eType == DocumentType.PRESENTATION ) 226 return "private:factory/simpress"; 227 if ( eType == DocumentType.FORMULA ) 228 return "private:factory/smath"; 229 return "private:factory/swriter"; 230 } 231 232 /* ------------------------------------------------------------------ */ 233 /** classifies a document 234 */ classify( )235 public DocumentType classify( ) 236 { 237 XServiceInfo xSI = UnoRuntime.queryInterface( XServiceInfo.class, m_documentComponent ); 238 239 if ( xSI.supportsService( "com.sun.star.text.TextDocument" ) ) 240 return DocumentType.WRITER; 241 else if ( xSI.supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) ) 242 return DocumentType.CALC; 243 else if ( xSI.supportsService( "com.sun.star.drawing.DrawingDocument" ) ) 244 return DocumentType.DRAWING; 245 else if ( xSI.supportsService( "com.sun.star.presentation.PresentationDocument" ) ) 246 return DocumentType.PRESENTATION; 247 else if ( xSI.supportsService( "com.sun.star.formula.FormulaProperties" ) ) 248 return DocumentType.FORMULA; 249 250 return DocumentType.UNKNOWN; 251 } 252 253 /* ------------------------------------------------------------------ */ 254 /** retrieves a com.sun.star.drawing.DrawPage of the document, denoted by index 255 * @param index 256 * the index of the draw page 257 * @throws 258 * com.sun.star.lang.IndexOutOfBoundsException 259 * com.sun.star.lang.WrappedTargetException 260 */ getDrawPage( int index )261 protected XDrawPage getDrawPage( int index ) throws com.sun.star.lang.IndexOutOfBoundsException, com.sun.star.lang.WrappedTargetException 262 { 263 XDrawPagesSupplier xSuppPages = UnoRuntime.queryInterface( XDrawPagesSupplier.class, getDocument() ); 264 XDrawPages xPages = xSuppPages.getDrawPages(); 265 266 return UnoRuntime.queryInterface( XDrawPage.class, xPages.getByIndex( index ) ); 267 } 268 269 /* ------------------------------------------------------------------ */ 270 /** retrieves the <type scope="com.sun.star.drawing">DrawPage</type> of the document 271 */ getMainDrawPage( )272 protected XDrawPage getMainDrawPage( ) throws com.sun.star.uno.Exception 273 { 274 XDrawPage xReturn; 275 276 // in case of a Writer document, this is rather easy: simply ask the XDrawPageSupplier 277 XDrawPageSupplier xSuppPage = UnoRuntime.queryInterface( XDrawPageSupplier.class, getDocument() ); 278 if ( null != xSuppPage ) 279 xReturn = xSuppPage.getDrawPage(); 280 else 281 { // the model itself is no draw page supplier - okay, it may be a Writer or Calc document 282 // (or any other multi-page document) 283 XDrawPagesSupplier xSuppPages = UnoRuntime.queryInterface( XDrawPagesSupplier.class, getDocument() ); 284 XDrawPages xPages = xSuppPages.getDrawPages(); 285 286 xReturn = UnoRuntime.queryInterface( XDrawPage.class, xPages.getByIndex( 0 ) ); 287 288 // Note that this is no really error-proof code: If the document model does not support the 289 // XDrawPagesSupplier interface, or if the pages collection returned is empty, this will break. 290 } 291 292 return xReturn; 293 } 294 295 /* ------------------------------------------------------------------ */ 296 /** creates a component at the service factory provided by the document 297 */ createInstance( String serviceSpecifier )298 public XInterface createInstance( String serviceSpecifier ) throws com.sun.star.uno.Exception 299 { 300 XMultiServiceFactory xORB = UnoRuntime.queryInterface( XMultiServiceFactory.class, m_documentComponent ); 301 return (XInterface)xORB.createInstance( serviceSpecifier ); 302 } 303 304 /* ------------------------------------------------------------------ */ 305 /** creates a component at the service factory provided by the document, queried for a given interface type 306 */ createInstance( String i_serviceSpecifier, Class<T> i_interfaceClass )307 public <T> T createInstance( String i_serviceSpecifier, Class<T> i_interfaceClass ) throws com.sun.star.uno.Exception 308 { 309 return UnoRuntime.queryInterface( i_interfaceClass, createInstance( i_serviceSpecifier ) ); 310 } 311 312 /* ------------------------------------------------------------------ */ 313 /** creates a component at the service factory provided by the document 314 */ createInstanceWithArguments( String serviceSpecifier, Object[] arguments )315 public XInterface createInstanceWithArguments( String serviceSpecifier, Object[] arguments ) throws com.sun.star.uno.Exception 316 { 317 XMultiServiceFactory xORB = UnoRuntime.queryInterface( XMultiServiceFactory.class, m_documentComponent ); 318 return (XInterface) xORB.createInstanceWithArguments( serviceSpecifier, arguments ); 319 } 320 321 private XMultiServiceFactory m_orb; 322 private XComponent m_documentComponent; 323 }; 324 325