blob: 501898bd844d50580a3afbaa522cbd65cea4ef55 [file] [log] [blame]
/**
* Created by IntelliJ IDEA.
* User: brendan
* Date: Apr 5, 2006
* Time: 4:32:57 PM
* To change this template use File | Settings | File Templates.
*/
package com.atlassian.uwc.ui.xmlrpcwrapperOld;
import com.atlassian.uwc.ui.ConfluenceSettingsForm;
import com.atlassian.uwc.ui.FileUtils;
import com.atlassian.uwc.ui.UWCForm2;
import com.atlassian.uwc.ui.UWCUserSettings;
import org.apache.log4j.Logger;
import org.apache.xmlrpc.XmlRpcClient;
import org.apache.xmlrpc.XmlRpcException;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.util.Date;
import java.util.Vector;
/**
* The RemoteWikiBrokerOld will handle the the step of sending
* or receiving remote objects to and from Confluence via XMLRPC.
* <p/>
* XMLRPC is proving to be the most stable means of communicating remotely
* with Confluence at this time. 2006-04
* <p/>
* This class will also have some utility methods for managing the life cycle
* of the remote objects.
* <p/>
* If we ever decide to explore an alternative way of moving remote objects to
* and from Confluence we'll want to extract an interface from this...we probably
* should anyway but one thing at a time :)
*/
public class RemoteWikiBrokerOld {
Logger log = Logger.getLogger("RemoteWikiBrokerOld");
/**
* singleton stuff - generated by IDEA
*/
private static RemoteWikiBrokerOld ourInstance = new RemoteWikiBrokerOld();
private XmlRpcClient clientConnection = null;
private String loginToken = null;
private long lastLoginTimeStamp = 0;
/**
* tracks whether a new login is required
*/
boolean reloginNeeded = false;
public void needNewLogin() {
reloginNeeded = true;
}
/**
* singleton stuff - generated by IDEA
*/
public static RemoteWikiBrokerOld getInstance() {
return ourInstance;
}
/**
* singleton stuff - generated by IDEA
*/
private RemoteWikiBrokerOld() {
}
/**
* Creates a local page metadata object which can then be sent
* to Confluence with a 'store' method
*
* @param title
* @param content
* @return
* @see PageForXmlRpcOld
*/
public PageForXmlRpcOld createPage(String title, String content) {
PageForXmlRpcOld page = new PageForXmlRpcOld();
page.setTitle(title);
page.setContent(content);
return page;
}
/**
* calls storeNewOrUpdatePage(PageForXmlRpcOld page, String space) using space
* currently stored in the settings form
*
* @param page
* @return
*/
public PageForXmlRpcOld storeNewOrUpdatePage(PageForXmlRpcOld page) {
ConfluenceSettingsForm confSettings = UWCForm2.getInstance().getConfluenceSettingsForm();
String space = confSettings.getSpaceName();
PageForXmlRpcOld resultPage;
resultPage = storeNewOrUpdatePage(page, space);
return resultPage;
}
/**
* A convenience method to get the pageId from Confluence with only a space
* name and a page title.
*
* @param space
* @param pageTitle
* @return
*/
public String getPageIdFromConfluence(String space, String pageTitle) {
PageForXmlRpcOld page = populatePageXmlRpcData(space, pageTitle);
return page.getId();
}
/**
* populate all the data in a PageForXmlRpcOld from the minimum parameters
*
* @param space the space name
* @param pageTitle the title of the page
* @return a populated PageForXmlRpcOld object or an empty object if the page does not exist
*/
public PageForXmlRpcOld populatePageXmlRpcData(String space, String pageTitle) {
PageForXmlRpcOld page = new PageForXmlRpcOld();
Vector<Serializable> paramsVector = new Vector<Serializable>();
loginToken = getLoginToken();
paramsVector.add(loginToken);
paramsVector.add(space);
paramsVector.add(pageTitle);
XmlRpcClient client = getXMLRPCClient();
try {
page.setPageParams(client.execute("confluence1.getPage", paramsVector));
} catch (XmlRpcException e) {
// page may already exist
log.info("could not retrieve infor for page space:title - " + space + ":" + pageTitle);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return page;
}
/**
* @param page
* @return
*/
public PageForXmlRpcOld storeNewOrUpdatePage(PageForXmlRpcOld page, String space) {
// get a handle to the XMLRPC client obj, this method should be called
// to manage the connection and make sure it's live even though there
// is a class var. This is actually called here for coding clarity.
XmlRpcClient client = getXMLRPCClient();
// make sure loginToken is up to date
String loginToken = getLoginToken();
Vector<Serializable> paramsVector = new Vector<Serializable>();
// add the login token
paramsVector.add(loginToken);
// add the page ---------------------
page.setSpace(space);
paramsVector.add(page.getPageParams());
PageForXmlRpcOld resultPage = new PageForXmlRpcOld();
// write the page ---------------------
try {
resultPage.setPageParams(client.execute("confluence1.storePage", paramsVector));
return resultPage;
} catch (XmlRpcException e) {
if (e.getMessage().contains("already exists")) {
log.info("This page already exists, now updating - space:title - " + space + ":" + page.getTitle());
} else {
// Some other error occurred
log.error("Error while adding page " + page.getTitle(), e);
}
} catch (IOException e) {
log.error("Error while adding page " + page.getTitle(), e);
}
// page may already exist, get more info on page ---------------------
resultPage = populatePageXmlRpcData(space, page.getTitle());
if (page.getContent() == null || "".equals(page.getContent())) {
// Do not overwrite existing pages with empty ones.
return resultPage;
}
// write the page ---------------------
loginToken = getLoginToken();
paramsVector = new Vector<Serializable>();
// add the login token
paramsVector.add(loginToken);
page.setSpace(space);
resultPage.setContent(page.getContent());
paramsVector.add(resultPage.getPageParams());
// write the page
try {
resultPage.setPageParams(client.execute("confluence1.storePage", paramsVector));
} catch (XmlRpcException e) {
log.error("Failed to update page " + page.getTitle(), e);
} catch (IOException e) {
log.error("Failed to update page " + page.getTitle(), e);
}
return resultPage;
}
/**
* get the login token for the XmlRpc call.
* Reuse the existing one or acquire a new one from the server if needed.
* Confluence server login token is set as valid for 30 min. by default
*
* @return
*/
private String getLoginToken() {
// check login token
long currentTimeStamp = (new Date()).getTime();
// if 25 minutes has not passed since login
// check last retrieval time
if (Math.abs(currentTimeStamp - lastLoginTimeStamp) > 1500000) {
reloginNeeded = true;
}
// return the token if it's still valid
if (loginToken != null && !reloginNeeded)
return loginToken;
ConfluenceSettingsForm confSettings = UWCForm2.getInstance().getConfluenceSettingsForm();
String login = confSettings.getLogin();
String password = confSettings.getPassword();
String spaceName = confSettings.getSpaceName();
String url = confSettings.getUrl();
Vector<String> loginParams = new Vector<String>(2);
loginParams.add(login);
loginParams.add(password);
XmlRpcClient client = getXMLRPCClient();
try {
loginToken = (String) client.execute("confluence1.login", loginParams);
} catch (XmlRpcException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
reloginNeeded = false;
return loginToken;
}
/**
* manage and hand back the XMLRPC client connection
*/
protected XmlRpcClient getXMLRPCClient() {
//old way of doing it (with a form)
ConfluenceSettingsForm confSettings = UWCForm2.getInstance().getConfluenceSettingsForm();
return getXMLRPCClient(
confSettings.getLogin(),
confSettings.getPassword(),
confSettings.getSpaceName(),
confSettings.getUrl()
);
}
protected XmlRpcClient getXMLRPCClient(
UWCUserSettings settings) {
return getXMLRPCClient(
settings.getLogin(),
settings.getPassword(),
settings.getSpace(),
settings.getUrl());
}
protected XmlRpcClient getXMLRPCClient(
String login, String password, String space, String url) {
//
if (clientConnection != null) {
return clientConnection;
}
// retrieve the correct URL
// String login = confSettings.getLogin();
// String password = confSettings.getPassword();
// String spaceName = confSettings.getSpaceName();
// String url = confSettings.getUrl();
String connectionURL;
if (url.startsWith("http://")) {
connectionURL = url + "/rpc/xmlrpc";
} else {
connectionURL = "http://" + url + "/rpc/xmlrpc";
}
try {
clientConnection = new XmlRpcClient(connectionURL);
} catch (MalformedURLException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return clientConnection;
}
/**
* Only write this new page if an existing one with the same name
* doesn't already exist.
*
* @param page
* @return
*/
public PageForXmlRpcOld safeStoreNewPage(PageForXmlRpcOld page) {
return null;
}
/**
* @param pageId
* @param attachment
* @return
* @todo -
*/
public AttachmentForXmlRpcOld storeAttachment(String pageId, AttachmentForXmlRpcOld attachment) throws IOException, XmlRpcException {
Vector<Serializable> paramsVector = new Vector<Serializable>();
loginToken = getLoginToken();
paramsVector.add(loginToken);
paramsVector.add(pageId);
paramsVector.add(attachment.getPageParams());
File file = new File(attachment.getFileLocation());
byte fileBytes[] = FileUtils.getBytesFromFile(file);
paramsVector.add(fileBytes);
XmlRpcClient client = getXMLRPCClient();
attachment.setPageParams(client.execute("confluence1.addAttachment", paramsVector));
log.info("attachment written " + attachment.getFileName());
return attachment;
}
}