Java/Texclipse Plugin ... am I on the right track?

Dear all,

I only recently started to use zotero after Endnote did not fulfill my needs and manually editing .bib files isn't heaven either. My primary editor is Eclipse/Texlipse (originally a Java IDE [1]/[2]) and Word (to work with co-authors).

I dug around a bit and had an idea how to develop a integration with the Java based environment to facilitate citation management. My starting point was the word/oo plugin. From what I can deduct most of the functionality needed is already provided with the integration.js SOAP/XML interface. In the code below you can also see that I managed to get most of the functionality working from Java (excuse the messy code and thanks to [3] where i ripped of the SOAP code).

The question now is if this is the right way to tackle this problem (Texlipse/zotero integration) or is there another more straight forward way to communicate with zotero?

If this is the right way, then there is the other question how to reach a usable result. There are three possible ways I can see:

(a) Use the current zotero interface and process the information it provides in Java (i.e. translate all the response in tex code and build a new BibTex bibliography from scratch. - probably the most painful way and very vulnerable to API changes).

(b) Modify integration.js and try to reuse some of the code of the BibTex export feature. (Needs investigation and most likely a change/extension of the API but might be usful for the integration with other editors as well)

(c) Use the current setup. but add an additional generic citation style that provides latex citations (\cite{ref_if}) and an BibTex bibliography. (Maybe the easiest way, but I don't know if there are hidden problems?)

Does anyone have any suggestion?

MaS


[1] http://www.eclipse.org/
[2] http://texlipse.sourceforge.net/
[3] http://www.ibm.com/developerworks/xml/library/x-soapcl/

--- code ZoteroSOAPTest.java ---

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ZoteroSOAPTest {

public static String zoteroSOAPMessage(String method, String params) {
String msg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<SOAP-ENV:Envelope xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\" "+
"xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\" "+
"SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" "+
"xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<SOAP-ENV:Body>"+
"<m:"+method+" xmlns:m=\"http://www.zotero.org/namespaces/SOAP\">"+
"<input xsi:type=\"xsd:string\">"+params+"</input>" +
"</m:"+method+"></SOAP-ENV:Body></SOAP-ENV:Envelope>";
return msg;
}

public static String getZoteroSOAPResponseOutput(String SOAPUrl, String msg) throws Exception {

byte[] b = msg.getBytes();

// Create the connection where we're going to send the file.
URL url = new URL(SOAPUrl);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;

// Set the appropriate HTTP parameters.
httpConn.setRequestProperty( "Content-Length",
String.valueOf( b.length ) );
httpConn.setRequestProperty("Content-Type","text/xml; charset=utf-8");
httpConn.setRequestProperty("SOAPAction","");
httpConn.setRequestMethod( "POST" );
httpConn.setDoOutput(true);
httpConn.setDoInput(true);

// Everything's set up; send the XML that was read in to b.
OutputStream out = httpConn.getOutputStream();
out.write( b );
out.close();

// Read the response and write it to standard out.

InputStreamReader isr =
new InputStreamReader(httpConn.getInputStream());
BufferedReader in = new BufferedReader(isr);

String inputLine;
String result = "";

while ((inputLine = in.readLine()) != null)
{
System.out.println(inputLine);
result += inputLine;
}

in.close();

Pattern p = Pattern.compile("<output xmlns=\"http://purl.org/net/xbiblio/csl\">(.*?)</output>");
Matcher m = p.matcher(result);
String r = "";
if (m.find()) {
r = m.group(1);
}
System.out.println( "Return: " + r);
return r;
}


public static void main(String[] args) throws Exception {

String SOAPUrl = "http://127.0.0.1:50001/";

// init
String msg = zoteroSOAPMessage("init", "");
getZoteroSOAPResponseOutput(SOAPUrl, msg);

// setDocPrefs
msg = zoteroSOAPMessage("setDocPrefs", "!:0.1/5/JAVA");
getZoteroSOAPResponseOutput(SOAPUrl, msg);

// restoreSession
msg = zoteroSOAPMessage("restoreSession", "0.1/5/JAVA:!:http:://www.zotero.org/styles/apsa:0:0");
String session = getZoteroSOAPResponseOutput(SOAPUrl, msg);

// update
msg = zoteroSOAPMessage("update", session + ":http:://www.zotero.org/styles/apsa:in-text:N");
getZoteroSOAPResponseOutput(SOAPUrl, msg);

}


}
  • Nice work. Using the integration server may not be the easiest route, though, due to the challenges you outline.

    You might want to take a look at JSSh, a TCP/IP JavaScript Shell Server for Mozilla. You could use a Java telnet class to connect to Zotero, run some BibTeX export code directly using the JavaScript API, and return the result. I used it the other day to set up server-based CSL previewing for the styles page, using a copy of Firefox/Zotero running on one of our servers.

    Longer-term, it'd probably be helpful to be able to access export formats via the citation layer (as you suggested in (c)), but I don't think this is possible at the moment. We'll likely also offer a way for third-party apps to access the data layer similarly to JSSh in the future.
  • Thanks for the answer. I had a look at JSSh, that looks very promising but I don't really want to go down this path for the moment for two reasons. (a) As I understand it this requires additional software and that Firefox is started with special command line options. That does not sit well with an independent plugin as I understand it. And (b) I would like to work with the unmodified zotero for the moment, as my expertise is not in programming mozilla plugins. And if the API will change in the future anyway, I don't want to invest to much time.

    I gave option (c) another try and found it rather straight forward. I constructed a .csl file that produces (for the moment simplified) BibTex code. Then it is easy to call the integration server to retrieve the information about the reference and put that into the editor and an additional .bib file. The only issues are the BibTex keys as discussed elsewhere [1] and how to manage the the entries that are already in the document.

    I keep on going this way until somebody tells me to stop or until I have found a solution (or gave up).

    [1] http://forums.zotero.org/discussion/31/bibtex-export/#Item_32
  • Glad to hear you got something working. I only suggested JSSh as a way to access Zotero's native BibTeX generation code. If you don't mind generating the BibTeX yourself via CSL, that'd definitely be a more straightforward (and future-proof) approach.

    If there's a demand for accessing the various non-bibliography export formats via the integration server, I can create a ticket for it.
Sign In or Register to comment.