/**********************************************************************
 *
 * corbaproto.cpp -- 
 * Copyright (C) 2000 The New Zealand Digital Library Project
 *
 * A component of the Greenstone digital library software
 * from the New Zealand Digital Library Project at the
 * University of Waikato, New Zealand.
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: corbaproto.mpp 25231 2012-03-16 08:38:01Z ak19 $
 *
 *********************************************************************/

#define USE_POA

#include <iostream>
#include <fstream>

#include "fileutil.h"

// protocol headers for CORBA
#include "corbaiface.h"
using namespace gsdlInterface;

// greenstone library headers
#include "corbaconv_text_t.h"

// greenstone local headers
#include "corbatext_t.h"

#include "corbaproto.h"
#include "colservrconfig.h"

// default headers
#include <assert.h>

void corbatext_optionValueArrayToCorba(OptionValue_tarray array, corbaOptionValue_array &corba)
{
  unsigned int i = 0;
  OptionValue_tarray::iterator here = array.begin();
  OptionValue_tarray::iterator end = array.end();
  
  while (here != end)
    {
      corba.length(i+1);
      
      corbaconv_text_t::getCorbatext(here->name,corba[i].name);
      corbaconv_text_t::getCorbatext(here->value,corba[i].value);

      i ++;
      here ++;
    }
  //  std::cout << "Options " << i << std::endl;
}

void corbaresponse_resultMetadataToCorba(MetadataInfo_t &meta, corbaMetadataInfo &corbaMeta)
{
  corbaconv_text_t::getCorbatext(meta.params,corbaMeta.params);
  corbatext_arrayToCorbaArray(meta.values, &corbaMeta.values);
  corbaMeta.isRef    = meta.isRef;
}

void corbaresponse_resultMetadataToC(const corbaMetadataInfo &corbaMeta, MetadataInfo_t &meta)
{
  corbaconv_text_t::setCorbatext(meta.params,corbaMeta.params);
  corbatext_corbaArrayToArray(corbaMeta.values, &meta.values);
  meta.isRef    = corbaMeta.isRef;
}

int corbaresponse_resultMetaParentToCorba(MetadataInfo_t *parent, corbaMetadataInfo_array &corbaparent)
{
  int reply = -1, pid = -1;

  // extend for new parent
  reply = corbaparent.length();
  corbaparent.length(reply+1);

  // copy content into new array element
  corbaresponse_resultMetadataToCorba(*parent, corbaparent[reply]);

  // deal with our own parent
  if (parent->parent != NULL)
    {
      // get offset of new parent and extend parent vector

      pid  = corbaresponse_resultMetaParentToCorba(parent->parent, corbaparent);
    }
  corbaparent[reply].parentid = pid;

  // return the parent id from here
  return reply;
}

MetadataInfo_t *corbaresponse_resultMetaParentToC(corbaMetadataInfo_array &corbaparent, int pid)
{
  MetadataInfo_t *reply;

  reply = new MetadataInfo_t;

  corbaresponse_resultMetadataToC(corbaparent[pid], *reply);

  // deal with our own parent
  if (corbaparent[pid].parentid >= 0)
    {
      // get offset of new parent and extend parent vector

      reply->parent = corbaresponse_resultMetaParentToC(corbaparent, corbaparent[pid].parentid);
    }
  else
    {
      reply->parent = NULL;
    }

  // return the parent id from here
  return reply;
}

