// ServiceCallerModel.java
//
// Created: February 2006
//
// This file is a component of the BioMoby project.
// Copyright Martin Senger (martin.senger@gmail.com).
//

package org.biomoby.service.dashboard;

import org.biomoby.shared.MobyException;
import org.biomoby.shared.MobyService;
import org.biomoby.shared.parser.MobyPackage;
import org.biomoby.shared.parser.MobyJob;
import org.biomoby.client.ExtendedProtocolClient;
import org.biomoby.client.MobyServiceLocator;
import org.biomoby.client.ExtendedServiceLocator;
import org.biomoby.service.dashboard.data.DataContainer;

import org.tulsoft.shared.UUtils;

/**
 * A model that achieves its task by calling (local, remote, or none)
 * Biomoby service. It delegates the task of calling a service to a
 * true Biomoby client (that extends <tt>BaseClient</tt>). <p>
 *
 * @author <A HREF="mailto:martin.senger@gmail.com">Martin Senger</A>
 * @version $Id: ServiceCallerModel.java,v 1.8 2008/12/03 15:21:13 groscurt Exp $
 */

public class ServiceCallerModel
    extends AbstractModel {

//    private static org.apache.commons.logging.Log log =
//       org.apache.commons.logging.LogFactory.getLog (ServiceCallerModel.class);

    /**************************************************************************
     * Call a service. This is the main purpose of this model. <p>
     *
     * @param data contains input data and this method replaces them
     * by result data
     *************************************************************************/
    public void runIt (DataContainer data)
	throws MobyException {
	SimpleClient worker = new SimpleClient (data);
	worker.process();
    }
    
    /**************************************************************************
     *
     * A real client - the main worker for this model..
     *
     *************************************************************************/
    protected class SimpleClient
	extends ExtendedProtocolClient {

	DataContainer data;

	/**************************************************************************
	 * Constructor.
	 *************************************************************************/
	public SimpleClient (DataContainer data) {
	    super();
	    this.data = data;
	}

	/**************************************************************************
	 * What service to call and where to find it.
	 *************************************************************************/
	public MobyServiceLocator getServiceLocator()
	    throws MobyException {
	    return new MyServiceLocator();
	}

	/**************************************************************************
	 * Not used here...
	 *************************************************************************/
	public boolean fillRequest (MobyJob request, MobyPackage inputContext)
	    throws MobyException {
	    return true;
	}

	/**************************************************************************
	 * Not used here...
	 *************************************************************************/
	public boolean useResponse (MobyJob response,
				    MobyPackage responseContext)
	    throws MobyException {
	    return true;
	}

	/**************************************************************************
	 * Return input XML (from a data container obtained in the
	 * constructor).
	 *************************************************************************/
	public String fillRequest()
	    throws MobyException {

	    if (data == null)
		throw new MobyException ("No input data given.");

	    return (String)data.getData();
	}

	/**************************************************************************
	 *
	 *************************************************************************/
	public boolean useResponse (String xmlResponse)
	    throws MobyException {

	    data.setData (xmlResponse);

	    // do nothing more if it is just an input echo
	    if ( ((ExtendedServiceLocator)getServiceLocator()).isLoop())
		return false;

	    return false;
	}
    }

    /**************************************************************************
     *
     * A service locator filled from the property channel.
     *
     *************************************************************************/
    protected class MyServiceLocator
	extends ExtendedServiceLocator {

	public MyServiceLocator()
	    throws MobyException {
	    super();

	    // fill this locator by a service
	    MobyService selService = (MobyService)propertyChannel.get (DP_SC_SERVICE);
	    if (selService == null)
		throw new MobyException ("No service given.");
	    MobyService clonedService = new MobyService (selService.getName(), selService.getAuthority());
	    clonedService.setURL (selService.getURL());
	    setService (clonedService);

	    // fill how to call this service
	    String howToCall = propertyChannel.getString (DP_CALL_SERVICE);
	    if (DP_CS_NEWURL.equals (howToCall)) {
		String sEndpoint = propertyChannel.getString (DP_ENDPOINT);
		if (! UUtils.isEmpty (sEndpoint))
		    clonedService.setURL (sEndpoint);

	    } else if (DP_CS_REGISTRY.equals (howToCall)) {
		clonedService.setURL (null);
		setRegistryEndpoint (propertyChannel.getString (DP_REGISTRY_ENDPOINT));
		setRegistryNamespace (propertyChannel.getString (DP_REGISTRY_NAMESPACE));

	    } else if (DP_CS_CLASS.equals (howToCall)) {
		String localClass = propertyChannel.getString (DP_IMPL_CLASS);
		if (UUtils.isEmpty (localClass))
		    throw new MobyException ("No local class given.");
		setLocalClass (localClass);

	    } else if (DP_CS_NONE.equals (howToCall)) {
		setLoop (true);
	    } 

	    setAsBytes (propertyChannel.getBoolean (DP_INP_ASBYTES, false));
	    
	    // sets the user and the password
	    // the getString method returns an empty string in case the
	    // key is not in the propertychannel, therefore the test if
	    // the value is not empty
	    String user = propertyChannel.getString(DP_USER_AUTHENTICATION);
	    if(user.length() > 0) {
	        setUser( user );
	    }
	    String password = propertyChannel.getString(DP_PASSWORD_AUTHENTICATION);
	    if(password.length() > 0) {
	        setPassword( password );
	    }
	}
    }

}
