<commit_before>/* <x0d/plugins/director/DirectorPlugin.cpp>
 *
 * This file is part of the x0 web server project and is released under AGPL-3.
 * http://www.xzero.io/
 *
 * (c) 2009-2014 Christian Parpart <trapni@gmail.com>
 *
 * --------------------------------------------------------------------------
 *
 * plugin type: content generator
 *
 * description:
 *     Implements basic load balancing, ideally taking out the need of an HAproxy
 *     in front of us.
 *
 * setup API:
 *     function director.load(string director_name_1 => string path_to_db,
 *                            ...);
 *
 *     function director.cache.ttl(timespan, [timespan])
 *     function director.cache.deliver_stale
 *     function director.cache.deliver_active
 *
 * request processing API:
 *     handler director.balance(string director, string bucket = "");
 *     handler director.pass(string director, string backend);
 *
 *     handler director.fcgi(socket_spec);
 *     handler director.http(socket_spec);
 *
 *     handler director.ondemand();
 *     function director.cache.ttl(timespan ttl);
 *     function director.cache.ttl(timespan ttl, timespan shadow_ttl);
 *     function director.cache.key(string pattern);
 *     function director.cache.bypass();
 */

#include "DirectorPlugin.h"
#include "Director.h"
#include "Backend.h"
#include "ApiRequest.h"
#include "RequestNotes.h"
#include "RoadWarrior.h"
#include "HaproxyApi.h"
#include "ObjectCache.h"

#include <x0/http/HttpServer.h>
#include <x0/http/HttpRequest.h>
#include <x0/SocketSpec.h>
#include <x0/Url.h>
#include <x0/Types.h>

using namespace x0;

DirectorPlugin::DirectorPlugin(x0d::XzeroDaemon* d, const std::string& name) :
	x0d::XzeroPlugin(d, name),
	directors_(),
	roadWarrior_(),
	haproxyApi_(new HaproxyApi(&directors_))
{
    setupFunction("director.load", &DirectorPlugin::director_load)
        .param<FlowString>("name")
        .param<FlowString>("path");

#if defined(X0_DIRECTOR_CACHE)
    mainFunction("director.cache.key", &DirectorPlugin::director_cache_key, FlowType::String);
    mainFunction("director.cache.bypass", &DirectorPlugin::director_cache_bypass);
#endif

    mainHandler("director.balance", &DirectorPlugin::director_balance)
        .param<FlowString>("director")
        .param<FlowString>("bucket", "");

    mainHandler("director.pass", &DirectorPlugin::director_pass)
        .param<FlowString>("director")
        .param<FlowString>("backend");

    mainHandler("director.api", &DirectorPlugin::director_api)
        .param<FlowString>("prefix", "/");

    mainHandler("director.fcgi", &DirectorPlugin::director_fcgi)
        .param<IPAddress>("address", IPAddress("0.0.0.0"))
        .param<int>("port", 80)
        .param<int>("backlog", 128)
        .param<int>("multi_accept", 1)
        .param<bool>("reuse_port", false);

    mainHandler("director.http", &DirectorPlugin::director_http)
        .param<IPAddress>("address", IPAddress("0.0.0.0"))
        .param<int>("port", 80)
        .param<int>("backlog", 128)
        .param<int>("multi_accept", 1)
        .param<bool>("reuse_port", false);

    mainHandler("director.haproxy_stats", &DirectorPlugin::director_haproxy_stats)
        .param<FlowString>("prefix", "/");

    mainHandler("director.haproxy_monitor", &DirectorPlugin::director_haproxy_monitor)
        .param<FlowString>("prefix", "/");

    roadWarrior_ = new RoadWarrior(server().selectWorker());
}

DirectorPlugin::~DirectorPlugin()
{
	for (auto director: directors_)
		delete director.second;

	delete roadWarrior_;
	delete haproxyApi_;
}

RequestNotes* DirectorPlugin::requestNotes(HttpRequest* r)
{
	if (auto notes = r->customData<RequestNotes>(this))
		return notes;

	return r->setCustomData<RequestNotes>(this, r);
}

// {{{ setup_function director.load(name, path)
void DirectorPlugin::director_load(FlowVM::Params& args)
{
    const auto directorName = args.get<std::string>(1);
    const auto path = args.get<std::string>(2);

    // TODO verify that given director name is still available.
    // TODO verify that no director has been instanciated already by given path.

    server().log(Severity::debug, "director: Loading director %s from %s.", directorName.c_str(), path.c_str());

    Director* director = new Director(server().nextWorker(), directorName);
    if (!director)
        return;

    director->load(path);

    directors_[directorName] = director;
}
// }}}
// {{{ function director.cache.bypass()
#if defined(X0_DIRECTOR_CACHE)
void DirectorPlugin::director_cache_key(HttpRequest* r, FlowVM::Params& args)
{
	auto notes = requestNotes(r);
    notes->setCacheKey(args.get<FlowString>(1).str());
}

void DirectorPlugin::director_cache_bypass(HttpRequest* r, FlowVM::Params& args)
{
	auto notes = requestNotes(r);
	notes->cacheIgnore = true;
}
#endif
// }}}
// {{{ handler director.balance(string director_id [, string segment_id ] );
/**
 * \returns always true.
 */
bool DirectorPlugin::internalServerError(HttpRequest* r)
{
	if (r->status != HttpStatus::Undefined)
		r->status = HttpStatus::InternalServerError;

	r->finish();
	return true;
}

// handler director.balance(string director_name, string bucket_name = '');
bool DirectorPlugin::director_balance(HttpRequest* r, FlowVM::Params& args)
{
	std::string directorName = args.get<FlowString>(1).str();
	std::string bucketName = args.get<FlowString>(2).str();

    auto i = directors_.find(directorName);
    if (i == directors_.end()) {
        r->log(Severity::error, "director.balance(): No director with name '%s' configured.", directorName.c_str());
        return internalServerError(r);
    }
	Director* director = i->second;

	RequestShaper::Node* bucket = nullptr;
    if (!bucketName.empty()) {
        bucket = director->findBucket(bucketName);
        if (!bucket) {
            // explicit bucket specified, but not found -> ignore.
            bucket = director->rootBucket();
            r->log(Severity::error, "director: Requested bucket '%s' not found in director '%s'. Assigning root bucket.",
                bucketName.c_str(), directorName.c_str());
        }
    } else {
        bucket = director->rootBucket();
    }

	auto rn = requestNotes(r);
	rn->manager = director;

	server().log(Severity::debug, "director: passing request to %s [%s].", director->name().c_str(), bucket->name().c_str());
	director->schedule(rn, bucket);
	return true;
} // }}}
// {{{ handler director.pass(string director_id [, string backend_id ] );
bool DirectorPlugin::director_pass(HttpRequest* r, FlowVM::Params& args)
{
    std::string directorName = args.get<FlowString>(1).str();
    auto i = directors_.find(directorName);
    if (i == directors_.end()) {
        r->log(Severity::error, "director.pass(): No director with name '%s' configured.", directorName.c_str());
        return internalServerError(r);
    }
    Director* director = i->second;

    // custom backend route
    std::string backendName = args.get<FlowString>(2).str();
    Backend* backend = nullptr;
    if (!backendName.empty()) {
        backend = director->findBackend(backendName);

        if (!backend) {
            // explicit backend specified, but not found -> do not serve.
            r->log(Severity::error, "director: Requested backend '%s' not found.", backendName.c_str());
            return internalServerError(r);
        }
    }

	server().log(Severity::debug, "director: passing request to %s [backend %s].", director->name().c_str(), backend->name().c_str());

	auto rn = requestNotes(r);
	rn->manager = director;

	director->schedule(rn, backend);

	return true;
}
// }}}
// {{{ handler director.api(string prefix);
bool DirectorPlugin::director_api(HttpRequest* r, FlowVM::Params& args)
{
    const FlowString* prefix = args.get<FlowString*>(1);

    if (!r->path.begins(*prefix))
        return false;

    BufferRef path(r->path.ref(prefix->size()));

    return ApiRequest::process(&directors_, r, path);
}
// }}}
// {{{ handler director.fcgi(socketspec);
bool DirectorPlugin::director_fcgi(HttpRequest* r, FlowVM::Params& args)
{
    SocketSpec socketSpec(
        args.get<IPAddress>(1),  // bind addr
        args.get<FlowNumber>(2), // port
        args.get<FlowNumber>(3), // backlog
        args.get<FlowNumber>(4), // multi accept
        args.get<bool>(5)        // reuse port
    );

    roadWarrior_->handleRequest(requestNotes(r), socketSpec, RoadWarrior::FCGI);
    return true;
}
// }}}
// {{{ handler director.http(socketspec);
bool DirectorPlugin::director_http(HttpRequest* r, FlowVM::Params& args)
{
    SocketSpec socketSpec(
        args.get<IPAddress>(1),  // bind addr
        args.get<FlowNumber>(2), // port
        args.get<FlowNumber>(3), // backlog
        args.get<FlowNumber>(4), // multi accept
        args.get<bool>(5)        // reuse port
    );

    roadWarrior_->handleRequest(requestNotes(r), socketSpec, RoadWarrior::HTTP);
    return true;
}
// }}}
// {{{ haproxy compatibility API
bool DirectorPlugin::director_haproxy_monitor(HttpRequest* r, FlowVM::Params& args)
{
	const FlowString* prefix = args.get<FlowString*>(1);

	if (!r->path.begins(*prefix) && !r->unparsedUri.begins(*prefix))
		return false;

	haproxyApi_->monitor(r);
	return true;
}

bool DirectorPlugin::director_haproxy_stats(HttpRequest* r, FlowVM::Params& args)
{
	const FlowString* prefix = args.get<FlowString*>(1);

	if (!r->path.begins(*prefix) && !r->unparsedUri.begins(*prefix))
		return false;

	haproxyApi_->stats(r, prefix->str());
	return true;
}
// }}}
X0_EXPORT_PLUGIN_CLASS(DirectorPlugin)
<commit_msg>[x0d] director: fixes director.fcgi and director.http signature<commit_after>/* <x0d/plugins/director/DirectorPlugin.cpp>
 *
 * This file is part of the x0 web server project and is released under AGPL-3.
 * http://www.xzero.io/
 *
 * (c) 2009-2014 Christian Parpart <trapni@gmail.com>
 *
 * --------------------------------------------------------------------------
 *
 * plugin type: content generator
 *
 * description:
 *     Implements basic load balancing, ideally taking out the need of an HAproxy
 *     in front of us.
 *
 * setup API:
 *     function director.load(string director_name_1 => string path_to_db,
 *                            ...);
 *
 *     function director.cache.ttl(timespan, [timespan])
 *     function director.cache.deliver_stale
 *     function director.cache.deliver_active
 *
 * request processing API:
 *     handler director.balance(string director, string bucket = "");
 *     handler director.pass(string director, string backend);
 *
 *     handler director.fcgi(socket_spec);
 *     handler director.http(socket_spec);
 *
 *     handler director.ondemand();
 *     function director.cache.ttl(timespan ttl);
 *     function director.cache.ttl(timespan ttl, timespan shadow_ttl);
 *     function director.cache.key(string pattern);
 *     function director.cache.bypass();
 */

