/* Copyright (C) 2003-2011 JabRef contributors.
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package net.sf.jabref.remote;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.Vector;
import net.sf.jabref.Globals;
import net.sf.jabref.JabRef;
import net.sf.jabref.imports.ParserResult;
import javax.swing.*;
public class RemoteListener extends Thread {
private JabRef jabref;
private ServerSocket socket;
private boolean active = true, toStop = false;
private static final String IDENTIFIER = "jabref";
public RemoteListener(JabRef jabref, ServerSocket socket) {
this.jabref = jabref;
this.socket = socket;
}
public void disable() {
toStop = true;
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (active) {
try {
Socket newSocket = socket.accept();
newSocket.setSoTimeout(1000);
if (toStop) {
active = false;
return;
}
OutputStream out = newSocket.getOutputStream();
InputStream in = newSocket.getInputStream();
out.write(IDENTIFIER.getBytes());
out.write('\0');
out.flush();
int c;
StringBuffer sb = new StringBuffer();
try {
while (((c = in.read()) != '\0') && (c >= 0)) {
sb.append((char)c);
}
if (sb.length() == 0) {
continue;
}
String[] args = sb.toString().split("\n");
Vector<ParserResult> loaded = jabref.processArguments(args, false);
// put "bringToFront" in the queue
// it has to happen before the call to import as the import might open a dialog
// --> Globals.prefs.getBoolean("useImportInspectionDialog")
// this dialog has to be shown AFTER JabRef has been brought to front
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JabRef.jrf.showIfMinimizedToSysTray();
}
});
for (int i=0; i<loaded.size(); i++) {
ParserResult pr = loaded.elementAt(i);
JabRef.jrf.addParserResult(pr, (i==0));
}
in.close();
out.close();
newSocket.close();
} catch (SocketTimeoutException ex) {
//System.out.println("timeout");
in.close();
out.close();
newSocket.close();
}
} catch (SocketException ex) {
active = false;
//ex.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static RemoteListener openRemoteListener(JabRef jabref) {
try {
ServerSocket socket = new ServerSocket(Globals.prefs.getInt("remoteServerPort"), 1,
InetAddress.getByAddress(new byte[] {127, 0, 0, 1}));
RemoteListener listener = new RemoteListener(jabref, socket);
return listener;
} catch (IOException e) {
if (!e.getMessage().startsWith("Address already in use"))
e.printStackTrace();
return null;
}
}
/**
* Attempt to send command line arguments to already running JabRef instance.
* @param args Command line arguments.
* @return true if successful, false otherwise.
*/
public static boolean sendToActiveJabRefInstance(String[] args) {
try {
InetAddress local = InetAddress.getByName("localhost");
Socket socket = new Socket(local, Globals.prefs.getInt("remoteServerPort"));
socket.setSoTimeout(2000);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
int c;
StringBuffer sb = new StringBuffer();
try {
while (((c = in.read()) != '\0') && (c >= 0)) {
sb.append((char)c);
}
} catch (SocketTimeoutException ex) {
System.out.println("Connection timed out.");
}
if (!IDENTIFIER.equals(sb.toString())) {
String port = String.valueOf(Globals.prefs.getInt("remoteServerPort"));
String error = Globals.lang("Cannot use port %0 for remote operation; another application may be using it. Try specifying another port.", port);
System.out.println(error);
return false;
}
for (int i=0; i<args.length; i++) {
byte[] bytes = args[i].getBytes();
out.write(bytes);
out.write('\n');
}
out.write('\0');
out.flush();
in.close();
out.close();
socket.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}