<commit_before>/* worker.cpp
 * Copyright (C) 2003-2005 Tommi Maekitalo
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
 * NON-INFRINGEMENT.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 * You must obey the GNU General Public License in all respects
 * for all of the code used other than OpenSSL.  If you modify
 * file(s) with this exception, you may extend this exception to your
 * version of the file(s), but you are not obligated to do so.  If you
 * do not wish to do so, delete this exception statement from your
 * version.  If you delete this exception statement from all source
 * files in the program, then also delete it here.
 */

#include "tnt/worker.h"
#include "tnt/dispatcher.h"
#include "tnt/job.h"
#include <tnt/httprequest.h>
#include <tnt/httpreply.h>
#include <tnt/httperror.h>
#include <tnt/http.h>
#include <tnt/poller.h>
#include <tnt/sessionscope.h>
#include <cxxtools/log.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <locale>
#include <errno.h>

log_define("tntnet.worker")

namespace
{
  class ComponentUnloadLock
  {
      tnt::Component& comp;

    public:
      ComponentUnloadLock(tnt::Component& c)
        : comp(c)
      { comp.lock(); }
      ~ComponentUnloadLock()
      { comp.unlock(); }
  };

  static const char stateStarting[]          = "0 starting";
  static const char stateWaitingForJob[]     = "1 waiting for job";
  static const char stateParsing[]           = "2 parsing request";
  static const char statePostParsing[]       = "3 post parsing";
  static const char stateDispatch[]          = "4 dispatch";
  static const char stateProcessingRequest[] = "5 processing request";
  static const char stateFlush[]             = "6 flush";
  static const char stateSendReply[]         = "7 send reply";
  static const char stateSendError[]         = "8 send error";
  static const char stateStopping[]          = "9 stopping";
}

namespace tnt
{
  cxxtools::Mutex Worker::mutex;
  unsigned Worker::nextThreadNumber = 0;
  Worker::workers_type Worker::workers;
  unsigned Worker::compLifetime = 600;
  unsigned Worker::maxRequestTime = 600;
  unsigned Worker::reportStateTime = 0;
  time_t Worker::nextReportStateTime = 0;
  unsigned Worker::minThreads = 5;
  bool Worker::enableCompression = true;

  Worker::ComploaderPoolType Worker::comploaderPool;

  Worker::Worker(Tntnet& app)
    : application(app),
      comploaderObject(comploaderPool.get()),
      comploader(comploaderObject),
      threadId(0),
      state(stateStarting),
      lastWaitTime(0)
  {
    log_debug("initialize thread " << threadId);

    cxxtools::MutexLock lock(mutex);
    workers.insert(this);
  }

  Worker::~Worker()
  {
    cxxtools::MutexLock lock(mutex);
    workers.erase(this);
    comploader.cleanup(0);

    log_debug("delete worker " << threadId << " - " << workers.size() << " threads left - " << application.getQueue().getWaitThreadCount() << " waiting threads");
  }

  void Worker::run()
  {
    threadId = pthread_self();
    Jobqueue& queue = application.getQueue();
    log_debug("start thread " << threadId);
    while (queue.getWaitThreadCount() < minThreads)
    {
      log_debug("waiting for job");
      state = stateWaitingForJob;
      Jobqueue::JobPtr j = queue.get();
      if (Tntnet::shouldStop())
      {
        log_warn("stop worker");
        break;
      }
      log_debug("got job - fd=" << j->getFd());

      std::iostream& socket = j->getStream();

      try
      {
        bool keepAlive;
        do
        {
          time(&lastWaitTime);

          log_debug("read request");

          keepAlive = false;
          state = stateParsing;
          j->getParser().parse(socket);
          state = statePostParsing;

          if (socket.eof())
            log_debug("eof");
          else if (j->getParser().failed())
          {
            state = stateSendError;
            log_warn("bad request");
            socket << "HTTP/1.0 500 bad request\r\n"
                      "Content-Type: text/html\r\n"
                      "\r\n"
                      "
Error

bad request
"
                   << std::endl;
          }
          else if (socket.fail())
            log_error("socket failed");
          else
          {
            j->getRequest().doPostParse();

            j->setWrite();
            keepAlive = processRequest(j->getRequest(), socket,
              j->decrementKeepAliveCounter());

            if (keepAlive)
            {
              j->setRead();
              j->clear();

              // if there is something to do and no threads waiting, we take
              // the next job just to improve resposiveness.
              if (queue.getWaitThreadCount() == 0
                && !queue.empty())
              {
                application.getPoller().addIdleJob(j);
                keepAlive = false;
              }
              else
              {
                struct pollfd fd;
                fd.fd = j->getFd();
                fd.events = POLLIN;
                if (::poll(&fd, 1, Job::getSocketReadTimeout()) == 0)
                {
                  application.getPoller().addIdleJob(j);
                  keepAlive = false;
                }
              }
            }
          }
        } while (keepAlive);
      }
      catch (const cxxtools::net::Timeout& e)
      {
        log_debug("timeout - put job in poller");
        application.getPoller().addIdleJob(j);
      }
      catch (const cxxtools::net::Exception& e)
      {
        if (e.getErrno() != ENOENT)
          log_warn("unexpected exception: " << e.what());
      }
      catch (const std::exception& e)
      {
        log_warn("unexpected exception: " << e.what());
      }
    }

    time(&lastWaitTime);

    log_debug("end worker-thread " << threadId);

    state = stateStopping;
  }

  bool Worker::processRequest(HttpRequest& request, std::iostream& socket,
         unsigned keepAliveCount)
  {
    // log message
    log_info("process request: " << request.getMethod() << ' ' << request.getQuery()
      << " from client " << request.getPeerIp() << " user-Agent \"" << request.getUserAgent()
      << '"');

    // create reply-object
    HttpReply reply(socket);
    reply.setVersion(request.getMajorVersion(), request.getMinorVersion());
    reply.setMethod(request.getMethod());

    std::locale loc = request.getLocale();
    reply.out().imbue(loc);
    reply.sout().imbue(loc);

    if (request.keepAlive())
      reply.setKeepAliveCounter(keepAliveCount);

    if (enableCompression)
      reply.setAcceptEncoding(request.getEncoding());

    // process request
    try
    {
      try
      {
        dispatch(request, reply);

        if (!request.keepAlive() || !reply.keepAlive())
          keepAliveCount = 0;

        if (keepAliveCount > 0)
          log_debug("keep alive");
        else
        {
          log_debug("no keep alive request/reply="
              << request.keepAlive() << '/' << reply.keepAlive());
        }
      }
      catch (const HttpError& e)
      {
        throw;
      }
      catch (const std::exception& e)
      {
        throw HttpError(HTTP_INTERNAL_SERVER_ERROR, e.what());
      }
    }
    catch (const HttpError& e)
    {
      state = stateSendError;
      log_warn("http-Error: " << e.what());
      HttpReply reply(socket);
      reply.setVersion(request.getMajorVersion(), request.getMinorVersion());
      if (request.keepAlive())
        reply.setKeepAliveCounter(keepAliveCount);
      else
        keepAliveCount = 0;
      reply.out() << "
Error

"
                  << e.what() << "
" << std::endl;
      reply.sendReply(e.getErrcode(), e.getErrmsg());
    }

    return keepAliveCount > 0;
  }

  void Worker::dispatch(HttpRequest& request, HttpReply& reply)
  {
    state = stateDispatch;
    const std::string& url = request.getUrl();

    log_debug("dispatch " << request.getQuery());

    if (!HttpRequest::checkUrl(url))
      throw HttpError(HTTP_BAD_REQUEST, "illegal url");

    Dispatcher::PosType pos(application.getDispatcher(), request.getUrl());
    while (true)
    {
      state = stateDispatch;

      // pos.getNext() throws NotFoundException at end
      Dispatcher::CompidentType ci = pos.getNext();
      try
      {
        log_debug("load component " << ci);
        Component& comp = comploader.fetchComp(ci, application.getDispatcher());
        ComponentUnloadLock unload_lock(comp);
        request.setPathInfo(ci.hasPathInfo() ? ci.getPathInfo() : url);
        request.setArgs(ci.getArgs());

        application.getScopemanager().preCall(request, ci.libname);

        log_debug("call component " << ci << " path " << request.getPathInfo());
        state = stateProcessingRequest;
        unsigned http_return = comp(request, reply, request.getQueryParams());
        if (http_return != DECLINED)
        {
          if (reply.isDirectMode())
          {
            log_info("request ready, returncode " << http_return);
            state = stateFlush;
            reply.out().flush();
          }
          else
          {
            log_info("request ready, returncode " << http_return << " - ContentSize: " << reply.getContentSize());

            application.getScopemanager().postCall(request, reply, ci.libname);

            state = stateSendReply;
            reply.sendReply(http_return);
          }

          if (reply.out())
            log_debug("reply sent");
          else
            log_warn("stream error");

          return;
        }
        else
          log_debug("component " << ci << " returned DECLINED");
      }
      catch (const cxxtools::dl::DlopenError& e)
      {
        log_warn("dl::DlopenError catched - libname " << e.getLibname());
      }
      catch (const cxxtools::dl::SymbolNotFound& e)
      {
        log_warn("dl::SymbolNotFound catched - symbol " << e.getSymbol());
      }
    }

    throw NotFoundException(request.getUrl());
  }

