Patch level : 10.0 00

38
Files correlati     :
Ricompilazione Demo : [ ]
Commento           :

server di transazioni (Postman)


git-svn-id: svn://10.65.10.50/trunk@16541 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
alex 2008-04-24 07:50:31 +00:00
parent 116dbdc76f
commit 2980a95395
4 changed files with 635 additions and 17 deletions

View File

@ -497,25 +497,18 @@ void TBaseServerApp::OnSocketEvent(wxSocketEvent& e)
sock.SetNotify(wxSOCKET_LOST_FLAG);
// Read the data
const size_t BUFSIZE = 2048;
const size_t BUFSIZE = 1024;
wxString str;
wxChar* bufStart = str.GetWriteBuf(BUFSIZE);
memset(bufStart, 0, BUFSIZE);
wxChar* buf = bufStart;
wxChar buf[BUFSIZE + 1];
const size_t len = sock.Read(buf, BUFSIZE).LastCount();
buf += len;
// Attendi la fine del comando HTTP!
if (strncmp(bufStart, "GET ", 4) == 0 || strncmp(bufStart, "POST ", 5) == 0)
memset(buf, 0, sizeof(buf));
while (sock.Read(buf, BUFSIZE).LastCount() == BUFSIZE)
{
while (strstr(bufStart, "\r\n\r\n") == NULL)
{
const size_t len = sock.Read(buf, BUFSIZE).LastCount();
buf += len;
}
str << buf;
memset(buf, 0, sizeof(buf));
}
str.UngetWriteBuf();
str << buf;
WriteLog(str);
if (CanProcessCommand(str, sock))

605
server/postman.cpp Executable file
View File