#include "DirectorPlugin.h"
#include "Director.h"
#include "Backend.h"
#include "ApiRequest.h"
#include "RequestNotes.h"
#include "RoadWarrior.h"
#include "HaproxyApi.h"
#include "ObjectCache.h"

#include <x0/http/HttpServer.h>
#include <x0/http/HttpRequest.h>
#include <x0/SocketSpec.h>
#include <x0/Url.h>
#include <x0/Types.h>

using namespace x0;

DirectorPlugin::DirectorPlugin(x0d::XzeroDaemon* d, const std::string& name) :
	x0d::XzeroPlugin(d, name),
	directors_(),
	roadWarrior_(),
	haproxyApi_(new HaproxyApi(&directors_))
{
    setupFunction("director.load", &DirectorPlugin::director_load)
        .param<FlowString>("name")
        .param<FlowString>("path");

#if defined(X0_DIRECTOR_CACHE)
    mainFunction("director.cache.key", &DirectorPlugin::director_cache_key, FlowType::String);
    mainFunction("director.cache.bypass", &DirectorPlugin::director_cache_bypass);
#endif

    mainHandler("director.balance", &DirectorPlugin::director_balance)
        .param<FlowString>("director")
        .param<FlowString>("bucket", "");

    mainHandler("director.pass", &DirectorPlugin::director_pass)
        .param<FlowString>("director")
        .param<FlowString>("backend");

    mainHandler("director.api", &DirectorPlugin::director_api)
        .param<FlowString>("prefix", "/");

    mainHandler("director.fcgi", &DirectorPlugin::director_fcgi)
        .param<IPAddress>("address", IPAddress("0.0.0.0"))
        .param<int>("port", 80);

    mainHandler("director.http", &DirectorPlugin::director_http)
        .param<IPAddress>("address", IPAddress("0.0.0.0"))
        .param<int>("port", 80);

    mainHandler("director.haproxy_stats", &DirectorPlugin::director_haproxy_stats)
        .param<FlowString>("prefix", "/");

    mainHandler("director.haproxy_monitor", &DirectorPlugin::director_haproxy_monitor)
        .param<FlowString>("prefix", "/");

    roadWarrior_ = new RoadWarrior(server().selectWorker());
}

DirectorPlugin::~DirectorPlugin()
{
	for (auto director: directors_)
		delete director.second;

	delete roadWarrior_;
	delete haproxyApi_;
}

RequestNotes* DirectorPlugin::requestNotes(HttpRequest* r)
{
	if (auto notes = r->customData<RequestNotes>(this))
		return notes;

	return r->setCustomData<RequestNotes>(this, r);
}

// {{{ setup_function director.load(name, path)
void DirectorPlugin::director_load(FlowVM::Params& args)
{
    const auto directorName = args.get<std::string>(1);
    const auto path = args.get<std::string>(2);

    // TODO verify that given director name is still available.
    // TODO verify that no director has been instanciated already by given path.

    server().log(Severity::debug, "director: Loading director %s from %s.", directorName.c_str(), path.c_str());

    Director* director = new Director(server().nextWorker(), directorName);
    if (!director)
        return;

    director->load(path);

    directors_[directorName] = director;
}
// }}}
// {{{ function director.cache.bypass()
#if defined(X0_DIRECTOR_CACHE)
void DirectorPlugin::director_cache_key(HttpRequest* r, FlowVM::Params& args)
{
	auto notes = requestNotes(r);
    notes->setCacheKey(args.get<FlowString>(1).str());
}

void DirectorPlugin::director_cache_bypass(HttpRequest* r, FlowVM::Params& args)
{
	auto notes = requestNotes(r);
	notes->cacheIgnore = true;
}
#endif
// }}}
// {{{ handler director.balance(string director_id [, string segment_id ] );
/**
 * \returns always true.
 */
bool DirectorPlugin::internalServerError(HttpRequest* r)
{
	if (r->status != HttpStatus::Undefined)
		r->status = HttpStatus::InternalServerError;

	r->finish();
	return true;
}

// handler director.balance(string director_name, string bucket_name = '');
bool DirectorPlugin::director_balance(HttpRequest* r, FlowVM::Params& args)
{
	std::string directorName = args.get<FlowString>(1).str();
	std::string bucketName = args.get<FlowString>(2).str();

    auto i = directors_.find(directorName);
    if (i == directors_.end()) {
        r->log(Severity::error, "director.balance(): No director with name '%s' configured.", directorName.c_str());
        return internalServerError(r);
    }
	Director* director = i->second;

	RequestShaper::Node* bucket = nullptr;
    if (!bucketName.empty()) {
        bucket = director->findBucket(bucketName);
        if (!bucket) {
            // explicit bucket specified, but not found -> ignore.
            bucket = director->rootBucket();
            r->log(Severity::error, "director: Requested bucket '%s' not found in director '%s'. Assigning root bucket.",
                bucketName.c_str(), directorName.c_str());
        }
    } else {
        bucket = director->rootBucket();
    }

	auto rn = requestNotes(r);
	rn->manager = director;

	server().log(Severity::debug, "director: passing request to %s [%s].", director->name().c_str(), bucket->name().c_str());
	director->schedule(rn, bucket);
	return true;
} // }}}
// {{{ handler director.pass(string director_id [, string backend_id ] );
bool DirectorPlugin::director_pass(HttpRequest* r, FlowVM::Params& args)
{
    std::string directorName = args.get<FlowString>(1).str();
    auto i = directors_.find(directorName);
    if (i == directors_.end()) {
        r->log(Severity::error, "director.pass(): No director with name '%s' configured.", directorName.c_str());
        return internalServerError(r);
    }
    Director* director = i->second;

    // custom backend route
    std::string backendName = args.get<FlowString>(2).str();
    Backend* backend = nullptr;
    if (!backendName.empty()) {
        backend = director->findBackend(backendName);

        if (!backend) {
            // explicit backend specified, but not found -> do not serve.
            r->log(Severity::error, "director: Requested backend '%s' not found.", backendName.c_str());
            return internalServerError(r);
        }
    }

	server().log(Severity::debug, "director: passing request to %s [backend %s].", director->name().c_str(), backend->name().c_str());

	auto rn = requestNotes(r);
	rn->manager = director;

	director->schedule(rn, backend);

	return true;
}
// }}}
// {{{ handler director.api(string prefix);
bool DirectorPlugin::director_api(HttpRequest* r, FlowVM::Params& args)
{
    const FlowString* prefix = args.get<FlowString*>(1);

    if (!r->path.begins(*prefix))
        return false;

    BufferRef path(r->path.ref(prefix->size()));

    return ApiRequest::process(&directors_, r, path);
}
// }}}
// {{{ handler director.fcgi(socketspec);
bool DirectorPlugin::director_fcgi(HttpRequest* r, FlowVM::Params& args)
{
    SocketSpec socketSpec(
        args.get<IPAddress>(1),  // bind addr
        args.get<FlowNumber>(2)  // port
    );

    roadWarrior_->handleRequest(requestNotes(r), socketSpec, RoadWarrior::FCGI);
    return true;
}
// }}}
// {{{ handler director.http(socketspec);
bool DirectorPlugin::director_http(HttpRequest* r, FlowVM::Params& args)
{
    SocketSpec socketSpec(
        args.get<IPAddress>(1),  // bind addr
        args.get<FlowNumber>(2)  // port
    );

    roadWarrior_->handleRequest(requestNotes(r), socketSpec, RoadWarrior::HTTP);
    return true;
}
// }}}
// {{{ haproxy compatibility API
bool DirectorPlugin::director_haproxy_monitor(HttpRequest* r, FlowVM::Params& args)
{
	const FlowString* prefix = args.get<FlowString*>(1);

	if (!r->path.begins(*prefix) && !r->unparsedUri.begins(*prefix))
		return false;

	haproxyApi_->monitor(r);
	return true;
}

bool DirectorPlugin::director_haproxy_stats(HttpRequest* r, FlowVM::Params& args)
{
	const FlowString* prefix = args.get<FlowString*>(1);

	if (!r->path.begins(*prefix) && !r->unparsedUri.begins(*prefix))
		return false;

	haproxyApi_->stats(r, prefix->str());
	return true;
}
// }}}
X0_EXPORT_PLUGIN_CLASS(DirectorPlugin)
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLEventExport.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 14:18:46 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLEVENTEXPORT_HXX
#include "XMLEventExport.hxx"
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

#ifndef _COM_SUN_STAR_DOCUMENT_XEVENTSSUPPLIER_HPP
#include <com/sun/star/document/XEventsSupplier.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEREPLACE_HPP
#include <com/sun/star/container/XNameReplace.hpp>
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif

using namespace ::com::sun::star::uno;

using std::map;
using ::rtl::OUString;
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::document::XEventsSupplier;
using ::com::sun::star::container::XNameReplace;
using ::com::sun::star::container::XNameAccess;
using ::xmloff::token::GetXMLToken;
using ::xmloff::token::XML_EVENT_LISTENERS;

XMLEventExport::XMLEventExport(SvXMLExport& rExp,
                         const XMLEventNameTranslation* pTranslationTable) :
    rExport(rExp),
    sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType"))
{
    AddTranslationTable(pTranslationTable);
}

XMLEventExport::~XMLEventExport()
{
    // delete all handlers
    HandlerMap::iterator aEnd = aHandlerMap.end();
    for( HandlerMap::iterator aIter =
             aHandlerMap.begin();
         aIter != aEnd;
         aIter++ )
    {
        delete aIter->second;
    }
    aHandlerMap.clear();
}

void XMLEventExport::AddHandler( const OUString& rName,
                                 XMLEventExportHandler* pHandler )
{
    DBG_ASSERT(pHandler != NULL, "Need EventExportHandler");
    if (pHandler != NULL)
    {
        aHandlerMap[rName] = pHandler;
    }
}

void XMLEventExport::AddTranslationTable(
    const XMLEventNameTranslation* pTransTable )
{
    if (NULL != pTransTable)
    {
        // put translation table into map
        for(const XMLEventNameTranslation* pTrans = pTransTable;
            pTrans->sAPIName != NULL;
            pTrans++)
        {
            aNameTranslationMap[OUString::createFromAscii(pTrans->sAPIName)] =
                XMLEventName(pTrans->nPrefix, pTrans->sXMLName);
        }
    }
    // else? ignore!
}

void XMLEventExport::Export( Reference<XEventsSupplier> & rSupplier,
                             sal_Bool bWhitespace)
{
    if (rSupplier.is())
    {
        Reference<XNameAccess> xAccess(rSupplier->getEvents(), UNO_QUERY);
        Export(xAccess, bWhitespace);
    }
    // else: no supplier, no export -> ignore!
}

void XMLEventExport::Export( Reference<XNameReplace> & rReplace,
                             sal_Bool bWhitespace)
{
    Reference<XNameAccess> xAccess(rReplace, UNO_QUERY);
    Export(xAccess, bWhitespace);
}