void corbaresponse_resultDocInfoToCorba(ResultDocInfo_tarray docinfo, corbaResultDocInfo_array &corbainfo)
{
  ResultDocInfo_tarray::iterator here = docinfo.begin();
  ResultDocInfo_tarray::iterator end  = docinfo.end();
  unsigned int i;

  i = 0;
  while (here != end)
    {
      corbainfo.length(i+1);

      // copy the easy bits
      corbaconv_text_t::getCorbatext(here->OID,corbainfo[i].OID);

      corbainfo[i].resultNum     = here->result_num;
      corbainfo[i].ranking       = here->ranking;
      corbainfo[i].termsMatched  = here->num_terms_matched;
      corbainfo[i].phraseMatched = here->num_phrase_match;

      // copy the docFreq array
      vector<int>::iterator fhere = here->docFreq.begin();
      vector<int>::iterator fend  = here->docFreq.end();
      unsigned int          fi = 0;

      while (fhere != fend)
	{
	  corbainfo[i].docFreq.length(fi+1);

	  corbainfo[i].docFreq[fi] = *fhere;

	  fhere ++;
	  fi ++;
	}

      // copy the MetadataInfo map
      MetadataInfo_tmap::iterator mhere = here->metadata.begin();
      MetadataInfo_tmap::iterator mend  = here->metadata.end();
      unsigned int mi = 0;

      while (mhere != mend)
	{
	  corbainfo[i].metadata.names.length(mi+1);
	  corbainfo[i].metadata.values.length(mi+1);
	  
	  // copy name
	  corbaconv_text_t::getCorbatext((*mhere).first,corbainfo[i].metadata.names[mi]);

	  // copy metadata
	  corbaresponse_resultMetadataToCorba((*mhere).second, corbainfo[i].metadata.values[mi]);
	  if (mhere->second.parent != NULL)
	    {
	      int pid;

	      pid = corbaresponse_resultMetaParentToCorba(mhere->second.parent, 
							      corbainfo[i].metaparents);
	      corbainfo[i].metadata.values[mi].parentid = pid;
	    }
	  else
	    {
	      corbainfo[i].metadata.values[mi].parentid = -1;
	    }

	  std::cout << "Parent " << mi << " " << (off_t) &mhere->second << " " << (off_t) mhere->second.parent << std::endl;

	  mhere ++;
	  mi ++;
	}

      // Copy the classifier variables
      corbaconv_text_t::getCorbatext(here->classifier_metadata_type, corbainfo[i].classifierMetadataType);
      corbainfo[i].classifierMetadataOffset = here->classifier_metadata_offset;

      // Get next Docinfo item
      i++;
      here ++;
    }
}

void corbaresponse_resultDocInfoToC(corbaResultDocInfo_array corbainfo, ResultDocInfo_tarray &docinfo)
{
  unsigned int i;
  ResultDocInfo_t doc;

  for (i = 0; i < corbainfo.length(); i++)
    {
      corbaconv_text_t::setCorbatext(doc.OID,corbainfo[i].OID);
      doc.result_num        = corbainfo[i].resultNum;
      doc.ranking           = corbainfo[i].ranking;
      doc.num_terms_matched = corbainfo[i].termsMatched;
      doc.num_phrase_match  = corbainfo[i].phraseMatched;

      // copy the doc freq array
      unsigned int fi;
      for (fi = 0; fi < corbainfo[i].docFreq.length(); fi ++)
	{
	  doc.docFreq.push_back(corbainfo[i].docFreq[fi]);
	}

      // copy the MetadataInfomap
      unsigned int   mi;
      text_t         mname;
      MetadataInfo_t mdata;
      
      doc.metadata.clear();
      for (mi = 0; mi < corbainfo[i].metadata.names.length(); mi ++)
	{
	  // get name
	  corbaconv_text_t::setCorbatext(mname,corbainfo[i].metadata.names[mi]);

	  // get metadata
	  corbaresponse_resultMetadataToC(corbainfo[i].metadata.values[mi], mdata);

	  if (corbainfo[i].metadata.values[mi].parentid >= 0)
	    {
	      mdata.parent = 
		corbaresponse_resultMetaParentToC(corbainfo[i].metaparents, 
						  corbainfo[i].metadata.values[mi].parentid);	      
	    }
	 
	  doc.metadata.insert(make_pair(mname, mdata));
	}

      // GRB: sort out parent data
      for (mi = 0; mi < corbainfo[i].metadata.names.length(); mi ++)
	{
	  if (corbainfo[i].metadata.values[mi].parentid != 0)
	    { 
	      int pi;

	      for (pi = 0; pi < corbainfo[i].metadata.names.length(); pi ++)
		{
		  if (pi != mi &&
		      corbainfo[i].metadata.values[mi].parentid ==
		      corbainfo[i].metadata.values[pi].id)
		    {
		      doc.metadata[mi].parent = &doc.metadata[pi];
		    }
		}
	    }
	}
      //      doc.metadata

      // convert metadata classifer information
      corbaconv_text_t::setCorbatext(doc.classifier_metadata_type,corbainfo[i].classifierMetadataType);
      doc.classifier_metadata_offset = corbainfo[i].classifierMetadataOffset;

      docinfo.push_back(doc); 
    }
}


