1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 package com.sun.star.wiki;
29 
30 import com.sun.star.task.UrlRecord;
31 import java.io.*;
32 import java.util.Hashtable;
33 import javax.swing.text.html.*;
34 import com.sun.star.uno.XComponentContext;
35 
36 import org.apache.commons.httpclient.*;
37 import org.apache.commons.httpclient.methods.*;
38 
39 
40 public class WikiArticle
41 {
42     private XComponentContext m_xContext;
43 
44     private String m_sEditTime = "";
45     private String m_sEditToken = "";
46 
47     protected String m_sHTMLCode;
48     private boolean m_bNoArticle = true;
49 
50     protected String m_sWikiUser;
51     protected String m_sWikiPass;
52 
53     protected String m_sTitle = "";
54 
55     private URI m_aMainURI;
56     private HostConfiguration m_aHostConfig;
57 
58 
59     /** Creates a new instance of WikiArticle */
60     public WikiArticle( XComponentContext xContext, String sTitle, Hashtable wikiSettings, boolean bLogin, WikiPropDialog aPropDialog )
61         throws java.net.MalformedURLException, com.sun.star.uno.Exception, java.io.IOException, WikiCancelException
62     {
63         m_xContext = xContext;
64 
65         String sMainUrl = (String) wikiSettings.get("Url");
66         m_sWikiUser = (String) wikiSettings.get("Username");
67         m_sWikiPass = (String) wikiSettings.get("Password");
68         m_sTitle = sTitle;
69 
70         m_aMainURI = new URI( sMainUrl );
71 
72 //         viewURL = sMainUrl + "index.php?title=" + m_sTitle;
73 //         editURL = sMainUrl + "index.php?title=" + m_sTitle + "&action=edit";
74 //         submitURL = sMainUrl + "index.php?title=" + m_sTitle + "&action=submit";
75 //         loginURL = sMainUrl + "index.php?title=Special:Userlogin";
76 //         loginSubmitURL = sMainUrl + "index.php?title=Special:Userlogin&action=submitlogin";
77 
78         if ( bLogin )
79         {
80             WikiEditSettingDialog aDialog = new WikiEditSettingDialog(m_xContext, "vnd.sun.star.script:WikiEditor.EditSetting?location=application", wikiSettings, false );
81             try
82             {
83                 while( !Login() )
84                 {
85                     if ( aPropDialog != null )
86                         aPropDialog.SetThrobberActive( false );
87 
88                     if ( MainThreadDialogExecutor.Show( xContext, aDialog ) )
89                     {
90                         m_sWikiUser = (String) wikiSettings.get("Username");
91                         m_sWikiPass = (String) wikiSettings.get("Password");
92                     }
93                     else
94                         throw new WikiCancelException();
95 
96                     if ( aPropDialog != null )
97                     {
98                         aPropDialog.SetThrobberActive( true );
99                         Thread.yield();
100                     }
101                 }
102             }
103             finally
104             {
105                 aDialog.DisposeDialog();
106             }
107         }
108 
109         // in case of loading the html contents are used
110         // in case of saving the contents should be checked whether they are empty
111         InitArticleHTML();
112 
113         // getArticleWiki();
114     }
115 
116     public String GetMainURL()
117     {
118         return m_aMainURI.toString();
119     }
120 
121     public String GetTitle()
122     {
123         return m_sTitle;
124     }
125 
126     public String GetViewURL()
127     {
128         return m_aMainURI.toString() + "index.php?title=" + m_sTitle;
129     }
130 
131     private String getArticleWiki()
132         throws com.sun.star.uno.Exception, java.io.IOException, WikiCancelException
133     {
134         String sWikiCode = null;
135 
136         if ( m_aHostConfig != null )
137         {
138             URI aURI = new URI( m_aMainURI.toString() + "index.php?title=" + m_sTitle + "&action=edit" );
139             GetMethod aRequest = new GetMethod( aURI.getEscapedPathQuery() );
140 
141             Helper.ExecuteMethod( aRequest, m_aHostConfig, aURI, m_xContext, false );
142 
143             int nResultCode = aRequest.getStatusCode();
144             String sWebPage = null;
145             if ( nResultCode == 200 )
146                 sWebPage = aRequest.getResponseBodyAsString();
147 
148             aRequest.releaseConnection();
149 
150             if ( sWebPage != null )
151             {
152                 StringReader r = new StringReader(sWebPage);
153                 HTMLEditorKit.Parser parse = Helper.GetHTMLParser();
154                 EditPageParser callback = new EditPageParser();
155 
156                 parse.parse(r,callback,true);
157                 m_sEditTime = callback.m_sEditTime;
158                 m_sEditToken = callback.m_sEditToken;
159 
160                 int iPosStart = callback.m_nWikiArticleStart;
161                 int iPosEnd = callback.m_nWikiArticleEnd;
162 
163                 if ( iPosStart >= 0 && iPosEnd > 0 )
164                 {
165                     String sArticle = sWebPage.substring(iPosStart, iPosEnd);
166                     iPosStart = sArticle.indexOf(">") + 1;
167                     sWikiCode = sArticle.substring( iPosStart, sArticle.length() );
168                 }
169             }
170         }
171 
172         return sWikiCode;
173     }
174 
175     private void InitArticleHTML()
176         throws com.sun.star.uno.Exception, java.io.IOException, WikiCancelException
177     {
178         if ( m_aHostConfig != null )
179         {
180             URI aURI = new URI( m_aMainURI.toString() + "index.php?title=" + m_sTitle );
181             GetMethod aRequest = new GetMethod( aURI.getEscapedPathQuery() );
182 
183             Helper.ExecuteMethod( aRequest, m_aHostConfig, aURI, m_xContext, false );
184 
185             int nResultCode = aRequest.getStatusCode();
186             String sWebPage = null;
187             if ( nResultCode == 200 )
188                 sWebPage = aRequest.getResponseBodyAsString();
189 
190             if ( sWebPage != null )
191             {
192                 StringReader r = new StringReader(sWebPage);
193                 HTMLEditorKit.Parser parse = Helper.GetHTMLParser();
194                 EditPageParser callback = new EditPageParser();
195 
196                 parse.parse(r,callback,true);
197 
198                 int iPosStart = callback.m_nHTMLArticleStart;
199                 int iPosEnd = callback.m_nHTMLArticleEnd;
200                 int nPosNoArt = callback.m_nNoArticleInd;
201 
202                 if ( iPosStart >= 0 && iPosEnd > 0 )
203                 {
204                     m_sHTMLCode = sWebPage.substring(iPosStart, iPosEnd);
205                     m_bNoArticle = ( nPosNoArt >= 0 && nPosNoArt >= iPosStart && nPosNoArt <= iPosEnd );
206                 }
207             }
208         }
209     }
210 
211     protected boolean setArticle( String sWikiCode, String sWikiComment, boolean bMinorEdit )
212         throws com.sun.star.uno.Exception, java.io.IOException, WikiCancelException
213     {
214         boolean bResult = false;
215 
216         if ( m_aHostConfig != null && sWikiCode != null && sWikiComment != null )
217         {
218             // get the edit time and token
219             getArticleWiki();
220 
221             URI aURI = new URI( m_aMainURI.getPath() + "index.php?title=" + m_sTitle + "&action=submit" );
222             PostMethod aPost = new PostMethod();
223             aPost.setPath( aURI.getEscapedPathQuery() );
224 
225             // aPost.addParameter( "title", m_sTitle );
226             // aPost.addParameter( "action", "submit" );
227             aPost.addParameter( "wpTextbox1", sWikiCode );
228             aPost.addParameter( "wpSummary", sWikiComment );
229             aPost.addParameter( "wpSection", "" );
230             aPost.addParameter( "wpEdittime", m_sEditTime );
231             aPost.addParameter( "wpSave", "Save page" );
232             aPost.addParameter( "wpEditToken", m_sEditToken );
233 
234             if ( bMinorEdit )
235                 aPost.addParameter( "wpMinoredit", "1" );
236 
237             Helper.ExecuteMethod( aPost, m_aHostConfig, aURI, m_xContext, false );
238 
239             int nResultCode = aPost.getStatusCode();
240             if ( nResultCode < 400 )
241                 bResult = true;
242 
243             String aResult = aPost.getResponseBodyAsString();
244 
245             // TODO: remove the debug printing, try to detect the error
246             System.out.print( "nSubmitCode = " + nResultCode + "\n===\n" + aResult );
247         }
248 
249         return bResult;
250     }
251 
252     protected boolean Login()
253         throws com.sun.star.uno.Exception, java.io.IOException, WikiCancelException
254     {
255         m_aHostConfig = Helper.Login( m_aMainURI, m_sWikiUser, m_sWikiPass, m_xContext );
256         return ( m_aHostConfig != null );
257     }
258 
259     protected void cleanHTML()
260     {
261         if ( m_sHTMLCode != null )
262         {
263             //Welcome to regex hell ;)
264 
265             //strip comments
266             m_sHTMLCode = m_sHTMLCode.replaceAll("\\<![ \\r\\n\\t]*(--([^\\-]|[\\r\\n]|-[^\\-])*--[ \\r\\n\\t]*)\\>","");
267 
268             //strip edit section links
269             m_sHTMLCode = m_sHTMLCode.replaceAll("\\<div class=\"editsection\".*?\\</div\\>","");
270 
271             //strip huge spaces
272             m_sHTMLCode = m_sHTMLCode.replaceAll("\\<p\\>\\<br /\\>[ \r\n\t]*?\\</p\\>","");
273 
274             //strip toc
275             m_sHTMLCode = m_sHTMLCode.replaceAll("\\<table.*id=\"toc\"(.|[\r\n])*?\\</table\\>","");
276 
277             //strip jump-to-nav
278             m_sHTMLCode = m_sHTMLCode.replaceAll("\\<div id=\"jump-to-nav\".*?\\</div\\>","");
279 
280             //strip Javascript
281             m_sHTMLCode = m_sHTMLCode.replaceAll("\\<script(.|[\r\n])*?\\</script\\>","");
282         }
283     }
284 
285 
286     protected boolean NotExist()
287     {
288         boolean bResult = true;
289         if ( m_sHTMLCode != null )
290             bResult = m_bNoArticle;
291 
292         return bResult;
293     }
294 
295 }
296