void XMLEventExport::Export( Reference<XNameAccess> & rAccess,
                             sal_Bool bWhitespace)
{
    // early out if we don't actually get any events
    if (!rAccess.is())
    {
        return;
    }

    // have we already processed an element?
    sal_Bool bStarted = sal_False;

    // iterate over all event types
    Sequence<OUString> aNames = rAccess->getElementNames();
    sal_Int32 nCount = aNames.getLength();
    for(sal_Int32 i = 0; i < nCount; i++)
    {
        // translate name
        NameMap::iterator aIter = aNameTranslationMap.find(aNames[i]);
        if (aIter != aNameTranslationMap.end())
        {
            const XMLEventName& rXmlName = aIter->second;

            // get PropertyValues for this event
            Any aAny = rAccess->getByName( aNames[i] );
            Sequence<PropertyValue> aValues;
            aAny >>= aValues;

            // now export the current event
            ExportEvent( aValues, rXmlName, bWhitespace, bStarted );
        }
        else
        {
            // don't proceed further
            DBG_ERROR("Unknown event name.");
        }
    }

    // close <script:events> element (if it was opened before)
    if (bStarted)
    {
        EndElement(bWhitespace);
    }
}

/// export a singular event and wirte <office:events> container
void XMLEventExport::ExportSingleEvent(
    Sequence<PropertyValue>& rEventValues,
    const OUString& rApiEventName,
    sal_Bool bUseWhitespace )
{
    // translate the name
    NameMap::iterator aIter = aNameTranslationMap.find(rApiEventName);
    if (aIter != aNameTranslationMap.end())
    {
        const XMLEventName& rXmlName = aIter->second;

        // export the event ...
        sal_Bool bStarted = sal_False;
        ExportEvent( rEventValues, rXmlName, bUseWhitespace, bStarted );

        // ... and close the container element (if necessary)
        if (bStarted)
        {
            EndElement(bUseWhitespace);
        }
    }
    else
    {
        // unknown name!
        DBG_ERROR("unknown event name");
    }
}

/// export a single event
void XMLEventExport::ExportEvent(
    Sequence<PropertyValue>& rEventValues,
    const XMLEventName& rXmlEventName,
    sal_Bool bUseWhitespace,
    sal_Bool& rExported )
{
    // search for EventType value and then delegate to EventHandler
    sal_Int32 nValues = rEventValues.getLength();
    const PropertyValue* pValues = rEventValues.getConstArray();

    for(sal_Int32 nVal = 0; nVal < nValues; nVal++)
    {
        if (sEventType.equals(pValues[nVal].Name))
        {
            // found! Now find handler and delegate
            OUString sType;
            pValues[nVal].Value >>= sType;

            if (aHandlerMap.count(sType))
            {
                if (! rExported)
                {
                    // OK, we have't yet exported the enclosing
                    // element. So we do that now.
                    rExported = sal_True;
                    StartElement(bUseWhitespace);
                }

                OUString aEventQName(
                    rExport.GetNamespaceMap().GetQNameByKey(
                            rXmlEventName.m_nPrefix, rXmlEventName.m_aName ) );

                // delegate to proper ExportEventHandler
                aHandlerMap[sType]->Export(rExport, aEventQName,
                                           rEventValues, bUseWhitespace);
            }
            else
            {
                if (! sType.equalsAsciiL("None", sizeof("None")-1))
                {
                    DBG_ERROR("unknown event type returned by API");
                    // unknown type -> error (ignore)
                }
                // else: we ignore None fields
            }

            // early out: we don't need to look for another type
            break;
        }
        // else: we only care for EventType -> ignore
    }
}

void XMLEventExport::StartElement(sal_Bool bWhitespace)
{
    if (bWhitespace)
    {
        rExport.IgnorableWhitespace();
    }
    rExport.StartElement( XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS,
                          bWhitespace);
}

void XMLEventExport::EndElement(sal_Bool bWhitespace)
{
    rExport.EndElement(XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, bWhitespace);
    if (bWhitespace)
    {
        rExport.IgnorableWhitespace();
    }
}

// implement aStandardEventTable (defined in xmlevent.hxx)
const XMLEventNameTranslation aStandardEventTable[] =
{
    { "OnSelect",           XML_NAMESPACE_DOM, "select" }, // "on-select"
    { "OnInsertStart",      XML_NAMESPACE_OFFICE, "insert-start" }, // "on-insert-start"
    { "OnInsertDone",       XML_NAMESPACE_OFFICE, "insert-done" }, // "on-insert-done"
    { "OnMailMerge",        XML_NAMESPACE_OFFICE, "mail-merge" }, // "on-mail-merge"
    { "OnAlphaCharInput",   XML_NAMESPACE_OFFICE, "alpha-char-input" }, // "on-alpha-char-input"
    { "OnNonAlphaCharInput",    XML_NAMESPACE_OFFICE, "non-alpha-char-input" }, // "on-non-alpha-char-input"
    { "OnResize",           XML_NAMESPACE_DOM, "resize" }, // "on-resize"
    { "OnMove",             XML_NAMESPACE_OFFICE, "move" }, // "on-move"
    { "OnPageCountChange",  XML_NAMESPACE_OFFICE, "page-count-change" }, // "on-page-count-change"
    { "OnMouseOver",        XML_NAMESPACE_DOM, "mouseover" }, // "on-mouse-over"
    { "OnClick",            XML_NAMESPACE_DOM, "click" }, // "on-click"
    { "OnMouseOut",         XML_NAMESPACE_DOM, "mouseout" }, // "on-mouse-out"
    { "OnLoadError",        XML_NAMESPACE_OFFICE, "load-error" }, // "on-load-error"
    { "OnLoadCancel",       XML_NAMESPACE_OFFICE, "load-cancel" }, // "on-load-cancel"
    { "OnLoadDone",         XML_NAMESPACE_OFFICE, "load-done" }, // "on-load-done"
    { "OnLoad",             XML_NAMESPACE_DOM, "load" }, // "on-load"
    { "OnUnload",           XML_NAMESPACE_DOM, "unload" }, // "on-unload"
    { "OnStartApp",         XML_NAMESPACE_OFFICE, "start-app" }, // "on-start-app"
    { "OnCloseApp",         XML_NAMESPACE_OFFICE, "close-app" }, // "on-close-app"
    { "OnNew",              XML_NAMESPACE_OFFICE, "new" }, // "on-new"
    { "OnSave",             XML_NAMESPACE_OFFICE, "save" }, // "on-save"
    { "OnSaveAs",           XML_NAMESPACE_OFFICE, "save-as" }, // "on-save-as"
    { "OnFocus",            XML_NAMESPACE_DOM, "DOMFocusIn" }, // "on-focus"
    { "OnUnfocus",          XML_NAMESPACE_DOM, "DOMFocusOut" }, // "on-unfocus"
    { "OnPrint",            XML_NAMESPACE_OFFICE, "print" }, // "on-print"
    { "OnError",            XML_NAMESPACE_DOM, "error" }, // "on-error"
    { "OnLoadFinished",     XML_NAMESPACE_OFFICE, "load-finished" }, // "on-load-finished"
    { "OnSaveFinished",     XML_NAMESPACE_OFFICE, "save-finished" }, // "on-save-finished"
    { "OnModifyChanged",    XML_NAMESPACE_OFFICE, "modify-changed" }, // "on-modify-changed"
    { "OnPrepareUnload",    XML_NAMESPACE_OFFICE, "prepare-unload" }, // "on-prepare-unload"
    { "OnNewMail",          XML_NAMESPACE_OFFICE, "new-mail" }, // "on-new-mail"
    { "OnToggleFullscreen", XML_NAMESPACE_OFFICE, "toggle-fullscreen" }, // "on-toggle-fullscreen"
    { "OnSaveDone",         XML_NAMESPACE_OFFICE, "save-done" }, // "on-save-done"
    { "OnSaveAsDone",       XML_NAMESPACE_OFFICE, "save-as-done" }, // "on-save-as-done"
    { "OnCopyTo",           XML_NAMESPACE_OFFICE, "copy-to" },
    { "OnCopyToDone",       XML_NAMESPACE_OFFICE, "copy-to-done" },
    { "OnViewCreated",      XML_NAMESPACE_OFFICE, "view-created" },
    { "OnPrepareViewClosing", XML_NAMESPACE_OFFICE, "prepare-view-closing" },
    { "OnViewClosed",       XML_NAMESPACE_OFFICE, "view-close" },
    { "OnVisAreaChanged",   XML_NAMESPACE_OFFICE, "visarea-changed" }, // "on-visarea-changed"

    { NULL, NULL }
};
<commit_msg>INTEGRATION: CWS warnings01 (1.15.34); FILE MERGED 2005/11/16 22:47:13 pl 1.15.34.2: #i55991# removed warnings 2005/11/03 17:47:01 cl 1.15.34.1: warning free code changes for unxlngi6<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLEventExport.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 18:22:19 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLEVENTEXPORT_HXX
#include "XMLEventExport.hxx"
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

#ifndef _COM_SUN_STAR_DOCUMENT_XEVENTSSUPPLIER_HPP
#include <com/sun/star/document/XEventsSupplier.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEREPLACE_HPP
#include <com/sun/star/container/XNameReplace.hpp>
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif

using namespace ::com::sun::star::uno;

using std::map;
using ::rtl::OUString;
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::document::XEventsSupplier;
using ::com::sun::star::container::XNameReplace;
using ::com::sun::star::container::XNameAccess;
using ::xmloff::token::GetXMLToken;
using ::xmloff::token::XML_EVENT_LISTENERS;

XMLEventExport::XMLEventExport(SvXMLExport& rExp,
                         const XMLEventNameTranslation* pTranslationTable) :
    sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")),
    rExport(rExp)
{
    AddTranslationTable(pTranslationTable);
}

XMLEventExport::~XMLEventExport()
{
    // delete all handlers
    HandlerMap::iterator aEnd = aHandlerMap.end();
    for( HandlerMap::iterator aIter =
             aHandlerMap.begin();
         aIter != aEnd;
         aIter++ )
    {
        delete aIter->second;
    }
    aHandlerMap.clear();
}

void XMLEventExport::AddHandler( const OUString& rName,
                                 XMLEventExportHandler* pHandler )
{
    DBG_ASSERT(pHandler != NULL, "Need EventExportHandler");
    if (pHandler != NULL)
    {
        aHandlerMap[rName] = pHandler;
    }
}

void XMLEventExport::AddTranslationTable(
    const XMLEventNameTranslation* pTransTable )
{
    if (NULL != pTransTable)
    {
        // put translation table into map
        for(const XMLEventNameTranslation* pTrans = pTransTable;
            pTrans->sAPIName != NULL;
            pTrans++)
        {
            aNameTranslationMap[OUString::createFromAscii(pTrans->sAPIName)] =
                XMLEventName(pTrans->nPrefix, pTrans->sXMLName);
        }
    }
    // else? ignore!
}

