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