  void Worker::timer()
  {
    time_t currentTime;
    time(&currentTime);
    bool reportState = false;
    if (reportStateTime > 0 && currentTime > nextReportStateTime)
    {
      if (nextReportStateTime)
        reportState = true;
      nextReportStateTime = currentTime + reportStateTime;
    }

    cxxtools::MutexLock lock(mutex);
    for (workers_type::iterator it = workers.begin();
         it != workers.end(); ++it)
    {
      (*it)->healthCheck(currentTime);
      (*it)->cleanup(compLifetime);
      if (reportState)
        log_info("threadstate " << (*it)->threadId << ": " << (*it)->state);
    }
  }

  void Worker::healthCheck(time_t currentTime)
  {
    if (state != stateWaitingForJob
        && lastWaitTime != 0
        && maxRequestTime > 0)
    {
      if (currentTime - lastWaitTime > maxRequestTime)
      {
        log_fatal("requesttime " << maxRequestTime << " seconds in thread "
          << threadId << " exceeded - exit process");
        log_info("current state: " << state);
        exit(111);
      }
    }
  }

  Worker::workers_type::size_type Worker::getCountThreads()
  {
    cxxtools::MutexLock lock(mutex);
    return workers.size();
  }
}
<commit_msg>remove unused include<commit_after>/* worker.cpp
 * Copyright (C) 2003-2005 Tommi Maekitalo
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
 * NON-INFRINGEMENT.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 * You must obey the GNU General Public License in all respects
 * for all of the code used other than OpenSSL.  If you modify
 * file(s) with this exception, you may extend this exception to your
 * version of the file(s), but you are not obligated to do so.  If you
 * do not wish to do so, delete this exception statement from your
 * version.  If you delete this exception statement from all source
 * files in the program, then also delete it here.
 */

#include "tnt/worker.h"
#include "tnt/dispatcher.h"
#include "tnt/job.h"
#include <tnt/httprequest.h>
#include <tnt/httpreply.h>
#include <tnt/httperror.h>
#include <tnt/http.h>
#include <tnt/poller.h>
#include <cxxtools/log.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <locale>
#include <errno.h>

log_define("tntnet.worker")

namespace
{
  class ComponentUnloadLock
  {
      tnt::Component& comp;

    public:
      ComponentUnloadLock(tnt::Component& c)
        : comp(c)
      { comp.lock(); }
      ~ComponentUnloadLock()
      { comp.unlock(); }
  };

  static const char stateStarting[]          = "0 starting";
  static const char stateWaitingForJob[]     = "1 waiting for job";
  static const char stateParsing[]           = "2 parsing request";
  static const char statePostParsing[]       = "3 post parsing";
  static const char stateDispatch[]          = "4 dispatch";
  static const char stateProcessingRequest[] = "5 processing request";
  static const char stateFlush[]             = "6 flush";
  static const char stateSendReply[]         = "7 send reply";
  static const char stateSendError[]         = "8 send error";
  static const char stateStopping[]          = "9 stopping";
}

namespace tnt
{
  cxxtools::Mutex Worker::mutex;
  unsigned Worker::nextThreadNumber = 0;
  Worker::workers_type Worker::workers;
  unsigned Worker::compLifetime = 600;
  unsigned Worker::maxRequestTime = 600;
  unsigned Worker::reportStateTime = 0;
  time_t Worker::nextReportStateTime = 0;
  unsigned Worker::minThreads = 5;
  bool Worker::enableCompression = true;

  Worker::ComploaderPoolType Worker::comploaderPool;

  Worker::Worker(Tntnet& app)
    : application(app),
      comploaderObject(comploaderPool.get()),
      comploader(comploaderObject),
      threadId(0),
      state(stateStarting),
      lastWaitTime(0)
  {
    log_debug("initialize thread " << threadId);

    cxxtools::MutexLock lock(mutex);
    workers.insert(this);
  }

  Worker::~Worker()
  {
    cxxtools::MutexLock lock(mutex);
    workers.erase(this);
    comploader.cleanup(0);

    log_debug("delete worker " << threadId << " - " << workers.size() << " threads left - " << application.getQueue().getWaitThreadCount() << " waiting threads");
  }

  void Worker::run()
  {
    threadId = pthread_self();
    Jobqueue& queue = application.getQueue();
    log_debug("start thread " << threadId);
    while (queue.getWaitThreadCount() < minThreads)
    {
      log_debug("waiting for job");
      state = stateWaitingForJob;
      Jobqueue::JobPtr j = queue.get();
      if (Tntnet::shouldStop())
      {
        log_warn("stop worker");
        break;
      }
      log_debug("got job - fd=" << j->getFd());

      std::iostream& socket = j->getStream();

      try
      {
        bool keepAlive;
        do
        {
          time(&lastWaitTime);

          log_debug("read request");

          keepAlive = false;
          state = stateParsing;
          j->getParser().parse(socket);
          state = statePostParsing;

          if (socket.eof())
            log_debug("eof");
          else if (j->getParser().failed())
          {
            state = stateSendError;
            log_warn("bad request");
            socket << "HTTP/1.0 500 bad request\r\n"
                      "Content-Type: text/html\r\n"
                      "\r\n"
                      "
Error

bad request
"
                   << std::endl;
          }
          else if (socket.fail())
            log_error("socket failed");
          else
          {
            j->getRequest().doPostParse();

            j->setWrite();
            keepAlive = processRequest(j->getRequest(), socket,
              j->decrementKeepAliveCounter());

            if (keepAlive)
            {
              j->setRead();
              j->clear();

              // if there is something to do and no threads waiting, we take
              // the next job just to improve resposiveness.
              if (queue.getWaitThreadCount() == 0
                && !queue.empty())
              {
                application.getPoller().addIdleJob(j);
                keepAlive = false;
              }
              else
              {
                struct pollfd fd;
                fd.fd = j->getFd();
                fd.events = POLLIN;
                if (::poll(&fd, 1, Job::getSocketReadTimeout()) == 0)
                {
                  application.getPoller().addIdleJob(j);
                  keepAlive = false;
                }
              }
            }
          }
        } while (keepAlive);
      }
      catch (const cxxtools::net::Timeout& e)
      {
        log_debug("timeout - put job in poller");
        application.getPoller().addIdleJob(j);
      }
      catch (const cxxtools::net::Exception& e)
      {
        if (e.getErrno() != ENOENT)
          log_warn("unexpected exception: " << e.what());
      }
      catch (const std::exception& e)
      {
        log_warn("unexpected exception: " << e.what());
      }
    }

    time(&lastWaitTime);

    log_debug("end worker-thread " << threadId);

    state = stateStopping;
  }

  bool Worker::processRequest(HttpRequest& request, std::iostream& socket,
         unsigned keepAliveCount)
  {
    // log message
    log_info("process request: " << request.getMethod() << ' ' << request.getQuery()
      << " from client " << request.getPeerIp() << " user-Agent \"" << request.getUserAgent()
      << '"');

    // create reply-object
    HttpReply reply(socket);
    reply.setVersion(request.getMajorVersion(), request.getMinorVersion());
    reply.setMethod(request.getMethod());

    std::locale loc = request.getLocale();
    reply.out().imbue(loc);
    reply.sout().imbue(loc);

    if (request.keepAlive())
      reply.setKeepAliveCounter(keepAliveCount);

    if (enableCompression)
      reply.setAcceptEncoding(request.getEncoding());

    // process request
    try
    {
      try
      {
        dispatch(request, reply);

        if (!request.keepAlive() || !reply.keepAlive())
          keepAliveCount = 0;

        if (keepAliveCount > 0)
          log_debug("keep alive");
        else
        {
          log_debug("no keep alive request/reply="
              << request.keepAlive() << '/' << reply.keepAlive());
        }
      }
      catch (const HttpError& e)
      {
        throw;
      }
      catch (const std::exception& e)
      {
        throw HttpError(HTTP_INTERNAL_SERVER_ERROR, e.what());
      }
    }
    catch (const HttpError& e)
    {
      state = stateSendError;
      log_warn("http-Error: " << e.what());
      HttpReply reply(socket);
      reply.setVersion(request.getMajorVersion(), request.getMinorVersion());
      if (request.keepAlive())
        reply.setKeepAliveCounter(keepAliveCount);
      else
        keepAliveCount = 0;
      reply.out() << "
Error

"
                  << e.what() << "
" << std::endl;
      reply.sendReply(e.getErrcode(), e.getErrmsg());
    }

    return keepAliveCount > 0;
  }

  void Worker::dispatch(HttpRequest& request, HttpReply& reply)
  {
    state = stateDispatch;
    const std::string& url = request.getUrl();

    log_debug("dispatch " << request.getQuery());

    if (!HttpRequest::checkUrl(url))
      throw HttpError(HTTP_BAD_REQUEST, "illegal url");

    Dispatcher::PosType pos(application.getDispatcher(), request.getUrl());
    while (true)
    {
      state = stateDispatch;

      // pos.getNext() throws NotFoundException at end
      Dispatcher::CompidentType ci = pos.getNext();
      try
      {
        log_debug("load component " << ci);
        Component& comp = comploader.fetchComp(ci, application.getDispatcher());
        ComponentUnloadLock unload_lock(comp);
        request.setPathInfo(ci.hasPathInfo() ? ci.getPathInfo() : url);
        request.setArgs(ci.getArgs());

        application.getScopemanager().preCall(request, ci.libname);

        log_debug("call component " << ci << " path " << request.getPathInfo());
        state = stateProcessingRequest;
        unsigned http_return = comp(request, reply, request.getQueryParams());
        if (http_return != DECLINED)
        {
          if (reply.isDirectMode())
          {
            log_info("request ready, returncode " << http_return);
            state = stateFlush;
            reply.out().flush();
          }
          else
          {
            log_info("request ready, returncode " << http_return << " - ContentSize: " << reply.getContentSize());

            application.getScopemanager().postCall(request, reply, ci.libname);

            state = stateSendReply;
            reply.sendReply(http_return);
          }

          if (reply.out())
            log_debug("reply sent");
          else
            log_warn("stream error");

          return;
        }
        else
          log_debug("component " << ci << " returned DECLINED");
      }
      catch (const cxxtools::dl::DlopenError& e)
      {
        log_warn("dl::DlopenError catched - libname " << e.getLibname());
      }
      catch (const cxxtools::dl::SymbolNotFound& e)
      {
        log_warn("dl::SymbolNotFound catched - symbol " << e.getSymbol());
      }
    }

    throw NotFoundException(request.getUrl());
  }