@ -0,0 +1,605 @@
#include "baseserv.h"
#include "xml.h"
#include <wx/config.h>
#include <wx/filename.h>
#include <wx/tokenzr.h>
#ifdef WIN32
#include <wx/fileconf.h>
#endif
#define LF_TABGEN 3
#define LF_TABCOM 4
#define LF_TAB 5
//////////////////////////////////////////////////////////
// Date utilities
///////////////////////////////////////////////////////////
static const byte _days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int last_day(int month, int year)
// parse_filastrok(
// "trenta giorni ha novembre
// con april, giugno e settembre
// son ventotto case uno
// per default ce n'ha trentuno");
{
int d = _days_in_month[month-1];
if (month == 2 && (year % 4) == 0)
d++;
return d;
}
bool isdate(const wxChar * s)
{
const int len = strlen(s);
if (len != 8 && len != 10)
return false;
int d = 0, m = 0, y = 0, i;
if (len == 8)
{
for (i = 0; i < 8; i++)
if (!isdigit(s[i])) break;
if (i == 8)
{
wxString str(s);
d = atoi(((const char *)str)+6); str[6] = '\0';
m = atoi(((const char *)str)+4); str[4] = '\0';
y = atoi(((const char *)str)+0);
}
}
else
if (len == 10)
{
if (s[2] == s[5] && !isdigit(s[2]))
{
d = atoi(s);
m = atoi(&s[3]);
y = atoi(&s[6]);
}
}
if (d < 1 || d > 31 ||
m < 1 || m > 12 ||
y < 0)
return false;
return d <= last_day(m,y);
}
long date2ansi(const wxChar * s)
{
long val = 0L;
const int len = (s && *s >= '0') ? strlen(s) : 0;
if (len != 8 && len != 10) // Chi si azzarda ad aggiungere len != 6 ?
return 0L;
if (len == 8)
{
int i;
for (i = 0; i < 8; i++)
if (!isdigit(s[i])) break;
if (i == 8)
val = atol(s);
}
else
{
if (s[2] == s[5] && !isdigit(s[2]))
{
const int d = atoi(s);
const int m = atoi(&s[3]);
const int y = atoi(&s[6]);
val = d + m + 100 + y * 10000;
}
}
return val;
}
///////////////////////////////////////////////////////////
// TPostmanServer
///////////////////////////////////////////////////////////
class TPostmanServer : public TBaseServerApp
{
wxArrayString m_Editors;
wxArrayString m_FirmEditors;
int m_Logicnum;
int m_Firm;
int m_LastFirm;
wxArrayString m_TableName;
int m_Err;
wxString m_DataPath;
protected:
virtual void ProcessHttpGet(wxString cmd, wxSocketBase& outs);
bool IsMagicName(wxString& strFilename) const;
virtual const wxChar* GetAppName() const;
void AbsoluteNameName(wxString & name);
const wxString Table2Editor(const wxString & table);
bool LoadEditors(const wxChar * filename, wxArrayString & editors);
void SaveXml2IniParagraph(wxFileConfig & ini, TXmlItem& xmlItem);
void SaveTransaction(const TXmlItem& xmlMethod, wxString & filename);
const wxString EditorCommand();
void ExecuteTransaction(wxString & filename);
void LoadXmlParagraph(TXmlItem & xmlItem, wxString & paragraph, wxString & filename);
void LoadTransaction(wxString & filename, TXmlItem & xmlAnswer);
void Log(TXmlItem& xmlItem, wxString & filename);
virtual void SoapProcessMethod(const TXmlItem& xmlMethod, TXmlItem& xmlAnswer);
virtual int GetDefaultPort() const;
public:
virtual bool Initialization();
TPostmanServer() : m_Logicnum(0), m_Err(0), m_Firm(0), m_LastFirm(0) {}
};
void TPostmanServer::ProcessHttpGet(wxString cmd, wxSocketBase& outs)
{
const int stop = cmd.Find(" HTTP");
wxString str = cmd.Mid(4, stop-4).Trim();
if (str == "/")
str += "index.htm";
wxString strFilename = GetDocumentRoot() + str;
IsMagicName(strFilename);
SendFile(strFilename, outs);
}
bool TPostmanServer::IsMagicName(wxString& strFilename) const
{
wxFileName fnName(strFilename);
wxString strName(fnName.GetName().Lower());
if (strName == "index" || strName == "log")
{
strFilename = GetLogFileName();
return true;
}
return false;
}
const wxString TPostmanServer::Table2Editor(const wxString & table)
{
wxString row;
wxString module;
wxString editor;
wxString name;
{
name << "../recdesc/d" << table << ".des";
name.Lower();
wxFileName f(name);
f.MakeAbsolute();
name = f.GetFullPath();
wxTextFile file(name);
if (file.Open())
{
for (row = file.GetFirstLine(); !file.Eof(); row = file.GetNextLine())
{
row.Trim(false);
if (row.StartsWith("Module"))
{
const int pos = row.Find("=");
if (pos >= 0)
module = row.Mid(pos + 1);
module.Trim();
module.Trim(false);
break;
}
}
}
}
if (module.IsEmpty())
{
module = "ba";
name = "../??tb";
name << table << ".msk";
name.Lower();
wxFileName f(name);
f.MakeAbsolute();
name = f.GetFullPath();
wxString foundfile = ::wxFindFirstFile(name, wxFILE);
while (!foundfile.IsEmpty())
{
f = foundfile;
wxString str(f.GetName().Left(2));
if (str != "ba")
{
module = str;
break;
}
foundfile = ::wxFindNextFile();
}
}
wxFileName f("../install.ini");
f.MakeAbsolute();
name = f.GetFullPath();
wxTextFile file(name);
wxString wmodule;
if (file.Open())
{
for (row = file.GetFirstLine(); !file.Eof(); row = file.GetNextLine())
{
row.Trim(false);
if (row.StartsWith("["))
wmodule = row.Mid(1, 2);
else
if (row.StartsWith("Edit_"))
{
const int pos = row.Find("=");
if (pos >= 0)
{
const wxString table(row.Mid(5, pos - 4));
const int logicnum = atoi(table);
if ((logicnum <= LF_TAB && module == wmodule) || table == m_TableName[m_Logicnum])
{
editor = row.Mid(pos + 1);
editor.Trim(false);
editor << " ";
if (m_Logicnum == LF_TABGEN)
editor << '#';
else
if (m_Logicnum == LF_TABCOM)
editor << '%';
editor << m_TableName[m_Logicnum];
if (table == m_TableName[m_Logicnum])
break;
}
}
}
}
}
return editor;
}
bool TPostmanServer::LoadEditors(const wxChar * filename, wxArrayString & editors)
{
wxFileName f(filename);
f.MakeAbsolute();
wxString name(f.GetFullPath());
wxTextFile file(name);
wxString row;
wxString module;
if (file.Open())
{
for (row = file.GetFirstLine(); !file.Eof(); row = file.GetNextLine())
{
wxString editor;
row.Trim(false);
if (row.StartsWith("["))
module = row.Mid(1, 2);
else
if (row.StartsWith("Edit_"))
{
const int pos = row.Find("=");
if (pos < 0)
continue;
const int logicnum = atoi(row.Mid(5, pos - 4));
if (logicnum < 7 && module != "ba")
continue;
editor = row.Mid(pos + 1);
editor.Trim(false);
int nrows2add = logicnum - editors.GetCount() + 1;
if (nrows2add > 0)
editors.Add(wxEmptyString, nrows2add);
editors[logicnum] = editor;
}
}
}
return editors.GetCount() > 0;
}
int TPostmanServer::GetDefaultPort() const
{
return GetConfigInt("Port", 80);
}
void TPostmanServer::SaveXml2IniParagraph(wxFileConfig& ini, TXmlItem& xmlItem)
{
int items = xmlItem.GetChildren();
for (int i = 0; i < items; i++)
{
TXmlItem * child = xmlItem.GetChild(i);
wxString key(child->GetAttr("Name"));
wxString val(child->GetEnclosedText());
if (key == "Firm")
m_Firm = atoi(val);
ini.Write(key, val);
}
}
void TPostmanServer::SaveTransaction(const TXmlItem& xmlMethod, wxString & filename)
{
wxString paragraph;
int items = xmlMethod.GetChildren();
for (int i = 0; i < items; i++)
{
TXmlItem * child = xmlMethod.GetChild(i);
const int logicnum = atoi(child->GetAttr("LogicNumber"));
paragraph = "/";
if (logicnum > 0)
{
if (m_Logicnum == 0)
m_Logicnum = logicnum;
paragraph << logicnum;
const int rownum = atoi(child->GetAttr("RowNumber"));
if (rownum > 0)
paragraph << ',' << rownum;
int nrows2add = logicnum - m_TableName.GetCount() + 1;
if (nrows2add > 0)
m_TableName.Add(wxEmptyString, nrows2add);
m_TableName[logicnum] = child->GetAttr("TableName");
}
else
paragraph << child->GetTag();
wxFileConfig ini("", "", filename, "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
ini.SetPath(paragraph);
SaveXml2IniParagraph(ini, *child);
}
}
const wxString TPostmanServer::EditorCommand()
{
const bool firmchanged = m_Firm != m_LastFirm;
m_LastFirm = m_Firm;
if (firmchanged)
{
m_FirmEditors.empty();
wxString name(m_DataPath);
wxChar l = name[name.Len() - 1];
if (l != '/' && l != '\\')
name << '/';
wxString str;
str << m_Firm;
while(str.Len() < 5)
str.insert(0, "0");
name << str << "a/ditta.ini";
LoadEditors(name.c_str(), m_FirmEditors);
}
wxString table(m_TableName[m_Logicnum]);
if (m_Logicnum <= LF_TAB && !table.IsEmpty())
{
wxString editor(Table2Editor(table));
if (!editor.IsEmpty())
return editor;
}
if (m_Logicnum < (int) m_FirmEditors.GetCount() && !m_FirmEditors[m_Logicnum].IsEmpty())
return m_FirmEditors[m_Logicnum].c_str();
if (m_Logicnum < (int) m_Editors.GetCount() && !m_Editors[m_Logicnum].IsEmpty())
return m_Editors[m_Logicnum].c_str();
return wxEmptyString;
}
void TPostmanServer::ExecuteTransaction(wxString & filename)
{
wxString editor(EditorCommand());
if (!editor.IsEmpty())
{
wxString str;
str << "../" << editor;
wxFileName cmdname(str);
cmdname.MakeAbsolute();
wxString command(cmdname.GetFullPath());
const wxString currdir(wxGetCwd());
wxSetWorkingDirectory("../");
command << " -i" <<filename << " -uADMIN";
m_Err = 0;
if (::wxExecute(command, wxEXEC_SYNC) < 0)
{
wxString str;
m_Err = 2;
str << "Errore nell'esecuzione di " << command << m_Err ;
WriteLog(str);
}
wxSetWorkingDirectory(currdir);
}
}
void TPostmanServer::LoadXmlParagraph(TXmlItem& xmlItem, wxString& paragraph, wxString & filename)
{
wxString path;
wxFileConfig ini("", "", filename, "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
path << "/" << paragraph;
ini.SetPath(path);
wxStringTokenizer tok(paragraph, ",");
wxString tag = tok.GetNextToken();
int logicnum = atoi(tag);
const wxChar * attr = logicnum > 0 ? "Field" : "Attr";
int rownum = 0 ;
if (logicnum > 0 && tok.HasMoreTokens())
rownum = atoi(tok.GetNextToken());
if (logicnum > 0)
tag = "Record";
TXmlItem & child =xmlItem.AddChild(tag);
if (logicnum > 0)
{
child.SetAttr("LogicNumber", logicnum);
child.SetAttr("TableName", m_TableName[logicnum]);
if (rownum > 0)
child.SetAttr("RowNumber", rownum);
}
wxString s;
wxString key;
long index = 0;
for (bool ok = ini.GetFirstEntry(key, index); ok; ok = ini.GetNextEntry (key, index))
{
wxString val(ini.Read(key));
if (val.StartsWith("\"") && val.EndsWith("\""))
{
val = val.Mid(1);
val[val.Len()] = '\0';
}
else
{
val.Trim();
val.Trim(false);
}
if (isdate(val))
child.AddSoapInt(attr, date2ansi(val)).SetAttr("Name", key);
else
{
if (val.IsNumber())
{
if (key == "Error" && m_Err != 0)
child.AddSoapInt(attr, m_Err).SetAttr("Name", key);
else
child.AddSoapInt(attr, atoi(val)).SetAttr("Name", key);
}
else
{
if (key == "Result" && m_Err != 0)
child.AddSoapString(attr, "ERROR").SetAttr("Name", key);
else
child.AddSoapString(attr, val).SetAttr("Name", key);
}
}
}
}
void TPostmanServer::LoadTransaction(wxString & filename, TXmlItem& xmlAnswer)
{
wxString paragraph;
long index = 0;
wxFileConfig ini("", "", filename, "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
for (bool ok = ini.GetFirstGroup(paragraph, index); ok; ok = ini.GetNextGroup(paragraph, index))
LoadXmlParagraph(xmlAnswer, paragraph, filename);
}
void TPostmanServer::Log(TXmlItem& xmlItem, wxString & filename)
{
wxFileConfig ini("", "", filename, "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
wxString str;
wxString key;
long index = 0;
ini.SetPath("/Transaction");
str << "Transaction : Command " << m_Editors[m_Logicnum];
WriteLog(str);
for (bool ok = ini.GetFirstEntry(key, index); ok; ok = ini.GetNextEntry (key, index))
{
wxString val(ini.Read(key));
str = " ",
str << key << " = " << val;
WriteLog(str);
}
}
void TPostmanServer::SoapProcessMethod(const TXmlItem& xmlMethod, TXmlItem& xmlAnswer)
{
const wxString& strMethod = xmlMethod.GetTag();
if (strMethod == "m:CampoTransaction")
{
m_Logicnum = 0;
wxFileName filename(GetTempFilename());
filename.SetExt("ini");
wxString name(filename.GetFullPath());
SaveTransaction(xmlMethod, name);
ExecuteTransaction(name);
LoadTransaction(name, xmlAnswer);
Log(xmlAnswer, name);
}
}
// Implementazione delle due funzioni pure virtuali
const wxChar* TPostmanServer::GetAppName() const
{
return "Postman";
}
bool TPostmanServer::Initialization()
{
wxFileName f("../campo.ini");
f.MakeAbsolute();
wxString name(f.GetFullPath());
wxTextFile file(name);
wxString row;
if (file.Open())
{
for (row = file.GetFirstLine(); !file.Eof(); row = file.GetNextLine())
{
if (row.StartsWith("Study"))
{
const int pos = row.Find('=');
if (pos >= 0)
{
m_DataPath = row.Mid(pos + 1);
m_DataPath.Trim(false);
}
break;
}
}
}
if (m_DataPath.IsEmpty())
{
WriteLog("No data path");
return false;
}
if (!LoadEditors("../install.ini", m_Editors))
{
WriteLog("No editors found");
return false;
}
return true;
}
// Istanziare l'applicazione principale
IMPLEMENT_APP(TPostmanServer)

8
server/postman.h Executable file
View File

@ -0,0 +1,8 @@
#ifndef __POSTMAN_H
#define __POSTMAN_H
bool DoTranslate(const TXmlItem& xmlMethod, TXmlItem& xmlAnswer);
#endif

View File

@ -269,7 +269,8 @@ int TXmlItem::ReadTag(wxInputStream& inf)
}
if (bFirstChar)
{
str << ' ';
if (c != ' ' && c != '=')
str << ' ';
bFirstChar = false;
}
if (c == '&')
@ -300,6 +301,7 @@ int TXmlItem::ReadTag(wxInputStream& inf)
if (name[0u] == '/')
{
bChildrenFollow = false;
name = GetWord(inf);
continue;
}
@ -309,6 +311,11 @@ int TXmlItem::ReadTag(wxInputStream& inf)
break;
// Leggo il valore dell'attributo
str = GetWord(inf);
const int len = str.Len();
if (len >= 2 && (str[0] == '"' || str[0] == '\'') && str[len-1] == str[0])
{
str = str.Mid(1, len - 2);
}
SetAttr(name, str);
name = GetWord(inf);
@ -382,7 +389,12 @@ void TXmlItem::RemoveLastChild()
bool TXmlItem::Read(wxInputStream& inf)
{
const int res = ReadTag(inf);
int res = ReadTag(inf);
// Ignora la eventuale riga <?xml version="1.0" encoding="UTF-8" ?>
if (res == 0 && GetTag()[0] == '?')
res = ReadTag(inf);
if (res > 0) // There are children ahead
{
while (!inf.Eof())