void XMLEventExport::Export( Reference<XEventsSupplier> & rSupplier,
                             sal_Bool bWhitespace)
{
    if (rSupplier.is())
    {
        Reference<XNameAccess> xAccess(rSupplier->getEvents(), UNO_QUERY);
        Export(xAccess, bWhitespace);
    }
    // else: no supplier, no export -> ignore!
}

void XMLEventExport::Export( Reference<XNameReplace> & rReplace,
                             sal_Bool bWhitespace)
{
    Reference<XNameAccess> xAccess(rReplace, UNO_QUERY);
    Export(xAccess, bWhitespace);
}

void XMLEventExport::Export( Reference<XNameAccess> & rAccess,
                             sal_Bool bWhitespace)
{
    // early out if we don't actually get any events
    if (!rAccess.is())
    {
        return;
    }

    // have we already processed an element?
    sal_Bool bStarted = sal_False;

    // iterate over all event types
    Sequence<OUString> aNames = rAccess->getElementNames();
    sal_Int32 nCount = aNames.getLength();
    for(sal_Int32 i = 0; i < nCount; i++)
    {
        // translate name
        NameMap::iterator aIter = aNameTranslationMap.find(aNames[i]);
        if (aIter != aNameTranslationMap.end())
        {
            const XMLEventName& rXmlName = aIter->second;

            // get PropertyValues for this event
            Any aAny = rAccess->getByName( aNames[i] );
            Sequence<PropertyValue> aValues;
            aAny >>= aValues;

            // now export the current event
            ExportEvent( aValues, rXmlName, bWhitespace, bStarted );
        }
        else
        {
            // don't proceed further
            DBG_ERROR("Unknown event name.");
        }
    }

    // close <script:events> element (if it was opened before)
    if (bStarted)
    {
        EndElement(bWhitespace);
    }
}

/// export a singular event and wirte <office:events> container
void XMLEventExport::ExportSingleEvent(
    Sequence<PropertyValue>& rEventValues,
    const OUString& rApiEventName,
    sal_Bool bUseWhitespace )
{
    // translate the name
    NameMap::iterator aIter = aNameTranslationMap.find(rApiEventName);
    if (aIter != aNameTranslationMap.end())
    {
        const XMLEventName& rXmlName = aIter->second;

        // export the event ...
        sal_Bool bStarted = sal_False;
        ExportEvent( rEventValues, rXmlName, bUseWhitespace, bStarted );

        // ... and close the container element (if necessary)
        if (bStarted)
        {
            EndElement(bUseWhitespace);
        }
    }
    else
    {
        // unknown name!
        DBG_ERROR("unknown event name");
    }
}

/// export a single event
void XMLEventExport::ExportEvent(
    Sequence<PropertyValue>& rEventValues,
    const XMLEventName& rXmlEventName,
    sal_Bool bUseWhitespace,
    sal_Bool& rExported )
{
    // search for EventType value and then delegate to EventHandler
    sal_Int32 nValues = rEventValues.getLength();
    const PropertyValue* pValues = rEventValues.getConstArray();

    for(sal_Int32 nVal = 0; nVal < nValues; nVal++)
    {
        if (sEventType.equals(pValues[nVal].Name))
        {
            // found! Now find handler and delegate
            OUString sType;
            pValues[nVal].Value >>= sType;

            if (aHandlerMap.count(sType))
            {
                if (! rExported)
                {
                    // OK, we have't yet exported the enclosing
                    // element. So we do that now.
                    rExported = sal_True;
                    StartElement(bUseWhitespace);
                }

                OUString aEventQName(
                    rExport.GetNamespaceMap().GetQNameByKey(
                            rXmlEventName.m_nPrefix, rXmlEventName.m_aName ) );

                // delegate to proper ExportEventHandler
                aHandlerMap[sType]->Export(rExport, aEventQName,
                                           rEventValues, bUseWhitespace);
            }
            else
            {
                if (! sType.equalsAsciiL("None", sizeof("None")-1))
                {
                    DBG_ERROR("unknown event type returned by API");
                    // unknown type -> error (ignore)
                }
                // else: we ignore None fields
            }

            // early out: we don't need to look for another type
            break;
        }
        // else: we only care for EventType -> ignore
    }
}

void XMLEventExport::StartElement(sal_Bool bWhitespace)
{
    if (bWhitespace)
    {
        rExport.IgnorableWhitespace();
    }
    rExport.StartElement( XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS,
                          bWhitespace);
}

void XMLEventExport::EndElement(sal_Bool bWhitespace)
{
    rExport.EndElement(XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, bWhitespace);
    if (bWhitespace)
    {
        rExport.IgnorableWhitespace();
    }
}

// implement aStandardEventTable (defined in xmlevent.hxx)
const XMLEventNameTranslation aStandardEventTable[] =
{
    { "OnSelect",           XML_NAMESPACE_DOM, "select" }, // "on-select"
    { "OnInsertStart",      XML_NAMESPACE_OFFICE, "insert-start" }, // "on-insert-start"
    { "OnInsertDone",       XML_NAMESPACE_OFFICE, "insert-done" }, // "on-insert-done"
    { "OnMailMerge",        XML_NAMESPACE_OFFICE, "mail-merge" }, // "on-mail-merge"
    { "OnAlphaCharInput",   XML_NAMESPACE_OFFICE, "alpha-char-input" }, // "on-alpha-char-input"
    { "OnNonAlphaCharInput",    XML_NAMESPACE_OFFICE, "non-alpha-char-input" }, // "on-non-alpha-char-input"
    { "OnResize",           XML_NAMESPACE_DOM, "resize" }, // "on-resize"
    { "OnMove",             XML_NAMESPACE_OFFICE, "move" }, // "on-move"
    { "OnPageCountChange",  XML_NAMESPACE_OFFICE, "page-count-change" }, // "on-page-count-change"
    { "OnMouseOver",        XML_NAMESPACE_DOM, "mouseover" }, // "on-mouse-over"
    { "OnClick",            XML_NAMESPACE_DOM, "click" }, // "on-click"
    { "OnMouseOut",         XML_NAMESPACE_DOM, "mouseout" }, // "on-mouse-out"
    { "OnLoadError",        XML_NAMESPACE_OFFICE, "load-error" }, // "on-load-error"
    { "OnLoadCancel",       XML_NAMESPACE_OFFICE, "load-cancel" }, // "on-load-cancel"
    { "OnLoadDone",         XML_NAMESPACE_OFFICE, "load-done" }, // "on-load-done"
    { "OnLoad",             XML_NAMESPACE_DOM, "load" }, // "on-load"
    { "OnUnload",           XML_NAMESPACE_DOM, "unload" }, // "on-unload"
    { "OnStartApp",         XML_NAMESPACE_OFFICE, "start-app" }, // "on-start-app"
    { "OnCloseApp",         XML_NAMESPACE_OFFICE, "close-app" }, // "on-close-app"
    { "OnNew",              XML_NAMESPACE_OFFICE, "new" }, // "on-new"
    { "OnSave",             XML_NAMESPACE_OFFICE, "save" }, // "on-save"
    { "OnSaveAs",           XML_NAMESPACE_OFFICE, "save-as" }, // "on-save-as"
    { "OnFocus",            XML_NAMESPACE_DOM, "DOMFocusIn" }, // "on-focus"
    { "OnUnfocus",          XML_NAMESPACE_DOM, "DOMFocusOut" }, // "on-unfocus"
    { "OnPrint",            XML_NAMESPACE_OFFICE, "print" }, // "on-print"
    { "OnError",            XML_NAMESPACE_DOM, "error" }, // "on-error"
    { "OnLoadFinished",     XML_NAMESPACE_OFFICE, "load-finished" }, // "on-load-finished"
    { "OnSaveFinished",     XML_NAMESPACE_OFFICE, "save-finished" }, // "on-save-finished"
    { "OnModifyChanged",    XML_NAMESPACE_OFFICE, "modify-changed" }, // "on-modify-changed"
    { "OnPrepareUnload",    XML_NAMESPACE_OFFICE, "prepare-unload" }, // "on-prepare-unload"
    { "OnNewMail",          XML_NAMESPACE_OFFICE, "new-mail" }, // "on-new-mail"
    { "OnToggleFullscreen", XML_NAMESPACE_OFFICE, "toggle-fullscreen" }, // "on-toggle-fullscreen"
    { "OnSaveDone",         XML_NAMESPACE_OFFICE, "save-done" }, // "on-save-done"
    { "OnSaveAsDone",       XML_NAMESPACE_OFFICE, "save-as-done" }, // "on-save-as-done"
    { "OnCopyTo",           XML_NAMESPACE_OFFICE, "copy-to" },
    { "OnCopyToDone",       XML_NAMESPACE_OFFICE, "copy-to-done" },
    { "OnViewCreated",      XML_NAMESPACE_OFFICE, "view-created" },
    { "OnPrepareViewClosing", XML_NAMESPACE_OFFICE, "prepare-view-closing" },
    { "OnViewClosed",       XML_NAMESPACE_OFFICE, "view-close" },
    { "OnVisAreaChanged",   XML_NAMESPACE_OFFICE, "visarea-changed" }, // "on-visarea-changed"

    { NULL, 0, 0 }
};
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/string_util.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome/browser/net/url_request_failed_dns_job.h"
#include "chrome/browser/net/url_request_mock_http_job.h"
#include "net/test/test_server.h"

class ErrorPageTest : public UITest {
 protected:
  bool WaitForTitleMatching(const std::wstring& title) {
    for (int i = 0; i < 10; ++i) {
      if (GetActiveTabTitle() == title)
        return true;
      base::PlatformThread::Sleep(TestTimeouts::action_timeout_ms());
    }
    EXPECT_EQ(title, GetActiveTabTitle());
    return false;
  }
};

TEST_F(ErrorPageTest, DNSError_Basic) {
  GURL test_url(URLRequestFailedDnsJob::kTestUrl);

  // The first navigation should fail, and the second one should be the error
  // page.
  NavigateToURLBlockUntilNavigationsComplete(test_url, 2);

  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
}

TEST_F(ErrorPageTest, DNSError_GoBack1) {
  // Test that a DNS error occuring in the main frame does not result in an
  // additional session history entry.
  GURL test_url(URLRequestFailedDnsJob::kTestUrl);

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title2.html"))));
  // The first navigation should fail, and the second one should be the error
  // page.
  NavigateToURLBlockUntilNavigationsComplete(test_url, 2);
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));

  EXPECT_TRUE(GetActiveTab()->GoBack());

  EXPECT_TRUE(WaitForTitleMatching(L"Title Of Awesomeness"));
}

TEST_F(ErrorPageTest, DNSError_GoBack2) {
  // Test that a DNS error occuring in the main frame does not result in an
  // additional session history entry.
  GURL test_url(URLRequestFailedDnsJob::kTestUrl);

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title2.html"))));
  // The first navigation should fail, and the second one should be the error
  // page.
  NavigateToURLBlockUntilNavigationsComplete(test_url, 2);
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title3.html"))));

  // The first navigation should fail, and the second one should be the error
  // page.
  EXPECT_TRUE(GetActiveTab()->GoBackBlockUntilNavigationsComplete(2));
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  EXPECT_TRUE(GetActiveTab()->GoBack());

  EXPECT_TRUE(WaitForTitleMatching(L"Title Of Awesomeness"));
}

