1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959 |
- #include <memory>
- #include "daclient.hpp"
- #include "environment.hpp"
- #include "workunit.hpp"
- #include "wujobq.hpp"
- #include "fileview.hpp"
- #include "ws_ecl_service.hpp"
- #include "ws_ecl_wuinfo.hpp"
- #include "xsdparser.hpp"
- #include "httpclient.hpp"
- #include "xpp/XmlPullParser.h"
- #define SDS_LOCK_TIMEOUT (5*60*1000) // 5mins, 30s a bit short
- #define WSECL_ACCESS "WsEclAccess"
- const char *wsEclXsdTypes[] = {
- "xsd:string",
- "xsd:string",
- "xsd:boolean",
- "xsd:decimal",
- "xsd:float",
- "xsd:double",
- "xsd:duration",
- "xsd:dateTime",
- "xsd:time",
- "xsd:date",
- "xsd:gYearMonth",
- "xsd:gYear",
- "xsd:gMonthDay",
- "xsd:gDay",
- "xsd:gMonth",
- "xsd:hexBinary",
- "xsd:base64Binary",
- "xsd:anyURI",
- "xsd:QName",
- "xsd:NOTATION",
- "xsd:normalizedString",
- "xsd:token",
- "xsd:language",
- "xsd:NMTOKEN",
- "xsd:NMTOKENS",
- "xsd:Name",
- "xsd:NCName",
- "xsd:ID",
- "xsd:IDREF",
- "xsd:IDREFS",
- "xsd:ENTITY",
- "xsd:ENTITIES",
- "xsd:integer",
- "xsd:nonPositiveInteger",
- "xsd:negativeInteger",
- "xsd:long",
- "xsd:int",
- "xsd:short",
- "xsd:byte",
- "xsd:nonNegativeInteger",
- "xsd:unsignedLong",
- "xsd:unsignedInt",
- "xsd:unsignedShort",
- "xsd:unsignedByte",
- "xsd:positiveInteger",
- "tns:RawDataFile",
- "tns:CsvDataFile",
- "tns:EspStringArray",
- "tns:EspIntArray",
- "tns:XmlDataSet"
- };
- typedef MapStringTo<wsEclType> MapStringToWsEclType;
- int strptrcmp(char const ** l, char const ** r) { return strcmp(*l, *r); }
- class wsEclTypeTranslator
- {
- private:
- MapStringToWsEclType typemap;
- public:
- wsEclTypeTranslator();
- wsEclType translate(const char *type);
- };
- wsEclTypeTranslator::wsEclTypeTranslator()
- {
- typemap.setValue("xsd:string", xsdString);
- typemap.setValue("xsd:boolean", xsdBoolean);
- typemap.setValue("xsd:decimal", xsdDecimal);
- typemap.setValue("xsd:float", xsdFloat);
- typemap.setValue("xsd:double", xsdDouble);
- typemap.setValue("xsd:duration", xsdDuration);
- typemap.setValue("xsd:dateTime", xsdDateTime);
- typemap.setValue("xsd:time", xsdTime);
- typemap.setValue("xsd:date", xsdDate);
- typemap.setValue("xsd:gyearmonth", xsdYearMonth);
- typemap.setValue("xsd:gyear", xsdYear);
- typemap.setValue("xsd:gmonthday", xsdMonthDay);
- typemap.setValue("xsd:gday", xsdDay);
- typemap.setValue("xsd:gmonth", xsdMonth);
- typemap.setValue("xsd:hexbinary", xsdHexBinary);
- typemap.setValue("xsd:base64binary", xsdBase64Binary);
- typemap.setValue("xsd:anyuri", xsdAnyURI);
- typemap.setValue("xsd:qname", xsdQName);
- typemap.setValue("xsd:notation", xsdNOTATION);
- typemap.setValue("xsd:normalizedstring", xsdNormalizedString);
- typemap.setValue("xsd:token", xsdToken);
- typemap.setValue("xsd:language", xsdLanguage);
- typemap.setValue("xsd:nmtoken", xsdNMTOKEN);
- typemap.setValue("xsd:nmtokens", xsdNMTOKENS);
- typemap.setValue("xsd:name", xsdName);
- typemap.setValue("xsd:ncname", xsdNCName);
- typemap.setValue("xsd:id", xsdID);
- typemap.setValue("xsd:idref", xsdIDREF);
- typemap.setValue("xsd:idrefs", xsdIDREFS);
- typemap.setValue("xsd:entity", xsdENTITY);
- typemap.setValue("xsd:entities", xsdENTITIES);
- typemap.setValue("xsd:integer", xsdInteger);
- typemap.setValue("xsd:nonpositiveinteger", xsdNonPositiveInteger);
- typemap.setValue("xsd:negativeinteger", xsdNegativeInteger);
- typemap.setValue("xsd:long", xsdLong);
- typemap.setValue("xsd:int", xsdInt);
- typemap.setValue("xsd:short", xsdShort);
- typemap.setValue("xsd:byte", xsdByte);
- typemap.setValue("xsd:nonnegativeinteger", xsdNonNegativeInteger);
- typemap.setValue("xsd:unsignedlong", xsdUnsignedLong);
- typemap.setValue("xsd:unsignedint", xsdUnsignedInt);
- typemap.setValue("xsd:unsignedshort", xsdUnsignedShort);
- typemap.setValue("xsd:unsignedbyte", xsdUnsignedByte);
- typemap.setValue("xsd:positiveinteger", xsdPositiveInteger);
- typemap.setValue("tns:rawdatafile", tnsRawDataFile);
- typemap.setValue("tns:csvdatafile", tnsCsvDataFile);
- typemap.setValue("tns:espstringarray", tnsEspStringArray);
- typemap.setValue("tns:espintarray", tnsEspIntArray);
- typemap.setValue("tns:xmldataset", tnsXmlDataSet);
- }
- wsEclType wsEclTypeTranslator::translate(const char *type)
- {
- if (!type || !*type)
- return wsEclTypeUnknown;
- StringBuffer value(type);
- wsEclType *ret = typemap.getValue(value.toLowerCase().str());
- return (ret) ? *ret : wsEclTypeUnknown;
- }
- const char *wsEclToXsdTypes(wsEclType from);
- static wsEclTypeTranslator *translator = NULL;
- const char *wsEclToXsdTypes(wsEclType from)
- {
- if (from < maxWsEclType)
- return wsEclXsdTypes[from];
- return wsEclXsdTypes[wsEclTypeUnknown];
- }
- const char *translateXsdType(const char *from)
- {
- return wsEclToXsdTypes(translator->translate(from));
- }
- // Interestingly, only single quote needs to HTML escape.
- // ", <, >, & don't need escape.
- static void escapeSingleQuote(StringBuffer& src, StringBuffer& escaped)
- {
- for (const char* p = src.str(); *p!=0; p++)
- {
- if (*p == '\'')
- escaped.append("'");
- else
- escaped.append(*p);
- }
- }
- static void appendServerAddress(StringBuffer &s, IPropertyTree &env, IPropertyTree &server, const char *daliAddress)
- {
- const char *port = server.queryProp("@port");
- if (port && streq(port, "0")) //roxie on demand
- return;
- const char *netAddress = server.queryProp("@netAddress");
- if (!netAddress && server.hasProp("@computer"))
- {
- VStringBuffer xpath("Hardware/Computer[@name='%s']/@netAddress", server.queryProp("@computer"));
- netAddress = env.queryProp(xpath.str());
- }
- if ((!netAddress || *netAddress=='.') && daliAddress && *daliAddress)
- netAddress = daliAddress;
- if (!netAddress || !*netAddress)
- return;
- if (s.length())
- s.append('|');
- s.append(netAddress).append(':').append(port ? port : "9876");
- }
- bool CWsEclService::init(const char * name, const char * type, IPropertyTree * cfg, const char * process)
- {
- StringBuffer xpath;
- xpath.appendf("Software/EspProcess[@name='%s']", process);
- IPropertyTree *prc = cfg->queryPropTree(xpath.str());
- if (!prc)
- throw MakeStringException(-1, "ESP Process %s not configured", process);
- auth_method.set(prc->queryProp("Authentication/@method"));
- portal_URL.set(prc->queryProp("@protalurl"));
- StringBuffer daliAddress;
- const char *daliServers = prc->queryProp("@daliServers");
- if (daliServers)
- {
- while (*daliServers && !strchr(":;,", *daliServers))
- daliAddress.append(*daliServers++);
- }
- Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
- Owned<IConstEnvironment> environment = factory->openEnvironmentByFile();
- Owned<IPropertyTree> pRoot = &environment->getPTree();
- xpath.clear().appendf("EspService[@name='%s']/VIPS", name);
- IPropertyTree *vips = prc->queryPropTree(xpath.str());
- Owned<IPropertyTreeIterator> it = pRoot->getElements("Software/RoxieCluster");
- ForEach(*it)
- {
- const char *name = it->query().queryProp("@name");
- if (connMap.getValue(name)) //bad config?
- continue;
- bool loadBalanced = false;
- StringBuffer list;
- const char *vip = NULL;
- if (vips)
- vip = vips->queryProp(xpath.clear().appendf("ProcessCluster[@name='%s']/@vip", name).str());
- if (vip && *vip)
- {
- list.append(vip);
- loadBalanced = true;
- }
- else
- {
- Owned<IPropertyTreeIterator> servers = it->query().getElements("RoxieServerProcess");
- ForEach(*servers)
- appendServerAddress(list, *pRoot, servers->query(), daliAddress.str());
- }
- if (list.length())
- {
- Owned<ISmartSocketFactory> sf = createSmartSocketFactory(list.str(), !loadBalanced);
- connMap.setValue(name, sf.get());
- }
- }
- translator = new wsEclTypeTranslator();
- return true;
- }
- CWsEclService::~CWsEclService()
- {
- if (translator)
- delete translator;
- }
- void CWsEclBinding::getNavigationData(IEspContext &context, IPropertyTree & data)
- {
- DBGLOG("CScrubbedXmlBinding::getNavigationData");
- StringArray wsModules;
- StringBuffer mode;
- data.addProp("@viewType", "wsecl_tree");
- data.addProp("@action", "NavMenuEvent");
- data.addProp("@appName", "WsECL 3.0");
- ensureNavDynFolder(data, "Targets", "Targets", "root=true", NULL);
- }
- IPropertyTree * getQueryRegistries()
- {
- Owned<IRemoteConnection> conn = querySDS().connect("/QuerySets/", myProcessSession(), RTM_LOCK_READ|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT);
- return conn->getRoot();
- }
- void CWsEclBinding::getRootNavigationFolders(IEspContext &context, IPropertyTree & data)
- {
- DBGLOG("CScrubbedXmlBinding::getNavigationData");
- StringArray wsModules;
- StringBuffer mode;
- data.addProp("@viewType", "wsecl_tree");
- data.addProp("@action", "NavMenuEvent");
- data.addProp("@appName", "WsECL 3.0");
- Owned<IStringIterator> targets = getTargetClusters(NULL, NULL);
- SCMStringBuffer target;
- ForEach(*targets)
- {
- VStringBuffer parms("queryset=%s", targets->str(target).str());
- ensureNavDynFolder(data, target.str(), target.str(), parms.str(), NULL);
- }
- }
- void CWsEclBinding::addQueryNavLink(IPropertyTree &data, IPropertyTree *query, const char *setname, const char *qname)
- {
- if (!query)
- return;
- if (query->getPropBool("@suspended"))
- return;
- if (!qname || !*qname)
- qname = query->queryProp("@id");
- if (!setname || !*setname || !qname || !*qname)
- return;
- StringBuffer navPath;
- navPath.appendf("/WsEcl/tabview/query/%s/%s", setname, qname);
- ensureNavLink(data, qname, navPath.str(), qname, "menu2", navPath.str());
- }
- void CWsEclBinding::getQueryNames(IPropertyTree* settree, const char *id, const char *qname, StringArray& qnames)
- {
- if (!id || !*id)
- return;
- VStringBuffer xpath("Query[@id='%s']", id);
- IPropertyTree *query = settree->queryPropTree(xpath.str());
- if (query->getPropBool("@isLibrary") || query->getPropBool("@suspended"))
- return;
- if (!qname || !*qname)
- qname = query->queryProp("@id");
- if (!qname || !*qname)
- return;
- qnames.append(qname);
- }
- void CWsEclBinding::getDynNavData(IEspContext &context, IProperties *params, IPropertyTree & data)
- {
- if (!params)
- return;
- data.setPropBool("@volatile", true);
- if (params->getPropBool("root", false))
- {
- getRootNavigationFolders(context, data);
- }
- else if (params->hasProp("queryset"))
- {
- const char *setname = params->queryProp("queryset");
- if (!setname || !*setname)
- return;
- Owned<IPropertyTree> settree = getQueryRegistry(setname, true);
- if (params->hasProp("QueryList"))
- {
- Owned<IPropertyTreeIterator> iter = settree->getElements("Query");
- ForEach(*iter)
- {
- if (!iter->query().getPropBool("@isLibrary"))
- addQueryNavLink(data, &iter->query(), setname);
- }
- }
- else
- {
- StringArray qnames;
- Owned<IPropertyTreeIterator> iter = settree->getElements("Alias");
- ForEach(*iter)
- {
- IPropertyTree &alias = iter->query();
- getQueryNames(settree, alias.queryProp("@id"), alias.queryProp("@name"), qnames);
- }
- if (qnames.ordinality())
- {
- qnames.sort(strptrcmp);
- ForEachItemIn(i,qnames)
- {
- StringBuffer navPath;
- const char *qname = qnames.item(i);
- navPath.appendf("/WsEcl/tabview/query/%s/%s", setname, qname);
- ensureNavLink(data, qname, navPath.str(), qname, "menu2", navPath.str());
- }
- }
- }
- }
- }
- static inline bool isPathSeparator(char sep)
- {
- return (sep=='\\')||(sep=='/');
- }
- static inline const char *skipPathNodes(const char *&s, int skip)
- {
- if (s) {
- while (*s) {
- if (isPathSeparator(*s++))
- if (!skip--)
- return s;
- }
- }
- return NULL;
- }
- static inline const char *nextPathNode(const char *&s, StringBuffer &node, int skip=0)
- {
- if (skip)
- skipPathNodes(s, skip);
- if (s) while (*s) {
- if (isPathSeparator(*s))
- return s++;
- node.append(*s++);
- }
- return NULL;
- }
- static inline const char *firstPathNode(const char *&s, StringBuffer &node)
- {
- if (s && isPathSeparator(*s))
- s++;
- return nextPathNode(s, node);
- }
- static void splitPathTailAndExt(const char *s, StringBuffer &path, StringBuffer &tail, StringBuffer *ext)
- {
- if (s)
- {
- const char *finger=s;
- while (*finger++);
- const char *extpos=finger;
- const char *tailpos=s;
- while (s!=finger && tailpos==s)
- {
- switch (*finger)
- {
- case '.':
- if (ext && *extpos!='.')
- extpos=finger;
- break;
- case '/':
- case '\\':
- tailpos=finger;
- break;
- }
- finger--;
- }
- if (ext && *extpos=='.')
- ext->append(extpos+1);
- if (tailpos!=s)
- path.append(tailpos - s, s);
- if (strchr("\\/", *tailpos))
- tailpos++;
- tail.append(extpos - tailpos, tailpos);
- }
- }
- static void splitLookupInfo(IProperties *parms, const char *&s, StringBuffer &wuid, StringBuffer &qs, StringBuffer &qid)
- {
- StringBuffer lookup;
- nextPathNode(s, lookup);
- if (strieq(lookup.str(), "query"))
- {
- nextPathNode(s, qs);
- nextPathNode(s, qid);
- }
- else if (strieq(lookup.str(), "wuid"))
- {
- nextPathNode(s, wuid);
- qs.append(parms->queryProp("qset"));
- qid.append(parms->queryProp("qname"));
- }
- }
- void CWsEclBinding::xsltTransform(const char* xml, unsigned int len, const char* xslFileName, IProperties *params, StringBuffer& ret)
- {
- Owned<IXslProcessor> proc = getXslProcessor();
- Owned<IXslTransform> trans = proc->createXslTransform();
- trans->setXmlSource(xml, len);
- StringBuffer xslpath(getCFD());
- xslpath.append(xslFileName);
- trans->loadXslFromFile(xslpath.str());
- if (params)
- {
- Owned<IPropertyIterator> it = params->getIterator();
- for (it->first(); it->isValid(); it->next())
- {
- const char *key = it->getPropKey();
- //set parameter in the XSL transform skipping over the @ prefix, if any
- const char* paramName = *key == '@' ? key+1 : key;
- trans->setParameter(paramName, StringBuffer().append('\'').append(params->queryProp(key)).append('\'').str());
- }
- }
- trans->transform(ret);
- }
- StringBuffer &CWsEclBinding::generateNamespace(IEspContext &context, CHttpRequest* request, const char *serv, const char *method, StringBuffer &ns)
- {
- ns.append("urn:hpccsystems:ecl:");
- if (method && *method)
- ns.appendLower(strlen(method), method);
- return ns;
- }
- #define REQXML_ROOT 0x0001
- #define REQXML_SAMPLE_DATA 0x0002
- #define REQXML_TRIM 0x0004
- #define REQXML_ESCAPEFORMATTERS 0x0008
- static void buildReqXml(StringStack& parent, IXmlType* type, StringBuffer& out, const char* tag, IPropertyTree *parmtree, unsigned flags, const char* ns=NULL)
- {
- assertex(type!=NULL);
- if (!parmtree && (flags & REQXML_TRIM) && !(flags & REQXML_ROOT))
- return;
- const char* typeName = type->queryName();
- if (type->isComplexType())
- {
- if (typeName && std::find(parent.begin(),parent.end(),typeName) != parent.end())
- return; // recursive
- int startlen = out.length();
- out.appendf("<%s", tag);
- if (ns)
- out.append(' ').append(ns);
- int taglen=out.length()+1;
- for (size_t i=0; i<type->getAttrCount(); i++)
- {
- IXmlAttribute* attr = type->queryAttr(i);
- if (parmtree)
- {
- StringBuffer attrpath("@");
- const char *attrval = parmtree->queryProp(attrpath.append(attr->queryName()).str());
- if (attrval)
- out.appendf(" %s='", attr->queryName()).append(attrval);
- }
- else
- {
- out.appendf(" %s='", attr->queryName());
- attr->getSampleValue(out);
- }
- out.append('\'');
- }
- out.append('>');
- if (typeName)
- parent.push_back(typeName);
- int flds = type->getFieldCount();
- switch (type->getSubType())
- {
- case SubType_Complex_SimpleContent:
- assertex(flds==0);
- if (parmtree)
- {
- const char *attrval = parmtree->queryProp(NULL);
- if (attrval)
- out.append(attrval);
- }
- else if (flags & REQXML_SAMPLE_DATA)
- type->queryFieldType(0)->getSampleValue(out,tag);
- break;
- default:
- for (int idx=0; idx<flds; idx++)
- {
- IPropertyTree *childtree = NULL;
- const char *childname = type->queryFieldName(idx);
- if (parmtree)
- childtree = parmtree->queryPropTree(childname);
- buildReqXml(parent,type->queryFieldType(idx), out, childname, childtree, flags & ~REQXML_ROOT);
- }
- break;
- }
- if (typeName)
- parent.pop_back();
- if ((flags & REQXML_TRIM) && !(flags & REQXML_ROOT) && out.length()==taglen)
- out.setLength(startlen);
- else
- out.appendf("</%s>",tag);
- }
- else if (type->isArray())
- {
- if (typeName && std::find(parent.begin(),parent.end(),typeName) != parent.end())
- return; // recursive
- const char* itemName = type->queryFieldName(0);
- IXmlType* itemType = type->queryFieldType(0);
- if (!itemName || !itemType)
- throw MakeStringException(-1,"*** Invalid array definition: tag=%s, itemName=%s", tag, itemName?itemName:"NULL");
- if (typeName)
- parent.push_back(typeName);
- int startlen = out.length();
- out.appendf("<%s", tag);
- if (ns)
- out.append(' ').append(ns);
- out.append(">");
- int taglen=out.length();
- if (parmtree)
- {
- VStringBuffer countpath("%s/itemcount", itemName);
- const char *countstr=parmtree->queryProp(countpath.str());
- if (countstr && *countstr)
- {
- int count = atoi(countstr);
- for (int idx=0; idx<count; idx++)
- {
- StringBuffer itempath;
- itempath.append(itemName).append(idx);
- IPropertyTree *itemtree = parmtree->queryPropTree(itempath.str());
- if (itemtree)
- buildReqXml(parent,itemType,out,itemName, itemtree, flags & ~REQXML_ROOT);
- }
- }
- else if (parmtree->hasProp(itemName))
- {
- Owned<IPropertyTreeIterator> items = parmtree->getElements(itemName);
- ForEach(*items)
- buildReqXml(parent,itemType,out,itemName, &items->query(), flags & ~REQXML_ROOT);
- }
- else
- {
- const char *s = parmtree->queryProp(NULL);
- if (s && *s)
- {
- StringArray items;
- items.appendList(s, "\n");
- ForEachItemIn(i, items)
- appendXMLTag(out, itemName, items.item(i));
- }
- }
- }
- else
- buildReqXml(parent,itemType,out,itemName, NULL, flags & ~REQXML_ROOT);
- if (typeName)
- parent.pop_back();
- if ((flags & REQXML_TRIM) && !(flags & REQXML_ROOT) && out.length()==taglen)
- out.setLength(startlen);
- else
- out.appendf("</%s>",tag);
- }
- else // simple type
- {
- StringBuffer parmval;
- if (parmtree)
- parmval.append(parmtree->queryProp(NULL));
- if (!parmval.length() && (flags & REQXML_SAMPLE_DATA))
- type->getSampleValue(parmval, NULL);
-
- if (parmval.length() || !(flags&REQXML_TRIM))
- {
- if (strieq(typeName, "boolean"))
- {
- if (!strieq(parmval, "default"))
- {
- out.appendf("<%s>", tag);
- if (parmval.length())
- out.append((strieq(parmval.str(),"1")||strieq(parmval.str(),"true")||strieq(parmval.str(), "on")) ? '1' : '0');
- out.appendf("</%s>", tag);
- }
- }
- else
- {
- out.appendf("<%s>", tag);
- out.append(parmval);
- out.appendf("</%s>", tag);
- }
- }
- }
- }
- inline void indenter(StringBuffer &s, int count)
- {
- s.appendN(count*3, ' ');
- }
- IException *MakeJSONValueException(int code, const char *start, const char *pos, const char *tail, const char *intro="Invalid json format: ")
- {
- StringBuffer s(intro);
- s.append(pos-start, start).append('^').append(pos);
- if (tail && *tail)
- s.append(" - ").append(tail);
- return MakeStringException(code, "%s", s.str());
- }
- inline StringBuffer &jsonNumericNext(StringBuffer &s, const char *&c, bool &allowDecimal, bool &allowExponent, const char *start)
- {
- if (isdigit(*c))
- s.append(*c++);
- else if ('.'==*c)
- {
- if (!allowDecimal || !allowExponent)
- throw MakeJSONValueException(-1, start, c, "Unexpected decimal");
- allowDecimal=false;
- s.append(*c++);
- }
- else if ('e'==*c || 'E'==*c)
- {
- if (!allowExponent)
- throw MakeJSONValueException(-1, start, c, "Unexpected exponent");
- allowDecimal=false;
- allowExponent=false;
- s.append(*c++);
- if ('-'==*c || '+'==*c)
- s.append(*c++);
- if (!isdigit(*c))
- throw MakeJSONValueException(-1, start, c, "Unexpected token");
- }
- else
- throw MakeJSONValueException(-1, start, c, "Unexpected token");
- return s;
- }
- inline StringBuffer &jsonNumericStart(StringBuffer &s, const char *&c, const char *start)
- {
- if ('-'==*c)
- return jsonNumericStart(s.append(*c++), c, start);
- else if ('0'==*c)
- {
- s.append(*c++);
- if (*c && '.'!=*c)
- throw MakeJSONValueException(-1, start, c, "Unexpected token");
- }
- else if (isdigit(*c))
- s.append(*c++);
- else
- throw MakeJSONValueException(-1, start, c, "Unexpected token");
- return s;
- }
- StringBuffer &appendJSONNumericString(StringBuffer &s, const char *value, bool allowDecimal)
- {
- if (!value || !*value)
- return s.append("null");
- bool allowExponent = allowDecimal;
- const char *pos = value;
- jsonNumericStart(s, pos, value);
- while (*pos)
- jsonNumericNext(s, pos, allowDecimal, allowExponent, value);
- return s;
- }
- inline const char *jsonNewline(unsigned flags){return ((flags & REQXML_ESCAPEFORMATTERS) ? "\\n" : "\n");}
- static void buildJsonMsg(StringStack& parent, IXmlType* type, StringBuffer& out, const char* tag, IPropertyTree *parmtree, unsigned flags, int &indent)
- {
- assertex(type!=NULL);
- if (flags & REQXML_ROOT)
- {
- out.append("{");
- out.append(jsonNewline(flags));
- indent++;
- }
- const char* typeName = type->queryName();
- if (type->isComplexType())
- {
- if (typeName && std::find(parent.begin(),parent.end(),typeName) != parent.end())
- return; // recursive
- int startlen = out.length();
- indenter(out, indent++);
- if (tag)
- out.appendf("\"%s\": {", tag).append(jsonNewline(flags));
- else
- out.append("{").append(jsonNewline(flags));
- int taglen=out.length()+1;
- if (typeName)
- parent.push_back(typeName);
- if (type->getSubType()==SubType_Complex_SimpleContent)
- {
- if (parmtree)
- {
- const char *attrval = parmtree->queryProp(NULL);
- indenter(out, indent);
- out.appendf("\"%s\" ", (attrval) ? attrval : "");
- }
- else if (flags & REQXML_SAMPLE_DATA)
- {
- indenter(out, indent);
- out.append("\"");
- type->queryFieldType(0)->getSampleValue(out,tag);
- out.append("\" ");
- }
- }
- else
- {
- bool first=true;
- int flds = type->getFieldCount();
- for (int idx=0; idx<flds; idx++)
- {
- if (first)
- first=false;
- else
- out.append(",").append(jsonNewline(flags));
- IPropertyTree *childtree = NULL;
- const char *childname = type->queryFieldName(idx);
- if (parmtree)
- childtree = parmtree->queryPropTree(childname);
- buildJsonMsg(parent, type->queryFieldType(idx), out, childname, childtree, flags & ~REQXML_ROOT, indent);
- }
- out.append(jsonNewline(flags));
- }
- if (typeName)
- parent.pop_back();
- indenter(out, indent--);
- out.append("}");
- }
- else if (type->isArray())
- {
- if (typeName && std::find(parent.begin(),parent.end(),typeName) != parent.end())
- return; // recursive
- const char* itemName = type->queryFieldName(0);
- IXmlType* itemType = type->queryFieldType(0);
- if (!itemName || !itemType)
- throw MakeStringException(-1,"*** Invalid array definition: tag=%s, itemName=%s", tag, itemName?itemName:"NULL");
- if (typeName)
- parent.push_back(typeName);
- int startlen = out.length();
- indenter(out, indent++);
- if (tag)
- out.appendf("\"%s\": {%s", tag, jsonNewline(flags));
- else
- out.append("{").append(jsonNewline(flags));
- indenter(out, indent++);
- out.appendf("\"%s\": [", itemName).append(jsonNewline(flags));
- indent++;
- int taglen=out.length();
- if (parmtree)
- {
- VStringBuffer countpath("%s/itemcount", itemName);
- const char *countstr=parmtree->queryProp(countpath.str());
- if (countstr && *countstr)
- {
- bool first=true;
- int count = atoi(countstr);
- for (int idx=0; idx<count; idx++)
- {
- if (first)
- first=false;
- else
- out.append(",").append(jsonNewline(flags));
- StringBuffer itempath;
- itempath.append(itemName).append(idx);
- IPropertyTree *itemtree = parmtree->queryPropTree(itempath.str());
- if (itemtree)
- buildJsonMsg(parent,itemType,out, NULL, itemtree, flags & ~REQXML_ROOT, indent);
- }
- out.append(jsonNewline(flags));
- }
- else
- {
- Owned<IPropertyTreeIterator> items = parmtree->getElements(itemName);
- bool first=true;
- ForEach(*items)
- {
- if (first)
- first=false;
- else
- out.append(",").append(jsonNewline(flags));
- buildJsonMsg(parent,itemType,out, NULL, &items->query(), flags & ~REQXML_ROOT, indent);
- }
- out.append(jsonNewline(flags));
- }
- }
- else
- buildJsonMsg(parent, itemType, out, NULL, NULL, flags & ~REQXML_ROOT, indent);
- indenter(out, indent--);
- out.append("]").append(jsonNewline(flags));
- if (typeName)
- parent.pop_back();
- indenter(out, indent--);
- out.append("}");
- }
- else // simple type
- {
- const char *parmval = (parmtree) ? parmtree->queryProp(NULL) : NULL;
- indenter(out, indent);
- out.appendf("\"%s\": ", tag);
- if (parmval)
- {
- const char *tname = type->queryName();
- //TBD: HACK
- if (!strnicmp(tname, "real", 4) ||
- !strnicmp(tname, "dec", 3) ||
- !strnicmp(tname, "double", 6) ||
- !strnicmp(tname, "float", 5))
- appendJSONNumericString(out, parmval, true);
- else if (!strnicmp(tname, "int", 3))
- appendJSONNumericString(out, parmval, false);
- else if (!strnicmp(tname, "bool", 4))
- appendJSONValue(out, NULL, (bool)('1'==*parmval || strieq(parmval, "true")));
- else
- appendJSONValue(out, NULL, parmval);
- }
- else if (flags & REQXML_SAMPLE_DATA)
- {
- out.append('\"');
- type->getSampleValue(out,NULL);
- out.append('\"');
- }
- else
- out.append("null");
- }
- if (flags & REQXML_ROOT)
- out.append(jsonNewline(flags)).append("}");
- }
- static inline StringBuffer &appendNamespaceSpecificString(StringBuffer &dest, const char *src)
- {
- if (src)
- while(*src){
- dest.append((const char)(isspace(*src) ? '_' : tolower(*src)));
- src++;
- }
- return dest;
- }
- void buildSampleDataset(StringBuffer &xml, IPropertyTree *xsdtree, const char *service, const char *method, const char *resultname)
- {
- StringBuffer schemaXml;
- toXML(xsdtree, schemaXml);
- Owned<IXmlSchema> schema = createXmlSchemaFromString(schemaXml);
- if (schema.get())
- {
- IXmlType* type = schema->queryElementType("Dataset");
- if (type)
- {
- StringBuffer ns("xmlns=\"urn:hpccsystems:ecl:");
- appendNamespaceSpecificString(ns, method).append(":result:");
- appendNamespaceSpecificString(ns, resultname);
- ns.append('\"');
- StringStack parent;
- buildReqXml(parent, type, xml, "Dataset", NULL, REQXML_SAMPLE_DATA, ns.str());
- }
- }
- }
- void CWsEclBinding::buildSampleResponseXml(StringBuffer& msg, IEspContext &context, CHttpRequest* request, WsEclWuInfo &wsinfo)
- {
- StringBuffer element;
- element.append(wsinfo.queryname.sget()).append("Response");
- StringBuffer xsds;
- wsinfo.getSchemas(xsds);
- msg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- if (context.queryRequestParameters()->hasProp("display"))
- msg.append("<?xml-stylesheet type=\"text/xsl\" href=\"/esp/xslt/xmlformatter.xsl\"?>");
- msg.append('<').append(element.str()).append(" xmlns=\"urn:hpccsystems:ecl:");
- msg.appendLower(wsinfo.queryname.length(), wsinfo.queryname.sget()).append("\">");
- msg.append("<Results><Result>");
- Owned<IPropertyTree> xsds_tree;
- if (xsds.length())
- xsds_tree.setown(createPTreeFromXMLString(xsds.str()));
- if (xsds_tree)
- {
- Owned<IPropertyTreeIterator> result_xsds =xsds_tree->getElements("Result");
- ForEach (*result_xsds)
- buildSampleDataset(msg, result_xsds->query().queryPropTree("xs:schema"), wsinfo.qsetname.sget(), wsinfo.queryname.sget(), result_xsds->query().queryProp("@name"));
- }
- msg.append("</Result></Results>");
- msg.append("</").append(element.str()).append('>');
- }
- int CWsEclBinding::getWsEclLinks(IEspContext &context, CHttpRequest* request, CHttpResponse* response, WsEclWuInfo &wsinfo)
- {
- StringBuffer xml;
- xml.append("<links>");
- xml.append("<version>3</version>");
- xml.append("<path>").append(wsinfo.qsetname.sget()).append("</path>");
- xml.append("<query>").append(wsinfo.queryname.sget()).append("</query>");
- StringBuffer xsds;
- wsinfo.getSchemas(xsds);
- Owned<IPropertyTree> xsdtree;
- if (xsds.length())
- xsdtree.setown(createPTreeFromXMLString(xsds.str()));
- if (xsdtree)
- {
- xml.append("<input_datasets>");
- Owned<IPropertyTreeIterator> input_xsds =xsdtree->getElements("Input");
- ForEach (*input_xsds)
- {
- xml.append("<dataset>");
- xml.append("<name>").append(input_xsds->query().queryProp("@sname")).append("</name>");
- xml.append("</dataset>");
- }
- xml.append("</input_datasets>");
- xml.append("<result_datasets>");
- Owned<IPropertyTreeIterator> result_xsds =xsdtree->getElements("Result");
- ForEach (*result_xsds)
- {
- xml.append("<dataset>");
- xml.append("<name>").append(result_xsds->query().queryProp("@sname")).append("</name>");
- xml.append("</dataset>");
- }
- xml.append("</result_datasets>");
- }
- xml.append("</links>");
- Owned<IXslProcessor> xslp = getXslProcessor();
- Owned<IXslTransform> xform = xslp->createXslTransform();
- xform->loadXslFromFile(StringBuffer(getCFD()).append("./xslt/wsecl3_links.xslt").str());
- xform->setXmlSource(xml.str(), xml.length());
- StringBuffer page;
- xform->transform(page);
- response->setContent(page);
- response->setContentType("text/html; charset=UTF-8");
- response->setStatus(HTTP_STATUS_OK);
- response->send();
- return 0;
- }
- int CWsEclBinding::getWsEcl2TabView(CHttpRequest* request, CHttpResponse* response, const char *thepath)
- {
- IEspContext *context = request->queryContext();
- IProperties *parms = request->queryParameters();
- StringBuffer wuid;
- StringBuffer qs;
- StringBuffer qid;
- splitLookupInfo(request->queryParameters(), thepath, wuid, qs, qid);
- WsEclWuInfo wsinfo(wuid.str(), qs.str(), qid.str(), context->queryUserId(), context->queryPassword());
- StringBuffer xml;
- xml.append("<tabview>");
- xml.append("<version>3</version>");
- xml.appendf("<wuid>%s</wuid>", wsinfo.wuid.sget());
- xml.appendf("<qset>%s</qset>", wsinfo.qsetname.sget());
- xml.appendf("<qname>%s</qname>", wsinfo.queryname.sget());
- StringBuffer xsds;
- wsinfo.getSchemas(xsds);
- Owned<IPropertyTree> xsdtree;
- if (xsds.length())
- xsdtree.setown(createPTreeFromXMLString(xsds.str()));
- if (xsdtree)
- {
- xml.append("<input_datasets>");
- Owned<IPropertyTreeIterator> input_xsds =xsdtree->getElements("Input");
- ForEach (*input_xsds)
- {
- xml.append("<dataset>");
- xml.append("<name>").append(input_xsds->query().queryProp("@name")).append("</name>");
- xml.append("</dataset>");
- }
- xml.append("</input_datasets>");
- xml.append("<result_datasets>");
- Owned<IPropertyTreeIterator> result_xsds =xsdtree->getElements("Result");
- ForEach (*result_xsds)
- {
- xml.append("<dataset>");
- xml.append("<name>").append(result_xsds->query().queryProp("@name")).append("</name>");
- xml.append("</dataset>");
- }
- xml.append("</result_datasets>");
- }
- xml.append("</tabview>");
- StringBuffer html;
- xsltTransform(xml.str(), xml.length(), "./xslt/wsecl3_tabview.xsl", NULL, html);
- response->setStatus("200 OK");
- response->setContent(html.str());
- response->setContentType("text/html");
- response->send();
- return 0;
- }
- void CWsEclBinding::appendSchemaNamespaces(IPropertyTree *namespaces, IEspContext &ctx, CHttpRequest* req, const char *service, const char *method)
- {
- WsEclWuInfo *wsinfo = (WsEclWuInfo *) ctx.getBindingValue();
- if (wsinfo)
- appendSchemaNamespaces(namespaces, ctx, req, *wsinfo);
- }
- void CWsEclBinding::appendSchemaNamespaces(IPropertyTree *namespaces, IEspContext &ctx, CHttpRequest* req, WsEclWuInfo &wsinfo)
- {
- IProperties *parms = ctx.queryRequestParameters();
- StringBuffer xsds;
- wsinfo.getSchemas(xsds);
- Owned<IPropertyTree> xsdtree;
- if (xsds.length())
- xsdtree.setown(createPTreeFromXMLString(xsds.str()));
- if (xsdtree)
- {
- Owned<IPropertyTreeIterator> result_xsds =xsdtree->getElements("Result");
- int count=1;
- ForEach (*result_xsds)
- {
- const char *resultname = result_xsds->query().queryProp("@sname");
- StringBuffer urn("urn:hpccsystems:ecl:");
- appendNamespaceSpecificString(urn, wsinfo.queryname.get()).append(":result:");
- appendNamespaceSpecificString(urn, resultname);
- VStringBuffer nsxml("<namespace nsvar=\"ds%d\" ns=\"%s\" import=\"1\" location=\"../result/%s.xsd\"/>", count++, urn.toLowerCase().str(), resultname);
- namespaces->addPropTree("namespace", createPTreeFromXMLString(nsxml.str()));
- }
- }
- }
- StringBuffer &appendEclXsdName(StringBuffer &content, const char *name, bool istype=false)
- {
- if (name)
- {
- if (!strnicmp(name, "xs:", 3))
- content.append("xsd:").append(name+3);
- else
- {
- if (istype && !strchr(name, ':'))
- content.append("tns:");
- content.append(name);
- }
- }
- return content;
- }
- void appendEclXsdStartTag(StringBuffer &content, IPropertyTree *element, int indent, const char *attrstr=NULL, bool forceclose=false)
- {
- //while (indent--)
- // content.append('\t');
- const char *name = element->queryName();
- appendEclXsdName(content.append('<'), name);
- if (strieq(name, "xs:element"))
- {
- const char *elname=element->queryProp("@name");
- if (!elname || !*elname) //ecl bug?
- element->setProp("@name", "__unknown");
- if (!element->hasProp("@minOccurs"))
- content.append(' ').append("minOccurs=\"0\"");
- }
- if (attrstr)
- content.append(' ').append(attrstr);
- Owned<IAttributeIterator> attrs = element->getAttributes();
- ForEach(*attrs)
- {
- const char *attrname=attrs->queryName()+1;
- appendEclXsdName(content.append(' '), attrname);
- appendEclXsdName(content.append("=\""), attrs->queryValue(), !stricmp(attrname, "type")).append('\"');
- }
- if (forceclose || !element->hasChildren())
- content.append('/');
- content.append(">");
- }
- void appendEclXsdComplexType(StringArray &names, StringBuffer &content, IPropertyTree *element, int indent=0)
- {
- StringBuffer name("t_");
- ForEachItemIn(idx, names)
- {
- name.append(names.item(idx));
- }
- content.appendf("<xsd:complexType name=\"%s\">", name.str());
- Owned<IPropertyTreeIterator> children = element->getElements("*");
- ForEach(*children)
- {
- IPropertyTree &child = children->query();
- appendEclXsdStartTag(content, &child, indent);
- if (strieq(child.queryName(), "xs:sequence") || strieq(child.queryName(), "xs:all"))
- {
- Owned<IPropertyTreeIterator> els = child.getElements("xs:element");
- ForEach(*els)
- {
- IPropertyTree &el = els->query();
- StringBuffer typeattr;
- if (!el.hasProp("@type") && el.hasProp("xs:complexType") && el.hasProp("@name"))
- typeattr.appendf("type=\"tns:%s%s\"", name.str(), el.queryProp("@name"));
- appendEclXsdStartTag(content, &el, indent, typeattr.str(), true);
- }
- }
- if (child.hasChildren())
- {
- content.appendf("</");
- appendEclXsdName(content, child.queryName());
- content.append(">");
- }
- }
- content.append("</xsd:complexType>");
- }
- void appendEclXsdNestedComplexTypes(StringArray &names, StringBuffer &content, IPropertyTree *element, int indent=0)
- {
- if (element->hasChildren())
- {
- Owned<IPropertyTreeIterator> children = element->getElements("*");
- ForEach(*children)
- {
- if (element->hasProp("@name"))
- names.append(element->queryProp("@name"));
- appendEclXsdNestedComplexTypes(names, content, &children->query(), indent+1);
- if (element->hasProp("@name"))
- names.pop();
- }
- if (strieq(element->queryName(), "xs:complexType"))
- appendEclXsdComplexType(names, content, element, indent);
- }
- }
- void appendEclXsdSection(StringBuffer &content, IPropertyTree *element, int indent=0)
- {
- appendEclXsdStartTag(content, element, indent);
- if (element->hasChildren())
- {
- Owned<IPropertyTreeIterator> children = element->getElements("*");
- ForEach(*children)
- {
- appendEclXsdSection(content, &children->query(), indent+1);
- }
- appendEclXsdName(content.append("</"), element->queryName()).append('>');
- }
- }
- void appendEclInputXsds(StringBuffer &content, IPropertyTree *xsd, BoolHash &added)
- {
- Owned<IPropertyTreeIterator> it = xsd->getElements("xs:schema/*");
- const char *schema_name=xsd->queryProp("@name");
- if (schema_name && *schema_name)
- {
- ForEach (*it)
- {
- IPropertyTree &item = it->query();
- StringArray names;
- names.append(schema_name);
- appendEclXsdNestedComplexTypes(names, content, &item, 1);
- const char *aname = item.queryProp("@name");
- StringBuffer temp;
- const char *elname = item.getName(temp).str();
- if (!stricmp(aname, "dataset") || !added.getValue(aname))
- {
- StringBuffer temp;
- if (!stricmp(aname, "dataset"))
- {
- #if 0
- content.appendf("<xsd:complexType name=\"%s\"><xsd:sequence>", schema_name);
- IPropertyTreeIterator *children = item.getElements("xs:complexType/xs:sequence/*");
- ForEach(*children)
- {
- IPropertyTree &child = children->query();
- if (child.hasProp("@name") && !stricmp(child.queryProp("@name"), "Row"))
- {
- child.setProp("@minOccurs", "0");
- child.setProp("@maxOccurs", "unbounded");
- }
- //appendEclXsdSection(content, &child, 2);
- //toXML(&child, content);
- }
- content.appendf("</xsd:sequence></xsd:complexType>", aname);
- #endif
- }
- else
- {
- added.setValue(aname, true);
- appendEclXsdSection(content, &item, 1);
- //toXML(&item, content);
- }
- }
- }
- }
- }
- void CWsEclBinding::SOAPSectionToXsd(WsEclWuInfo &wsinfo, const char *parmXml, StringBuffer &schema, bool isRequest, IPropertyTree *xsdtree)
- {
- Owned<IPropertyTree> tree = createPTreeFromXMLString(parmXml, ipt_none, (XmlReaderOptions)(xr_ignoreWhiteSpace|xr_noRoot));
- schema.appendf("<xsd:element name=\"%s%s\">", wsinfo.queryname.sget(), isRequest ? "Request" : "Response");
- schema.append("<xsd:complexType>");
- schema.append("<xsd:all>");
- Owned<IPropertyTreeIterator> parts = tree->getElements("part");
- if (parts)
- {
- ForEach(*parts)
- {
- IPropertyTree &part = parts->query();
- const char *name=part.queryProp("@name");
- const char *ptype=part.queryProp("@type");
- StringBuffer type;
- if (!strnicmp(ptype, "xsd:", 4))
- {
- type.append(translateXsdType(part.queryProp("@type")));
- }
- else
- {
- StringBuffer xpath;
- StringBuffer xname(name);
- xpath.appendf("Input[@name='%s']",xname.toLowerCase().str());
- if (xsdtree->hasProp(xpath.str()))
- type.append("tns:t_").append(xname).append("Dataset");
- else
- type.append(translateXsdType(part.queryProp("@type")));
- }
- schema.appendf("<xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"%s\" type=\"%s\"", name, type.str());
- if (strieq(type.str(), "tns:XmlDataSet"))
- {
- schema.append(">"
- "<xsd:annotation><xsd:appinfo>"
- "<form formRows=\"25\" formCols=\"60\"/>"
- "</xsd:appinfo></xsd:annotation>"
- "</xsd:element>");
- }
- else
- schema.append("/>");
- }
- }
- schema.append("</xsd:all>");
- schema.append("</xsd:complexType>");
- schema.append("</xsd:element>");
- }
- int CWsEclBinding::getXsdDefinition(IEspContext &context, CHttpRequest *request, StringBuffer &content, const char *service, const char *method, bool mda)
- {
- WsEclWuInfo *wsinfo = (WsEclWuInfo *) context.getBindingValue();
- if (wsinfo)
- getXsdDefinition(context, request, content, *wsinfo);
- return 0;
- }
- int CWsEclBinding::getXsdDefinition(IEspContext &context, CHttpRequest *request, StringBuffer &content, WsEclWuInfo &wsinfo)
- {
- IProperties *httpparms=request->queryParameters();
- if (wsecl)
- {
- StringBuffer xsds;
- wsinfo.getSchemas(xsds);
- Owned<IPropertyTree> xsdtree;
- if (xsds.length())
- xsdtree.setown(createPTreeFromXMLString(xsds.str()));
- //common types
- content.append(
- "<xsd:complexType name=\"EspStringArray\">"
- "<xsd:sequence>"
- "<xsd:element name=\"Item\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>"
- "</xsd:sequence>"
- "</xsd:complexType>"
- "<xsd:complexType name=\"EspIntArray\">"
- "<xsd:sequence>"
- "<xsd:element name=\"Item\" type=\"xsd:int\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>"
- "</xsd:sequence>"
- "</xsd:complexType>"
- "<xsd:simpleType name=\"XmlDataSet\">"
- "<xsd:restriction base=\"xsd:string\"/>"
- "</xsd:simpleType>"
- "<xsd:simpleType name=\"CsvDataFile\">"
- "<xsd:restriction base=\"xsd:string\"/>"
- "</xsd:simpleType>"
- "<xsd:simpleType name=\"RawDataFile\">"
- "<xsd:restriction base=\"xsd:base64Binary\"/>"
- "</xsd:simpleType>");
- if (wsinfo.queryname.length()>0)
- {
- StringBuffer parmXml;
- if (wsinfo.getWsResource("SOAP", parmXml))
- {
- if (xsdtree)
- {
- BoolHash added;
- Owned<IPropertyTreeIterator> input_xsds =xsdtree->getElements("Input");
- ForEach (*input_xsds)
- {
- appendEclInputXsds(content, &input_xsds->query(), added);
- }
- }
- SOAPSectionToXsd(wsinfo, parmXml.str(), content, true, xsdtree);
- }
- content.appendf("<xsd:element name=\"%sResponse\">", wsinfo.queryname.sget());
- content.append("<xsd:complexType>");
- content.append("<xsd:all>");
- content.append("<xsd:element name=\"Exceptions\" type=\"tns:ArrayOfEspException\" minOccurs=\"0\"/>");
- Owned<IPropertyTreeIterator> result_xsds =xsdtree->getElements("Result");
- if (!result_xsds->first())
- {
- content.append("<xsd:element name=\"Results\" type=\"xsd:string\" minOccurs=\"0\"/>");
- }
- else
- {
- content.append(
- "<xsd:element name=\"Results\" minOccurs=\"0\">"
- "<xsd:complexType>"
- "<xsd:all>"
- "<xsd:element name=\"Result\">"
- "<xsd:complexType>"
- "<xsd:all>");
- int count=1;
- ForEach (*result_xsds)
- {
- content.appendf("<xsd:element ref=\"ds%d:Dataset\" minOccurs=\"0\"/>", count++);
- }
- content.append(
- "</xsd:all>"
- "</xsd:complexType>"
- "</xsd:element>"
- "</xsd:all>"
- "</xsd:complexType>"
- "</xsd:element>");
- }
- content.append("</xsd:all>");
- content.append("<xsd:attribute name=\"sequence\" type=\"xsd:int\"/>");
- content.append("</xsd:complexType>");
- content.append("</xsd:element>");
- }
- }
- return 0;
- }
- bool CWsEclBinding::getSchema(StringBuffer& schema, IEspContext &ctx, CHttpRequest* req, WsEclWuInfo &wsinfo)
- {
- Owned<IPropertyTree> namespaces = createPTree();
- appendSchemaNamespaces(namespaces, ctx, req, wsinfo);
- Owned<IPropertyTreeIterator> nsiter = namespaces->getElements("namespace");
-
- StringBuffer urn("urn:hpccsystems:ecl:");
- urn.appendLower(wsinfo.queryname.length(), wsinfo.queryname.sget());
- schema.appendf("<xsd:schema elementFormDefault=\"qualified\" targetNamespace=\"%s\" ", urn.str());
- schema.appendf(" xmlns:tns=\"%s\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"", urn.str());
- ForEach(*nsiter)
- {
- IPropertyTree &ns = nsiter->query();
- schema.appendf(" xmlns:%s=\"%s\"", ns.queryProp("@nsvar"), ns.queryProp("@ns"));
- }
- schema.append(">\n");
- ForEach(*nsiter)
- {
- IPropertyTree &ns = nsiter->query();
- if (ns.hasProp("@import"))
- schema.appendf("<xsd:import namespace=\"%s\" schemaLocation=\"%s\"/>", ns.queryProp("@ns"), ns.queryProp("@location"));
- }
- schema.append(
- "<xsd:complexType name=\"EspException\">"
- "<xsd:all>"
- "<xsd:element name=\"Code\" type=\"xsd:string\" minOccurs=\"0\"/>"
- "<xsd:element name=\"Audience\" type=\"xsd:string\" minOccurs=\"0\"/>"
- "<xsd:element name=\"Source\" type=\"xsd:string\" minOccurs=\"0\"/>"
- "<xsd:element name=\"Message\" type=\"xsd:string\" minOccurs=\"0\"/>"
- "</xsd:all>"
- "</xsd:complexType>\n"
- "<xsd:complexType name=\"ArrayOfEspException\">"
- "<xsd:sequence>"
- "<xsd:element name=\"Source\" type=\"xsd:string\" minOccurs=\"0\"/>"
- "<xsd:element name=\"Exception\" type=\"tns:EspException\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>"
- "</xsd:sequence>"
- "</xsd:complexType>\n"
- "<xsd:element name=\"Exceptions\" type=\"tns:ArrayOfEspException\"/>\n"
- );
- getXsdDefinition(ctx, req, schema, wsinfo);
- schema.append("<xsd:element name=\"string\" nillable=\"true\" type=\"xsd:string\" />\n");
- schema.append("</xsd:schema>");
- return true;
- }
- int CWsEclBinding::getGenForm(IEspContext &context, CHttpRequest* request, CHttpResponse* response, WsEclWuInfo &wsinfo, bool box)
- {
- IProperties *parms = request->queryParameters();
- StringBuffer page;
- Owned<IXslProcessor> xslp = getXslProcessor();
- StringBuffer v;
- StringBuffer formxml("<FormInfo>");
- appendXMLTag(formxml, "WUID", wsinfo.wuid.sget());
- appendXMLTag(formxml, "QuerySet", wsinfo.qsetname.sget());
- appendXMLTag(formxml, "QueryName", wsinfo.queryname.sget());
- appendXMLTag(formxml, "ClientVersion", v.appendf("%g",context.getClientVersion()).str());
- appendXMLTag(formxml, "RequestElement", v.clear().append(wsinfo.queryname).append("Request").str());
- Owned<IWuWebView> web = createWuWebView(*wsinfo.wu.get(), wsinfo.queryname.get(), getCFD(), true);
- if (web)
- {
- appendXMLTag(formxml, "Help", web->aggregateResources("HELP", v.clear()).str());
- appendXMLTag(formxml, "Info", web->aggregateResources("INFO", v.clear()).str());
- }
- context.addOptions(ESPCTX_ALL_ANNOTATION);
- if (box)
- {
- StringBuffer xmlreq;
- getWsEcl2XmlRequest(xmlreq, context, request, wsinfo, "xml", NULL, 0);
- if (xmlreq.length())
- {
- Owned<IPropertyTree> pretty = createPTreeFromXMLString(xmlreq.str(), ipt_ordered);
- if (pretty)
- {
- toXML(pretty, xmlreq.clear());
- formxml.append("<Request>");
- encodeUtf8XML(xmlreq, formxml);
- formxml.append("</Request>");
- }
- }
- }
- else
- getSchema(formxml, context, request, wsinfo);
- formxml.append("<CustomViews>");
- if (web)
- {
- StringArray views;
- web->getResultViewNames(views);
- ForEachItemIn(i, views)
- appendXMLTag(formxml, "Result", views.item(i));
- }
- formxml.append("</CustomViews>");
- formxml.append("</FormInfo>");
- Owned<IXslTransform> xform = xslp->createXslTransform();
- StringBuffer xslfile(getCFD());
- if (box)
- xslfile.append("./xslt/wsecl3_boxform.xsl");
- else
- xslfile.append("./xslt/wsecl3_form.xsl");
- xform->loadXslFromFile(xslfile.str());
- xform->setXmlSource(formxml.str(), formxml.length()+1);
- // pass params to form (excluding form and __querystring)
- StringBuffer params;
- if (!getUrlParams(context.queryRequestParameters(),params))
- params.appendf("%cver_=%g",(params.length()>0) ? '&' : '?', context.getClientVersion());
- xform->setStringParameter("queryParams", params.str());
- xform->setParameter("formOptionsAccess", "1");
- xform->setParameter("includeSoapTest", "1");
- xform->setParameter("useTextareaForStringArray", "1");
- // set the prop noDefaultValue param
- IProperties* props = context.queryRequestParameters();
- bool formInitialized = false;
- if (props) {
- Owned<IPropertyIterator> it = props->getIterator();
- for (it->first(); it->isValid(); it->next()) {
- const char* key = it->getPropKey();
- if (*key=='.') {
- formInitialized = true;
- break;
- }
- }
- }
- xform->setParameter("noDefaultValue", formInitialized ? "1" : "0");
- xform->transform(page);
- response->setContentType("text/html");
- response->setContent(page.str());
- response->send();
- return 0;
- }
- inline void appendParameterNode(StringBuffer &xpath, StringBuffer &node)
- {
- if (node.length())
- {
- if (isdigit(node.charAt(0)))
- xpath.setLength(xpath.length()-1);
- xpath.append(node);
- node.clear();
- }
- }
- void buildParametersXml(IPropertyTree *parmtree, IProperties *parms)
- {
- Owned<IPropertyIterator> it = parms->getIterator();
- ForEach(*it)
- {
- const char *key = it->getPropKey();
- const char *val = parms->queryProp(key);
- StringBuffer xpath;
- if (key && *key && val && *val)
- {
- bool isidx=false;
- StringBuffer node;
- for (int pos=0; key[pos]!=0; pos++)
- {
- if (key[pos]!='.')
- node.append(key[pos]);
- else
- {
- appendParameterNode(xpath, node);
- xpath.append('/');
- }
- }
- appendParameterNode(xpath, node);
- ensurePTree(parmtree, xpath.str());
- parmtree->setProp(xpath.str(), val);
- }
- }
- StringBuffer xml;
- toXML(parmtree, xml);
- DBGLOG("parmtree: %s", xml.str());
- }
- void appendValidInputBoxContent(StringBuffer &xml, const char *in)
- {
- //more later
- Owned<IPropertyTree> validAndFlat = createPTreeFromXMLString(in, ipt_ordered);
- toXML(validAndFlat, xml, 0, 0);
- }
- void CWsEclBinding::getWsEcl2XmlRequest(StringBuffer& soapmsg, IEspContext &context, CHttpRequest* request, WsEclWuInfo &wsinfo, const char *xmltype, const char *ns, unsigned flags)
- {
- Owned<IPropertyTree> parmtree = createPTree();
- IProperties *parms = context.queryRequestParameters();
- const char *boxInput = parms->queryProp("_boxFormInput");
- if (boxInput)
- {
- appendValidInputBoxContent(soapmsg, boxInput);
- return;
- }
- buildParametersXml(parmtree, parms);
- StringBuffer element;
- element.append(wsinfo.queryname.sget());
- element.append("Request");
- StringBuffer schemaXml;
- getSchema(schemaXml, context, request, wsinfo);
- DBGLOG("request schema: %s", schemaXml.str());
- Owned<IXmlSchema> schema = createXmlSchemaFromString(schemaXml);
- if (schema.get())
- {
- IXmlType* type = schema->queryElementType(element);
- if (type)
- {
- StringStack parent;
- buildReqXml(parent, type, soapmsg, (!stricmp(xmltype, "roxiexml")) ? wsinfo.queryname.sget() : element.str(), parmtree, flags|REQXML_ROOT, ns);
- }
- }
- }
- StringBuffer &appendJSONException(StringBuffer &s, IException *e, const char *objname="Exceptions", const char *arrayName = "Exception")
- {
- if (!e)
- return s;
- if (objname && *objname)
- appendJSONName(s, objname).append('{');
- if (arrayName && *arrayName)
- appendJSONName(s, arrayName).append('[');
- delimitJSON(s);
- s.append('{');
- appendJSONValue(s, "Code", e->errorCode());
- StringBuffer temp;
- appendJSONValue(s, "Message", e->errorMessage(temp).str());
- s.append('}');
- if (arrayName && *arrayName)
- s.append(']');
- if (objname && *objname)
- s.append('}');
- return s;
- }
- StringBuffer &appendJSONExceptions(StringBuffer &s, IMultiException *e, const char *objname="Exceptions", const char *arrayName = "Exception")
- {
- if (!e)
- return s;
- if (objname && *objname)
- appendJSONName(s, objname).append('{');
- if (arrayName && *arrayName)
- appendJSONName(s, arrayName).append('[');
- ForEachItemIn(i, *e)
- appendJSONException(s, &e->item(i), NULL, NULL);
- if (arrayName && *arrayName)
- s.append(']');
- if (objname && *objname)
- s.append('}');
- return s;
- }
- void CWsEclBinding::getWsEclJsonRequest(StringBuffer& jsonmsg, IEspContext &context, CHttpRequest* request, WsEclWuInfo &wsinfo, const char *xmltype, const char *ns, unsigned flags)
- {
- size32_t start = jsonmsg.length();
- try
- {
- Owned<IPropertyTree> parmtree = createPTree();
- IProperties *parms = context.queryRequestParameters();
- buildParametersXml(parmtree, parms);
- StringBuffer element;
- element.append(wsinfo.queryname.sget());
- element.append("Request");
- StringBuffer schemaXml;
- getSchema(schemaXml, context, request, wsinfo);
- DBGLOG("request schema: %s", schemaXml.str());
- Owned<IXmlSchema> schema = createXmlSchemaFromString(schemaXml);
- if (schema.get())
- {
- IXmlType* type = schema->queryElementType(element);
- if (type)
- {
- StringStack parent;
- int indent=0;
- buildJsonMsg(parent, type, jsonmsg, wsinfo.queryname.sget(), parmtree, flags|REQXML_ROOT|REQXML_ESCAPEFORMATTERS, indent);
- }
- }
- }
- catch (IException *e)
- {
- jsonmsg.setLength(start);
- appendJSONException(jsonmsg.append('{'), e);
- jsonmsg.append('}');
- }
- }
- void CWsEclBinding::getWsEclJsonResponse(StringBuffer& jsonmsg, IEspContext &context, CHttpRequest *request, const char *xml, WsEclWuInfo &wsinfo)
- {
- size32_t start = jsonmsg.length();
- try
- {
- Owned<IPropertyTree> parmtree = createPTreeFromXMLString(xml, ipt_none, (XmlReaderOptions)(xr_ignoreWhiteSpace|xr_ignoreNameSpaces));
- StringBuffer element;
- element.append(wsinfo.queryname.sget());
- element.append("Response");
- VStringBuffer xpath("Body/%s/Results/Result/Exception", element.str());
- Owned<IPropertyTreeIterator> exceptions = parmtree->getElements(xpath.str());
- jsonmsg.appendf("{\n \"%s\": {\n \"Results\": {\n", element.str());
- if (exceptions && exceptions->first())
- {
- jsonmsg.append(" \"Exceptions\": {\n \"Exception\": [\n");
- bool first=true;
- ForEach(*exceptions)
- {
- if (first)
- first=false;
- else
- jsonmsg.append(",\n");
- jsonmsg.appendf(" {\n \"Code\": %d,\n \"Message\": \"%s\"\n }", exceptions->query().getPropInt("Code"), exceptions->query().queryProp("Message"));
- }
- jsonmsg.append("\n ]\n }\n");
- }
- xpath.clear().append("Body/*[1]/Results/Result/Dataset");
- Owned<IPropertyTreeIterator> datasets = parmtree->getElements(xpath.str());
- ForEach(*datasets)
- {
- IPropertyTree &ds = datasets->query();
- const char *dsname = ds.queryProp("@name");
- if (dsname && *dsname)
- {
- StringBuffer schemaResult;
- wsinfo.getOutputSchema(schemaResult, dsname);
- if (schemaResult.length())
- {
- Owned<IXmlSchema> schema = createXmlSchemaFromString(schemaResult);
- if (schema.get())
- {
- IXmlType* type = schema->queryElementType("Dataset");
- if (type)
- {
- StringStack parent;
- int indent=4;
- StringBuffer outname(dsname);
- buildJsonMsg(parent, type, jsonmsg, outname.replace(' ', '_').str(), &ds, 0, indent);
- }
- }
- }
- }
- }
- jsonmsg.append(" }\n }\n}");
- }
- catch (IException *e)
- {
- jsonmsg.setLength(start);
- appendJSONException(jsonmsg.append('{'), e);
- jsonmsg.append('}');
- }
- }
- void CWsEclBinding::getSoapMessage(StringBuffer& soapmsg, IEspContext &context, CHttpRequest* request, WsEclWuInfo &wsinfo, unsigned flags)
- {
- soapmsg.append(
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""
- " xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\">"
- " <soap:Body>"
- );
- StringBuffer ns;
- ns.append("xmlns=\"urn:hpccsystems:ecl:").appendLower(wsinfo.queryname.length(), wsinfo.queryname.sget()).append('\"');
- getWsEcl2XmlRequest(soapmsg, context, request, wsinfo, "soap", ns.str(), flags);
- soapmsg.append("</soap:Body></soap:Envelope>");
- }
- int CWsEclBinding::getXmlTestForm(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *formtype, WsEclWuInfo &wsinfo)
- {
- getXmlTestForm(context, request, response, wsinfo, formtype);
- return 0;
- };
- inline StringBuffer &buildWsEclTargetUrl(StringBuffer &url, WsEclWuInfo &wsinfo, const char *type, const char *params)
- {
- url.append("/WsEcl/").append(type).append('/');
- if (wsinfo.qsetname.length() && wsinfo.queryname.length())
- url.append("query/").append(wsinfo.qsetname.get()).append('/').append(wsinfo.queryname.get());
- else
- url.append("wuid/").append(wsinfo.wuid.sget());
- if (params && *params)
- url.append('?').append(params);
- return url;
- }
- int CWsEclBinding::getXmlTestForm(IEspContext &context, CHttpRequest* request, CHttpResponse* response, WsEclWuInfo &wsinfo, const char *formtype)
- {
- IProperties *parms = context.queryRequestParameters();
- StringBuffer soapmsg, pageName;
- getSoapMessage(soapmsg, context, request, wsinfo, 0);
- StringBuffer params;
- const char* excludes[] = {"soap_builder_",NULL};
- getEspUrlParams(context,params,excludes);
- Owned<IXslProcessor> xslp = getXslProcessor();
- Owned<IXslTransform> xform = xslp->createXslTransform();
- xform->loadXslFromFile(StringBuffer(getCFD()).append("./xslt/wsecl3_xmltest.xsl").str());
- StringBuffer srcxml;
- srcxml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><srcxml><soapbody><![CDATA[");
- srcxml.append(soapmsg.str());
- srcxml.append("]]></soapbody></srcxml>");
- xform->setXmlSource(srcxml.str(), srcxml.length());
- StringBuffer header;
- if (!stricmp(formtype, "roxiexml"))
- {
- header.append("Content-Type: application/xml; charset=UTF-8");
- xform->setStringParameter("showhttp", "true()");
- pageName.append("ROXIE XML Test");
- }
- else if (!stricmp(formtype, "roxiesoap"))
- {
- header.append("Content-Type: text/xml; charset=UTF-8");
- xform->setStringParameter("showhttp", "true()");
- pageName.append("ROXIE SOAP Test");
- }
- else
- {
- header.append("Content-Type: text/xml; charset=UTF-8");
- xform->setStringParameter("showhttp", "true()");
- pageName.append("SOAP Test");
- }
- // params
- xform->setStringParameter("pageName", pageName.str());
- xform->setStringParameter("serviceName", wsinfo.qsetname.sget());
- xform->setStringParameter("methodName", wsinfo.queryname.sget());
- xform->setStringParameter("wuid", wsinfo.wuid.sget());
- xform->setStringParameter("header", header.str());
- ISecUser* user = context.queryUser();
- bool inhouse = user && (user->getStatus()==SecUserStatus_Inhouse);
- xform->setParameter("inhouseUser", inhouse ? "true()" : "false()");
- StringBuffer url;
- xform->setStringParameter("destination", buildWsEclTargetUrl(url, wsinfo, formtype, params.str()).str());
- StringBuffer page;
- xform->transform(page);
- response->setContent(page);
- response->setContentType("text/html; charset=UTF-8");
- response->setStatus(HTTP_STATUS_OK);
- response->send();
- return 0;
- }
- int CWsEclBinding::getJsonTestForm(IEspContext &context, CHttpRequest* request, CHttpResponse* response, WsEclWuInfo &wsinfo, const char *formtype)
- {
- IProperties *parms = context.queryRequestParameters();
- StringBuffer jsonmsg, pageName;
- getWsEclJsonRequest(jsonmsg, context, request, wsinfo, "json", NULL, 0);
- StringBuffer params;
- const char* excludes[] = {"soap_builder_",NULL};
- getEspUrlParams(context,params,excludes);
- StringBuffer header("Content-Type: application/json; charset=UTF-8");
- Owned<IXslProcessor> xslp = getXslProcessor();
- Owned<IXslTransform> xform = xslp->createXslTransform();
- xform->loadXslFromFile(StringBuffer(getCFD()).append("./xslt/wsecl3_jsontest.xsl").str());
- StringBuffer srcxml;
- srcxml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><srcxml><jsonreq><![CDATA[");
- srcxml.append(jsonmsg.str());
- srcxml.append("]]></jsonreq></srcxml>");
- xform->setXmlSource(srcxml.str(), srcxml.length());
- xform->setStringParameter("showhttp", "true()");
- pageName.append("JSON Test");
- // params
- xform->setStringParameter("pageName", pageName.str());
- xform->setStringParameter("serviceName", wsinfo.qsetname.sget());
- xform->setStringParameter("methodName", wsinfo.queryname.sget());
- xform->setStringParameter("wuid", wsinfo.wuid.sget());
- xform->setStringParameter("header", header.str());
- ISecUser* user = context.queryUser();
- bool inhouse = user && (user->getStatus()==SecUserStatus_Inhouse);
- xform->setParameter("inhouseUser", inhouse ? "true()" : "false()");
- StringBuffer url;
- xform->setStringParameter("destination", buildWsEclTargetUrl(url, wsinfo, formtype, params.str()).str());
- StringBuffer page;
- xform->transform(page);
- response->setContent(page);
- response->setContentType("text/html; charset=UTF-8");
- response->setStatus(HTTP_STATUS_OK);
- response->send();
- return 0;
- }
- int CWsEclBinding::onGetSoapBuilder(IEspContext &context, CHttpRequest* request, CHttpResponse* response, WsEclWuInfo &wsinfo)
- {
- return getXmlTestForm(context, request, response, wsinfo, "soap");
- }
- bool checkWsEclFormType(StringBuffer &form, const char *value)
- {
- if (value)
- {
- bool save = (strieq(value, "ecl")||strieq(value, "box"));
- if (save || (strieq(value, "soap")||strieq(value, "json")))
- {
- form.set(value);
- return save;
- }
- }
- form.set("ecl");
- return false;
- }
- void getWsEclFormType(CHttpRequest* request, CHttpResponse* response, StringBuffer &form)
- {
- bool save=false;
- if (strieq(form, "default"))
- {
- CEspCookie *cookie = request->queryCookie("defaultWsEclForm");
- checkWsEclFormType(form, (cookie) ? cookie->getValue() : NULL);
- }
- else if (checkWsEclFormType(form, form.str()))
- {
- CEspCookie *cookie = request->queryCookie("defaultWsEclForm");
- if (!cookie || !strieq(cookie->getValue(), form.str()))
- response->addCookie(new CEspCookie("defaultWsEclForm", form));
- }
- }
- int CWsEclBinding::getWsEcl2Form(CHttpRequest* request, CHttpResponse* response, const char *thepath)
- {
- IEspContext *context = request->queryContext();
- StringBuffer formtype;
- nextPathNode(thepath, formtype);
- StringBuffer wuid;
- StringBuffer qs;
- StringBuffer qid;
- splitLookupInfo(request->queryParameters(), thepath, wuid, qs, qid);
- WsEclWuInfo wsinfo(wuid.str(), qs.str(), qid.str(), context->queryUserId(), context->queryPassword());
- getWsEclFormType(request, response, formtype);
- if (strieq(formtype.str(), "ecl"))
- return getGenForm(*context, request, response, wsinfo, false);
- else if (strieq(formtype.str(), "box"))
- return getGenForm(*context, request, response, wsinfo, true);
- else if (strieq(formtype.str(), "soap"))
- return getXmlTestForm(*context, request, response, "soap", wsinfo);
- else if (strieq(formtype.str(), "json"))
- return getJsonTestForm(*context, request, response, wsinfo, "json");
- return 0;
- }
- void CWsEclBinding::addParameterToWorkunit(IWorkUnit * workunit, IConstWUResult &vardef, IResultSetMetaData &metadef, const char *varname, IPropertyTree *valtree)
- {
- if (!varname || !*varname)
- return;
- Owned<IWUResult> var = workunit->updateVariableByName(varname);
- if (!vardef.isResultScalar())
- {
- StringBuffer ds;
- if (valtree->hasChildren())
- toXML(valtree, ds);
- else
- {
- const char *val = valtree->queryProp(NULL);
- if (val)
- decodeXML(val, ds);
- }
- if (ds.length())
- var->setResultRaw(ds.length(), ds.str(), ResultFormatXml);
- }
- else
- {
- const char *val = valtree->queryProp(NULL);
- if (val && *val)
- {
- switch (metadef.getColumnDisplayType(0))
- {
- case TypeBoolean:
- var->setResultBool(strieq(val, "1") || strieq(val, "true") || strieq(val, "on"));
- break;
- case TypeInteger:
- var->setResultInt(_atoi64(val));
- break;
- case TypeUnsignedInteger:
- var->setResultInt(_atoi64(val));
- break;
- case TypeReal:
- var->setResultReal(atof(val));
- break;
- case TypeSet:
- case TypeDataset:
- case TypeData:
- var->setResultRaw(strlen(val), val, ResultFormatRaw);
- break;
- case TypeUnicode: {
- MemoryBuffer target;
- convertUtf(target, UtfReader::Utf16le, strlen(val), val, UtfReader::Utf8);
- var->setResultUnicode(target.toByteArray(), (target.length()>1) ? target.length()/2 : 0);
- }
- break;
- case TypeString:
- case TypeUnknown:
- default:
- var->setResultString(val, strlen(val));
- break;
- break;
- }
- var->setResultStatus(ResultStatusSupplied);
- }
- }
- }
- int CWsEclBinding::submitWsEclWorkunit(IEspContext & context, WsEclWuInfo &wsinfo, const char *xml, StringBuffer &out, unsigned flags, const char *viewname, const char *xsltname)
- {
- Owned <IWorkUnitFactory> factory = getSecWorkUnitFactory(*context.querySecManager(), *context.queryUser());
- Owned <IWorkUnit> workunit = factory->createWorkUnit(NULL, "wsecl", context.queryUserId());
- IExtendedWUInterface *ext = queryExtendedWU(workunit);
- ext->copyWorkUnit(wsinfo.wu, false);
- workunit->clearExceptions();
- workunit->resetWorkflow();
- workunit->setClusterName(wsinfo.qsetname.sget());
- workunit->setUser(context.queryUserId());
-
- SCMStringBuffer wuid;
- workunit->getWuid(wuid);
- SCMStringBuffer token;
- createToken(wuid.str(), context.queryUserId(), context.queryPassword(), token);
- workunit->setSecurityToken(token.str());
- workunit->setState(WUStateSubmitted);
- workunit->commit();
- Owned<IPropertyTree> req = createPTreeFromXMLString(xml, ipt_none, (XmlReaderOptions)(xr_ignoreWhiteSpace|xr_ignoreNameSpaces));
- IPropertyTree *start = req.get();
- if (start->hasProp("Envelope"))
- start=start->queryPropTree("Envelope");
- if (start->hasProp("Body"))
- start=start->queryPropTree("Body/*[1]");
- Owned<IResultSetFactory> resultSetFactory(getResultSetFactory(context.queryUserId(), context.queryPassword()));
- Owned<IPropertyTreeIterator> it = start->getElements("*");
- ForEach(*it)
- {
- IPropertyTree &eclparm=it->query();
- const char *varname = eclparm.queryName();
- IConstWUResult *vardef = wsinfo.wu->getVariableByName(varname);
- if (vardef)
- {
- Owned<IResultSetMetaData> metadef = resultSetFactory->createResultSetMeta(vardef);
- if (metadef)
- addParameterToWorkunit(workunit.get(), *vardef, *metadef, varname, &eclparm);
- }
- }
- workunit->schedule();
- workunit.clear();
- runWorkUnit(wuid.str(), wsinfo.qsetname.sget());
- //don't wait indefinately, in case submitted to an inactive queue wait max + 5 mins
- int wutimeout = 300000;
- if (waitForWorkUnitToComplete(wuid.str(), wutimeout))
- {
- Owned<IWuWebView> web = createWuWebView(wuid.str(), wsinfo.queryname.get(), getCFD(), true);
- if (!web)
- {
- DBGLOG("WS-ECL failed to create WuWebView for workunit %s", wuid.str());
- return 0;
- }
- if (viewname)
- web->renderResults(viewname, out);
- else if (xsltname)
- web->applyResultsXSLT(xsltname, out);
- else
- web->expandResults(out, flags);
- }
- else
- {
- DBGLOG("WS-ECL request timed out, WorkUnit %s", wuid.str());
- }
- DBGLOG("WS-ECL Request processed [using Doxie]");
- return true;
- }
- void xppToXmlString(XmlPullParser &xpp, StartTag &stag, StringBuffer &buffer)
- {
- int level = 1; //assumed due to the way gotonextdataset works.
- int type = XmlPullParser::END_TAG;
- const char * content = "";
- const char *tag = NULL;
- EndTag etag;
- tag = stag.getLocalName();
- if (tag && *tag)
- {
- buffer.appendf("<%s", tag);
- for (int idx=0; idx<stag.getLength(); idx++)
- buffer.appendf(" %s=\"%s\"", stag.getRawName(idx), stag.getValue(idx));
- buffer.append(">");
- }
- do
- {
- type = xpp.next();
- switch(type)
- {
- case XmlPullParser::START_TAG:
- {
- xpp.readStartTag(stag);
- ++level;
- tag = stag.getLocalName();
- if (tag && *tag)
- {
- buffer.appendf("<%s", tag);
- for (int idx=0; idx<stag.getLength(); idx++)
- buffer.appendf(" %s=\"%s\"", stag.getRawName(idx), stag.getValue(idx));
- buffer.append(">");
- }
- break;
- }
- case XmlPullParser::END_TAG:
- xpp.readEndTag(etag);
- tag = etag.getLocalName();
- if (tag && *tag)
- buffer.appendf("</%s>", tag);
- --level;
- break;
- case XmlPullParser::CONTENT:
- content = xpp.readContent();
- encodeUtf8XML(content, buffer);
- break;
- case XmlPullParser::END_DOCUMENT:
- level=0;
- break;
- }
- }
- while (level > 0);
- }
- bool xppGotoTag(XmlPullParser &xppx, const char *tagname, StartTag &stag)
- {
- int level = 0;
- int type = XmlPullParser::END_TAG;
- do
- {
- type = xppx.next();
- switch(type)
- {
- case XmlPullParser::START_TAG:
- {
- xppx.readStartTag(stag);
- ++level;
- const char *tag = stag.getLocalName();
- if (tag && strieq(tag, tagname))
- return true;
- break;
- }
- case XmlPullParser::END_TAG:
- --level;
- break;
- case XmlPullParser::END_DOCUMENT:
- level=0;
- break;
- }
- }
- while (level > 0);
- return false;
- }
- void CWsEclBinding::sendRoxieRequest(const char *target, StringBuffer &req, StringBuffer &resp, StringBuffer &status, const char *query)
- {
- ISmartSocketFactory *conn = NULL;
- SocketEndpoint ep;
- try
- {
- Owned<IConstWUClusterInfo> clusterInfo = getTargetClusterInfo(target);
- if (!clusterInfo)
- throw MakeStringException(-1, "target cluster not found");
- SCMStringBuffer process;
- clusterInfo->getRoxieProcess(process);
- ISmartSocketFactory *conn = wsecl->connMap.getValue(process.str());
- if (!conn)
- throw MakeStringException(-1, "process cluster not found: %s", process.str());
- ep = conn->nextEndpoint();
- Owned<IHttpClientContext> httpctx = getHttpClientContext();
- StringBuffer url("http://");
- ep.getIpText(url).append(':').append(ep.port);
- Owned<IHttpClient> httpclient = httpctx->createHttpClient(NULL, url);
- if (0 > httpclient->sendRequest("POST", "text/xml", req, resp, status))
- throw MakeStringException(-1, "Process cluster communication error: %s", process.str());
- }
- catch (IException *e)
- {
- if (conn && !ep.isNull())
- conn->setStatus(ep, false);
- StringBuffer s;
- VStringBuffer uri("urn:hpccsystems:ecl:%s", query);
- resp.set("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- resp.append("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body>");
- resp.append('<').append(query).append("Response xmlns='").append(uri).append("'>");
- resp.append("<Results><Result><Exception><Source>WsEcl</Source>");
- resp.append("<Code>").append(e->errorCode()).append("</Code>");
- resp.append("<Message>").append(e->errorMessage(s)).append("</Message>");
- resp.append("</Exception></Result></Results>");
- resp.append("</").append(query).append("Response></soap:Body></soap:Envelope>");
- e->Release();
- }
- }
- int CWsEclBinding::onSubmitQueryOutputXML(IEspContext &context, CHttpRequest* request, CHttpResponse* response, WsEclWuInfo &wsinfo, const char *format)
- {
- StringBuffer soapmsg;
- getSoapMessage(soapmsg, context, request, wsinfo, REQXML_TRIM|REQXML_ROOT);
- DBGLOG("submitQuery soap: %s", soapmsg.str());
- const char *thepath = request->queryPath();
- StringBuffer status;
- StringBuffer output;
- SCMStringBuffer clustertype;
- wsinfo.wu->getDebugValue("targetclustertype", clustertype);
- unsigned xmlflags = WWV_ADD_RESPONSE_TAG | WWV_INCL_NAMESPACES | WWV_INCL_GENERATED_NAMESPACES;
- if (context.queryRequestParameters()->hasProp("display"))
- xmlflags |= WWV_USE_DISPLAY_XSLT;
- if (!format || !streq(format, "expanded"))
- xmlflags |= WWV_OMIT_SCHEMAS;
- if (strieq(clustertype.str(), "roxie"))
- {
- StringBuffer roxieresp;
- sendRoxieRequest(wsinfo.qsetname.get(), soapmsg, roxieresp, status, wsinfo.queryname);
- Owned<IWuWebView> web = createWuWebView(*wsinfo.wu, wsinfo.queryname.get(), getCFD(), true);
- if (web.get())
- web->expandResults(roxieresp.str(), output, xmlflags);
- }
- else
- {
- submitWsEclWorkunit(context, wsinfo, soapmsg.str(), output, xmlflags);
- }
- response->setContent(output.str());
- response->setContentType(HTTP_TYPE_APPLICATION_XML);
- response->setStatus("200 OK");
- response->send();
- return 0;
- }
- int CWsEclBinding::onSubmitQueryOutputView(IEspContext &context, CHttpRequest* request, CHttpResponse* response, WsEclWuInfo &wsinfo)
- {
- StringBuffer soapmsg;
- getSoapMessage(soapmsg, context, request, wsinfo, REQXML_TRIM|REQXML_ROOT);
- DBGLOG("submitQuery soap: %s", soapmsg.str());
- const char *thepath = request->queryPath();
- StringBuffer output;
- StringBuffer status;
- StringBuffer html;
- SCMStringBuffer clustertype;
- wsinfo.wu->getDebugValue("targetclustertype", clustertype);
- StringBuffer xsltfile(getCFD());
- xsltfile.append("xslt/wsecl3_result.xslt");
- const char *view = context.queryRequestParameters()->queryProp("view");
- if (strieq(clustertype.str(), "roxie"))
- {
- sendRoxieRequest(wsinfo.qsetname.get(), soapmsg, output, status, wsinfo.queryname);
- Owned<IWuWebView> web = createWuWebView(*wsinfo.wu, wsinfo.queryname.get(), getCFD(), true);
- if (!view)
- web->applyResultsXSLT(xsltfile.str(), output.str(), html);
- else
- web->renderResults(view, output.str(), html);
- }
- else
- {
- submitWsEclWorkunit(context, wsinfo, soapmsg.str(), html, 0, view, xsltfile.str());
- }
- response->setContent(html.str());
- response->setContentType("text/html; charset=utf-8");
- response->setStatus("200 OK");
- response->send();
- return 0;
- }
- int CWsEclBinding::getWsdlMessages(IEspContext &context, CHttpRequest *request, StringBuffer &content, const char *service, const char *method, bool mda)
- {
- WsEclWuInfo *wsinfo = (WsEclWuInfo *) context.getBindingValue();
- if (wsinfo)
- {
- content.appendf("<message name=\"%sSoapIn\">", wsinfo->queryname.sget());
- content.appendf("<part name=\"parameters\" element=\"tns:%sRequest\"/>", wsinfo->queryname.sget());
- content.append("</message>");
- content.appendf("<message name=\"%sSoapOut\">", wsinfo->queryname.sget());
- content.appendf("<part name=\"parameters\" element=\"tns:%sResponse\"/>", wsinfo->queryname.sget());
- content.append("</message>");
- }
- return 0;
- }
- int CWsEclBinding::getWsdlPorts(IEspContext &context, CHttpRequest *request, StringBuffer &content, const char *service, const char *method, bool mda)
- {
- WsEclWuInfo *wsinfo = (WsEclWuInfo *) context.getBindingValue();
- if (wsinfo)
- {
- content.appendf("<portType name=\"%sServiceSoap\">", wsinfo->qsetname.sget());
- content.appendf("<operation name=\"%s\">", wsinfo->queryname.sget());
- content.appendf("<input message=\"tns:%sSoapIn\"/>", wsinfo->queryname.sget());
- content.appendf("<output message=\"tns:%sSoapOut\"/>", wsinfo->queryname.sget());
- content.append("</operation>");
- content.append("</portType>");
- }
- return 0;
- }
- int CWsEclBinding::getWsdlBindings(IEspContext &context, CHttpRequest *request, StringBuffer &content, const char *service, const char *method, bool mda)
- {
- WsEclWuInfo *wsinfo = (WsEclWuInfo *) context.getBindingValue();
- if (wsinfo)
- {
- content.appendf("<binding name=\"%sServiceSoap\" type=\"tns:%sServiceSoap\">", wsinfo->qsetname.sget(), wsinfo->qsetname.sget());
- content.append("<soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"document\"/>");
- content.appendf("<operation name=\"%s\">", wsinfo->queryname.sget());
- content.appendf("<soap:operation soapAction=\"/%s/%s?ver_=1.0\" style=\"document\"/>", wsinfo->qsetname.sget(), wsinfo->queryname.sget());
- content.append("<input>");
- content.append("<soap:body use=\"literal\"/>");
- content.append("</input>");
- content.append("<output><soap:body use=\"literal\"/></output>");
- content.append("</operation>");
- content.append("</binding>");
- }
- return 0;
- }
- int CWsEclBinding::onGetWsdl(IEspContext &context, CHttpRequest* request, CHttpResponse* response, WsEclWuInfo &wsinfo)
- {
- context.setBindingValue(&wsinfo);
- EspHttpBinding::onGetWsdl(context, request, response, wsinfo.qsetname.sget(), wsinfo.queryname.sget());
- context.setBindingValue(NULL);
- return 0;
- }
- int CWsEclBinding::onGetXsd(IEspContext &context, CHttpRequest* request, CHttpResponse* response, WsEclWuInfo &wsinfo)
- {
- context.setBindingValue(&wsinfo);
- EspHttpBinding::onGetXsd(context, request, response, wsinfo.qsetname.sget(), wsinfo.queryname.sget());
- context.setBindingValue(NULL);
- return 0;
- }
- int CWsEclBinding::getWsEclDefinition(CHttpRequest* request, CHttpResponse* response, const char *thepath)
- {
- IEspContext *context = request->queryContext();
- IProperties *parms = context->queryRequestParameters();
- StringBuffer wuid;
- StringBuffer qs;
- StringBuffer qid;
- splitLookupInfo(parms, thepath, wuid, qs, qid);
- WsEclWuInfo wsinfo(wuid.str(), qs.str(), qid.str(), context->queryUserId(), context->queryPassword());
- StringBuffer scope; //main, input, result, etc.
- nextPathNode(thepath, scope);
- StringBuffer respath;
- StringBuffer resname;
- StringBuffer restype;
- if (strieq(scope.str(), "resource"))
- {
- StringBuffer ext;
- splitPathTailAndExt(thepath, respath, resname, &ext);
- }
- else
- splitPathTailAndExt(thepath, respath, resname, &restype);
- if (strieq(scope.str(), "resource"))
- {
- StringBuffer blockStr("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- if (request->getParameters()->hasProp("display"))
- blockStr.append("<?xml-stylesheet type=\"text/xsl\" href=\"/esp/xslt/xmlformatter.xsl\"?>");
- wsinfo.getWsResource(respath.str(), blockStr);
- if (blockStr.length())
- {
- response->setStatus("200 OK");
- response->setContent(blockStr.str());
- response->setContentType(HTTP_TYPE_APPLICATION_XML);
- response->send();
- }
- }
- else if (strieq(restype.str(), "wsdl"))
- {
- if (strieq(scope.str(), "main"))
- {
- VStringBuffer dest("/WsEcl/soap/query/%s/%s", qs.str(), qid.str());
- parms->setProp("multiple_resp_schemas", 1);
- parms->setProp("wsdl_destination_path", dest.str());
- return onGetWsdl(*context, request, response, wsinfo);
- }
- }
- else if (strieq(restype.str(), "xsd"))
- {
- if (strieq(scope.str(), "main"))
- {
- parms->setProp("multiple_resp_schemas", 1);
- return onGetXsd(*context, request, response, wsinfo);
- }
- else if (strieq(scope.str(), "input") || strieq(scope.str(), "result"))
- {
- StringBuffer output;
- StringBuffer xsds;
- wsinfo.getSchemas(xsds);
- Owned<IPropertyTree> xsds_tree;
- if (xsds.length())
- xsds_tree.setown(createPTreeFromXMLString(xsds.str()));
- if (xsds_tree)
- {
- StringBuffer xpath;
- Owned<IPropertyTree> selected_xsd;
- StringBuffer urn("urn:hpccsystems:ecl:");
- appendNamespaceSpecificString(urn, wsinfo.queryname.get());
- urn.appendf(":%s:", scope.toLowerCase().str());
- appendNamespaceSpecificString(urn, resname.str());
- if (!stricmp(scope.str(), "input"))
- xpath.appendf("Input[@sname='%s']/xs:schema", resname.str());
- else if (!stricmp(scope.str(), "result"))
- xpath.appendf("Result[@sname='%s']/xs:schema",resname.str());
- if (xpath.length())
- selected_xsd.setown(xsds_tree->getPropTree(xpath.str()));
- if (selected_xsd)
- {
- selected_xsd->setProp("@targetNamespace", urn.str());
- selected_xsd->setProp("@xmlns", urn.str());
- IPropertyTree *dstree = selected_xsd->queryPropTree("xs:element[@name='Dataset']/xs:complexType");
- if (dstree && !dstree->hasProp("xs:attribute[@name='name']"))
- dstree->addPropTree("xs:attribute", createPTreeFromXMLString("<xs:attribute name=\"name\" type=\"xs:string\"/>"));
- Owned<IPropertyTreeIterator> elements = selected_xsd->getElements("xs:element//xs:element");
- ForEach(*elements)
- elements->query().setPropInt("@minOccurs", 0);
- output.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- if (context->queryRequestParameters()->hasProp("display"))
- output.append("<?xml-stylesheet type=\"text/xsl\" href=\"/esp/xslt/xmlformatter.xsl\"?>");
- toXML(selected_xsd, output);
- }
- }
- if (output.length())
- {
- response->setStatus("200 OK");
- response->setContent(output.str());
- response->setContentType(HTTP_TYPE_APPLICATION_XML);
- response->send();
- }
- }
- }
- return 0;
- }
- int CWsEclBinding::getWsEclExample(CHttpRequest* request, CHttpResponse* response, const char *thepath)
- {
- IProperties *parms = request->queryParameters();
- IEspContext *context = request->queryContext();
- StringBuffer exampletype;
- nextPathNode(thepath, exampletype);
- StringBuffer wuid;
- StringBuffer qs;
- StringBuffer qid;
- splitLookupInfo(parms, thepath, wuid, qs, qid);
- WsEclWuInfo wsinfo(wuid.str(), qs.str(), qid.str(), context->queryUserId(), context->queryPassword());
- context->setBindingValue(&wsinfo);
- if (!stricmp(exampletype.str(), "request"))
- return onGetReqSampleXml(*context, request, response, qs.str(), qid.str());
- else if (!stricmp(exampletype.str(), "response"))
- {
- StringBuffer output;
- buildSampleResponseXml(output, *context, request, wsinfo);
- if (output.length())
- {
- response->setStatus("200 OK");
- response->setContent(output.str());
- response->setContentType(HTTP_TYPE_APPLICATION_XML);
- response->send();
- }
- }
- context->setBindingValue(NULL);
- return 0;
- }
- int CWsEclBinding::onGet(CHttpRequest* request, CHttpResponse* response)
- {
- Owned<IMultiException> me = MakeMultiException("WsEcl");
- try
- {
- IEspContext *context = request->queryContext();
- IProperties *parms = request->queryParameters();
- if (!context->validateFeatureAccess(WSECL_ACCESS, SecAccess_Full, false))
- throw MakeStringException(-1, "WsEcl access permission denied.");
- const char *thepath = request->queryPath();
- StringBuffer serviceName;
- firstPathNode(thepath, serviceName);
- if (stricmp(serviceName.str(), "WsEcl"))
- return EspHttpBinding::onGet(request, response);
- StringBuffer methodName;
- nextPathNode(thepath, methodName);
- if (!stricmp(methodName.str(), "tabview"))
- {
- return getWsEcl2TabView(request, response, thepath);
- }
- else if (!stricmp(methodName.str(), "forms"))
- {
- return getWsEcl2Form(request, response, thepath);
- }
- else if (!stricmp(methodName.str(), "submit"))
- {
- StringBuffer wuid;
- StringBuffer qs;
- StringBuffer qid;
- splitLookupInfo(parms, thepath, wuid, qs, qid);
- StringBuffer format;
- nextPathNode(thepath, format);
- WsEclWuInfo wsinfo(wuid.str(), qs.str(), qid.str(), context->queryUserId(), context->queryPassword());
- return onSubmitQueryOutputXML(*context, request, response, wsinfo, format.str());
- }
- else if (!stricmp(methodName.str(), "xslt"))
- {
- StringBuffer wuid;
- StringBuffer qs;
- StringBuffer qid;
- splitLookupInfo(parms, thepath, wuid, qs, qid);
- WsEclWuInfo wsinfo(wuid.str(), qs.str(), qid.str(), context->queryUserId(), context->queryPassword());
- return onSubmitQueryOutputView(*context, request, response, wsinfo);
- }
- else if (!stricmp(methodName.str(), "example"))
- {
- return getWsEclExample(request, response, thepath);
- }
- else if (!stricmp(methodName.str(), "definitions"))
- {
- return getWsEclDefinition(request, response, thepath);
- }
- else if (!stricmp(methodName.str(), "links"))
- {
- StringBuffer wuid;
- StringBuffer qs;
- StringBuffer qid;
- splitLookupInfo(parms, thepath, wuid, qs, qid);
- WsEclWuInfo wsinfo(wuid.str(), qs.str(), qid.str(), context->queryUserId(), context->queryPassword());
- return getWsEclLinks(*context, request, response, wsinfo);
- }
- else if (strieq(methodName.str(), "soap"))
- {
- StringBuffer url;
- url.append("/WsEcl/forms/soap/").append(thepath);
- response->redirect(*request, url);
- return 0;
- }
- }
- catch (IMultiException* mex)
- {
- me->append(*mex);
- mex->Release();
- }
- catch (IException* e)
- {
- me->append(*e);
- }
- catch (...)
- {
- me->append(*MakeStringExceptionDirect(-1, "Unknown Exception"));
- }
-
- response->handleExceptions(getXslProcessor(), me, "WsEcl", "", StringBuffer(getCFD()).append("./smc_xslt/exceptions.xslt").str());
- return 0;
- }
- void checkForXmlResponseName(StartTag &starttag, StringBuffer &respname, int &soaplevel)
- {
- if (respname.length())
- return;
- switch(soaplevel)
- {
- case 0:
- {
- if (!stricmp(starttag.getLocalName(), "Envelope"))
- soaplevel=1;
- else
- respname.append(starttag.getLocalName());
- break;
- }
- case 1:
- if (!stricmp(starttag.getLocalName(), "Body"))
- soaplevel=2;
- break;
- case 2:
- respname.append(starttag.getLocalName());
- default:
- break;
- }
- int len=respname.length();
- if (len>8 && !stricmp(respname.str()+len-8, "Response"))
- respname.setLength(len-8);
- }
- void createPTreeFromJsonString(const char *json, bool caseInsensitive, StringBuffer &xml, const char *tail);
- void CWsEclBinding::handleJSONPost(CHttpRequest *request, CHttpResponse *response)
- {
- IEspContext *ctx = request->queryContext();
- IProperties *parms = request->queryParameters();
- StringBuffer jsonresp;
- try
- {
- if (!ctx->validateFeatureAccess(WSECL_ACCESS, SecAccess_Full, false))
- throw MakeStringException(-1, "WsEcl access permission denied.");
- const char *thepath = request->queryPath();
- StringBuffer serviceName;
- firstPathNode(thepath, serviceName);
- if (!strieq(serviceName.str(), "WsEcl"))
- EspHttpBinding::handleHttpPost(request, response);
- StringBuffer action;
- nextPathNode(thepath, action);
- StringBuffer lookup;
- nextPathNode(thepath, lookup);
- StringBuffer wuid;
- StringBuffer queryset;
- StringBuffer queryname;
- if (strieq(lookup.str(), "wuid"))
- {
- nextPathNode(thepath, wuid);
- queryset.append(parms->queryProp("qset"));
- queryname.append(parms->queryProp("qname"));
- }
- else if (strieq(lookup.str(), "query"))
- {
- nextPathNode(thepath, queryset);
- nextPathNode(thepath, queryname);
- }
- WsEclWuInfo wsinfo(wuid.str(), queryset.str(), queryname.str(), ctx->queryUserId(), ctx->queryPassword());
- StringBuffer content(request->queryContent());
- StringBuffer status;
- StringBuffer soapfromjson;
- soapfromjson.append(
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""
- " xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\">"
- " <soap:Body>"
- );
- createPTreeFromJsonString(content.str(), false, soapfromjson, "Request");
- soapfromjson.append("</soap:Body></soap:Envelope>");
- DBGLOG("soap from json req: %s", soapfromjson.str());
- StringBuffer soapresp;
- SCMStringBuffer clustertype;
- wsinfo.wu->getDebugValue("targetclustertype", clustertype);
- unsigned xmlflags = WWV_ADD_SOAP | WWV_ADD_RESULTS_TAG | WWV_ADD_RESPONSE_TAG | WWV_INCL_NAMESPACES | WWV_INCL_GENERATED_NAMESPACES;
- if (ctx->queryRequestParameters()->hasProp("display"))
- xmlflags |= WWV_USE_DISPLAY_XSLT;
- if (streq(action.str(), "expanded"))
- xmlflags |= WWV_CDATA_SCHEMAS;
- else
- xmlflags |= WWV_OMIT_SCHEMAS;
- if (strieq(clustertype.str(), "roxie"))
- {
- StringBuffer output;
- sendRoxieRequest(wsinfo.qsetname.get(), soapfromjson, output, status, wsinfo.queryname);
- Owned<IWuWebView> web = createWuWebView(*wsinfo.wu, NULL, getCFD(), true);
- if (web.get())
- web->expandResults(output.str(), soapresp, xmlflags);
- }
- else
- {
- submitWsEclWorkunit(*ctx, wsinfo, soapfromjson.str(), soapresp, xmlflags);
- }
- DBGLOG("HandleSoapRequest response: %s", soapresp.str());
- getWsEclJsonResponse(jsonresp, *ctx, request, soapresp.str(), wsinfo);
- }
- catch (IException *e)
- {
- appendJSONException(jsonresp.set("{"), e);
- jsonresp.append('}');
- }
- response->setContent(jsonresp.str());
- response->setContentType("application/json");
- response->setStatus("200 OK");
- response->send();
- }
- void CWsEclBinding::handleHttpPost(CHttpRequest *request, CHttpResponse *response)
- {
- StringBuffer ct;
- request->getContentType(ct);
- if (!strnicmp(ct.str(), "application/json", 16))
- {
- handleJSONPost(request, response);
- }
- else
- {
- EspHttpBinding::handleHttpPost(request, response);
- }
- }
- int CWsEclBinding::HandleSoapRequest(CHttpRequest* request, CHttpResponse* response)
- {
- IEspContext *ctx = request->queryContext();
- IProperties *parms = request->queryParameters();
- const char *thepath = request->queryPath();
- StringBuffer serviceName;
- firstPathNode(thepath, serviceName);
- if (!strieq(serviceName.str(), "WsEcl"))
- return CHttpSoapBinding::HandleSoapRequest(request, response);
- if(ctx->toBeAuthenticated()) //future support WsSecurity tags?
- {
- response->sendBasicChallenge(getChallengeRealm(), false);
- return 0;
- }
- if (!ctx->validateFeatureAccess(WSECL_ACCESS, SecAccess_Full, false))
- throw MakeStringException(-1, "WsEcl access permission denied.");
- StringBuffer action;
- nextPathNode(thepath, action);
- StringBuffer lookup;
- nextPathNode(thepath, lookup);
- StringBuffer wuid;
- StringBuffer queryset;
- StringBuffer queryname;
- if (strieq(lookup.str(), "wuid"))
- {
- nextPathNode(thepath, wuid);
- queryset.append(parms->queryProp("qset"));
- queryname.append(parms->queryProp("qname"));
- }
- else if (strieq(lookup.str(), "query"))
- {
- nextPathNode(thepath, queryset);
- nextPathNode(thepath, queryname);
- }
- WsEclWuInfo wsinfo(wuid.str(), queryset.str(), queryname.str(), ctx->queryUserId(), ctx->queryPassword());
- StringBuffer content(request->queryContent());
- StringBuffer soapresp;
- StringBuffer status;
- SCMStringBuffer clustertype;
- wsinfo.wu->getDebugValue("targetclustertype", clustertype);
- unsigned xmlflags = WWV_ADD_SOAP | WWV_ADD_RESULTS_TAG | WWV_ADD_RESPONSE_TAG | WWV_INCL_NAMESPACES | WWV_INCL_GENERATED_NAMESPACES;
- if (ctx->queryRequestParameters()->hasProp("display"))
- xmlflags |= WWV_USE_DISPLAY_XSLT;
- if (streq(action.str(), "expanded"))
- xmlflags |= WWV_CDATA_SCHEMAS;
- else
- xmlflags |= WWV_OMIT_SCHEMAS;
- if (strieq(clustertype.str(), "roxie"))
- {
- StringBuffer content(request->queryContent());
- StringBuffer output;
- sendRoxieRequest(wsinfo.qsetname.get(), content, output, status, wsinfo.queryname);
- Owned<IWuWebView> web = createWuWebView(*wsinfo.wu, wsinfo.queryname.get(), getCFD(), true);
- if (web.get())
- web->expandResults(output.str(), soapresp, xmlflags);
- }
- else
- submitWsEclWorkunit(*ctx, wsinfo, content.str(), soapresp, xmlflags);
- DBGLOG("HandleSoapRequest response: %s", soapresp.str());
- response->setContent(soapresp.str());
- response->setContentType("text/xml");
- response->setStatus("200 OK");
- response->send();
- return 0;
- }
|