Files correlati : tutti tranne uno Ricompilazione Demo : [ ] Commento : git-svn-id: svn://10.65.10.50/trunk@13107 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			403 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			403 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <expr.h>
 | 
						|
#include <golem.h>
 | 
						|
#include <recarray.h>
 | 
						|
#include <relapp.h>
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TRecipient
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TRecipient : public TObject
 | 
						|
{
 | 
						|
  TString _address;
 | 
						|
  TString _group;
 | 
						|
  TString _expr;
 | 
						|
 | 
						|
public:
 | 
						|
  const TString& address() const { return _address; }
 | 
						|
  const TString& group() const { return _group; }
 | 
						|
  void  add_expr(char op, const TString& expr);
 | 
						|
  bool can_receive(const TRectype& rec) const;
 | 
						|
  
 | 
						|
  virtual bool ok() const 
 | 
						|
  { return _address.not_empty() && _expr.not_empty(); }
 | 
						|
 | 
						|
  TRecipient(const TToken_string& str);
 | 
						|
  virtual ~TRecipient() { }
 | 
						|
};
 | 
						|
 | 
						|
TRecipient::TRecipient(const TToken_string& str)
 | 
						|
{
 | 
						|
  str.get(0, _address);
 | 
						|
  str.get(1, _group);
 | 
						|
}
 | 
						|
 | 
						|
void TRecipient::add_expr(char op, const TString& expr)
 | 
						|
{
 | 
						|
  if (_expr.not_empty())
 | 
						|
    _expr << (op == 'A' ? "&&" : "||");
 | 
						|
 | 
						|
  if (expr.blank())
 | 
						|
    _expr << 1;
 | 
						|
  else
 | 
						|
    _expr << '(' << expr << ')';
 | 
						|
}
 | 
						|
 | 
						|