  void Worker::timer()
  {
    time_t currentTime;
    time(&currentTime);
    bool reportState = false;
    if (reportStateTime > 0 && currentTime > nextReportStateTime)
    {
      if (nextReportStateTime)
        reportState = true;
      nextReportStateTime = currentTime + reportStateTime;
    }

    cxxtools::MutexLock lock(mutex);
    for (workers_type::iterator it = workers.begin();
         it != workers.end(); ++it)
    {
      (*it)->healthCheck(currentTime);
      (*it)->cleanup(compLifetime);
      if (reportState)
        log_info("threadstate " << (*it)->threadId << ": " << (*it)->state);
    }
  }

  void Worker::healthCheck(time_t currentTime)
  {
    if (state != stateWaitingForJob
        && lastWaitTime != 0
        && maxRequestTime > 0)
    {
      if (currentTime - lastWaitTime > maxRequestTime)
      {
        log_fatal("requesttime " << maxRequestTime << " seconds in thread "
          << threadId << " exceeded - exit process");
        log_info("current state: " << state);
        exit(111);
      }
    }
  }

  Worker::workers_type::size_type Worker::getCountThreads()
  {
    cxxtools::MutexLock lock(mutex);
    return workers.size();
  }
}
<|endoftext|>


<commit_before>/* worker.cpp
   Copyright (C) 2003-2005 Tommi Maekitalo

This file is part of tntnet.

Tntnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

Tntnet 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with tntnet; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA  02111-1307  USA
*/

#include "tnt/worker.h"
#include "tnt/dispatcher.h"
#include "tnt/job.h"
#include <tnt/httprequest.h>
#include <tnt/httpreply.h>
#include <tnt/httperror.h>
#include <tnt/http.h>
#include <tnt/poller.h>
#include <tnt/sessionscope.h>
#include <cxxtools/log.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <locale>

log_define("tntnet.worker")

namespace
{
  class ComponentUnloadLock
  {
      tnt::Component& comp;

    public:
      ComponentUnloadLock(tnt::Component& c)
        : comp(c)
      { comp.lock(); }
      ~ComponentUnloadLock()
      { comp.unlock(); }
  };

  static const char stateStarting[]          = "0 starting";
  static const char stateWaitingForJob[]     = "1 waiting for job";
  static const char stateParsing[]           = "2 parsing request";
  static const char statePostParsing[]       = "3 post parsing";
  static const char stateDispatch[]          = "4 dispatch";
  static const char stateProcessingRequest[] = "5 processing request";
  static const char stateFlush[]             = "6 flush";
  static const char stateSendReply[]         = "7 send reply";
  static const char stateSendError[]         = "8 send error";
  static const char stateStopping[]          = "9 stopping";
}

namespace tnt
{
  cxxtools::Mutex Worker::mutex;
  unsigned Worker::nextThreadNumber = 0;
  Worker::workers_type Worker::workers;
  unsigned Worker::compLifetime = 600;
  unsigned Worker::maxRequestTime = 600;
  unsigned Worker::reportStateTime = 0;
  time_t Worker::nextReportStateTime = 0;
  unsigned Worker::minThreads = 5;
  bool Worker::enableCompression = false;

  Worker::ComploaderPoolType Worker::comploaderPool;

  Worker::Worker(Tntnet& app)
    : application(app),
      comploaderObject(comploaderPool.get()),
      comploader(comploaderObject),
      threadId(0),
      state(stateStarting),
      lastWaitTime(0)
  {
    log_debug("initialize thread " << threadId);

    cxxtools::MutexLock lock(mutex);
    workers.insert(this);
  }

  Worker::~Worker()
  {
    cxxtools::MutexLock lock(mutex);
    workers.erase(this);
    comploader.cleanup(0);

    log_debug("delete worker " << threadId << " - " << workers.size() << " threads left - " << application.getQueue().getWaitThreadCount() << " waiting threads");
  }

  void Worker::run()
  {
    threadId = pthread_self();
    Jobqueue& queue = application.getQueue();
    log_debug("start thread " << threadId);
    while (queue.getWaitThreadCount() < minThreads)
    {
      log_debug("waiting for job");
      state = stateWaitingForJob;
      Jobqueue::JobPtr j = queue.get();
      log_debug("got job - fd=" << j->getFd());

      std::iostream& socket = j->getStream();

      try
      {
        bool keepAlive;
        do
        {
          time(&lastWaitTime);

          keepAlive = false;
          log_debug("call parser");
          state = stateParsing;
          j->getParser().parse(socket);
          state = statePostParsing;

          if (socket.eof())
            log_debug("eof");
          else if (j->getParser().failed())
          {
            state = stateSendError;
            log_warn("bad request");
            socket << "HTTP/1.0 500 bad request\r\n"
                      "Content-Type: text/html\r\n"
                      "\r\n"
                      "
Error

bad request
"
                   << std::endl;
          }
          else if (socket.fail())
            log_error("socket failed");
          else
          {
            j->getRequest().doPostParse();

            j->setWrite();
            keepAlive = processRequest(j->getRequest(), socket,
              j->decrementKeepAliveCounter());

            if (keepAlive)
            {
              j->setRead();
              j->clear();

              // if there is something to do and no threads waiting, we take
              // the next job just to improve resposiveness.
              if (queue.getWaitThreadCount() == 0
                && !queue.empty())
              {
                application.getPoller().addIdleJob(j);
                keepAlive = false;
              }
            }
          }
        } while (keepAlive);
      }
      catch (const cxxtools::net::Timeout& e)
      {
        log_debug("timeout - put job in poller");
        application.getPoller().addIdleJob(j);
      }
      catch (const std::exception& e)
      {
        log_warn("unexpected exception: " << e.what());
      }
    }

    time(&lastWaitTime);

    log_debug("end worker-thread " << threadId);

    state = stateStopping;
  }

  bool Worker::processRequest(HttpRequest& request, std::iostream& socket,
         unsigned keepAliveCount)
  {
    // log message
    log_info("process request: " << request.getMethod() << ' ' << request.getUrl()
      << " from client " << request.getPeerIp() << " user-Agent \"" << request.getUserAgent()
      << '"');

    // create reply-object
    HttpReply reply(socket);
    reply.setVersion(request.getMajorVersion(), request.getMinorVersion());
    reply.setMethod(request.getMethod());
    std::string LANG = request.getLang();
    if (!LANG.empty())
    {
      try
      {
        std::locale loc(LANG.c_str());
        reply.out().imbue(loc);
        reply.sout().imbue(loc);
      }
      catch (const std::exception& e)
      {
        log_warn("unknown locale " << LANG);
      }
    }

    if (request.keepAlive())
      reply.setKeepAliveCounter(keepAliveCount);

    // process request
    try
    {
      try
      {
        dispatch(request, reply);

        if (!request.keepAlive() || !reply.keepAlive())
          keepAliveCount = 0;

        if (keepAliveCount > 0)
          log_debug("keep alive");
        else
        {
          log_debug("no keep alive request/reply="
              << request.keepAlive() << '/' << reply.keepAlive());
        }
      }
      catch (const HttpError& e)
      {
        throw;
      }
      catch (const std::exception& e)
      {
        throw HttpError(HTTP_INTERNAL_SERVER_ERROR, e.what());
      }
    }
    catch (const HttpError& e)
    {
      state = stateSendError;
      log_warn("http-Error: " << e.what());
      socket << "HTTP/1.0 " << std::string(e.what(), 3) << "\r\n"
                "Content-Type: text/html\r\n"
                "\r\n"
                "
Error

"
             << e.what() << "
" << std::endl;
      return false;
    }

    return keepAliveCount > 0;
  }

  void Worker::dispatch(HttpRequest& request, HttpReply& reply)
  {
    state = stateDispatch;
    const std::string& url = request.getUrl();

    log_info("dispatch " << request.getQuery());

    if (!HttpRequest::checkUrl(url))
      throw HttpError(HTTP_BAD_REQUEST, "illegal url");

    Dispatcher::PosType pos(application.getDispatcher(), request.getUrl());
    while (true)
    {
      state = stateDispatch;

      // pos.getNext() throws NotFoundException at end
      Dispatcher::CompidentType ci = pos.getNext();
      try
      {
        log_debug("load component " << ci);
        Component& comp = comploader.fetchComp(ci, application.getDispatcher());
        ComponentUnloadLock unload_lock(comp);
        request.setPathInfo(ci.hasPathInfo() ? ci.getPathInfo() : url);
        request.setArgs(ci.getArgs());

        application.getScopemanager().preCall(request, ci.libname);

        log_info("call component " << ci << " path " << request.getPathInfo());
        state = stateProcessingRequest;
        unsigned http_return = comp(request, reply, request.getQueryParams());
        if (http_return != DECLINED)
        {
          if (reply.isDirectMode())
          {
            log_info("request ready, returncode " << http_return);
            state = stateFlush;
            reply.out().flush();
          }
          else
          {
            log_info("request ready, returncode " << http_return << " - ContentSize: " << reply.getContentSize());

            application.getScopemanager().postCall(request, reply, ci.libname);

            if (enableCompression)
              reply.setAcceptEncoding(request.getEncoding());

            state = stateSendReply;
            reply.sendReply(http_return);
          }

          if (reply.out())
            log_info("reply sent");

          return;
        }
        else
          log_debug("component " << ci << " returned DECLINED");
      }
      catch (const cxxtools::dl::DlopenError& e)
      {
        log_warn("dl::DlopenError catched - libname " << e.getLibname());
      }
      catch (const cxxtools::dl::SymbolNotFound& e)
      {
        log_warn("dl::SymbolNotFound catched - symbol " << e.getSymbol());
      }
    }

    throw NotFoundException(request.getUrl());
  }