// Added 31/1/2001, Michael Dewsnip
void corbaresponse_resultTermInfoToC(corbaTermInfo_array corbainfo, TermInfo_tarray &terminfo)
{
  TermInfo_t ti;

  for (unsigned int i = 0; i < corbainfo.length(); i++) {
    corbaconv_text_t::setCorbatext(ti.term, corbainfo[i].term);
    ti.freq = corbainfo[i].frequency;

    for (unsigned int j = 0; j < corbainfo[i].matchTerms.length(); j++) {
      text_t mt;
      corbaconv_text_t::setCorbatext(mt, corbainfo[i].matchTerms[j]);

      ti.matchTerms.push_back(mt);
    }

    terminfo.push_back(ti);
  }
}


corbaproto::corbaproto(char* _site_name)
{ char *dummyv[1] = {""};
  int   dummyc = 0;
  // CORBA variables
  /* static CORBA::ORB_var orb = CORBA::ORB_init( dummyc , dummyv, "mico-local-orb" );
     static CORBA::BOA_var boa = orb->BOA_init( dummyc , dummyv, "mico-local-boa" ); */

  CORBA::ORB_var orb = CORBA::ORB_init( dummyc , dummyv, "mico-local-orb" );

#if defined(USE_POA)
    CORBA::Object_var poaobj = orb->resolve_initial_references ("RootPOA");
    PortableServer::POA_var poa = PortableServer::POA::_narrow (poaobj);
    poa->the_POAManager()->activate();
#else
    CORBA::BOA_var boa = orb->BOA_init( dummyc , dummyv, "mico-local-boa" );
#endif

  char objid_filename[256];
  sprintf(objid_filename,"/tmp/%s.objid",_site_name);

  // Get ref from "naming service"
  ifstream in (objid_filename);
  char ref[1000];
  in >> ref;
  in.close ();

  // startup corba
  // static CORBA::Object_var obj = orb->string_to_object (ref);
  CORBA::Object_var obj = orb->string_to_object (ref);

  client = corbaiface::_narrow( obj ); 
  // client = NULL; // ****

  gsdlhome.clear();
  site_name = _site_name;
}

corbaiface_var corbaproto::getCorbaClient()
{
  // This function was written to help corba when ORB and BOA were
  // not working in "persistent" mode.
  // Now that persistent mode is working it is not longer needed/used.

  char *dummyv[1] = {""};
  int   dummyc = 0;
  // CORBA variables
//  static CORBA::ORB_var orb = CORBA::ORB_init( dummyc , dummyv, "mico-local-orb" );
//  static CORBA::BOA_var boa = orb->BOA_init( dummyc , dummyv, "mico-local-boa" );

  // DB // Try this out!! // ****
  CORBA::ORB_var orb = CORBA::ORB_init( dummyc , dummyv, "mico-local-orb" );

#if defined(USE_POA)
    CORBA::Object_var poaobj = orb->resolve_initial_references ("RootPOA");
    PortableServer::POA_var poa = PortableServer::POA::_narrow (poaobj);

    poa->the_POAManager()->activate();
#else
    CORBA::BOA_var boa = orb->BOA_init( dummyc , dummyv, "mico-local-boa" );
#endif

  /*  char* site_name_chars = site_name.getcstr();
  char objid_filename[256];
  sprintf(objid_filename,"/tmp/%s.objid",site_name_chars);
  // delete site_name_chars; */

  text_t objid_filename = "/tmp/" + site_name + ".objid";

  // Get ref from "naming service"
  ifstream in (objid_filename.getcstr());
  char ref[1000];
  in >> ref;
  in.close ();

  // startup corba
  // DB // Try this out!! // ****
  // static CORBA::Object_var obj = orb->string_to_object (ref);
  CORBA::Object_var obj = orb->string_to_object (ref);

  return corbaiface::_narrow( obj );
}


