00001
00002
00003
00004
00005
00006
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#ifdef HAVE_CONFIG_H
00022
#include <config.h>
00023
#endif
00024
00025
#include <iostream>
00026
#include <stdlib.h>
00027
#include <string>
00028
#include "ParserEventGeneratorKit.h"
00029
#include "libofx.h"
00030
#include "ofx_utilities.hh"
00031
#include "messages.hh"
00032
#include "ofx_containers.hh"
00033
#include "ofc_sgml.hh"
00034
00035
using namespace std;
00036
00037
00038 extern SGMLApplication::OpenEntityPtr
entity_ptr;
00039 extern SGMLApplication::Position
position;
00040
extern OfxMainContainer * MainContainer;
00041
00044
class OFCApplication :
public SGMLApplication{
00045
private:
00046
OfxGenericContainer *curr_container_element;
00047
OfxGenericContainer *tmp_container_element;
00048
bool is_data_element;
00049 string incoming_data;
00050 LibofxContext * libofx_context;
00051
public:
00052
OFCApplication (LibofxContext * p_libofx_context)
00053 {
00054 MainContainer=NULL;
00055 curr_container_element = NULL;
00056 is_data_element =
false;
00057 libofx_context=p_libofx_context;
00058 }
00059
00064 void startElement (
const StartElementEvent & event)
00065 {
00066 string identifier;
00067
CharStringtostring (event.gi, identifier);
00068
message_out(
PARSER,
"startElement event received from OpenSP for element " + identifier);
00069
00070
position = event.pos;
00071
00072
switch (event.contentType)
00073 {
00074
case StartElementEvent::empty:
message_out(
ERROR,
"StartElementEvent::empty\n");
00075
break;
00076
case StartElementEvent::cdata:
message_out(
ERROR,
"StartElementEvent::cdata\n");
00077
break;
00078
case StartElementEvent::rcdata:
message_out(
ERROR,
"StartElementEvent::rcdata\n");
00079
break;
00080
case StartElementEvent::mixed:
message_out(
PARSER,
"StartElementEvent::mixed");
00081 is_data_element =
true;
00082
break;
00083
case StartElementEvent::element:
message_out(
PARSER,
"StartElementEvent::element");
00084 is_data_element =
false;
00085
break;
00086
default:
00087
message_out(
ERROR,
"Unknow SGML content type?!?!?!? OpenSP interface changed?");
00088 }
00089
00090
if (is_data_element ==
false)
00091 {
00092
00093
00094
if (identifier ==
"OFC")
00095 {
00096
message_out (
PARSER,
"Element " + identifier +
" found");
00097 MainContainer =
new OfxMainContainer (libofx_context, curr_container_element, identifier);
00098 curr_container_element = MainContainer;
00099 }
00100
else if (identifier ==
"STATUS")
00101 {
00102
message_out (
PARSER,
"Element " + identifier +
" found");
00103 curr_container_element =
new OfxStatusContainer (libofx_context, curr_container_element, identifier);
00104 }
00105
else if (identifier ==
"ACCTSTMT")
00106 {
00107
message_out (
PARSER,
"Element " + identifier +
" found");
00108 curr_container_element =
new OfxStatementContainer (libofx_context, curr_container_element, identifier);
00109 }
00110
else if (identifier ==
"STMTRS")
00111 {
00112
message_out (
PARSER,
"Element " + identifier +
" found");
00113
00114
if(curr_container_element->
type!=
"STATEMENT")
00115 {
00116
message_out(
ERROR,
"Element " + identifier +
" found while not inside a STATEMENT container");
00117 }
00118
else
00119 {
00120 curr_container_element =
new OfxPushUpContainer (libofx_context, curr_container_element, identifier);
00121 }
00122 }
00123
else if (identifier ==
"GENTRN" ||
00124 identifier ==
"STMTTRN")
00125 {
00126
message_out (
PARSER,
"Element " + identifier +
" found");
00127 curr_container_element =
new OfxBankTransactionContainer (libofx_context, curr_container_element, identifier);
00128 }
00129
else if(identifier ==
"BUYDEBT" ||
00130 identifier ==
"BUYMF" ||
00131 identifier ==
"BUYOPT" ||
00132 identifier ==
"BUYOTHER" ||
00133 identifier ==
"BUYSTOCK" ||
00134 identifier ==
"CLOSUREOPT" ||
00135 identifier ==
"INCOME" ||
00136 identifier ==
"INVEXPENSE" ||
00137 identifier ==
"JRNLFUND" ||
00138 identifier ==
"JRNLSEC" ||
00139 identifier ==
"MARGININTEREST" ||
00140 identifier ==
"REINVEST" ||
00141 identifier ==
"RETOFCAP" ||
00142 identifier ==
"SELLDEBT" ||
00143 identifier ==
"SELLMF" ||
00144 identifier ==
"SELLOPT" ||
00145 identifier ==
"SELLOTHER" ||
00146 identifier ==
"SELLSTOCK" ||
00147 identifier ==
"SPLIT" ||
00148 identifier ==
"TRANSFER" )
00149 {
00150
message_out (
PARSER,
"Element " + identifier +
" found");
00151 curr_container_element =
new OfxInvestmentTransactionContainer (libofx_context, curr_container_element, identifier);
00152 }
00153
00154
else if (identifier ==
"INVBUY" ||
00155 identifier ==
"INVSELL" ||
00156 identifier ==
"INVTRAN" ||
00157 identifier ==
"SECID")
00158 {
00159
message_out (
PARSER,
"Element " + identifier +
" found");
00160 curr_container_element =
new OfxPushUpContainer (libofx_context, curr_container_element, identifier);
00161 }
00162
00163
00164
else if (identifier ==
"ACCOUNT"||
00165 identifier ==
"ACCTFROM" )
00166 {
00167
message_out (
PARSER,
"Element " + identifier +
" found");
00168 curr_container_element =
new OfxAccountContainer (libofx_context, curr_container_element, identifier);
00169 }
00170
else if (identifier ==
"SECINFO")
00171 {
00172
message_out (
PARSER,
"Element " + identifier +
" found");
00173 curr_container_element =
new OfxSecurityContainer (libofx_context, curr_container_element, identifier);
00174 }
00175
00176
else if (identifier ==
"LEDGERBAL" || identifier ==
"AVAILBAL")
00177 {
00178
message_out (
PARSER,
"Element " + identifier +
" found");
00179 curr_container_element =
new OfxBalanceContainer (libofx_context, curr_container_element, identifier);
00180 }
00181
else
00182 {
00183
00184 curr_container_element =
new OfxDummyContainer(libofx_context, curr_container_element, identifier);
00185 }
00186 }
00187
else
00188 {
00189
00190
message_out (
PARSER,
"Data element " + identifier +
" found");
00191
00192
if (incoming_data !=
"")
00193 {
00194
message_out (
ERROR,
"startElement: incoming_data should be empty! You are probably using OpenSP <= 1.3.4. The folowing data was lost: " + incoming_data );
00195 incoming_data.assign (
"");
00196 }
00197 }
00198 }
00199
00204 void endElement (
const EndElementEvent & event)
00205 {
00206 string identifier;
00207
bool end_element_for_data_element;
00208
00209
CharStringtostring (event.gi, identifier);
00210 end_element_for_data_element=is_data_element;
00211
message_out(
PARSER,
"endElement event received from OpenSP for element " + identifier);
00212
00213
position = event.pos;
00214
if (curr_container_element == NULL)
00215 {
00216
message_out (
ERROR,
"Tried to close a "+identifier+
" without a open element (NULL pointer)");
00217 incoming_data.assign (
"");
00218 }
00219
else
00220 {
00221
if (end_element_for_data_element ==
true)
00222 {
00223 incoming_data =
strip_whitespace(incoming_data);
00224
00225 curr_container_element->
add_attribute (identifier, incoming_data);
00226
message_out (
PARSER,
"endElement: Added data '" + incoming_data +
"' from " + identifier +
" to " + curr_container_element->
type +
" container_element");
00227 incoming_data.assign (
"");
00228 is_data_element=
false;
00229 }
00230
else
00231 {
00232
if (identifier == curr_container_element->
tag_identifier)
00233 {
00234
if(incoming_data!=
"")
00235 {
00236
message_out(
ERROR,
"End tag for non data element "+identifier+
", incoming data should be empty but contains: "+incoming_data+
" DATA HAS BEEN LOST SOMEWHERE!");
00237 }
00238
00239
if(identifier ==
"OFX")
00240 {
00241
00242 tmp_container_element = curr_container_element;
00243 curr_container_element = curr_container_element->
getparent ();
00244 MainContainer->
gen_event();
00245
delete MainContainer;
00246 MainContainer = NULL;
00247
message_out (
DEBUG,
"Element " + identifier +
" closed, MainContainer destroyed");
00248 }
00249
else
00250 {
00251 tmp_container_element = curr_container_element;
00252 curr_container_element = curr_container_element->
getparent ();
00253
if(MainContainer != NULL)
00254 {
00255 tmp_container_element->
add_to_main_tree();
00256
message_out (
PARSER,
"Element " + identifier +
" closed, object added to MainContainer");
00257 }
00258
else
00259 {
00260
message_out (
ERROR,
"MainContainer is NULL trying to add element " + identifier);
00261 }
00262 }
00263 }
00264
else
00265 {
00266
message_out (
ERROR,
"Tried to close a "+identifier+
" but a "+curr_container_element->
type+
" is currently open.");
00267 }
00268 }
00269 }
00270 }
00271
00276 void data (
const DataEvent & event)
00277 {
00278 string tmp;
00279
position = event.pos;
00280
AppendCharStringtostring (event.data, incoming_data);
00281
message_out(
PARSER,
"data event received from OpenSP, incoming_data is now: " + incoming_data);
00282 }
00283
00288 void error (
const ErrorEvent & event)
00289 {
00290 string message;
00291 string string_buf;
00292
OfxMsgType error_type =
ERROR;
00293
00294
position = event.pos;
00295 message = message +
"OpenSP parser: ";
00296
switch (event.type){
00297
case SGMLApplication::ErrorEvent::quantity:
00298 message = message +
"quantity (Exceeding a quantity limit):";
00299 error_type =
ERROR;
00300
break;
00301
case SGMLApplication::ErrorEvent::idref:
00302 message = message +
"idref (An IDREF to a non-existent ID):";
00303 error_type =
ERROR;
00304
break;
00305
case SGMLApplication::ErrorEvent::capacity:
00306 message = message +
"capacity (Exceeding a capacity limit):";
00307 error_type =
ERROR;
00308
break;
00309
case SGMLApplication::ErrorEvent::otherError:
00310 message = message +
"otherError (misc parse error):";
00311 error_type =
ERROR;
00312
break;
00313
case SGMLApplication::ErrorEvent::warning:
00314 message = message +
"warning (Not actually an error.):";
00315 error_type =
WARNING;
00316
break;
00317
case SGMLApplication::ErrorEvent::info:
00318 message = message +
"info (An informationnal message. Not actually an error):";
00319 error_type =
INFO;
00320
break;
00321
default:
00322 message = message +
"OpenSP sent an unknown error to LibOFX (You probably have a newer version of OpenSP):";
00323 }
00324 message = message +
"\n" +
CharStringtostring (event.message, string_buf);
00325
message_out (error_type, message);
00326 }
00327
00332 void openEntityChange (
const OpenEntityPtr & para_entity_ptr)
00333 {
00334
message_out(
DEBUG,
"openEntityChange()\n");
00335
entity_ptr = para_entity_ptr;
00336
00337 };
00338
00339
private:
00340 };
00341
00345 int ofc_proc_sgml(LibofxContext * libofx_context,
int argc,
char *argv[])
00346 {
00347
message_out(
DEBUG,
"Begin ofx_proc_sgml()");
00348
message_out(
DEBUG,argv[0]);
00349
message_out(
DEBUG,argv[1]);
00350
message_out(
DEBUG,argv[2]);
00351
00352 ParserEventGeneratorKit parserKit;
00353 parserKit.setOption (ParserEventGeneratorKit::showOpenEntities);
00354 EventGenerator *egp = parserKit.makeEventGenerator (argc, argv);
00355 egp->inhibitMessages (
true);
00356
OFCApplication *app =
new OFCApplication(libofx_context);
00357
unsigned nErrors = egp->run (*app);
00358
delete egp;
00359
return nErrors > 0;
00360 }