  void Worker::timer()
  {
    time_t currentTime;
    time(&currentTime);
    bool reportState = false;
    if (reportStateTime > 0 && currentTime > nextReportStateTime)
    {
      if (nextReportStateTime)
        reportState = true;
      nextReportStateTime = currentTime + reportStateTime;
    }

    cxxtools::MutexLock lock(mutex);
    for (workers_type::iterator it = workers.begin();
         it != workers.end(); ++it)
    {
      (*it)->healthCheck(currentTime);
      (*it)->cleanup(compLifetime);
      if (reportState)
        log_info("threadstate " << (*it)->threadId << ": " << (*it)->state);
    }
  }

  void Worker::healthCheck(time_t currentTime)
  {
    if (state != stateWaitingForJob
        && lastWaitTime != 0
        && maxRequestTime > 0)
    {
      if (currentTime - lastWaitTime > maxRequestTime)
      {
        log_fatal("requesttime " << maxRequestTime << " seconds in thread "
          << threadId << " exceeded - exit process");
        log_info("current state: " << state);
        exit(111);
      }
    }
  }

  Worker::workers_type::size_type Worker::getCountThreads()
  {
    cxxtools::MutexLock lock(mutex);
    return workers.size();
  }
}
<commit_msg>enable compression by default<commit_after>/* worker.cpp
   Copyright (C) 2003-2005 Tommi Maekitalo

This file is part of tntnet.

Tntnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

Tntnet 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with tntnet; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA  02111-1307  USA
*/

#include "tnt/worker.h"
#include "tnt/dispatcher.h"
#include "tnt/job.h"
#include <tnt/httprequest.h>
#include <tnt/httpreply.h>
#include <tnt/httperror.h>
#include <tnt/http.h>
#include <tnt/poller.h>
#include <tnt/sessionscope.h>
#include <cxxtools/log.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <locale>

log_define("tntnet.worker")

namespace
{
  class ComponentUnloadLock
  {
      tnt::Component& comp;

    public:
      ComponentUnloadLock(tnt::Component& c)
        : comp(c)
      { comp.lock(); }
      ~ComponentUnloadLock()
      { comp.unlock(); }
  };

  static const char stateStarting[]          = "0 starting";
  static const char stateWaitingForJob[]     = "1 waiting for job";
  static const char stateParsing[]           = "2 parsing request";
  static const char statePostParsing[]       = "3 post parsing";
  static const char stateDispatch[]          = "4 dispatch";
  static const char stateProcessingRequest[] = "5 processing request";
  static const char stateFlush[]             = "6 flush";
  static const char stateSendReply[]         = "7 send reply";
  static const char stateSendError[]         = "8 send error";
  static const char stateStopping[]          = "9 stopping";
}

namespace tnt
{
  cxxtools::Mutex Worker::mutex;
  unsigned Worker::nextThreadNumber = 0;
  Worker::workers_type Worker::workers;
  unsigned Worker::compLifetime = 600;
  unsigned Worker::maxRequestTime = 600;
  unsigned Worker::reportStateTime = 0;
  time_t Worker::nextReportStateTime = 0;
  unsigned Worker::minThreads = 5;
  bool Worker::enableCompression = true;

  Worker::ComploaderPoolType Worker::comploaderPool;

  Worker::Worker(Tntnet& app)
    : application(app),
      comploaderObject(comploaderPool.get()),
      comploader(comploaderObject),
      threadId(0),
      state(stateStarting),
      lastWaitTime(0)
  {
    log_debug("initialize thread " << threadId);

    cxxtools::MutexLock lock(mutex);
    workers.insert(this);
  }

  Worker::~Worker()
  {
    cxxtools::MutexLock lock(mutex);
    workers.erase(this);
    comploader.cleanup(0);

    log_debug("delete worker " << threadId << " - " << workers.size() << " threads left - " << application.getQueue().getWaitThreadCount() << " waiting threads");
  }

  void Worker::run()
  {
    threadId = pthread_self();
    Jobqueue& queue = application.getQueue();
    log_debug("start thread " << threadId);
    while (queue.getWaitThreadCount() < minThreads)
    {
      log_debug("waiting for job");
      state = stateWaitingForJob;
      Jobqueue::JobPtr j = queue.get();
      log_debug("got job - fd=" << j->getFd());

      std::iostream& socket = j->getStream();

      try
      {
        bool keepAlive;
        do
        {
          time(&lastWaitTime);

          keepAlive = false;
          log_debug("call parser");
          state = stateParsing;
          j->getParser().parse(socket);
          state = statePostParsing;

          if (socket.eof())
            log_debug("eof");
          else if (j->getParser().failed())
          {
            state = stateSendError;
            log_warn("bad request");
            socket << "HTTP/1.0 500 bad request\r\n"
                      "Content-Type: text/html\r\n"
                      "\r\n"
                      "
Error

bad request
"
                   << std::endl;
          }
          else if (socket.fail())
            log_error("socket failed");
          else
          {
            j->getRequest().doPostParse();

            j->setWrite();
            keepAlive = processRequest(j->getRequest(), socket,
              j->decrementKeepAliveCounter());

            if (keepAlive)
            {
              j->setRead();
              j->clear();

              // if there is something to do and no threads waiting, we take
              // the next job just to improve resposiveness.
              if (queue.getWaitThreadCount() == 0
                && !queue.empty())
              {
                application.getPoller().addIdleJob(j);
                keepAlive = false;
              }
            }
          }
        } while (keepAlive);
      }
      catch (const cxxtools::net::Timeout& e)
      {
        log_debug("timeout - put job in poller");
        application.getPoller().addIdleJob(j);
      }
      catch (const std::exception& e)
      {
        log_warn("unexpected exception: " << e.what());
      }
    }

    time(&lastWaitTime);

    log_debug("end worker-thread " << threadId);

    state = stateStopping;
  }

  bool Worker::processRequest(HttpRequest& request, std::iostream& socket,
         unsigned keepAliveCount)
  {
    // log message
    log_info("process request: " << request.getMethod() << ' ' << request.getUrl()
      << " from client " << request.getPeerIp() << " user-Agent \"" << request.getUserAgent()
      << '"');

    // create reply-object
    HttpReply reply(socket);
    reply.setVersion(request.getMajorVersion(), request.getMinorVersion());
    reply.setMethod(request.getMethod());
    std::string LANG = request.getLang();
    if (!LANG.empty())
    {
      try
      {
        std::locale loc(LANG.c_str());
        reply.out().imbue(loc);
        reply.sout().imbue(loc);
      }
      catch (const std::exception& e)
      {
        log_warn("unknown locale " << LANG);
      }
    }

    if (request.keepAlive())
      reply.setKeepAliveCounter(keepAliveCount);

    // process request
    try
    {
      try
      {
        dispatch(request, reply);

        if (!request.keepAlive() || !reply.keepAlive())
          keepAliveCount = 0;

        if (keepAliveCount > 0)
          log_debug("keep alive");
        else
        {
          log_debug("no keep alive request/reply="
              << request.keepAlive() << '/' << reply.keepAlive());
        }
      }
      catch (const HttpError& e)
      {
        throw;
      }
      catch (const std::exception& e)
      {
        throw HttpError(HTTP_INTERNAL_SERVER_ERROR, e.what());
      }
    }
    catch (const HttpError& e)
    {
      state = stateSendError;
      log_warn("http-Error: " << e.what());
      socket << "HTTP/1.0 " << std::string(e.what(), 3) << "\r\n"
                "Content-Type: text/html\r\n"
                "\r\n"
                "
Error

"
             << e.what() << "
" << std::endl;
      return false;
    }

    return keepAliveCount > 0;
  }

  void Worker::dispatch(HttpRequest& request, HttpReply& reply)
  {
    state = stateDispatch;
    const std::string& url = request.getUrl();

    log_info("dispatch " << request.getQuery());

    if (!HttpRequest::checkUrl(url))
      throw HttpError(HTTP_BAD_REQUEST, "illegal url");

    Dispatcher::PosType pos(application.getDispatcher(), request.getUrl());
    while (true)
    {
      state = stateDispatch;

      // pos.getNext() throws NotFoundException at end
      Dispatcher::CompidentType ci = pos.getNext();
      try
      {
        log_debug("load component " << ci);
        Component& comp = comploader.fetchComp(ci, application.getDispatcher());
        ComponentUnloadLock unload_lock(comp);
        request.setPathInfo(ci.hasPathInfo() ? ci.getPathInfo() : url);
        request.setArgs(ci.getArgs());

        application.getScopemanager().preCall(request, ci.libname);

        log_info("call component " << ci << " path " << request.getPathInfo());
        state = stateProcessingRequest;
        unsigned http_return = comp(request, reply, request.getQueryParams());
        if (http_return != DECLINED)
        {
          if (reply.isDirectMode())
          {
            log_info("request ready, returncode " << http_return);
            state = stateFlush;
            reply.out().flush();
          }
          else
          {
            log_info("request ready, returncode " << http_return << " - ContentSize: " << reply.getContentSize());

            application.getScopemanager().postCall(request, reply, ci.libname);

            if (enableCompression)
              reply.setAcceptEncoding(request.getEncoding());

            state = stateSendReply;
            reply.sendReply(http_return);
          }

          if (reply.out())
            log_info("reply sent");

          return;
        }
        else
          log_debug("component " << ci << " returned DECLINED");
      }
      catch (const cxxtools::dl::DlopenError& e)
      {
        log_warn("dl::DlopenError catched - libname " << e.getLibname());
      }
      catch (const cxxtools::dl::SymbolNotFound& e)
      {
        log_warn("dl::SymbolNotFound catched - symbol " << e.getSymbol());
      }
    }

    throw NotFoundException(request.getUrl());
  }