bool TRecipient::can_receive(const TRectype& rec) const
 | 
						|
{
 | 
						|
  TExpression e(_expr, _strexpr, TRUE);
 | 
						|
  for (int v = 0; v < e.numvar(); v++)
 | 
						|
  {
 | 
						|
    const char* name = e.varname(v);
 | 
						|
    if (rec.exist(name))
 | 
						|
      e.setvar(name, rec.get(name));
 | 
						|
    else
 | 
						|
      e.setvar(name, "");
 | 
						|
  }
 | 
						|
  bool yes = e.as_bool();
 | 
						|
  return yes;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TPostman
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TPostman : public TObject
 | 
						|
{
 | 
						|
  long _firm;
 | 
						|
  bool _recipients_ok;
 | 
						|
  TArray _recipient;
 | 
						|
  TAssoc_array _expr;
 | 
						|
 | 
						|
protected:
 | 
						|
  void test_firm();
 | 
						|
  
 | 
						|
  TRecipient& recipient(int r) const 
 | 
						|
  { return (TRecipient&)_recipient[r]; }
 | 
						|
 | 
						|
  void add_expr(const TString& addr,
 | 
						|
                char op, const TString& expr);
 | 
						|
 | 
						|
  void load_filters();
 | 
						|
 | 
						|
public:
 | 
						|
  bool can_dispatch_transaction(const TRectype& rec);
 | 
						|
  bool dispatch_transaction(const TRectype& rec, 
 | 
						|
                            const TFilename& name);
 | 
						|
 | 
						|
  TExpression* get_filter_expr(const char* flt);
 | 
						|
  const char* get_filter(const char* flt);
 | 
						|
  bool user_can(const char* flt, const TRelation* rel);
 | 
						|
 | 
						|
  TPostman();
 | 
						|
  virtual ~TPostman() { }
 | 
						|
};
 | 
						|
 | 
						|
void TPostman::test_firm()
 | 
						|
{
 | 
						|
  const long firm = prefix().get_codditta();
 | 
						|
  if (firm != _firm)
 | 
						|
  {
 | 
						|
    _firm = firm;
 | 
						|
    _recipients_ok = FALSE;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TPostman::add_expr(const TString& addr,
 | 
						|
                        char op, const TString& expr)
 | 
						|
{
 | 
						|
  for (int r = _recipient.last(); r >= 0; r--)
 | 
						|
  {
 | 
						|
    TRecipient& rec = recipient(r);
 | 
						|
    if (rec.address() == addr)
 | 
						|
    {
 | 
						|
      rec.add_expr(op, expr);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if (rec.group() == addr)
 | 
						|
        rec.add_expr(op, expr);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
bool TPostman::can_dispatch_transaction(const TRectype& rec)
 | 
						|
{
 | 
						|
  test_firm();
 | 
						|
  if (!_recipients_ok)
 | 
						|
  {
 | 
						|
    _recipients_ok = TRUE;
 | 
						|
    _recipient.destroy();
 | 
						|
    
 | 
						|
    TConfig cfg(CONFIG_DITTA, "MailTransactions");
 | 
						|
    TAuto_token_string str; 
 | 
						|
    TString addr, opr, expr;
 | 
						|
 | 
						|
    // Costruisce la lista dei destinatari
 | 
						|
    for (int r = 0; cfg.exist("Recipient", r); r++)
 | 
						|
    {
 | 
						|
      str = cfg.get("Recipient", NULL, r);
 | 
						|
      TRecipient* rcp = new TRecipient(str);
 | 
						|
      _recipient.add(rcp);
 | 
						|
    }
 | 
						|
 | 
						|
    // Costruisce i filtri per i destinatari
 | 
						|
    for (int f = 0; cfg.exist("Filter", f); f++)
 | 
						|
    {
 | 
						|
      str = cfg.get("Filter", NULL, f);
 | 
						|
      const int num = str.get_int(1);
 | 
						|
      if (num != rec.num()) continue;
 | 
						|
 | 
						|
      str.get(0, addr);
 | 
						|
      str.get(2, opr);
 | 
						|
      str.get(3, expr);
 | 
						|
      add_expr(addr, opr[0], expr);
 | 
						|
    }
 | 
						|
 | 
						|
    // Elimina destinatari inutili
 | 
						|
    for (int d = _recipient.last(); d >= 0; d--)
 | 
						|
    {
 | 
						|
      if (!recipient(d).ok())
 | 
						|
        _recipient.destroy(d, TRUE);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return _recipient.items() > 0;
 | 
						|
}
 | 
						|
 | 
						|
bool TPostman::dispatch_transaction(const TRectype& rec,
 | 
						|
                                    const TFilename& name)
 | 
						|
{
 | 
						|
  bool ok = can_dispatch_transaction(rec);
 | 
						|
  if (ok)
 | 
						|
  {
 | 
						|
    TToken_string dest;
 | 
						|
    for (int r = 0; r < _recipient.items(); r++)
 | 
						|
    {
 | 
						|
      const TRecipient& a = recipient(r);
 | 
						|
      if (a.can_receive(rec))
 | 
						|
        dest.add(a.address());
 | 
						|
    }
 | 
						|
 | 
						|
    ok = dest.items() > 0;
 | 
						|
    if (ok)
 | 
						|
    {
 | 
						|
      TMail_message msg(dest.get(0));
 | 
						|
      for (const char* r = dest.get(1); r; r = dest.get())
 | 
						|
        msg.add_copy_recipient(r);
 | 
						|
 | 
						|
      TString16 subject;
 | 
						|
      switch (rec.num())
 | 
						|
      {
 | 
						|
        case LF_TAB:
 | 
						|
        case LF_TABCOM:
 | 
						|
        case LF_TABGEN:
 | 
						|
          subject << rec.get("COD"); break;
 | 
						|
        default:
 | 
						|
          subject << rec.num();
 | 
						|
      }
 | 
						|
      msg.set_subject(subject);
 | 
						|
 | 
						|
      TScanner trans(name);
 | 
						|
      while (trans.good())
 | 
						|
      {
 | 
						|
        TString& line = trans.line();
 | 
						|
        msg.add_line(line);
 | 
						|
      }
 | 
						|
      ok = msg.send(TRUE);
 | 
						|
    }
 | 
						|
  }  
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
void TPostman::load_filters()
 | 
						|
{
 | 
						|
  TRecord_cache users(LF_USER);
 | 
						|
  
 | 
						|
  TToken_string perm(4096, '\n');
 | 
						|
  TAuto_token_string row(80);
 | 
						|
 | 
						|
  // Costruisce il nome dell'applicazione principale
 | 
						|
  TFilename app(main_app().argv(0));
 | 
						|
  app.ext("");
 | 
						|
  app = app.name();
 | 
						|
 | 
						|
  for (int a = 1; a < main_app().argc(); a++)
 | 
						|
  {
 | 
						|
    row = main_app().argv(a);
 | 
						|
    if (row[0] != '/') 
 | 
						|
      app << ' ' << row;
 | 
						|
    else
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  // Stringhe delle espressioni i filtro
 | 
						|
  TAssoc_array expr;
 | 
						|
  
 | 
						|
  // Scandisce l'albero degli utenti/gruppi
 | 
						|
  for (TString16 u = user(); u.not_empty() && !users.already_loaded(u); )
 | 
						|
  {                    
 | 
						|
    const TRectype& urec = users.get(u);       
 | 
						|
    
 | 
						|
    // Test di validita'del record da eseguire solo la prima volta
 | 
						|
    if (u == user() && !urec.exist("PERMISSION")) 
 | 
						|
      break;
 | 
						|
    perm = urec.get("PERMISSION");  // Permessi del nodo corrente
 | 
						|
    if (!perm.blank())
 | 
						|
    {
 | 
						|
      FOR_EACH_TOKEN(perm, tok)
 | 
						|
      {
 | 
						|
        row = tok;
 | 
						|
        const TString80 appmod = row.get(0);
 | 
						|
        const bool is_mod = appmod.len() == 2;
 | 
						|
        // Il programma oppure il modulo corrispondono
 | 
						|
        if ((is_mod && app.compare(appmod, 2, TRUE) == 0) ||
 | 
						|
             app.compare(appmod, -1, TRUE) == 0) 
 | 
						|
        { 
 | 
						|
          TString80 key = row.get(2); key.trim(); // Tipo di filtro 
 | 
						|
          row = row.get(); row.trim();  // Espressione di filtro 
 | 
						|
          if (key.not_empty() && row.not_empty() && row != "1")
 | 
						|
          {
 | 
						|
            key.upper();
 | 
						|
            TString* str = (TString*)expr.objptr(key);
 | 
						|
            if (str == NULL)            
 | 
						|
            {
 | 
						|
              str = new TString(row);   // Crea una nuova stringa
 | 
						|
              expr.add(key, str);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {                           // Somma alla stringa precendente 
 | 
						|
              if (*str != "0")          // Se sono FALSE lasciami stare
 | 
						|
              {
 | 
						|
                if (row != "0")         // Se aggiungo qualcosa di non ovvio
 | 
						|
                {
 | 
						|
                  str->insert("(", 0);
 | 
						|
                  *str << ")AND(";           
 | 
						|
                  *str << row << ')';
 | 
						|
                }
 | 
						|
                else
 | 
						|
                  *str = "0";              
 | 
						|
              }
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    u = urec.get("GROUPNAME");
 | 
						|
  } 
 | 
						|
 | 
						|
  // Trasforma le stringhe in espressioni     
 | 
						|
  FOR_EACH_ASSOC_STRING(expr, hash, key, str)
 | 
						|
  {
 | 
						|
    TExpression* e = new TExpression(str, _strexpr, TRUE);
 | 
						|
    _expr.add(key, e);
 | 
						|
  }
 | 
						|
 | 
						|
  // Inserisce un elemento fasullo per segnalare l'avvenuta lettura
 | 
						|
  if (_expr.items() == 0)  
 | 
						|
    _expr.add("", NULL);  
 | 
						|
}
 | 
						|
 | 
						|
TExpression* TPostman::get_filter_expr(const char* flt)
 | 
						|
{
 | 
						|
  if (_expr.items() == 0)
 | 
						|
    load_filters();
 | 
						|
  TString80 f(flt); f.upper();
 | 
						|
  TExpression* e = (TExpression*)_expr.objptr(f);
 | 
						|
  return e;
 | 
						|
}
 | 
						|
 | 
						|
const char* TPostman::get_filter(const char* flt)
 | 
						|
{
 | 
						|
  TExpression* e = get_filter_expr(flt);
 | 
						|
  return e ? e->string() : NULL;
 | 
						|
}
 | 
						|
 | 
						|
bool TPostman::user_can(const char* flt, const TRelation* rel)
 | 
						|
{
 | 
						|
  bool yes_he_can = TRUE;
 | 
						|
  TExpression* e = get_filter_expr(flt);
 | 
						|
  if (e != NULL)
 | 
						|
  {
 | 
						|
    if (rel != NULL)
 | 
						|
    {
 | 
						|
      for (int i = e->numvar()-1; i >= 0; i--)
 | 
						|
      {
 | 
						|
        const TString& name = e->varname(i);
 | 
						|
        const TFieldref ref(name, 0);
 | 
						|
        const TString& val = ref.read(*rel);
 | 
						|
        e->setvar(name, val);
 | 
						|
      }
 | 
						|
      yes_he_can = e->as_bool();
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if (e->numvar() == 0)
 | 
						|
        yes_he_can = e->as_bool();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return yes_he_can;
 | 
						|
}
 | 
						|
 | 
						|
TPostman::TPostman() : _firm(-1), _recipients_ok(FALSE)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
TPostman& postman()
 | 
						|
{
 | 
						|
  static TPostman* _postman = NULL;
 | 
						|
  if (_postman == NULL) 
 | 
						|
    _postman = new TPostman;
 | 
						|
  return *_postman;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Public interface
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
bool can_dispatch_transaction(const TRectype& rec)
 | 
						|
{
 | 
						|
  return postman().can_dispatch_transaction(rec);
 | 
						|
}
 | 
						|
 | 
						|
bool dispatch_transaction(const TRectype& rec, const TFilename& name)
 | 
						|
{
 | 
						|
  return postman().dispatch_transaction(rec, name);
 | 
						|
}
 | 
						|
 | 
						|
const char* get_user_filter(const char* flt)
 | 
						|
{
 | 
						|
  return postman().get_filter(flt);
 | 
						|
}
 | 
						|
 | 
						|
const char* get_user_read_filter()
 | 
						|
{
 | 
						|
  return get_user_filter("Lettura");
 | 
						|
}
 | 
						|
 | 
						|
const char* get_user_write_filter()
 | 
						|
{
 | 
						|
  return get_user_filter("Scrittura");
 | 
						|
}
 | 
						|
 | 
						|
bool user_can_read(const TRelation* rel)
 | 
						|
{
 | 
						|
  return postman().user_can("Lettura", rel);
 | 
						|
}
 | 
						|
 | 
						|
bool user_can_write(const TRelation* rel)
 | 
						|
{
 | 
						|
  return user_can_read(rel) && postman().user_can("Scrittura", rel);
 | 
						|
}
 | 
						|
 | 
						|
bool user_can_delete(const TRelation* rel)
 | 
						|
{
 | 
						|
  return user_can_write(rel) && postman().user_can("Eliminazione", rel);
 | 
						|
}
 | 
						|
 | 
						|
bool user_can_do(const char* azione, const TRelation* rel)
 | 
						|
{
 | 
						|
  return postman().user_can(azione, rel);
 | 
						|
}
 | 
						|
 |