1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 package com.sun.star.wiki; 29 30 import com.sun.star.awt.XDialog; 31 import com.sun.star.awt.XWindowPeer; 32 import com.sun.star.beans.PropertyValue; 33 import com.sun.star.frame.DispatchDescriptor; 34 import com.sun.star.frame.XComponentLoader; 35 import com.sun.star.frame.XController; 36 import com.sun.star.frame.XDesktop; 37 import com.sun.star.frame.XDispatch; 38 import com.sun.star.frame.XDispatchProvider; 39 import com.sun.star.frame.XFrame; 40 import com.sun.star.frame.XModel; 41 import com.sun.star.frame.XStatusListener; 42 import com.sun.star.frame.XStorable; 43 import com.sun.star.io.XInputStream; 44 import com.sun.star.lang.XComponent; 45 import com.sun.star.lang.XInitialization; 46 import com.sun.star.uno.UnoRuntime; 47 import com.sun.star.uno.XComponentContext; 48 import com.sun.star.lib.uno.helper.Factory; 49 import com.sun.star.lang.XSingleComponentFactory; 50 import com.sun.star.registry.XRegistryKey; 51 import com.sun.star.lib.uno.helper.WeakBase; 52 import com.sun.star.util.XCloseBroadcaster; 53 import com.sun.star.view.XSelectionSupplier; 54 import java.io.File; 55 import java.net.URI; 56 import java.net.URISyntaxException; 57 import java.util.HashMap; 58 import java.util.Hashtable; 59 import java.util.Iterator; 60 import java.util.Map; 61 import java.util.Set; 62 import javax.net.ssl.SSLException; 63 64 65 public final class WikiEditorImpl extends WeakBase 66 implements com.sun.star.lang.XServiceInfo, XDispatchProvider, XDispatch, XInitialization 67 { 68 69 private final XComponentContext m_xContext; 70 private static final String m_implementationName = WikiEditorImpl.class.getName(); 71 private static final String[] m_serviceNames = {"com.sun.star.wiki.WikiEditor" }; 72 73 // information needed for component registration 74 public static final String[] supportedServiceNames = {"com.sun.star.frame.ProtocolHandler"}; 75 public static final Class implementationClass = WikiEditorImpl.class; 76 // protocol name that this protocol handler handles 77 public static final String protocolName = "vnd.com.sun.star.wiki:"; 78 79 private Map m_statusListeners = new HashMap(); 80 81 82 private XComponent xComp; 83 private String sTempUrl; 84 85 private XFrame m_xFrame; 86 private XModel m_xModel; 87 private Settings m_aSettings; 88 89 private String m_aFilterName; 90 91 public WikiEditorImpl( XComponentContext xContext ) 92 { 93 // Helper.trustAllSSL(); 94 m_xContext = xContext; 95 m_aSettings = Settings.getSettings( m_xContext ); 96 }; 97 98 public static XSingleComponentFactory __getComponentFactory( String sImplementationName ) 99 { 100 XSingleComponentFactory xFactory = null; 101 102 if ( sImplementationName.equals( m_implementationName ) ) 103 xFactory = Factory.createComponentFactory( WikiEditorImpl.class, m_serviceNames ); 104 else if ( sImplementationName.equals( WikiOptionsEventHandlerImpl.m_sImplementationName ) ) 105 xFactory = Factory.createComponentFactory( WikiOptionsEventHandlerImpl.class, 106 WikiOptionsEventHandlerImpl.m_pServiceNames ); 107 108 return xFactory; 109 } 110 111 public static boolean __writeRegistryServiceInfo( XRegistryKey xRegistryKey ) 112 { 113 boolean bResult = Factory.writeRegistryServiceInfo( m_implementationName, 114 m_serviceNames, 115 xRegistryKey ); 116 return ( bResult && Factory.writeRegistryServiceInfo( WikiOptionsEventHandlerImpl.m_sImplementationName, 117 WikiOptionsEventHandlerImpl.m_pServiceNames, 118 xRegistryKey ) ); 119 } 120 121 // com.sun.star.lang.XServiceInfo: 122 public String getImplementationName() 123 { 124 return m_implementationName; 125 } 126 127 public boolean supportsService( String sService ) 128 { 129 int len = m_serviceNames.length; 130 131 for( int i=0; i < len; i++ ) 132 { 133 if ( sService.equals( m_serviceNames[i] )) 134 return true; 135 } 136 return false; 137 } 138 139 public String[] getSupportedServiceNames() 140 { 141 return m_serviceNames; 142 } 143 144 145 private XSelectionSupplier m_sel; 146 private XController m_ctrl; 147 private boolean m_bInitialized; 148 public synchronized void initialize( Object[] args ) throws com.sun.star.uno.Exception 149 { 150 if ( m_bInitialized ) 151 { 152 //logger.log( Level.SEVERE, "Extension instance was initialized again" ); 153 } 154 if ( args.length > 0 ) 155 { 156 m_bInitialized = true; 157 m_xFrame = ( XFrame )UnoRuntime.queryInterface( XFrame.class, args[0] ); 158 // become close listener 159 XCloseBroadcaster cb = ( XCloseBroadcaster )UnoRuntime.queryInterface( 160 XCloseBroadcaster.class, m_xFrame ); 161 } 162 } 163 164 165 166 public void dispatch( 167 final com.sun.star.util.URL aURL, 168 com.sun.star.beans.PropertyValue[] propertyValue ) 169 { 170 final com.sun.star.util.URL myURL = aURL; 171 //logger.log( Level.INFO, "received dispatch request for: "+aURL.Complete ); 172 if ( aURL.Protocol.compareTo( protocolName ) == 0 ) 173 { 174 /* 175 synchronized( this ) 176 { 177 if( m_bClosing ) return; 178 else m_bActive = true; 179 } 180 **/ 181 182 try 183 { 184 if ( myURL.Path.compareTo( "send" ) == 0 ) 185 { 186 sendArticle(); 187 } 188 } catch( java.lang.Throwable t ) 189 { 190 //logger.log( Level.WARNING, "exception while handeling dispatch", t ); 191 } 192 193 /* 194 synchronized( this ) 195 { 196 m_bActive = false; 197 // if we became owner while we were active 198 // we are responsible for closing the m_xFrame now 199 if ( m_bOwner && m_xFrame != null ) 200 { 201 try 202 { 203 XCloseable xclose = ( XCloseable )UnoRuntime.queryInterface( 204 XCloseable.class, m_xFrame ); 205 xclose.close( true ); 206 } catch ( CloseVetoException cve ) 207 { 208 logger.log( Level.SEVERE, "cannot close owned frame" ); 209 } 210 // relase reference to the m_xFrame; 211 m_xFrame = null; 212 } 213 } 214 */ 215 } 216 } 217 218 219 public com.sun.star.frame.XDispatch queryDispatch( 220 com.sun.star.util.URL aURL, 221 String str, 222 int param ) 223 { 224 if ( aURL.Protocol.equals( protocolName )) 225 { 226 227 // by default, we are responsible 228 return this; 229 } else 230 { 231 return null; 232 } 233 } 234 235 public XDispatch[] queryDispatches( DispatchDescriptor[] seqDescripts ) 236 { 237 int nCount = seqDescripts.length; 238 XDispatch[] lDispatcher = new XDispatch[nCount]; 239 240 for( int i=0; i<nCount; ++i ) 241 lDispatcher[i] = queryDispatch( 242 seqDescripts[i].FeatureURL, 243 seqDescripts[i].FrameName, 244 seqDescripts[i].SearchFlags ); 245 return lDispatcher; 246 } 247 248 249 public void removeStatusListener( 250 com.sun.star.frame.XStatusListener xStatusListener, 251 com.sun.star.util.URL aURL ) 252 { 253 } 254 255 256 public void addStatusListener( 257 com.sun.star.frame.XStatusListener listener, 258 com.sun.star.util.URL url ) 259 { 260 String urlstring = url.Complete; 261 m_statusListeners.put( urlstring, listener ); 262 // synchroneous callback required!!! 263 callStatusListener( urlstring, listener ); 264 } 265 266 public void callStatusListeners() 267 { 268 Set entries = m_statusListeners.entrySet(); 269 Iterator iter = entries.iterator(); 270 while ( iter.hasNext() ) 271 { 272 Map.Entry entry = ( Map.Entry ) iter.next(); 273 String uristring = ( String ) entry.getKey(); 274 XStatusListener listener = ( XStatusListener ) entry.getValue(); 275 callStatusListener( uristring, listener ); 276 } 277 } 278 279 public void callStatusListener( String uristring, XStatusListener listener ) 280 { 281 try 282 { 283 284 URI uri = new URI( uristring ); 285 286 // check whether any blogs are live... 287 setListenerState( listener, "command", false ); 288 } catch ( URISyntaxException ex ) 289 { 290 ex.printStackTrace(); 291 } 292 } 293 294 295 private void setListenerState( XStatusListener listener, String urlstring, boolean state ) 296 { 297 com.sun.star.util.URL url = new com.sun.star.util.URL(); 298 url.Complete = urlstring; 299 //listener.statusChanged( new FeatureStateEvent( this, url, "", state, false, null )); 300 301 } 302 303 public void sendArticle() 304 { 305 if ( m_xFrame != null ) 306 { 307 WikiPropDialog aSendDialog = null; 308 try 309 { 310 if ( m_xModel == null ) 311 { 312 XController xController = m_xFrame.getController(); 313 if ( xController != null ) 314 m_xModel = xController.getModel(); 315 } 316 317 if ( m_xModel != null ) 318 { 319 // The related Wiki filter must be detected from the typename 320 String aServiceName = Helper.GetDocServiceName( m_xContext, m_xModel ); 321 m_aFilterName = Helper.GetFilterName( m_xContext, "MediaWiki", aServiceName ); 322 323 if ( m_aFilterName == null || m_aFilterName.length() == 0 ) 324 { 325 Helper.ShowError( m_xContext, 326 (XWindowPeer)UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ), 327 Helper.DLG_SENDTITLE, 328 Helper.NOWIKIFILTER_ERROR, 329 null, 330 false ); 331 throw new com.sun.star.uno.RuntimeException(); 332 } 333 334 m_aSettings.loadConfiguration(); // throw away all the noncommited changes 335 // show the send dialog 336 aSendDialog = new WikiPropDialog( m_xContext, "vnd.sun.star.script:WikiEditor.SendToMediaWiki?location=application", this ); 337 aSendDialog.fillWikiList(); 338 aSendDialog.SetWikiTitle( Helper.GetDocTitle( m_xModel ) ); 339 aSendDialog.show(); // triggers the sending 340 } 341 } 342 catch ( Exception e ) 343 { 344 // TODO: Error handling here 345 e.printStackTrace(); 346 } 347 finally 348 { 349 if ( aSendDialog != null ) 350 aSendDialog.DisposeDialog(); 351 } 352 } 353 } 354 355 public boolean SendArticleImpl( WikiPropDialog aSendDialog, Hashtable aWikiSetting ) 356 { 357 boolean bResult = false; 358 359 if ( aSendDialog != null ) 360 { 361 String sTemp2Url = null; 362 363 try 364 { 365 // TODO: stop progress spinning 366 WikiArticle aArticle = new WikiArticle( m_xContext, aSendDialog.GetWikiTitle(), aWikiSetting, true, aSendDialog ); 367 368 boolean bAllowSending = true; 369 if ( !aArticle.NotExist() ) 370 { 371 // ask whether creation of a new page is allowed 372 aSendDialog.SetThrobberActive( false ); 373 bAllowSending = Helper.ShowError( 374 m_xContext, 375 (XWindowPeer)UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ), 376 Helper.DLG_SENDTITLE, 377 Helper.DLG_WIKIPAGEEXISTS_LABEL1, 378 aSendDialog.GetWikiTitle(), 379 true ); 380 aSendDialog.SetThrobberActive( true ); 381 } 382 383 if ( bAllowSending ) 384 { 385 PropertyValue[] lProperties = new PropertyValue[2]; 386 lProperties[0] = new PropertyValue(); 387 lProperties[0].Name = "FilterName"; 388 lProperties[0].Value = m_aFilterName; 389 lProperties[1] = new PropertyValue(); 390 lProperties[1].Name = "Overwrite"; 391 lProperties[1].Value = new Boolean( true ); 392 393 sTemp2Url = Helper.CreateTempFile( m_xContext ); 394 395 XStorable xStore = ( com.sun.star.frame.XStorable )UnoRuntime.queryInterface ( XStorable.class, m_xModel ); 396 if ( xStore == null ) 397 throw new com.sun.star.uno.RuntimeException(); 398 399 xStore.storeToURL( sTemp2Url, lProperties ); 400 String sWikiCode = Helper.EachLine( sTemp2Url ); 401 402 if ( aArticle.setArticle( sWikiCode, aSendDialog.m_sWikiComment, aSendDialog.m_bWikiMinorEdit ) ) 403 { 404 bResult = true; 405 Object desktop = m_xContext.getServiceManager().createInstanceWithContext( "com.sun.star.frame.Desktop", m_xContext ); 406 XDesktop xDesktop = ( XDesktop ) UnoRuntime.queryInterface( com.sun.star.frame.XDesktop.class, desktop ); 407 Helper.SetDocTitle( m_xModel, aArticle.GetTitle() ); 408 Hashtable aDocInfo = new Hashtable(); 409 aDocInfo.put( "Doc", aArticle.GetTitle() ); 410 aDocInfo.put( "Url", aArticle.GetMainURL() ); 411 aDocInfo.put( "CompleteUrl", aArticle.GetMainURL() + aArticle.GetTitle() ); 412 m_aSettings.addWikiDoc( aDocInfo ); 413 m_aSettings.storeConfiguration(); 414 } 415 else 416 { 417 Helper.ShowError( m_xContext, 418 (XWindowPeer)UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ), 419 Helper.DLG_SENDTITLE, 420 Helper.GENERALSEND_ERROR, 421 null, 422 false ); 423 } 424 } 425 } 426 catch( WikiCancelException ec ) 427 { 428 // nothing to do, the sending was cancelled 429 } 430 catch( SSLException essl ) 431 { 432 if ( Helper.IsConnectionAllowed() ) 433 { 434 // report the error only if sending was not cancelled 435 Helper.ShowError( m_xContext, 436 (XWindowPeer)UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ), 437 Helper.DLG_SENDTITLE, 438 Helper.UNKNOWNCERT_ERROR, 439 null, 440 false ); 441 } 442 } 443 catch( Exception e ) 444 { 445 if ( Helper.IsConnectionAllowed() ) 446 { 447 // report the error only if sending was not cancelled 448 Helper.ShowError( m_xContext, 449 (XWindowPeer)UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ), 450 Helper.DLG_SENDTITLE, 451 Helper.GENERALSEND_ERROR, 452 null, 453 false ); 454 } 455 e.printStackTrace(); 456 } 457 458 if ( sTemp2Url != null ) 459 { 460 try 461 { 462 // remove the temporary file 463 File aFile = new File( new URI( sTemp2Url ) ); 464 aFile.delete(); 465 } 466 catch ( java.lang.Exception e ) 467 { 468 e.printStackTrace(); 469 } 470 } 471 } 472 473 return bResult; 474 } 475 476 } 477