  void Worker::timer()
  {
    time_t currentTime;
    time(&currentTime);
    bool reportState = false;
    if (reportStateTime > 0 && currentTime > nextReportStateTime)
    {
      if (nextReportStateTime)
        reportState = true;
      nextReportStateTime = currentTime + reportStateTime;
    }

    cxxtools::MutexLock lock(mutex);
    for (workers_type::iterator it = workers.begin();
         it != workers.end(); ++it)
    {
      (*it)->healthCheck(currentTime);
      (*it)->cleanup(compLifetime);
      if (reportState)
        log_info("threadstate " << (*it)->threadId << ": " << (*it)->state);
    }
  }

  void Worker::healthCheck(time_t currentTime)
  {
    if (state != stateWaitingForJob
        && lastWaitTime != 0
        && maxRequestTime > 0)
    {
      if (currentTime - lastWaitTime > maxRequestTime)
      {
        log_fatal("requesttime " << maxRequestTime << " seconds in thread "
          << threadId << " exceeded - exit process");
        log_info("current state: " << state);
        exit(111);
      }
    }
  }

  Worker::workers_type::size_type Worker::getCountThreads()
  {
    cxxtools::MutexLock lock(mutex);
    return workers.size();
  }
}
<|endoftext|>


<commit_before>/* variable.cpp
 * Copyright (C) 2003 Tommi Maekitalo
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This program 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 program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include "tnt/ecppc/variable.h"
#include <sstream>
#include <locale>

namespace tnt
{
  namespace ecppc
  {
    Variable::Variable(const std::string& arg, const std::string& value_)
    {
      // 'name' might be prefixed by a type
      // the variablename is the last word in 'name'
      // type is the rest before the variablename
      // examples:
      //   " int var "
      //   " var"
      //   " ns :: someclass  param"
      std::ostringstream a;

      std::string::size_type e = arg.size();
      while (e > 0 && std::isspace(arg.at(e - 1)))
        --e;

      // e points past the last character of our arg

      if (e > 1 && arg.at(e - 2) == '[' && arg.at(e-1) == ']')
      {
        isvector = true;
        e -= 2;
        while (e > 0 && std::isspace(arg.at(e - 1)))
          --e;
      }
      else
        isvector = false;

      std::string::size_type b = e;
      while (b > 0 && !std::isspace(arg.at(b - 1)))
        --b;
      // b points to the first character of our arg

      std::string::size_type t = b;
      while (t > 0 && std::isspace(arg.at(t - 1)))
        --t;
      // t points past the last character of the type

      name = std::string(arg.begin() + b, arg.begin() + e);
      type = std::string(arg.begin(), arg.begin() + t);
      value = value_;

    }

    void Variable::getParamCodeVector(std::ostream& o) const
    {
      if (type.empty())
      {
        o << "typedef std::vector<std::string> " << name << "_type;\n"
          << name << "_type " << name << "(qparam.begin(\"" << name
          << "\"), qparam.end());\n";
      }
      else
      {
        o << "typedef std::vector<" << type << "> " << name << "_type;\n"
          << name << "_type " << name << ";\n"
          << "std::transform(qparam.begin(\"" << name
          << "\"), qparam.end(), std::back_inserter(" << name
          << "), tnt::stringToConverter<" << type
          << ">(reply.out().getloc()));\n";
      }
    }

    void Variable::getParamCode(std::ostream& o) const
    {
      if (isvector)
        getParamCodeVector(o);
      else if (!type.empty())
      {
        // we have a type

        // print out type and name
        o << type << ' ' << name << " = ";

        if (value.empty())
        {
          // no default-value

          o << "tnt::stringToConverter<" << type
            << ">(reply.out().getloc())( qparam.param(\"" << name << "\") );\n";
        }
        else
        {
          // with default-value
          o << "qparam.has(\"" << name << "\") ? tnt::stringToWithDefaultConverter<"
            << type << ">(" << value << ", reply.out().getloc())(qparam.param(\""
            << name << "\")) : " << value << ";\n";
        }
      }
      else
      {
        // type defaults to std::string
        o << "std::string " << name
          << " = qparam.param(\"" << name << '"';
        if (!value.empty())
          o << ", " << value;

        o << ");\n";
      }
    }

    void Variable::getConfigInit(std::ostream& o, const std::string& classname) const
    {
      if (!type.empty())
      {
        // we have a type

        o << "    if (config.hasValue(\"" << name << "\"))\n"
          << "      " << classname << "::" << name << " = tnt::stringTo<" << type
          << ">( config.getValue(\"" << name << "\") );\n";
      }
      else
      {
        // type defaults to std::string
        if (value.empty())
          o << "    " << classname << "::" << name
            << " = config.getValue(\"" << name << "\");\n";
        else
          o << "    if (config.hasValue(\"" << name << "\"))\n"
            << "      " << classname << "::" << name << " = config.getValue(\""
            << name << "\");\n";
      }
    }

    void Variable::getConfigDecl(std::ostream& o, const std::string& classname) const
    {
      std::string t = type.empty() ? "std::string" : type;

      o << t << ' ' << classname << "::" << name;
      if (!value.empty())
        o << " = " << value;
      o << ";\n";
    }

    void Variable::getConfigHDecl(std::ostream& o) const
    {
      std::string t = type.empty() ? "std::string" : type;

      o << "    static " << t << " " << name << ";\n";
    }
  }
}
<commit_msg>fix include<commit_after>/* variable.cpp
 * Copyright (C) 2003 Tommi Maekitalo
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This program 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 program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include "tnt/ecppc/variable.h"
#include <sstream>
#include <cctype>

namespace tnt
{
  namespace ecppc
  {
    Variable::Variable(const std::string& arg, const std::string& value_)
    {
      // 'name' might be prefixed by a type
      // the variablename is the last word in 'name'
      // type is the rest before the variablename
      // examples:
      //   " int var "
      //   " var"
      //   " ns :: someclass  param"
      std::ostringstream a;

      std::string::size_type e = arg.size();
      while (e > 0 && std::isspace(arg.at(e - 1)))
        --e;

      // e points past the last character of our arg

      if (e > 1 && arg.at(e - 2) == '[' && arg.at(e-1) == ']')
      {
        isvector = true;
        e -= 2;
        while (e > 0 && std::isspace(arg.at(e - 1)))
          --e;
      }
      else
        isvector = false;

      std::string::size_type b = e;
      while (b > 0 && !std::isspace(arg.at(b - 1)))
        --b;
      // b points to the first character of our arg

      std::string::size_type t = b;
      while (t > 0 && std::isspace(arg.at(t - 1)))
        --t;
      // t points past the last character of the type

      name = std::string(arg.begin() + b, arg.begin() + e);
      type = std::string(arg.begin(), arg.begin() + t);
      value = value_;

    }

    void Variable::getParamCodeVector(std::ostream& o) const
    {
      if (type.empty())
      {
        o << "typedef std::vector<std::string> " << name << "_type;\n"
          << name << "_type " << name << "(qparam.begin(\"" << name
          << "\"), qparam.end());\n";
      }
      else
      {
        o << "typedef std::vector<" << type << "> " << name << "_type;\n"
          << name << "_type " << name << ";\n"
          << "std::transform(qparam.begin(\"" << name
          << "\"), qparam.end(), std::back_inserter(" << name
          << "), tnt::stringToConverter<" << type
          << ">(reply.out().getloc()));\n";
      }
    }

    void Variable::getParamCode(std::ostream& o) const
    {
      if (isvector)
        getParamCodeVector(o);
      else if (!type.empty())
      {
        // we have a type

        // print out type and name
        o << type << ' ' << name << " = ";

        if (value.empty())
        {
          // no default-value

          o << "tnt::stringToConverter<" << type
            << ">(reply.out().getloc())( qparam.param(\"" << name << "\") );\n";
        }
        else
        {
          // with default-value
          o << "qparam.has(\"" << name << "\") ? tnt::stringToWithDefaultConverter<"
            << type << ">(" << value << ", reply.out().getloc())(qparam.param(\""
            << name << "\")) : " << value << ";\n";
        }
      }
      else
      {
        // type defaults to std::string
        o << "std::string " << name
          << " = qparam.param(\"" << name << '"';
        if (!value.empty())
          o << ", " << value;

        o << ");\n";
      }
    }

    void Variable::getConfigInit(std::ostream& o, const std::string& classname) const
    {
      if (!type.empty())
      {
        // we have a type

        o << "    if (config.hasValue(\"" << name << "\"))\n"
          << "      " << classname << "::" << name << " = tnt::stringTo<" << type
          << ">( config.getValue(\"" << name << "\") );\n";
      }
      else
      {
        // type defaults to std::string
        if (value.empty())
          o << "    " << classname << "::" << name
            << " = config.getValue(\"" << name << "\");\n";
        else
          o << "    if (config.hasValue(\"" << name << "\"))\n"
            << "      " << classname << "::" << name << " = config.getValue(\""
            << name << "\");\n";
      }
    }

    void Variable::getConfigDecl(std::ostream& o, const std::string& classname) const
    {
      std::string t = type.empty() ? "std::string" : type;

      o << t << ' ' << classname << "::" << name;
      if (!value.empty())
        o << " = " << value;
      o << ";\n";
    }

    void Variable::getConfigHDecl(std::ostream& o) const
    {
      std::string t = type.empty() ? "std::string" : type;

      o << "    static " << t << " " << name << ";\n";
    }
  }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: dlgolbul.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-13 17:26:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef SD_DLLIMPLEMENTATION
#undef SD_DLLIMPLEMENTATION
#endif

#include "OutlineBulletDlg.hxx"

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#ifndef _SFX_OBJSH_HXX //autogen
#include <sfx2/objsh.hxx>
#endif
#define ITEMID_COLOR_TABLE      SID_COLOR_TABLE
#ifndef _SVX_DRAWITEM_HXX //autogen
#include <svx/drawitem.hxx>
#endif
#ifndef _SVX_BULITEM_HXX
#include <svx/bulitem.hxx>
#endif
#ifndef _EEITEM_HXX
#include <svx/eeitem.hxx>
#endif

//CHINA001 #include <svx/numpages.hxx>
#include <svx/numitem.hxx>

#include <svx/dialogs.hrc>
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif

#ifndef _SVDMARK_HXX //autogen
#include <svx/svdmark.hxx>
#endif

#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif

#ifndef _SVDOBJ_HXX //autogen
#include <svx/svdobj.hxx>
#endif

#ifndef _SFXSTYLE_HXX //autogen
#include <svtools/style.hxx>
#endif

#ifndef _DRAWDOC_HXX
#include <drawdoc.hxx>
#endif

#ifndef _SD_SDRESID_HXX
#include "sdresid.hxx"
#endif

#include "glob.hrc"
#include "dlgolbul.hrc"
//#include "enumdlg.hxx"
#include "bulmaper.hxx"
#include "DrawDocShell.hxx"
#include <svx/svxids.hrc> //add CHINA001
#include <svtools/aeitem.hxx> //add CHINA001

namespace sd {

/*************************************************************************
|*
|* Konstruktor des Tab-Dialogs: Fuegt die Seiten zum Dialog hinzu
|*
\************************************************************************/

