diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
commit | 267c6f2ac71f92999e969232431ba04678e7437e (patch) | |
tree | 358c9467650e1d0a1d7227a21dac2e3d08b622b2 /swext/mediawiki/src/com | |
parent | Initial commit. (diff) | |
download | libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip |
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'swext/mediawiki/src/com')
13 files changed, 4045 insertions, 0 deletions
diff --git a/swext/mediawiki/src/com/sun/star/wiki/EditPageParser.java b/swext/mediawiki/src/com/sun/star/wiki/EditPageParser.java new file mode 100644 index 0000000000..114709fae3 --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/EditPageParser.java @@ -0,0 +1,176 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wiki; + +import javax.swing.text.html.*; +import javax.swing.text.MutableAttributeSet; + +public class EditPageParser extends HTMLEditorKit.ParserCallback +{ + + protected String m_sEditTime = ""; + protected String m_sEditToken = ""; + protected String m_sLoginToken = ""; + protected String m_sMainURL = ""; + + private boolean m_bHTMLStartFound = false; + private boolean m_bInHead = false; + + protected int m_nWikiArticleStart = -1; + protected int m_nWikiArticleEnd = -1; + protected int m_nHTMLArticleStart = -1; + protected int m_nHTMLArticleEnd = -1; + protected int m_nNoArticleInd = -1; + protected int m_nErrorInd = -1; + + @Override + public void handleComment( char[] data,int pos ) + { + // insert code to handle comments + } + + @Override + public void handleEndTag( HTML.Tag t,int pos ) + { + if ( t == HTML.Tag.TEXTAREA ) + { + m_nWikiArticleEnd = pos; + } + else if ( t == HTML.Tag.DIV ) + { + if ( m_bHTMLStartFound ) + { + m_nHTMLArticleStart = pos+6; + m_bHTMLStartFound = false; + } + } + else if ( t == HTML.Tag.HEAD ) + { + m_bInHead = false; + } + } + + @Override + public void handleError( String errorMsg,int pos ) + { + } + + @Override + public void handleSimpleTag( HTML.Tag t, MutableAttributeSet a,int pos ) + { + // insert code to handle simple tags + + if ( t == HTML.Tag.INPUT ) + { + String sName = ( String ) a.getAttribute( HTML.Attribute.NAME ); + if ( sName != null ) + { + if ( sName.equalsIgnoreCase( "wpEdittime" ) ) + { + this.m_sEditTime = ( String ) a.getAttribute( HTML.Attribute.VALUE ); + } + else if ( sName.equalsIgnoreCase( "wpEditToken" ) ) + { + this.m_sEditToken = ( String ) a.getAttribute( HTML.Attribute.VALUE ); + } + else if ( sName.equalsIgnoreCase( "wpLoginToken" ) ) + { + this.m_sLoginToken = ( String ) a.getAttribute( HTML.Attribute.VALUE ); + } + } + + } + else if ( t == HTML.Tag.LINK ) + { + if ( m_bInHead ) + { + String sName = ( String ) a.getAttribute( HTML.Attribute.HREF ); + if ( sName != null ) + { + // get the main URL from the first header-link with load.php (which is used for stylesheet) + int nPhpFileStart = sName.indexOf( "load.php" ); + if (nPhpFileStart < 0) + // if not found, try header-link with opensearch_desc.php + nPhpFileStart = sName.indexOf( "opensearch_desc.php" ); + + if ( nPhpFileStart >= 0 + && m_sMainURL.length() == 0 ) + { + m_sMainURL = sName.substring( 0, nPhpFileStart ); + } + } + } + } + + } + + @Override + public void handleStartTag( HTML.Tag t, MutableAttributeSet a,int pos ) + { + // insert code to handle starting tags + String sClass; + + if ( t == HTML.Tag.HEAD ) + { + m_bInHead = true; + } + else if ( t == HTML.Tag.TEXTAREA ) + { + String sName = ( String ) a.getAttribute( HTML.Attribute.NAME ); + if ( sName != null && sName.equalsIgnoreCase( "wpTextbox1" ) ) + { + m_nWikiArticleStart = pos; + } + } + else if ( t == HTML.Tag.DIV ) + { + String sId = ( String ) a.getAttribute( HTML.Attribute.ID ); + sClass = ( String ) a.getAttribute( HTML.Attribute.CLASS ); + if ( sId != null && sId.equalsIgnoreCase( "contentSub" ) ) + { + m_bHTMLStartFound = true; + } + if ( sClass != null ) + { + if ( sClass.equalsIgnoreCase( "printfooter" ) ) + { + m_nHTMLArticleEnd = pos; + } + else if ( sClass.equalsIgnoreCase( "noarticletext" ) ) + { + m_nNoArticleInd = pos; + } + else if ( sClass.equalsIgnoreCase( "errorbox" ) ) + { + m_nErrorInd = pos; + } + } + } + else if ( t == HTML.Tag.P ) + { + sClass = ( String ) a.getAttribute( HTML.Attribute.CLASS ); + if ( sClass != null && sClass.equalsIgnoreCase( "error" ) ) + { + m_nErrorInd = pos; + } + } + } + + +} diff --git a/swext/mediawiki/src/com/sun/star/wiki/Helper.java b/swext/mediawiki/src/com/sun/star/wiki/Helper.java new file mode 100644 index 0000000000..e43091d2e2 --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/Helper.java @@ -0,0 +1,1079 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wiki; + +import com.sun.star.awt.MessageBoxButtons; +import com.sun.star.awt.MessageBoxType; +import com.sun.star.awt.XControl; +import com.sun.star.awt.XDialog; +import com.sun.star.awt.XMessageBox; +import com.sun.star.awt.XMessageBoxFactory; +import com.sun.star.awt.XWindowPeer; +import com.sun.star.beans.NamedValue; +import com.sun.star.beans.PropertyValue; +import com.sun.star.beans.XPropertySet; +import com.sun.star.container.XContainerQuery; +import com.sun.star.container.XEnumeration; +import com.sun.star.container.XNameAccess; +import com.sun.star.container.XNameContainer; +import com.sun.star.document.XDocumentPropertiesSupplier; +import com.sun.star.document.XDocumentProperties; +import com.sun.star.frame.XModel; +import com.sun.star.frame.XModuleManager; +import com.sun.star.io.XInputStream; +import com.sun.star.io.XOutputStream; +import com.sun.star.lang.IllegalArgumentException; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XComponent; +import com.sun.star.system.SystemShellExecuteFlags; +import com.sun.star.system.XSystemShellExecute; +import com.sun.star.task.UrlRecord; +import com.sun.star.task.XInteractionHandler; +import com.sun.star.task.XMasterPasswordHandling; +import com.sun.star.task.XPasswordContainer; +import com.sun.star.uno.AnyConverter; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import com.sun.star.util.XChangesBatch; +import java.net.*; +import java.io.*; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLException; +import javax.swing.text.html.HTMLEditorKit; + + +public class Helper +{ + public static final int GENERALSEND_ERROR = 0; + public static final int NOWIKIFILTER_ERROR = 1; + public static final int NOURLCONNECTION_ERROR = 2; + public static final int WRONGLOGIN_ERROR = 3; + public static final int INVALIDURL_ERROR = 4; + public static final int NOURL_ERROR = 5; + + public static final int DLG_SENDTITLE = 6; + public static final int DLG_WIKIARTICLE = 7; + + public static final int DLG_OK = 9; + + // 11 is reserved + public static final int DLG_ADDBUTTON = 12; + public static final int DLG_EDITBUTTON = 13; + public static final int DLG_SENDBUTTON = 14; + public static final int DLG_REMOVEBUTTON = 15; + + public static final int DLG_EDITSETTING_URLLABEL = 16; + public static final int DLG_EDITSETTING_USERNAMELABEL = 17; + public static final int DLG_EDITSETTING_PASSWORDLABEL = 18; + + public static final int DLG_SENDTOMEDIAWIKI_LABEL1 = 20; + public static final int DLG_SENDTOMEDIAWIKI_LABEL2 = 21; + public static final int DLG_SENDTOMEDIAWIKI_LABEL3 = 22; + public static final int DLG_SENDTOMEDIAWIKI_MINORCHECK = 23; + public static final int DLG_SENDTOMEDIAWIKI_BROWSERCHECK = 24; + public static final int UNKNOWNCERT_ERROR = 25; + public static final int DLG_MEDIAWIKI_TITLE = 26; + public static final int DLG_EDITSETTING_ACCOUNTLINE = 27; + public static final int DLG_EDITSETTING_WIKILINE = 28; + public static final int DLG_EDITSETTING_SAVEBOX = 29; + public static final int CANCELSENDING_ERROR = 30; + public static final int DLG_MEDIAWIKIEXTENSION_STRING = 31; + public static final int DLG_WIKIPAGEEXISTS_LABEL1 = 32; + + private static final int STRINGS_NUM = 33; + + private static final String[] m_pEntryNames = { "GeneralSendError", + "NoWikiFilter", + "NoConnectionToURL", + "WrongLogin", + "InvalidURL", + "NoURL", + "Dlg_SendTitle", + "Dlg_WikiArticle", + "Dlg_No", + "Dlg_OK", + "Dlg_Yes", + null, // reserved + "Dlg_AddButton", + "Dlg_EditButton", + "Dlg_SendButton", + "Dlg_RemoveButton", + "Dlg_EditSetting_UrlLabel", + "Dlg_EditSetting_UsernameLabel", + "Dlg_EditSetting_PasswordLabel", + "Dlg_NewWikiPage_Label1", + "Dlg_SendToMediaWiki_Label1", + "Dlg_SendToMediaWiki_Label2", + "Dlg_SendToMediaWiki_Label3", + "Dlg_SendToMediaWiki_MinorCheck", + "Dlg_SendToMediaWiki_BrowserCheck", + "UnknownCert", + "Dlg_MediaWiki_Title", + "Dlg_EditSetting_AccountLine", + "Dlg_EditSetting_WikiLine", + "Dlg_EditSetting_SaveBox", + "CancelSending", + "Dlg_MediaWiki_Extension_String", + "Dlg_WikiPageExists_Label1" }; + + private static String[] m_pConfigStrings; + + private static boolean m_bAllowConnection = true; + + private static Boolean m_bShowInBrowser = null; + + private static XPasswordContainer m_xPasswordContainer; + private static XInteractionHandler m_xInteractionHandler; + + synchronized protected static String GetLocalizedString( XComponentContext xContext, int nID ) + throws com.sun.star.uno.Exception + { + if ( nID >= STRINGS_NUM ) + throw new com.sun.star.uno.RuntimeException(); + + if ( m_pConfigStrings == null ) + { + XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Office.Custom.WikiExtension/Strings" ); + + String[] pStrings = new String[STRINGS_NUM]; + for ( int nInd = 0; nInd < STRINGS_NUM; nInd++ ) + if ( m_pEntryNames[nInd] != null ) + pStrings[nInd] = AnyConverter.toString( xNameAccess.getByName( m_pEntryNames[nInd] ) ); + else + pStrings[nInd] = ""; + + m_pConfigStrings = pStrings; + } + + return m_pConfigStrings[nID]; + } + + synchronized protected static void AllowConnection( boolean bAllow ) + { + m_bAllowConnection = bAllow; + // TODO: how to shut down any pending connections? + // hope it doesn't matter? + } + + synchronized protected static boolean IsConnectionAllowed() + { + return m_bAllowConnection; + } + + synchronized protected static boolean GetShowInBrowserByDefault( XComponentContext xContext ) + { + if ( m_bShowInBrowser == null ) + { + try + { + XNameAccess xAccess = Helper.GetConfigNameAccess( xContext, "org.openoffice.Office.Custom.WikiExtension/Settings" ); + m_bShowInBrowser = Boolean.valueOf( AnyConverter.toBoolean( xAccess.getByName( "PreselectShowBrowser" ) ) ); + } + catch( com.sun.star.uno.Exception e ) + { + e.printStackTrace(); + } + } + + return m_bShowInBrowser != null ? m_bShowInBrowser.booleanValue() : false; + } + + synchronized protected static void SetShowInBrowserByDefault( XComponentContext xContext, boolean bValue ) + { + try + { + m_bShowInBrowser = Boolean.valueOf( bValue ); + + XPropertySet xProps = Helper.GetConfigProps( xContext, "org.openoffice.Office.Custom.WikiExtension/Settings" ); + xProps.setPropertyValue( "PreselectShowBrowser", Boolean.valueOf( bValue ) ); + XChangesBatch xBatch = UnoRuntime.queryInterface( XChangesBatch.class, xProps ); + if ( xBatch != null ) + xBatch.commitChanges(); + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + + synchronized protected static XPasswordContainer GetPasswordContainer( XComponentContext xContext ) + throws com.sun.star.uno.Exception + { + if ( m_xPasswordContainer == null && xContext != null ) + { + XMultiComponentFactory xFactory = xContext.getServiceManager(); + if ( xFactory != null ) + m_xPasswordContainer = UnoRuntime.queryInterface( + XPasswordContainer.class, + xFactory.createInstanceWithContext( "com.sun.star.task.PasswordContainer", xContext ) ); + } + + if ( m_xPasswordContainer == null ) + throw new com.sun.star.uno.RuntimeException(); + + return m_xPasswordContainer; + } + + synchronized protected static XInteractionHandler GetInteractionHandler( XComponentContext xContext ) + throws com.sun.star.uno.Exception + { + if ( m_xInteractionHandler == null && xContext != null ) + { + XMultiComponentFactory xFactory = xContext.getServiceManager(); + if ( xFactory != null ) + m_xInteractionHandler = UnoRuntime.queryInterface( + XInteractionHandler.class, + xFactory.createInstanceWithContext( "com.sun.star.task.InteractionHandler", xContext ) ); + } + + if ( m_xInteractionHandler == null ) + throw new com.sun.star.uno.RuntimeException(); + + return m_xInteractionHandler; + } + + protected static String GetMainURL( String sWebPage, String sVURL ) + { + String sResultURL = ""; + try + { + StringReader aReader = new StringReader( sWebPage ); + HTMLEditorKit.Parser aParser = GetHTMLParser(); + EditPageParser aCallback = new EditPageParser(); + + aParser.parse( aReader, aCallback, true ); + sResultURL = aCallback.m_sMainURL; + + if ( !sResultURL.startsWith( "http" ) ) + { + //if the url is only relative then complete it + URL aURL = new URL( sVURL ); + sResultURL = aURL.getProtocol() + "://" + aURL.getHost() + sResultURL; + } + } + catch( Exception e ) + { + e.printStackTrace(); + } + + if ( sResultURL.length() == 0 ) + { + // usually that should not happen + // workaround: try to get index.php from the provided URL + int nIndex = sVURL.indexOf( "index.php" ); + if ( nIndex >= 0 ) + sResultURL = sVURL.substring( 0, nIndex ); + } + + return sResultURL; + } + + protected static String GetRedirectURL( String sWebPage, String sURL ) + { + //scrape the HTML source and find the EditURL + // TODO/LATER: Use parser in future + + int nInd = sWebPage.indexOf( "http-equiv=\"refresh\"" ); + if ( nInd == -1 ) + return ""; + + String sResultURL = ""; + int nContent = sWebPage.indexOf( "content=", nInd ); + if ( nContent > 0 ) + { + int nURL = sWebPage.indexOf( "URL=", nContent ); + if ( nURL > 0 ) + { + int nEndURL = sWebPage.indexOf('"', nURL ); + if ( nEndURL > 0 ) + sResultURL = sWebPage.substring( nURL + 4, nEndURL ); + } + } + + try + { + URL aURL = new URL( sURL ); + if ( !sResultURL.startsWith( aURL.getProtocol() )) + { + //if the url is only relative then complete it + if ( sResultURL.startsWith( "/" ) ) + sResultURL = aURL.getProtocol() + "://" + aURL.getHost() + sResultURL; + else + sResultURL = aURL.getProtocol() + "://" + aURL.getHost() + aURL.getPath() + sResultURL; + } + } + catch ( MalformedURLException ex ) + { + ex.printStackTrace(); + } + + return sResultURL; + + } + + protected static String CreateTempFile( XComponentContext xContext ) + { + String sURL = ""; + try + { + Object oTempFile = xContext.getServiceManager().createInstanceWithContext( "com.sun.star.io.TempFile", xContext ); + XPropertySet xPropertySet = UnoRuntime.queryInterface( XPropertySet.class, oTempFile ); + xPropertySet.setPropertyValue( "RemoveFile", Boolean.FALSE ); + sURL = ( String ) xPropertySet.getPropertyValue( "Uri" ); + + XInputStream xInputStream = UnoRuntime.queryInterface( XInputStream.class, oTempFile ); + xInputStream.closeInput(); + XOutputStream xOutputStream = UnoRuntime.queryInterface( XOutputStream.class, oTempFile ); + xOutputStream.closeOutput(); + } catch ( com.sun.star.uno.Exception ex ) + { + ex.printStackTrace(); + } + return sURL; + } + + private static void close(BufferedReader c) { + if (c == null) return; + try { + c.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + protected static String EachLine( String sURL ) + { + String sText = ""; + BufferedReader aBufReader = null; + try + { + URL aURL = new URL( sURL ); + File aFile = new File( aURL.getFile() ); + InputStreamReader aInputReader = new InputStreamReader( new FileInputStream( aFile ), "UTF-8" ); + aBufReader = new BufferedReader( aInputReader ); + + StringBuffer aBuf = new StringBuffer(); + String sEachLine = aBufReader.readLine(); + + while( sEachLine != null ) + { + aBuf.append( sEachLine ); + aBuf.append( "\n" ); + + sEachLine = aBufReader.readLine(); + } + sText = aBuf.toString(); + + aBufReader.close(); + } catch ( Exception e ) { + e.printStackTrace(); + } + finally { + close(aBufReader); + } + return sText; + } + + protected static String GetDocTitle( XModel xDoc ) + { + XDocumentPropertiesSupplier xDocPropSup = + UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xDoc); + XDocumentProperties xDocProps = xDocPropSup.getDocumentProperties(); + return xDocProps.getTitle(); + } + + protected static void SetDocTitle( XModel xDoc, String sTitle ) + { + XDocumentPropertiesSupplier xDocPropSup = + UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xDoc); + XDocumentProperties xDocProps = xDocPropSup.getDocumentProperties(); + xDocProps.setTitle(sTitle); + } + + protected static String GetDocServiceName( XComponentContext xContext, XModel xModel ) + { + String aDocServiceName = ""; + if ( xModel != null && xContext != null ) + { + try + { + XMultiComponentFactory xFactory = xContext.getServiceManager(); + if ( xFactory == null ) + throw new com.sun.star.uno.RuntimeException(); + + Object oModuleManager = xFactory.createInstanceWithContext( "com.sun.star.frame.ModuleManager", xContext ); + XModuleManager xModuleManager = UnoRuntime.queryInterface( XModuleManager.class, oModuleManager ); + if ( xModuleManager != null ) + aDocServiceName = xModuleManager.identify( xModel ); + } + catch( java.lang.Exception e ) + { + e.printStackTrace(); + } + } + + return aDocServiceName; + } + + protected static String GetFilterName( XComponentContext xContext, String aTypeName, String aDocServiceName ) + { + if ( xContext == null || aTypeName == null || aTypeName.length() == 0 + || aDocServiceName == null || aDocServiceName.length() == 0 ) { + return ""; + } + String aFilterName = ""; + try + { + Object oFilterFactory = xContext.getServiceManager().createInstanceWithContext( "com.sun.star.document.FilterFactory", xContext ); + XContainerQuery xQuery = UnoRuntime.queryInterface( XContainerQuery.class, oFilterFactory ); + if ( xQuery != null ) + { + NamedValue[] aRequest = new NamedValue[2]; + aRequest[0] = new NamedValue( "Type", aTypeName ); + aRequest[1] = new NamedValue( "DocumentService", aDocServiceName ); + + XEnumeration xSet = xQuery.createSubSetEnumerationByProperties( aRequest ); + if ( xSet != null ) + { + boolean bAcceptable = false; + while ( xSet.hasMoreElements() && !bAcceptable ) + { + PropertyValue[] pFilterProps = ( PropertyValue[] )AnyConverter.toArray( xSet.nextElement() ); + if ( pFilterProps != null ) + { + int nLen = pFilterProps.length; + String aTmpFilter = null; + + for ( int nInd = 0; nInd < nLen; nInd++ ) + { + if ( pFilterProps[nInd].Name.equals( "Name" ) ) + aTmpFilter = AnyConverter.toString( pFilterProps[nInd].Value ); + else if ( pFilterProps[nInd].Name.equals( "Flags" ) ) + bAcceptable = ( ( AnyConverter.toInt( pFilterProps[nInd].Value ) & 2 ) == 2 ); // must allow export + } + + if ( bAcceptable ) + aFilterName = aTmpFilter; + } + } + } + } + } + catch( java.lang.Exception e ) + { + e.printStackTrace(); + } + + return aFilterName; + } + + private static XMultiServiceFactory GetConfigurationProvider( XComponentContext xContext ) + throws com.sun.star.uno.Exception + { + XMultiServiceFactory xConfigurationProvider = null; + if ( xContext != null ) + { + XMultiComponentFactory xFactory = xContext.getServiceManager(); + Object oConfigProvider = xFactory.createInstanceWithContext( "com.sun.star.configuration.ConfigurationProvider", xContext ); + xConfigurationProvider = UnoRuntime.queryInterface( XMultiServiceFactory.class, oConfigProvider ); + } + + if ( xConfigurationProvider == null ) + throw new com.sun.star.uno.RuntimeException(); + + return xConfigurationProvider; + } + + private static Object GetConfig( XComponentContext xContext, String sNodepath, boolean bWriteAccess ) + throws com.sun.star.uno.Exception + { + if ( xContext == null || sNodepath == null ) + throw new com.sun.star.uno.RuntimeException(); + + PropertyValue aVal = new PropertyValue(); + aVal.Name = "nodepath"; + aVal.Value = sNodepath; + Object[] aArgs = new Object[1]; + aArgs[0] = aVal; + + return GetConfigurationProvider( xContext ).createInstanceWithArguments( + ( bWriteAccess ? "com.sun.star.configuration.ConfigurationUpdateAccess" + : "com.sun.star.configuration.ConfigurationAccess" ), + aArgs ); + } + + private static XPropertySet GetConfigProps( XComponentContext xContext, String sNodepath ) + throws com.sun.star.uno.Exception + { + XPropertySet xProps = UnoRuntime.queryInterface( XPropertySet.class, GetConfig( xContext, sNodepath, true ) ); + if ( xProps == null ) + throw new com.sun.star.uno.RuntimeException(); + + return xProps; + } + + + protected static XNameContainer GetConfigNameContainer( XComponentContext xContext, String sNodepath ) + throws com.sun.star.uno.Exception + { + XNameContainer xContainer = UnoRuntime.queryInterface( XNameContainer.class, GetConfig( xContext, sNodepath, true ) ); + if ( xContainer == null ) + throw new com.sun.star.uno.RuntimeException(); + + return xContainer; + } + + protected static XNameAccess GetConfigNameAccess( XComponentContext xContext, String sNodepath ) + throws com.sun.star.uno.Exception + { + XNameAccess xNameAccess = UnoRuntime.queryInterface( XNameAccess.class, GetConfig( xContext, sNodepath, false ) ); + if ( xNameAccess == null ) + throw new com.sun.star.uno.RuntimeException(); + + return xNameAccess; + } + + private static Proxy GetConfigurationProxy(URI uri, XComponentContext xContext) + { + assert(uri != null); + assert(xContext != null); + + try + { + XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Inet/Settings" ); + + int nProxyType = AnyConverter.toInt( xNameAccess.getByName( "ooInetProxyType" ) ); + if ( nProxyType == 0 ) { + return Proxy.NO_PROXY; + } else { + if ( nProxyType == 1 ) + { + // system proxy + return null; + } + else if ( nProxyType == 2 ) + { + String aProxyNameProp = "ooInetHTTPProxyName"; + String aProxyPortProp = "ooInetHTTPProxyPort"; + + if (uri.getScheme().equals("https")) + { + aProxyNameProp = "ooInetHTTPSProxyName"; + aProxyPortProp = "ooInetHTTPSProxyPort"; + } + + String aProxyName = AnyConverter.toString( xNameAccess.getByName( aProxyNameProp ) ); + + int nProxyPort = 80; + + Object aPortNo = xNameAccess.getByName( aProxyPortProp ); + if ( !AnyConverter.isVoid( aPortNo ) ) + nProxyPort = AnyConverter.toInt( aPortNo ); + + if ( nProxyPort == -1 ) + nProxyPort = 80; + + // TODO: check whether the URL is in the NoProxy list + InetSocketAddress address = new InetSocketAddress(aProxyName, nProxyPort); + return new Proxy(Proxy.Type.HTTP, address); + } + } + } + catch( java.lang.Exception e ) + { + e.printStackTrace(); + } + return null; // invalid configuration value? + } + + protected static void ShowURLInBrowser( XComponentContext xContext, String sURL ) + { + if ( xContext != null && sURL != null && sURL.length() > 0 ) + { + try + { + Object oSystemShell = xContext.getServiceManager().createInstanceWithContext( "com.sun.star.system.SystemShellExecute", xContext ); + XSystemShellExecute xSystemShell = UnoRuntime.queryInterface( XSystemShellExecute.class, oSystemShell ); + if ( xSystemShell != null ) + xSystemShell.execute( sURL, "", SystemShellExecuteFlags.URIS_ONLY ); + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + } + + protected static HttpURLConnection PrepareMethod(String method, URI uri, XComponentContext xContext) + throws WikiCancelException, IOException, SSLException + { + assert(method != null); + assert(uri != null); + assert(xContext != null); + + if (!IsConnectionAllowed()) { + throw new WikiCancelException(); + } + + if (java.net.CookieHandler.getDefault() == null) { + // set a cookie manager so cookies don't get lost + // apparently it's not possible to do that on a per-connection + // basis but only globally? + java.net.CookieHandler.setDefault(new java.net.CookieManager()); + } + + Proxy proxy = GetConfigurationProxy(uri, xContext); + HttpURLConnection conn = null; + if (proxy != null) { + conn = (HttpURLConnection) uri.toURL().openConnection(proxy); + } else { + conn = (HttpURLConnection) uri.toURL().openConnection(); + } + + boolean isAllowedInsecure; + try { + XNameAccess xNameAccess = GetConfigNameAccess(xContext, "org.openoffice.Office.Security/Net"); + isAllowedInsecure = AnyConverter.toBoolean(xNameAccess.getByName("AllowInsecureProtocols")); + } catch (Exception e) { + throw new RuntimeException("failed to read configuration", e); + } + if (!isAllowedInsecure) { + if (!uri.getScheme().equals("https")) { + throw new IllegalArgumentException("insecure connection not allowed by configuration", null, (short)0); + } + try { + SSLContext context = SSLContext.getInstance("TLSv1.2"); + context.init(null, null, null); // defaults + ((HttpsURLConnection) conn).setSSLSocketFactory(context.getSocketFactory()); + } catch (Exception e) { + throw new RuntimeException("failed to create SSLContext", e); + } + } + else if (uri.getScheme().equals("https") && AllowUnknownCert(xContext, uri.getHost())) + { + // let unknown certificates be accepted + ((HttpsURLConnection) conn).setSSLSocketFactory(new WikiProtocolSocketFactory()); + } + +// enable this to help debug connections where TLS gets in the way +// ((HttpsURLConnection) conn).setSSLSocketFactory(new LoggingProtocolSocketFactory()); + + conn.setRequestMethod(method); + // TODO: is it possible to read the version from the extension metadata? + conn.setRequestProperty("User-Agent", "LibreOffice Wiki Publisher 1.2.0"); + // note: don't connect yet so that the caller can do some further setup + + return conn; + } + + protected static String ReadResponseBody(HttpURLConnection conn) + throws IOException + { + String ret = null; + InputStream stream = conn.getInputStream(); + try { + // there doesn't seem to be an easier way get the content encoding + String type = conn.getContentType(); + String charset = "ISO-8859-1"; // default in RFC2616 + for (String param : type.split(";")) { + if (param.trim().toLowerCase().startsWith("charset=")) { + charset = param.trim().substring("charset=".length()); + break; + } + } + BufferedReader br = + new BufferedReader(new InputStreamReader(stream, charset)); + StringBuilder buf = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + buf.append(line); + } + ret = buf.toString(); + } finally { + stream.close(); + } + return ret; + } + + private static class HTMLParse extends HTMLEditorKit + { + + @Override + public HTMLEditorKit.Parser getParser() + { + return super.getParser(); + } + } + + protected static HTMLEditorKit.Parser GetHTMLParser() + { + return new HTMLParse().getParser(); + } + + private static boolean LoginReportsError( String sRespond ) + { + boolean bResult = true; + if ( sRespond != null ) + { + try + { + StringReader aReader = new StringReader( sRespond ); + HTMLEditorKit.Parser aParser = GetHTMLParser(); + EditPageParser aCallback = new EditPageParser(); + + aParser.parse( aReader, aCallback, true ); + bResult = ( aCallback.m_nErrorInd >= 0 ); + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + + return bResult; + } + + private static String GetLoginToken( String sLoginPage ) + { + String sResult = ""; + if ( sLoginPage != null && sLoginPage.length() > 0 ) + { + try + { + StringReader aReader = new StringReader( sLoginPage ); + HTMLEditorKit.Parser aParser = Helper.GetHTMLParser(); + EditPageParser aCallbacks = new EditPageParser(); + + aParser.parse( aReader, aCallbacks, true ); + sResult = aCallbacks.m_sLoginToken; + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + + return sResult; + } + + protected static boolean Login(URI aMainURL, String sWikiUser, String sWikiPass, XComponentContext xContext) + throws java.io.IOException, WikiCancelException, URISyntaxException + { + boolean success = false; + + if ( sWikiUser != null && sWikiPass != null && xContext != null ) + { + String sLoginPage = null; + URI aURI = new URI(aMainURL.toString() + "index.php?title=Special:Userlogin"); + HttpURLConnection connGet = PrepareMethod("GET", aURI, xContext); + connGet.setInstanceFollowRedirects(true); + + connGet.connect(); + int nResultCode = connGet.getResponseCode(); + if (nResultCode == 200) { + sLoginPage = ReadResponseBody(connGet); + } + + if ( sLoginPage != null ) + { + String sLoginToken = GetLoginToken( sLoginPage ); + + URI aPostURI = new URI(aMainURL.toString() + "index.php?title=Special:Userlogin&action=submitlogin"); + + HttpURLConnection connPost = PrepareMethod("POST", aPostURI, xContext); + connPost.setInstanceFollowRedirects(true); + connPost.setDoInput(true); + connPost.setDoOutput(true); + connPost.connect(); + + OutputStreamWriter post = new OutputStreamWriter(connPost.getOutputStream(), "UTF-8"); + try + { + post.write("wpName="); + post.write(URLEncoder.encode(sWikiUser, "UTF-8")); + post.write("&wpRemember=1"); + post.write("&wpPassword="); + post.write(URLEncoder.encode(sWikiPass, "UTF-8")); + + if (sLoginToken.length() > 0) { + post.write("&wpLoginToken="); + post.write(URLEncoder.encode(sLoginToken, "UTF-8")); + } + + String[][] pArgs = GetSpecialArgs( xContext, aMainURL.getHost() ); + if ( pArgs != null ) + for ( int nArgInd = 0; nArgInd < pArgs.length; nArgInd++ ) + if ( pArgs[nArgInd].length == 2 && pArgs[nArgInd][0] != null && pArgs[nArgInd][1] != null ) + { + post.write("&"); + post.write(URLEncoder.encode(pArgs[nArgInd][0], "UTF-8")); + post.write("="); + post.write(URLEncoder.encode(pArgs[nArgInd][0], "UTF-8")); + } + + post.flush(); + } + finally + { + post.close(); + } + + nResultCode = connPost.getResponseCode(); + + if ( nResultCode == 200 ) + { + String sResult = ReadResponseBody(connPost); + if ( !LoginReportsError( sResult ) ) + success = true; + } + } + } + + return success; + } + + protected static String[] GetPasswordsForURLAndUser( XComponentContext xContext, String sURL, String sUserName ) + { + String[] aResult = null; + + try + { + if ( xContext != null && sURL != null && sURL.length() > 0 && sUserName != null && sUserName.length() > 0 ) + { + UrlRecord aRec = GetPasswordContainer( xContext ).findForName( sURL, sUserName, GetInteractionHandler( xContext ) ); + if ( aRec != null && aRec.UserList != null && aRec.UserList.length > 0 + && aRec.UserList[0].UserName.equals( sUserName ) ) + aResult = aRec.UserList[0].Passwords; + } + } + catch( Exception e ) + { + e.printStackTrace(); + } + + return aResult; + } + + protected static boolean PasswordStoringIsAllowed( XComponentContext xContext ) + { + boolean bResult = false; + try + { + XMasterPasswordHandling xMasterHdl = UnoRuntime.queryInterface( XMasterPasswordHandling.class, GetPasswordContainer( xContext ) ); + if ( xMasterHdl != null ) + bResult = xMasterHdl.isPersistentStoringAllowed(); + } + catch( Exception e ) + { + e.printStackTrace(); + } + + return bResult; + } + + protected static void ShowError( XComponentContext xContext, XDialog xDialog, int nTitleID, int nErrorID, String sArg, boolean bQuery ) + { + XWindowPeer xPeer = null; + XControl xControl = UnoRuntime.queryInterface( XControl.class, xDialog ); + if ( xControl != null ) + xPeer = xControl.getPeer(); + ShowError( xContext, xPeer, nTitleID, nErrorID, sArg, bQuery ); + } + + protected static boolean ShowError( XComponentContext xContext, XWindowPeer xParentPeer, int nTitleID, int nErrorID, String sArg, boolean bQuery ) + { + boolean bResult = false; + + if ( xContext != null && nErrorID >= 0 && nErrorID < STRINGS_NUM ) + { + String sError = null; + String sTitle = ""; + + try + { + sError = GetLocalizedString( xContext, nErrorID ); + if ( sError != null && sArg != null ) + sError = sError.replaceAll( "\\$ARG1", sArg ); + + sTitle = GetLocalizedString( xContext, nTitleID ); + } + catch( Exception e ) + { + e.printStackTrace(); + } + + if ( sError == null ) + sError = "Error: " + nErrorID; + + if ( xParentPeer != null ) + { + XMessageBoxFactory xMBFactory = null; + XMessageBox xMB = null; + try + { + XMultiComponentFactory xFactory = xContext.getServiceManager(); + if ( xFactory != null ) + xMBFactory = UnoRuntime.queryInterface( + XMessageBoxFactory.class, + xFactory.createInstanceWithContext( "com.sun.star.awt.Toolkit", xContext ) ); + + if ( xMBFactory != null ) + { + if ( bQuery ) + { + xMB = xMBFactory.createMessageBox( + xParentPeer, + MessageBoxType.QUERYBOX, + MessageBoxButtons.BUTTONS_YES_NO | MessageBoxButtons.DEFAULT_BUTTON_NO, + sTitle, + sError ); + } + else + { + xMB = xMBFactory.createMessageBox( + xParentPeer, + MessageBoxType.ERRORBOX, + MessageBoxButtons.BUTTONS_OK, + sTitle, + sError ); + } + if ( xMB != null ) + { + bResult = MainThreadDialogExecutor.Execute( xContext, xMB ); + } + } + } + catch( Exception e ) + { + e.printStackTrace(); + } + finally + { + if ( xMB != null ) + Dispose( xMB ); + } + } + } + + return bResult; + } + + private static boolean AllowUnknownCert( XComponentContext xContext, String aURL ) + { + try + { + XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Office.Custom.WikiExtension/SpecialData" ); + if ( xNameAccess.hasByName( aURL ) ) + { + XNameAccess xEntry = UnoRuntime.queryInterface( XNameAccess.class, xNameAccess.getByName( aURL ) ); + if ( xEntry != null && xEntry.hasByName( "AllowUnknownCertificate" ) ) + return AnyConverter.toBoolean( xEntry.getByName( "AllowUnknownCertificate" ) ); + } + } + catch( Exception e ) + { + e.printStackTrace(); + } + + return false; + } + + private static String[][] GetSpecialArgs( XComponentContext xContext, String aURL ) + { + try + { + XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Office.Custom.WikiExtension/SpecialData" ); + if ( xNameAccess.hasByName( aURL ) ) + { + XNameAccess xEntry = UnoRuntime.queryInterface( XNameAccess.class, xNameAccess.getByName( aURL ) ); + if ( xEntry != null ) + { + XNameAccess xArgs = UnoRuntime.queryInterface( XNameAccess.class, xEntry.getByName( "AdditionalLoginArguments" ) ); + if ( xArgs != null ) + { + String[] pNames = xArgs.getElementNames(); + if ( pNames != null && pNames.length > 0 ) + { + String[][] pResult = new String[pNames.length][2]; + for ( int nInd = 0; nInd < pNames.length; nInd++ ) + { + XNameAccess xArgument = UnoRuntime.queryInterface( XNameAccess.class, xArgs.getByName( pNames[nInd] ) ); + if ( xArgument == null ) + throw new com.sun.star.uno.RuntimeException(); + + pResult[nInd][0] = pNames[nInd]; + pResult[nInd][1] = AnyConverter.toString( xArgument.getByName( "Value" ) ); + } + + return pResult; + } + } + } + } + } + catch( Exception e ) + { + e.printStackTrace(); + } + + return null; + } + + protected static boolean AllowThreadUsage( XComponentContext xContext ) + { + if ( xContext != null ) + { + try + { + XMultiComponentFactory xFactory = xContext.getServiceManager(); + if ( xFactory == null ) + throw new com.sun.star.uno.RuntimeException(); + + Object oCheckCallback = xFactory.createInstanceWithContext( "com.sun.star.awt.AsyncCallback", xContext ); + return ( oCheckCallback != null ); + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + + return false; + } + + public static void Dispose( Object oObject ) + { + if ( oObject != null ) + { + try + { + XComponent xComp = UnoRuntime.queryInterface( XComponent.class, oObject ); + if ( xComp != null ) + xComp.dispose(); + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + } +} + diff --git a/swext/mediawiki/src/com/sun/star/wiki/MANIFEST.MF b/swext/mediawiki/src/com/sun/star/wiki/MANIFEST.MF new file mode 100644 index 0000000000..6f900e21f5 --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/MANIFEST.MF @@ -0,0 +1 @@ +RegistrationClassName: com.sun.star.wiki.WikiEditorImpl diff --git a/swext/mediawiki/src/com/sun/star/wiki/MainThreadDialogExecutor.java b/swext/mediawiki/src/com/sun/star/wiki/MainThreadDialogExecutor.java new file mode 100644 index 0000000000..a6ee07fc85 --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/MainThreadDialogExecutor.java @@ -0,0 +1,158 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wiki; + +import com.sun.star.uno.Any; +import com.sun.star.awt.XDialog; +import com.sun.star.awt.XCallback; +import com.sun.star.awt.XMessageBox; +import com.sun.star.awt.XRequestCallback; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; + +public class MainThreadDialogExecutor implements XCallback +{ + private WikiDialog m_aWikiDialog; + private XDialog m_xDialog; + private XMessageBox m_xMessageBox; + private boolean m_bResult = false; + private boolean m_bCalled = false; + private boolean m_bClose = false; + + public static boolean Show( XComponentContext xContext, WikiDialog aWikiDialog ) + { + MainThreadDialogExecutor aExecutor = new MainThreadDialogExecutor( aWikiDialog ); + return GetCallback( xContext, aExecutor ); + } + + + + public static boolean Execute( XComponentContext xContext, XMessageBox xMessageBox ) + { + MainThreadDialogExecutor aExecutor = new MainThreadDialogExecutor( xMessageBox ); + return GetCallback( xContext, aExecutor ); + } + + public static boolean Close( XComponentContext xContext, XDialog xDialog ) + { + MainThreadDialogExecutor aExecutor = new MainThreadDialogExecutor( xDialog ); + aExecutor.m_bClose = true; + aExecutor.m_bCalled = true; // no yielding, asynchronous closing + return GetCallback( xContext, aExecutor ); + } + + private static boolean GetCallback( XComponentContext xContext, MainThreadDialogExecutor aExecutor ) + { + if (aExecutor == null) + return false; + + try + { + String aThreadName = null; + Thread aCurThread = Thread.currentThread(); + if ( aCurThread != null ) + aThreadName = aCurThread.getName(); + + if ( aThreadName != null && aThreadName.equals( "com.sun.star.thread.WikiEditorSendingThread" ) ) + { + // the main thread should be accessed asynchronously + XMultiComponentFactory xFactory = xContext.getServiceManager(); + if ( xFactory == null ) + throw new com.sun.star.uno.RuntimeException(); + + XRequestCallback xRequest = UnoRuntime.queryInterface( + XRequestCallback.class, + xFactory.createInstanceWithContext( "com.sun.star.awt.AsyncCallback", xContext ) ); + if ( xRequest != null ) + { + xRequest.addCallback( aExecutor, Any.VOID ); + do + { + Thread.yield(); + } + while( !aExecutor.m_bCalled ); + } + } + else + { + // handle it as a main thread + aExecutor.notify( Any.VOID ); + } + } + catch( Exception e ) + { + e.printStackTrace(); + } + + return aExecutor.GetResult(); + } + + private MainThreadDialogExecutor( WikiDialog aWikiDialog ) + { + m_aWikiDialog = aWikiDialog; + } + + private MainThreadDialogExecutor( XDialog xDialog ) + { + m_xDialog = xDialog; + } + + private MainThreadDialogExecutor( XMessageBox xMessageBox ) + { + m_xMessageBox = xMessageBox; + } + + private boolean GetResult() + { + return m_bResult; + } + + public void notify( Object aData ) + { + if ( m_aWikiDialog != null ) + m_bResult = m_aWikiDialog.show(); + else if ( m_xDialog != null ) + { + if ( !m_bClose ) + m_bResult = ( m_xDialog.execute() == 1 ); + else + { + try + { + m_xDialog.endExecute(); + } + catch( Exception e ) + { + e.printStackTrace(); + } + m_bResult = true; + } + } + else if ( m_xMessageBox != null ) + { + int nRes = m_xMessageBox.execute(); + m_bResult = ( nRes == com.sun.star.awt.MessageBoxResults.OK + || nRes == com.sun.star.awt.MessageBoxResults.YES ); + } + + m_bCalled = true; + } +} + diff --git a/swext/mediawiki/src/com/sun/star/wiki/Settings.java b/swext/mediawiki/src/com/sun/star/wiki/Settings.java new file mode 100644 index 0000000000..34e11e13e8 --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/Settings.java @@ -0,0 +1,310 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wiki; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.sun.star.beans.XPropertySet; +import com.sun.star.container.XNameAccess; +import com.sun.star.container.XNameContainer; +import com.sun.star.container.XNameReplace; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.uno.AnyConverter; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import com.sun.star.util.XChangesBatch; + +public class Settings +{ + + /* Singleton */ + private static Settings m_instance; + + + private final XComponentContext m_xContext; + private final List<Map<String, String>> m_WikiConnections = new ArrayList<Map<String, String>>(); + private final List<Map<String, Object>> m_aWikiDocs = new ArrayList<Map<String, Object>>(); + + private Settings( XComponentContext ctx ) + { + m_xContext=ctx; + loadConfiguration(); + } + + + public static synchronized Settings getSettings( XComponentContext ctx ) + { + if ( m_instance == null ) + m_instance = new Settings( ctx ); + return m_instance; + } + + + public void addWikiCon ( Map<String, String> wikiCon ) + { + m_WikiConnections.add( wikiCon ); + } + + + private String getWikiConUrlByNumber( int num ) + { + String url = ""; + if ( num >=0 && num < m_WikiConnections.size() ) + { + Map<String,String> ht = m_WikiConnections.get( num ); + url = ht.get( "Url" ); + } + return url; + } + + + public void addWikiDoc ( Map<String, Object> aWikiDoc ) + { + String sURL = ( String ) aWikiDoc.get( "CompleteUrl" ); + Map<String,Object> aEntry = getDocByCompleteUrl( sURL ); + + if ( aEntry != null ) + { + // add doc to the end, even if it has been added before + m_aWikiDocs.remove( aEntry ); + } + else if ( m_aWikiDocs.size() > 10 ) + { + // if the number of elements has reached maximum the oldest element should be removed + m_aWikiDocs.remove( 0 ); + } + + m_aWikiDocs.add( aWikiDoc ); + } + + + public Object[] getWikiDocList( int serverid ) + { + String wikiserverurl = getWikiConUrlByNumber( serverid ); + List<String> theDocs = new ArrayList<String>(); + String [] docs = new String[0]; + for ( int i=0; i<m_aWikiDocs.size(); i++ ) + { + Map<String,Object> ht = m_aWikiDocs.get( i ); + String docurl = ( String ) ht.get( "Url" ); + if ( docurl.equals( wikiserverurl ) ) + { + theDocs.add( (String ) ht.get( "Doc" ) ); + } + } + return theDocs.toArray( docs ); + } + + public String[] getWikiURLs() + { + String [] WikiList = new String [m_WikiConnections.size()]; + for ( int i=0; i<m_WikiConnections.size(); i++ ) + { + Map<String,String> ht = m_WikiConnections.get( i ); + WikiList[i] = ht.get( "Url" ); + } + return WikiList; + } + + + public Map<String, String> getSettingByUrl( String sUrl ) + { + Map<String, String> ht = null; + for( int i=0;i<m_WikiConnections.size();i++ ) + { + Map<String, String> h1 = m_WikiConnections.get( i ); + String u1 = h1.get( "Url" ); + if ( u1.equals( sUrl ) ) + { + ht = h1; + try + { + String sUserName = ht.get( "Username" ); + String aPassword = ht.get( "Password" ); + if ( sUserName != null && sUserName.length() > 0 && ( aPassword == null || aPassword.length() == 0 ) ) + { + String[] pPasswords = Helper.GetPasswordsForURLAndUser( m_xContext, sUrl, sUserName ); + if ( pPasswords != null && pPasswords.length > 0 ) + ht.put( "Password", pPasswords[0] ); + } + } + catch( Exception e ) + { + e.printStackTrace(); + } + + break; + } + } + return ht; + } + + private Map<String,Object> getDocByCompleteUrl( String curl ) + { + Map<String,Object> ht = null; + for( int i=0;i<m_aWikiDocs.size();i++ ) + { + Map<String,Object> h1 = m_aWikiDocs.get( i ); + String u1 = ( String ) h1.get( "CompleteUrl" ); + if ( u1.equals( curl ) ) + { + ht = h1; + } + } + return ht; + } + + + public void removeSettingByUrl( String sUrl ) + { + for( int i=0;i<m_WikiConnections.size();i++ ) + { + Map<String,String> h1 = m_WikiConnections.get( i ); + String u1 = h1.get( "Url" ); + if ( u1.equals( sUrl ) ) + { + m_WikiConnections.remove( i ); + } + } + } + + + public void storeConfiguration() + { + try + { + { + // remove stored connection information + XNameContainer xContainer = Helper.GetConfigNameContainer(m_xContext, "org.openoffice.Office.Custom.WikiExtension/ConnectionList"); + String[] pNames = xContainer.getElementNames(); + for (String pName : pNames) + { + xContainer.removeByName(pName); + } + // store all connections + XSingleServiceFactory xConnectionFactory = UnoRuntime.queryInterface(XSingleServiceFactory.class, xContainer); + for (Map<String, String> ht : m_WikiConnections) + { + Object oNewConnection = xConnectionFactory.createInstance(); + XNameReplace xNewConn = UnoRuntime.queryInterface(XNameReplace.class, oNewConnection); + if (xNewConn != null) + { + xNewConn.replaceByName("UserName", ht.get("Username")); + } + xContainer.insertByName(ht.get("Url"), xNewConn); + } + // commit changes + XChangesBatch xBatch = UnoRuntime.queryInterface(XChangesBatch.class, xContainer); + xBatch.commitChanges(); + } + + { + // remove stored connection information + XNameContainer xContainer = Helper.GetConfigNameContainer(m_xContext, "org.openoffice.Office.Custom.WikiExtension/RecentDocs"); + String[] pNames = xContainer.getElementNames(); + for (String pName : pNames) + { + xContainer.removeByName(pName); + } + // store all Docs + XSingleServiceFactory xDocListFactory = UnoRuntime.queryInterface(XSingleServiceFactory.class, xContainer); + int i = 0; + for (Map<String, Object> ht : m_aWikiDocs) + { + Object oNewDoc = xDocListFactory.createInstance(); + XNameReplace xNewDoc = UnoRuntime.queryInterface(XNameReplace.class, oNewDoc); + for (Map.Entry<String, Object> entry : ht.entrySet()) + { + xNewDoc.replaceByName(entry.getKey(), entry.getValue()); + } + xContainer.insertByName("d" + i++, xNewDoc); + } + // commit changes + XChangesBatch xBatch = UnoRuntime.queryInterface(XChangesBatch.class, xContainer); + xBatch.commitChanges(); + } + + } + catch ( Exception ex ) + { + ex.printStackTrace(); + } + } + + public void loadConfiguration() + { + m_WikiConnections.clear(); + try + { + // get configuration service + // connect to configmanager + XNameAccess xAccess = Helper.GetConfigNameAccess( m_xContext, "org.openoffice.Office.Custom.WikiExtension" ); + + if ( xAccess != null ) + { + Object oList = xAccess.getByName( "ConnectionList" ); + XNameAccess xConnectionList = UnoRuntime.queryInterface( XNameAccess.class, oList ); + String [] allCons = xConnectionList.getElementNames(); + for (String aConnection : allCons) + { + Map<String, String> ht = new HashMap<String, String>(); + ht.put("Url", aConnection); + ht.put( "Username", "" ); + ht.put( "Password", "" ); + try + { + XPropertySet xProps = UnoRuntime.queryInterface(XPropertySet.class, xConnectionList.getByName(aConnection)); + if ( xProps != null ) + { + String aUsername = AnyConverter.toString( xProps.getPropertyValue( "UserName" ) ); + if ( aUsername != null && aUsername.length() > 0 ) + ht.put( "Username", aUsername ); + } + } + catch( Exception e ) + { + e.printStackTrace(); + } + addWikiCon( ht ); + } + + Object oDocs = xAccess.getByName( "RecentDocs" ); + XNameAccess xRecentDocs = UnoRuntime.queryInterface( XNameAccess.class, oDocs ); + String [] allDocs = xRecentDocs.getElementNames(); + for (String aDocument : allDocs) + { + Object oDoc = xRecentDocs.getByName(aDocument); + XNameAccess xDoc = UnoRuntime.queryInterface( XNameAccess.class, oDoc ); + Map<String, Object> ht = new HashMap<String, Object>(); + ht.put( "Url", xDoc.getByName( "Url" ) ); + ht.put( "CompleteUrl", xDoc.getByName( "CompleteUrl" ) ); + ht.put( "Doc", xDoc.getByName( "Doc" ) ); + addWikiDoc( ht ); + } + } + } + catch ( Exception ex ) + { + ex.printStackTrace(); + } + } +} diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiArticle.java b/swext/mediawiki/src/com/sun/star/wiki/WikiArticle.java new file mode 100644 index 0000000000..5c22afa2a6 --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiArticle.java @@ -0,0 +1,261 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wiki; + +import java.io.StringReader; +import java.io.OutputStreamWriter; +import java.util.Map; +import java.net.URLEncoder; +import java.net.URI; +import java.net.HttpURLConnection; + +import javax.swing.text.html.HTMLEditorKit; + +import com.sun.star.uno.XComponentContext; + + +public class WikiArticle +{ + private final XComponentContext m_xContext; + + private String m_sEditTime = ""; + private String m_sEditToken = ""; + + private String m_sHTMLCode; + private boolean m_bNoArticle = true; + + private String m_sWikiUser; + private String m_sWikiPass; + + private final String m_sTitle; + + private final URI m_aMainURI; + private boolean m_isLoggedIn = false; + + /** Creates a new instance of WikiArticle */ + public WikiArticle( XComponentContext xContext, String sTitle, Map<String,String> wikiSettings, boolean bLogin, WikiPropDialog aPropDialog ) + throws java.net.URISyntaxException, java.io.IOException, WikiCancelException + { + m_xContext = xContext; + + String sMainUrl = wikiSettings.get("Url"); + m_sWikiUser = wikiSettings.get("Username"); + m_sWikiPass = wikiSettings.get("Password"); + m_sTitle = sTitle; + + m_aMainURI = new URI(sMainUrl); + + if ( bLogin ) + { + WikiEditSettingDialog aDialog = new WikiEditSettingDialog(m_xContext, "vnd.sun.star.script:WikiEditor.EditSetting?location=application", wikiSettings, false ); + try + { + while( !Login() ) + { + if ( aPropDialog != null ) + aPropDialog.SetThrobberActive( false ); + + if ( MainThreadDialogExecutor.Show( xContext, aDialog ) ) + { + m_sWikiUser = wikiSettings.get("Username"); + m_sWikiPass = wikiSettings.get("Password"); + } + else + throw new WikiCancelException(); + + if ( aPropDialog != null ) + { + aPropDialog.SetThrobberActive( true ); + Thread.yield(); + } + } + } + finally + { + aDialog.DisposeDialog(); + } + } + + // in case of loading the html contents are used + // in case of saving the contents should be checked whether they are empty + InitArticleHTML(); + } + + public String GetMainURL() + { + return m_aMainURI.toString(); + } + + public String GetTitle() + { + return m_sTitle; + } + + + + private String getArticleWiki() + throws java.net.URISyntaxException, java.io.IOException, WikiCancelException + { + String sWikiCode = null; + + if (m_isLoggedIn) + { + URI aURI = new URI(m_aMainURI.toString() + "index.php?title=" + m_sTitle + "&action=edit"); + HttpURLConnection connGet = Helper.PrepareMethod("GET", aURI, m_xContext); + connGet.connect(); + + int nResultCode = connGet.getResponseCode(); + String sWebPage = null; + if (nResultCode == 200) { + sWebPage = Helper.ReadResponseBody(connGet); + } + + if ( sWebPage != null ) + { + StringReader r = new StringReader(sWebPage); + HTMLEditorKit.Parser parse = Helper.GetHTMLParser(); + EditPageParser callback = new EditPageParser(); + + parse.parse(r,callback,true); + m_sEditTime = callback.m_sEditTime; + m_sEditToken = callback.m_sEditToken; + + int iPosStart = callback.m_nWikiArticleStart; + int iPosEnd = callback.m_nWikiArticleEnd; + + if ( iPosStart >= 0 && iPosEnd > 0 ) + { + String sArticle = sWebPage.substring(iPosStart, iPosEnd); + iPosStart = sArticle.indexOf('>') + 1; + sWikiCode = sArticle.substring( iPosStart, sArticle.length() ); + } + } + } + + return sWikiCode; + } + + private void InitArticleHTML() + throws java.net.URISyntaxException, java.io.IOException, WikiCancelException + { + if (m_isLoggedIn) + { + URI uri = new URI(m_aMainURI.toString() + "index.php?title=" + m_sTitle); + HttpURLConnection connGet = Helper.PrepareMethod("GET", uri, m_xContext); + connGet.connect(); + + int nResultCode = connGet.getResponseCode(); + String sWebPage = null; + if (nResultCode == 200) { + sWebPage = Helper.ReadResponseBody(connGet); + } + + if ( sWebPage != null ) + { + StringReader r = new StringReader(sWebPage); + HTMLEditorKit.Parser parse = Helper.GetHTMLParser(); + EditPageParser callback = new EditPageParser(); + + parse.parse(r,callback,true); + + int iPosStart = callback.m_nHTMLArticleStart; + int iPosEnd = callback.m_nHTMLArticleEnd; + int nPosNoArt = callback.m_nNoArticleInd; + + if ( iPosStart >= 0 && iPosEnd > 0 ) + { + m_sHTMLCode = sWebPage.substring(iPosStart, iPosEnd); + m_bNoArticle = ( nPosNoArt >= 0 && nPosNoArt >= iPosStart && nPosNoArt <= iPosEnd ); + } + } + } + } + + protected boolean setArticle( String sWikiCode, String sWikiComment, boolean bMinorEdit ) + throws java.net.URISyntaxException, java.io.IOException, WikiCancelException + { + boolean bResult = false; + + if (m_isLoggedIn && sWikiCode != null && sWikiComment != null) + { + // get the edit time and token + getArticleWiki(); + + URI uri = new URI(m_aMainURI.toString() + "index.php?title=" + m_sTitle + "&action=submit"); + + HttpURLConnection connPost = Helper.PrepareMethod("POST", uri, m_xContext); + connPost.setDoInput(true); + connPost.setDoOutput(true); + connPost.connect(); + + OutputStreamWriter post = new OutputStreamWriter(connPost.getOutputStream(), "UTF-8"); + try + { + post.write("wpTextbox1="); + post.write(URLEncoder.encode(sWikiCode, "UTF-8")); + post.write("&wpSummary="); + post.write(URLEncoder.encode(sWikiComment, "UTF-8")); + post.write("&wpSection="); + post.write("&wpEdittime="); + post.write(URLEncoder.encode(m_sEditTime, "UTF-8")); + post.write("&wpSave=Save%20page"); + post.write("&wpEditToken="); + post.write(URLEncoder.encode(m_sEditToken, "UTF-8")); + + if (bMinorEdit) { + post.write("&wpMinoredit=1"); + } + + post.flush(); + } + finally + { + post.close(); + } + + int nResultCode = connPost.getResponseCode(); + if ( nResultCode < 400 ) + bResult = true; + + String aResult = Helper.ReadResponseBody(connPost); + + // TODO: remove the debug printing, try to detect the error + System.out.print( "nSubmitCode = " + nResultCode + "\n===\n" + aResult ); + } + + return bResult; + } + + private boolean Login() + throws java.net.URISyntaxException, java.io.IOException, WikiCancelException + { + m_isLoggedIn = Helper.Login( m_aMainURI, m_sWikiUser, m_sWikiPass, m_xContext ); + return m_isLoggedIn; + } + + protected boolean NotExist() + { + boolean bResult = true; + if ( m_sHTMLCode != null ) + bResult = m_bNoArticle; + + return bResult; + } + +} diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiCancelException.java b/swext/mediawiki/src/com/sun/star/wiki/WikiCancelException.java new file mode 100644 index 0000000000..0a6c81ebe4 --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiCancelException.java @@ -0,0 +1,24 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wiki; + +class WikiCancelException extends java.lang.Exception +{ +} + diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiDialog.java b/swext/mediawiki/src/com/sun/star/wiki/WikiDialog.java new file mode 100644 index 0000000000..66bef678e4 --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiDialog.java @@ -0,0 +1,283 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wiki; + +import com.sun.star.awt.XControl; +import com.sun.star.awt.XControlContainer; +import com.sun.star.awt.XControlModel; +import com.sun.star.awt.XDialog; +import com.sun.star.awt.XDialogEventHandler; +import com.sun.star.awt.XDialogProvider2; +import com.sun.star.awt.XAnimation; +import com.sun.star.beans.XPropertySet; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import com.sun.star.awt.XTopWindow; +import com.sun.star.awt.XTopWindowListener; +import com.sun.star.awt.XWindow; +import com.sun.star.container.XNameContainer; +import com.sun.star.lang.EventObject; +import com.sun.star.lang.XMultiServiceFactory; + +public class WikiDialog implements XDialogEventHandler, XTopWindowListener +{ + protected XComponentContext m_xContext; + private XControlContainer m_xControlContainer; + protected XDialog m_xDialog; + private String[] m_aMethods; + protected boolean m_bAction = false; + protected Settings m_aSettings; + protected Thread m_aThread; + protected boolean m_bThreadFinished = false; + + + /** Creates a new instance of WikiDialog */ + public WikiDialog(XComponentContext c, String DialogURL) + { + this.m_xContext = c; + XMultiComponentFactory xMCF = m_xContext.getServiceManager(); + m_aSettings = Settings.getSettings(m_xContext); + try + { + Object obj; + obj = xMCF.createInstanceWithContext("com.sun.star.awt.DialogProvider2", m_xContext ); + XDialogProvider2 xDialogProvider = UnoRuntime.queryInterface( XDialogProvider2.class, obj ); + + m_xDialog = xDialogProvider.createDialogWithHandler( DialogURL, this ); + m_xControlContainer = UnoRuntime.queryInterface( XControlContainer.class, m_xDialog ); + XTopWindow xTopWindow = UnoRuntime.queryInterface( XTopWindow.class, m_xDialog ); + if ( xTopWindow != null ) + xTopWindow.addTopWindowListener( this ); + } + catch (com.sun.star.uno.Exception ex) + { + ex.printStackTrace(); + } + } + + public synchronized void ThreadStop( boolean bSelf ) + { + if ( bSelf || m_aThread != null && !m_bThreadFinished ) + { + try + { + Helper.AllowConnection( bSelf ); + } + catch( Exception ex ) + { + ex.printStackTrace(); + } + } + + m_aThread = null; + m_bThreadFinished = true; + } + + protected void setMethods (String [] Methods) + { + this.m_aMethods = Methods; + } + + + public boolean show( ) + { + m_bThreadFinished = false; + + if( m_xDialog != null ) m_xDialog.execute(); + return m_bAction; + } + + + public String[] getSupportedMethodNames() + { + return m_aMethods; + } + + + public boolean callHandlerMethod( XDialog xDialog, Object EventObject, String MethodName ) + { + return true; + } + + public void SetTitle( String sTitle ) + throws Exception + { + SetTitle( m_xDialog, sTitle ); + } + + private static void SetTitle( XDialog xDialog, String sTitle ) + throws Exception + { + if ( xDialog == null || sTitle == null ) { + return; + } + XControl xDialogControl = UnoRuntime.queryInterface( XControl.class, xDialog ); + if ( xDialogControl != null ) + { + XPropertySet xPropSet = UnoRuntime.queryInterface( XPropertySet.class, xDialogControl.getModel() ); + if ( xPropSet != null ) + xPropSet.setPropertyValue( "Title", sTitle ); + } + } + + protected XPropertySet GetPropSet(String sControl) + { + return GetPropSet( m_xControlContainer, sControl ); + } + + private static XPropertySet GetPropSet( XControlContainer xControlContainer, String sControl ) + { + XPropertySet xPS = null; + + if ( xControlContainer != null && sControl != null ) + { + XControl xControl = xControlContainer.getControl(sControl); + xPS = UnoRuntime.queryInterface(XPropertySet.class, xControl.getModel() ); + } + + if ( xPS == null ) + throw new com.sun.star.uno.RuntimeException(); + + return xPS; + } + + + + protected void InsertThrobber( int X, int Y, int Width, int Height ) + { + try + { + XControl xDialogControl = UnoRuntime.queryInterface( XControl.class, m_xDialog ); + XControlModel xDialogModel = null; + if ( xDialogControl != null ) + xDialogModel = xDialogControl.getModel(); + + XMultiServiceFactory xDialogFactory = UnoRuntime.queryInterface( XMultiServiceFactory.class, xDialogModel ); + if ( xDialogFactory != null ) + { + XControlModel xThrobberModel = UnoRuntime.queryInterface( XControlModel.class, xDialogFactory.createInstance( "com.sun.star.awt.SpinningProgressControlModel" ) ); + XPropertySet xThrobberProps = UnoRuntime.queryInterface( XPropertySet.class, xThrobberModel ); + if ( xThrobberProps != null ) + { + xThrobberProps.setPropertyValue( "Name", "WikiThrobber" ); + xThrobberProps.setPropertyValue( "PositionX", Integer.valueOf( X ) ); + xThrobberProps.setPropertyValue( "PositionY", Integer.valueOf( Y ) ); + xThrobberProps.setPropertyValue( "Width", Integer.valueOf( Width ) ); + xThrobberProps.setPropertyValue( "Height", Integer.valueOf( Height ) ); + + XNameContainer xDialogContainer = UnoRuntime.queryInterface( XNameContainer.class, xDialogModel ); + xDialogContainer.insertByName( "WikiThrobber", xThrobberModel ); + } + } + } + catch( Exception e ) + { + e.printStackTrace(); + } + + SetThrobberVisible( false ); + } + + public void SetThrobberActive( boolean bActive ) + { + if ( m_xControlContainer != null ) + { + try + { + XAnimation xThrobber = UnoRuntime.queryInterface( XAnimation.class, m_xControlContainer.getControl( "WikiThrobber" ) ); + if ( xThrobber != null ) + { + if ( bActive ) + xThrobber.startAnimation(); + else + xThrobber.stopAnimation(); + } + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + } + + public void SetThrobberVisible( boolean bVisible ) + { + if ( m_xControlContainer != null ) + { + try + { + XWindow xWindow = UnoRuntime.queryInterface( XWindow.class, m_xControlContainer.getControl( "WikiThrobber" ) ); + if ( xWindow != null ) + xWindow.setVisible( bVisible ); + } + catch ( Exception e ) + { + e.printStackTrace(); + } + } + } + + public void SetFocusTo( String aControl ) + { + if ( m_xControlContainer != null ) + { + try + { + XWindow xWindow = UnoRuntime.queryInterface( XWindow.class, m_xControlContainer.getControl( aControl ) ); + if ( xWindow != null ) + xWindow.setFocus(); + } + catch ( Exception e ) + { + e.printStackTrace(); + } + } + } + + public void DisposeDialog() + { + Helper.Dispose( m_xDialog ); + } + + public void windowOpened( EventObject e ) + {} + + public void windowClosing( EventObject e ) + {} + + public void windowClosed( EventObject e ) + {} + + public void windowMinimized( EventObject e ) + {} + + public void windowNormalized( EventObject e ) + {} + + public void windowActivated( EventObject e ) + {} + + public void windowDeactivated( EventObject e ) + {} + + public void disposing( EventObject e ) + {} +} + diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiEditSettingDialog.java b/swext/mediawiki/src/com/sun/star/wiki/WikiEditSettingDialog.java new file mode 100644 index 0000000000..e1f1aac35d --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiEditSettingDialog.java @@ -0,0 +1,416 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wiki; + +import java.util.HashMap; +import java.util.Map; + +import java.net.URI; +import java.net.HttpURLConnection; +import javax.net.ssl.SSLException; + +import com.sun.star.awt.XDialog; +import com.sun.star.beans.XPropertySet; +import com.sun.star.lang.EventObject; +import com.sun.star.uno.XComponentContext; + +public class WikiEditSettingDialog extends WikiDialog +{ + + private static final String sOKMethod = "OK"; + + private final String[] Methods = {sOKMethod }; + private final Map<String,String> setting; + private final boolean addMode; + private boolean m_bAllowURLChange = true; + + public WikiEditSettingDialog( XComponentContext xContext, String DialogURL ) + { + super( xContext, DialogURL ); + super.setMethods( Methods ); + setting = new HashMap<String,String>(); + addMode = true; + + InsertThrobber( 184, 20, 10, 10 ); + InitStrings( xContext ); + InitSaveCheckbox( xContext, false ); + } + + public WikiEditSettingDialog( XComponentContext xContext, String DialogURL, Map<String,String> ht, boolean bAllowURLChange ) + { + super( xContext, DialogURL ); + super.setMethods( Methods ); + setting = ht; + + boolean bInitSaveCheckBox = false; + + try + { + XPropertySet xUrlField = GetPropSet( "UrlField" ); + + xUrlField.setPropertyValue( "Text", ht.get( "Url" ) ); + + GetPropSet( "UsernameField" ).setPropertyValue( "Text", ht.get( "Username" ) ); + + if ( Helper.PasswordStoringIsAllowed( m_xContext ) ) + { + String[] pPasswords = Helper.GetPasswordsForURLAndUser( m_xContext, ht.get( "Url" ), ht.get( "Username" ) ); + bInitSaveCheckBox = ( pPasswords != null && pPasswords.length > 0 && pPasswords[0].equals( ht.get( "Password" ) ) ); + } + + // the password should be entered by the user or the Cancel should be pressed + // GetPropSet( "PasswordField" ).setPropertyValue( "Text", ht.get( "Password" )); + } + catch ( Exception ex ) + { + ex.printStackTrace(); + } + + addMode = false; + m_bAllowURLChange = bAllowURLChange; + + InsertThrobber( 184, 20, 10, 10 ); + InitStrings( xContext ); + InitSaveCheckbox( xContext, bInitSaveCheckBox ); + } + + @Override + public boolean show( ) + { + SetThrobberVisible( false ); + EnableControls( true ); + boolean bResult = super.show(); + + try + { + if ( bResult && Helper.PasswordStoringIsAllowed( m_xContext ) + && ( (Short)( GetPropSet( "SaveBox" ).getPropertyValue("State") ) ).shortValue() != (short)0 ) + { + String sURL = setting.get( "Url" ); + String sUserName = setting.get( "Username" ); + String sPassword = setting.get( "Password" ); + + if ( sURL != null && sURL.length() > 0 && sUserName != null && sUserName.length() > 0 && sPassword != null && sPassword.length() > 0 ) + { + String[] pPasswords = { sPassword }; + Helper.GetPasswordContainer( m_xContext ).addPersistent( sURL, sUserName, pPasswords, Helper.GetInteractionHandler( m_xContext ) ); + } + } + } + catch( Exception e ) + { + e.printStackTrace(); + } + + return bResult; + } + + private void EnableControls( boolean bEnable ) + { + if ( !bEnable ) + SetFocusTo( "CancelButton" ); + + try + { + GetPropSet( "UsernameField" ).setPropertyValue( "Enabled", Boolean.valueOf( bEnable ) ); + GetPropSet( "PasswordField" ).setPropertyValue( "Enabled", Boolean.valueOf( bEnable ) ); + GetPropSet( "OkButton" ).setPropertyValue( "Enabled", Boolean.valueOf( bEnable ) ); + GetPropSet( "HelpButton" ).setPropertyValue( "Enabled", Boolean.valueOf( bEnable ) ); + + if ( bEnable ) + { + GetPropSet( "UrlField" ).setPropertyValue( "Enabled", Boolean.valueOf( m_bAllowURLChange ) ); + GetPropSet( "SaveBox" ).setPropertyValue( "Enabled", Boolean.valueOf( Helper.PasswordStoringIsAllowed( m_xContext ) ) ); + if ( m_bAllowURLChange ) + SetFocusTo( "UrlField" ); + else + SetFocusTo( "UsernameField" ); + } + else + { + GetPropSet( "UrlField" ).setPropertyValue( "Enabled", Boolean.FALSE ); + GetPropSet( "SaveBox" ).setPropertyValue( "Enabled", Boolean.FALSE ); + } + } + catch ( Exception ex ) + { + ex.printStackTrace(); + } + } + + private void InitStrings( XComponentContext xContext ) + { + try + { + SetTitle( Helper.GetLocalizedString( xContext, Helper.DLG_MEDIAWIKI_TITLE ) ); + GetPropSet( "UrlLabel" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_EDITSETTING_URLLABEL ) ); + GetPropSet( "UsernameLabel" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_EDITSETTING_USERNAMELABEL ) ); + GetPropSet( "PasswordLabel" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_EDITSETTING_PASSWORDLABEL ) ); + GetPropSet( "AccountLine" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_EDITSETTING_ACCOUNTLINE ) ); + GetPropSet( "WikiLine" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_EDITSETTING_WIKILINE ) ); + GetPropSet( "SaveBox" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_EDITSETTING_SAVEBOX ) ); + GetPropSet( "OkButton" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_OK ) ); + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + + private void InitSaveCheckbox( XComponentContext xContext, boolean bInitSaveCheckBox ) + { + XPropertySet xSaveCheck = GetPropSet( "SaveBox" ); + try + { + xSaveCheck.setPropertyValue( "State", Short.valueOf( bInitSaveCheckBox ? (short)1 : (short)0 ) ); + xSaveCheck.setPropertyValue( "Enabled", Boolean.valueOf( Helper.PasswordStoringIsAllowed( xContext ) ) ); + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + + private void DoLogin() + { + String sRedirectURL = ""; + String sURL = ""; + try + { + sURL = ( String ) GetPropSet( "UrlField" ).getPropertyValue( "Text" ); + String sUserName = ( String ) GetPropSet( "UsernameField" ).getPropertyValue( "Text" ); + String sPassword = ( String ) GetPropSet( "PasswordField" ).getPropertyValue( "Text" ); + + boolean bAllowIndex = true; + + do + { + if ( sRedirectURL.length() > 0 ) + { + sURL = sRedirectURL; + sRedirectURL = ""; + } + + if ( sURL.length() > 0 ) + { + URI aURI = new URI(sURL); + HttpURLConnection connGet = Helper.PrepareMethod("GET", aURI, m_xContext); + connGet.setInstanceFollowRedirects(false); + connGet.connect(); + + int nResultCode = connGet.getResponseCode(); + String sWebPage = null; + if ( nResultCode == 200 ) + sWebPage = Helper.ReadResponseBody(connGet); + else if ( nResultCode >= 301 && nResultCode <= 303 || nResultCode == 307 ) + sRedirectURL = connGet.getHeaderField("Location"); + + if ( sWebPage != null && sWebPage.length() > 0 ) + { + //the URL is valid + String sMainURL = Helper.GetMainURL( sWebPage, sURL ); + + if ( sMainURL.length() == 0 ) + { + // TODO: + // it's not a Wiki Page, check first whether a redirect is requested + // happens usually in case of https + sRedirectURL = Helper.GetRedirectURL( sWebPage, sURL ); + if ( sRedirectURL.length() == 0 ) + { + // show error + Helper.ShowError( m_xContext, + m_xDialog, + Helper.DLG_MEDIAWIKI_TITLE, + Helper.NOURLCONNECTION_ERROR, + sURL, + false ); + } + } + else + { + URI aMainURI = new URI(sMainURL); + + if ( ( sUserName.length() > 0 || sPassword.length() > 0 ) + && !Helper.Login(aMainURI, sUserName, sPassword, m_xContext)) + { + // a wrong login information is provided + // show error + Helper.ShowError( m_xContext, + m_xDialog, + Helper.DLG_MEDIAWIKI_TITLE, + Helper.WRONGLOGIN_ERROR, + null, + false ); + } + else + { + setting.put( "Url", aMainURI.toASCIIString() ); + setting.put( "Username", sUserName ); + setting.put( "Password", sPassword ); + if ( addMode ) + { + // no cleaning of the settings is necessary + Settings.getSettings( m_xContext ).addWikiCon( setting ); + Settings.getSettings( m_xContext ).storeConfiguration(); + } + + m_bAction = true; + } + } + } + else if ( sRedirectURL == null || sRedirectURL.length() == 0 ) + { + if ( sURL.length() > 0 && !sURL.endsWith( "index.php" ) && bAllowIndex ) + { + // the used MainURL is not always directly accessible + // add the suffix as workaround, but only once + sRedirectURL = sURL + "/index.php"; + bAllowIndex = false; + } + else + { + // URL invalid + // show error + Helper.ShowError( m_xContext, + m_xDialog, + Helper.DLG_MEDIAWIKI_TITLE, + Helper.INVALIDURL_ERROR, + null, + false ); + } + } + } + else + { + // URL field empty + // show error + Helper.ShowError( m_xContext, + m_xDialog, + Helper.DLG_MEDIAWIKI_TITLE, + Helper.NOURL_ERROR, + null, + false ); + } + } while (sRedirectURL != null && sRedirectURL.length() > 0); + } + catch ( WikiCancelException ce ) + { + } + catch ( SSLException essl ) + { + if ( Helper.IsConnectionAllowed() ) + { + Helper.ShowError( m_xContext, + m_xDialog, + Helper.DLG_MEDIAWIKI_TITLE, + Helper.UNKNOWNCERT_ERROR, + null, + false ); + } + essl.printStackTrace(); + } + catch ( Exception ex ) + { + if ( Helper.IsConnectionAllowed() ) + { + Helper.ShowError( m_xContext, + m_xDialog, + Helper.DLG_MEDIAWIKI_TITLE, + Helper.NOURLCONNECTION_ERROR, + sURL, + false ); + } + ex.printStackTrace(); + } + } + + @Override + public boolean callHandlerMethod( XDialog xDialog, Object EventObject, String MethodName ) + { + if ( MethodName.equals( sOKMethod ) ) + { + EnableControls( false ); + SetThrobberVisible( true ); + SetThrobberActive( true ); + + if ( Helper.AllowThreadUsage( m_xContext ) ) + { + final XDialog xDialogForThread = xDialog; + final XComponentContext xContext = m_xContext; + + // the thread name is used to allow the error dialogs + m_bThreadFinished = false; + m_aThread = new Thread( "com.sun.star.thread.WikiEditorSendingThread" ) + { + @Override + public void run() + { + try + { + Thread.yield(); + } catch( java.lang.Exception e ){} + + DoLogin(); + WikiEditSettingDialog.this.EnableControls( true ); + WikiEditSettingDialog.this.SetThrobberActive( false ); + WikiEditSettingDialog.this.SetThrobberVisible( false ); + + ThreadStop( true ); + + if ( m_bAction ) + MainThreadDialogExecutor.Close( xContext, xDialogForThread ); + } + }; + + m_aThread.start(); + } + else + { + try + { + DoLogin(); + } catch( java.lang.Exception e ) + {} + finally + { + EnableControls( true ); + SetThrobberActive( false ); + SetThrobberVisible( false ); + + if ( m_bAction ) + xDialog.endExecute(); + + Helper.AllowConnection( true ); + } + } + + return true; + } + + return false; + } + + @Override + public void windowClosed( EventObject e ) + { + ThreadStop( false ); + } +} + diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiEditorImpl.java b/swext/mediawiki/src/com/sun/star/wiki/WikiEditorImpl.java new file mode 100644 index 0000000000..3d1bee21e7 --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiEditorImpl.java @@ -0,0 +1,353 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wiki; + +import java.io.File; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import javax.net.ssl.SSLException; + +import com.sun.star.awt.XWindowPeer; +import com.sun.star.beans.PropertyValue; +import com.sun.star.frame.DispatchDescriptor; +import com.sun.star.frame.XController; +import com.sun.star.frame.XDispatch; +import com.sun.star.frame.XDispatchProvider; +import com.sun.star.frame.XFrame; +import com.sun.star.frame.XModel; +import com.sun.star.frame.XStorable; +import com.sun.star.lang.XInitialization; +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.lib.uno.helper.Factory; +import com.sun.star.lib.uno.helper.WeakBase; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; + + +public final class WikiEditorImpl extends WeakBase + implements com.sun.star.lang.XServiceInfo, XDispatchProvider, XDispatch, XInitialization +{ + + private static final String m_implementationName = WikiEditorImpl.class.getName(); + private static final String[] m_serviceNames = {"com.sun.star.wiki.WikiEditor" }; + + + + // protocol name that this protocol handler handles + private static final String protocolName = "vnd.com.sun.star.wiki:"; + + private final XComponentContext m_xContext; + private XFrame m_xFrame; + private XModel m_xModel; + private final Settings m_aSettings; + private String m_aFilterName; + + public WikiEditorImpl( XComponentContext xContext ) + { + // Helper.trustAllSSL(); + m_xContext = xContext; + m_aSettings = Settings.getSettings( m_xContext ); + } + + public static XSingleComponentFactory __getComponentFactory( String sImplementationName ) + { + XSingleComponentFactory xFactory = null; + + if ( sImplementationName.equals( m_implementationName ) ) + xFactory = Factory.createComponentFactory( WikiEditorImpl.class, m_serviceNames ); + else if ( sImplementationName.equals( WikiOptionsEventHandlerImpl.m_sImplementationName ) ) + xFactory = Factory.createComponentFactory( WikiOptionsEventHandlerImpl.class, + WikiOptionsEventHandlerImpl.m_pServiceNames ); + + return xFactory; + } + + // com.sun.star.lang.XServiceInfo: + public String getImplementationName() + { + return m_implementationName; + } + + public boolean supportsService( String sService ) + { + int len = m_serviceNames.length; + + for( int i=0; i < len; i++ ) + { + if ( sService.equals( m_serviceNames[i] )) + return true; + } + return false; + } + + public String[] getSupportedServiceNames() + { + return m_serviceNames; + } + + + public synchronized void initialize( Object[] args ) throws com.sun.star.uno.Exception + { + if ( args.length > 0 ) + { + m_xFrame = UnoRuntime.queryInterface( XFrame.class, args[0] ); + } + } + + + + public void dispatch( + final com.sun.star.util.URL aURL, + com.sun.star.beans.PropertyValue[] propertyValue ) + { + final com.sun.star.util.URL myURL = aURL; + if ( aURL.Protocol.equals(protocolName) ) + { + try + { + if ( myURL.Path.equals("send") ) + { + sendArticle(); + } + } catch( java.lang.Throwable t ) + { + } + } + } + + + public com.sun.star.frame.XDispatch queryDispatch( + com.sun.star.util.URL aURL, + String str, + int param ) + { + if ( aURL.Protocol.equals( protocolName )) + { + + // by default, we are responsible + return this; + } else + { + return null; + } + } + + public XDispatch[] queryDispatches( DispatchDescriptor[] seqDescripts ) + { + int nCount = seqDescripts.length; + XDispatch[] lDispatcher = new XDispatch[nCount]; + + for( int i=0; i<nCount; ++i ) + lDispatcher[i] = queryDispatch( + seqDescripts[i].FeatureURL, + seqDescripts[i].FrameName, + seqDescripts[i].SearchFlags ); + return lDispatcher; + } + + + public void removeStatusListener( + com.sun.star.frame.XStatusListener xStatusListener, + com.sun.star.util.URL aURL ) + { + } + + + public void addStatusListener( + com.sun.star.frame.XStatusListener listener, + com.sun.star.util.URL url ) + { + } + + private void sendArticle() + { + if ( m_xFrame != null ) + { + WikiPropDialog aSendDialog = null; + try + { + if ( m_xModel == null ) + { + XController xController = m_xFrame.getController(); + if ( xController != null ) + m_xModel = xController.getModel(); + } + + if ( m_xModel != null ) + { + // The related Wiki filter must be detected from the typename + String aServiceName = Helper.GetDocServiceName( m_xContext, m_xModel ); + m_aFilterName = Helper.GetFilterName( m_xContext, "MediaWiki", aServiceName ); + + if ( m_aFilterName == null || m_aFilterName.length() == 0 ) + { + Helper.ShowError( m_xContext, + UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ), + Helper.DLG_SENDTITLE, + Helper.NOWIKIFILTER_ERROR, + null, + false ); + throw new com.sun.star.uno.RuntimeException(); + } + + m_aSettings.loadConfiguration(); // throw away all the noncommitted changes + // show the send dialog + aSendDialog = new WikiPropDialog( m_xContext, "vnd.sun.star.script:WikiEditor.SendToMediaWiki?location=application", this ); + aSendDialog.fillWikiList(); + aSendDialog.SetWikiTitle( Helper.GetDocTitle( m_xModel ) ); + aSendDialog.show(); // triggers the sending + } + } + catch ( Exception e ) + { + // TODO: Error handling here + e.printStackTrace(); + } + finally + { + if ( aSendDialog != null ) + aSendDialog.DisposeDialog(); + } + } + } + + public boolean SendArticleImpl( WikiPropDialog aSendDialog, Map<String,String> aWikiSetting ) + { + boolean bResult = false; + + if ( aSendDialog != null ) + { + String sTemp2Url = null; + + try + { + // TODO: stop progress spinning + WikiArticle aArticle = new WikiArticle( m_xContext, aSendDialog.GetWikiTitle(), aWikiSetting, true, aSendDialog ); + + boolean bAllowSending = true; + if ( !aArticle.NotExist() ) + { + // ask whether creation of a new page is allowed + aSendDialog.SetThrobberActive( false ); + bAllowSending = Helper.ShowError( + m_xContext, + UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ), + Helper.DLG_SENDTITLE, + Helper.DLG_WIKIPAGEEXISTS_LABEL1, + aSendDialog.GetWikiTitle(), + true ); + aSendDialog.SetThrobberActive( true ); + } + + if ( bAllowSending ) + { + PropertyValue[] lProperties = new PropertyValue[2]; + lProperties[0] = new PropertyValue(); + lProperties[0].Name = "FilterName"; + lProperties[0].Value = m_aFilterName; + lProperties[1] = new PropertyValue(); + lProperties[1].Name = "Overwrite"; + lProperties[1].Value = Boolean.TRUE; + + sTemp2Url = Helper.CreateTempFile( m_xContext ); + + XStorable xStore = UnoRuntime.queryInterface ( XStorable.class, m_xModel ); + if ( xStore == null ) + throw new com.sun.star.uno.RuntimeException(); + + xStore.storeToURL( sTemp2Url, lProperties ); + String sWikiCode = Helper.EachLine( sTemp2Url ); + + if ( aArticle.setArticle( sWikiCode, aSendDialog.m_sWikiComment, aSendDialog.m_bWikiMinorEdit ) ) + { + bResult = true; + Helper.SetDocTitle( m_xModel, aArticle.GetTitle() ); + Map<String,Object> aDocInfo = new HashMap<String,Object>(); + aDocInfo.put( "Doc", aArticle.GetTitle() ); + aDocInfo.put( "Url", aArticle.GetMainURL() ); + aDocInfo.put( "CompleteUrl", aArticle.GetMainURL() + aArticle.GetTitle() ); + m_aSettings.addWikiDoc( aDocInfo ); + m_aSettings.storeConfiguration(); + } + else + { + Helper.ShowError( m_xContext, + UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ), + Helper.DLG_SENDTITLE, + Helper.GENERALSEND_ERROR, + null, + false ); + } + } + } + catch( WikiCancelException ec ) + { + // nothing to do, the sending was cancelled + } + catch( SSLException essl ) + { + if ( Helper.IsConnectionAllowed() ) + { + // report the error only if sending was not cancelled + Helper.ShowError( m_xContext, + UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ), + Helper.DLG_SENDTITLE, + Helper.UNKNOWNCERT_ERROR, + null, + false ); + } + } + catch( Exception e ) + { + if ( Helper.IsConnectionAllowed() ) + { + // report the error only if sending was not cancelled + Helper.ShowError( m_xContext, + UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ), + Helper.DLG_SENDTITLE, + Helper.GENERALSEND_ERROR, + null, + false ); + } + e.printStackTrace(); + } + + if ( sTemp2Url != null ) + { + try + { + // remove the temporary file + File aFile = new File( new URI( sTemp2Url ) ); + if (!aFile.delete()) { + throw new java.lang.Exception("could not remove" + sTemp2Url); + } + } + catch ( java.lang.Exception e ) + { + e.printStackTrace(); + } + } + } + + return bResult; + } + +} diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiOptionsEventHandlerImpl.java b/swext/mediawiki/src/com/sun/star/wiki/WikiOptionsEventHandlerImpl.java new file mode 100644 index 0000000000..c35246be4d --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiOptionsEventHandlerImpl.java @@ -0,0 +1,279 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wiki; + +import com.sun.star.awt.XContainerWindowEventHandler; +import com.sun.star.awt.XControl; +import com.sun.star.awt.XControlContainer; +import com.sun.star.awt.XDialog; +import com.sun.star.awt.XDialogEventHandler; +import com.sun.star.awt.XWindow; +import com.sun.star.beans.XPropertySet; +import com.sun.star.lang.WrappedTargetException; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.lib.uno.helper.WeakBase; +import com.sun.star.uno.AnyConverter; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import java.util.Map; + +public final class WikiOptionsEventHandlerImpl extends WeakBase + implements XServiceInfo, XContainerWindowEventHandler, XDialogEventHandler +{ + static final String[] m_pServiceNames = { "com.sun.star.wiki.WikiOptionsEventHandler" }; + static final String m_sImplementationName = WikiOptionsEventHandlerImpl.class.getName(); + + private static final String sExternalEvent = "external_event"; + private static final String sAdd = "Add"; + private static final String sEdit = "Edit"; + private static final String sRemove = "Remove"; + private static final String sListStatus = "ListStatus"; + private static final String sListEdit = "ListEdit"; + private static final String sInitialize = "initialize"; + private static final String sOk = "ok"; + private static final String sBack = "back"; + + private final XComponentContext m_xContext; + private XDialog m_xDialog; + private XControlContainer m_xControlContainer; + + private Settings m_aSettings; + + public WikiOptionsEventHandlerImpl( XComponentContext xContext ) + { + m_xContext = xContext; + } + + private XPropertySet GetPropSet( String sControl ) + { + if ( m_xControlContainer != null ) + { + XControl xControl = m_xControlContainer.getControl(sControl); + XPropertySet xListProps = UnoRuntime.queryInterface(XPropertySet.class, xControl.getModel() ); + return xListProps; + } + + return null; + } + + private void RefreshView() + { + if ( m_aSettings != null ) + { + String[] pWikiList = m_aSettings.getWikiURLs(); + XPropertySet xListProps = GetPropSet( "WikiList" ); + if ( xListProps != null ) + { + try + { + xListProps.setPropertyValue( "StringItemList", pWikiList ); + } + catch ( Exception ex ) + { + ex.printStackTrace(); + } + } + } + } + + private void CheckButtonState() + { + XPropertySet xListProps = GetPropSet( "WikiList" ); + if ( xListProps != null ) + { + try + { + short [] pSel = (short []) xListProps.getPropertyValue( "SelectedItems" ); + XPropertySet xEditProps = GetPropSet( "EditButton" ); + XPropertySet xRemoveProps = GetPropSet( "RemoveButton" ); + Boolean bState = Boolean.valueOf( pSel.length != 0 ); + + xEditProps.setPropertyValue( "Enabled", bState ); + xRemoveProps.setPropertyValue( "Enabled", bState ); + } + catch ( Exception ex ) + { + ex.printStackTrace(); + } + } + } + + private void AddSetting() + { + WikiEditSettingDialog aSettingDialog = new WikiEditSettingDialog( m_xContext, "vnd.sun.star.script:WikiEditor.EditSetting?location=application" ); + if ( aSettingDialog.show() ) + RefreshView(); + + aSettingDialog.DisposeDialog(); + } + + private void EditSetting() + { + XPropertySet xListProps = GetPropSet( "WikiList" ); + if ( xListProps != null ) + { + Map<String,String> ht = null; + try + { + short[] pSel = (short []) xListProps.getPropertyValue( "SelectedItems" ); + String[] pItems = (String []) xListProps.getPropertyValue("StringItemList"); + if ( pSel.length > 0 && pItems.length > pSel[0] ) + { + String selName = pItems[pSel[0]]; + ht = m_aSettings.getSettingByUrl( selName ); + } + } + catch ( Exception ex ) + { + ex.printStackTrace(); + } + + WikiEditSettingDialog aSettingDialog = new WikiEditSettingDialog(m_xContext, "vnd.sun.star.script:WikiEditor.EditSetting?location=application", ht, true ); + if ( aSettingDialog.show() ) + RefreshView(); + + aSettingDialog.DisposeDialog(); + } + } + + private void RemoveSetting() + { + XPropertySet xListProps = GetPropSet("WikiList"); + if ( xListProps != null ) + { + try + { + short[] pSel = (short []) xListProps.getPropertyValue("SelectedItems"); + String[] pItems = (String []) GetPropSet("WikiList").getPropertyValue("StringItemList"); + if ( pSel.length > 0 && pItems.length > pSel[0] ) + { + m_aSettings.removeSettingByUrl( pItems[pSel[0]] ); + RefreshView(); + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + } + + private void InitStrings() + { + try + { + GetPropSet( "FixedLine1" ).setPropertyValue( "Label", Helper.GetLocalizedString( m_xContext, Helper.DLG_MEDIAWIKIEXTENSION_STRING ) ); + GetPropSet( "AddButton" ).setPropertyValue( "Label", Helper.GetLocalizedString( m_xContext, Helper.DLG_ADDBUTTON ) ); + GetPropSet( "EditButton" ).setPropertyValue( "Label", Helper.GetLocalizedString( m_xContext, Helper.DLG_EDITBUTTON ) ); + GetPropSet( "RemoveButton" ).setPropertyValue( "Label", Helper.GetLocalizedString( m_xContext, Helper.DLG_REMOVEBUTTON ) ); + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + + // com.sun.star.lang.XServiceInfo: + public String getImplementationName() + { + return m_sImplementationName; + } + + public boolean supportsService( String sService ) + { + int len = m_pServiceNames.length; + + for( int i=0; i < len; i++ ) + { + if ( sService.equals( m_pServiceNames[i] )) + return true; + } + return false; + } + + public String[] getSupportedServiceNames() + { + return m_pServiceNames; + } + + // XContainerWindowEventHandler + public boolean callHandlerMethod( XWindow xWindow, Object aEventObject, String sMethod ) + throws WrappedTargetException, com.sun.star.uno.RuntimeException + { + if ( sMethod.equals( sExternalEvent ) ) + { + String sEvent = AnyConverter.toString( aEventObject ); + if ( sEvent != null ) + { + if ( sEvent.equals( sOk ) ) + { + if ( m_aSettings != null ) + m_aSettings.storeConfiguration(); + } + else if ( sEvent.equals( sInitialize ) || sEvent.equals( sBack ) ) + { + if ( sEvent.equals( sInitialize ) ) + { + m_xDialog = UnoRuntime.queryInterface( XDialog.class, xWindow ); + m_xControlContainer = UnoRuntime.queryInterface( XControlContainer.class, m_xDialog ); + m_aSettings = Settings.getSettings( m_xContext ); + m_aSettings.loadConfiguration(); // throw away all the noncommitted changes + InitStrings(); + } + else if ( m_aSettings != null ) + m_aSettings.loadConfiguration(); // throw away all the noncommitted changes + + RefreshView(); + CheckButtonState(); + } + } + } + else if ( sMethod.equals( sAdd ) ) + { + AddSetting(); + } + else if ( sMethod.equals( sEdit ) || sMethod.equals( sListEdit ) ) + { + EditSetting(); + } + else if ( sMethod.equals( sRemove ) ) + { + RemoveSetting(); + CheckButtonState(); + } + else if ( sMethod.equals( sListStatus ) ) + { + CheckButtonState(); + } + + return true; + } + + public boolean callHandlerMethod( XDialog xDialog, Object aEventObject, String sMethod ) + throws WrappedTargetException, com.sun.star.uno.RuntimeException + { + return true; + } + + public String[] getSupportedMethodNames() + { + return new String[] { sExternalEvent, sAdd, sEdit, sRemove }; + } +} + diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiPropDialog.java b/swext/mediawiki/src/com/sun/star/wiki/WikiPropDialog.java new file mode 100644 index 0000000000..9ac41d4d31 --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiPropDialog.java @@ -0,0 +1,372 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wiki; + +import java.util.Map; + +import com.sun.star.awt.XDialog; +import com.sun.star.beans.XPropertySet; +import com.sun.star.lang.EventObject; +import com.sun.star.uno.XComponentContext; + +public class WikiPropDialog extends WikiDialog{ + + private WikiEditorImpl m_aWikiEditor; + + private static final String sSendMethod = "Send"; + private static final String sWikiListMethod = "WikiListChange"; + private static final String sArticleTextMethod = "ArticleTextChange"; + private static final String sAddWikiMethod = "AddWiki"; + + private final String[] m_pMethods = {sSendMethod, sWikiListMethod, sArticleTextMethod, sAddWikiMethod}; + + private String m_sWikiTitle = ""; + private String m_sWikiEngineURL = ""; + protected String m_sWikiComment = ""; + protected boolean m_bWikiMinorEdit = false; + + /** Creates a new instance of WikiPropDialog */ + public WikiPropDialog(XComponentContext xContext, String DialogURL, WikiEditorImpl aWikiEditorForThrobber ) + { + super(xContext, DialogURL); + super.setMethods(m_pMethods); + + if ( aWikiEditorForThrobber != null ) + { + InsertThrobber( 224, 122, 10, 10 ); + m_aWikiEditor = aWikiEditorForThrobber; + } + + InitStrings( xContext ); + InitShowBrowser(); + InitControls(); + } + + private void InitControls() + { + try + { + GetPropSet( "CommentText" ).setPropertyValue( "AutoVScroll", Boolean.TRUE ); + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + + private void InitStrings( XComponentContext xContext ) + { + try + { + SetTitle( Helper.GetLocalizedString( xContext, Helper.DLG_SENDTITLE ) ); + GetPropSet( "Label1" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_SENDTOMEDIAWIKI_LABEL1 ) ); + GetPropSet( "FixedLine2" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_WIKIARTICLE ) ); + GetPropSet( "Label2" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_SENDTOMEDIAWIKI_LABEL2 ) ); + GetPropSet( "Label3" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_SENDTOMEDIAWIKI_LABEL3 ) ); + GetPropSet( "MinorCheck" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_SENDTOMEDIAWIKI_MINORCHECK ) ); + GetPropSet( "BrowserCheck" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_SENDTOMEDIAWIKI_BROWSERCHECK ) ); + GetPropSet( "AddButton" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_ADDBUTTON ) ); + GetPropSet( "SendButton" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_SENDBUTTON ) ); + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + + private void InitShowBrowser() + { + try + { + GetPropSet( "BrowserCheck" ).setPropertyValue( "State", Short.valueOf( Helper.GetShowInBrowserByDefault( m_xContext ) ? (short)1 : (short)0 ) ); + } + catch( Exception e ) + { + e.printStackTrace(); + } + } + + @Override + public boolean show() + { + EnableControls( true ); + boolean bResult = super.show(); + + if ( bResult && Helper.GetShowInBrowserByDefault( m_xContext ) ) + Helper.ShowURLInBrowser( m_xContext, m_sWikiEngineURL + "index.php?title=" + m_sWikiTitle ); + + return bResult; + } + + @Override + public synchronized void ThreadStop( boolean bSelf ) + { + boolean bShowError = ( !bSelf && m_aThread != null && !m_bThreadFinished ); + + super.ThreadStop( bSelf ); + + if ( bShowError ) + Helper.ShowError( m_xContext, + m_xDialog, + Helper.DLG_SENDTITLE, + Helper.CANCELSENDING_ERROR, + null, + false ); + } + + public void fillWikiList() + { + String [] WikiList = m_aSettings.getWikiURLs(); + + try + { + XPropertySet xPS = GetPropSet("WikiList"); + xPS.setPropertyValue("StringItemList", WikiList); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + private void fillDocList() + { + XPropertySet xPS = GetPropSet("ArticleText"); + try + { + short [] sel = (short[]) GetPropSet("WikiList").getPropertyValue("SelectedItems"); + xPS.setPropertyValue("StringItemList", m_aSettings.getWikiDocList(sel[0])); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + + public String GetWikiTitle() + { + return m_sWikiTitle; + } + + public void SetWikiTitle(String sArticle) + { + m_sWikiTitle = sArticle; + try + { + XPropertySet xPS = GetPropSet("ArticleText"); + xPS.setPropertyValue("Text", sArticle); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + + private void switchSendButtonIfNecessary() + { + XPropertySet xSendButton = GetPropSet( "SendButton" ); + if ( xSendButton != null ) + { + XPropertySet xWikiListProps = GetPropSet( "WikiList" ); + XPropertySet xArticleProps = GetPropSet( "ArticleText" ); + if ( xWikiListProps != null && xArticleProps != null ) + { + try + { + short [] pSel = (short[]) GetPropSet("WikiList").getPropertyValue("SelectedItems"); + String sArticle = (String)xArticleProps.getPropertyValue( "Text" ); + if ( pSel != null && pSel.length > 0 && sArticle != null && sArticle.length() != 0 ) + xSendButton.setPropertyValue( "Enabled", Boolean.TRUE ); + else + xSendButton.setPropertyValue( "Enabled", Boolean.FALSE ); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + } + } + + private void EnableControls( boolean bEnable ) + { + try + { + String[] pControls = { "WikiList", + "ArticleText", + "CommentText", + "MinorCheck", + "BrowserCheck", + "HelpButton", + "AddButton" }; + + for ( int nInd = 0; nInd < pControls.length; nInd++ ) + GetPropSet( pControls[nInd] ).setPropertyValue( "Enabled", Boolean.valueOf( bEnable ) ); + + if ( bEnable ) + { + SetFocusTo( "WikiList" ); + switchSendButtonIfNecessary(); + } + else + { + GetPropSet( "SendButton" ).setPropertyValue( "Enabled", Boolean.valueOf( bEnable ) ); + SetFocusTo( "CancelButton" ); + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + @Override + public boolean callHandlerMethod( XDialog xDialog, Object EventObject, String MethodName ) + { + if ( MethodName.equals( sSendMethod ) ) + { + try + { + XPropertySet aWikiListProps = GetPropSet( "WikiList" ); + XPropertySet aArticleTextProps = GetPropSet( "ArticleText" ); + XPropertySet aCommentTextProps = GetPropSet( "CommentText" ); + XPropertySet aMinorCheckProps = GetPropSet( "MinorCheck" ); + XPropertySet aBrowserCheckProps = GetPropSet( "BrowserCheck" ); + + short [] sel = (short[]) aWikiListProps.getPropertyValue("SelectedItems"); + String [] items = (String []) aWikiListProps.getPropertyValue("StringItemList"); + m_sWikiEngineURL = items[sel[0]]; + m_sWikiTitle = (String) aArticleTextProps.getPropertyValue("Text"); + m_sWikiComment = (String) aCommentTextProps.getPropertyValue("Text"); + + short minorState = ((Short) aMinorCheckProps.getPropertyValue("State")).shortValue(); + if (minorState != 0) + m_bWikiMinorEdit = true; + else + m_bWikiMinorEdit = false; + + short nBrowserState = ((Short) aBrowserCheckProps.getPropertyValue("State")).shortValue(); + Helper.SetShowInBrowserByDefault( m_xContext, nBrowserState != 0 ); + + // allow to disable other buttons + EnableControls( false ); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + + final XDialog xDialogToClose = xDialog; + final XComponentContext xContext = m_xContext; + + // start spinning + SetThrobberVisible( true ); + SetThrobberActive( true ); + + // the following method might show a dialog, should be used in main thread + final Map<String,String> aWikiSettings = m_aSettings.getSettingByUrl( m_sWikiEngineURL ); + if ( Helper.AllowThreadUsage( m_xContext ) ) + { + m_aThread = new Thread( "com.sun.star.thread.WikiEditorSendingThread" ) + { + @Override + public void run() + { + try + { + if ( m_aWikiEditor != null ) + { + Thread.yield(); + m_bAction = m_aWikiEditor.SendArticleImpl( + WikiPropDialog.this, aWikiSettings); + } + } + finally + { + EnableControls( true ); + SetThrobberActive( false ); + SetThrobberVisible( false ); + + ThreadStop( true ); + if ( m_bAction ) + MainThreadDialogExecutor.Close( xContext, xDialogToClose ); + } + } + }; + + m_aThread.start(); + } + else + { + try + { + if (m_aWikiEditor != null && aWikiSettings != null) + { + m_bAction = m_aWikiEditor.SendArticleImpl( + WikiPropDialog.this, aWikiSettings); + } + } catch( java.lang.Exception e ) + {} + finally + { + EnableControls( true ); + SetThrobberActive( false ); + SetThrobberVisible( false ); + + if ( m_bAction ) + xDialogToClose.endExecute(); + } + } + + return true; + } + else if ( MethodName.equals( sWikiListMethod ) ) + { + fillDocList(); + switchSendButtonIfNecessary(); + return true; + } + else if ( MethodName.equals( sArticleTextMethod ) ) + { + switchSendButtonIfNecessary(); + return true; + } + else if ( MethodName.equals( sAddWikiMethod ) ) + { + WikiEditSettingDialog xAddDialog = new WikiEditSettingDialog(m_xContext, "vnd.sun.star.script:WikiEditor.EditSetting?location=application"); + if ( xAddDialog.show() ) + fillWikiList(); + + xAddDialog.DisposeDialog(); + + return true; + } + + return false; + } + + @Override + public void windowClosed( EventObject e ) + { + ThreadStop( false ); + } +} + diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java b/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java new file mode 100644 index 0000000000..7ca94390dc --- /dev/null +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java @@ -0,0 +1,333 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wiki; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.security.KeyStore; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +class WikiProtocolSocketFactory extends SSLSocketFactory +{ + private SSLContext m_aSSLContext; + + private synchronized SSLContext GetNotSoSecureSSLContext() + { + if ( m_aSSLContext != null ) { + return m_aSSLContext; + } + TrustManager[] pTrustUnknownCerts = new TrustManager[] + { + new X509TrustManager() { + private X509TrustManager m_aOrgTrustManager; + + private X509TrustManager GetOrgTrustManager() + { + if ( m_aOrgTrustManager == null ) + { + try + { + TrustManagerFactory aFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() ); + aFactory.init( (KeyStore)null ); + TrustManager[] pTrustmanagers = aFactory.getTrustManagers(); + if ( pTrustmanagers.length != 0 && pTrustmanagers[0] != null ) + m_aOrgTrustManager = (X509TrustManager)pTrustmanagers[0]; + } + catch( Exception e ) + { + throw new RuntimeException( "No access to the default trust manager!", e ); + } + } + + if (m_aOrgTrustManager == null) + throw new RuntimeException("No access to the default trust manager!"); + + return m_aOrgTrustManager; + } + + public X509Certificate[] getAcceptedIssuers() + { + return GetOrgTrustManager().getAcceptedIssuers(); + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException + { + GetOrgTrustManager().checkClientTrusted( certs, authType ); + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException + { + if ( certs == null || certs.length == 0 ) + GetOrgTrustManager().checkServerTrusted( certs, authType ); + else + for ( int nInd = 0; nInd < certs.length; nInd++ ) + certs[nInd].checkValidity(); + } + } + }; + + try + { + SSLContext aContext = SSLContext.getInstance("TLSv1.2"); + if ( aContext != null ) + { + aContext.init( null, pTrustUnknownCerts, null ); + m_aSSLContext = aContext; + } + } + catch ( Exception e ) + { + } + + if ( m_aSSLContext == null ) + throw new RuntimeException("failed to create SSLContext"); + + return m_aSSLContext; + } + + @Override + public Socket createSocket(InetAddress address, int port) + throws IOException + { + return GetNotSoSecureSSLContext().getSocketFactory().createSocket(address, port); + } + + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) + throws IOException + { + return GetNotSoSecureSSLContext().getSocketFactory().createSocket(address, port, localAddress, localPort); + } + + @Override + public Socket createSocket( String sHost, int nPort, InetAddress clientHost, int clientPort ) + throws IOException, UnknownHostException + { + return GetNotSoSecureSSLContext().getSocketFactory().createSocket( sHost, nPort, clientHost, clientPort ); + } + + @Override + public Socket createSocket( String sHost, int nPort ) + throws IOException, UnknownHostException + { + return GetNotSoSecureSSLContext().getSocketFactory().createSocket( sHost, nPort ); + } + + @Override + public Socket createSocket( Socket aSocket, String sHost, int nPort, boolean bAutoClose ) + throws IOException + { + return GetNotSoSecureSSLContext().getSocketFactory().createSocket( aSocket, sHost, nPort, bAutoClose ); + } + + @Override + public String[] getDefaultCipherSuites() + { + return GetNotSoSecureSSLContext().getSocketFactory().getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() + { + return GetNotSoSecureSSLContext().getSocketFactory().getSupportedCipherSuites(); + } + + @Override + public boolean equals(Object obj) + { + return (obj != null) && (obj instanceof WikiProtocolSocketFactory); + } + + @Override + public int hashCode() + { + return WikiProtocolSocketFactory.class.hashCode(); + } +} + +// A factory that creates streams that log everything that's written +// to stderr - useful for debugging encrypted TLS connections +class LoggingProtocolSocketFactory extends SSLSocketFactory +{ + private static class LogSocket extends SSLSocket + { + private final SSLSocket m_Socket; + + public LogSocket(SSLSocket socket) + { + m_Socket = socket; + } + + private static class LogStream extends java.io.FilterOutputStream + { + public LogStream(java.io.OutputStream stream) + { + super(stream); + } + + @Override + public void write(byte[] buf, int offset, int len) + throws IOException + { + System.err.println("LogStream.write: \"" + new String(buf, offset, len, "UTF-8") + "\""); + out.write(buf, offset, len); + } + } + + @Override + public java.io.OutputStream getOutputStream() throws IOException + { + return new LogStream(m_Socket.getOutputStream()); + } + + @Override public void addHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener listener) { m_Socket.addHandshakeCompletedListener(listener); } + @Override public String[] getEnabledCipherSuites() { return m_Socket.getEnabledCipherSuites(); } + @Override public String[] getEnabledProtocols() { return m_Socket.getEnabledProtocols(); } + @Override public boolean getEnableSessionCreation() { return m_Socket.getEnableSessionCreation(); } + @Override public boolean getNeedClientAuth() { return m_Socket.getNeedClientAuth(); } + @Override public javax.net.ssl.SSLSession getSession() { return m_Socket.getSession(); } + @Override public javax.net.ssl.SSLParameters getSSLParameters() { return m_Socket.getSSLParameters(); } + @Override public String[] getSupportedCipherSuites() { return m_Socket.getSupportedCipherSuites(); } + @Override public String[] getSupportedProtocols() { return m_Socket.getSupportedProtocols(); } + @Override public boolean getUseClientMode() { return m_Socket.getUseClientMode(); } + @Override public boolean getWantClientAuth() { return m_Socket.getWantClientAuth(); } + @Override public void removeHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener listener) { m_Socket.removeHandshakeCompletedListener(listener); } + @Override public void setEnabledCipherSuites(String[] suites) { m_Socket.setEnabledCipherSuites(suites); } + @Override public void setEnabledProtocols(String[] protocols) { m_Socket.setEnabledProtocols(protocols); } + @Override public void setEnableSessionCreation(boolean flag) { m_Socket.setEnableSessionCreation(flag); } + @Override public void setNeedClientAuth(boolean need) { m_Socket.setNeedClientAuth(need); } + @Override public void setSSLParameters(javax.net.ssl.SSLParameters params) { m_Socket.setSSLParameters(params); } + @Override public void setUseClientMode(boolean mode) { m_Socket.setUseClientMode(mode); } + @Override public void setWantClientAuth(boolean want) { m_Socket.setWantClientAuth(want); } + @Override public void startHandshake() throws IOException { m_Socket.startHandshake(); } + + @Override public void bind(java.net.SocketAddress bindpoint) throws IOException { m_Socket.bind(bindpoint); } + @Override public void close() throws IOException { m_Socket.close(); } + @Override public void connect(java.net.SocketAddress endpoint) throws IOException { m_Socket.connect(endpoint); } + @Override public void connect(java.net.SocketAddress endpoint, int timeout) throws IOException { m_Socket.connect(endpoint, timeout); } + @Override public java.nio.channels.SocketChannel getChannel() { return m_Socket.getChannel(); } + @Override public InetAddress getInetAddress() { return m_Socket.getInetAddress(); } + @Override public java.io.InputStream getInputStream() throws IOException { return m_Socket.getInputStream(); } + @Override public boolean getKeepAlive() throws java.net.SocketException { return m_Socket.getKeepAlive(); } + @Override public InetAddress getLocalAddress() { return m_Socket.getLocalAddress(); } + @Override public int getLocalPort() { return m_Socket.getLocalPort(); } + @Override public java.net.SocketAddress getLocalSocketAddress() { return m_Socket.getLocalSocketAddress(); } + @Override public boolean getOOBInline() throws java.net.SocketException { return m_Socket.getOOBInline(); } + @Override public int getPort() { return m_Socket.getPort(); } + @Override public int getReceiveBufferSize() throws java.net.SocketException { return m_Socket.getReceiveBufferSize(); } + @Override public java.net.SocketAddress getRemoteSocketAddress() { return m_Socket.getRemoteSocketAddress(); } + @Override public boolean getReuseAddress() throws java.net.SocketException { return m_Socket.getReuseAddress(); } + @Override public int getSendBufferSize() throws java.net.SocketException { return m_Socket.getSendBufferSize(); } + @Override public int getSoLinger() throws java.net.SocketException { return m_Socket.getSoLinger(); } + @Override public int getSoTimeout() throws java.net.SocketException { return m_Socket.getSoTimeout(); } + @Override public boolean getTcpNoDelay() throws java.net.SocketException { return m_Socket.getTcpNoDelay(); } + @Override public int getTrafficClass() throws java.net.SocketException { return m_Socket.getTrafficClass(); } + @Override public boolean isBound() { return m_Socket.isBound(); } + @Override public boolean isClosed() { return m_Socket.isClosed(); } + @Override public boolean isConnected() { return m_Socket.isConnected(); } + @Override public boolean isInputShutdown() { return m_Socket.isInputShutdown(); } + @Override public boolean isOutputShutdown() { return m_Socket.isOutputShutdown(); } + @Override public void sendUrgentData(int data) throws IOException { m_Socket.sendUrgentData(data); } + @Override public void setKeepAlive(boolean on) throws java.net.SocketException { m_Socket.setKeepAlive(on); } + @Override public void setOOBInline(boolean on) throws java.net.SocketException { m_Socket.setOOBInline(on); } + @Override public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { m_Socket.setPerformancePreferences(connectionTime, latency, bandwidth); } + @Override public void setReceiveBufferSize(int size) throws java.net.SocketException { m_Socket.setReceiveBufferSize(size); } + @Override public void setReuseAddress(boolean on) throws java.net.SocketException { m_Socket.setReuseAddress(on); } + @Override public void setSendBufferSize(int size) throws java.net.SocketException { m_Socket.setSendBufferSize(size); } + @Override public void setSoLinger(boolean on, int linger) throws java.net.SocketException { m_Socket.setSoLinger(on, linger); } + @Override public void setSoTimeout(int timeout) throws java.net.SocketException{ m_Socket.setSoTimeout(timeout); } + @Override public void setTcpNoDelay(boolean on) throws java.net.SocketException{ m_Socket.setTcpNoDelay(on); } + @Override public void setTrafficClass(int tc) throws java.net.SocketException { m_Socket.setTrafficClass(tc); } + @Override public void shutdownInput() throws IOException { m_Socket.shutdownInput(); } + @Override public void shutdownOutput() throws IOException { m_Socket.shutdownOutput(); } + @Override public String toString() { return m_Socket.toString(); } + + } + + @Override + public Socket createSocket(InetAddress address, int port) + throws IOException + { + return new LogSocket((SSLSocket) SSLSocketFactory.getDefault().createSocket(address, port)); + } + + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) + throws IOException + { + return new LogSocket((SSLSocket) SSLSocketFactory.getDefault().createSocket(address, port, localAddress, localPort)); + } + + @Override + public Socket createSocket( String sHost, int nPort, InetAddress clientHost, int clientPort ) + throws IOException, UnknownHostException + { + return new LogSocket((SSLSocket) SSLSocketFactory.getDefault().createSocket(sHost, nPort, clientHost, clientPort)); + } + + @Override + public Socket createSocket( String sHost, int nPort ) + throws IOException, UnknownHostException + { + return new LogSocket((SSLSocket) SSLSocketFactory.getDefault().createSocket(sHost, nPort)); + } + + @Override + public Socket createSocket( Socket aSocket, String sHost, int nPort, boolean bAutoClose ) + throws IOException + { + return new LogSocket((SSLSocket) ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(aSocket, sHost, nPort, bAutoClose)); + } + + @Override + public String[] getDefaultCipherSuites() + { + // have to implement abstract method, just use the default + return ((SSLSocketFactory) SSLSocketFactory.getDefault()).getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() + { + // have to implement abstract method, just use the default + return ((SSLSocketFactory) SSLSocketFactory.getDefault()).getSupportedCipherSuites(); + } + + @Override + public boolean equals(Object obj) + { + return (obj != null) && (obj instanceof LoggingProtocolSocketFactory); + } + + @Override + public int hashCode() + { + return LoggingProtocolSocketFactory.class.hashCode(); + } +} + |