package com.ibm.able.examples.ableagent;

//====================================================================
//
// Licensed Materials - Property of IBM
//
// "Restricted Materials of IBM"
//
// Product: com.ibm.able.examples.ableagent
//
// (C) Copyright IBM Corp. 2000 All Rights Reserved.
//
// US Government Users Restricted Rights - Use, duplication or
// disclosure restricted by GSA ADP Schedule Contract with
// IBM Corp.
//
//
//                             DISCLAIMER
//                             ----------
//
// This material contains programming source code for your consideration.
// These examples have not been thoroughly tested under all conditions.
// IBM, therefore, cannot guarantee or imply reliability, serviceability,
// performance or function of these programs.  All programs contained
// herein are provided to you "AS IS".  THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
// DISCLAIMED.
//
//====================================================================

//====================================================================
// Imports
//====================================================================
import java.rmi.RemoteException;
import java.util.Iterator;
import java.util.Vector;

import com.ibm.able.Able;
import com.ibm.able.AbleBean;
import com.ibm.able.AbleDataSource;
import com.ibm.able.AbleDefaultAgent;
import com.ibm.able.AbleObject;

/**
 * This class illustrates the use of a serialized agent.  The agent is
 * reserialized, and data is passed and retrieved using data buffers.
 */ 
public class AppDataBuffer {
   	
  	                                       
   public static void main(String[] args) {
   	 try {
   	 	// agent to be restored
   	 	String serAgent = "%able.home%/examples/neural/animal.ser";
   	    if (args != null && args.length > 0) serAgent = args[0];

   	 	// must know the structure of that agent's inputbuffer to use it this way
   	 	// note agents can have a double[] buffer if all its values are numeric
        String[][] data  = new String[][]{
        	{"no","no","no","mammal","black","4","50000","uTellME!"},
        };
        String[] input  = null;
        String[] output = null; 
   	    
        // restore the agent 
        AbleDefaultAgent agent = (AbleDefaultAgent)AbleObject.restoreFromSerializedFile(serAgent);
        agent = insureDataBufferMode(agent);  // do a little bulletproofing

        // prove we're not cheating by showing the current values
   	  Able.setTraceConsoleHandlerLevel(Able.TRC_LOW);
        Able.TraceLog.text(Able.TRC_LOW,"Input  current: " + displayBuffer(agent.getInputBufferAsStringArray()));
        Able.TraceLog.text(Able.TRC_LOW,"Output current: " + displayBuffer(agent.getOutputBufferAsStringArray()));
        
        // pass the agent data and get the result
        output = (String[])agent.process(input = data[0]);
        
        // show the input that was passed and the result obtained
        Able.TraceLog.text(Able.TRC_LOW,"Input  result: " + displayBuffer(input));
        Able.TraceLog.text(Able.TRC_LOW,"Output result: " + displayBuffer(output));     

        Able.setTraceConsoleHandlerLevel(Able.TRC_NONE);

   	 } catch (Exception exp) {
       System.out.println(exp);
       exp.printStackTrace();
   	 }
     System.exit(0);
  }

    

  /**
   * The method <i>insureDataBufferMode</i> is a helper to generically accomodate 
   * some things that may be overlooked when an agent is serialized. 
   * <ol>
   *   <li>Serializing the container agent rather than exporting the agent that is
   *       developed.  This results in a container agent that contains only one 
   *       agent.  Hence an unnecessary layer is formed, and unnecessary processing
   *       is performed to copy between the container and the true agent's databuffers.
   *       This is though handled without additional code.  This method looks in the
   *       reserialized container and if it contains only one agent, it sheds the
   *       outer container.
   *   <li>Since the agent in deployed state will be using databuffers in this case,
   *       the agent itself must have dataflow enabled.
   *   <li>All datasources in the agent must have dataflow disabled so that they are
   *       not processed.  This would cause the agent's inputBuffer to be ignored.
   * </ol>
   * None of these actions are necessary if you are sure of your agent's configuration
   * when you serialize it!
   */
   private static AbleDefaultAgent insureDataBufferMode(AbleDefaultAgent theAgent) throws RemoteException, Exception {
      Vector beans = theAgent.getBeans();
      // often people just save agents instead of exporting them 
      // this is just to make sure we lose an unnecessary outer layer if its necessary
      AbleDefaultAgent result = null;
      if (beans.size() == 1 && beans.elementAt(0) instanceof AbleDefaultAgent) {
      	result = (AbleDefaultAgent)beans.elementAt(0);
      } else {
      	result = theAgent;
      }
      result.setDataFlowEnabled(true);
      // often folks will save an agent with import beans on
      // we want the agent's buffer to provide the data and do not wish to process imports
      // so turn dataflow off on any datasources in the bean to catch the lazy
      Iterator beanList = result.getBeans().iterator();
      while (beanList.hasNext()) {
      	AbleBean bean = (AbleBean)beanList.next();
      	if (bean instanceof AbleDataSource) 
      	  bean.setDataFlowEnabled(false);
      }
      return result;
   }
   
   private static String displayBuffer(Object[] buf) {
      StringBuffer buffer = new StringBuffer("");
      if (buf == null) {
      	buffer.append(buf);
      } else {
        for (int i = 0; i < buf.length; i++) buffer.append(buf[i] + " ");
      }
      return buffer.toString();
   }
   
   private static String displayBuffer(double[] buf) {
      StringBuffer buffer = new StringBuffer("");
      if (buf == null) {
      	buffer.append(buf);
      } else {
        for (int i = 0; i < buf.length; i++) buffer.append(buf[i] + " ");
      }
      return buffer.toString();
   }

}

