1 /*
2  * This file is part of the LibreOffice project.
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * This file incorporates work covered by the following license notice:
9  *
10  *   Licensed to the Apache Software Foundation (ASF) under one or more
11  *   contributor license agreements. See the NOTICE file distributed
12  *   with this work for additional information regarding copyright
13  *   ownership. The ASF licenses this file to you under the Apache
14  *   License, Version 2.0 (the "License"); you may not use this file
15  *   except in compliance with the License. You may obtain a copy of
16  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
17  */
18 
19 package com.sun.star.wiki;
20 
21 import com.sun.star.awt.MessageBoxButtons;
22 import com.sun.star.awt.MessageBoxType;
23 import com.sun.star.awt.XControl;
24 import com.sun.star.awt.XDialog;
25 import com.sun.star.awt.XMessageBox;
26 import com.sun.star.awt.XMessageBoxFactory;
27 import com.sun.star.awt.XWindowPeer;
28 import com.sun.star.beans.NamedValue;
29 import com.sun.star.beans.PropertyValue;
30 import com.sun.star.beans.XPropertySet;
31 import com.sun.star.container.XContainerQuery;
32 import com.sun.star.container.XEnumeration;
33 import com.sun.star.container.XNameAccess;
34 import com.sun.star.container.XNameContainer;
35 import com.sun.star.document.XDocumentPropertiesSupplier;
36 import com.sun.star.document.XDocumentProperties;
37 import com.sun.star.frame.XModel;
38 import com.sun.star.frame.XModuleManager;
39 import com.sun.star.io.XInputStream;
40 import com.sun.star.io.XOutputStream;
41 import com.sun.star.lang.XMultiComponentFactory;
42 import com.sun.star.lang.XMultiServiceFactory;
43 import com.sun.star.lang.XComponent;
44 import com.sun.star.system.SystemShellExecuteFlags;
45 import com.sun.star.system.XSystemShellExecute;
46 import com.sun.star.task.UrlRecord;
47 import com.sun.star.task.XInteractionHandler;
48 import com.sun.star.task.XMasterPasswordHandling;
49 import com.sun.star.task.XPasswordContainer;
50 import com.sun.star.uno.AnyConverter;
51 import com.sun.star.uno.UnoRuntime;
52 import com.sun.star.uno.XComponentContext;
53 import com.sun.star.util.XChangesBatch;
54 import java.net.*;
55 import java.io.*;
56 import javax.net.ssl.HttpsURLConnection;
57 import javax.net.ssl.SSLException;
58 import javax.swing.text.html.HTMLEditorKit;
59 
60 
61 public class Helper
62 {
63     public static final int GENERALSEND_ERROR = 0;
64     public static final int NOWIKIFILTER_ERROR = 1;
65     public static final int NOURLCONNECTION_ERROR = 2;
66     public static final int WRONGLOGIN_ERROR = 3;
67     public static final int INVALIDURL_ERROR = 4;
68     public static final int NOURL_ERROR = 5;
69 
70     public static final int DLG_SENDTITLE = 6;
71     public static final int DLG_WIKIARTICLE = 7;
72 
73     public static final int DLG_OK = 9;
74 
75     // 11 is reserved
76     public static final int DLG_ADDBUTTON = 12;
77     public static final int DLG_EDITBUTTON = 13;
78     public static final int DLG_SENDBUTTON = 14;
79     public static final int DLG_REMOVEBUTTON = 15;
80 
81     public static final int DLG_EDITSETTING_URLLABEL = 16;
82     public static final int DLG_EDITSETTING_USERNAMELABEL = 17;
83     public static final int DLG_EDITSETTING_PASSWORDLABEL = 18;
84 
85     public static final int DLG_SENDTOMEDIAWIKI_LABEL1 = 20;
86     public static final int DLG_SENDTOMEDIAWIKI_LABEL2 = 21;
87     public static final int DLG_SENDTOMEDIAWIKI_LABEL3 = 22;
88     public static final int DLG_SENDTOMEDIAWIKI_MINORCHECK = 23;
89     public static final int DLG_SENDTOMEDIAWIKI_BROWSERCHECK = 24;
90     public static final int UNKNOWNCERT_ERROR = 25;
91     public static final int DLG_MEDIAWIKI_TITLE = 26;
92     public static final int DLG_EDITSETTING_ACCOUNTLINE = 27;
93     public static final int DLG_EDITSETTING_WIKILINE = 28;
94     public static final int DLG_EDITSETTING_SAVEBOX = 29;
95     public static final int CANCELSENDING_ERROR = 30;
96     public static final int DLG_MEDIAWIKIEXTENSION_STRING = 31;
97     public static final int DLG_WIKIPAGEEXISTS_LABEL1 = 32;
98 
99     private static final int STRINGS_NUM = 33;
100 
101     private static final String[] m_pEntryNames = { "GeneralSendError",
102                                                     "NoWikiFilter",
103                                                     "NoConnectionToURL",
104                                                     "WrongLogin",
105                                                     "InvalidURL",
106                                                     "NoURL",
107                                                     "Dlg_SendTitle",
108                                                     "Dlg_WikiArticle",
109                                                     "Dlg_No",
110                                                     "Dlg_OK",
111                                                     "Dlg_Yes",
112                                                     null, // reserved
113                                                     "Dlg_AddButton",
114                                                     "Dlg_EditButton",
115                                                     "Dlg_SendButton",
116                                                     "Dlg_RemoveButton",
117                                                     "Dlg_EditSetting_UrlLabel",
118                                                     "Dlg_EditSetting_UsernameLabel",
119                                                     "Dlg_EditSetting_PasswordLabel",
120                                                     "Dlg_NewWikiPage_Label1",
121                                                     "Dlg_SendToMediaWiki_Label1",
122                                                     "Dlg_SendToMediaWiki_Label2",
123                                                     "Dlg_SendToMediaWiki_Label3",
124                                                     "Dlg_SendToMediaWiki_MinorCheck",
125                                                     "Dlg_SendToMediaWiki_BrowserCheck",
126                                                     "UnknownCert",
127                                                     "Dlg_MediaWiki_Title",
128                                                     "Dlg_EditSetting_AccountLine",
129                                                     "Dlg_EditSetting_WikiLine",
130                                                     "Dlg_EditSetting_SaveBox",
131                                                     "CancelSending",
132                                                     "Dlg_MediaWiki_Extension_String",
133                                                     "Dlg_WikiPageExists_Label1" };
134 
135     private static String[] m_pConfigStrings;
136 
137     private static boolean m_bAllowConnection = true;
138 
139     private static Boolean m_bShowInBrowser = null;
140 
141     private static XPasswordContainer m_xPasswordContainer;
142     private static XInteractionHandler m_xInteractionHandler;
143 
GetLocalizedString( XComponentContext xContext, int nID )144     synchronized protected static String GetLocalizedString( XComponentContext xContext, int nID )
145         throws com.sun.star.uno.Exception
146     {
147         if ( nID >= STRINGS_NUM )
148             throw new com.sun.star.uno.RuntimeException();
149 
150         if ( m_pConfigStrings == null )
151         {
152             XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Office.Custom.WikiExtension/Strings" );
153 
154             String[] pStrings = new String[STRINGS_NUM];
155             for ( int nInd = 0; nInd < STRINGS_NUM; nInd++ )
156                 if ( m_pEntryNames[nInd] != null )
157                     pStrings[nInd] = AnyConverter.toString( xNameAccess.getByName( m_pEntryNames[nInd] ) );
158                 else
159                     pStrings[nInd] = "";
160 
161             m_pConfigStrings = pStrings;
162         }
163 
164         return m_pConfigStrings[nID];
165     }
166 
AllowConnection( boolean bAllow )167     synchronized protected static void AllowConnection( boolean bAllow )
168     {
169         m_bAllowConnection = bAllow;
170         // TODO: how to shut down any pending connections?
171         // hope it doesn't matter?
172     }
173 
IsConnectionAllowed()174     synchronized protected static boolean IsConnectionAllowed()
175     {
176         return m_bAllowConnection;
177     }
178 
GetShowInBrowserByDefault( XComponentContext xContext )179     synchronized protected static boolean GetShowInBrowserByDefault( XComponentContext xContext )
180     {
181         if ( m_bShowInBrowser == null )
182         {
183             try
184             {
185                 XNameAccess xAccess = Helper.GetConfigNameAccess( xContext, "org.openoffice.Office.Custom.WikiExtension/Settings" );
186                 m_bShowInBrowser = Boolean.valueOf( AnyConverter.toBoolean( xAccess.getByName( "PreselectShowBrowser" ) ) );
187             }
188             catch( com.sun.star.uno.Exception e )
189             {
190                 e.printStackTrace();
191             }
192         }
193 
194         return m_bShowInBrowser != null ? m_bShowInBrowser.booleanValue() : false;
195     }
196 
SetShowInBrowserByDefault( XComponentContext xContext, boolean bValue )197     synchronized protected static void SetShowInBrowserByDefault( XComponentContext xContext, boolean bValue )
198     {
199         try
200         {
201             m_bShowInBrowser = Boolean.valueOf( bValue );
202 
203             XPropertySet xProps = Helper.GetConfigProps( xContext, "org.openoffice.Office.Custom.WikiExtension/Settings" );
204             xProps.setPropertyValue( "PreselectShowBrowser", Boolean.valueOf( bValue ) );
205             XChangesBatch xBatch = UnoRuntime.queryInterface( XChangesBatch.class, xProps );
206             if ( xBatch != null )
207                 xBatch.commitChanges();
208         }
209         catch( Exception e )
210         {
211             e.printStackTrace();
212         }
213     }
214 
GetPasswordContainer( XComponentContext xContext )215     synchronized protected static XPasswordContainer GetPasswordContainer( XComponentContext xContext )
216         throws com.sun.star.uno.Exception
217     {
218         if ( m_xPasswordContainer == null && xContext != null )
219         {
220             XMultiComponentFactory xFactory = xContext.getServiceManager();
221             if ( xFactory != null )
222                 m_xPasswordContainer = UnoRuntime.queryInterface(
223                                         XPasswordContainer.class,
224                                         xFactory.createInstanceWithContext( "com.sun.star.task.PasswordContainer", xContext ) );
225         }
226 
227         if ( m_xPasswordContainer == null )
228             throw new com.sun.star.uno.RuntimeException();
229 
230         return m_xPasswordContainer;
231     }
232 
GetInteractionHandler( XComponentContext xContext )233     synchronized protected static XInteractionHandler GetInteractionHandler( XComponentContext xContext )
234         throws com.sun.star.uno.Exception
235     {
236         if ( m_xInteractionHandler == null && xContext != null )
237         {
238             XMultiComponentFactory xFactory = xContext.getServiceManager();
239             if ( xFactory != null )
240                 m_xInteractionHandler = UnoRuntime.queryInterface(
241                                         XInteractionHandler.class,
242                                         xFactory.createInstanceWithContext( "com.sun.star.task.InteractionHandler", xContext ) );
243         }
244 
245         if ( m_xInteractionHandler == null )
246             throw new com.sun.star.uno.RuntimeException();
247 
248         return m_xInteractionHandler;
249     }
250 
GetMainURL( String sWebPage, String sVURL )251     protected static String GetMainURL( String sWebPage, String sVURL )
252     {
253         String sResultURL = "";
254         try
255         {
256             StringReader aReader = new StringReader( sWebPage );
257             HTMLEditorKit.Parser aParser = GetHTMLParser();
258             EditPageParser aCallback = new EditPageParser();
259 
260             aParser.parse( aReader, aCallback, true );
261             sResultURL = aCallback.m_sMainURL;
262 
263             if ( !sResultURL.startsWith( "http" ) )
264             {
265                 //if the url is only relative then complete it
266                 URL aURL = new URL( sVURL );
267                 sResultURL = aURL.getProtocol() + "://" + aURL.getHost() + sResultURL;
268             }
269         }
270         catch( Exception e )
271         {
272             e.printStackTrace();
273         }
274 
275         if ( sResultURL.length() == 0 )
276         {
277             // usually that should not happen
278             // workaround: try to get index.php from the provided URL
279             int nIndex = sVURL.indexOf( "index.php" );
280             if ( nIndex >= 0 )
281                 sResultURL = sVURL.substring( 0, nIndex );
282         }
283 
284         return sResultURL;
285     }
286 
GetRedirectURL( String sWebPage, String sURL )287     protected static String GetRedirectURL( String sWebPage, String sURL )
288     {
289         //scrape the HTML source and find the EditURL
290         // TODO/LATER: Use parser in future
291 
292         int nInd = sWebPage.indexOf( "http-equiv=\"refresh\"" );
293         if ( nInd == -1 )
294             return "";
295 
296         String sResultURL = "";
297         int nContent = sWebPage.indexOf( "content=", nInd );
298         if ( nContent > 0 )
299         {
300             int nURL = sWebPage.indexOf( "URL=", nContent );
301             if ( nURL > 0 )
302             {
303                 int nEndURL = sWebPage.indexOf('"', nURL );
304                 if ( nEndURL > 0 )
305                     sResultURL = sWebPage.substring( nURL + 4, nEndURL );
306             }
307         }
308 
309         try
310         {
311             URL aURL = new URL( sURL );
312             if ( !sResultURL.startsWith( aURL.getProtocol() ))
313             {
314                 //if the url is only relative then complete it
315                 if ( sResultURL.startsWith( "/" ) )
316                     sResultURL = aURL.getProtocol() + "://" + aURL.getHost() + sResultURL;
317                 else
318                     sResultURL = aURL.getProtocol() + "://" + aURL.getHost() + aURL.getPath() + sResultURL;
319             }
320         }
321         catch ( MalformedURLException ex )
322         {
323             ex.printStackTrace();
324         }
325 
326         return sResultURL;
327 
328     }
329 
CreateTempFile( XComponentContext xContext )330     protected static String CreateTempFile( XComponentContext xContext )
331     {
332         String sURL = "";
333         try
334         {
335             Object oTempFile = xContext.getServiceManager().createInstanceWithContext( "com.sun.star.io.TempFile", xContext );
336             XPropertySet xPropertySet = UnoRuntime.queryInterface( XPropertySet.class, oTempFile );
337             xPropertySet.setPropertyValue( "RemoveFile", Boolean.FALSE );
338             sURL = ( String ) xPropertySet.getPropertyValue( "Uri" );
339 
340             XInputStream xInputStream = UnoRuntime.queryInterface( XInputStream.class, oTempFile );
341             xInputStream.closeInput();
342             XOutputStream xOutputStream = UnoRuntime.queryInterface( XOutputStream.class, oTempFile );
343             xOutputStream.closeOutput();
344         } catch ( com.sun.star.uno.Exception ex )
345         {
346             ex.printStackTrace();
347         }
348         return sURL;
349     }
350 
close(BufferedReader c)351     private static void close(BufferedReader c) {
352         if (c == null) return;
353         try {
354             c.close();
355         } catch (IOException e) {
356             e.printStackTrace();
357         }
358     }
359 
EachLine( String sURL )360     protected static String EachLine( String sURL )
361     {
362         String sText = "";
363         BufferedReader aBufReader = null;
364         try
365         {
366             URL aURL = new URL( sURL );
367             File aFile = new File( aURL.getFile() );
368             InputStreamReader aInputReader = new InputStreamReader( new FileInputStream( aFile ), "UTF-8" );
369             aBufReader = new BufferedReader( aInputReader );
370 
371             StringBuffer aBuf = new StringBuffer();
372             String sEachLine = aBufReader.readLine();
373 
374             while( sEachLine != null )
375             {
376                 aBuf.append( sEachLine );
377                 aBuf.append( "\n" );
378 
379                 sEachLine = aBufReader.readLine();
380             }
381             sText = aBuf.toString();
382 
383             aBufReader.close();
384         } catch ( Exception e ) {
385             e.printStackTrace();
386         }
387         finally {
388             close(aBufReader);
389         }
390         return sText;
391     }
392 
GetDocTitle( XModel xDoc )393     protected static String GetDocTitle( XModel xDoc )
394     {
395         XDocumentPropertiesSupplier xDocPropSup =
396             UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xDoc);
397         XDocumentProperties xDocProps = xDocPropSup.getDocumentProperties();
398         return xDocProps.getTitle();
399     }
400 
SetDocTitle( XModel xDoc, String sTitle )401     protected static void SetDocTitle( XModel xDoc, String sTitle )
402     {
403         XDocumentPropertiesSupplier xDocPropSup =
404             UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xDoc);
405         XDocumentProperties xDocProps = xDocPropSup.getDocumentProperties();
406         xDocProps.setTitle(sTitle);
407     }
408 
GetDocServiceName( XComponentContext xContext, XModel xModel )409     protected static String GetDocServiceName( XComponentContext xContext, XModel xModel )
410     {
411         String aDocServiceName = "";
412         if ( xModel != null && xContext != null )
413         {
414             try
415             {
416                 XMultiComponentFactory xFactory = xContext.getServiceManager();
417                 if ( xFactory == null )
418                     throw new com.sun.star.uno.RuntimeException();
419 
420                 Object oModuleManager = xFactory.createInstanceWithContext( "com.sun.star.frame.ModuleManager", xContext );
421                 XModuleManager xModuleManager = UnoRuntime.queryInterface( XModuleManager.class, oModuleManager );
422                 if ( xModuleManager != null )
423                     aDocServiceName = xModuleManager.identify( xModel );
424             }
425             catch( java.lang.Exception e )
426             {
427                 e.printStackTrace();
428             }
429         }
430 
431         return aDocServiceName;
432     }
433 
GetFilterName( XComponentContext xContext, String aTypeName, String aDocServiceName )434     protected static String GetFilterName( XComponentContext xContext, String aTypeName, String aDocServiceName )
435     {
436         if ( xContext == null || aTypeName == null || aTypeName.length() == 0
437                 || aDocServiceName == null || aDocServiceName.length() == 0 ) {
438             return "";
439         }
440         String aFilterName = "";
441         try
442         {
443             Object oFilterFactory = xContext.getServiceManager().createInstanceWithContext( "com.sun.star.document.FilterFactory", xContext );
444             XContainerQuery xQuery = UnoRuntime.queryInterface( XContainerQuery.class, oFilterFactory );
445             if ( xQuery != null )
446             {
447                 NamedValue[] aRequest = new NamedValue[2];
448                 aRequest[0] = new NamedValue( "Type", aTypeName );
449                 aRequest[1] = new NamedValue( "DocumentService", aDocServiceName );
450 
451                 XEnumeration xSet = xQuery.createSubSetEnumerationByProperties( aRequest );
452                 if ( xSet != null )
453                 {
454                     boolean bAcceptable = false;
455                     while ( xSet.hasMoreElements() && !bAcceptable )
456                     {
457                         PropertyValue[] pFilterProps = ( PropertyValue[] )AnyConverter.toArray( xSet.nextElement() );
458                         if ( pFilterProps != null )
459                         {
460                             int nLen = pFilterProps.length;
461                             String aTmpFilter = null;
462 
463                             for ( int nInd = 0; nInd < nLen; nInd++ )
464                             {
465                                 if ( pFilterProps[nInd].Name.equals( "Name" ) )
466                                     aTmpFilter = AnyConverter.toString( pFilterProps[nInd].Value );
467                                 else if ( pFilterProps[nInd].Name.equals( "Flags" ) )
468                                     bAcceptable = ( ( AnyConverter.toInt( pFilterProps[nInd].Value ) & 2 ) == 2 ); // must allow export
469                             }
470 
471                             if ( bAcceptable )
472                                 aFilterName = aTmpFilter;
473                         }
474                     }
475                 }
476             }
477         }
478         catch( java.lang.Exception e )
479         {
480             e.printStackTrace();
481         }
482 
483         return aFilterName;
484     }
485 
GetConfigurationProvider( XComponentContext xContext )486     private static XMultiServiceFactory GetConfigurationProvider( XComponentContext xContext )
487         throws com.sun.star.uno.Exception
488     {
489         XMultiServiceFactory xConfigurationProvider = null;
490         if ( xContext != null )
491         {
492             XMultiComponentFactory xFactory = xContext.getServiceManager();
493             Object oConfigProvider = xFactory.createInstanceWithContext( "com.sun.star.configuration.ConfigurationProvider", xContext );
494             xConfigurationProvider = UnoRuntime.queryInterface( XMultiServiceFactory.class, oConfigProvider );
495         }
496 
497         if ( xConfigurationProvider == null )
498             throw new com.sun.star.uno.RuntimeException();
499 
500         return xConfigurationProvider;
501     }
502 
GetConfig( XComponentContext xContext, String sNodepath, boolean bWriteAccess )503     private static Object GetConfig( XComponentContext xContext, String sNodepath, boolean bWriteAccess )
504         throws com.sun.star.uno.Exception
505     {
506         if ( xContext == null || sNodepath == null )
507             throw new com.sun.star.uno.RuntimeException();
508 
509         PropertyValue aVal = new PropertyValue();
510         aVal.Name = "nodepath";
511         aVal.Value = sNodepath;
512         Object[] aArgs = new Object[1];
513         aArgs[0] = aVal;
514 
515         return GetConfigurationProvider( xContext ).createInstanceWithArguments(
516                                     ( bWriteAccess ? "com.sun.star.configuration.ConfigurationUpdateAccess"
517                                                    : "com.sun.star.configuration.ConfigurationAccess" ),
518                                     aArgs );
519     }
520 
GetConfigProps( XComponentContext xContext, String sNodepath )521     private static XPropertySet GetConfigProps( XComponentContext xContext, String sNodepath )
522         throws com.sun.star.uno.Exception
523     {
524         XPropertySet xProps = UnoRuntime.queryInterface( XPropertySet.class, GetConfig( xContext, sNodepath, true ) );
525         if ( xProps == null )
526             throw new com.sun.star.uno.RuntimeException();
527 
528         return xProps;
529     }
530 
531 
GetConfigNameContainer( XComponentContext xContext, String sNodepath )532     protected static XNameContainer GetConfigNameContainer( XComponentContext xContext, String sNodepath )
533         throws com.sun.star.uno.Exception
534     {
535         XNameContainer xContainer = UnoRuntime.queryInterface( XNameContainer.class, GetConfig( xContext, sNodepath, true ) );
536         if ( xContainer == null )
537             throw new com.sun.star.uno.RuntimeException();
538 
539         return xContainer;
540     }
541 
GetConfigNameAccess( XComponentContext xContext, String sNodepath )542     protected static XNameAccess GetConfigNameAccess( XComponentContext xContext, String sNodepath )
543         throws com.sun.star.uno.Exception
544     {
545         XNameAccess xNameAccess = UnoRuntime.queryInterface( XNameAccess.class, GetConfig( xContext, sNodepath, false ) );
546         if ( xNameAccess == null )
547             throw new com.sun.star.uno.RuntimeException();
548 
549         return xNameAccess;
550     }
551 
GetConfigurationProxy(URI uri, XComponentContext xContext)552     private static Proxy GetConfigurationProxy(URI uri, XComponentContext xContext)
553     {
554         assert(uri != null);
555         assert(xContext != null);
556 
557         try
558         {
559             XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Inet/Settings" );
560 
561             int nProxyType = AnyConverter.toInt( xNameAccess.getByName( "ooInetProxyType" ) );
562             if ( nProxyType == 0 ) {
563                 return Proxy.NO_PROXY;
564             } else {
565                 if ( nProxyType == 1 )
566                 {
567                     // system proxy
568                     return null;
569                 }
570                 else if ( nProxyType == 2 )
571                 {
572                     String aProxyNameProp = "ooInetHTTPProxyName";
573                     String aProxyPortProp = "ooInetHTTPProxyPort";
574 
575                     if (uri.getScheme().equals("https"))
576                     {
577                         aProxyNameProp = "ooInetHTTPSProxyName";
578                         aProxyPortProp = "ooInetHTTPSProxyPort";
579                     }
580 
581                     String aProxyName = AnyConverter.toString( xNameAccess.getByName( aProxyNameProp ) );
582 
583                     int nProxyPort = 80;
584 
585                     Object aPortNo = xNameAccess.getByName( aProxyPortProp );
586                     if ( !AnyConverter.isVoid( aPortNo ) )
587                         nProxyPort = AnyConverter.toInt( aPortNo );
588 
589                     if ( nProxyPort == -1 )
590                         nProxyPort = 80;
591 
592                     // TODO: check whether the URL is in the NoProxy list
593                     InetSocketAddress address = new InetSocketAddress(aProxyName, nProxyPort);
594                     return new Proxy(Proxy.Type.HTTP, address);
595                 }
596             }
597         }
598         catch( java.lang.Exception e )
599         {
600             e.printStackTrace();
601         }
602         return null; // invalid configuration value?
603     }
604 
ShowURLInBrowser( XComponentContext xContext, String sURL )605     protected static void ShowURLInBrowser( XComponentContext xContext, String sURL )
606     {
607         if ( xContext != null && sURL != null && sURL.length() > 0 )
608         {
609             try
610             {
611                 Object oSystemShell = xContext.getServiceManager().createInstanceWithContext( "com.sun.star.system.SystemShellExecute", xContext );
612                 XSystemShellExecute xSystemShell = UnoRuntime.queryInterface( XSystemShellExecute.class, oSystemShell );
613                 if ( xSystemShell != null )
614                     xSystemShell.execute( sURL, "", SystemShellExecuteFlags.URIS_ONLY );
615             }
616             catch( Exception e )
617             {
618                 e.printStackTrace();
619             }
620         }
621     }
622 
PrepareMethod(String method, URI uri, XComponentContext xContext)623     protected static HttpURLConnection PrepareMethod(String method, URI uri, XComponentContext xContext)
624         throws WikiCancelException, IOException, SSLException
625     {
626         assert(method != null);
627         assert(uri != null);
628         assert(xContext != null);
629 
630         if (!IsConnectionAllowed()) {
631             throw new WikiCancelException();
632         }
633 
634         if (java.net.CookieHandler.getDefault() == null) {
635             // set a cookie manager so cookies don't get lost
636             // apparently it's not possible to do that on a per-connection
637             // basis but only globally?
638             java.net.CookieHandler.setDefault(new java.net.CookieManager());
639         }
640 
641         Proxy proxy = GetConfigurationProxy(uri, xContext);
642         HttpURLConnection conn = null;
643         if (proxy != null) {
644             conn = (HttpURLConnection) uri.toURL().openConnection(proxy);
645         } else {
646             conn = (HttpURLConnection) uri.toURL().openConnection();
647         }
648         if (uri.getScheme().equals("https") && AllowUnknownCert(xContext, uri.getHost()))
649         {
650             // let unknown certificates be accepted
651             ((HttpsURLConnection) conn).setSSLSocketFactory(new WikiProtocolSocketFactory());
652         }
653 
654 // enable this to help debug connections where TLS gets in the way
655 //        ((HttpsURLConnection) conn).setSSLSocketFactory(new LoggingProtocolSocketFactory());
656 
657         conn.setRequestMethod(method);
658         // TODO: is it possible to read the version from the extension metadata?
659         conn.setRequestProperty("User-Agent", "LibreOffice Wiki Publisher 1.2.0");
660         // note: don't connect yet so that the caller can do some further setup
661 
662         return conn;
663     }
664 
ReadResponseBody(HttpURLConnection conn)665     protected static String ReadResponseBody(HttpURLConnection conn)
666         throws IOException
667     {
668         String ret = null;
669         InputStream stream = conn.getInputStream();
670         try {
671             // there doesn't seem to be an easier way get the content encoding
672             String type = conn.getContentType();
673             String charset = "ISO-8859-1"; // default in RFC2616
674             for (String param : type.split(";")) {
675                 if (param.trim().toLowerCase().startsWith("charset=")) {
676                     charset = param.trim().substring("charset=".length());
677                     break;
678                 }
679             }
680             BufferedReader br =
681                 new BufferedReader(new InputStreamReader(stream, charset));
682             StringBuilder buf = new StringBuilder();
683             String line;
684             while ((line = br.readLine()) != null) {
685                 buf.append(line);
686             }
687             ret = buf.toString();
688         } finally {
689             stream.close();
690         }
691         return ret;
692     }
693 
694     private static class HTMLParse extends HTMLEditorKit
695     {
696 
697         @Override
getParser()698         public HTMLEditorKit.Parser getParser()
699         {
700             return super.getParser();
701         }
702     }
703 
GetHTMLParser()704     protected static HTMLEditorKit.Parser GetHTMLParser()
705     {
706         return new HTMLParse().getParser();
707     }
708 
LoginReportsError( String sRespond )709     private static boolean LoginReportsError( String sRespond )
710     {
711         boolean bResult = true;
712         if ( sRespond != null )
713         {
714             try
715             {
716                 StringReader aReader = new StringReader( sRespond );
717                 HTMLEditorKit.Parser aParser = GetHTMLParser();
718                 EditPageParser aCallback = new EditPageParser();
719 
720                 aParser.parse( aReader, aCallback, true );
721                 bResult = ( aCallback.m_nErrorInd >= 0 );
722             }
723             catch( Exception e )
724             {
725                 e.printStackTrace();
726             }
727         }
728 
729         return bResult;
730     }
731 
GetLoginToken( String sLoginPage )732     private static String GetLoginToken( String sLoginPage )
733     {
734         String sResult = "";
735         if ( sLoginPage != null && sLoginPage.length() > 0 )
736         {
737             try
738             {
739                 StringReader aReader = new StringReader( sLoginPage );
740                 HTMLEditorKit.Parser aParser = Helper.GetHTMLParser();
741                 EditPageParser aCallbacks = new EditPageParser();
742 
743                 aParser.parse( aReader, aCallbacks, true );
744                 sResult = aCallbacks.m_sLoginToken;
745             }
746             catch( Exception e )
747             {
748                 e.printStackTrace();
749             }
750         }
751 
752         return sResult;
753     }
754 
Login(URI aMainURL, String sWikiUser, String sWikiPass, XComponentContext xContext)755     protected static boolean Login(URI aMainURL, String sWikiUser, String sWikiPass, XComponentContext xContext)
756         throws java.io.IOException, WikiCancelException, URISyntaxException
757     {
758         boolean success = false;
759 
760         if ( sWikiUser != null && sWikiPass != null && xContext != null )
761         {
762             String sLoginPage = null;
763             URI aURI = new URI(aMainURL.toString() + "index.php?title=Special:Userlogin");
764             HttpURLConnection connGet = PrepareMethod("GET", aURI, xContext);
765             connGet.setInstanceFollowRedirects(true);
766 
767             connGet.connect();
768             int nResultCode = connGet.getResponseCode();
769             if (nResultCode == 200) {
770                 sLoginPage = ReadResponseBody(connGet);
771             }
772 
773             if ( sLoginPage != null )
774             {
775                 String sLoginToken = GetLoginToken( sLoginPage );
776 
777                 URI aPostURI = new URI(aMainURL.toString() + "index.php?title=Special:Userlogin&action=submitlogin");
778 
779                 HttpURLConnection connPost = PrepareMethod("POST", aPostURI, xContext);
780                 connPost.setInstanceFollowRedirects(true);
781                 connPost.setDoInput(true);
782                 connPost.setDoOutput(true);
783                 connPost.connect();
784 
785                 OutputStreamWriter post = new OutputStreamWriter(connPost.getOutputStream(), "UTF-8");
786                 try
787                 {
788                     post.write("wpName=");
789                     post.write(URLEncoder.encode(sWikiUser, "UTF-8"));
790                     post.write("&wpRemember=1");
791                     post.write("&wpPassword=");
792                     post.write(URLEncoder.encode(sWikiPass, "UTF-8"));
793 
794                     if (sLoginToken.length() > 0) {
795                         post.write("&wpLoginToken=");
796                        post.write(URLEncoder.encode(sLoginToken, "UTF-8"));
797                     }
798 
799                     String[][] pArgs = GetSpecialArgs( xContext, aMainURL.getHost() );
800                     if ( pArgs != null )
801                         for ( int nArgInd = 0; nArgInd < pArgs.length; nArgInd++ )
802                             if ( pArgs[nArgInd].length == 2 && pArgs[nArgInd][0] != null && pArgs[nArgInd][1] != null )
803                             {
804                                 post.write("&");
805                                 post.write(URLEncoder.encode(pArgs[nArgInd][0], "UTF-8"));
806                                 post.write("=");
807                                post.write(URLEncoder.encode(pArgs[nArgInd][0], "UTF-8"));
808                            }
809 
810                     post.flush();
811                 }
812                 finally
813                 {
814                     post.close();
815                 }
816 
817                 nResultCode = connPost.getResponseCode();
818 
819                 if ( nResultCode == 200 )
820                 {
821                     String sResult = ReadResponseBody(connPost);
822                     if ( !LoginReportsError( sResult ) )
823                         success = true;
824                 }
825             }
826         }
827 
828         return success;
829     }
830 
GetPasswordsForURLAndUser( XComponentContext xContext, String sURL, String sUserName )831     protected static String[] GetPasswordsForURLAndUser( XComponentContext xContext, String sURL, String sUserName )
832     {
833         String[] aResult = null;
834 
835         try
836         {
837             if ( xContext != null && sURL != null && sURL.length() > 0 && sUserName != null && sUserName.length() > 0 )
838             {
839                 UrlRecord aRec = GetPasswordContainer( xContext ).findForName( sURL, sUserName, GetInteractionHandler( xContext ) );
840                 if ( aRec != null && aRec.UserList != null && aRec.UserList.length > 0
841                   && aRec.UserList[0].UserName.equals( sUserName ) )
842                     aResult = aRec.UserList[0].Passwords;
843             }
844         }
845         catch( Exception e )
846         {
847             e.printStackTrace();
848         }
849 
850         return aResult;
851     }
852 
PasswordStoringIsAllowed( XComponentContext xContext )853     protected static boolean PasswordStoringIsAllowed( XComponentContext xContext )
854     {
855         boolean bResult = false;
856         try
857         {
858             XMasterPasswordHandling xMasterHdl = UnoRuntime.queryInterface( XMasterPasswordHandling.class, GetPasswordContainer( xContext ) );
859             if ( xMasterHdl != null )
860                 bResult = xMasterHdl.isPersistentStoringAllowed();
861         }
862         catch( Exception e )
863         {
864             e.printStackTrace();
865         }
866 
867         return bResult;
868     }
869 
ShowError( XComponentContext xContext, XDialog xDialog, int nTitleID, int nErrorID, String sArg, boolean bQuery )870     protected static void ShowError( XComponentContext xContext, XDialog xDialog, int nTitleID, int nErrorID, String sArg, boolean bQuery )
871     {
872         XWindowPeer xPeer = null;
873         XControl xControl = UnoRuntime.queryInterface( XControl.class, xDialog );
874         if ( xControl != null )
875             xPeer = xControl.getPeer();
876         ShowError( xContext, xPeer, nTitleID, nErrorID, sArg, bQuery );
877     }
878 
ShowError( XComponentContext xContext, XWindowPeer xParentPeer, int nTitleID, int nErrorID, String sArg, boolean bQuery )879     protected static boolean ShowError( XComponentContext xContext, XWindowPeer xParentPeer, int nTitleID, int nErrorID, String sArg, boolean bQuery )
880     {
881         boolean bResult = false;
882 
883         if ( xContext != null && nErrorID >= 0 && nErrorID < STRINGS_NUM )
884         {
885             String sError = null;
886             String sTitle = "";
887 
888             try
889             {
890                 sError = GetLocalizedString( xContext, nErrorID );
891                 if ( sError != null && sArg != null )
892                     sError = sError.replaceAll( "\\$ARG1", sArg );
893 
894                 sTitle = GetLocalizedString( xContext, nTitleID );
895             }
896             catch( Exception e )
897             {
898                 e.printStackTrace();
899             }
900 
901             if ( sError == null )
902                 sError = "Error: " + nErrorID;
903 
904             if ( xParentPeer != null )
905             {
906                 XMessageBoxFactory xMBFactory = null;
907                 XMessageBox xMB = null;
908                 try
909                 {
910                     XMultiComponentFactory xFactory = xContext.getServiceManager();
911                     if ( xFactory != null )
912                         xMBFactory = UnoRuntime.queryInterface(
913                                      XMessageBoxFactory.class,
914                                      xFactory.createInstanceWithContext( "com.sun.star.awt.Toolkit", xContext ) );
915 
916                     if ( xMBFactory != null )
917                     {
918                         if ( bQuery )
919                         {
920                             xMB = xMBFactory.createMessageBox(
921                                                      xParentPeer,
922                                                      MessageBoxType.QUERYBOX,
923                                                      MessageBoxButtons.BUTTONS_YES_NO | MessageBoxButtons.DEFAULT_BUTTON_NO,
924                                                      sTitle,
925                                                      sError );
926                         }
927                         else
928                         {
929                             xMB = xMBFactory.createMessageBox(
930                                                      xParentPeer,
931                                                      MessageBoxType.ERRORBOX,
932                                                      MessageBoxButtons.BUTTONS_OK,
933                                                      sTitle,
934                                                      sError );
935                         }
936                         if ( xMB != null )
937                         {
938                             bResult = MainThreadDialogExecutor.Execute( xContext, xMB );
939                         }
940                     }
941                 }
942                 catch( Exception e )
943                 {
944                     e.printStackTrace();
945                 }
946                 finally
947                 {
948                     if ( xMB != null )
949                         Dispose( xMB );
950                 }
951             }
952         }
953 
954         return bResult;
955     }
956 
AllowUnknownCert( XComponentContext xContext, String aURL )957     private static boolean AllowUnknownCert( XComponentContext xContext, String aURL )
958     {
959         try
960         {
961             XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Office.Custom.WikiExtension/SpecialData" );
962             if ( xNameAccess.hasByName( aURL ) )
963             {
964                 XNameAccess xEntry = UnoRuntime.queryInterface( XNameAccess.class, xNameAccess.getByName( aURL ) );
965                 if ( xEntry != null && xEntry.hasByName( "AllowUnknownCertificate" ) )
966                     return AnyConverter.toBoolean( xEntry.getByName( "AllowUnknownCertificate" ) );
967             }
968         }
969         catch( Exception e )
970         {
971             e.printStackTrace();
972         }
973 
974         return false;
975     }
976 
GetSpecialArgs( XComponentContext xContext, String aURL )977     private static String[][] GetSpecialArgs( XComponentContext xContext, String aURL )
978     {
979         try
980         {
981             XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Office.Custom.WikiExtension/SpecialData" );
982             if ( xNameAccess.hasByName( aURL ) )
983             {
984                 XNameAccess xEntry = UnoRuntime.queryInterface( XNameAccess.class, xNameAccess.getByName( aURL ) );
985                 if ( xEntry != null )
986                 {
987                     XNameAccess xArgs = UnoRuntime.queryInterface( XNameAccess.class, xEntry.getByName( "AdditionalLoginArguments" ) );
988                     if ( xArgs != null )
989                     {
990                         String[] pNames = xArgs.getElementNames();
991                         if ( pNames != null && pNames.length > 0 )
992                         {
993                             String[][] pResult = new String[pNames.length][2];
994                             for ( int nInd = 0; nInd < pNames.length; nInd++ )
995                             {
996                                 XNameAccess xArgument = UnoRuntime.queryInterface( XNameAccess.class, xArgs.getByName( pNames[nInd] ) );
997                                 if ( xArgument == null )
998                                     throw new com.sun.star.uno.RuntimeException();
999 
1000                                 pResult[nInd][0] = pNames[nInd];
1001                                 pResult[nInd][1] = AnyConverter.toString( xArgument.getByName( "Value" ) );
1002                             }
1003 
1004                             return pResult;
1005                         }
1006                     }
1007                 }
1008             }
1009         }
1010         catch( Exception e )
1011         {
1012             e.printStackTrace();
1013         }
1014 
1015         return null;
1016     }
1017 
AllowThreadUsage( XComponentContext xContext )1018     protected static boolean AllowThreadUsage( XComponentContext xContext )
1019     {
1020         if ( xContext != null )
1021         {
1022             try
1023             {
1024                 XMultiComponentFactory xFactory = xContext.getServiceManager();
1025                 if ( xFactory == null )
1026                     throw new com.sun.star.uno.RuntimeException();
1027 
1028                 Object oCheckCallback = xFactory.createInstanceWithContext( "com.sun.star.awt.AsyncCallback", xContext );
1029                 return ( oCheckCallback != null );
1030             }
1031             catch( Exception e )
1032             {
1033                 e.printStackTrace();
1034             }
1035         }
1036 
1037         return false;
1038     }
1039 
Dispose( Object oObject )1040     public static void Dispose( Object oObject )
1041     {
1042         if ( oObject != null )
1043         {
1044             try
1045             {
1046                 XComponent xComp = UnoRuntime.queryInterface( XComponent.class, oObject );
1047                 if ( xComp != null )
1048                     xComp.dispose();
1049             }
1050             catch( Exception e )
1051             {
1052                 e.printStackTrace();
1053             }
1054         }
1055     }
1056 }
1057 
1058