TEST_F(ErrorPageTest, DNSError_GoBack2AndForward) {
  // Test that a DNS error occuring in the main frame does not result in an
  // additional session history entry.

  GURL test_url(URLRequestFailedDnsJob::kTestUrl);

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title2.html"))));
  // The first navigation should fail, and the second one should be the error
  // page.
  NavigateToURLBlockUntilNavigationsComplete(test_url, 2);
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title3.html"))));

  // The first navigation should fail, and the second one should be the error
  // page.
  EXPECT_TRUE(GetActiveTab()->GoBackBlockUntilNavigationsComplete(2));
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  EXPECT_TRUE(GetActiveTab()->GoBack());
  // The first navigation should fail, and the second one should be the error
  // page.
  EXPECT_TRUE(GetActiveTab()->GoForwardBlockUntilNavigationsComplete(2));

  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
}

// Flaky on Linux x64, see http://crbug.com/79412
#if defined(OS_LINUX) && defined(ARCH_CPU_64_BITS)
#define MAYBE_DNSError_GoBack2Forward2 FLAKY_DNSError_GoBack2Forward2
#else
#define MAYBE_DNSError_GoBack2Forward2 DNSError_GoBack2Forward2
#endif
TEST_F(ErrorPageTest, DNSError_GoBack2Forward2) {
  // Test that a DNS error occuring in the main frame does not result in an
  // additional session history entry.

  GURL test_url(URLRequestFailedDnsJob::kTestUrl);

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title3.html"))));
  // The first navigation should fail, and the second one should be the error
  // page.
  NavigateToURLBlockUntilNavigationsComplete(test_url, 2);
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title2.html"))));

  // The first navigation should fail, and the second one should be the error
  // page.
  EXPECT_TRUE(GetActiveTab()->GoBackBlockUntilNavigationsComplete(2));
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  EXPECT_TRUE(GetActiveTab()->GoBack());
  // The first navigation should fail, and the second one should be the error
  // page.
  EXPECT_TRUE(GetActiveTab()->GoForwardBlockUntilNavigationsComplete(2));
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  EXPECT_TRUE(GetActiveTab()->GoForward());

  EXPECT_TRUE(WaitForTitleMatching(L"Title Of Awesomeness"));
}

TEST_F(ErrorPageTest, IFrameDNSError_Basic) {
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("iframe_dns_error.html"))));
  EXPECT_TRUE(WaitForTitleMatching(L"Blah"));
}

TEST_F(ErrorPageTest, IFrameDNSError_GoBack) {
  // Test that a DNS error occuring in an iframe does not result in an
  // additional session history entry.

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title2.html"))));
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("iframe_dns_error.html"))));

  EXPECT_TRUE(GetActiveTab()->GoBack());

  EXPECT_TRUE(WaitForTitleMatching(L"Title Of Awesomeness"));
}

TEST_F(ErrorPageTest, IFrameDNSError_GoBackAndForward) {
  // Test that a DNS error occuring in an iframe does not result in an
  // additional session history entry.

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title2.html"))));
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("iframe_dns_error.html"))));

  EXPECT_TRUE(GetActiveTab()->GoBack());
  EXPECT_TRUE(GetActiveTab()->GoForward());

  EXPECT_TRUE(WaitForTitleMatching(L"Blah"));
}

// Checks that the Link Doctor is not loaded when we receive an actual 404 page.
TEST_F(ErrorPageTest, Page404) {
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("page404.html"))));

  EXPECT_TRUE(WaitForTitleMatching(L"SUCCESS"));
}
<commit_msg>Disable flaky error page tests<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/string_util.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome/browser/net/url_request_failed_dns_job.h"
#include "chrome/browser/net/url_request_mock_http_job.h"
#include "net/test/test_server.h"

class ErrorPageTest : public UITest {
 protected:
  bool WaitForTitleMatching(const std::wstring& title) {
    for (int i = 0; i < 10; ++i) {
      if (GetActiveTabTitle() == title)
        return true;
      base::PlatformThread::Sleep(TestTimeouts::action_timeout_ms());
    }
    EXPECT_EQ(title, GetActiveTabTitle());
    return false;
  }
};

TEST_F(ErrorPageTest, DNSError_Basic) {
  GURL test_url(URLRequestFailedDnsJob::kTestUrl);

  // The first navigation should fail, and the second one should be the error
  // page.
  NavigateToURLBlockUntilNavigationsComplete(test_url, 2);

  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
}

TEST_F(ErrorPageTest, DNSError_GoBack1) {
  // Test that a DNS error occuring in the main frame does not result in an
  // additional session history entry.
  GURL test_url(URLRequestFailedDnsJob::kTestUrl);

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title2.html"))));
  // The first navigation should fail, and the second one should be the error
  // page.
  NavigateToURLBlockUntilNavigationsComplete(test_url, 2);
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));

  EXPECT_TRUE(GetActiveTab()->GoBack());

  EXPECT_TRUE(WaitForTitleMatching(L"Title Of Awesomeness"));
}

// Flaky on Linux, see http://crbug.com/19361
#if defined(OS_LINUX)
#define MAYBE_DNSError_GoBack2 FLAKY_DNSError_GoBack2
#else
#define MAYBE_DNSError_GoBack2 DNSError_GoBack2
#endif
TEST_F(ErrorPageTest, MAYBE_DNSError_GoBack2) {
  // Test that a DNS error occuring in the main frame does not result in an
  // additional session history entry.
  GURL test_url(URLRequestFailedDnsJob::kTestUrl);

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title2.html"))));
  // The first navigation should fail, and the second one should be the error
  // page.
  NavigateToURLBlockUntilNavigationsComplete(test_url, 2);
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title3.html"))));

  // The first navigation should fail, and the second one should be the error
  // page.
  EXPECT_TRUE(GetActiveTab()->GoBackBlockUntilNavigationsComplete(2));
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  EXPECT_TRUE(GetActiveTab()->GoBack());

  EXPECT_TRUE(WaitForTitleMatching(L"Title Of Awesomeness"));
}

// Flaky on Linux, see http://crbug.com/19361
#if defined(OS_LINUX)
#define MAYBE_DNSError_GoBack2AndForwar FLAKY_DNSError_GoBack2AndForwar
#else
#define MAYBE_DNSError_GoBack2AndForwar DNSError_GoBack2AndForwar
#endif
TEST_F(ErrorPageTest, MAYBE_DNSError_GoBack2AndForward) {
  // Test that a DNS error occuring in the main frame does not result in an
  // additional session history entry.

  GURL test_url(URLRequestFailedDnsJob::kTestUrl);

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title2.html"))));
  // The first navigation should fail, and the second one should be the error
  // page.
  NavigateToURLBlockUntilNavigationsComplete(test_url, 2);
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title3.html"))));

  // The first navigation should fail, and the second one should be the error
  // page.
  EXPECT_TRUE(GetActiveTab()->GoBackBlockUntilNavigationsComplete(2));
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  EXPECT_TRUE(GetActiveTab()->GoBack());
  // The first navigation should fail, and the second one should be the error
  // page.
  EXPECT_TRUE(GetActiveTab()->GoForwardBlockUntilNavigationsComplete(2));

  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
}

// Flaky on Linux, see http://crbug.com/19361
#if defined(OS_LINUX)
#define MAYBE_DNSError_GoBack2Forward2 FLAKY_DNSError_GoBack2Forward2
#else
#define MAYBE_DNSError_GoBack2Forward2 DNSError_GoBack2Forward2
#endif
TEST_F(ErrorPageTest, MAYBE_DNSError_GoBack2Forward2) {
  // Test that a DNS error occuring in the main frame does not result in an
  // additional session history entry.

  GURL test_url(URLRequestFailedDnsJob::kTestUrl);

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title3.html"))));
  // The first navigation should fail, and the second one should be the error
  // page.
  NavigateToURLBlockUntilNavigationsComplete(test_url, 2);
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title2.html"))));

  // The first navigation should fail, and the second one should be the error
  // page.
  EXPECT_TRUE(GetActiveTab()->GoBackBlockUntilNavigationsComplete(2));
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  EXPECT_TRUE(GetActiveTab()->GoBack());
  // The first navigation should fail, and the second one should be the error
  // page.
  EXPECT_TRUE(GetActiveTab()->GoForwardBlockUntilNavigationsComplete(2));
  EXPECT_TRUE(WaitForTitleMatching(L"Mock Link Doctor"));
  EXPECT_TRUE(GetActiveTab()->GoForward());

  EXPECT_TRUE(WaitForTitleMatching(L"Title Of Awesomeness"));
}

TEST_F(ErrorPageTest, IFrameDNSError_Basic) {
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("iframe_dns_error.html"))));
  EXPECT_TRUE(WaitForTitleMatching(L"Blah"));
}

TEST_F(ErrorPageTest, IFrameDNSError_GoBack) {
  // Test that a DNS error occuring in an iframe does not result in an
  // additional session history entry.

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title2.html"))));
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("iframe_dns_error.html"))));

  EXPECT_TRUE(GetActiveTab()->GoBack());

  EXPECT_TRUE(WaitForTitleMatching(L"Title Of Awesomeness"));
}

TEST_F(ErrorPageTest, IFrameDNSError_GoBackAndForward) {
  // Test that a DNS error occuring in an iframe does not result in an
  // additional session history entry.

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("title2.html"))));
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("iframe_dns_error.html"))));

  EXPECT_TRUE(GetActiveTab()->GoBack());
  EXPECT_TRUE(GetActiveTab()->GoForward());

  EXPECT_TRUE(WaitForTitleMatching(L"Blah"));
}

// Checks that the Link Doctor is not loaded when we receive an actual 404 page.
TEST_F(ErrorPageTest, Page404) {
  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(
                    FilePath(FILE_PATH_LITERAL("page404.html"))));

  EXPECT_TRUE(WaitForTitleMatching(L"SUCCESS"));
}
<|endoftext|>


<commit_before><commit_msg>GTK Theme: Fix corner offsets on the find bar.<commit_after><|endoftext|>


<commit_before><commit_msg>linux: more NOTIMPLEMENTED bugs.<commit_after><|endoftext|>


<commit_before><commit_msg>Put findbar close button back where it belongs.<commit_after><|endoftext|>


<commit_before><commit_msg>Revert "It looks like the unit tests instantiate the TaskManagerView..."<commit_after><|endoftext|>


<commit_before>#include "jsonrequestparser.h"