// this configure will configure each of the collection servers
void corbaproto::configure (const text_t &key, const text_tarray &cfgline,
			    comerror_t &err) {
  // the naming of the collection should not be done here,
  // it should be done just after the collection server has been 
  // created

  // std::cout << "Corbaproto::Configure" << std::endl;
  corbatext_t      corbaKey;
  corbatext_tarray corbaCfgline;
  gsdlInterface::corbaComError error = corbaNoError;

  // get the corba client reference
  // corbaiface_var lclient = this->getCorbaClient(); // ****
  corbaiface_var lclient = client;

  // convert all the requisite structures into their CORBA form
  corbaconv_text_t::getCorbatext(key,corbaKey);
  corbatext_arrayToCorbaArray(cfgline, &corbaCfgline);

  // execute the corba transaction
  lclient->configure(corbaKey, corbaCfgline, error);    

  if (key=="gsdlhome")
    {
      // store gsdlhome in corba prototype so it can be used later to
      // check if icons specified in format statements exist on the
      // recptionist's side
      gsdlhome = cfgline[0];
    }
  err = (comerror_t) error;
}

// this init will configure and init each of the collection servers
bool corbaproto::init (comerror_t &err, ostream &logout) {
//  std::cout << "Corbaproto::Init" << std::endl;
  gsdlInterface::corbaComError error = corbaNoError;

  // get the corba client reference
  // corbaiface_var lclient = this->getCorbaClient(); // ****
  corbaiface_var lclient = client;

  // execute the corba transaction
  return lclient->initialise(error);
}

void  corbaproto::cache_missing_icons(text_tmap& format_map,
				      text_t& httpdomain, 
				      text_t& httpprefix)
{
  // consider making this a member function in the object?

  text_tmap::iterator format_here = format_map.begin();
  text_tmap::iterator format_end = format_map.end();
  while (format_here!=format_end)
    {
      text_t format_line = format_here->second;

      // std::cout << "*** format line = " << format_line << std::endl; // ****

      text_t::iterator fl_begin = format_line.begin();
      text_t::iterator fl_end = format_line.end();

      text_t::iterator httpimg_find = findword(fl_begin,fl_end,"_httpimg_");
      text_t::iterator http_find = httpimg_find;

      while (httpimg_find!=fl_end)
	{
	  http_find = httpimg_find+5;
	  httpimg_find += 9;

	  // look for white space " or >
	  text_t::iterator filename_end = httpimg_find;
	  while (filename_end != fl_end)
	    {
	      if (*filename_end == ' ') break;
	      if (*filename_end == '\t') break;
	      if (*filename_end == '\"') break;
	      if (*filename_end == '>') break;
	      filename_end++;
	    }

	  text_t img_filename = substr(httpimg_find,filename_end);

	  text_t site_img_filename = filename_cat(gsdlhome,"images",img_filename);

	  // look to see if img filename exists in images directory
	  if (!file_exists(site_img_filename))
	    {
	      text_t cache_img_dir
		= filename_cat(gsdlhome,"images",".cache");

	      text_t remote_img_url = "http://" + httpdomain + httpprefix
		+ "/images" + img_filename;

	      text_t wget_cmd = "wget -q -N --directory-prefix="+cache_img_dir
		+ " " + remote_img_url;

	      char* wget_cmd_chars = wget_cmd.getcstr();

	      system(wget_cmd_chars);
	      delete wget_cmd_chars;

	      format_map[format_here->first] 
		= substr(fl_begin,http_find) + "cache" + substr(http_find,fl_end);

	    }

	  httpimg_find = findword(httpimg_find,fl_end,"_httpimg_");
	}
      format_here++;
    }
}

text_t corbaproto::get_site_name (comerror_t &err) {
  return site_name;
}

text_t corbaproto::get_protocol_name (comerror_t &err) {
  return "corbaproto";
}


void corbaproto::get_collection_list (text_tarray &collist, comerror_t &err, 
				     ostream &/*logout*/) {

  // std::cout << "Corbaproto::Collection list" << std::endl;

  corbatext_tarray corba_collist;
  text_tarray      tcollist;
  gsdlInterface::corbaComError error = corbaNoError;

  // get the corba client reference
  // corbaiface_var lclient = this->getCorbaClient(); // ****
  corbaiface_var lclient = client;

  // execute the corba transaction
  lclient->collectionList(corba_collist,error);

  // convert the response back to normal form
  corbatext_corbaArrayToArray(corba_collist, &tcollist);
  collist = tcollist;

  err = (comerror_t) error;
}

