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 }