JSONRequestParser::JSONRequestParser(bool debug, QObject *parent) : QObject(parent)
{
    m_debug = debug;
}
QSharedPointer<VISSRequest> JSONRequestParser::parseJson(QString json)
{
    QSharedPointer<VISSRequest> request = QSharedPointer<VISSRequest>(new VISSRequest(json), &QObject::deleteLater);
    request.data()->setJsonDocument(QJsonDocument::fromJson(json.toUtf8(), &m_parseError));

    if(!isValidJson())
    {
        if(m_debug) { qDebug() << "json invalid"; }
        return request;
    }
    request->setJsonObject(request->getJsonDocument().object());

    if(!validateAction(request.data())) { return request; }

    switch (request->getAction())
    {
        case GET:
            if(!validateGetRequest(request.data())) { request->invalidateRequest(); }
            break;
        case SET:
            if(!validateSetRequest(request.data())) { request->invalidateRequest(); }
            break;
        case SUBSCRIBE:
            if(!validateSubscribeRequest(request.data())) { request->invalidateRequest(); }
            break;
        case UNSUBSCRIBE:
            if(!validateUnsubscribeRequest(request.data())) { request->invalidateRequest(); }
            break;
        case UNSUBSCRIBEALL:
            if(!validateUnsubscribeRequest(request.data())) { request->invalidateRequest(); }
            break;
        case AUTHORIZE:
            if(!validateAuthorizeRequest(request.data())) { request->invalidateRequest(); }
            break;
        case GETVSS:
            if(!validateGetVSSRequest(request.data())) { request->invalidateRequest(); }
            break;
        case ERROR: // Just to remove compilation warning.
            request->invalidateRequest();
            break;
    }
    return request;
}

// Validate the different Requests

/*
    {
    "action": "get",
    "path": "Signal.Drivetrain.InternalCombustionEngine.RPM",
    "requestId": "8756"
    }
*/
bool JSONRequestParser::validateGetRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];
    QJsonValue valuePath = request->getJsonObject()["path"];

    bool valid = (validateId(valueId) && validatePath(valuePath));

    if(m_debug) { qDebug() << "validateGetRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        request->setSignalPath(valuePath.toString());
        return true;
    }
}

/*
    {
    "action": "set",
    "path": "Signal.Drivetrain.InternalCombustionEngine.RPM",
    "value": 2000,
    "requestId": "8912"
    }
*/
bool JSONRequestParser::validateSetRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];
    QJsonValue valuePath = request->getJsonObject()["path"];
    QJsonValue valueValue = request->getJsonObject()["value"];

    bool valid = (validateId(valueId) && validatePath(valuePath) && validateValue(valueValue));

    if(m_debug) { qDebug() << "validateSetRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        request->setSignalPath(valuePath.toString());
        request->setValue(valueValue.toVariant());
        return true;
    }
}

/*
    {
    "action": "subscribe",
    "path": "Signal.Drivetrain.Transmission.TripMeter",
    "requestId": "5264"
    }
*/
bool JSONRequestParser::validateSubscribeRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];
    QJsonValue valuePath = request->getJsonObject()["path"];
    QJsonValue valueFilters = request->getJsonObject()["filters"];

    bool valid = (validateId(valueId) && validatePath(valuePath) && validateFilters(valueFilters));

    if(m_debug) { qDebug() << "validateSubscribeRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        request->setSignalPath(valuePath.toString());
        if(!valueFilters.isNull() && !valueFilters.isUndefined())
        {
            request->setFilters(valueFilters.toVariant());
        }
        return true;
    }
}

/*
    {
    "action": "unsubscribe",
    "subscriptionId": "102",
    "requestId": "5264"
    }
*/
bool JSONRequestParser::validateUnsubscribeRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];
    QJsonValue valueSubscriptionId = request->getJsonObject()["subscriptionId"];

    bool valid = (validateId(valueId) && validateSubscriptionId(valueSubscriptionId));

    if(m_debug) { qDebug() << "validateUnsubscribeRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        request->setSubscriptionId(valueSubscriptionId.toString());
        return true;
    }
}

/*
    {
        "action": "unsubscribeAll",
        "requestId": "3468"
    }
*/
bool JSONRequestParser::validateUnsubscribeAllRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];

    bool valid = (validateId(valueId));

    if(m_debug) { qDebug() << "validateUnsubscribeAllRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        return true;
    }
}

/*
    {
    "action": "authorize",
    "tokens":
    {
        "authorization": "a-token-value"
    },
    "requestId": "1"
    }
*/
bool JSONRequestParser::validateAuthorizeRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];
    QJsonValue valueTokens = request->getJsonObject()["tokens"];

    bool valid = (validateId(valueId) && validateTokens(valueTokens));

    if(m_debug) { qDebug() << "validateAuthorizeRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        request->setTokens(valueTokens.toObject());
        return true;
    }
}

/*
    {
    "action": "getVSS",
    "path": "Signal.Drivetrain.InternalCombustionEngine.RPM",
    "requestId": "3874"
    }
*/
bool JSONRequestParser::validateGetVSSRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];
    QJsonValue valuePath = request->getJsonObject()["path"];

    bool valid = (validateId(valueId) && validatePath(valuePath));

    if(m_debug) { qDebug() << "validateAuthorizeRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        request->setSignalPath(valuePath.toString());
        return true;
    }
}

// Validate each of the different parts of a request
bool JSONRequestParser::validateAction(VISSRequest* request)
{
    QJsonValue valueAction = request->getJsonObject()["action"];

    bool valid = valueAction.isString();

    if(m_debug) { qDebug() << "validateAction result" << (valid); }
    if(!valid) { return false; }

    QString val = valueAction.toString();

    if (val == "get")
    {
        request->setAction(GET);
    }
    else if (val == "set")
    {
        request->setAction(SET);
    }
    else if (val == "subscribe")
    {
        request->setAction(SUBSCRIBE);
    }
    else if (val == "unsubscribe")
    {
        request->setAction(UNSUBSCRIBE);
    }
    else if (val == "unsubscribeAll")
    {
        request->setAction(UNSUBSCRIBEALL);
    }
    else if (val == "authorize")
    {
        request->setAction(AUTHORIZE);
    }
    else if (val == "getVSS")
    {
        request->setAction(GETVSS);
    }
    else
    {
        request->setAction(ERROR);
    }
    return valid;
}

bool JSONRequestParser::validatePath(QJsonValue value)
{
    QString path = value.toString();
    if(path.isEmpty()) { return false; }

    QStringList splitPath = path.split('.');

    foreach(QString item, splitPath)
    {
        // Check for empty string. Caused by ex. two dots.
        if(item.isEmpty())
        {
            if(m_debug) { qDebug() << "validatePath string is empty"; }
            return false;
        }

        // Check if string is single asterisk.
        if(item.length() == 1 && item[0] != '*')
        {
            if(m_debug) { qDebug() << "validatePath string contains several asterisks"; }
            return false;
        }

        // Check if string contains only text.
        QRegExp regex("^[a-zA-Z]+$");
        if(!regex.exactMatch(item))
        {
            if(m_debug) { qDebug() << "validatePath string is not just simple text"; }
            return false;
        }
    }

    //(\w+|\*)

    // TODO Add Regex to check path?

    return true;
}

bool JSONRequestParser::validateValue(QJsonValue value)
{
    // TODO Validate the different structures of values? Currently just checks if it's there.
    return !value.isUndefined() && value.toVariant() != QVariant().Invalid ;
}

bool JSONRequestParser::validateId(QJsonValue value)
{
    QVariant id = value.toVariant();

    if(id == QVariant().Invalid) { return false; }
    bool parseOk = false;
    id.toInt(&parseOk);

    if(!parseOk)
    {
        QRegExp uuid("^[0-9A-F]{8}-[0-9A-F]{4}-[1-5][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$");
        return uuid.exactMatch(id.toString());
    }

    return true;
}

bool JSONRequestParser::validateSubscriptionId(QJsonValue value)
{
    return value.isString() || value.isNull();
}

bool JSONRequestParser::validateFilters(QJsonValue value)
{
    if(!value.isNull())
    {
        return value.isObject();
    }
    else
    {
        return true;
    }
}

bool JSONRequestParser::validateTokens(QJsonValue value)
{
    // TODO Validte the diffent tokens.
    return value.isObject();
}

bool JSONRequestParser::isValidJson()
{
    //qDebug() << parseError.errorString();
    return m_parseError.error == QJsonParseError::NoError;
}

JSONRequestParser::~JSONRequestParser()
{
    // Nothing needed atm?
}

<commit_msg>Small change in parser to fix a failing test.<commit_after>#include "jsonrequestparser.h"

JSONRequestParser::JSONRequestParser(bool debug, QObject *parent) : QObject(parent)
{
    m_debug = debug;
}
QSharedPointer<VISSRequest> JSONRequestParser::parseJson(QString json)
{
    QSharedPointer<VISSRequest> request = QSharedPointer<VISSRequest>(new VISSRequest(json), &QObject::deleteLater);
    request.data()->setJsonDocument(QJsonDocument::fromJson(json.toUtf8(), &m_parseError));

    if(!isValidJson())
    {
        if(m_debug) { qDebug() << "json invalid"; }
        return request;
    }
    request->setJsonObject(request->getJsonDocument().object());

    if(!validateAction(request.data())) { return request; }

    switch (request->getAction())
    {
        case GET:
            if(!validateGetRequest(request.data())) { request->invalidateRequest(); }
            break;
        case SET:
            if(!validateSetRequest(request.data())) { request->invalidateRequest(); }
            break;
        case SUBSCRIBE:
            if(!validateSubscribeRequest(request.data())) { request->invalidateRequest(); }
            break;
        case UNSUBSCRIBE:
            if(!validateUnsubscribeRequest(request.data())) { request->invalidateRequest(); }
            break;
        case UNSUBSCRIBEALL:
            if(!validateUnsubscribeRequest(request.data())) { request->invalidateRequest(); }
            break;
        case AUTHORIZE:
            if(!validateAuthorizeRequest(request.data())) { request->invalidateRequest(); }
            break;
        case GETVSS:
            if(!validateGetVSSRequest(request.data())) { request->invalidateRequest(); }
            break;
        case ERROR: // Just to remove compilation warning.
            request->invalidateRequest();
            break;
    }
    return request;
}

// Validate the different Requests

/*
    {
    "action": "get",
    "path": "Signal.Drivetrain.InternalCombustionEngine.RPM",
    "requestId": "8756"
    }
*/
bool JSONRequestParser::validateGetRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];
    QJsonValue valuePath = request->getJsonObject()["path"];

    bool valid = (validateId(valueId) && validatePath(valuePath));

    if(m_debug) { qDebug() << "validateGetRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        request->setSignalPath(valuePath.toString());
        return true;
    }
}

/*
    {
    "action": "set",
    "path": "Signal.Drivetrain.InternalCombustionEngine.RPM",
    "value": 2000,
    "requestId": "8912"
    }
*/
bool JSONRequestParser::validateSetRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];
    QJsonValue valuePath = request->getJsonObject()["path"];
    QJsonValue valueValue = request->getJsonObject()["value"];

    bool valid = (validateId(valueId) && validatePath(valuePath) && validateValue(valueValue));

    if(m_debug) { qDebug() << "validateSetRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        request->setSignalPath(valuePath.toString());
        request->setValue(valueValue.toVariant());
        return true;
    }
}