void corbaproto::has_collection (const text_t &collection, bool &hascollection, 
				comerror_t &err, ostream &/*logout*/) {
  // std::cout << "Corbaproto::Has collection" << std::endl;

  corbatext_t     corbaCollection;
  corbaComError corbaError = corbaNoError;
  CORBA::Boolean corbaHas;

  // get the corba client reference
  // corbaiface_var lclient = this->getCorbaClient(); // ****
  corbaiface_var lclient = client;

  // convert all the requisite structures into their CORBA form
  corbaconv_text_t::getCorbatext(collection,corbaCollection);
  
  // execute the corba transaction
  lclient->hasCollection(corbaCollection, corbaHas, corbaError);

  // convert the response back to normal form
  hascollection = (corbaHas != 0);
  err = noError;
}

void corbaproto::ping (const text_t &collection, bool &wassuccess, 
		      comerror_t &err, ostream &/*logout*/) {
  // std::cout << "Corbaproto::Ping" << std::endl;

  corbatext_t corbaCollect;
  corbaComError corbaError = corbaNoError;
  CORBA::Boolean success;

  // get the corba client reference
  // corbaiface_var lclient = this->getCorbaClient(); // ****
  corbaiface_var lclient = client;

  // convert all the requisite structures into their CORBA form
  corbaconv_text_t::getCorbatext(collection,corbaCollect);

  // execute the corba transaction
  lclient->ping(corbaCollect, success, corbaError);
  
  // convert the response back to normal form
  wassuccess = (success != 0);
  err = (comerror_t) corbaError;  
  std::cout << "Corbaproto::Ping" << err << std::endl;
}


void corbaproto::get_collectinfo (const text_t &collection, 
				 ColInfoResponse_t &collectinfo,
				 comerror_t &err, ostream &logout) {
  //  std::cout << "Corbaproto::Collectinfo" << std::endl;

  corbatext_t          corbaCollection;
  corbaComError        corbaError = corbaNoError;
  corbaColInfoResponse corbaCollectInfo;

  // get the corba client reference
  // corbaiface_var lclient = this->getCorbaClient(); // ****
  corbaiface_var lclient = client;

  // convert all the requisite structures into their CORBA form
  corbaconv_text_t::getCorbatext(collection,corbaCollection);

  // execute the corba transaction
  lclient->getCollectInfo(corbaCollection, corbaCollectInfo, corbaError);

  // convert the response back to normal form
  collectinfo.useBook = corbaCollectInfo.useBook;
  collectinfo.isPublic = corbaCollectInfo.isPublic;
  collectinfo.isBeta   = corbaCollectInfo.isBeta;
  collectinfo.buildDate = corbaCollectInfo.buildDate;
  corbatext_corbaArrayToArray(corbaCollectInfo.ccsCols, &collectinfo.ccsCols);
  corbatext_corbaArrayToArray(corbaCollectInfo.languages, &collectinfo.languages);
  collectinfo.numDocs   = corbaCollectInfo.numDocs;
  collectinfo.numWords  = corbaCollectInfo.numWords;
  collectinfo.numBytes  = corbaCollectInfo.numBytes;
  corbatext_corbaColmetamapToColmetamap(corbaCollectInfo.collectionMeta, collectinfo.collectionmeta);
  corbatext_corbaMapToMap(corbaCollectInfo.format, collectinfo.format);
  corbatext_corbaMapToMap(corbaCollectInfo.building, collectinfo.building);
  corbaconv_text_t::setCorbatext(collectinfo.httpdomain,corbaCollectInfo.httpdomain);
  corbaconv_text_t::setCorbatext(collectinfo.httpprefix,corbaCollectInfo.httpprefix);
  corbaconv_text_t::setCorbatext(collectinfo.receptionist,corbaCollectInfo.receptionist);

  // Member variables in comtools mirrored in corbaiface (and corbaproto) on 14/03/2012.
  // shortInfo (previously mistyped as "shoftInfo" in corbaiface.idl) has 3 simple fields
  corbaconv_text_t::setCorbatext(collectinfo.shortInfo.name, corbaCollectInfo.shortInfo.name);
  corbaconv_text_t::setCorbatext(collectinfo.shortInfo.host, corbaCollectInfo.shortInfo.host);
  collectinfo.shortInfo.port = corbaCollectInfo.shortInfo.response;
  
  collectinfo.isSegmented = corbaCollectInfo.isSegmented;
  collectinfo.isCollectGroup = corbaCollectInfo.isCollectGroup;

  collectinfo.numSections = corbaCollectInfo.numSections;
  collectinfo.ccsOptions = corbaCollectInfo.ccsOptions;
  collectinfo.stemIndexes = corbaCollectInfo.stemIndexes;

  corbatext_corbaColmetamapToColmetamap(corbaCollectInfo.collection_macros, collectinfo.collection_macros);

  corbaconv_text_t::setCorbatext(collectinfo.buildType,corbaCollectInfo.buildType);
  corbaconv_text_t::setCorbatext(collectinfo.infodbType,corbaCollectInfo.infodbType);
  corbaconv_text_t::setCorbatext(collectinfo.authenticate,corbaCollectInfo.authenticate);
  corbaconv_text_t::setCorbatext(collectinfo.auth_group,corbaCollectInfo.auth_group);
  corbaconv_text_t::setCorbatext(collectinfo.earliestDatestamp,corbaCollectInfo.earliestDatestamp);

  corbatext_corbaMapToMap(corbaCollectInfo.public_documents, collectinfo.public_documents);
  corbatext_corbaMapToMap(corbaCollectInfo.private_documents, collectinfo.private_documents);
  corbatext_corbaMapToMap(corbaCollectInfo.dynamic_classifiers, collectinfo.dynamic_classifiers);


  cache_missing_icons(collectinfo.format,collectinfo.httpdomain,
		      collectinfo.httpprefix);

  err = (comerror_t) corbaError;  
}


