/* **************************************************************************** * * putEntityAttributeValue - * * PUT /v2/entities/<id>/attrs/<attrName>/value * * Payload In: AttributeValue * Payload Out: None * * * 01. Fill in UpdateContextRequest with data from URI and payload * 02. Call standard op postUpdateContext * 03. Check output from mongoBackend - any errors? * 04. Prepare HTTP headers * 05. Cleanup and return result */ std::string putEntityAttributeValue ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string entityId = compV[2]; std::string attributeName = compV[4]; std::string type = ciP->uriParam["type"]; if (forbiddenIdChars(ciP->apiVersion, entityId.c_str(), NULL) || forbiddenIdChars(ciP->apiVersion, attributeName.c_str(), NULL)) { OrionError oe(SccBadRequest, ERROR_DESC_BAD_REQUEST_INVALID_CHAR_URI, ERROR_BAD_REQUEST); ciP->httpStatusCode = oe.code; return oe.toJson(); } // 01. Fill in UpdateContextRequest with data from URI and payload parseDataP->av.attribute.name = attributeName; parseDataP->av.attribute.type = ""; // Overwrite 'none', as no type can be given in 'value' payload parseDataP->av.attribute.onlyValue = true; std::string err = parseDataP->av.attribute.check(ciP->apiVersion, ciP->requestType); if (err != "OK") { OrionError oe(SccBadRequest, err, "BadRequest"); ciP->httpStatusCode = oe.code; return oe.toJson(); } parseDataP->upcr.res.fill(entityId, &parseDataP->av.attribute, ActionTypeUpdate, type); // 02. Call standard op postUpdateContext postUpdateContext(ciP, components, compV, parseDataP); // 03. Check output from mongoBackend std::string answer = ""; if (parseDataP->upcrs.res.oe.code != SccNone) { TIMED_RENDER(answer = parseDataP->upcrs.res.oe.toJson()); ciP->httpStatusCode = parseDataP->upcrs.res.oe.code; } else { ciP->httpStatusCode = SccNoContent; } // 05. Cleanup and return result parseDataP->upcr.res.release(); return answer; }
/* **************************************************************************** * * patchSubscription - * * PATCH /v2/subscriptions/{entityId} * * Payload In: None * Payload Out: None * * URI parameters: * - */ std::string patchSubscription ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string answer; std::string subscriptionId = compV[2]; UpdateContextSubscriptionResponse ucsr; // 'Fill In' UpdateContextSubscriptionRequest parseDataP->ucsr.res.subscriptionId.set(subscriptionId); TIMED_MONGO(ciP->httpStatusCode = mongoUpdateContextSubscription(&parseDataP->ucsr.res, &ucsr, ciP->outFormat, ciP->tenant, ciP->httpHeaders.xauthToken, ciP->servicePathV, ciP->apiVersion)); if (ciP->httpStatusCode != SccOk) { OrionError oe(ciP->httpStatusCode); TIMED_RENDER(answer = oe.render(ciP, "")); return answer; } else if (ucsr.subscribeError.errorCode.code != SccNone) { OrionError oe(ucsr.subscribeError.errorCode.code); ciP->httpStatusCode = ucsr.subscribeError.errorCode.code; oe.reasonPhrase = ucsr.subscribeError.errorCode.reasonPhrase; if (ucsr.subscribeError.errorCode.code == SccContextElementNotFound) { oe.details = "The requested subscription has not been found. Check id"; } TIMED_RENDER(answer = oe.render(ciP, "")); return answer; } ciP->httpStatusCode = SccNoContent; return ""; }
/* **************************************************************************** * * postEntities - * * POST /v2/entities * * Payload In: Entity * Payload Out: None * * URI parameters: * - * * 01. Fill in UpdateContextRequest * 02. Call standard op postUpdateContext * 03. Prepare HTTP headers * 04. Cleanup and return result */ std::string postEntities ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { Entity* eP = &parseDataP->ent.res; if (!legalEntityLength(eP, ciP->servicePath)) { OrionError oe(SccBadRequest, "Too long entity id/type/servicePath combination"); ciP->httpStatusCode = SccBadRequest; eP->release(); return oe.render(ciP, ""); } // 01. Fill in UpdateContextRequest parseDataP->upcr.res.fill(eP, "APPEND_STRICT"); // 02. Call standard op postUpdateContext postUpdateContext(ciP, components, compV, parseDataP, true); HttpStatusCode rcode = parseDataP->upcrs.res.contextElementResponseVector[0]->statusCode.code; std::string answer; // 03. Prepare HTTP headers if (rcode == SccOk || rcode == SccNone) { std::string location = "/v2/entities/" + eP->id; ciP->httpHeader.push_back("Location"); ciP->httpHeaderValue.push_back(location); ciP->httpStatusCode = SccCreated; } else if (rcode == SccInvalidModification) { OrionError oe(SccInvalidModification, "Entity already exists"); ciP->httpStatusCode = SccInvalidModification; answer = oe.render(ciP, ""); } // 04. Cleanup and return result eP->release(); return answer; }
/* **************************************************************************** * * badVerbGetDeletePatchOnly - */ std::string badVerbGetDeletePatchOnly ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string details = std::string("bad verb for url '") + ciP->url + "', method '" + ciP->method + "'"; OrionError oe(SccBadVerb, ERROR_DESC_BAD_VERB); ciP->httpHeader.push_back(HTTP_ALLOW); std::string headerValue = "GET, DELETE, PATCH"; // OPTIONS verb is only available for V2 API if ((corsEnabled == true) && (ciP->apiVersion == V2)) { headerValue = headerValue + ", OPTIONS"; } ciP->httpHeaderValue.push_back(headerValue); ciP->httpStatusCode = SccBadVerb; alarmMgr.badInput(clientIp, details); return (ciP->apiVersion == V1 || ciP->apiVersion == NO_VERSION)? "" : oe.smartRender(ciP->apiVersion); }
/* **************************************************************************** * * BatchQuery::check - */ std::string BatchQuery::check(ConnectionInfo* ciP, RequestType requestType) { std::string res; std::string err; if (((res = entities.check(ciP, requestType)) != "OK") || ((res = attributeV.check(requestType, "", err, 0)) != "OK") || ((res = scopeV.check(requestType, "", err, 0)) != "OK")) { std::string error = res; if (err != "") { error += ": "; error += err; } OrionError oe(SccBadRequest, res); alarmMgr.badInput(clientIp, error); return oe.render(); } return "OK"; }
int AssetTemplateItem::compare( const QModelIndex & idx, const QModelIndex & idx2, int column, bool asc ) const { int i = 0; Element e(r), oe(AssetTemplateTranslator::getRecordStatic(idx2)); if( e.isRecord() ) i++; if( oe.isRecord() ) i--; if( i==0 ) return ItemBase::compare(idx,idx2,column,asc); return i; }
/* **************************************************************************** * * getEntityAttribute - * * GET /v2/entities/:id:/attrs/:attrName: * * Payload In: None * Payload Out: Entity Attribute * * * 01. Fill in QueryContextRequest * 02. Call standard op postQueryContext * 03. Render Entity Attribute response * 04. Cleanup and return result */ std::string getEntityAttribute ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string type = ciP->uriParam["type"]; std::string answer; Attribute attribute; if (forbiddenIdChars(ciP->apiVersion, compV[2].c_str() , NULL) || (forbiddenIdChars(ciP->apiVersion, compV[4].c_str() , NULL))) { OrionError oe(SccBadRequest, INVAL_CHAR_URI, "BadRequest"); ciP->httpStatusCode = oe.code; return oe.toJson(); } // 01. Fill in QueryContextRequest parseDataP->qcr.res.fill(compV[2], type, "false", EntityTypeEmptyOrNotEmpty, ""); parseDataP->qcr.res.metadataList.fill(ciP->uriParam[URI_PARAM_METADATA]); // 02. Call standard op postQueryContext postQueryContext(ciP, components, compV, parseDataP); // 03. Render entity attribute response attribute.fill(&parseDataP->qcrs.res, compV[4]); TIMED_RENDER(answer = attribute.render(ciP, EntityAttributeResponse)); if (attribute.oe.reasonPhrase == "TooManyResults") { ciP->httpStatusCode = SccConflict; } else if (attribute.oe.reasonPhrase == "NotFound") { ciP->httpStatusCode = SccContextElementNotFound; // Attribute to be precise! } else { // the same of the wrapped operation ciP->httpStatusCode = parseDataP->qcrs.res.errorCode.code; } // 04. Cleanup and return result parseDataP->qcr.res.release(); return answer; }
/* **************************************************************************** * * getEntityType - * * GET /v2/types/<entityType> * * Payload In: None * Payload Out: EntityTypeResponse * * URI parameters: * - options=noAttrDetail * */ std::string getEntityType ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { EntityTypeResponse response; std::string entityTypeName = compV[2]; std::string answer; bool noAttrDetail = ciP->uriParamOptions[OPT_NO_ATTR_DETAIL]; if (entityTypeName == "") { OrionError oe(SccBadRequest, EMPTY_ENTITY_TYPE, "BadRequest"); ciP->httpStatusCode = oe.code; return oe.toJson(); } TIMED_MONGO(mongoAttributesForEntityType(entityTypeName, &response, ciP->tenant, ciP->servicePathV, ciP->uriParam, noAttrDetail, ciP->apiVersion)); if (response.entityType.count == 0) { OrionError oe(SccContextElementNotFound, "Entity type not found", "NotFound"); TIMED_RENDER(answer = oe.toJson()); ciP->httpStatusCode = oe.code; } else { TIMED_RENDER(answer = response.toJson(ciP)); } response.release(); return answer; }
/* **************************************************************************** * * badVerbPutDeleteOnly - */ std::string badVerbPutDeleteOnly ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string details = std::string("bad verb for url '") + ciP->url + "', method '" + ciP->method + "'"; OrionError oe(SccBadVerb, BAD_VERB); ciP->httpHeader.push_back("Allow"); ciP->httpHeaderValue.push_back("PUT, DELETE"); ciP->httpStatusCode = SccBadVerb; return (ciP->apiVersion == "v1")? "" : oe.smartRender(ciP->apiVersion); }
/* **************************************************************************** * * putEntity - * * PUT /v2/entities * * Payload In: Entity * Payload Out: None * * URI parameters: * - * * 01. Fill in UpdateContextRequest * 02. Call standard op putUpdateContext * 03. Check output from mongoBackend - any errors? * 04. Prepare HTTP headers * 05. Cleanup and return result */ std::string putEntity ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { Entity* eP = &parseDataP->ent.res; eP->id = compV[2]; eP->type = ciP->uriParam["type"]; if (forbiddenIdChars(ciP->apiVersion, compV[2].c_str() , NULL)) { OrionError oe(SccBadRequest, ERROR_DESC_BAD_REQUEST_INVALID_CHAR_URI, ERROR_BAD_REQUEST); ciP->httpStatusCode = oe.code; return oe.toJson(); } // 01. Fill in UpdateContextRequest parseDataP->upcr.res.fill(eP, ActionTypeReplace); // 02. Call standard op postUpdateContext postUpdateContext(ciP, components, compV, parseDataP); // 03. Check error std::string answer = ""; if (parseDataP->upcrs.res.oe.code != SccNone ) { TIMED_RENDER(answer = parseDataP->upcrs.res.oe.toJson()); ciP->httpStatusCode = parseDataP->upcrs.res.oe.code; } else { ciP->httpStatusCode = SccNoContent; } // 04. Cleanup and return result eP->release(); return answer; }
/* **************************************************************************** * * badVerbGetPostDeleteOnly - */ std::string badVerbGetPostDeleteOnly ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string details = std::string("bad verb for url '") + ciP->url + "', method '" + ciP->method + "'"; OrionError oe(SccBadVerb, ERROR_DESC_BAD_VERB); ciP->httpHeader.push_back(HTTP_ALLOW); ciP->httpHeaderValue.push_back("GET, POST, DELETE"); ciP->httpStatusCode = SccBadVerb; alarmMgr.badInput(clientIp, details); return (ciP->apiVersion == V1 || ciP->apiVersion == NO_VERSION)? "" : oe.smartRender(ciP->apiVersion); }
//void at(int pos) { ////argument check //if (pos > 0 && < 10) { //arr[pos]; //} //throw std::length_error("pos 超出范围"); //} int main(int argc, char *argv[]) { //printf("12:%d, yy: %d \n", arr[12], y); std::exception e; printf("%s\n", e.what()); std::logic_error le("logic xxxx"); printf("logic_error.what: %s\n", le.what()); std::out_of_range oe("out_of_range"); printf("oe: %p\n", &oe); show(oe); int i =3; show(i); std::invalid_argument ia("null pointer"); printf("invalid_argument.what: %s\n", ia.what()); std::length_error ll("length error"); printf("length_error.what: %s\n", ll.what()); std::range_error re("range_error"); printf("range_error.what: %s\n", re.what()); //std::system_error se(EDOM, std::system_category()); std::system_error se(ECHILD, std::system_category()); printf("system_error.what: %s error:%d\n", se.what(), se.code().value()); try { xx(); }catch(std::invalid_argument &e) { printf("caller catch inva:%s\n", e.what()); } //try { //ee(2); //} //catch(int i) { //printf("catch int :%d\n", i); //} //catch(std::out_of_range &e) { //printf("catch out:%s\n", e.what()); //} ////catch(std::invalid_argument &e) { ////printf("catch inva:%s\n", e.what()); ////} ////catch(double i) { ////printf("catch int :%g\n", i); ////} //catch(...) { //printf("catch unknown exception\n"); //throw; //} //; printf("xxx\n"); return 0; }
/* **************************************************************************** * * postEntities - * * POST /v2/entities * * Payload In: Entity * Payload Out: None * * URI parameters: * options=keyValues * options=upsert * * 01. Fill in UpdateContextRequest * 02. Call standard op postUpdateContext * 03. Prepare HTTP headers * 04. Cleanup and return result */ std::string postEntities ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { Entity* eP = &parseDataP->ent.res; bool upsert = ciP->uriParamOptions[OPT_UPSERT]; if (!legalEntityLength(eP, ciP->httpHeaders.servicePath)) { OrionError oe(SccBadRequest, "Too long entity id/type/servicePath combination", "BadRequest"); eP->release(); std::string out; TIMED_RENDER(out = oe.toJson()); ciP->httpStatusCode = oe.code; return out; } // Set some aspects depending on upsert or not upsert ActionType actionType; Ngsiv2Flavour ngsiv2flavour; HttpStatusCode sccCodeOnSuccess; if (upsert) { actionType = ActionTypeAppend; ngsiv2flavour = NGSIV2_NO_FLAVOUR; sccCodeOnSuccess = SccNoContent; } else { actionType = ActionTypeAppendStrict; ngsiv2flavour = NGSIV2_FLAVOUR_ONCREATE; sccCodeOnSuccess = SccCreated; } // 01. Fill in UpdateContextRequest parseDataP->upcr.res.fill(eP, actionType); // 02. Call standard op postUpdateContext postUpdateContext(ciP, components, compV, parseDataP, ngsiv2flavour); // // 03. Check error - 3 different ways to get an error from postUpdateContext ... :-( // FIXME P4: make postUpdateContext have ONE way to return errors. See github issue #2763 // std::string answer = ""; if (parseDataP->upcrs.res.oe.code != SccNone) { TIMED_RENDER(answer = parseDataP->upcrs.res.oe.toJson()); ciP->httpStatusCode = parseDataP->upcrs.res.oe.code; } else if (parseDataP->upcrs.res.errorCode.code != SccOk) { ciP->httpStatusCode = parseDataP->upcrs.res.errorCode.code; TIMED_RENDER(answer = parseDataP->upcrs.res.errorCode.toJson()); ciP->answer = answer; } else { // Prepare HTTP headers std::string location = "/v2/entities/" + eP->id; if (eP->type != "" ) { location += "?type=" + eP->type; } else { location += "?type=none"; } ciP->httpHeader.push_back(HTTP_RESOURCE_LOCATION); ciP->httpHeaderValue.push_back(location); ciP->httpStatusCode = sccCodeOnSuccess; } // 04. Cleanup and return result eP->release(); return answer; }
/* **************************************************************************** * * textParseAttributeValue - */ static std::string textParseAttributeValue(ConnectionInfo* ciP, ContextAttribute* caP) { double d; // 1. Starts and ends with citation marks? if (ciP->payload[0] == '"') { char* end = &ciP->payload[strlen(ciP->payload) - 1]; if (*end == '"') { *end = 0; caP->stringValue = &ciP->payload[1]; caP->valueType = orion::ValueTypeString; } else { OrionError oe(SccBadRequest, "Missing citation-mark at end of string"); return oe.render(ciP, ""); } } // 2. True or false? else if ((strlen(ciP->payload) == 4) && ((strcmp(ciP->payload, "true") == 0) || (strcmp(ciP->payload, "True") == 0) || (strcmp(ciP->payload, "TRUE") == 0))) { caP->boolValue = true; caP->valueType = orion::ValueTypeBoolean; } else if ((strlen(ciP->payload) == 5) && ((strcmp(ciP->payload, "false") == 0) || (strcmp(ciP->payload, "False") == 0) || (strcmp(ciP->payload, "FALSE") == 0))) { caP->boolValue = false; caP->valueType = orion::ValueTypeBoolean; } // 3. Null ? else if ((strlen(ciP->payload) == 4) && ((strcmp(ciP->payload, "null") == 0) || (strcmp(ciP->payload, "Null") == 0) || (strcmp(ciP->payload, "NULL") == 0))) { caP->valueType = orion::ValueTypeNone; } // // 4. Valid Double? // FIXME P4: this is much more complex than just (atof(string) != 0 || string == "0") // 0.000 also is a valid float and it given 0 - 0.0000000000, and 0e0 also ... // And, even worse, 123K gives 123.0 back, we would need to analyze the string to try to // find garbage bytes after it if we want to detect this error. // However, all of this is not so extremely important and for now, (strtod(string) != 0 || string== "0") is good enough // else if (((d = strtod(ciP->payload, NULL)) != 0) || ((ciP->payload[0] == '0') && (ciP->payload[1] == 0))) { caP->valueType = orion::ValueTypeNumber; caP->numberValue = d; } // 5. None of the above - it's an error else { OrionError oe(SccBadRequest, "attribute value type not recognized"); return oe.render(ciP, ""); } return "OK"; }
/* **************************************************************************** * * getEntity - * * GET /v2/entities/:id:[?attrs=:list:] * * Payload In: None * Payload Out: Entity * * * Fill in QueryContextRequest * Call standard op postQueryContext * Render Entity response * Cleanup and return result */ std::string getEntity ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { std::string attrs = ciP->uriParam["attrs"]; std::string type = ciP->uriParam["type"]; if (forbiddenIdChars(ciP->apiVersion, compV[2].c_str() , NULL)) { OrionError oe(SccBadRequest, INVAL_CHAR_URI); return oe.render(ciP, ""); } // Fill in QueryContextRequest parseDataP->qcr.res.fill(compV[2], type, "false", EntityTypeEmptyOrNotEmpty, ""); if (attrs != "") { std::vector<std::string> attrsV; stringSplit(attrs, ',', attrsV); for (std::vector<std::string>::const_iterator it = attrsV.begin(); it != attrsV.end(); ++it) { parseDataP->qcr.res.attributeList.push_back_if_absent(*it); } } // Call standard op postQueryContext postQueryContext(ciP, components, compV, parseDataP); // Render entity response Entity entity; // If request was for /entities/<<id>>/attrs, type and id should not be shown if (compV.size() == 4 && compV[3] == "attrs") { entity.hideIdAndType(); } entity.fill(&parseDataP->qcrs.res); std::string answer; TIMED_RENDER(answer = entity.render(ciP, EntityResponse)); if (parseDataP->qcrs.res.errorCode.code == SccOk && parseDataP->qcrs.res.contextElementResponseVector.size() > 1) { // No problem found, but we expect only one entity ciP->httpStatusCode = SccConflict; } else { // the same of the wrapped operation ciP->httpStatusCode = parseDataP->qcrs.res.errorCode.code; } // 04. Cleanup and return result entity.release(); parseDataP->qcr.res.release(); return answer; }
/* **************************************************************************** * * postBatchUpdate - * * POST /v2/op/update * * Payload In: BatchUpdateRequest * Payload Out: 201 or error * * URI parameters: * - limit=NUMBER * - offset=NUMBER * - options=keyValues */ std::string postBatchUpdate ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { BatchUpdate* buP = &parseDataP->bu.res; UpdateContextRequest* upcrP = &parseDataP->upcr.res; Entities entities; std::string answer; upcrP->fill(&buP->entities, buP->updateActionType.get()); buP->release(); // upcrP just 'took over' the data from buP, buP is no longer needed parseDataP->upcr.res.present(""); answer = postUpdateContext(ciP, components, compV, parseDataP); for (unsigned int ix = 0; ix < parseDataP->upcrs.res.contextElementResponseVector.size(); ++ix) { ContextElementResponse* cerP = parseDataP->upcrs.res.contextElementResponseVector[ix]; if (cerP->statusCode.code != SccOk) { parseDataP->upcrs.res.errorCode.fill(cerP->statusCode); } } // // If an error is flagged by ciP->httpStatusCode, store it in parseDataP->upcrs.res.errorCode // for later processing (not sure this ever happen ...) // if (ciP->httpStatusCode != SccOk) { parseDataP->upcrs.res.errorCode.code = ciP->httpStatusCode; parseDataP->upcrs.res.errorCode.details = answer; } // If postUpdateContext gives back a parseDataP->upcrs with !200 OK in 'errorCode', transform to HTTP Status error if (parseDataP->upcrs.res.errorCode.code != SccOk) { OrionError oe(parseDataP->upcrs.res.errorCode); ciP->httpStatusCode = parseDataP->upcrs.res.errorCode.code; // If 404 and details empty, assuming 'Entity not found' if ((parseDataP->upcrs.res.errorCode.code == SccContextElementNotFound) && (oe.details == "")) { oe.details = "Entity not found"; } answer = oe.render(ciP, ""); } else { // // NOTE // For simplicity, 204 is always returned, even if entities are created // ciP->httpStatusCode = SccNoContent; answer = ""; } // 04. Cleanup and return result entities.release(); parseDataP->upcr.res.release(); return answer; }
/* **************************************************************************** * * getEntities - * * GET /v2/entities * * Payload In: None * Payload Out: Entities * * URI parameters: * - limit=NUMBER * - offset=NUMBER * - count=true/false * - id * - idPattern * - q * - geometry * - coords * * 01. Fill in QueryContextRequest * 02. Call standard op postQueryContext * 03. Render Entities response * 04. Cleanup and return result */ std::string getEntities ( ConnectionInfo* ciP, int components, std::vector<std::string>& compV, ParseData* parseDataP ) { Entities entities; std::string answer; std::string pattern = ".*"; // all entities, default value std::string id = ciP->uriParam["id"]; std::string idPattern = ciP->uriParam["idPattern"]; std::string q = ciP->uriParam["q"]; std::string geometry = ciP->uriParam["geometry"]; std::string coords = ciP->uriParam["coords"]; std::string out; if ((idPattern != "") && (id != "")) { OrionError oe(SccBadRequest, "Incompatible parameters: id, IdPattern"); TIMED_RENDER(answer = oe.render(ciP, "")); return answer; } else if (id != "") { // FIXME: a more efficient query could be possible ... std::vector<std::string> idsV; stringSplit(id, ',', idsV); for (unsigned int ix = 0; ix != idsV.size(); ++ix) { if (ix != 0) { pattern += "|"; } pattern += idsV[ix]; } } else if (idPattern != "") { pattern = idPattern; } // Making sure geometry and coords are not used individually if ((coords != "") && (geometry == "")) { OrionError oe(SccBadRequest, "URI param /coords/ used without /geometry/"); TIMED_RENDER(out = oe.render(ciP, "")); return out; } else if ((geometry != "") && (coords == "")) { OrionError oe(SccBadRequest, "URI param /geometry/ used without /coords/"); TIMED_RENDER(out = oe.render(ciP, "")); return out; } // Making sure geometry is valid (if present) orion::Geometry geo; std::vector<std::string> coordsV; if (geometry != "") { std::string errorString; if (geo.parse(geometry.c_str(), &errorString) != 0) { OrionError oe(SccBadRequest, std::string("error parsing geometry: ") + errorString); TIMED_RENDER(out = oe.render(ciP, "")); return out; } if ((geo.areaType != "polygon") && (geo.areaType != "circle")) { OrionError oe(SccBadRequest, "URI param /geometry/ must be either /polygon/ or /circle/"); TIMED_RENDER(out = oe.render(ciP, "")); return out; } // // As 'geometry' is present, so is 'coords' - checking coords // int noOfCoords = stringSplit(coords, ';', coordsV); if (noOfCoords == 0) { OrionError oe(SccBadRequest, "URI param /coords/ has no coordinates"); TIMED_RENDER(out = oe.render(ciP, "")); return out; } if ((geo.areaType == "circle") && (noOfCoords != 1)) { OrionError oe(SccBadRequest, "Too many coordinates for circle"); TIMED_RENDER(out = oe.render(ciP, "")); return out; } if ((geo.areaType == "polygon") && (noOfCoords < 3)) { OrionError oe(SccBadRequest, "Too few coordinates for polygon"); TIMED_RENDER(out = oe.render(ciP, "")); return out; } } // // 01. Fill in QueryContextRequest - type "" is valid for all types // parseDataP->qcr.res.fill(pattern, ciP->uriParam["type"], "true", EntityTypeEmptyOrNotEmpty, ""); // If URI param 'q' is given, its value must be put in a scope if (q != "") { Scope* scopeP = new Scope(SCOPE_TYPE_SIMPLE_QUERY, q); parseDataP->qcr.res.restriction.scopeVector.push_back(scopeP); } // If URI params 'geometry' and 'coords' are given, another scope is to be created for this if ((coords != "") && (geometry != "")) { Scope* scopeP = new Scope(SCOPE_TYPE_LOCATION, ""); std::string errorString; if (scopeP->fill(&geo, coordsV, &errorString) != 0) { OrionError oe(SccBadRequest, errorString); TIMED_RENDER(out = oe.render(ciP, "")); return out; } parseDataP->qcr.res.restriction.scopeVector.push_back(scopeP); } // 02. Call standard op postQueryContext answer = postQueryContext(ciP, components, compV, parseDataP); if (ciP->httpStatusCode != SccOk) { // Something went wrong in the query, an invalid pattern for example parseDataP->qcr.res.release(); return answer; } // 03. Render Entities response if (parseDataP->qcrs.res.contextElementResponseVector.size() == 0) { ciP->httpStatusCode = SccOk; answer = "[]"; } else { entities.fill(&parseDataP->qcrs.res); TIMED_RENDER(answer = entities.render(ciP, EntitiesResponse)); } // 04. Cleanup and return result entities.release(); parseDataP->qcr.res.release(); return answer; }
void OverlayUserGroup::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { event->accept(); #ifdef Q_OS_MAC bool embed = g.ocIntercept != NULL; QMenu qm(embed ? NULL : event->widget()); if (embed) { QGraphicsScene *scene = g.ocIntercept->qgv.scene(); scene->addWidget(&qm); } #else QMenu qm(g.ocIntercept ? g.mw : event->widget()); #endif QMenu *qmShow = qm.addMenu(OverlayClient::tr("Filter")); QAction *qaShowTalking = qmShow->addAction(OverlayClient::tr("Only talking")); qaShowTalking->setCheckable(true); if (os->osShow == OverlaySettings::Talking) qaShowTalking->setChecked(true); QAction *qaShowActive = qmShow->addAction(OverlayClient::tr("Talking and recently active")); qaShowActive->setCheckable(true); if (os->osShow == OverlaySettings::Active) qaShowActive->setChecked(true); QAction *qaShowHome = qmShow->addAction(OverlayClient::tr("All in current channel")); qaShowHome->setCheckable(true); if (os->osShow == OverlaySettings::HomeChannel) qaShowHome->setChecked(true); QAction *qaShowLinked = qmShow->addAction(OverlayClient::tr("All in linked channels")); qaShowLinked->setCheckable(true); if (os->osShow == OverlaySettings::LinkedChannels) qaShowLinked->setChecked(true); qmShow->addSeparator(); QAction *qaShowSelf = qmShow->addAction(OverlayClient::tr("Always show yourself")); qaShowSelf->setCheckable(true); qaShowSelf->setEnabled(os->osShow == OverlaySettings::Talking || os->osShow == OverlaySettings::Active); if (os->bAlwaysSelf) qaShowSelf->setChecked(true); qmShow->addSeparator(); QAction *qaConfigureRecentlyActiveTime = qmShow->addAction(OverlayClient::tr("Configure recently active time (%1 seconds)...").arg(os->uiActiveTime)); qaConfigureRecentlyActiveTime->setEnabled(os->osShow == OverlaySettings::Active); QMenu *qmColumns = qm.addMenu(OverlayClient::tr("Columns")); QAction *qaColumns[6]; for (unsigned int i=1;i<=5;++i) { qaColumns[i] = qmColumns->addAction(QString::number(i)); qaColumns[i]->setCheckable(true); qaColumns[i]->setChecked(i == os->uiColumns); } QMenu *qmSort = qm.addMenu(OverlayClient::tr("Sort")); QAction *qaSortAlphabetically = qmSort->addAction(OverlayClient::tr("Alphabetically")); qaSortAlphabetically->setCheckable(true); if (os->osSort == OverlaySettings::Alphabetical) qaSortAlphabetically->setChecked(true); QAction *qaSortLastStateChange = qmSort->addAction(OverlayClient::tr("Last state change")); qaSortLastStateChange->setCheckable(true); if (os->osSort == OverlaySettings::LastStateChange) qaSortLastStateChange->setChecked(true); QAction *qaEdit = qm.addAction(OverlayClient::tr("Edit...")); QAction *qaZoom = qm.addAction(OverlayClient::tr("Reset Zoom")); QAction *act = qm.exec(event->screenPos()); if (! act) return; if (act == qaEdit) { if (g.ocIntercept) { QMetaObject::invokeMethod(g.ocIntercept, "openEditor", Qt::QueuedConnection); } else { OverlayEditor oe(qApp->activeModalWidget(), NULL, os); connect(&oe, SIGNAL(applySettings()), this, SLOT(updateLayout())); oe.exec(); } } else if (act == qaZoom) { os->fZoom = 1.0f; updateLayout(); } else if (act == qaShowTalking) { os->osShow = OverlaySettings::Talking; updateUsers(); } else if (act == qaShowActive) { os->osShow = OverlaySettings::Active; updateUsers(); } else if (act == qaShowHome) { os->osShow = OverlaySettings::HomeChannel; updateUsers(); } else if (act == qaShowLinked) { os->osShow = OverlaySettings::LinkedChannels; updateUsers(); } else if (act == qaShowSelf) { os->bAlwaysSelf = ! os->bAlwaysSelf; updateUsers(); } else if (act == qaConfigureRecentlyActiveTime) { // FIXME: This might not be the best place to configure this setting, but currently // there's not really a suitable place to put this. In the future an additional tab // might be added for some advanced overlay options, which could then include this // setting. bool ok; int newValue = QInputDialog::getInt( qm.parentWidget(), OverlayClient::tr("Configure recently active time"), OverlayClient::tr("Amount of seconds users remain active after talking:"), os->uiActiveTime, 1, 2147483647, 1, &ok); if (ok) { os->uiActiveTime = newValue; } updateUsers(); } else if (act == qaSortAlphabetically) { os->osSort = OverlaySettings::Alphabetical; updateUsers(); } else if (act == qaSortLastStateChange) { os->osSort = OverlaySettings::LastStateChange; updateUsers(); } else { for (int i=1;i<=5;++i) { if (act == qaColumns[i]) { os->uiColumns = i; updateLayout(); } } } }
/* **************************************************************************** * * jsonRequestTreat - */ std::string jsonRequestTreat ( ConnectionInfo* ciP, ParseData* parseDataP, RequestType requestType, JsonDelayedRelease* releaseP, std::vector<std::string>& compV ) { std::string answer; struct timespec start; struct timespec end; if (timingStatistics) { clock_gettime(CLOCK_REALTIME, &start); } switch (requestType) { case EntitiesRequest: // POST /v2/entities releaseP->entity = &parseDataP->ent.res; answer = parseEntity(ciP, &parseDataP->ent.res, false); if (answer != "OK") { return answer; } if ((answer = parseDataP->ent.res.check(ciP, EntitiesRequest)) != "OK") { OrionError oe(SccBadRequest, answer); return oe.setStatusCodeAndSmartRender(ciP); } break; case EntityRequest: // POST|PUT /v2/entities/<eid> releaseP->entity = &parseDataP->ent.res; answer = parseEntity(ciP, &parseDataP->ent.res, true); if (answer != "OK") { return answer; } if ((answer = parseDataP->ent.res.check(ciP, EntityRequest)) != "OK") { OrionError oe(SccBadRequest, answer); return oe.setStatusCodeAndSmartRender(ciP); } break; case EntityAttributeRequest: releaseP->attribute = &parseDataP->attr.attribute; releaseP->attribute->name = compV[4]; answer = parseContextAttribute(ciP, &parseDataP->attr.attribute); if (answer != "OK") { return answer; } if ((answer = parseDataP->attr.attribute.check(ciP, EntityAttributeRequest, "", "", 0)) != "OK") { OrionError oe(SccBadRequest, answer); return oe.setStatusCodeAndSmartRender(ciP); } break; case EntityAttributeValueRequest: releaseP->attribute = &parseDataP->av.attribute; answer = parseAttributeValue(ciP, &parseDataP->av.attribute); if (answer != "OK") { return answer; } break; case SubscriptionsRequest: answer = parseSubscription(ciP, &parseDataP->subsV2); if (answer != "OK") { return answer; } break; case IndividualSubscriptionRequest: answer = parseSubscription(ciP, &parseDataP->subsV2, true); // NOTE: partial == true if (answer != "OK") { return answer; } break; case BatchQueryRequest: answer = parseBatchQuery(ciP, &parseDataP->bq.res); if (answer != "OK") { return answer; } break; case BatchUpdateRequest: answer = parseBatchUpdate(ciP, &parseDataP->bu.res); if (answer != "OK") { return answer; } break; default: OrionError error(SccNotImplemented, "Request Treat function not implemented"); answer = error.render(); ciP->httpStatusCode = SccNotImplemented; break; } if (timingStatistics) { clock_gettime(CLOCK_REALTIME, &end); clock_difftime(&end, &start, &threadLastTimeStat.jsonV2ParseTime); } return answer; }