OutlineBulletDlg::OutlineBulletDlg(
    ::Window* pParent,
    const SfxItemSet* pAttr,
    ::sd::View* pView )
    : SfxTabDialog  ( pParent, SdResId(TAB_OUTLINEBULLET) ),
      aInputSet     ( *pAttr ),
      bTitle            ( FALSE ),
      pSdView           ( pView )
{
    FreeResource();

    aInputSet.MergeRange( SID_PARAM_NUM_PRESET, SID_PARAM_CUR_NUM_LEVEL );
    aInputSet.Put( *pAttr );

    pOutputSet = new SfxItemSet( *pAttr );
    pOutputSet->ClearItem();

    BOOL bOutliner = FALSE;

    // Sonderbehandlung wenn eine Title Objekt selektiert wurde
    if( pView )
    {
        const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
        const ULONG nCount = rMarkList.GetMarkCount();
        for(ULONG nNum = 0; nNum < nCount; nNum++)
        {
            SdrObject* pObj = rMarkList.GetMark(nNum)->GetObj();
            if( pObj->GetObjInventor() == SdrInventor )
            {

                switch(pObj->GetObjIdentifier())
                {
                case OBJ_TITLETEXT:
                    bTitle = TRUE;
                    break;
                case OBJ_OUTLINETEXT:
                    bOutliner = TRUE;
                    break;
                }
            }
        }
    }

    if( SFX_ITEM_SET != aInputSet.GetItemState(EE_PARA_NUMBULLET))
    {
        const SvxNumBulletItem *pItem = NULL;
        if(bOutliner)
        {
            SfxStyleSheetBasePool* pSSPool = pView->GetDocSh()->GetStyleSheetPool();
            String aStyleName((SdResId(STR_LAYOUT_OUTLINE)));
            aStyleName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " 1" ) );
            SfxStyleSheetBase* pFirstStyleSheet = pSSPool->Find( aStyleName, SFX_STYLE_FAMILY_PSEUDO);
            if( pFirstStyleSheet )
                pFirstStyleSheet->GetItemSet().GetItemState(EE_PARA_NUMBULLET, FALSE, (const SfxPoolItem**)&pItem);
        }

        if( pItem == NULL )
            pItem = (SvxNumBulletItem*) aInputSet.GetPool()->GetSecondaryPool()->GetPoolDefaultItem(EE_PARA_NUMBULLET);

        DBG_ASSERT( pItem, "Kein EE_PARA_NUMBULLET im Pool! [CL]" );

        aInputSet.Put(*pItem, EE_PARA_NUMBULLET);
    }

    /* debug
    if( SFX_ITEM_SET == aInputSet.GetItemState(EE_PARA_NUMBULLET, FALSE, &pItem ))
    {
        SvxNumRule& rItem = *((SvxNumBulletItem*)pItem)->GetNumRule();
        for( int i = 0; i < 9; i++ )
        {
            SvxNumberFormat aNumberFormat = rItem.GetLevel(i);
        }
    }
    */

    if(bTitle && aInputSet.GetItemState(EE_PARA_NUMBULLET,TRUE) == SFX_ITEM_ON )
    {
        SvxNumBulletItem* pItem = (SvxNumBulletItem*)aInputSet.GetItem(EE_PARA_NUMBULLET,TRUE);
        SvxNumRule* pRule = pItem->GetNumRule();
        if(pRule)
        {
            SvxNumRule aNewRule( *pRule );
            aNewRule.SetFeatureFlag( NUM_NO_NUMBERS, TRUE );

            SvxNumBulletItem aNewItem( aNewRule, EE_PARA_NUMBULLET );
            aInputSet.Put(aNewItem);
        }
    }

    SdBulletMapper::PreMapNumBulletForDialog( aInputSet );

    SetInputSet( &aInputSet );

    if(!bTitle)
        AddTabPage(RID_SVXPAGE_PICK_SINGLE_NUM);//CHINA001 AddTabPage(RID_SVXPAGE_PICK_SINGLE_NUM, &SvxSingleNumPickTabPage::Create, 0);
    else
        RemoveTabPage( RID_SVXPAGE_PICK_SINGLE_NUM );

    AddTabPage( RID_SVXPAGE_PICK_BULLET  ); //CHINA001 AddTabPage(RID_SVXPAGE_PICK_BULLET    , &SvxBulletPickTabPage::Create, 0);
    AddTabPage( RID_SVXPAGE_PICK_BMP   ); //CHINA001 AddTabPage(RID_SVXPAGE_PICK_BMP      , &SvxBitmapPickTabPage::Create, 0);
    AddTabPage(RID_SVXPAGE_NUM_OPTIONS  ); //CHINA001 AddTabPage(RID_SVXPAGE_NUM_OPTIONS      , &SvxNumOptionsTabPage::Create, 0);
    AddTabPage(RID_SVXPAGE_NUM_POSITION ); //CHINA001 AddTabPage(RID_SVXPAGE_NUM_POSITION     , &SvxNumPositionTabPage::Create, 0);

}

OutlineBulletDlg::~OutlineBulletDlg()
{
    delete pOutputSet;
}

void OutlineBulletDlg::PageCreated( USHORT nId, SfxTabPage &rPage )
{
    switch ( nId )
    {
        case RID_SVXPAGE_NUM_OPTIONS:
        {
            if( pSdView )
            {
                FieldUnit eMetric = pSdView->GetDoc()->GetUIUnit();
                //CHINA001 ((SvxNumOptionsTabPage&)rPage).SetMetric(eMetric);
                SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));//add CHINA001
                aSet.Put ( SfxAllEnumItem(SID_METRIC_ITEM,eMetric));//add CHINA001
                rPage.PageCreated(aSet);//add CHINA001
            }
        }
        break;
        case RID_SVXPAGE_NUM_POSITION:
        {
            if( pSdView )
            {
                FieldUnit eMetric = pSdView->GetDoc()->GetUIUnit();
                //CHINA001 ((SvxNumPositionTabPage&)rPage).SetMetric(eMetric);
                SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));//add CHINA001
                aSet.Put ( SfxAllEnumItem(SID_METRIC_ITEM,eMetric));//add CHINA001
                rPage.PageCreated(aSet);//add CHINA001
            }
        }
        break;
    }
}

const SfxItemSet* OutlineBulletDlg::GetOutputItemSet() const
{
    SfxItemSet aSet( *SfxTabDialog::GetOutputItemSet() );
    pOutputSet->Put( aSet );

    const SfxPoolItem *pItem = NULL;
    if( SFX_ITEM_SET == pOutputSet->GetItemState(pOutputSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE), FALSE, &pItem ))
    {
        SdBulletMapper::MapFontsInNumRule( *((SvxNumBulletItem*)pItem)->GetNumRule(), *pOutputSet );

        SfxUInt16Item aBulletState( EE_PARA_BULLETSTATE, 1 );
        pOutputSet->Put(aBulletState);
    }

    SdBulletMapper::PostMapNumBulletForDialog( *pOutputSet );

    if(bTitle && pOutputSet->GetItemState(EE_PARA_NUMBULLET,TRUE) == SFX_ITEM_ON )
    {
        SvxNumBulletItem* pItem = (SvxNumBulletItem*)pOutputSet->GetItem(EE_PARA_NUMBULLET,TRUE);
        SvxNumRule* pRule = pItem->GetNumRule();
        if(pRule)
            pRule->SetFeatureFlag( NUM_NO_NUMBERS, FALSE );
    }

    return pOutputSet;
}

} // end of namespace sd
<commit_msg>INTEGRATION: CWS ooo19126 (1.7.242); FILE MERGED 2005/09/05 13:21:47 rt 1.7.242.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dlgolbul.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 03:57:39 $
 *
 *  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
 *
 ************************************************************************/