void corbaproto::get_filterinfo (const text_t &collection,
				InfoFiltersResponse_t &response,
				comerror_t &err, ostream &logout) {
  //  std::cout << "Corbaproto::Filterinfo" << std::endl;

  corbatext_t corbaCollection;
  corbatext_tset corbaResponse;
  corbaComError corbaError = corbaNoError;
  
  // get the corba client reference
  // corbaiface_var lclient = this->getCorbaClient(); // ****
  corbaiface_var lclient = client;

  // convert all the requisite structures into their CORBA form
  corbaconv_text_t::getCorbatext(collection,corbaCollection);

  // execute the corba transaction
  lclient->getFilterInfo(corbaCollection, corbaResponse, corbaError);

  // convert the response back to normal form
  corbatext_corbaArrayToSet(corbaResponse, &response.filterNames);

  err = (comerror_t) corbaError;
}

void corbaproto::get_filteroptions (const text_t &collection,
				   const InfoFilterOptionsRequest_t &request,
				   InfoFilterOptionsResponse_t &response, 
				   comerror_t &err, ostream &logout) {
  //  std::cout << "Corbaproto::Filteroptions" << std::endl;

  corbatext_t corbaCollection;
  corbatext_t filterName;
  corbaFilterOptionsResponse corbaResponse;
  corbaComError corbaError = corbaNoError;
  unsigned int i;
  corbaconv_text_t *cc_name;
  FilterOption_t *option;

  // get the corba client reference
  // corbaiface_var lclient = this->getCorbaClient(); // ****
  corbaiface_var lclient = client;

  // convert all the requisite structures into their CORBA form
  corbaconv_text_t::getCorbatext(collection,corbaCollection);
  corbaconv_text_t::getCorbatext(request.filterName,filterName);

  // execute the corba transaction
  lclient->getFilterOptions(corbaCollection, filterName, corbaResponse, corbaError);

  // convert the response back to normal form
  for (i = 0; i < corbaResponse.names.length(); i ++)
    {
      cc_name = new corbaconv_text_t(corbaResponse.names[i]);

      option = new FilterOption_t;
      corbaconv_text_t::setCorbatext(option->name,corbaResponse.options[i].name);
      option->type = (FilterOption_t::type_t) corbaResponse.options[i].type;
      option->repeatable = (FilterOption_t::repeatable_t) corbaResponse.options[i].repeatable;
      corbaconv_text_t::setCorbatext(option->defaultValue,corbaResponse.options[i].defaultValue);
      corbatext_corbaArrayToArray(corbaResponse.options[i].validValues, &option->validValues);

      response.filterOptions.insert(make_pair(*cc_name, *option)); // typecast to text_t
    }

  err =  (comerror_t) corbaError;
}

