/** * Gets the field names and values for a particular X509_NAME. * * For instance, if the subject name is passed, then the "CN" (common name) * value, "C" (country) value, etc. will be added to the output. * * @param name the X509_name, i.e. X509_get_subject_name(mX509). * @param output the array to populate. */ static void _getX509NameValues(X509_NAME* name, DynamicObject& output) { output->setType(Array); unsigned char* value; X509_NAME_ENTRY* entry; int count = X509_NAME_entry_count(name); for(int i = 0; i < count; ++i) { entry = X509_NAME_get_entry(name, i); // get entry name (object) and value (data) ASN1_OBJECT* obj = X509_NAME_ENTRY_get_object(entry); ASN1_STRING* str = X509_NAME_ENTRY_get_data(entry); // convert name and value to strings int nid = OBJ_obj2nid(obj); const char* sn = OBJ_nid2sn(nid); if(ASN1_STRING_to_UTF8(&value, str) != -1) { DynamicObject& item = output->append(); item["type"] = sn; item["value"] = value; OPENSSL_free(value); } } }
bool SampleService::getFileInfos( BtpAction* action, DynamicObject& in, DynamicObject& out, DynamicObject& fileInfos) { bool rval; // do not send dyno as response out.setNull(); // get catalog interface CatalogInterface* ci = dynamic_cast<CatalogInterface*>( mNode->getModuleApiByType("bitmunk.catalog")); // get targeted node user DynamicObject vars; action->getResourceQuery(vars); if(!vars->hasMember("nodeuser")) { BM_ID_SET(vars["nodeuser"], mNode->getDefaultUserId()); } // get resource parameters DynamicObject params; action->getResourceParams(params); // populate ware bundle Ware ware; BM_ID_SET(ware["mediaId"], BM_MEDIA_ID(params[0])); MediaPreferenceList mpl; mpl[0]["preferences"][0]["contentType"] = vars["contentType"]; mpl[0]["preferences"][0]["minBitrate"] = 1; // FIXME: Make sure the node user is checked against logged in user? if((rval = ci->populateWareBundle( BM_USER_ID(vars["nodeuser"]), ware, mpl))) { FileInfoIterator i = ware["fileInfos"].getIterator(); while(i->hasNext()) { FileInfo& fi = i->next(); // FIXME: get content type for file info instead of "extension" const char* extension = fi["extension"]->getString(); // FIXME: only support for mp3 audio at this time if(strcmp(extension, "mp3") == 0) { // get sample range for file info Media media; BM_ID_SET(media["id"], BM_MEDIA_ID(fi["mediaId"])); if(getSampleRange(media)) { fi["media"] = media; fileInfos->append() = fi; } } } } return rval; }
/** * Recursively applies context to the given input object. * * @param ctx the context to use. * @param usedCtx the used context values. * @param predicate the related predicate or NULL if none. * @param in the input object. * @param out the contextualized output object. */ static void _applyContext( DynamicObject& ctx, DynamicObject& usedCtx, const char* predicate, DynamicObject& in, DynamicObject& out) { if(in.isNull()) { out.setNull(); } else { // initialize output DynamicObjectType inType = in->getType(); out->setType(inType); if(inType == Map) { // add context to each property in the map char* tmp = NULL; DynamicObjectIterator i = in.getIterator(); while(i->hasNext()) { // compact predicate DynamicObject& next = i->next(); DynamicObject cp(NULL); const char* p; if(strcmp(i->getName(), "@") == 0) { p = "@"; } else { cp = _compactString(ctx, usedCtx, NULL, i->getName(), &tmp); p = cp; } // recurse _applyContext(ctx, usedCtx, p, next, out[p]); } free(tmp); } else if(inType == Array) { // apply context to each object in the array DynamicObjectIterator i = in.getIterator(); while(i->hasNext()) { DynamicObject& next = i->next(); _applyContext(ctx, usedCtx, predicate, next, out->append()); } } // only strings need context applied, numbers & booleans don't else if(inType == String) { // compact string char* tmp = NULL; out = _compactString(ctx, usedCtx, predicate, in->getString(), &tmp); free(tmp); } } }
DynamicObject Bitmunk::getWaitEvents() { DynamicObject rval; DynamicObject event; event["id"] = APP_NAME; event["type"] = APP_NAME ".wait"; rval->append(event); return rval; }
void WebServer::cleanup() { // reset container mContainer->clear(); DynamicObject domains; domains->append("*"); mContainer->setDefaultDomains(domains); // clean up mHostAddress.setNull(); mSslContext.setNull(); mSocketDataPresenterList.setNull(); }
// Currently just handles top level and @:[...] constructs. static bool _findType(DynamicObject& in, const char* type, DynamicObject& out) { out->clear(); if(in->hasMember("@")) { DynamicObject& id = in["@"]; switch(id->getType()) { // top level object case String: { if(_isType(in, type)) { out->append(in); } break; } // top level is blank node case Array: { DynamicObjectIterator i = id.getIterator(); while(i->hasNext()) { DynamicObject& next = i->next(); if(_isType(next, type)) { out->append(next); } } break; } default: break; } } return true; }
void DatabaseClient::buildColumnSchemas( SchemaObject& schema, DynamicObject* excludeMembers, DynamicObject* includeMembers, DynamicObject& columnSchemas, const char* tableAlias) { // create shared table alias object DynamicObject taObj(NULL); if(tableAlias != NULL) { taObj = DynamicObject(); taObj = tableAlias; } DynamicObjectIterator i = schema["columns"].getIterator(); while(i->hasNext()) { DynamicObject& next = i->next(); const char* memberName = next["memberName"]->getString(); // if exclude members does not exist or the current member is not // in it, then see if we should include this column schema if(excludeMembers == NULL || !(*excludeMembers)->hasMember(memberName)) { // if we are to include all column schemas (include == NULL) or if // our current member is in the list of schemas to include, include it if(includeMembers == NULL || (*includeMembers)->hasMember(memberName)) { DynamicObject cs; cs["column"] = next; if(tableAlias != NULL) { cs["tableAlias"] = taObj; } columnSchemas->append(cs); } } } }
/** * Recursively removes context from the given input object. * * @param ctx the context to use (changes during recursion as necessary). * @param in the input object. * @param out the normalized output object. * @param bnodeId the last blank node ID used. * * @return true on success, false on failure with exception set. */ static bool _removeContext( DynamicObject& ctx, DynamicObject& in, DynamicObject& out, int& bnodeId) { bool rval = true; if(in.isNull()) { out.setNull(); } else { // initialize output DynamicObjectType inType = in->getType(); out->setType(inType); // update context if(inType == Map && in->hasMember("#")) { ctx = in["#"]; } if(inType == Map) { rval = _normalize(ctx, in, NULL, &out, bnodeId); } else if(inType == Array) { // strip context from each object in the array DynamicObjectIterator i = in.getIterator(); while(i->hasNext()) { DynamicObject& next = i->next(); rval = _removeContext(ctx, next, out->append(), bnodeId); } } } return rval; }
bool WebServiceContainer::addService( WebServiceRef& service, WebService::SecurityType st, bool initialize, const char* domain) { bool rval = true; if(initialize) { rval = service->initialize(); } if(rval) { // build list of domains to add service to DynamicObject domains(NULL); DynamicObject added; added->setType(Array); if(domain != NULL) { domains = DynamicObject(); domains->append(domain); } else { domains = mDefaultDomains; } HttpRequestServicer* hrs = &(*service); const char* path = hrs->getPath(); // prevent other container access mContainerLock.lockExclusive(); DynamicObjectIterator di = domains.getIterator(); while(rval && di->hasNext()) { const char* dom = di->next()->getString(); rval = internalAddService(service, st, dom); if(rval) { added->append(dom); } } di = rval ? domains.getIterator() : added.getIterator(); while(di->hasNext()) { const char* dom = di->next()->getString(); // success, add domain to http servicer if(rval) { if(st == WebService::Secure || st == WebService::Both) { mHttpConnectionServicer.addRequestServicer(hrs, true, dom); MO_CAT_DEBUG(MO_WS_CAT, "Added secure web service: %s%s", dom, path); } if(st != WebService::Secure) { mHttpConnectionServicer.addRequestServicer(hrs, false, dom); MO_CAT_DEBUG(MO_WS_CAT, "Added non-secure web service: %s%s", dom, path); } } // could not add service to all domains, so remove it else { internalRemoveService(path, st, dom, NULL); } } // permit access again mContainerLock.unlockExclusive(); } // failed to add service if(!rval) { // service was initialized, so clean it up if(initialize) { service->cleanup(); } // set exception ExceptionRef e = new Exception( "Could not add web service.", "monarch.ws.AddWebServiceFailure"); Exception::push(e); } return rval; }
bool JsonLd::normalize(DynamicObject& in, DynamicObject& out) { bool rval = true; // initialize output out->setType(Map); out->clear(); // create map to store subjects DynamicObject subjects; subjects->setType(Map); // initialize context DynamicObject ctx(NULL); if(in->hasMember("#")) { ctx = in["#"]; } // put all subjects in an array for single code path DynamicObject input; input->setType(Array); if(in->hasMember("@") && in["@"]->getType() == Array) { input.merge(in["@"], true); } else { input->append(in); } // do normalization int bnodeId = 0; DynamicObjectIterator i = input.getIterator(); while(rval && i->hasNext()) { rval = _normalize(ctx, i->next(), &subjects, NULL, bnodeId); } // build output if(rval) { // single subject if(subjects->length() == 1) { DynamicObject subject = subjects.first(); out.merge(subject, false); // FIXME: will need to check predicates for blank nodes as well... // and fail if they aren't embeds? // strip blank node '@' if(_isBlankNode(out)) { out->removeMember("@"); } } // multiple subjects else { DynamicObject& array = out["@"]; array->setType(Array); i = subjects.getIterator(); while(i->hasNext()) { DynamicObject& next = i->next(); // FIXME: will need to check predicates for blank nodes as well... // and fail if they aren't embeds? // strip blank node '@' if(_isBlankNode(next)) { next->removeMember("@"); } array->append(next); } } } return rval; }
/** * Recursively normalizes the given input object. * * Input: A subject with predicates and possibly embedded other subjects. * Output: Either a map of normalized subjects OR a tree of normalized subjects. * * Normalization Algorithm: * * Replace the existing context if the input has '#'. * * For each key-value: * 1. Split the key on a colon and look for prefix in the context. If found, * expand the key to an IRI, else it is already an IRI, add <>, save the * new predicate to add to the output. * 2. If value is a Map, then it is a subject, set the predicate to the * subject's '@' IRI value and recurse into it. Else goto #3. * 3. Look up the key in the context to find type coercion info. If not found, * goto #4, else goto #5. * 4. Check the value for an integer, double, or boolean. If matched, set * type according to xsd types. If not matched, look for <>, if found, * do CURIE vs. IRI check like #1 and create appropriate value. * 5. If type coercion entry is a string, encode the value using the specific * type. If it is an array, check the type in order of preference. If an * unrecognized type (non-xsd, non-IRI) is provided, throw an exception. * * @param ctx the context to use (changes during recursion as necessary). * @param in the input object. * @param subjects a map of normalized subjects. * @param out a tree normalized objects. * @param bnodeId the last blank node ID used. * * @return true on success, false on failure with exception set. */ static bool _normalize( DynamicObject ctx, DynamicObject& in, DynamicObject* subjects, DynamicObject* out, int& bnodeId) { bool rval = true; // FIXME: validate context (check for non-xsd types in type coercion arrays) if(!in.isNull()) { // update context if(in->hasMember("#")) { ctx = in["#"]; } // vars for normalization state DynamicObject subject(NULL); if(subjects != NULL) { subject = DynamicObject(); subject->setType(Map); // assign blank node ID as needed if(!in->hasMember("@")) { string bnodeKey = _createBlankNodeId(++bnodeId); subject["@"] = bnodeKey.c_str(); } } string nKey; // iterate over key-values DynamicObjectIterator i = in.getIterator(); while(rval && i->hasNext()) { DynamicObject& value = i->next(); const char* key = i->getName(); // skip context keys if(key[0] == '#') { continue; } // get normalized key nKey = _normalizeValue(ctx, key, RDF_TYPE_IRI, NULL, NULL); // put values in an array for single code path DynamicObject values; values->setType(Array); if(value->getType() == Array) { values.merge(value, true); // preserve array structure when not using subjects map if(out != NULL) { (*out)[nKey.c_str()]->setType(Array); } } else { values->append(value); } // normalize all values DynamicObjectIterator vi = values.getIterator(); while(rval && vi->hasNext()) { DynamicObject v = vi->next(); if(v->getType() == Map) { if(subjects != NULL) { // get a normalized subject for the value string vSubject; if(v->hasMember("@")) { // normalize existing subject vSubject = _normalizeValue( ctx, v["@"], RDF_TYPE_IRI, NULL, NULL); } else { // generate the next blank node ID in order to preserve // the blank node embed in the code below vSubject = _createBlankNodeId(bnodeId + 1); } // determine if value is a blank node bool isBNode = _isBlankNode(v); // update non-blank node subject (use value's subject IRI) if(!isBNode) { _setPredicate(subject, nKey.c_str(), vSubject.c_str()); } // recurse rval = _normalize(ctx, v, subjects, out, bnodeId); // preserve embedded blank node if(rval && isBNode) { // remove embed from top-level subjects DynamicObject embed = (*subjects)[vSubject.c_str()]; (*subjects)->removeMember(vSubject.c_str()); embed->removeMember("@"); _setEmbed(subject, nKey.c_str(), embed); } } else { // update out and recurse DynamicObject next = (*out)[nKey.c_str()]; if(value->getType() == Array) { next = next->append(); } else { next->setType(Map); } rval = _normalize(ctx, v, subjects, &next, bnodeId); } } else { _setPredicate( (subjects != NULL) ? subject : *out, nKey.c_str(), _normalizeValue(ctx, v, RDF_TYPE_UNKNOWN, key, NULL).c_str()); } } } // add subject to map if(subjects != NULL) { (*subjects)[subject["@"]->getString()] = subject; } } return rval; }
void DatabaseClient::buildParams( SchemaObject& schema, DynamicObject& members, DynamicObject& params, const char* tableAlias) { // ensure params is an array params->setType(Array); // create shared table alias object DynamicObject taObj(NULL); if(tableAlias != NULL) { taObj = DynamicObject(); taObj = tableAlias; } // map the given members object into a list of parameters that can // be used to generate sql and set parameter values DynamicObjectIterator i = schema["columns"].getIterator(); while(i->hasNext()) { DynamicObject& column = i->next(); const char* memberName = column["memberName"]->getString(); // if the members map contains the given member name, create a param // for it and append it to the params array if(members->hasMember(memberName)) { /* Note: The member value is either a value, map, or an array. If it's * an array, then each entry in the array is either a value or a map. * * Create a single parameter for all values. Create an individual * parameter for every map entry. This algorithm will store all maps * in "p" and all values in "values". Then "values" will be added to * "p". Then a new parameter will be created for each entry in "p". */ DynamicObject& mv = members[memberName]; DynamicObject p(Array); DynamicObject values(Array); // group maps and values if(mv->getType() == Map) { p->append(mv); } else if(mv->getType() == Array) { DynamicObjectIterator mvi = mv.getIterator(); while(mvi->hasNext()) { DynamicObject& next = mvi->next(); if(next->getType() == Map) { p->append(next); } else { values->append(next); } } } else { values->append(mv); } // treat values as a single param if(values->length() > 0) { p->append(values); } // create params DynamicObjectIterator pi = p.getIterator(); while(pi->hasNext()) { DynamicObject& next = pi->next(); // add param DynamicObject& param = params->append(); param["name"] = column["name"]; param["type"] = column["columnType"]; param["op"] = "="; param["boolOp"] = "AND"; if(column->hasMember("encode")) { param["encode"] = column["encode"]; } if(tableAlias != NULL) { param["tableAlias"] = taObj; } // if next param is a map, get operator and value if(next->getType() == Map) { if(next->hasMember("op")) { param["op"] = next["op"].clone(); } if(next->hasMember("boolOp")) { param["boolOp"] = next["boolOp"].clone(); } param["value"] = next["value"].clone(); } else { param["value"] = next.clone(); } } } } }
/** * Build a columnSchema Map out of an ORDER specification. * * Input: * [ * { * "name1": order, * ... * }, * ... * ] * * Output: * { * "name1": { * "value * } * } */ static void _buildOrderParams( SchemaObject& schema, DynamicObject& order, DynamicObject& params, const char* tableAlias) { // create shared table alias object DynamicObject taObj(NULL); if(tableAlias != NULL) { taObj = DynamicObject(); taObj = tableAlias; } // build map of names DynamicObject names(Array); { DynamicObjectIterator i = order.getIterator(); while(i->hasNext()) { DynamicObjectIterator ni = i->next().getIterator(); while(ni->hasNext()) { DynamicObject& next = ni->next(); names[ni->getName()]["direction"] = next; } } } // get column details for each name { DynamicObjectIterator i = schema["columns"].getIterator(); while(i->hasNext()) { DynamicObject& next = i->next(); const char* memberName = next["memberName"]->getString(); // get details for column if needed if(names->hasMember(memberName)) { DynamicObject& nameInfo = names[memberName]; nameInfo["name"] = next["name"]; if(tableAlias != NULL) { nameInfo["tableAlias"] = taObj; } } } } // setup params in proper order { DynamicObjectIterator i = order.getIterator(); while(i->hasNext()) { DynamicObjectIterator ni = i->next().getIterator(); while(ni->hasNext()) { ni->next(); params->append(names[ni->getName()]); } } } }