#ifdef SD_DLLIMPLEMENTATION
#undef SD_DLLIMPLEMENTATION
#endif

#include "OutlineBulletDlg.hxx"

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#ifndef _SFX_OBJSH_HXX //autogen
#include <sfx2/objsh.hxx>
#endif
#define ITEMID_COLOR_TABLE      SID_COLOR_TABLE
#ifndef _SVX_DRAWITEM_HXX //autogen
#include <svx/drawitem.hxx>
#endif
#ifndef _SVX_BULITEM_HXX
#include <svx/bulitem.hxx>
#endif
#ifndef _EEITEM_HXX
#include <svx/eeitem.hxx>
#endif

//CHINA001 #include <svx/numpages.hxx>
#include <svx/numitem.hxx>

#include <svx/dialogs.hrc>
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif

#ifndef _SVDMARK_HXX //autogen
#include <svx/svdmark.hxx>
#endif

#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif

#ifndef _SVDOBJ_HXX //autogen
#include <svx/svdobj.hxx>
#endif

#ifndef _SFXSTYLE_HXX //autogen
#include <svtools/style.hxx>
#endif

#ifndef _DRAWDOC_HXX
#include <drawdoc.hxx>
#endif

#ifndef _SD_SDRESID_HXX
#include "sdresid.hxx"
#endif

#include "glob.hrc"
#include "dlgolbul.hrc"
//#include "enumdlg.hxx"
#include "bulmaper.hxx"
#include "DrawDocShell.hxx"
#include <svx/svxids.hrc> //add CHINA001
#include <svtools/aeitem.hxx> //add CHINA001

namespace sd {

/*************************************************************************
|*
|* Konstruktor des Tab-Dialogs: Fuegt die Seiten zum Dialog hinzu
|*
\************************************************************************/

OutlineBulletDlg::OutlineBulletDlg(
    ::Window* pParent,
    const SfxItemSet* pAttr,
    ::sd::View* pView )
    : SfxTabDialog  ( pParent, SdResId(TAB_OUTLINEBULLET) ),
      aInputSet     ( *pAttr ),
      bTitle            ( FALSE ),
      pSdView           ( pView )
{
    FreeResource();

    aInputSet.MergeRange( SID_PARAM_NUM_PRESET, SID_PARAM_CUR_NUM_LEVEL );
    aInputSet.Put( *pAttr );

    pOutputSet = new SfxItemSet( *pAttr );
    pOutputSet->ClearItem();

    BOOL bOutliner = FALSE;

    // Sonderbehandlung wenn eine Title Objekt selektiert wurde
    if( pView )
    {
        const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
        const ULONG nCount = rMarkList.GetMarkCount();
        for(ULONG nNum = 0; nNum < nCount; nNum++)
        {
            SdrObject* pObj = rMarkList.GetMark(nNum)->GetObj();
            if( pObj->GetObjInventor() == SdrInventor )
            {

                switch(pObj->GetObjIdentifier())
                {
                case OBJ_TITLETEXT:
                    bTitle = TRUE;
                    break;
                case OBJ_OUTLINETEXT:
                    bOutliner = TRUE;
                    break;
                }
            }
        }
    }

    if( SFX_ITEM_SET != aInputSet.GetItemState(EE_PARA_NUMBULLET))
    {
        const SvxNumBulletItem *pItem = NULL;
        if(bOutliner)
        {
            SfxStyleSheetBasePool* pSSPool = pView->GetDocSh()->GetStyleSheetPool();
            String aStyleName((SdResId(STR_LAYOUT_OUTLINE)));
            aStyleName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " 1" ) );
            SfxStyleSheetBase* pFirstStyleSheet = pSSPool->Find( aStyleName, SFX_STYLE_FAMILY_PSEUDO);
            if( pFirstStyleSheet )
                pFirstStyleSheet->GetItemSet().GetItemState(EE_PARA_NUMBULLET, FALSE, (const SfxPoolItem**)&pItem);
        }

        if( pItem == NULL )
            pItem = (SvxNumBulletItem*) aInputSet.GetPool()->GetSecondaryPool()->GetPoolDefaultItem(EE_PARA_NUMBULLET);

        DBG_ASSERT( pItem, "Kein EE_PARA_NUMBULLET im Pool! [CL]" );

        aInputSet.Put(*pItem, EE_PARA_NUMBULLET);
    }

    /* debug
    if( SFX_ITEM_SET == aInputSet.GetItemState(EE_PARA_NUMBULLET, FALSE, &pItem ))
    {
        SvxNumRule& rItem = *((SvxNumBulletItem*)pItem)->GetNumRule();
        for( int i = 0; i < 9; i++ )
        {
            SvxNumberFormat aNumberFormat = rItem.GetLevel(i);
        }
    }
    */

    if(bTitle && aInputSet.GetItemState(EE_PARA_NUMBULLET,TRUE) == SFX_ITEM_ON )
    {
        SvxNumBulletItem* pItem = (SvxNumBulletItem*)aInputSet.GetItem(EE_PARA_NUMBULLET,TRUE);
        SvxNumRule* pRule = pItem->GetNumRule();
        if(pRule)
        {
            SvxNumRule aNewRule( *pRule );
            aNewRule.SetFeatureFlag( NUM_NO_NUMBERS, TRUE );

            SvxNumBulletItem aNewItem( aNewRule, EE_PARA_NUMBULLET );
            aInputSet.Put(aNewItem);
        }
    }

    SdBulletMapper::PreMapNumBulletForDialog( aInputSet );

    SetInputSet( &aInputSet );

    if(!bTitle)
        AddTabPage(RID_SVXPAGE_PICK_SINGLE_NUM);//CHINA001 AddTabPage(RID_SVXPAGE_PICK_SINGLE_NUM, &SvxSingleNumPickTabPage::Create, 0);
    else
        RemoveTabPage( RID_SVXPAGE_PICK_SINGLE_NUM );

    AddTabPage( RID_SVXPAGE_PICK_BULLET  ); //CHINA001 AddTabPage(RID_SVXPAGE_PICK_BULLET    , &SvxBulletPickTabPage::Create, 0);
    AddTabPage( RID_SVXPAGE_PICK_BMP   ); //CHINA001 AddTabPage(RID_SVXPAGE_PICK_BMP      , &SvxBitmapPickTabPage::Create, 0);
    AddTabPage(RID_SVXPAGE_NUM_OPTIONS  ); //CHINA001 AddTabPage(RID_SVXPAGE_NUM_OPTIONS      , &SvxNumOptionsTabPage::Create, 0);
    AddTabPage(RID_SVXPAGE_NUM_POSITION ); //CHINA001 AddTabPage(RID_SVXPAGE_NUM_POSITION     , &SvxNumPositionTabPage::Create, 0);

}

OutlineBulletDlg::~OutlineBulletDlg()
{
    delete pOutputSet;
}

void OutlineBulletDlg::PageCreated( USHORT nId, SfxTabPage &rPage )
{
    switch ( nId )
    {
        case RID_SVXPAGE_NUM_OPTIONS:
        {
            if( pSdView )
            {
                FieldUnit eMetric = pSdView->GetDoc()->GetUIUnit();
                //CHINA001 ((SvxNumOptionsTabPage&)rPage).SetMetric(eMetric);
                SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));//add CHINA001
                aSet.Put ( SfxAllEnumItem(SID_METRIC_ITEM,eMetric));//add CHINA001
                rPage.PageCreated(aSet);//add CHINA001
            }
        }
        break;
        case RID_SVXPAGE_NUM_POSITION:
        {
            if( pSdView )
            {
                FieldUnit eMetric = pSdView->GetDoc()->GetUIUnit();
                //CHINA001 ((SvxNumPositionTabPage&)rPage).SetMetric(eMetric);
                SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));//add CHINA001
                aSet.Put ( SfxAllEnumItem(SID_METRIC_ITEM,eMetric));//add CHINA001
                rPage.PageCreated(aSet);//add CHINA001
            }
        }
        break;
    }
}

const SfxItemSet* OutlineBulletDlg::GetOutputItemSet() const
{
    SfxItemSet aSet( *SfxTabDialog::GetOutputItemSet() );
    pOutputSet->Put( aSet );

    const SfxPoolItem *pItem = NULL;
    if( SFX_ITEM_SET == pOutputSet->GetItemState(pOutputSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE), FALSE, &pItem ))
    {
        SdBulletMapper::MapFontsInNumRule( *((SvxNumBulletItem*)pItem)->GetNumRule(), *pOutputSet );

        SfxUInt16Item aBulletState( EE_PARA_BULLETSTATE, 1 );
        pOutputSet->Put(aBulletState);
    }

    SdBulletMapper::PostMapNumBulletForDialog( *pOutputSet );

    if(bTitle && pOutputSet->GetItemState(EE_PARA_NUMBULLET,TRUE) == SFX_ITEM_ON )
    {
        SvxNumBulletItem* pItem = (SvxNumBulletItem*)pOutputSet->GetItem(EE_PARA_NUMBULLET,TRUE);
        SvxNumRule* pRule = pItem->GetNumRule();
        if(pRule)
            pRule->SetFeatureFlag( NUM_NO_NUMBERS, FALSE );
    }

    return pOutputSet;
}

} // end of namespace sd
<|endoftext|>


