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