|
@@ -46,8 +46,8 @@ public:
|
|
|
|
|
|
ResourceManager::ResourceManager()
|
|
|
{
|
|
|
- nextmfid = 1;
|
|
|
- nextbsid = 0;
|
|
|
+ nextmfid = MANIFEST_BASE + 1;
|
|
|
+ nextbsid = BIGSTRING_BASE;
|
|
|
totalbytes = 0;
|
|
|
finalized=false;
|
|
|
}
|
|
@@ -59,30 +59,32 @@ unsigned ResourceManager::count()
|
|
|
|
|
|
unsigned ResourceManager::addString(unsigned len, const char *data)
|
|
|
{
|
|
|
- unsigned id = BIGSTRING_BASE + nextbsid++;
|
|
|
+ unsigned id = nextbsid++;
|
|
|
resources.append(*new ResourceItem("BIGSTRING", id, len, data));
|
|
|
return id;
|
|
|
}
|
|
|
|
|
|
-void ResourceManager::addNamed(const char * type, unsigned len, const void * data, IPropertyTree *entryEx, unsigned id, bool addToManifest, bool compressed)
|
|
|
+void ResourceManager::addNamed(const char * type, unsigned len, const void * data, IPropertyTree *manifestEntry, unsigned id, bool addToManifest, bool compressed)
|
|
|
{
|
|
|
if (id==(unsigned)-1)
|
|
|
- id = MANIFEST_BASE + nextmfid++;
|
|
|
- if (addToManifest && !finalized)
|
|
|
+ id = nextmfid++;
|
|
|
+ if (addToManifest)
|
|
|
{
|
|
|
+ if (finalized)
|
|
|
+ throwError1(HQLERR_ResourceAddAfterFinalManifest, type);
|
|
|
Owned<IPropertyTree> entry=createPTree("Resource");
|
|
|
entry->setProp("@type", type);
|
|
|
entry->setPropInt("@id", id);
|
|
|
if (compressed)
|
|
|
- entry->setPropBool("compressed", true);
|
|
|
- if (entryEx)
|
|
|
- mergePTree(entry, entryEx);
|
|
|
+ entry->setPropBool("@compressed", true);
|
|
|
+ if (manifestEntry)
|
|
|
+ mergePTree(entry, manifestEntry);
|
|
|
ensureManifestInfo()->addPropTree("Resource", entry.getClear());
|
|
|
}
|
|
|
resources.append(*new ResourceItem(type, id, len, data));
|
|
|
}
|
|
|
|
|
|
-bool ResourceManager::addCompress(const char * type, unsigned len, const void * data, IPropertyTree *entryEx, unsigned id, bool addToManifest)
|
|
|
+bool ResourceManager::addCompress(const char * type, unsigned len, const void * data, IPropertyTree *manifestEntry, unsigned id, bool addToManifest)
|
|
|
{
|
|
|
bool isCompressed=false;
|
|
|
if (len>=32) //lzw assert if too small
|
|
@@ -90,10 +92,10 @@ bool ResourceManager::addCompress(const char * type, unsigned len, const void *
|
|
|
isCompressed = true;
|
|
|
MemoryBuffer compressed;
|
|
|
compressResource(compressed, len, data);
|
|
|
- addNamed(type, compressed.length(), compressed.toByteArray(), entryEx, id, addToManifest, isCompressed);
|
|
|
+ addNamed(type, compressed.length(), compressed.toByteArray(), manifestEntry, id, addToManifest, isCompressed);
|
|
|
}
|
|
|
else
|
|
|
- addNamed(type, len, data, entryEx, id, addToManifest, isCompressed);
|
|
|
+ addNamed(type, len, data, manifestEntry, id, addToManifest, isCompressed);
|
|
|
return isCompressed;
|
|
|
}
|
|
|
|
|
@@ -104,65 +106,172 @@ static void loadResource(const char *filepath, MemoryBuffer &content)
|
|
|
read(fio, 0, (size32_t) f->size(), content);
|
|
|
}
|
|
|
|
|
|
+bool ResourceManager::getDuplicateResourceId(const char *srctype, const char *filename, int &id)
|
|
|
+{
|
|
|
+ VStringBuffer xpath("Resource[@filename='%s']", filename);
|
|
|
+ Owned<IPropertyTreeIterator> iter = manifest->getElements(xpath.str());
|
|
|
+ ForEach (*iter)
|
|
|
+ {
|
|
|
+ IPropertyTree &item = iter->query();
|
|
|
+ if (item.hasProp("@id"))
|
|
|
+ {
|
|
|
+ const char *type = item.queryProp("@type");
|
|
|
+ if (type && strieq(type, srctype))
|
|
|
+ {
|
|
|
+ id=item.getPropInt("@id");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
void ResourceManager::addManifest(const char *filename)
|
|
|
{
|
|
|
+ if (finalized)
|
|
|
+ throwError1(HQLERR_ResourceAddAfterFinalManifest, "MANIFEST");
|
|
|
Owned<IPropertyTree> manifestSrc = createPTreeFromXMLFile(filename);
|
|
|
|
|
|
StringBuffer dir;
|
|
|
splitDirTail(filename, dir);
|
|
|
|
|
|
- Owned<IPropertyTreeIterator> itres = manifestSrc->getElements("Resource[@filename]");
|
|
|
- ForEach(*itres)
|
|
|
+ ensureManifestInfo();
|
|
|
+ Owned<IAttributeIterator> aiter = manifestSrc->getAttributes();
|
|
|
+ ForEach (*aiter)
|
|
|
+ manifest->setProp(aiter->queryName(), aiter->queryValue());
|
|
|
+ Owned<IPropertyTreeIterator> iter = manifestSrc->getElements("*");
|
|
|
+ ForEach(*iter)
|
|
|
{
|
|
|
- unsigned id = MANIFEST_BASE + nextmfid++;
|
|
|
- IPropertyTree &resource = itres->query();
|
|
|
- resource.setPropInt("@id", id);
|
|
|
- if (!resource.hasProp("@type"))
|
|
|
- resource.setProp("@type", "UNKOWN");
|
|
|
-
|
|
|
- StringBuffer fullpath;
|
|
|
- const char *respath = resource.queryProp("@filename");
|
|
|
- if (!isAbsolutePath(respath))
|
|
|
- fullpath.append(dir);
|
|
|
- fullpath.append(respath);
|
|
|
-
|
|
|
- MemoryBuffer content;
|
|
|
- loadResource(fullpath.str(), content);
|
|
|
- if (addCompress(resource.queryProp("@type"), content.length(), content.toByteArray(), NULL, id, false))
|
|
|
- resource.setPropBool("@compressed", true);
|
|
|
+ IPropertyTree &item = iter->query();
|
|
|
+ if (streq(item.queryName(), "Resource") && item.hasProp("@filename"))
|
|
|
+ {
|
|
|
+ if (!item.hasProp("@type"))
|
|
|
+ item.setProp("@type", "UNKNOWN");
|
|
|
+ const char *filename = item.queryProp("@filename");
|
|
|
+ int id;
|
|
|
+ if (getDuplicateResourceId(item.queryProp("@type"), filename, id))
|
|
|
+ {
|
|
|
+ item.setPropInt("@id", id);
|
|
|
+ manifest->addPropTree("Resource", LINK(&item));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ StringBuffer fullpath;
|
|
|
+ if (!isAbsolutePath(filename))
|
|
|
+ fullpath.append(dir);
|
|
|
+ fullpath.append(filename);
|
|
|
+
|
|
|
+ MemoryBuffer content;
|
|
|
+ loadResource(fullpath.str(), content);
|
|
|
+ addCompress(item.queryProp("@type"), content.length(), content.toByteArray(), &item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ manifest->addPropTree(item.queryName(), LINK(&item));
|
|
|
}
|
|
|
- mergePTree(ensureManifestInfo(), manifestSrc);
|
|
|
}
|
|
|
|
|
|
void ResourceManager::addManifestFromArchive(IPropertyTree *archive)
|
|
|
{
|
|
|
- if (archive)
|
|
|
+ if (!archive)
|
|
|
+ return;
|
|
|
+ if (finalized)
|
|
|
+ throwError1(HQLERR_ResourceAddAfterFinalManifest, "MANIFEST");
|
|
|
+ ensureManifestInfo();
|
|
|
+ Owned<IPropertyTreeIterator> manifests = archive->getElements("AdditionalFiles/Manifest");
|
|
|
+ ForEach(*manifests)
|
|
|
{
|
|
|
- Owned<IPropertyTreeIterator> manifests = archive->getElements("AdditionalFiles/Manifest");
|
|
|
- ForEach(*manifests)
|
|
|
+ const char *xml = manifests->query().queryProp(NULL);
|
|
|
+ Owned<IPropertyTree> manifestSrc = createPTreeFromXMLString(xml);
|
|
|
+ Owned<IAttributeIterator> aiter = manifestSrc->getAttributes();
|
|
|
+ ForEach (*aiter)
|
|
|
+ manifest->setProp(aiter->queryName(), aiter->queryValue());
|
|
|
+ Owned<IPropertyTreeIterator> iter = manifestSrc->getElements("*");
|
|
|
+ ForEach(*iter)
|
|
|
{
|
|
|
- const char *xml = manifests->query().queryProp(NULL);
|
|
|
- Owned<IPropertyTree> manifestSrc = createPTreeFromXMLString(xml);
|
|
|
-
|
|
|
- Owned<IPropertyTreeIterator> itres = manifestSrc->getElements("Resource[@filename]");
|
|
|
- ForEach(*itres)
|
|
|
+ IPropertyTree &item = iter->query();
|
|
|
+ if (streq(item.queryName(), "Resource")&& item.hasProp("@filename"))
|
|
|
{
|
|
|
- unsigned id = MANIFEST_BASE + nextmfid++;
|
|
|
- IPropertyTree &resource = itres->query();
|
|
|
- resource.setPropInt("@id", id);
|
|
|
- if (!resource.hasProp("@type"))
|
|
|
- resource.setProp("@type", "UNKOWN");
|
|
|
- const char *filename = resource.queryProp("@filename");
|
|
|
- VStringBuffer xpath("AdditionalFiles/Resource[@originalFilename=\"%s\"]", filename);
|
|
|
- MemoryBuffer content;
|
|
|
- archive->getPropBin(xpath.str(), content);
|
|
|
- if (content.length())
|
|
|
+ if (!item.hasProp("@type"))
|
|
|
+ item.setProp("@type", "UNKNOWN");
|
|
|
+ const char *filename = item.queryProp("@filename");
|
|
|
+ int id;
|
|
|
+ if (getDuplicateResourceId(item.queryProp("@type"), filename, id))
|
|
|
+ {
|
|
|
+ item.setPropInt("@id", (int)id);
|
|
|
+ manifest->addPropTree("Resource", LINK(&item));
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- if (addCompress(resource.queryProp("@type"), content.length(), content.toByteArray(), NULL, id, false))
|
|
|
- resource.setPropBool("@compressed", true);
|
|
|
+ VStringBuffer xpath("AdditionalFiles/Resource[@originalFilename=\"%s\"]", filename);
|
|
|
+ MemoryBuffer content;
|
|
|
+ archive->getPropBin(xpath.str(), content);
|
|
|
+ addCompress(item.queryProp("@type"), content.length(), content.toByteArray(), &item);
|
|
|
}
|
|
|
}
|
|
|
- mergePTree(ensureManifestInfo(), manifestSrc);
|
|
|
+ else
|
|
|
+ manifest->addPropTree(item.queryName(), LINK(&item));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void ResourceManager::addWebServiceInfo(IPropertyTree *wsinfo)
|
|
|
+{
|
|
|
+ //convert legacy web service info to the new resource format
|
|
|
+ if (wsinfo)
|
|
|
+ {
|
|
|
+ if (wsinfo->hasProp("SOAP"))
|
|
|
+ ensureManifestInfo()->addProp("WS-PARAMS", wsinfo->queryProp("SOAP"));
|
|
|
+ if (wsinfo->hasProp("HELP"))
|
|
|
+ {
|
|
|
+ const char *content = wsinfo->queryProp("HELP");
|
|
|
+ addCompress("HELP", strlen(content)+1, content);
|
|
|
+ }
|
|
|
+ if (wsinfo->hasProp("INFO"))
|
|
|
+ {
|
|
|
+ const char *content = wsinfo->queryProp("INFO");
|
|
|
+ addCompress("INFO", strlen(content)+1, content);
|
|
|
+ }
|
|
|
+ if (wsinfo->hasProp("OTX"))
|
|
|
+ {
|
|
|
+ const char *content = wsinfo->queryProp("OTX");
|
|
|
+ addCompress("HYPER-LINK", strlen(content)+1, content);
|
|
|
+ }
|
|
|
+ if (wsinfo->hasProp("HTML"))
|
|
|
+ {
|
|
|
+ const char *content = wsinfo->queryProp("HTML");
|
|
|
+ Owned<IPropertyTree> manifestEntry = createPTree("Resource");
|
|
|
+ manifestEntry->setProp("@name", "Custom Form");
|
|
|
+ addCompress("XSLT", strlen(content)+1, content, manifestEntry);
|
|
|
+ IPropertyTree *view = ensurePTree(ensureManifestInfo(), "Views/XSLT/FORM");
|
|
|
+ view->setProp("@resource", "Custom Form");
|
|
|
+ }
|
|
|
+ if (wsinfo->hasProp("HTMLD"))
|
|
|
+ {
|
|
|
+ const char *content = wsinfo->queryProp("HTMLD");
|
|
|
+ Owned<IPropertyTree> manifestEntry = createPTree("Resource");
|
|
|
+ manifestEntry->setProp("@name", "Custom HTML");
|
|
|
+ addCompress("HTML", strlen(content)+1, content, manifestEntry);
|
|
|
+ IPropertyTree *view = ensurePTree(ensureManifestInfo(), "Views/HTML/FORM");
|
|
|
+ view->setProp("@resource", "Custom HTML");
|
|
|
+ }
|
|
|
+ if (wsinfo->hasProp("RESULT"))
|
|
|
+ {
|
|
|
+ const char *content = wsinfo->queryProp("RESULT");
|
|
|
+ Owned<IPropertyTree> manifestEntry = createPTree("Resource");
|
|
|
+ manifestEntry->setProp("@name", "Results");
|
|
|
+ addCompress("XSLT", strlen(content)+1, content, manifestEntry);
|
|
|
+ IPropertyTree *view = ensurePTree(ensureManifestInfo(), "Views/XSLT/RESULTS");
|
|
|
+ view->setProp("@resource", "Results");
|
|
|
+ }
|
|
|
+ if (wsinfo->hasProp("ERROR"))
|
|
|
+ {
|
|
|
+ const char *content = wsinfo->queryProp("ERROR");
|
|
|
+ Owned<IPropertyTree> manifestEntry = createPTree("Resource");
|
|
|
+ manifestEntry->setProp("@name", "Error");
|
|
|
+ addCompress("XSLT", strlen(content)+1, content, manifestEntry);
|
|
|
+ IPropertyTree *view = ensurePTree(ensureManifestInfo(), "Views/XSLT/ERROR");
|
|
|
+ view->setProp("@resource", "Error");
|
|
|
}
|
|
|
}
|
|
|
}
|