예제 #1
0
bool ClassHandler::init(Core::BaseObject *obj, void *n, TagSet &mandatory) {
	xmlNodePtr node = reinterpret_cast<xmlNodePtr>(n);

	// Fill in mandatory tags
	for ( MemberList::iterator it = attributes.begin();
	      it != attributes.end(); ++it ) {
		if ( !it->optional ) mandatory.insert(it->tag);
	}

	for ( MemberList::iterator it = elements.begin();
	      it != elements.end(); ++it ) {
		if ( !it->optional && !it->tag.empty() ) mandatory.insert(it->tag);
	}

	for ( MemberList::iterator it = childs.begin();
	      it != childs.end(); ++it ) {
		if ( !it->optional && !it->tag.empty() ) mandatory.insert(it->tag);
	}

	if ( cdataUsed )
		cdata.get(obj, n, this);

	if ( attributes.empty() ) return true;

	for ( xmlAttrPtr attr = node->properties; attr != NULL; attr = attr->next ) {
		if ( attr->children ) {
			for ( MemberList::iterator it = attributes.begin();
			      it != attributes.end(); ++it ) {
				if ( equalsTag(attr, it->tag.c_str(), it->nameSpace.c_str()) ) {
					if ( it->get(obj, attr, this) && !it->optional ) {
						mandatory.erase(it->tag);
						break;
					}
				}
			}
		}
	}

	return true;
}
예제 #2
0
bool Importer::traverse(NodeHandler *handler, void *n, void *c, Core::BaseObject *target) {
	xmlNodePtr node = reinterpret_cast<xmlNodePtr>(n);
	xmlNodePtr childs = reinterpret_cast<xmlNodePtr>(c);
	ChildList remaining;
	TagSet mandatory;

	handler->init(target, n, mandatory);

	bool result = true;

	for ( xmlNodePtr child = childs; child != NULL; child = child->next ) {
		if ( child->type != XML_ELEMENT_NODE ) continue;

		handler->propagate(NULL, false, true);

		try {
			handler->get(target, child);
		}
		catch ( std::exception &e ) {
			if ( handler->isOptional )
				SEISCOMP_WARNING("(optional) %s.%s: %s", node->name, child->name, e.what());
			else
				throw e;
		}

		if ( !handler->isOptional )
			mandatory.erase((const char*)child->name);

		if ( handler->object == NULL && handler->isAnyType ) {
			if ( _any.get(target, child) ) {
				handler->object = _any.object;
				handler->childHandler = _any.childHandler;
				handler->newInstance = _any.newInstance;
			}
		}

		Core::BaseObject *newTarget = handler->object;
		MemberNodeHandler *memberHandler = handler->memberHandler;
		NodeHandler *childHandler = handler->childHandler;
		bool newInstance = handler->newInstance;
		bool optional = handler->isOptional;

		if ( newTarget ) {
			if ( childHandler == NULL ) {
				childHandler = _typemap->getHandler(newTarget->className());
				if ( childHandler == NULL ) {
					SEISCOMP_WARNING("No class handler for %s", newTarget->className());
					if ( newInstance )
						delete newTarget;
					handler->object = NULL;
					newTarget = NULL;
					childHandler = &_none;
				}
			}
		}
		else
			childHandler = &_none;

		try {
			if ( traverse(childHandler, child, child->children, handler->object) ) {
				if ( newTarget && newInstance && !memberHandler )
					remaining.push_back(newTarget);

			}
			else {
				if ( newTarget && newInstance )
					delete newTarget;
				newTarget = NULL;
				if ( optional )
					SEISCOMP_INFO("Invalid %s element: ignoring", child->name);
				else {
					SEISCOMP_WARNING("%s is not optional within %s", child->name, node->name);
					result = false;
				}
			}
		}
		catch ( std::exception &e ) {
			SEISCOMP_WARNING("%s: %s", child->name, e.what());
			if ( newTarget ) {
				if ( newInstance )
					delete newTarget;

				if ( !optional ) {
					SEISCOMP_WARNING("%s is not optional within %s", child->name, node->name);
					result = false;
				}
				else
					SEISCOMP_WARNING("%s: ignoring optional member %s: invalid", node->name, child->name);

				newTarget = NULL;
			}
		}

		if ( memberHandler ) {
			if ( !memberHandler->finalize(target, newTarget) ) {
				if ( newTarget && newInstance )
					remaining.push_back(newTarget);
			}
		}
	}

	handler->finalize(target, &remaining);

	if ( target != NULL ) {
		for ( ChildList::iterator it = remaining.begin(); it != remaining.end(); ++it )
			if ( *it != NULL ) delete *it;
	}
	else {
		for ( ChildList::iterator it = remaining.begin(); it != remaining.end(); ++it ) {
			if ( *it != NULL ) {
				if ( _result == NULL )
					_result = *it;
				else
					delete *it;
			}
		}
	}

	if ( !mandatory.empty() ) {
		std::string attribs;
		for ( TagSet::iterator it = mandatory.begin(); it != mandatory.end(); ++it ) {
			if ( it != mandatory.begin() ) attribs += ", ";
			attribs += *it;
		}
		SEISCOMP_WARNING("%s: missing mandatory attribute%s: %s", node->name, mandatory.size() == 1?"":"s", attribs.c_str());
		return false;
	}

	return result;
}