/*
    {
    "action": "subscribe",
    "path": "Signal.Drivetrain.Transmission.TripMeter",
    "requestId": "5264"
    }
*/
bool JSONRequestParser::validateSubscribeRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];
    QJsonValue valuePath = request->getJsonObject()["path"];
    QJsonValue valueFilters = request->getJsonObject()["filters"];

    bool valid = (validateId(valueId) && validatePath(valuePath) && validateFilters(valueFilters));

    if(m_debug) { qDebug() << "validateSubscribeRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        request->setSignalPath(valuePath.toString());
        if(!valueFilters.isNull() && !valueFilters.isUndefined())
        {
            request->setFilters(valueFilters.toVariant());
        }
        return true;
    }
}

/*
    {
    "action": "unsubscribe",
    "subscriptionId": "102",
    "requestId": "5264"
    }
*/
bool JSONRequestParser::validateUnsubscribeRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];
    QJsonValue valueSubscriptionId = request->getJsonObject()["subscriptionId"];

    bool valid = (validateId(valueId) && validateSubscriptionId(valueSubscriptionId));

    if(m_debug) { qDebug() << "validateUnsubscribeRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        request->setSubscriptionId(valueSubscriptionId.toString());
        return true;
    }
}

/*
    {
        "action": "unsubscribeAll",
        "requestId": "3468"
    }
*/
bool JSONRequestParser::validateUnsubscribeAllRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];

    bool valid = (validateId(valueId));

    if(m_debug) { qDebug() << "validateUnsubscribeAllRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        return true;
    }
}

/*
    {
    "action": "authorize",
    "tokens":
    {
        "authorization": "a-token-value"
    },
    "requestId": "1"
    }
*/
bool JSONRequestParser::validateAuthorizeRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];
    QJsonValue valueTokens = request->getJsonObject()["tokens"];

    bool valid = (validateId(valueId) && validateTokens(valueTokens));

    if(m_debug) { qDebug() << "validateAuthorizeRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        request->setTokens(valueTokens.toObject());
        return true;
    }
}

/*
    {
    "action": "getVSS",
    "path": "Signal.Drivetrain.InternalCombustionEngine.RPM",
    "requestId": "3874"
    }
*/
bool JSONRequestParser::validateGetVSSRequest(VISSRequest* request)
{
    QJsonValue valueId = request->getJsonObject()["requestId"];
    QJsonValue valuePath = request->getJsonObject()["path"];

    bool valid = (validateId(valueId) && validatePath(valuePath));

    if(m_debug) { qDebug() << "validateAuthorizeRequest result" << (valid); }

    if(!valid) { return false; }
    else
    {
        request->setRequestId(valueId.toString());
        request->setSignalPath(valuePath.toString());
        return true;
    }
}

// Validate each of the different parts of a request
bool JSONRequestParser::validateAction(VISSRequest* request)
{
    QJsonValue valueAction = request->getJsonObject()["action"];

    bool valid = valueAction.isString();

    if(m_debug) { qDebug() << "validateAction result" << (valid); }
    if(!valid) { return false; }

    QString val = valueAction.toString();

    if (val == "get")
    {
        request->setAction(GET);
    }
    else if (val == "set")
    {
        request->setAction(SET);
    }
    else if (val == "subscribe")
    {
        request->setAction(SUBSCRIBE);
    }
    else if (val == "unsubscribe")
    {
        request->setAction(UNSUBSCRIBE);
    }
    else if (val == "unsubscribeAll")
    {
        request->setAction(UNSUBSCRIBEALL);
    }
    else if (val == "authorize")
    {
        request->setAction(AUTHORIZE);
    }
    else if (val == "getVSS")
    {
        request->setAction(GETVSS);
    }
    else
    {
        request->setAction(ERROR);
    }
    return valid;
}

bool JSONRequestParser::validatePath(QJsonValue value)
{
    QString path = value.toString();
    if(path.isEmpty()) { return false; }

    QStringList splitPath = path.split('.');

    foreach(QString item, splitPath)
    {
        // Check for empty string. Caused by ex. two dots.
        if(item.isEmpty())
        {
            if(m_debug) { qDebug() << "validatePath string is empty"; }
            return false;
        }

        // Check if string is single asterisk.
        if(item.length() == 1 && item[0] != '*')
        {
            if(m_debug) { qDebug() << "validatePath string contains several asterisks"; }
            return false;
        }

        // Check if string contains only text.
        QRegExp regex("^[a-zA-Z]+$");
        if(!regex.exactMatch(item))
        {
            if(m_debug) { qDebug() << "validatePath string is not just simple text"; }
            return false;
        }
    }

    //(\w+|\*)

    // TODO Add Regex to check path?

    return true;
}

bool JSONRequestParser::validateValue(QJsonValue value)
{
    // TODO Validate the different structures of values? Currently just checks if it's there.
    return !value.isNull() && !value.isUndefined() && value.toVariant() != QVariant().Invalid ;
}

bool JSONRequestParser::validateId(QJsonValue value)
{
    QVariant id = value.toVariant();

    if(id == QVariant().Invalid) { return false; }
    bool parseOk = false;
    id.toInt(&parseOk);

    if(!parseOk)
    {
        QRegExp uuid("^[0-9A-F]{8}-[0-9A-F]{4}-[1-5][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$");
        return uuid.exactMatch(id.toString());
    }

    return true;
}

bool JSONRequestParser::validateSubscriptionId(QJsonValue value)
{
    return value.isString() || value.isNull();
}

bool JSONRequestParser::validateFilters(QJsonValue value)
{
    if(!value.isNull())
    {
        return value.isObject();
    }
    else
    {
        return true;
    }
}

bool JSONRequestParser::validateTokens(QJsonValue value)
{
    // TODO Validte the diffent tokens.
    return value.isObject();
}

bool JSONRequestParser::isValidJson()
{
    //qDebug() << parseError.errorString();
    return m_parseError.error == QJsonParseError::NoError;
}

JSONRequestParser::~JSONRequestParser()
{
    // Nothing needed atm?
}

<|endoftext|>


<commit_before>#include "Building.h"

#include <unordered_map>

Building::Building(TextureLoader const * textureLoader, unsigned int maxBurnedDamage, unsigned int currentBurnedDamage):
	m_maxBurnedDamage(maxBurnedDamage),
	m_currentBurnedDamage(currentBurnedDamage),
	m_textureLoader(textureLoader),
	m_floors(std::vector<Floor *>()),
	m_currentFloor(0)
{}

Building::~Building()
{
    for(auto it = m_floors.begin(); it != m_floors.end(); ++it)
        delete *it;
}

std::vector<Floor * > * Building::getFloors()
{
	return &m_floors;
}

unsigned int Building::getCurrentFloor()
{
	return m_currentFloor;
}

bool Building::checkCollisions(Ray * collisionRay)
{
    m_floors[m_currentFloor]->collision(collisionRay);

    return collisionRay->validIntersectionFound();
}

void Building::loadToTileSet(std::string const &path)
{
    std::ifstream levelFile(path, std::ios_base::in);

	Floor * currentFloor = new Floor(m_textureLoader);

    std::unordered_map<unsigned char, Object*> objects;
    std::unordered_map<unsigned char, bool> objectsSentInRoom;

    std::unordered_map<unsigned char, FireDetector*> fireDetectors;
    std::unordered_map<unsigned char, bool> fireDetectorsSentInRoom;

	bool mapConstruction = false;

	unsigned int floorId = 0;

    unsigned int lineNumber = 0;
    while(levelFile.good())
    {
		unsigned char roomId = '0';
        std::string line;
        getline(levelFile, line);
        ++lineNumber;

        if(line.length() > 0)
        {
            if(line[0] == '=')
            {
                //new floor
                m_floors.push_back(currentFloor);
                currentFloor = new Floor(m_textureLoader);
            }

            else if(line[0] == 'o')
            {
                //object
                bool error = false;
                if(line.length() >= 6)
                {
                    unsigned char objectID = line[1];
                    unsigned char objectType = line[2];
                    std::string x_str;
                    std::string y_str;
                    bool first = true;

                    for(unsigned int i = 3; i < line.length(); ++i)
                    {
                        if(line[i] == ':')
                            first = false;
                        else
                            (first? x_str : y_str).push_back(line[i]);
                    }

                    int x = atoi(x_str.c_str());
                    int y = atoi(y_str.c_str());

                    Object * obj = Object::fromID(objectType, x, y, m_textureLoader->getObjectsTexture());
                    objects.insert(std::pair<unsigned char, Object*>(objectID, obj));
                    objectsSentInRoom.insert(std::pair<unsigned char, bool>(objectID, false));
                }

                else
                    error = true;

                if(error)
                    std::cerr << "error while loading level '" << path << "' at line " << lineNumber << " : malformed object declaration" << std::endl;
            }

            else if(line[0] == 'f')
            {
                //fire detector
                bool error = false;
                if(line.length() >= 5)
                {
                    unsigned char fireID = line[1];
                    std::string x_str;
                    std::string y_str;
                    bool first = true;

                    for(unsigned int i = 2; i < line.length(); ++i)
                    {
                        if(line[i] == ':')
                            first = false;
                        else
                            (first? x_str : y_str).push_back(line[i]);
                    }

                    unsigned int x = atoi(x_str.c_str());
                    unsigned int y = atoi(y_str.c_str());

                    FireDetector * fd = new FireDetector(x,y, 64, m_textureLoader->getFireDetectorTexture());
                    fireDetectors.insert(std::pair<unsigned char, FireDetector *>(fireID, fd));
                    fireDetectorsSentInRoom.insert(std::pair<unsigned char, bool>(fireID, false));
                }

                else
                    error = true;

                if(error)
                    std::cerr << "error while loading level '" << path << "' at line " << lineNumber << " : malformed fire detector declaration" << std::endl;
            }

            else if(line[0] == 'r')
            {
                //room
                bool ids_fireDetector = false;

                Room * room = new Room(roomId);
                for(unsigned int i = 1; i < line.length(); ++i)
                {
                    if(line[i] == ':')
                        ids_fireDetector = true;

                    else
                    {
                        unsigned char id = line[i];

                        if(!ids_fireDetector)
                        {
                            //TODO: check if id exists
                            room->addObject(objects[id]);
                            objectsSentInRoom[id] = true;
                        }

                        else
                        {
                            //TODO: check if id exists
                            room->addFireDetector(fireDetectors[id]);
                            fireDetectorsSentInRoom[id] = true;
                        }
                    }
                }

                currentFloor->addRoom(room);
				roomId++;
            }

			else if (line[0] == 'd')
			{
				//doors
				if (line.length() >= 4)
				{
					std::string x_str;
					std::string y_str;

					std::vector<unsigned char> adjacentRooms;

					bool posxDefinition = true;
					bool adjacentRoomDefinition = false;

					for (unsigned int i = 1; i < line.length(); ++i)
					{
						if(line[i] == ':')
							posxDefinition = false;
						if(line[i] == '>')
							adjacentRoomDefinition = true;

						if(adjacentRoomDefinition)
							adjacentRooms.push_back(line[i]);
						else
							(posxDefinition ? x_str : y_str).push_back(line[i]);
					}

					unsigned int x = atoi(x_str.c_str());
					unsigned int y = atoi(y_str.c_str());

					Door * door = new Door(x,y,std::pair<unsigned char, unsigned char>(adjacentRooms[0],adjacentRooms[1]),m_textureLoader->getObjectsTexture());
					currentFloor->addDoor(door);
				}
			}

			else if (line[0] == 't')
			{
				//teleporter
				if (line.length() >= 5)
				{
					std::string x_str;
					std::string y_str;
					unsigned char direction = line[1];

					bool first = true;

					for (unsigned int i = 2; i < line.length(); ++i)
					{
						if (line[i] == ':')
							first = false;

						else
							(first ? x_str : y_str).push_back(line[i]);
					}

					unsigned int x = atoi(x_str.c_str());
					unsigned int y = atoi(y_str.c_str());

					Teleporter * teleporter = new Teleporter(x*32, y*32, m_textureLoader->getTeleporterTexture(),direction);
					currentFloor->addTeleporter(teleporter);
				}
			}

			else if(line[0] == '|')
			{
				mapConstruction = !mapConstruction;
				std::cout << "begin map" << std::endl;
			}

			else if(mapConstruction)
			{
				std::vector<unsigned char> buffer;
				for (auto it = line.cbegin(); it != line.cend(); ++it)
					buffer.push_back(*it);

				currentFloor->addLineToRoomsMap(buffer);
			}

            else
            {
                std::vector<unsigned char> buffer;
                for(auto it = line.cbegin(); it != line.cend(); ++it)
                    buffer.push_back(*it);

                currentFloor->addLine(buffer);
            }
        }
		floorId++;
    }

    //delete orphaned objects
    for(auto it = objects.begin(); it != objects.end(); ++it)
        if(!objectsSentInRoom.at(it->first))
            delete it->second;

    //delete orphaned fireDetectors
    for(auto it = fireDetectors.begin(); it != fireDetectors.end(); ++it)
        if(!fireDetectorsSentInRoom.at(it->first))
            delete it->second;

    m_floors.push_back(currentFloor);
}