<commit_before><commit_msg>fdo#39528: do not lose height of tree list box in Navigator<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: unoprnms.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-11-26 20:19:29 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SD_UNOPRNMS_HXX
#define _SD_UNOPRNMS_HXX

#define UNO_NAME_MODEL_LANGUAGE         "CharLocale"
#define UNO_NAME_MODEL_TABSTOP          "TabStop"

#define UNO_NAME_PAGE_BACKGROUND        "Background"
#define UNO_NAME_PAGE_LEFT              "BorderLeft"
#define UNO_NAME_PAGE_RIGHT             "BorderRight"
#define UNO_NAME_PAGE_TOP               "BorderTop"
#define UNO_NAME_PAGE_BOTTOM            "BorderBottom"
#define UNO_NAME_PAGE_CHANGE            "Change"
#define UNO_NAME_PAGE_DURATION          "Duration"
#define UNO_NAME_PAGE_EFFECT            "Effect"
#define UNO_NAME_PAGE_HEIGHT            "Height"
#define UNO_NAME_PAGE_LAYOUT            "Layout"
#define UNO_NAME_PAGE_NUMBER            "Number"
#define UNO_NAME_PAGE_OBJECTS           "Objects"
#define UNO_NAME_PAGE_ORIENTATION       "Orientation"
#define UNO_NAME_PAGE_SPEED             "Speed"
#define UNO_NAME_PAGE_WIDTH             "Width"
#define UNO_NAME_PAGE_PREVIEW           "Preview"
#define UNO_NAME_PAGE_VISIBLE           "Visible"

#define UNO_NAME_OBJ_BOOKMARK           "Bookmark"
#define UNO_NAME_OBJ_DIMCOLOR           "DimColor"
#define UNO_NAME_OBJ_DIMHIDE            "DimHide"
#define UNO_NAME_OBJ_DIMPREV            "DimPrevious"
#define UNO_NAME_OBJ_EFFECT             "Effect"
#define UNO_NAME_OBJ_ISEMPTYPRESOBJ     "IsEmptyPresentationObject"
#define UNO_NAME_OBJ_ISPRESOBJ          "IsPresentationObject"
#define UNO_NAME_OBJ_CLICKACTION        "OnClick"
#define UNO_NAME_OBJ_PLAYFULL           "PlayFull"
#define UNO_NAME_OBJ_PRESORDER          "PresentationOrder"
#define UNO_NAME_OBJ_SOUNDFILE          "Sound"
#define UNO_NAME_OBJ_SOUNDON            "SoundOn"
#define UNO_NAME_OBJ_SPEED              "Speed"
#define UNO_NAME_OBJ_TEXTEFFECT         "TextEffect"
#define UNO_NAME_OBJ_BLUESCREEN         "TransparentColor"
#define UNO_NAME_OBJ_VERB               "Verb"
#define UNO_NAME_OBJ_STYLE              "Style"
#define UNO_NAME_OBJ_MASTERDEPENDENT    "IsPlaceholderDependent"
#define UNO_NAME_OBJ_ANIMATIONPATH      "AnimationPath"

#define UNO_NAME_LAYER_LOCKED           "IsLocked"
#define UNO_NAME_LAYER_PRINTABLE        "IsPrintable"
#define UNO_NAME_LAYER_VISIBLE          "IsVisible"
#define UNO_NAME_LAYER_NAME             "Name"

#define UNO_NAME_SHOW_ALLOWANIM         "AllowAnimations"
#define UNO_NAME_SHOW_CUSTOMSHOW        "CustomShow"
#define UNO_NAME_SHOW_FIRSTPAGE         "FirstPage"
#define UNO_NAME_SHOW_ONTOP             "IsAlwaysOnTop"
#define UNO_NAME_SHOW_AUTOMATIC         "IsAutomatic"
#define UNO_NAME_SHOW_ENDLESS           "IsEndless"
#define UNO_NAME_SHOW_FULLSCREEN        "IsFullScreen"
#define UNO_NAME_SHOW_MOUSEVISIBLE      "IsMouseVisible"
#define UNO_NAME_SHOW_PAGERANGE         "PageRange"
#define UNO_NAME_SHOW_PAUSE             "Pause"
#define UNO_NAME_SHOW_STARTWITHNAV      "StartWithNavigator"
#define UNO_NAME_SHOW_USEPEN            "UsePen"

#define UNO_NAME_SEARCH_BACKWARDS   "SearchBackwards"
#define UNO_NAME_SEARCH_CASE        "SearchCaseSensitive"
#define UNO_NAME_SEARCH_WORDS       "SearchWords"

#define UNO_NAME_LINKDISPLAYNAME                "LinkDisplayName"
#define UNO_NAME_LINKDISPLAYBITMAP              "LinkDisplayBitmap"

#define UNO_NAME_STYLE_FAMILY   "Family"
#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.4.288); FILE MERGED 2005/09/05 13:23:33 rt 1.4.288.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: unoprnms.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 05:59:49 $
 *
 *  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 _SD_UNOPRNMS_HXX
#define _SD_UNOPRNMS_HXX

#define UNO_NAME_MODEL_LANGUAGE         "CharLocale"
#define UNO_NAME_MODEL_TABSTOP          "TabStop"

#define UNO_NAME_PAGE_BACKGROUND        "Background"
#define UNO_NAME_PAGE_LEFT              "BorderLeft"
#define UNO_NAME_PAGE_RIGHT             "BorderRight"
#define UNO_NAME_PAGE_TOP               "BorderTop"
#define UNO_NAME_PAGE_BOTTOM            "BorderBottom"
#define UNO_NAME_PAGE_CHANGE            "Change"
#define UNO_NAME_PAGE_DURATION          "Duration"
#define UNO_NAME_PAGE_EFFECT            "Effect"
#define UNO_NAME_PAGE_HEIGHT            "Height"
#define UNO_NAME_PAGE_LAYOUT            "Layout"
#define UNO_NAME_PAGE_NUMBER            "Number"
#define UNO_NAME_PAGE_OBJECTS           "Objects"
#define UNO_NAME_PAGE_ORIENTATION       "Orientation"
#define UNO_NAME_PAGE_SPEED             "Speed"
#define UNO_NAME_PAGE_WIDTH             "Width"
#define UNO_NAME_PAGE_PREVIEW           "Preview"
#define UNO_NAME_PAGE_VISIBLE           "Visible"

#define UNO_NAME_OBJ_BOOKMARK           "Bookmark"
#define UNO_NAME_OBJ_DIMCOLOR           "DimColor"
#define UNO_NAME_OBJ_DIMHIDE            "DimHide"
#define UNO_NAME_OBJ_DIMPREV            "DimPrevious"
#define UNO_NAME_OBJ_EFFECT             "Effect"
#define UNO_NAME_OBJ_ISEMPTYPRESOBJ     "IsEmptyPresentationObject"
#define UNO_NAME_OBJ_ISPRESOBJ          "IsPresentationObject"
#define UNO_NAME_OBJ_CLICKACTION        "OnClick"
#define UNO_NAME_OBJ_PLAYFULL           "PlayFull"
#define UNO_NAME_OBJ_PRESORDER          "PresentationOrder"
#define UNO_NAME_OBJ_SOUNDFILE          "Sound"
#define UNO_NAME_OBJ_SOUNDON            "SoundOn"
#define UNO_NAME_OBJ_SPEED              "Speed"
#define UNO_NAME_OBJ_TEXTEFFECT         "TextEffect"
#define UNO_NAME_OBJ_BLUESCREEN         "TransparentColor"
#define UNO_NAME_OBJ_VERB               "Verb"
#define UNO_NAME_OBJ_STYLE              "Style"
#define UNO_NAME_OBJ_MASTERDEPENDENT    "IsPlaceholderDependent"
#define UNO_NAME_OBJ_ANIMATIONPATH      "AnimationPath"

#define UNO_NAME_LAYER_LOCKED           "IsLocked"
#define UNO_NAME_LAYER_PRINTABLE        "IsPrintable"
#define UNO_NAME_LAYER_VISIBLE          "IsVisible"
#define UNO_NAME_LAYER_NAME             "Name"

#define UNO_NAME_SHOW_ALLOWANIM         "AllowAnimations"
#define UNO_NAME_SHOW_CUSTOMSHOW        "CustomShow"
#define UNO_NAME_SHOW_FIRSTPAGE         "FirstPage"
#define UNO_NAME_SHOW_ONTOP             "IsAlwaysOnTop"
#define UNO_NAME_SHOW_AUTOMATIC         "IsAutomatic"
#define UNO_NAME_SHOW_ENDLESS           "IsEndless"
#define UNO_NAME_SHOW_FULLSCREEN        "IsFullScreen"
#define UNO_NAME_SHOW_MOUSEVISIBLE      "IsMouseVisible"
#define UNO_NAME_SHOW_PAGERANGE         "PageRange"
#define UNO_NAME_SHOW_PAUSE             "Pause"
#define UNO_NAME_SHOW_STARTWITHNAV      "StartWithNavigator"
#define UNO_NAME_SHOW_USEPEN            "UsePen"

#define UNO_NAME_SEARCH_BACKWARDS   "SearchBackwards"
#define UNO_NAME_SEARCH_CASE        "SearchCaseSensitive"
#define UNO_NAME_SEARCH_WORDS       "SearchWords"

#define UNO_NAME_LINKDISPLAYNAME                "LinkDisplayName"
#define UNO_NAME_LINKDISPLAYBITMAP              "LinkDisplayBitmap"

#define UNO_NAME_STYLE_FAMILY   "Family"
#endif

<|endoftext|>