12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025 |
- /*##############################################################################
- HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ############################################################################## */
- #include "jlib.hpp"
- #include "jexcept.hpp"
- #include "jptree.hpp"
- #include "junicode.hpp"
- #include "workunit.hpp"
- #include "dllserver.hpp"
- #include "thorplugin.hpp"
- #include "xslprocessor.hpp"
- #include "fileview.hpp"
- #include "wuwebview.hpp"
- #include "wuweberror.hpp"
- class WuExpandedResultBuffer : public CInterface, implements IPTreeNotifyEvent
- {
- public:
- IMPLEMENT_IINTERFACE;
- WuExpandedResultBuffer(const char *queryname, unsigned _flags=0) :
- name(queryname), datasetLevel(0), finalized(false), flags(_flags), hasXmlns(false)
- {
- if (flags & (WWV_INCL_NAMESPACES | WWV_INCL_GENERATED_NAMESPACES))
- {
- StringBuffer lower(name);
- ns.append("urn:hpccsystems:ecl:").append(lower.toLowerCase());
- }
- if (!(flags & WWV_OMIT_XML_DECLARATION))
- buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- if (flags & WWV_USE_DISPLAY_XSLT)
- buffer.append("<?xml-stylesheet type=\"text/xsl\" href=\"/esp/xslt/xmlformatter.xsl\"?>");
- if (flags & WWV_ADD_SOAP)
- buffer.append(
- "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""
- " xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\">"
- " <soap:Body>"
- );
- if (flags & WWV_ADD_RESPONSE_TAG)
- {
- buffer.append('<');
- if (queryname)
- buffer.append(queryname);
- buffer.append("Response");
- if ((flags & WWV_INCL_NAMESPACES) && ns.length())
- buffer.append(" xmlns=\"").append(ns.str()).append('\"');
- buffer.append('>');
- }
- if (flags & WWV_ADD_RESULTS_TAG)
- buffer.append("<Results>");
- if (!(flags & WWV_OMIT_RESULT_TAG))
- buffer.append("<Result>");
- }
- void appendResults(IConstWorkUnit *wu, const char *username, const char *pw)
- {
- StringBufferAdaptor resultXML(buffer);
- getFullWorkUnitResultsXML(username, pw, wu, resultXML, WorkUnitXML_NoRoot, ExceptionSeverityError);
- }
- void appendSingleResult(IConstWorkUnit *wu, const char *resultname, const char *username, const char *pw)
- {
- SCMStringBuffer wuid;
- StringBufferAdaptor resultXML(buffer);
- Owned<IResultSetFactory> factory = getResultSetFactory(username, pw);
- Owned<INewResultSet> nr = factory->createNewResultSet(wu->getWuid(wuid).str(), 0, resultname);
- getResultXml(resultXML, nr.get(), resultname, 0, 0, NULL);
- }
- void appendDatasetsFromXML(const char *xml)
- {
- assertex(!finalized);
- Owned<IPullPTreeReader> reader = createPullXMLStringReader(xml, *this);
- reader->load();
- }
- void append(const char *value)
- {
- assertex(!finalized);
- buffer.append(value);
- }
- void appendSchemaResource(IPropertyTree &res, ILoadedDllEntry *dll)
- {
- if (!dll || (flags & WWV_OMIT_SCHEMAS))
- return;
- if (res.getPropInt("@seq", -1)>=0 && res.hasProp("@id"))
- {
- int id = res.getPropInt("@id");
- size32_t len = 0;
- const void *data = NULL;
- if (dll->getResource(len, data, "RESULT_XSD", (unsigned) id) && len>0)
- {
- buffer.append("<XmlSchema name=\"").append(res.queryProp("@name")).append("\">");
- if (res.getPropBool("@compressed"))
- {
- StringBuffer decompressed;
- decompressResource(len, data, decompressed);
- if (flags & WWV_CDATA_SCHEMAS)
- buffer.append("<![CDATA[");
- buffer.append(decompressed.str());
- if (flags & WWV_CDATA_SCHEMAS)
- buffer.append("]]>");
- }
- else
- buffer.append(len, (const char *)data);
- buffer.append("</XmlSchema>");
- }
- }
- }
- void appendManifestSchemas(IPropertyTree &manifest, ILoadedDllEntry *dll)
- {
- if (flags & WWV_OMIT_SCHEMAS)
- return;
- assertex(!finalized);
- if (!dll)
- return;
- Owned<IPropertyTreeIterator> iter = manifest.getElements("Resource[@type='RESULT_XSD']");
- ForEach(*iter)
- appendSchemaResource(iter->query(), dll);
- }
- void appendManifestResultSchema(IPropertyTree &manifest, const char *resultname, ILoadedDllEntry *dll)
- {
- assertex(!finalized);
- if (!dll)
- return;
- VStringBuffer xpath("Resource[@name='%s'][@type='RESULT_XSD']", resultname);
- IPropertyTree *res=manifest.queryPropTree(xpath.str());
- if (res)
- appendSchemaResource(*res, dll);
- }
- void appendXML(IPropertyTree *xml, const char *tag=NULL)
- {
- assertex(!finalized);
- if (tag)
- buffer.append('<').append(tag).append('>');
- if (xml)
- toXML(xml, buffer);
- if (tag)
- buffer.append("</").append(tag).append('>');
- }
- virtual void beginNode(const char *tag, offset_t startOffset)
- {
- if (streq("Dataset", tag) || streq("Exception", tag))
- datasetLevel++;
- if (datasetLevel)
- buffer.append('<').append(tag);
- }
- virtual void newAttribute(const char *name, const char *value)
- {
- if (datasetLevel)
- {
- if (streq(name, "@xmlns"))
- {
- if (!(flags & WWV_INCL_NAMESPACES))
- return;
- if (datasetLevel==1)
- hasXmlns=true;
- }
- if (datasetLevel==1 && streq(name, "@name"))
- dsname.set(value).toLowerCase().replace(' ', '_');;
- buffer.append(' ').append(name+1).append("=\"");
- encodeUtf8XML(value, buffer);
- buffer.append('\"');
- }
- }
- virtual void beginNodeContent(const char *tag)
- {
- if (datasetLevel==1 && streq("Dataset", tag))
- {
- if (!hasXmlns && dsname.length() && (flags & WWV_INCL_GENERATED_NAMESPACES))
- {
- StringBuffer s(ns);
- s.append(":result:").append(dsname.str());
- buffer.append(" xmlns=\"").append(s).append('\"');
- }
- dsname.clear();
- hasXmlns=false;
- }
- if (datasetLevel)
- buffer.append('>');
- }
- virtual void endNode(const char *tag, unsigned length, const void *value, bool binary, offset_t endOffset)
- {
- if (datasetLevel)
- {
- if (length)
- {
- if (binary)
- JBASE64_Encode(value, length, buffer);
- else
- encodeUtf8XML((const char *)value, buffer);
- }
- buffer.append("</").append(tag).append('>');
- if (streq("Dataset", tag) || streq("Exception", tag))
- datasetLevel--;
- }
- }
- StringBuffer &finalize()
- {
- if (!finalized)
- {
- if (!(flags & WWV_OMIT_RESULT_TAG))
- buffer.append("</Result>");
- if (flags & WWV_ADD_RESULTS_TAG)
- buffer.append("</Results>");
- if (flags & WWV_ADD_RESPONSE_TAG)
- buffer.appendf("</%sResponse>", name.sget());
- if (flags & WWV_ADD_SOAP)
- buffer.append("</soap:Body></soap:Envelope>");
- finalized=true;
- }
- return buffer;
- }
- const char *str()
- {
- finalize();
- return buffer.str();
- }
- size32_t length()
- {
- finalize();
- return buffer.length();
- }
- public:
- StringBuffer buffer;
- StringAttr name;
- StringBuffer dsname;
- StringBuffer ns;
- bool hasXmlns;
- bool finalized;
- unsigned flags;
- private:
- int datasetLevel;
- };
- class WuWebView : public CInterface,
- implements IWuWebView,
- implements IIncludeHandler
- {
- public:
- IMPLEMENT_IINTERFACE;
- WuWebView(IConstWorkUnit &wu, const char *_target, const char *queryname, const char *wdir, bool mapEspDir, bool delay=true) :
- manifestIncludePathsSet(false), dir(wdir), mapEspDirectories(mapEspDir), delayedDll(delay), target(_target)
- {
- name.set(queryname);
- setWorkunit(wu);
- }
- WuWebView(const char *wuid, const char *_target, const char *queryname, const char *wdir, bool mapEspDir, bool delay=true) :
- manifestIncludePathsSet(false), dir(wdir), mapEspDirectories(mapEspDir), delayedDll(delay), target(_target)
- {
- name.set(queryname);
- setWorkunit(wuid);
- }
- void setWorkunit(IConstWorkUnit &wu);
- void setWorkunit(const char *wuid);
- ILoadedDllEntry *loadDll(bool force=false);
- IPropertyTree *ensureManifest();
- virtual void getResultViewNames(StringArray &names);
- virtual void getResourceURLs(StringArray &urls, const char *prefix);
- virtual unsigned getResourceURLCount();
- virtual void renderResults(const char *viewName, const char *xml, StringBuffer &html);
- virtual void renderResults(const char *viewName, StringBuffer &html);
- virtual void renderSingleResult(const char *viewName, const char *resultname, StringBuffer &html);
- virtual void renderResultsJSON(StringBuffer &out, const char *jsonp);
- virtual void expandResults(const char *xml, StringBuffer &out, unsigned flags);
- virtual void expandResults(StringBuffer &out, unsigned flags);
- virtual void createWuidResponse(StringBuffer &out, unsigned flags);
- virtual void applyResultsXSLT(const char *filename, const char *xml, StringBuffer &out);
- virtual void applyResultsXSLT(const char *filename, StringBuffer &out);
- virtual StringBuffer &aggregateResources(const char *type, StringBuffer &content);
- void renderExpandedResults(const char *viewName, WuExpandedResultBuffer &expanded, StringBuffer &out);
- void appendResultSchemas(WuExpandedResultBuffer &buffer);
- void getResultXSLT(const char *viewName, StringBuffer &xslt, StringBuffer &abspath);
- bool getResource(IPropertyTree *res, StringBuffer &content);
- bool getResource(IPropertyTree *res, MemoryBuffer &content);
- bool getResource(IPropertyTree *res, size32_t & len, const void * & data);
- void getResource(const char *name, StringBuffer &content, StringBuffer &abspath, const char *type);
- bool getResourceByPath(const char *path, MemoryBuffer &mb);
- StringBuffer &getManifest(StringBuffer &mf){return toXML(ensureManifest(), mf);}
- void calculateResourceIncludePaths();
- virtual bool getInclude(const char *includename, MemoryBuffer &includebuf, bool &pathOnly);
- bool getEspInclude(const char *includename, MemoryBuffer &includebuf, bool &pathOnly);
- void addVariableFromPTree(IWorkUnit *w, IConstWUResult &vardef, IResultSetMetaData &metadef, const char *varname, IPropertyTree *valtree);
- void addInputsFromPTree(IPropertyTree *pt);
- void addInputsFromXml(const char *xml);
- protected:
- SCMStringBuffer dllname;
- SCMStringBuffer name;
- StringBuffer manifestDir;
- Owned<IConstWorkUnit> cw;
- Owned<ILoadedDllEntry> dll;
- Owned<IPropertyTree> manifest;
- StringAttr target;
- StringAttr dir;
- StringAttr username;
- StringAttr pw;
- bool mapEspDirectories;
- bool manifestIncludePathsSet;
- bool delayedDll;
- };
- IPropertyTree *WuWebView::ensureManifest()
- {
- if (!manifest)
- {
- StringBuffer xml;
- manifest.setown((loadDll() && getEmbeddedManifestXML(dll, xml)) ? createPTreeFromXMLString(xml.str()) : createPTree());
- }
- return manifest.get();
- }
- StringBuffer &makeResourcePath(const char *path, const char *basedir, StringBuffer &respath)
- {
- StringBuffer abspath;
- makeAbsolutePath(path, basedir, abspath);
- return makePathUniversal(abspath, respath);
- }
- void WuWebView::calculateResourceIncludePaths()
- {
- if (!manifestIncludePathsSet)
- {
- manifestDir.set(ensureManifest()->queryProp("@manifestDir"));
- Owned<IPropertyTreeIterator> iter = manifest->getElements("Resource[@filename]");
- ForEach(*iter)
- {
- if (!iter->query().hasProp("@resourcePath")) //backward compatible
- {
- StringBuffer respath;
- makeResourcePath(iter->query().queryProp("@filename"), dir.get(), respath);
- iter->query().setProp("@resourcePath", respath.str());
- }
- }
- manifestIncludePathsSet=true;
- }
- }
- bool WuWebView::getEspInclude(const char *includename, MemoryBuffer &includebuf, bool &pathOnly)
- {
- StringBuffer absPath;
- makeAbsolutePath(includename, dir.get(), absPath);
- if (checkFileExists(absPath.str()))
- {
- Owned <IFile> f = createIFile(absPath.str());
- Owned <IFileIO> fio = f->open(IFOread);
- read(fio, 0, (size32_t) f->size(), includebuf);
- }
- //esp looks in two places for path starting with "xslt/"
- else if (mapEspDirectories && !strncmp(includename, "xslt/", 5))
- {
- absPath.clear().append(dir.get());
- absPath.append("smc_").append(includename);;
- makeAbsolutePath(absPath);
- if (checkFileExists(absPath.str()))
- {
- Owned <IFile> f = createIFile(absPath.str());
- Owned <IFileIO> fio = f->open(IFOread);
- read(fio, 0, (size32_t) f->size(), includebuf);
- }
- }
- return true;
- }
- bool WuWebView::getInclude(const char *includename, MemoryBuffer &includebuf, bool &pathOnly)
- {
- //eliminate "file://"
- if (strncmp(includename, "file:", 5)==0)
- includename+=5;
- if (*includename=='/')
- {
- while (includename[1]=='/')
- includename++;
- //eliminate extra '/' for windows absolute paths
- if (includename[1] && includename[2]==':')
- includename++;
- }
- if (mapEspDirectories && !strnicmp(includename, "/esp/", 5))
- return getEspInclude(includename+5, includebuf, pathOnly);
- IPropertyTree *res = NULL;
- if (manifest)
- {
- if (strieq(includename, "/EmbeddedView"))
- res = manifest->queryPropTree("Resource[@name='Results'][@type='XSLT']");
- else
- {
- VStringBuffer xpath("Resource[@resourcePath='%s']", includename);
- res = manifest->queryPropTree(xpath.str());
- }
- }
- if (res)
- {
- StringBuffer xslt;
- getResource(res, xslt);
- includebuf.append(xslt.str());
- }
- else if (checkFileExists(includename))
- {
- Owned <IFile> f = createIFile(includename);
- Owned <IFileIO> fio = f->open(IFOread);
- read(fio, 0, (size32_t) f->size(), includebuf);
- }
- return true;
- }
- bool WuWebView::getResourceByPath(const char *path, MemoryBuffer &mb)
- {
- calculateResourceIncludePaths();
- StringBuffer xpath;
- if (!manifestDir.length())
- xpath.setf("Resource[@filename='%s'][1]", path);
- else
- {
- StringBuffer respath;
- makeResourcePath(path, manifestDir.str(), respath);
- xpath.setf("Resource[@resourcePath='%s'][1]", respath.str());
- }
- IPropertyTree *res = ensureManifest()->queryPropTree(xpath.str());
- if (!res)
- return false;
- return getResource(res, mb);
- }
- unsigned WuWebView::getResourceURLCount()
- {
- unsigned urlCount = 1;
- Owned<IPropertyTreeIterator> iter = ensureManifest()->getElements("Resource");
- ForEach(*iter)
- {
- IPropertyTree &res = iter->query();
- if (res.hasProp("@ResourcePath") || res.hasProp("@filename"))
- urlCount++;
- }
- return urlCount;
- }
- void WuWebView::getResourceURLs(StringArray &urls, const char *prefix)
- {
- SCMStringBuffer wuid;
- cw->getWuid(wuid);
- StringBuffer url(prefix);
- url.append("manifest/");
- if (target.length() && name.length())
- url.appendf("query/%s/%s", target.get(), name.str());
- else
- url.append(wuid.str());
- urls.append(url);
- Owned<IPropertyTreeIterator> iter = ensureManifest()->getElements("Resource");
- ForEach(*iter)
- {
- IPropertyTree &res = iter->query();
- url.set(prefix).append("res/");
- if (target.length() && name.length())
- url.appendf("query/%s/%s", target.get(), name.str());
- else
- url.append(wuid.str());
- if (res.hasProp("@ResourcePath"))
- urls.append(url.append(res.queryProp("@ResourcePath")));
- else if (res.hasProp("@filename"))
- urls.append(url.append('/').append(res.queryProp("@filename")));
- }
- }
- void WuWebView::getResultViewNames(StringArray &names)
- {
- Owned<IPropertyTreeIterator> iter = ensureManifest()->getElements("Views/Results[@name]");
- ForEach(*iter)
- names.append(iter->query().queryProp("@name"));
- if (manifest->hasProp("Views/XSLT/RESULTS[@resource='Results']"))
- names.append("EmbeddedView");
- }
- bool WuWebView::getResource(IPropertyTree *res, size32_t & len, const void * & data)
- {
- if (!loadDll())
- return false;
- if (res->hasProp("@id") && (res->hasProp("@header")||res->hasProp("@compressed")))
- {
- int id = res->getPropInt("@id");
- return (dll->getResource(len, data, res->queryProp("@type"), (unsigned) id) && len>0);
- }
- return false;
- }
- bool WuWebView::getResource(IPropertyTree *res, MemoryBuffer &content)
- {
- size32_t len = 0;
- const void *data = NULL;
- if (getResource(res, len, data))
- {
- if (res->getPropBool("@compressed"))
- decompressResource(len, data, content);
- else
- content.append(len, (const char *)data);
- return true;
- }
- return false;
- }
- bool WuWebView::getResource(IPropertyTree *res, StringBuffer &content)
- {
- size32_t len = 0;
- const void *data = NULL;
- if (getResource(res, len, data))
- {
- if (res->getPropBool("@compressed"))
- decompressResource(len, data, content);
- else
- content.append(len, (const char *)data);
- return true;
- }
- return false;
- }
- void WuWebView::getResource(const char *name, StringBuffer &content, StringBuffer &includepath, const char *type)
- {
- VStringBuffer xpath("Resource[@name='%s']", name);
- if (type)
- xpath.append("[@type='").append(type).append("']");
- IPropertyTree *res = ensureManifest()->queryPropTree(xpath.str());
- calculateResourceIncludePaths();
- includepath.append(res->queryProp("@resourcePath"));
- if (res)
- getResource(res, content);
- }
- StringBuffer &WuWebView::aggregateResources(const char *type, StringBuffer &content)
- {
- VStringBuffer xpath("Resource[@type='%s']", type);
- Owned<IPropertyTreeIterator> iter = ensureManifest()->getElements(xpath.str());
- ForEach(*iter)
- getResource(&iter->query(), content);
- return content;
- }
- void WuWebView::getResultXSLT(const char *viewName, StringBuffer &xslt, StringBuffer &abspath)
- {
- if (!viewName || !*viewName)
- return;
- if (strieq("EmbeddedView", viewName))
- {
- getResource("Results", xslt, abspath, "XSLT");
- return;
- }
- VStringBuffer xpath("Views/Results[@name='%s']/@resource", viewName);
- const char *resource = ensureManifest()->queryProp(xpath.str());
- if (resource)
- getResource(resource, xslt, abspath, "XSLT");
- }
- void WuWebView::renderExpandedResults(const char *viewName, WuExpandedResultBuffer &expanded, StringBuffer &out)
- {
- IPropertyTree *mf = ensureManifest();
- calculateResourceIncludePaths();
- IPropertyTree *view;
- const char *type = NULL;
- const char *respath = NULL;
- if (strieq("EmbeddedView", viewName))
- {
- view = mf->queryPropTree("Views/XSLT/RESULTS[@resource='Results']");
- if (!view)
- throw MakeStringException(WUWEBERR_ViewResourceNotFound, "EmbeddedView not found");
- type="xslt";
- respath="/EmbeddedView";
- }
- else
- {
- VStringBuffer xpath("Views/Results[@name='%s']", viewName);
- view = mf->queryPropTree(xpath.str());
- if (!view)
- throw MakeStringException(WUWEBERR_ViewResourceNotFound, "Result view %s not found", viewName);
- type=view->queryProp("@type");
- if (!type)
- throw MakeStringException(WUWEBERR_UnknownViewType, "No type defined for view %s", viewName);
- if (strieq(type, "xslt"))
- {
- const char *resname = view->queryProp("@resource");
- if (!resname || !*resname)
- throw MakeStringException(WUWEBERR_ViewResourceNotFound, "resource for %s view not defined", viewName);
- xpath.set("Resource[@name='").append(resname).append("']/@resourcePath");
- respath = mf->queryProp(xpath.str());
- if (!respath || !*respath)
- throw MakeStringException(WUWEBERR_ViewResourceNotFound, "resource %s not resolved", resname);
- }
- else if (!strieq(type, "xml"))
- throw MakeStringException(WUWEBERR_UnknownViewType, "View %s has an unknown type of %s", viewName, type);
- }
- expanded.appendXML(view, "view");
- expanded.appendManifestSchemas(*mf, loadDll());
- expanded.finalize();
- if (strieq(type, "xml"))
- return out.swapWith(expanded.buffer);
- Owned<IXslTransform> t = getXslProcessor()->createXslTransform();
- StringBuffer cacheId(viewName);
- cacheId.append('@').append(dllname.str()); //using dllname, cloned workunits can share cache entry
- t->setIncludeHandler(this);
- t->loadXslFromEmbedded(respath, cacheId.str());
- t->setXmlSource(expanded.buffer.str(), expanded.buffer.length());
- t->transform(out);
- }
- void WuWebView::renderResults(const char *viewName, const char *xml, StringBuffer &out)
- {
- WuExpandedResultBuffer buffer(name.str(), WWV_ADD_RESPONSE_TAG | WWV_ADD_RESULTS_TAG);
- buffer.appendDatasetsFromXML(xml);
- renderExpandedResults(viewName, buffer, out);
- }
- void WuWebView::renderResults(const char *viewName, StringBuffer &out)
- {
- WuExpandedResultBuffer buffer(name.str(), WWV_ADD_RESPONSE_TAG | WWV_ADD_RESULTS_TAG);
- buffer.appendResults(cw, username.get(), pw.get());
- renderExpandedResults(viewName, buffer, out);
- }
- void WuWebView::renderResultsJSON(StringBuffer &out, const char *jsonp)
- {
- if (jsonp && *jsonp)
- out.append(jsonp).append('(');
- out.append('{');
- StringBuffer responseName(name.str());
- responseName.append("Response");
- appendJSONName(out, responseName);
- StringBufferAdaptor json(out);
- getFullWorkUnitResultsJSON(username, pw, cw, json, 0, ExceptionSeverityError);
- out.append("}");
- if (jsonp && *jsonp)
- out.append(");");
- }
- void WuWebView::renderSingleResult(const char *viewName, const char *resultname, StringBuffer &out)
- {
- WuExpandedResultBuffer buffer(name.str(), WWV_ADD_RESPONSE_TAG | WWV_ADD_RESULTS_TAG);
- buffer.appendSingleResult(cw, resultname, username.get(), pw.get());
- renderExpandedResults(viewName, buffer, out);
- }
- void expandWuXmlResults(StringBuffer &out, const char *name, const char *xml, unsigned flags, IPropertyTree *manifest, ILoadedDllEntry *dll)
- {
- WuExpandedResultBuffer expander(name, flags);
- expander.appendDatasetsFromXML(xml);
- if (!(flags & WWV_OMIT_SCHEMAS) && manifest && dll)
- expander.appendManifestSchemas(*manifest, dll);
- expander.finalize();
- out.append(expander.buffer);
- }
- extern WUWEBVIEW_API void expandWuXmlResults(StringBuffer &out, const char *name, const char *xml, unsigned flags)
- {
- expandWuXmlResults(out, name, xml, flags, NULL, NULL);
- }
- void WuWebView::expandResults(const char *xml, StringBuffer &out, unsigned flags)
- {
- IPropertyTree *manifest = NULL;
- ILoadedDllEntry *dll = NULL;
- if (!(flags & WWV_OMIT_SCHEMAS))
- {
- manifest = ensureManifest();
- dll = loadDll();
- }
- expandWuXmlResults(out, name.str(), xml, flags, manifest, dll);
- }
- void WuWebView::createWuidResponse(StringBuffer &out, unsigned flags)
- {
- flags &= ~WWV_ADD_RESULTS_TAG;
- flags |= WWV_OMIT_RESULT_TAG;
- WuExpandedResultBuffer expander(name.str(), flags);
- SCMStringBuffer wuid;
- appendXMLTag(expander.buffer, "Wuid", cw->getWuid(wuid).str());
- expander.finalize();
- out.append(expander.buffer);
- }
- void WuWebView::expandResults(StringBuffer &out, unsigned flags)
- {
- SCMStringBuffer xml;
- getFullWorkUnitResultsXML(username.get(), pw.get(), cw, xml);
- expandResults(xml.str(), out, flags);
- }
- void WuWebView::applyResultsXSLT(const char *filename, const char *xml, StringBuffer &out)
- {
- WuExpandedResultBuffer buffer(name.str(), WWV_ADD_RESPONSE_TAG | WWV_ADD_RESULTS_TAG);
- buffer.appendDatasetsFromXML(xml);
- buffer.appendManifestSchemas(*ensureManifest(), loadDll());
- Owned<IXslTransform> t = getXslProcessor()->createXslTransform();
- t->setIncludeHandler(this);
- //override default behavior using filename as cache identifier, there's a chance includes are
- //mapped to resources and need to be distinguished in cache
- StringBuffer cacheId(filename);
- cacheId.append('@').append(dllname.str()); //cloned workunits have same dll and resources
- t->loadXslFromFile(filename, cacheId.str());
- t->setXmlSource(buffer.str(), buffer.length());
- t->transform(out);
- }
- void WuWebView::applyResultsXSLT(const char *filename, StringBuffer &out)
- {
- SCMStringBuffer xml;
- getFullWorkUnitResultsXML(username.get(), pw.get(), cw, xml);
- applyResultsXSLT(filename, xml.str(), out);
- }
- ILoadedDllEntry *WuWebView::loadDll(bool force)
- {
- if (!dll && dllname.length() && (force || delayedDll))
- {
- try
- {
- dll.setown(queryDllServer().loadDll(dllname.str(), DllLocationAnywhere));
- }
- catch(...)
- {
- DBGLOG("Failed to load %s", dllname.str());
- }
- delayedDll=false;
- }
- return dll.get();
- }
- void WuWebView::setWorkunit(IConstWorkUnit &_cw)
- {
- cw.set(&_cw);
- if (!name.length())
- {
- cw->getJobName(name);
- name.s.replace(' ','_');
- }
- Owned<IConstWUQuery> q = cw->getQuery();
- if (q)
- {
- q->getQueryDllName(dllname);
- if (!delayedDll)
- loadDll(true);
- }
- }
- void WuWebView::setWorkunit(const char *wuid)
- {
- Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
- Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid, false);
- if (!wu)
- throw MakeStringException(WUWEBERR_WorkUnitNotFound, "Workunit not found %s", wuid);
- setWorkunit(*wu);
- }
- void WuWebView::addVariableFromPTree(IWorkUnit *w, IConstWUResult &vardef, IResultSetMetaData &metadef, const char *varname, IPropertyTree *valtree)
- {
- if (!varname || !*varname)
- return;
- Owned<IWUResult> var = w->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);
- }
- }
- }
- void WuWebView::addInputsFromPTree(IPropertyTree *pt)
- {
- IPropertyTree *start = pt;
- if (start->hasProp("Envelope"))
- start=start->queryPropTree("Envelope");
- if (start->hasProp("Body"))
- start=start->queryPropTree("Body/*[1]");
- Owned<IResultSetFactory> resultSetFactory(getResultSetFactory(username.get(), pw.get()));
- Owned<IPropertyTreeIterator> it = start->getElements("*");
- WorkunitUpdate wu(&cw->lock());
- ForEach(*it)
- {
- IPropertyTree &eclparm=it->query();
- const char *varname = eclparm.queryName();
- IConstWUResult *vardef = wu->getVariableByName(varname);
- if (vardef)
- {
- Owned<IResultSetMetaData> metadef = resultSetFactory->createResultSetMeta(vardef);
- if (metadef)
- addVariableFromPTree(wu.get(), *vardef, *metadef, varname, &eclparm);
- }
- }
- }
- void WuWebView::addInputsFromXml(const char *xml)
- {
- Owned<IPropertyTree> pt = createPTreeFromXMLString(xml, ipt_none, (PTreeReaderOptions)(ptr_ignoreWhiteSpace|ptr_ignoreNameSpaces));
- addInputsFromPTree(pt.get());
- }
- extern WUWEBVIEW_API IWuWebView *createWuWebView(IConstWorkUnit &wu, const char *target, const char *queryname, const char *dir, bool mapEspDirectories)
- {
- try
- {
- return new WuWebView(wu, target, queryname, dir, mapEspDirectories);
- }
- catch (...)
- {
- SCMStringBuffer wuid;
- DBGLOG("ERROR loading workunit %s shared object.", wu.getWuid(wuid).str());
- }
- return NULL;
- }
- extern WUWEBVIEW_API IWuWebView *createWuWebView(const char *wuid, const char *target, const char *queryname, const char *dir, bool mapEspDirectories)
- {
- try
- {
- return new WuWebView(wuid, target, queryname, dir, mapEspDirectories);
- }
- catch (...)
- {
- DBGLOG("ERROR loading workunit %s shared object.", wuid);
- }
- return NULL;
- }
- const char *mimeTypeFromFileExt(const char *ext)
- {
- if (!ext)
- return "application/octet-stream";
- if (*ext=='.')
- ext++;
- if (strieq(ext, "html") || strieq(ext, "htm"))
- return "text/html";
- if (strieq(ext, "xml") || strieq(ext, "xsl") || strieq(ext, "xslt"))
- return "application/xml";
- if (strieq(ext, "js"))
- return "text/javascript";
- if (strieq(ext, "css"))
- return "text/css";
- if (strieq(ext, "jpeg") || strieq(ext, "jpg"))
- return "image/jpeg";
- if (strieq(ext, "gif"))
- return "image/gif";
- if (strieq(ext, "png"))
- return "image/png";
- if (strieq(ext, "svg"))
- return "image/svg+xml";
- if (strieq(ext, "txt") || strieq(ext, "text"))
- return "text/plain";
- if (strieq(ext, "zip"))
- return "application/zip";
- if (strieq(ext, "pdf"))
- return "application/pdf";
- if (strieq(ext, "xpi"))
- return "application/x-xpinstall";
- if (strieq(ext, "exe") || strieq(ext, "class"))
- return "application/octet-stream";
- return "application/octet-stream";
- }
- static void getQueryInfoFromPath(const char *&path, const char *op, StringBuffer &target, StringBuffer &queryname, StringBuffer &wuid)
- {
- StringBuffer s;
- nextPathNode(path, s);
- if (op && strieq(s, op))
- nextPathNode(path, s.clear());
- if (strieq(s, "query"))
- {
- nextPathNode(path, target);
- if (!target.length())
- throw MakeStringException(WUWEBERR_TargetNotFound, "Target cluster required");
- nextPathNode(path, queryname);
- Owned<IPropertyTree> query = resolveQueryAlias(target, queryname, true);
- if (!query)
- throw MakeStringException(WUWEBERR_QueryNotFound, "Query not found");
- wuid.set(query->queryProp("@wuid"));
- }
- else
- wuid.swapWith(s);
- }
- extern WUWEBVIEW_API void getWuResourceByPath(const char *path, MemoryBuffer &mb, StringBuffer &mimetype)
- {
- StringBuffer wuid, target, queryname;
- getQueryInfoFromPath(path, "res", target, queryname, wuid);
- Owned<IWuWebView> web = createWuWebView(wuid, target, queryname, NULL, true);
- if (!web)
- throw MakeStringException(WUWEBERR_WorkUnitNotFound, "Cannot open workunit");
- mimetype.append(mimeTypeFromFileExt(strrchr(path, '.')));
- if (!web->getResourceByPath(path, mb))
- throw MakeStringException(WUWEBERR_ViewResourceNotFound, "Cannot open resource");
- }
- extern WUWEBVIEW_API void getWuManifestByPath(const char *path, StringBuffer &mf)
- {
- StringBuffer wuid, target, queryname;
- getQueryInfoFromPath(path, "manifest", target, queryname, wuid);
- Owned<IWuWebView> web = createWuWebView(wuid, target, queryname, NULL, true);
- if (!web)
- throw MakeStringException(WUWEBERR_WorkUnitNotFound, "Cannot open workunit");
- if (!web->getManifest(mf).length())
- throw MakeStringException(WUWEBERR_ViewResourceNotFound, "Cannot open manifest");
- }
- extern WUWEBVIEW_API void getWuResourceUrlListByPath(const char *path, StringBuffer &fmt, StringBuffer &content, const char *prefix)
- {
- StringBuffer wuid, target, queryname;
- getQueryInfoFromPath(path, "resurls", target, queryname, wuid);
- nextPathNode(path, fmt);
- if (!fmt.length())
- fmt.set("xml");
- Owned<IWuWebView> web = createWuWebView(wuid, target, queryname, NULL, true);
- if (!web)
- throw MakeStringException(WUWEBERR_WorkUnitNotFound, "Cannot open workunit");
- StringArray urls;
- web->getResourceURLs(urls, prefix);
- bool json = strieq(fmt, "json");
- content.append(json ? "{\"url\": [" : "<ResourceUrls>");
- ForEachItemIn(i, urls)
- {
- if (json)
- appendJSONValue(content, NULL, urls.item(i));
- else
- appendXMLTag(content, "url", urls.item(i));
- }
- content.append(json ? "]}" : "</ResourceUrls>");
- }
|