Java classes edit

The following classes would be useful for making a bot in java.

WikiSessionManager.java edit

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.net.URL;
import java.net.URLEncoder;
import java.net.URLConnection;

    /**
     * WikiSessionManager is a utility class that logs into the English
     * Wikipedia and facilitates making HTTP requests with cookies.
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 2 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     * 
     * @author Gracenotes
     * @version 0.1
     **/

public class WikiSessionManager
{
    private String cookie, sessionData, username;
    private boolean loggedIn;

    public WikiSessionManager()
    {
        this.loggedIn = false;
        this.sessionData = "";
        this.cookie = "";
    }

    public void userLogin(String username, char[] password) throws IOException
    {
        username = username.trim();
        if (username.length() == 0 || password.length == 0) throw new IllegalArgumentException("Blank parameter");

        URL url = new URL("http://en.wikipedia.org/w/api.php");
        URLConnection connection = url.openConnection();

        connection.setDoOutput(true);
        connection.setUseCaches(false);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

        OutputStreamWriter output = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
        
        String token = "login_"+System.currentTimeMillis();
        output.write("action=login" +
            "&lgname=" + URLEncoder.encode(username, "UTF-8") +
            "&lgpassword=" + URLEncoder.encode(new String(password).trim(), "UTF-8") +
            "&lgtoken=" + URLEncoder.encode(token, "UTF-8")
            );
        output.flush();
        output.close();
            
        Arrays.fill(password, ' ');

        // Send request and get code
        int code = connection.getResponseCode();
        if (code != HttpURLConnection.HTTP_OK)
                throw new IOException("HTTP error "+code+": "+connection.getResponseMessage());

        String headerName;
        StringBuffer receivedCookie = new StringBuffer();
        int i = 0;
        while ((headerName = connection.getHeaderFieldKey(i)) != null)
        {
            if (headerName != null && headerName.equalsIgnoreCase("Set-Cookie"))
            {
                if (receivedCookie.length()>0) receivedCookie.append("; ");
                receivedCookie.append(connection.getHeaderField(i).split(";")[0]);
            }
            i++;
        }
        this.cookie = receivedCookie.toString();
        this.loggedIn = this.cookie.contains("Token=");
        this.username = this.loggedIn ? username : null;
     }

    public void userLogout() throws IOException
    {
        if (!this.loggedIn)
            return;
        URL url = new URL("http://en.wikipedia.org/w/index.php?title=Special:Userlogout");
        URLConnection connection = url.openConnection();
        this.addCookies(connection);
        connection.connect();
        
        this.loggedIn = false;
        this.cookie = "";
        this.sessionData = "";
    }

    /**
     * Indicates whether a user is logged in or not
     * 
     * @return A boolean showing whether a user is logged in or not
     */
    public boolean isLoggedIn()
    {
        return this.loggedIn;
    }

    public void addCookies(URLConnection connection)
    {
        if (!this.loggedIn)
            return;
        connection.setRequestProperty("Cookie", this.cookie +
                                      (this.sessionData != null ? "; " + this.sessionData : ""));
        connection.setRequestProperty("User-Agent", this.username);
    }

    public boolean findSessionData(URLConnection connection)
    {
        sessionData = "";
        String headerName;
        int i = 0;
        while ((headerName = connection.getHeaderFieldKey(++i)) != null)
        {
            if (headerName.equals("Set-Cookie") && connection.getHeaderField(i).contains("_session"))
                this.sessionData = connection.getHeaderField(i).split(";")[0];
        }
        
        return this.sessionData.length() != 0;
    }
}

WikiEdit edit

import java.io.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.net.URL;
import java.net.URLEncoder;
import java.net.URLConnection;

    /**
     * WikiEdit is a class that depends on WikiSessionManager. It gets wikitext
     * of articles and edits them
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 2 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     * 
     * @author Gracenotes
     * @version 0.1
     **/

public class WikiEdit
{
    private WikiSessionManager session;
    private boolean maxlagDo; //TODO: implement MaxLag stuff
    private int maxlagLimit, maxlagTime;