void Building::draw(sf::RenderWindow *window) const
{
	m_floors[m_currentFloor]->draw(window);
	//this->drawHUD();
}

void Building::update(sf::Clock const & clk)
{
    for(auto it = m_floors.begin(); it != m_floors.end(); ++it)
        (*it)->update(clk);

	loadNextFloor();
}

void Building::loadNextFloor()
{

	for (auto it = m_floors[getCurrentFloor()]->getTeleporter().cbegin();
		it != m_floors[getCurrentFloor()]->getTeleporter().cend(); ++it){

		if ((*it)->getStatusColision())
		{
			if ((*it)->getDirection() == 0){
				if (m_currentFloor > 0){
					m_currentFloor =0 ;
				}
			}
			else
			{
				m_currentFloor=1;
			}

		}
	}

}<commit_msg> MAJ OK FONCTIONNELLE<commit_after>#include "Building.h"

#include <unordered_map>

Building::Building(TextureLoader const * textureLoader, unsigned int maxBurnedDamage, unsigned int currentBurnedDamage):
	m_maxBurnedDamage(maxBurnedDamage),
	m_currentBurnedDamage(currentBurnedDamage),
	m_textureLoader(textureLoader),
	m_floors(std::vector<Floor *>()),
	m_currentFloor(0)
{}

Building::~Building()
{
    for(auto it = m_floors.begin(); it != m_floors.end(); ++it)
        delete *it;
}

std::vector<Floor * > * Building::getFloors()
{
	return &m_floors;
}

unsigned int Building::getCurrentFloor()
{
	return m_currentFloor;
}

bool Building::checkCollisions(Ray * collisionRay)
{
    m_floors[m_currentFloor]->collision(collisionRay);

    return collisionRay->validIntersectionFound();
}

void Building::loadToTileSet(std::string const &path)
{
    std::ifstream levelFile(path, std::ios_base::in);

	Floor * currentFloor = new Floor(m_textureLoader);

    std::unordered_map<unsigned char, Object*> objects;
    std::unordered_map<unsigned char, bool> objectsSentInRoom;

    std::unordered_map<unsigned char, FireDetector*> fireDetectors;
    std::unordered_map<unsigned char, bool> fireDetectorsSentInRoom;

	bool mapConstruction = false;

	unsigned int floorId = 0;
	unsigned char roomId = 'A';
    unsigned int lineNumber = 0;
    while(levelFile.good())
    {

        std::string line;
        getline(levelFile, line);
        ++lineNumber;

        if(line.length() > 0)
        {
            if(line[0] == '=')
            {
                //new floor
                m_floors.push_back(currentFloor);
                currentFloor = new Floor(m_textureLoader);
            }

            else if(line[0] == 'o')
            {
                //object
                bool error = false;
                if(line.length() >= 6)
                {
                    unsigned char objectID = line[1];
                    unsigned char objectType = line[2];
                    std::string x_str;
                    std::string y_str;
                    bool first = true;

                    for(unsigned int i = 3; i < line.length(); ++i)
                    {
                        if(line[i] == ':')
                            first = false;
                        else
                            (first? x_str : y_str).push_back(line[i]);
                    }

                    int x = atoi(x_str.c_str());
                    int y = atoi(y_str.c_str());

                    Object * obj = Object::fromID(objectType, x, y, m_textureLoader->getObjectsTexture());
                    objects.insert(std::pair<unsigned char, Object*>(objectID, obj));
                    objectsSentInRoom.insert(std::pair<unsigned char, bool>(objectID, false));
                }

                else
                    error = true;

                if(error)
                    std::cerr << "error while loading level '" << path << "' at line " << lineNumber << " : malformed object declaration" << std::endl;
            }

            else if(line[0] == 'f')
            {
                //fire detector
                bool error = false;
                if(line.length() >= 5)
                {
                    unsigned char fireID = line[1];
                    std::string x_str;
                    std::string y_str;
                    bool first = true;

                    for(unsigned int i = 2; i < line.length(); ++i)
                    {
                        if(line[i] == ':')
                            first = false;
                        else
                            (first? x_str : y_str).push_back(line[i]);
                    }

                    unsigned int x = atoi(x_str.c_str());
                    unsigned int y = atoi(y_str.c_str());

                    FireDetector * fd = new FireDetector(x,y, 64, m_textureLoader->getFireDetectorTexture());
                    fireDetectors.insert(std::pair<unsigned char, FireDetector *>(fireID, fd));
                    fireDetectorsSentInRoom.insert(std::pair<unsigned char, bool>(fireID, false));
                }

                else
                    error = true;

                if(error)
                    std::cerr << "error while loading level '" << path << "' at line " << lineNumber << " : malformed fire detector declaration" << std::endl;
            }

            else if(line[0] == 'r')
            {
                //room
                bool ids_fireDetector = false;

                Room * room = new Room(roomId);
                for(unsigned int i = 1; i < line.length(); ++i)
                {
                    if(line[i] == ':')
                        ids_fireDetector = true;

                    else
                    {
                        unsigned char id = line[i];

                        if(!ids_fireDetector)
                        {
                            //TODO: check if id exists
                            room->addObject(objects[id]);
                            objectsSentInRoom[id] = true;
                        }

                        else
                        {
                            //TODO: check if id exists
                            room->addFireDetector(fireDetectors[id]);
                            fireDetectorsSentInRoom[id] = true;
                        }
                    }
                }

                currentFloor->addRoom(room);
				roomId++;
            }

			else if (line[0] == 'd')
			{
				//doors
				if (line.length() >= 4)
				{
					std::string x_str;
					std::string y_str;

					std::vector<unsigned char> adjacentRooms;

					bool posxDefinition = true;
					bool adjacentRoomDefinition = false;

					for (unsigned int i = 1; i < line.length(); ++i)
					{
						if(line[i] == ':')
							posxDefinition = false;
						if(line[i] == '>')
							adjacentRoomDefinition = true;

						if(adjacentRoomDefinition)
							adjacentRooms.push_back(line[i]);
						else
							(posxDefinition ? x_str : y_str).push_back(line[i]);
					}

					unsigned int x = atoi(x_str.c_str());
					unsigned int y = atoi(y_str.c_str());

					Door * door = new Door(x,y,std::pair<unsigned char, unsigned char>(adjacentRooms[0],adjacentRooms[1]),m_textureLoader->getObjectsTexture());
					currentFloor->addDoor(door);
				}
			}

			else if (line[0] == 't')
			{
				//teleporter
				if (line.length() >= 5)
				{
					std::string x_str;
					std::string y_str;
					unsigned char direction = line[1];

					bool first = true;

					for (unsigned int i = 2; i < line.length(); ++i)
					{
						if (line[i] == ':')
							first = false;

						else
							(first ? x_str : y_str).push_back(line[i]);
					}

					unsigned int x = atoi(x_str.c_str());
					unsigned int y = atoi(y_str.c_str());

					Teleporter * teleporter = new Teleporter(x*32, y*32, m_textureLoader->getTeleporterTexture(),direction);
					currentFloor->addTeleporter(teleporter);
				}
			}

			else if(line[0] == '|')
			{
				mapConstruction = !mapConstruction;
				std::cout << "begin map" << std::endl;
			}

			else if(mapConstruction)
			{
				std::vector<unsigned char> buffer;
				for (auto it = line.cbegin(); it != line.cend(); ++it)
					buffer.push_back(*it);

				currentFloor->addLineToRoomsMap(buffer);
			}

            else
            {
                std::vector<unsigned char> buffer;
                for(auto it = line.cbegin(); it != line.cend(); ++it)
                    buffer.push_back(*it);

                currentFloor->addLine(buffer);
            }
        }
		floorId++;
    }

    //delete orphaned objects
    for(auto it = objects.begin(); it != objects.end(); ++it)
        if(!objectsSentInRoom.at(it->first))
            delete it->second;

    //delete orphaned fireDetectors
    for(auto it = fireDetectors.begin(); it != fireDetectors.end(); ++it)
        if(!fireDetectorsSentInRoom.at(it->first))
            delete it->second;

    m_floors.push_back(currentFloor);
}

void Building::draw(sf::RenderWindow *window) const
{
	m_floors[m_currentFloor]->draw(window);
	//this->drawHUD();
}

void Building::update(sf::Clock const & clk)
{
    for(auto it = m_floors.begin(); it != m_floors.end(); ++it)
        (*it)->update(clk);

	loadNextFloor();
}

void Building::loadNextFloor()
{

	for (auto it = m_floors[getCurrentFloor()]->getTeleporter().cbegin();
		it != m_floors[getCurrentFloor()]->getTeleporter().cend(); ++it){

		if ((*it)->getStatusColision())
		{
			if ((*it)->getDirection() == 0){
				if (m_currentFloor > 0){
					m_currentFloor =0 ;
				}
			}
			else
			{
				m_currentFloor=1;
			}

		}
	}

}<|endoftext|>