void NodeHierarchy<BasicTraits>::addAdapter (const GeomObjectType& obj) { CacheData& data = Cache::the()[obj]; AdapterType* adapter = FactoryType::the().newObject(); m_leaf.push_back(adapter); adapter->setObjectAdapter(&data); adapter->init(obj); data.setAdapter(AdapterType::getAdapterId(), adapter); }
void populateSchema( const AdapterType &node, Schema &schema, boost::optional<DereferenceFunction<AdapterType> > deref = boost::none, Schema *parentSchema = NULL, const std::string *ownName = NULL) { if ((isReference(node))) { const AdapterType &childNode = resolveReference<AdapterType>(deref, schema, node); populateSchema<AdapterType>(childNode, schema, deref, parentSchema, ownName); return; } const typename AdapterType::Object object = node.asObject(); typename AdapterType::Object::const_iterator itr(object.end()); if ((itr = object.find("id")) != object.end()) { if (itr->second.maybeString()) { schema.setId(itr->second.asString()); } } if ((itr = object.find("allOf")) != object.end()) { const AdapterType originalChildNode = itr->second; const AdapterType &actualChildNode = resolveReference<AdapterType>(deref, schema, originalChildNode); schema.addConstraint(makeAllOfConstraint(actualChildNode, deref)); } if ((itr = object.find("anyOf")) != object.end()) { schema.addConstraint(makeAnyOfConstraint(itr->second, deref)); } if ((itr = object.find("dependencies")) != object.end()) { schema.addConstraint(makeDependenciesConstraint(itr->second, deref)); } if ((itr = object.find("enum")) != object.end()) { schema.addConstraint(makeEnumConstraint(itr->second)); } { // Check for schema keywords that require the creation of a // ItemsConstraint instance. const typename AdapterType::Object::const_iterator itemsItr = object.find("items"), additionalitemsItr = object.find("additionalItems"); if (object.end() != itemsItr || object.end() != additionalitemsItr) { schema.addConstraint(makeItemsConstraint( itemsItr != object.end() ? &itemsItr->second : NULL, additionalitemsItr != object.end() ? &additionalitemsItr->second : NULL, deref)); } } if ((itr = object.find("maximum")) != object.end()) { typename AdapterType::Object::const_iterator exclusiveMaximumItr = object.find("exclusiveMaximum"); if (exclusiveMaximumItr == object.end()) { schema.addConstraint(makeMaximumConstraint<AdapterType>(itr->second, NULL)); } else { schema.addConstraint(makeMaximumConstraint(itr->second, &exclusiveMaximumItr->second)); } } else if (object.find("exclusiveMaximum") != object.end()) { // throw exception } if ((itr = object.find("maxItems")) != object.end()) { schema.addConstraint(makeMaxItemsConstraint(itr->second)); } if ((itr = object.find("maxLength")) != object.end()) { schema.addConstraint(makeMaxLengthConstraint(itr->second)); } if ((itr = object.find("maxProperties")) != object.end()) { schema.addConstraint(makeMaxPropertiesConstraint(itr->second)); } if ((itr = object.find("minimum")) != object.end()) { typename AdapterType::Object::const_iterator exclusiveMinimumItr = object.find("exclusiveMinimum"); if (exclusiveMinimumItr == object.end()) { schema.addConstraint(makeMinimumConstraint<AdapterType>(itr->second, NULL)); } else { schema.addConstraint(makeMinimumConstraint(itr->second, &exclusiveMinimumItr->second)); } } else if (object.find("exclusiveMinimum") != object.end()) { // throw exception } if ((itr = object.find("minItems")) != object.end()) { schema.addConstraint(makeMinItemsConstraint(itr->second)); } if ((itr = object.find("minLength")) != object.end()) { schema.addConstraint(makeMinLengthConstraint(itr->second)); } if ((itr = object.find("minProperties")) != object.end()) { schema.addConstraint(makeMinPropertiesConstraint(itr->second)); } if ((itr = object.find("not")) != object.end()) { schema.addConstraint(makeNotConstraint(itr->second, deref)); } if ((itr = object.find("oneOf")) != object.end()) { schema.addConstraint(makeOneOfConstraint(itr->second, deref)); } if ((itr = object.find("pattern")) != object.end()) { schema.addConstraint(makePatternConstraint(itr->second)); } { // Check for schema keywords that require the creation of a // PropertiesConstraint instance. const typename AdapterType::Object::const_iterator propertiesItr = object.find("properties"), patternPropertiesItr = object.find("patternProperties"), additionalPropertiesItr = object.find("additionalProperties"); if (object.end() != propertiesItr || object.end() != patternPropertiesItr || object.end() != additionalPropertiesItr) { schema.addConstraint(makePropertiesConstraint( propertiesItr != object.end() ? &propertiesItr->second : NULL, patternPropertiesItr != object.end() ? &patternPropertiesItr->second : NULL, additionalPropertiesItr != object.end() ? &additionalPropertiesItr->second : NULL, deref, &schema)); } } if ((itr = object.find("required")) != object.end()) { if (version == kDraft3) { if (parentSchema && ownName) { if (constraints::Constraint *c = makeRequiredConstraintForSelf(itr->second, *ownName)) { parentSchema->addConstraint(c); } } else { throw std::runtime_error("'required' constraint not valid here"); } } else { schema.addConstraint(makeRequiredConstraint(itr->second)); } } if ((itr = object.find("title")) != object.end()) { } if ((itr = object.find("type")) != object.end()) { schema.addConstraint(makeTypeConstraint(itr->second, deref)); } if ((itr = object.find("uniqueItems")) != object.end()) { constraints::Constraint *constraint = makeUniqueItemsConstraint(itr->second); if (constraint) { schema.addConstraint(constraint); } } }
inline AdapterType resolveJsonPointer( const AdapterType &node, const std::string &jsonPointer, const std::string::const_iterator jsonPointerItr) { // TODO: This function will probably need to implement support for // fetching documents referenced by JSON Pointers, similar to the // populateSchema function. const std::string::const_iterator jsonPointerEnd = jsonPointer.end(); // Terminate recursion if all reference tokens have been consumed if (jsonPointerItr == jsonPointerEnd) { return node; } // Reference tokens must begin with a leading slash if (*jsonPointerItr != '/') { throw std::runtime_error("Expected reference token to begin with " "leading slash; remaining tokens: " + std::string(jsonPointerItr, jsonPointerEnd)); } // Find iterator that points to next slash or newline character; this is // one character past the end of the current reference token std::string::const_iterator jsonPointerNext = std::find(jsonPointerItr + 1, jsonPointerEnd, '/'); // Extract the next reference token const std::string referenceToken = extractReferenceToken( jsonPointerItr + 1, jsonPointerNext); // Empty reference tokens should be ignored if (referenceToken.empty()) { return resolveJsonPointer(node, jsonPointer, jsonPointerNext); } else if (node.isArray()) { if (referenceToken.compare("-") == 0) { throw std::runtime_error("Hyphens cannot be used as array indices " "since the requested array element does not yet exist"); } try { // Fragment must be non-negative integer const uint64_t index = std::stoul(referenceToken); typedef typename AdapterType::Array Array; typename Array::const_iterator itr = node.asArray().begin(); if (index > node.asArray().size() - 1) { throw std::runtime_error("Expected reference token to identify " "an element in the current array, but array index is " "out of bounds; actual token: " + referenceToken); } if (index > static_cast<uint64_t>(std::numeric_limits<std::ptrdiff_t>::max())) { throw std::runtime_error("Array index out of bounds; hard " "limit is " + std::to_string( std::numeric_limits<std::ptrdiff_t>::max())); } itr.advance(static_cast<std::ptrdiff_t>(index)); // Recursively process the remaining tokens return resolveJsonPointer(*itr, jsonPointer, jsonPointerNext); } catch (std::invalid_argument &) { throw std::runtime_error("Expected reference token to contain a " "non-negative integer to identify an element in the " "current array; actual token: " + referenceToken); } } else if (node.maybeObject()) { // Fragment must identify a member of the candidate object typedef typename AdapterType::Object Object; typename Object::const_iterator itr = node.asObject().find( referenceToken); if (itr == node.asObject().end()) { throw std::runtime_error("Expected reference token to identify an " "element in the current object; " "actual token: " + referenceToken); } // Recursively process the remaining tokens return resolveJsonPointer(itr->second, jsonPointer, jsonPointerNext); } throw std::runtime_error("Expected end of JSON Pointer, but at least " "one reference token has not been processed; remaining tokens: " + std::string(jsonPointerNext, jsonPointerEnd)); }