    public WikiEdit(WikiSessionManager session) throws IOException
    {
        this.session = session;
        this.maxlagDo = false;
        this.maxlagLimit = 0;
        this.maxlagTime = 5;
    }

    public boolean isLoggedIn()
    {
        return session.isLoggedIn();    
    }

    public String getWikitext(String page) throws IOException
    {
        URL url = new URL("http://en.wikipedia.org/w/api.php?titles=" + URLEncoder.encode(page, "UTF-8") +
                          "&action=query&prop=revisions&rvprop=content&format=xml");
                          
        URLConnection connection = url.openConnection();
        session.addCookies(connection);
        
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        StringBuffer responseText = new StringBuffer();
        String line;   
        while ((line = reader.readLine()) != null)
        {
            responseText.append(line + "\n");
        }
        line = responseText.toString();
        int pos = line.indexOf("<rev>");
        if (pos == -1)
            line = null;
        else
            line = line.substring(pos + 5, line.lastIndexOf("</rev>")).replace("&lt;", "<").replace("&gt;", ">").replace("&quot;", "\"").replace("&apos;", "'").replace("&amp;", "&");
        reader.close();
        return line;
    }
    
    public void editPage(String page, String wikitext, String editsum, boolean minor) throws IOException
    {
        if (!this.isLoggedIn())
        {
           System.err.println("Not logged in.");
           return;
        }
        
        String pageURL = "http://en.wikipedia.org/w/index.php?title=" + URLEncoder.encode(page, "UTF-8");
        URL url = new URL(pageURL + "&action=edit");
        URLConnection connection = url.openConnection();
        session.addCookies(connection);
        connection.connect();
        session.findSessionData(connection);
       
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        StringBuffer textToSend = new StringBuffer();
        String line;
        Pattern pattern = Pattern.compile("<input type='hidden' value=\"(.*?)\" name=\"(.*?)\" />");
        while ((line = reader.readLine()) != null)
        {
            if (line.contains("<input type='hidden'"))
            {
                Matcher matcher = pattern.matcher(line);
                matcher.find();
                String name = matcher.group(2);
                String value = matcher.group(1);
                if (name.equals("wpStarttime"))
                    textToSend.append("&wpStarttime=" + value);
                if (name.equals("wpEdittime"))
                    textToSend.append("&wpEdittime=" + value);
                if (name.equals("wpEditToken"))
                    textToSend.append("&wpEditToken=" + URLEncoder.encode(value, "UTF-8"));
            }
        }
        reader.close();
      
        textToSend.append("&wpTextbox1=" + URLEncoder.encode(wikitext, "UTF-8"));
        textToSend.append("&wpSummary=" + URLEncoder.encode(editsum, "UTF-8"));
        if (minor)
            textToSend.append("&wpMinoredit=0");
        textToSend.deleteCharAt(0);
        
        //now, send the data

        url = new URL(pageURL + "&action=submit");
        connection = url.openConnection();
        
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);      
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        session.addCookies(connection);

        OutputStreamWriter output = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
        output.write(textToSend.toString());
        output.flush();
        output.close();

        BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        line = input.readLine();

   /*   StringBuffer responseText = new StringBuffer();
        
        while ((line = input.readLine()) != null)
        {
            responseText.append(line + "\n");
        }
        //this code can be used to read the response
   */
    }
}

WikiEditTest edit

import java.net.*;
import java.io.*;

public class WikiEditTest
{
    public static void main() throws IOException
    {
        WikiSessionManager sessionMgr = new WikiSessionManager();
        sessionMgr.userLogin("Gracenotes", "password".toCharArray());
        WikiEdit edit = new WikiEdit(sessionMgr);
        if (!edit.isLoggedIn())
        {
            System.out.println("Not logged in");
            return;
        }
        edit.editPage("User:Gracenotes/Sandbox", edit.getWikitext("User:Gracenotes/Sandbox") + "\nAddendum", "minor test edit", true);
    }
}

The above code would result in this.