// returns the contents of a collection's rss-items.rdf file (generated by BasePlugout)
void corbaproto::get_rss_items (const text_t &collection, 
				const text_t &gsdlhome, 
				text_t &rss_items, 
				comerror_t &err, 
				ostream &logout) {

  corbatext_t     corbaCollection;
  corbatext_t     corbaGsdlHome;
  corbatext_t     corbaRssItems;
  corbaComError   corbaError = corbaNoError;

  // convert all the requisite structures into their CORBA form
  corbaconv_text_t::getCorbatext(collection,corbaCollection);
  corbaconv_text_t::getCorbatext(gsdlhome,corbaGsdlHome);

  // get the corba client reference
  // corbaiface_var lclient = this->getCorbaClient(); // ****
  corbaiface_var lclient = client;

  // execute the corba transaction
  lclient->getRssItems (corbaCollection, corbaGsdlHome, corbaRssItems, corbaError);

  err =  (comerror_t) corbaError;

  // convert the response back to normal form
  corbaconv_text_t::setCorbatext(rss_items,corbaRssItems);
}

void corbaproto::filter (const text_t &collection,
			  FilterRequest_t &request,
			  FilterResponse_t &response,
			  comerror_t &err, ostream &logout) {
  //  std::cout << "Corbaproto::Filter" << std::endl;

  corbaFilterRequest corbaRequest;
  corbaFilterResponse corbaResponse;
  corbatext_t     corbaCollection;
  corbaComError corbaError = corbaNoError;

  // get the corba client reference
  // corbaiface_var lclient = this->getCorbaClient(); // ****
  corbaiface_var lclient = client;

  // convert all the requisite structures into their CORBA form
  corbaconv_text_t::getCorbatext(collection,corbaCollection);
  corbaconv_text_t::getCorbatext(request.filterName,corbaRequest.filter);
  corbatext_optionValueArrayToCorba(request.filterOptions, corbaRequest.filterOptions);
  corbatext_arrayToCorbaArray(request.docSet, &corbaRequest.docSet);
  corbaRequest.filterResultOptions = request.filterResultOptions;
  corbaconv_text_t::getCorbatext(request.requestParams,corbaRequest.requestParams);
  corbaconv_text_t::getCorbatext(request.refParams,corbaRequest.refParams);
  corbaRequest.getParents = request.getParents;
  corbatext_setToCorbaArray(request.fields, &corbaRequest.fields);

  corbaResponse.numDocs = response.numDocs;
  corbaresponse_resultDocInfoToCorba(response.docInfo, corbaResponse.docInfo);

  // execute the corba transaction
  lclient->filter (corbaCollection, corbaRequest, corbaResponse, corbaError);

  // convert the response back to normal form
  response.numDocs = corbaResponse.numDocs;
  response.isApprox = (enum isapprox) corbaResponse.isApprox;
  corbaresponse_resultDocInfoToC(corbaResponse.docInfo, response.docInfo);

  // Added 31/1/2001, Michael Dewsnip
  corbaresponse_resultTermInfoToC(corbaResponse.termInfo, response.termInfo);

  err = (comerror_t) corbaError;
  //  std::cout << "Corbaproto::Filter" << std::endl;
}


void corbaproto::get_document (const text_t &collection,
			       const DocumentRequest_t &request,
			       DocumentResponse_t &response,
			       comerror_t &err, ostream &logout) {
  //  std::cout << "Corbaproto::Get Document" << std::endl;

  corbatext_t      corbaCollect;
  corbaDocRequest  corbaRequest;
  corbaDocResponse corbaResponse;
  corbaComError    corbaError = corbaNoError;

  // get the corba client reference
  // corbaiface_var lclient = this->getCorbaClient(); // ****
  corbaiface_var lclient = client;

  // convert all the requisite structures into their CORBA form
  corbaconv_text_t::getCorbatext(collection,corbaCollect);
  corbaconv_text_t::getCorbatext(request.OID,corbaRequest.OID);
  corbaconv_text_t::getCorbatext(request.docType,corbaRequest.docType);
  corbaconv_text_t::getCorbatext(request.docFormat,corbaRequest.docFormat);

  // execute the corba transaction
  lclient->getDocument(corbaCollect, corbaRequest, corbaResponse, corbaError);

  // convert the response back to normal form
  corbaconv_text_t::setCorbatext(response.doc,corbaResponse.doc);

  err = (comerror_t) corbaError;
}

