package org.eparapher.rcp.tools;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import org.apache.log4j.Logger;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.jface.action.Action;
import org.eclipse.ui.progress.UIJob;
import org.eparapher.core.encryption.CMSEncryption;
import org.eparapher.rcp.ApplicationWorkbenchAdvisor;
import org.eparapher.rcp.EPReferences;
import org.eparapher.rcp.actions.CMSDecryptionAction;
import org.eparapher.rcp.actions.CMSEncryptionAction;
import org.eparapher.rcp.actions.CMSSignDocumentAction;
import org.eparapher.rcp.actions.ToPDFAndSignDocumentAction;
import org.eparapher.rcp.actions.XMLSignDocumentAction;
/**
* RCPSingleton manage :
*
* - A single instance of eParapher
* - start the wizards if it's started with the following command line options:
*
* - eParapher -CMSSignature file1 file2 ...
* - eParapher -PDFSignature file1 file2 ...
* - eParapher -XMLDSigSignature file1 file2 ...
*
*
*
* @author arnault
*
*/
public class RCPSingleton implements Runnable {
private static Logger log = Logger.getLogger(RCPSingleton.class);
private static String SINGLE_INSTANCE_SHARED_KEY = "1E4RFCS";
Integer port;
private Thread serverThread;
private ServerSocket server;
private boolean alreadystarted;
private String[] cmdline_args;
public String[] getCmdline_args() {
return cmdline_args;
}
public void setCmdline_args(String[] cmdlineArgs) {
cmdline_args = cmdlineArgs;
}
public RCPSingleton(IApplicationContext context, ApplicationWorkbenchAdvisor madvisor) {
super();
//TODO : set the TCP port elsewhere (parameter)
port=35768;
cmdline_args = (String[]) context.getArguments().get(IApplicationContext.APPLICATION_ARGS);
for (String cmd : cmdline_args) {
log.debug("Argument for command line : "+cmd);
}
if (!checkServerPort()) {
try {
alreadystarted = false;
server = new ServerSocket(port,50, InetAddress.getByName("localhost"));
serverThread = new Thread( this );
serverThread.start();
log.info("eParapher Socket for RCP Singleton managment started on "+InetAddress.getByName("localhost")+" TCP/" + port);
} catch (IOException ex) {
ex.printStackTrace();
log.error("eParapher Socket for RCP Singleton managment could not start on localhost TCP/" + port, ex);
}
} else {
try {
alreadystarted = true;
log.info("Contacting the main instance and send parameters");
Socket clientSocket = new Socket("127.0.0.1", port);
OutputStream out = clientSocket.getOutputStream();
String message = ""+SINGLE_INSTANCE_SHARED_KEY;
for (String cmd : cmdline_args) {
message+="\r\n" + cmd;
}
out.write(message.getBytes());
out.close();
clientSocket.close();
} catch (UnknownHostException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
EPReferences.getInstance().setRcpsingleton(this);
}
public boolean isAlreadystarted() {
return alreadystarted;
}
/** Thread of the main instance that will receive information
* from other
*/
public void run() {
boolean socketClosed = false;
while (!socketClosed) {
if (server.isClosed()) {
socketClosed = true;
} else {
try {
Socket client = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String message = "",line;
boolean sharedkeyOK = false;
while ((line=in.readLine())!=null) {
if ( message.equals("") && SINGLE_INSTANCE_SHARED_KEY.trim().equals(line.trim())) {
sharedkeyOK = true;
} else {
if (message.equals(""))
message +=line;
else
message += "\r\n" + line;
}
}
if (sharedkeyOK) {
log.info("Receiving message from another startup : "+message.replaceAll("\\r\\n","|")+"");
new RiseeParapherGUI("Sending parameters to main eParapher instance...",message).schedule();
} else {
log.debug("Receiving garbage data on local socket (" + message.getBytes().length + " bytes)");
}
in.close();
client.close();
} catch (IOException ex) {
socketClosed = false;
}
}
}
}
private boolean checkServerPort() {
try {
new Socket("localhost", port);
} catch (IOException ex) {
return false;
}
return true;
}
/**
* This method is called when
* @param args list of the commands from the comand line
*/
public void executeCommandsFromCommandLine(String[] args) {
Action action = null;
boolean wizard = false;
if (args == null && ( cmdline_args == null || cmdline_args.length ==0 ))
return;
if (args == null && cmdline_args != null) {
args = cmdline_args;
wizard = true;
}
for (String arg : args) {
if (arg.equalsIgnoreCase("--wizard")) {
wizard = true;
}
}
if (args[0].equals("-CMSSignature"))
action = new CMSSignDocumentAction(args,wizard);
else if (args[0].equals("-PDFSignature"))
action = new ToPDFAndSignDocumentAction(args,wizard);
else if (args[0].equals("-XMLDSigSignature"))
action = new XMLSignDocumentAction(args,wizard);
if (args[0].equals("-CMSEncrypt"))
action = new CMSEncryptionAction(args,wizard);
if (args[0].equals("-CMSDencrypt"))
action = new CMSDecryptionAction(args,wizard);
// TODO : implement encryption+signature
//if (args[0].equals("-CMSEncryptAndSign"))
// action = new CMSEncryptAndSignAction(files,wizard);
//if (args[0].equals("-CMSDecryptAndVerify"))
// action = new CMSDecryptAndVerifyAction(files,wizard);
if (action != null ) {
log.info("Executing in main thread : "+args.toString());
action.run();
if (!wizard) {
EPReferences.getInstance().getAppadvisor().getTrayIcon().setTooltipMessage("Job from command line launched");
}
} else {
log.info("Binary parameters does not correspond to a valid action");
//if (args.length==0 || (args.length==1&&args[0].equals("")) )
EPReferences.getInstance().getAppadvisor().getTrayIcon().setTooltipMessage("eParapher is already running!");
}
}
private class RiseeParapherGUI extends UIJob {
private String message;
public RiseeParapherGUI(String name, String mmessage) {
super(name);
message = mmessage;
}
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
monitor.beginTask("Starting Wizard", 1);
EPReferences.getInstance().getAppadvisor().handleEvent(null,message);
monitor.done();
return Status.OK_STATUS;
}
}
}