% Retrieve a ltpda_uo from a repository
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION:    fromRepository
%
% DESCRIPTION: Retrieve a ltpda_uo from a repository
%
% CALL:        obj = fromRepository(pl)
%
% PARAMETER:   pl: Parameter list object
%
% VERSION:     $Id: fromRepository.m,v 1.8 2010/10/29 16:09:11 ingo Exp $
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function coll = fromRepository(coll, pli)
  
  VERSION = '$Id: fromRepository.m,v 1.8 2010/10/29 16:09:11 ingo Exp $';
  
  % get object info
  ii = collection.getInfo('collection', 'From Repository');
  % Set the method version string in the minfo object
  ii.setMversion([VERSION '-->' ii.mversion]);
  
  % Check if the user supplied a DB connection
  conn = find(pli, 'conn');
  
  % Add default values if necessary
  if isempty(conn)
    pl = combine(pli, ii.plists);
  else
    pl = pli;
  end
  plh = copy(pl, 1);
  
  % Get parameters
  hostname = find(pl, 'hostname');
  database = find(pl, 'database');
  user     = find(pl, 'user');
  passwd   = find(pl, 'passwd');
  ids      = find(pl, 'id');
  cids     = find(pl, 'cid');
  bin      = find(pl, 'binary');
  
  collFound  = false;
  
  %%% check if using binary or not: 'yes'/'no' or true/false or
  %%% 'true'/'false'
  bin = utils.prog.yes2true(bin);
  
  % do we have a connection?
  closeConn = 0;
  if isempty(conn)
    closeConn = 1;
    % Connect to repository
    % Connect to repository
    if ~isempty(user) && ~isempty(passwd)
      conn = utils.jmysql.connect(hostname, database, user, passwd);
    else
      conn = utils.jmysql.connect(hostname, database);
    end
  end
  if ~isa(conn, 'database') && ~isa(conn, 'mpipeline.repository.RepositoryConnection')
    error('### connection to the database failed.');
  end
  
  if ~isempty(cids)
    for kk=1:numel(cids)
      cid = cids(kk);
      if isa(conn, 'database')
        % get the ids from the cid
        ids = [ids utils.mysql.getObjIds(conn,cid)];
      else
        c_ids = mpipeline.repository.MySQLUtils.getObjectIDsFromCollectionID(conn, cid);
        ids = [ids c_ids.'];
      end
    end
  end
  
  % Get each ID
  Nids     = length(ids);
  collObjs = {};
  
  for kk=1:Nids
    
    %---- copy the input plist because each object should get an other plist
    plh = copy(pl, 1);
    
    %---- This id
    id = ids(kk);
    utils.helper.msg(utils.const.msg.OPROC2, 'retrieving ID %d', id);
    
    try
      %---- call database constructor
      if bin
        try
          robj = ltpda_uo.retrieve(conn, 'binary', id);
        catch
          warning('!!! Unable to do binary retrieval for object %d; trying to retrieve XML instead.', id);
          robj = ltpda_uo.retrieve(conn, id);
        end
      else
        robj = ltpda_uo.retrieve(conn, id);
      end
      
      %  - remove connection object from plist first
      if isempty(hostname) || isempty(database)
        txt = textscan(conn.URL, '%s', 'Delimiter', '/', 'CollectOutput', 1);
        plc = plist('hostname', txt{1}{3}, 'database', txt{1}{4});
        plh = combine(pli, plc);
      end
      
      %---- remove the connection from the history plist
      if plh.isparam('conn')
        plh.remove('conn');
      end
      
      %---- Set only the ID of the current object to the plist
      plh.pset('ID', id);
      
      %---- Add history
      robj.addHistoryWoChangingUUID(robj.getInfo(class(robj), 'From Repository'), plh, [], robj.hist);
      
      %---- Add to output array
      if isa(robj, 'collection')
        if numel(ids) == 1
          coll = robj;
          return
        end
        
        if numel(robj.objs)>0
          collFound = true;
          collObjs = [collObjs; robj.objs(:)];
        end
      else
        collObjs = [collObjs; {robj}];
      end
    catch Exception
      if closeConn
        close(conn);
      end
      throw(Exception)
    end
    
  end
  
  % close connection
  if closeConn
    if isa(conn, 'database')
      close(conn);
    else
      conn.closeConnection;
    end
  end
  
  if collFound
    warning(sprintf(['!!! The output collection contains the contents of at least one retrieved collection.' ...
      '\nThe history of those collection objects is discarded. The internal objects of those ' ...
      'objects is retained.']));
  end
  if isempty(collObjs)
    warning('!!! No objects were retrieved from the ids %s and/or collection id %s', mat2str(ids), mat2str(cid));
  end
  
  % Define collection-plist for the history
  plh.pset('id', pli.find('id'));
  plh.pset('cid', pli.find('cid'));
  
  % Set properties from the plist
  coll.setProperties(pl);
  coll.objs = collObjs;
  coll.addHistory(ii, plh, [], []);
  
end

