//----------------------------BEGIN LICENSE----------------------------
/*
* Willow : the Open Source WorkFlow Project
* Distributable under GNU LGPL license by gun.org
*
* Copyright (C) 2004-2010 huihoo.org
* Copyright (C) 2004-2010 ZosaTapo <dertyang@hotmail.com>
*
* ====================================================================
* Project Homepage : http://www.huihoo.org/willow
* Source Forge : http://sourceforge.net/projects/huihoo
* Mailing list : willow@lists.sourceforge.net
*/
//----------------------------END LICENSE-----------------------------
package org.huihoo.willow.client;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.rmi.MarshalledObject;
import java.rmi.RemoteException;
import java.util.Hashtable;
import javax.naming.NamingException;
import javax.naming.ServiceUnavailableException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.huihoo.willow.Globals;
import org.huihoo.workflow.WorkflowException;
import org.huihoo.workflow.client.SerialClient;
import org.huihoo.workflow.client.WorkflowClient;
import org.huihoo.workflow.client.serial.model.SerialService;
/**
* @author reic
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class SerialClientImpl implements SerialClient, java.io.Serializable
{
private static Log log = LogFactory.getLog(SerialClientImpl.class);
protected ServiceContext serviceContext;
protected Hashtable env;
protected String sessionID;
//-----------------------------------------------------------constructor
public SerialClientImpl(Hashtable environment) throws WorkflowException, NamingException
{
init(environment);
}
//------------------------------------------------------------public
public String getSessionID() throws WorkflowException
{
return sessionID;
}
public int getMaxInactiveInterval() throws WorkflowException
{
try
{
return serviceContext.getMaxInactiveInterval(sessionID);
}
catch (RemoteException ex)
{
ex.printStackTrace();
throw new WorkflowException(ex);
}
}
public void setMaxInactiveInterval(int interval) throws WorkflowException
{
try
{
serviceContext.setMaxInactiveInterval(sessionID, interval);
}
catch (RemoteException ex)
{
ex.printStackTrace();
throw new WorkflowException(ex);
}
}
public void keepAlive() throws WorkflowException
{
try
{
serviceContext.keepAlive(sessionID);
}
catch (RemoteException ex)
{
ex.printStackTrace();
throw new WorkflowException(ex);
}
}
public SerialService findService(String serviceName) throws WorkflowException
{
try
{
SerialService workflow = null;
if (serviceContext != null)
{
workflow = serviceContext.findService(serviceName, sessionID);
if (workflow != null)
{
return workflow;
}
}
}
catch (Exception ex)
{
throw new WorkflowException(ex);
}
return null;
}
public SerialService[] findServices() throws WorkflowException
{
SerialService[] services = new SerialService[0];
try
{
if (serviceContext != null)
{
services = serviceContext.findServices(sessionID);
}
}
catch (Exception ex)
{
throw new WorkflowException(ex);
}
return services;
}
public void disconnect() throws WorkflowException
{
try
{
serviceContext.disconnect(sessionID);
}
catch (RemoteException ex)
{
throw new WorkflowException(ex);
}
}
//------------------------------------------------------------
private void init(Hashtable refEnv) throws WorkflowException, NamingException
{
if (refEnv == null)
{
refEnv = new Hashtable();
}
this.env = (Hashtable) refEnv.clone();
String host = "localhost";
int port = 2126;
// Locate naming service
String provider_url = (String) refEnv.get(WorkflowClient.PROVIDER_URL);
if (provider_url != null && provider_url.length() > 0)
{
String serverInfo = parseServerInfo(provider_url);
if (serverInfo != null)
{
int colon = serverInfo.indexOf(':');
if (colon < 0)
{
host = serverInfo;
}
else
{
host = serverInfo.substring(0, colon).trim();
try
{
port = Integer.parseInt(serverInfo.substring(colon + 1).trim());
}
catch (Exception ex)
{
// Use default;
}
}
} //~end if (provider_url != null && provider_url.length() > 0)
try
{
// Get server from connection
serviceContext = getServer(host, port, refEnv);
String username = (String) env.get(WorkflowClient.SECURITY_PRINCIPAL);
String password = (String) env.get(WorkflowClient.SECURITY_CREDENTIALS);
this.sessionID = serviceContext.authenticate(username, password);
}
catch (Throwable ex)
{
log.warn("Failed to get service context " + host + ":" + port, ex);
serviceContext = null;
throw new WorkflowException(ex);
}
}
}
static ServiceContext getServer(String host, int port, Hashtable env) throws WorkflowException
{
String hostKey = host + ":" + port;
ServiceContext server = null;
try
{
Socket socket = null;
try
{
InetAddress localAddr = null;
int localPort = 0;
String localAddrStr = (String) env.get(WorkflowClient.LOCAL_BINDING_ADDRESS);
String localPortStr = (String) env.get(WorkflowClient.LOCAL_BINDING_PORT);
if (localAddrStr != null)
{
localAddr = InetAddress.getByName(localAddrStr);
}
if (localPortStr != null)
{
localPort = Integer.parseInt(localPortStr);
}
socket = new Socket(host, port, localAddr, localPort);
}
catch (IOException e)
{
NamingException ex = new ServiceUnavailableException("Failed to connect to service context" + hostKey);
ex.setRootCause(e);
throw ex;
}
// Get stub from naming server
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
ObjectInputStream in = new ObjectInputStream(bis);
MarshalledObject stub = (MarshalledObject) in.readObject();
server = (ServiceContext) stub.get();
socket.close();
return server;
}
catch (Exception ex)
{
throw new WorkflowException(ex);
}
}
static String parseServerInfo(String provider_url)
{
String serverInfo = null;
if (provider_url != null && provider_url.length() > 0)
{
int schemeLength = 0;
String schemePrefix = Globals.PROTOCOL_WORKFLOW_LIVE + ":";
if (provider_url.startsWith(schemePrefix))
{
schemeLength = schemePrefix.length();
}
if (schemeLength > 0)
{
serverInfo = provider_url.substring(schemeLength);
if (serverInfo != null && serverInfo.length() > 0)
{
while (serverInfo.charAt(0) == '/')
{
if (serverInfo.length() == 1)
{
serverInfo = null;
break;
}
serverInfo = serverInfo.substring(1);
}
if (serverInfo != null && serverInfo.length() > 0)
{
int pos = serverInfo.indexOf("/");
if (pos > 0)
{
serverInfo = serverInfo.substring(0, pos);
}
}
}
}
}
return serverInfo;
}
}