<commit_before>/*
 * Copyright 2016 Adam Chyła, adam@chyla.org
 * All rights reserved. Distributed under the terms of the MIT License.
 */

#include "network_trainer.h"

#include <patlms/util/run_partially.h>

#include <algorithm>
#include <vector>
#include <fstream>
#include <boost/log/trivial.hpp>

#include "src/bash/analyzer/detail/command_summary_divider/command_summary_divider.h"
#include "src/library/fann/fann_wrapper.h"
#include "src/library/fann/fann_guard.h"

namespace bash
{

namespace analyzer
{

namespace detail
{

namespace network_trainer
{

NetworkTrainerPtr NetworkTrainer::Create(::bash::database::detail::DatabaseFunctionsInterfacePtr database_functions,
                                         ::database::detail::GeneralDatabaseFunctionsInterfacePtr general_database_functions,
                                         const std::string &neural_network_data_directory) {
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::Create: Function call";

  auto fann_wrapper = ::library::fann::FannWrapper::Create();

  return Create(database_functions, general_database_functions, neural_network_data_directory, fann_wrapper);
}

NetworkTrainerPtr NetworkTrainer::Create(::bash::database::detail::DatabaseFunctionsInterfacePtr database_functions,
                                         ::database::detail::GeneralDatabaseFunctionsInterfacePtr general_database_functions,
                                         const std::string &neural_network_data_directory,
                                         ::library::fann::detail::FannWrapperInterfacePtr fann_wrapper) {
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::Create: Function call";

  return NetworkTrainerPtr(new NetworkTrainer(database_functions, general_database_functions, neural_network_data_directory, fann_wrapper));
}

void NetworkTrainer::Train() {
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::Train: Function call";

  auto configurations = database_functions_->GetAnomalyDetectionConfigurations();

  for (const auto &c : configurations) {
    BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::Train: Is configuration changed for agent " << c.agent_name_id << "?: " << c.changed;

    if (c.changed) {
      CreateLearningSetFile(c);
      CreateNetworkConfiguration(c);
    }
  }
}

NetworkTrainer::NetworkTrainer(::bash::database::detail::DatabaseFunctionsInterfacePtr database_functions,
                               ::database::detail::GeneralDatabaseFunctionsInterfacePtr general_database_functions,
                               const std::string &neural_network_data_directory,
                               ::library::fann::detail::FannWrapperInterfacePtr fann_wrapper) :
database_functions_(database_functions),
general_database_functions_(general_database_functions),
neural_network_data_directory_(neural_network_data_directory),
fann_wrapper_(fann_wrapper) {
}

void NetworkTrainer::CreateLearningSetFile(const ::bash::database::type::AnomalyDetectionConfiguration &configuration) {
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Function call";

  auto users = database_functions_->GetUsersIdsFromSelectedDailyStatisticsInConfiguration(configuration.id);

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Found " << users.size() << " users";

  constexpr::database::type::RowsCount MAX_ROWS_IN_MEMORY = 100;
  constexpr unsigned int number_of_inputs = 100;
  unsigned int number_of_outputs = users.size();
  long long learning_set_size = database_functions_->CountSelectedDailyStatisticsWithoutUnknownClassificationInConfiguration(configuration.id);
  std::string file_path = neural_network_data_directory_ + "/training-" + std::to_string(configuration.id) + ".data";

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Number of inputs: " << number_of_inputs;
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Number of outputs: " << number_of_outputs;
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Learning set size: " << learning_set_size;
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Training file path: " << file_path;

  std::vector<double> input;
  input.resize(number_of_inputs, 0);

  std::vector<int> output;
  output.resize(number_of_outputs, -1);

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Opening training file";
  std::fstream file(file_path.c_str(), std::ios::out | std::ios::trunc);

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Writing training data";
  file << learning_set_size << ' ' << number_of_inputs << ' ' << number_of_outputs << '\n';

  auto selected_commands_ids = database_functions_->GetMarkedCommandsIds(configuration.id);
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Found " << selected_commands_ids.size() << " selected commands ids";

  for (const auto &id : selected_commands_ids)
    BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: id: " << id;

  command_summary_divider::CommandSummaryDivider divider;
  unsigned selected_commands_position = 0;
  unsigned commands_statistics_position = 0;
  int user_output_position = 0;
  for (const auto &user_id : users) {
    BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Writing data for user id (from database) " << user_id;

    auto daily_user_statistics_count = database_functions_->CountSelectedDailyUserStatisticsWithoutUnknownClassificationFromConfigurationByUser(configuration.id, user_id);
    BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Found " << daily_user_statistics_count << " daily user statistics";

    util::RunPartially(MAX_ROWS_IN_MEMORY, daily_user_statistics_count, [&](long long part_count, long long offset) {
      auto daily_user_statistics = database_functions_->GetSelectedDailyUserStatisticsWithoutUnknownClassificationFromConfigurationByUser(configuration.id, user_id, part_count, offset);
      BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Found " << daily_user_statistics.size() << " statistics in part";

      for (const auto &statistic : daily_user_statistics) {
        std::fill(input.begin(), input.end(), 0);

        auto commands_statistics = database_functions_->GetSelectedDailyUserCommandsStatistics(statistic.id);
        BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Found " << commands_statistics.size() << " selected daily user commands statistics with statistic id " << statistic.id;

        selected_commands_position = 0;
        commands_statistics_position = 0;
        while (selected_commands_position < selected_commands_ids.size()
            && commands_statistics_position < commands_statistics.size()) {
          const auto &command_statistic = commands_statistics.at(commands_statistics_position);
          BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Position " << selected_commands_position;

          if (command_statistic.command_id == selected_commands_ids.at(selected_commands_position)) {
            BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Found command with id " << command_statistic.command_id;

            input.at(selected_commands_position) = command_statistic.summary;
            commands_statistics_position++;
          }

          selected_commands_position++;
        }

        std::transform(input.begin(), input.end(), input.begin(), divider);

        if (statistic.classification == ::database::type::Classification::ANOMALY)
          output.at(user_output_position) = -1;
        else if (statistic.classification == ::database::type::Classification::NORMAL)
          output.at(user_output_position) = 1;

        BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Classification set: " << output.at(user_output_position);

        BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Saving to file";

        for (const auto &v : input)
          file << v << " ";
        file << '\n';

        for (const auto &v : output)
          file << v << " ";
        file << '\n';
      }
    });

    output.at(user_output_position) = -1;
    user_output_position++;
  }

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Closing training file";
  file.close();

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Done";
}

void NetworkTrainer::CreateNetworkConfiguration(const ::bash::database::type::AnomalyDetectionConfiguration &configuration) {
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateNetworkConfiguration: Done";

  auto users = database_functions_->GetUsersIdsFromSelectedDailyStatisticsInConfiguration(configuration.id);

  constexpr::database::type::RowsCount MAX_ROWS_IN_MEMORY = 100;
  constexpr unsigned int number_of_inputs = 100;
  constexpr unsigned int number_of_layers = 3;
  constexpr unsigned int number_of_hidden_neurons = 3;
  const unsigned int number_of_outputs = users.size();
  constexpr float desired_error = 0.001f;
  constexpr unsigned int max_epochs = 100;
  constexpr unsigned int epochs_between_reports = max_epochs;

  const std::string file_path = neural_network_data_directory_ + "/training-" + std::to_string(configuration.id) + ".data";
  const std::string network_configuration_file_path = neural_network_data_directory_ + "/network-" + std::to_string(configuration.id) + ".data";

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateNetworkConfiguration: Creating network";

  struct fann *ann = fann_wrapper_->CreateStandard(number_of_layers, number_of_inputs, number_of_hidden_neurons, number_of_outputs);
  ::library::fann::FannGuard fann_guard(ann);

  fann_wrapper_->SetActivationFunctionHidden(ann, FANN_SIGMOID);
  fann_wrapper_->SetActivationFunctionOutput(ann, FANN_SIGMOID);

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateNetworkConfiguration: Training network";
  fann_wrapper_->TrainOnFile(ann, file_path, max_epochs, epochs_between_reports, desired_error);

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateNetworkConfiguration: Saving network to file: " << network_configuration_file_path;
  fann_wrapper_->Save(ann, network_configuration_file_path);
}

}

}

}

}
<commit_msg>Mark configuration as unchanged<commit_after>/*
 * Copyright 2016 Adam Chyła, adam@chyla.org
 * All rights reserved. Distributed under the terms of the MIT License.
 */

#include "network_trainer.h"

#include <patlms/util/run_partially.h>

#include <algorithm>
#include <vector>
#include <fstream>
#include <boost/log/trivial.hpp>

#include "src/bash/analyzer/detail/command_summary_divider/command_summary_divider.h"
#include "src/library/fann/fann_wrapper.h"
#include "src/library/fann/fann_guard.h"

namespace bash
{

namespace analyzer
{

namespace detail
{

namespace network_trainer
{

NetworkTrainerPtr NetworkTrainer::Create(::bash::database::detail::DatabaseFunctionsInterfacePtr database_functions,
                                         ::database::detail::GeneralDatabaseFunctionsInterfacePtr general_database_functions,
                                         const std::string &neural_network_data_directory) {
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::Create: Function call";

  auto fann_wrapper = ::library::fann::FannWrapper::Create();

  return Create(database_functions, general_database_functions, neural_network_data_directory, fann_wrapper);
}

NetworkTrainerPtr NetworkTrainer::Create(::bash::database::detail::DatabaseFunctionsInterfacePtr database_functions,
                                         ::database::detail::GeneralDatabaseFunctionsInterfacePtr general_database_functions,
                                         const std::string &neural_network_data_directory,
                                         ::library::fann::detail::FannWrapperInterfacePtr fann_wrapper) {
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::Create: Function call";

  return NetworkTrainerPtr(new NetworkTrainer(database_functions, general_database_functions, neural_network_data_directory, fann_wrapper));
}

void NetworkTrainer::Train() {
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::Train: Function call";

  auto configurations = database_functions_->GetAnomalyDetectionConfigurations();

  for (const auto &c : configurations) {
    BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::Train: Is configuration changed for agent " << c.agent_name_id << "?: " << c.changed;

    if (c.changed) {
      CreateLearningSetFile(c);
      CreateNetworkConfiguration(c);
      database_functions_->MarkConfigurationAsUnchanged(c.id);
    }
  }
}

NetworkTrainer::NetworkTrainer(::bash::database::detail::DatabaseFunctionsInterfacePtr database_functions,
                               ::database::detail::GeneralDatabaseFunctionsInterfacePtr general_database_functions,
                               const std::string &neural_network_data_directory,
                               ::library::fann::detail::FannWrapperInterfacePtr fann_wrapper) :
database_functions_(database_functions),
general_database_functions_(general_database_functions),
neural_network_data_directory_(neural_network_data_directory),
fann_wrapper_(fann_wrapper) {
}

void NetworkTrainer::CreateLearningSetFile(const ::bash::database::type::AnomalyDetectionConfiguration &configuration) {
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Function call";

  auto users = database_functions_->GetUsersIdsFromSelectedDailyStatisticsInConfiguration(configuration.id);

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Found " << users.size() << " users";

  constexpr::database::type::RowsCount MAX_ROWS_IN_MEMORY = 100;
  constexpr unsigned int number_of_inputs = 100;
  unsigned int number_of_outputs = users.size();
  long long learning_set_size = database_functions_->CountSelectedDailyStatisticsWithoutUnknownClassificationInConfiguration(configuration.id);
  std::string file_path = neural_network_data_directory_ + "/training-" + std::to_string(configuration.id) + ".data";

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Number of inputs: " << number_of_inputs;
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Number of outputs: " << number_of_outputs;
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Learning set size: " << learning_set_size;
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Training file path: " << file_path;

  std::vector<double> input;
  input.resize(number_of_inputs, 0);

  std::vector<int> output;
  output.resize(number_of_outputs, -1);

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Opening training file";
  std::fstream file(file_path.c_str(), std::ios::out | std::ios::trunc);

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Writing training data";
  file << learning_set_size << ' ' << number_of_inputs << ' ' << number_of_outputs << '\n';

  auto selected_commands_ids = database_functions_->GetMarkedCommandsIds(configuration.id);
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Found " << selected_commands_ids.size() << " selected commands ids";

  for (const auto &id : selected_commands_ids)
    BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: id: " << id;

  command_summary_divider::CommandSummaryDivider divider;
  unsigned selected_commands_position = 0;
  unsigned commands_statistics_position = 0;
  int user_output_position = 0;
  for (const auto &user_id : users) {
    BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Writing data for user id (from database) " << user_id;

    auto daily_user_statistics_count = database_functions_->CountSelectedDailyUserStatisticsWithoutUnknownClassificationFromConfigurationByUser(configuration.id, user_id);
    BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Found " << daily_user_statistics_count << " daily user statistics";

    util::RunPartially(MAX_ROWS_IN_MEMORY, daily_user_statistics_count, [&](long long part_count, long long offset) {
      auto daily_user_statistics = database_functions_->GetSelectedDailyUserStatisticsWithoutUnknownClassificationFromConfigurationByUser(configuration.id, user_id, part_count, offset);
      BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Found " << daily_user_statistics.size() << " statistics in part";

      for (const auto &statistic : daily_user_statistics) {
        std::fill(input.begin(), input.end(), 0);

        auto commands_statistics = database_functions_->GetSelectedDailyUserCommandsStatistics(statistic.id);
        BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Found " << commands_statistics.size() << " selected daily user commands statistics with statistic id " << statistic.id;

        selected_commands_position = 0;
        commands_statistics_position = 0;
        while (selected_commands_position < selected_commands_ids.size()
            && commands_statistics_position < commands_statistics.size()) {
          const auto &command_statistic = commands_statistics.at(commands_statistics_position);
          BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Position " << selected_commands_position;

          if (command_statistic.command_id == selected_commands_ids.at(selected_commands_position)) {
            BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Found command with id " << command_statistic.command_id;

            input.at(selected_commands_position) = command_statistic.summary;
            commands_statistics_position++;
          }

          selected_commands_position++;
        }

        std::transform(input.begin(), input.end(), input.begin(), divider);

        if (statistic.classification == ::database::type::Classification::ANOMALY)
          output.at(user_output_position) = -1;
        else if (statistic.classification == ::database::type::Classification::NORMAL)
          output.at(user_output_position) = 1;

        BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Classification set: " << output.at(user_output_position);

        BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Saving to file";

        for (const auto &v : input)
          file << v << " ";
        file << '\n';

        for (const auto &v : output)
          file << v << " ";
        file << '\n';
      }
    });

    output.at(user_output_position) = -1;
    user_output_position++;
  }

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Closing training file";
  file.close();

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateLearningSetFile: Done";
}

void NetworkTrainer::CreateNetworkConfiguration(const ::bash::database::type::AnomalyDetectionConfiguration &configuration) {
  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateNetworkConfiguration: Done";

  auto users = database_functions_->GetUsersIdsFromSelectedDailyStatisticsInConfiguration(configuration.id);

  constexpr::database::type::RowsCount MAX_ROWS_IN_MEMORY = 100;
  constexpr unsigned int number_of_inputs = 100;
  constexpr unsigned int number_of_layers = 3;
  constexpr unsigned int number_of_hidden_neurons = 3;
  const unsigned int number_of_outputs = users.size();
  constexpr float desired_error = 0.001f;
  constexpr unsigned int max_epochs = 100;
  constexpr unsigned int epochs_between_reports = max_epochs;

  const std::string file_path = neural_network_data_directory_ + "/training-" + std::to_string(configuration.id) + ".data";
  const std::string network_configuration_file_path = neural_network_data_directory_ + "/network-" + std::to_string(configuration.id) + ".data";

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateNetworkConfiguration: Creating network";

  struct fann *ann = fann_wrapper_->CreateStandard(number_of_layers, number_of_inputs, number_of_hidden_neurons, number_of_outputs);
  ::library::fann::FannGuard fann_guard(ann);

  fann_wrapper_->SetActivationFunctionHidden(ann, FANN_SIGMOID);
  fann_wrapper_->SetActivationFunctionOutput(ann, FANN_SIGMOID);

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateNetworkConfiguration: Training network";
  fann_wrapper_->TrainOnFile(ann, file_path, max_epochs, epochs_between_reports, desired_error);

  BOOST_LOG_TRIVIAL(debug) << "bash::analyzer::detail::network_trainer::NetworkTrainer::CreateNetworkConfiguration: Saving network to file: " << network_configuration_file_path;
  fann_wrapper_->Save(ann, network_configuration_file_path);
}

}

}

}

}
<|endoftext|>


<commit_before>#pragma once

#include "wrd-deps.hpp"

//	World는 객체 안에서 다른 객체에 접근하는 접근자함수들에 경우에는 DelayingNullCorruption으로 인해 객체가 Null이라고 해도 Null을 반환할뿐 프로그램이 죽지는 않는다.
//	접근자 아닌 경우에는 "속도문제" 로 인해 수행하지 않는다.
//	또한 반환형이 객체에 대한 레퍼런스나 포인터가 아닌경우에도 정상적인 반환값과 겹칠 수있기 때문에 체크하지 않는다.
#define WRD_IS_NULL_2(VALUE, RET)	\
	if((VALUE.isNull())) {			\
		RET.warn(#VALUE);			\
		return RET;					\
	}
#define WRD_IS_NULL_1(VALUE)		\
	WRD_IS_NULL_2(VALUE, NullPtr)
#define WRD_IS_NULL(...) WRD_OVERLOAD(WRD_IS_NULL, __VA_ARGS__)

//	multiple NULL check macro:
//		if you need to check plenty arguments to be checked null
//		and return value will be same, you can accomplish it conveniently
//		with this macro.
//
//		usage:
//			WRD_IS_NULL(arg1, -1)
//			WRD_IS_NULL(arg2, -1)
//			WRD_IS_NULL(arg3, -1)
//				or
//			WRD_ARE_NULL(-1, arg1, arg2, arg3)
#define _ARE_NULL(VALUE, RET)		WRD_IS_NULL(VALUE, RET)
#define WRD_ARE_NULL(RET, ...)		NE_EACH_EXPAND(_ARE_NULL, RET, __VA_ARGS__)

#define WRD_IS_THIS_1(TYPE)			WRD_IS_NULL(*this, Nuller<Type>::ref)
#define WRD_IS_THIS_0()				WRD_IS_THIS_1(This)
#define WRD_IS_THIS(...) 			WRD_OVERLOAD(WRD_IS_THIS, __VA_ARGS__)

#define WRD_IS_SUPER_1(call)        \
    if(Super:: call ) return SuperFail;
#define WRD_IS_SUPER_2(res, call)  \
    Result& res = Super:: call ;    \
    if(res) return SuperFail;
#define WRD_IS_SUPER(...)          WRD_OVERLOAD(WRD_IS_SUPER, __VA_ARGS__)

#define WRD_IS_CONST(RET)			\
	if((this->isConst())) {			\
		ConstCancel.warn(#RET);		\
		return RET;					\
	}

#define WRD_ASSERT_4(expr, ret, dump, msg)  \
    if( (expr) )                            \
        return ret.dump(msg);
#define WRD_ASSERT_3(expr, ret, msg)		WRD_ASSERT_4(expr, ret, warn, msg)
#define WRD_ASSERT_2(expr, ret)				WRD_ASSERT_4(expr, ret, warn, "")
#define WRD_ASSERT_1(expr)                  WRD_ASSERT_4(expr, Invalid, warn, "")
#define WRD_ASSERT(...)                    	WRD_OVERLOAD(WRD_ASSERT, __VA_ARGS__)

#define WRD_IS_RES_5(expr, ret, chk, dump, msg) \
    {                                          	\
        const Result& res = expr;              	\
        WRD_ASSERT(res.chk, ret, dump, msg)    	\
   }
#define WRD_IS_RES_4(expr, chk, dump, msg)  WRD_IS_RES_5(expr, res, chk, dump, msg)
#define WRD_IS_RES_3(expr, chk, msg)        WRD_IS_RES_5(expr, res, chk, warn, msg)
#define WRD_IS_RES_2(expr, chk)            	WRD_IS_RES_5(expr, res, chk, warn, #expr)
#define WRD_IS_RES(...)                    	WRD_OVERLOAD(WRD_IS_RES, __VA_ARGS__)

#define WRD_IS_WARN_3(expr, ret, msg)      	WRD_IS_RES(expr, ret, isWarn(), warn, msg)
#define WRD_IS_WARN_2(expr, ret)            WRD_IS_RES(expr, ret, isWarn(), warn, #expr)
#define WRD_IS_WARN_1(expr)                	WRD_IS_RES(expr, isWarn())
#define WRD_IS_WARN(...)                    WRD_OVERLOAD(WRD_IS_WARN, __VA_ARGS__)

#define WRD_IS_ERR_3(expr, ret, msg)        WRD_IS_RES(expr, ret, isErr(), err, msg)
#define WRD_IS_ERR_2(expr, ret)            	WRD_IS_RES(expr, ret, isErr(), err, #expr)
#define WRD_IS_ERR_1(expr)                  WRD_IS_RES(expr, isErr())
#define WRD_IS_ERR(...)                    	WRD_OVERLOAD(WRD_IS_ERR, __VA_ARGS__)
#define WRD_IS_GOOD_3(expr, ret, msg)      	WRD_IS_RES(expr, ret, isGood(), info, msg)
#define WRD_IS_GOOD_2(expr, ret)            WRD_IS_RES(expr, ret, isGood(), info, #expr)
#define WRD_IS_GOOD_1(expr)              	WRD_IS_RES(expr, isGood())
#define WRD_IS_GOOD(...)                    WRD_OVERLOAD(WRD_IS_GOOD, __VA_ARGS__)

#define _CLASS_BASE					\
    public:							\
        virtual WRD_LAZY_METHOD(Class&, getClass, const, TClass<This>, WRD_VOID) \
        TStrong<This> clone() const { return _clone(); } \
		virtual TStrong<Instance> _clone() const { \
			return new This(*this);	\
		}
#define WRD_CLASS_2(THIS, SUPER)  	\
    WRD_INHERIT(THIS, SUPER)      	\
    _CLASS_BASE
#define WRD_CLASS_1(THIS)			\
    WRD_INHERIT(THIS)				\
    _CLASS_BASE
#define WRD_CLASS(...) WRD_OVERLOAD(WRD_CLASS, __VA_ARGS__)
<commit_msg>- [wrd] fix macro has not been declared error.<commit_after>#pragma once

#include "wrd-deps.hpp"

//	World는 객체 안에서 다른 객체에 접근하는 접근자함수들에 경우에는 DelayingNullCorruption으로 인해 객체가 Null이라고 해도 Null을 반환할뿐 프로그램이 죽지는 않는다.
//	접근자 아닌 경우에는 "속도문제" 로 인해 수행하지 않는다.
//	또한 반환형이 객체에 대한 레퍼런스나 포인터가 아닌경우에도 정상적인 반환값과 겹칠 수있기 때문에 체크하지 않는다.
#define WRD_IS_NULL_2(VALUE, RET)	\
	if((VALUE.isNull())) {			\
		RET.warn(#VALUE);			\
		return RET;					\
	}
#define WRD_IS_NULL_1(VALUE)		\
	WRD_IS_NULL_2(VALUE, NullPtr)
#define WRD_IS_NULL(...) WRD_OVERLOAD(WRD_IS_NULL, __VA_ARGS__)

//	multiple NULL check macro:
//		if you need to check plenty arguments to be checked null
//		and return value will be same, you can accomplish it conveniently
//		with this macro.
//
//		usage:
//			WRD_IS_NULL(arg1, -1)
//			WRD_IS_NULL(arg2, -1)
//			WRD_IS_NULL(arg3, -1)
//				or
//			WRD_ARE_NULL(-1, arg1, arg2, arg3)
#define _ARE_NULL(VALUE, RET)		WRD_IS_NULL(VALUE, RET)
#define WRD_ARE_NULL(RET, ...)		NE_EACH_EXPAND(_ARE_NULL, RET, __VA_ARGS__)

#define WRD_IS_THIS_1(TYPE)			WRD_IS_NULL(*this, Nuller<Type>::ref)
#define WRD_IS_THIS_0()				WRD_IS_THIS_1(This)
#define WRD_IS_THIS(...) 			WRD_OVERLOAD(WRD_IS_THIS, __VA_ARGS__)

#define WRD_IS_SUPER_1(call)        \
    if(Super:: call ) return SuperFail;
#define WRD_IS_SUPER_2(res, call)  \
    Result& res = Super:: call ;    \
    if(res) return SuperFail;
#define WRD_IS_SUPER(...)          WRD_OVERLOAD(WRD_IS_SUPER, __VA_ARGS__)

#define WRD_IS_CONST(RET)			\
	if((this->isConst())) {			\
		ConstCancel.warn(#RET);		\
		return RET;					\
	}

#define WRD_ASSERT_4(expr, ret, dump, msg)  \
    if( (expr) )                            \
        return ret.dump(msg);
#define WRD_ASSERT_3(expr, ret, msg)		WRD_ASSERT_4(expr, ret, warn, msg)
#define WRD_ASSERT_2(expr, ret)				WRD_ASSERT_4(expr, ret, warn, "")
#define WRD_ASSERT_1(expr)                  WRD_ASSERT_4(expr, Invalid, warn, "")
#define WRD_ASSERT(...)                    	WRD_OVERLOAD(WRD_ASSERT, __VA_ARGS__)

#define WRD_IS_RES_5(expr, ret, chk, dump, msg) \
    {                                          	\
        const Result& res = expr;              	\
        WRD_ASSERT(res.chk, ret, dump, msg)    	\
   }
#define WRD_IS_RES_4(expr, chk, dump, msg)  WRD_IS_RES_5(expr, res, chk, dump, msg)
#define WRD_IS_RES_3(expr, chk, msg)        WRD_IS_RES_5(expr, res, chk, warn, msg)
#define WRD_IS_RES_2(expr, chk)            	WRD_IS_RES_5(expr, res, chk, warn, #expr)
#define WRD_IS_RES(...)                    	WRD_OVERLOAD(WRD_IS_RES, __VA_ARGS__)

#define WRD_IS_WARN_3(expr, ret, msg)      	WRD_IS_RES(expr, ret, isWarn(), warn, msg)
#define WRD_IS_WARN_2(expr, ret)            WRD_IS_RES(expr, ret, isWarn(), warn, #expr)
#define WRD_IS_WARN_1(expr)                	WRD_IS_RES(expr, isWarn())
#define WRD_IS_WARN(...)                    WRD_OVERLOAD(WRD_IS_WARN, __VA_ARGS__)

#define WRD_IS_ERR_3(expr, ret, msg)        WRD_IS_RES(expr, ret, isErr(), err, msg)
#define WRD_IS_ERR_2(expr, ret)            	WRD_IS_RES(expr, ret, isErr(), err, #expr)
#define WRD_IS_ERR_1(expr)                  WRD_IS_RES(expr, isErr())
#define WRD_IS_ERR(...)                    	WRD_OVERLOAD(WRD_IS_ERR, __VA_ARGS__)
#define WRD_IS_GOOD_3(expr, ret, msg)      	WRD_IS_RES(expr, ret, isGood(), info, msg)
#define WRD_IS_GOOD_2(expr, ret)            WRD_IS_RES(expr, ret, isGood(), info, #expr)
#define WRD_IS_GOOD_1(expr)              	WRD_IS_RES(expr, isGood())
#define WRD_IS_GOOD(...)                    WRD_OVERLOAD(WRD_IS_GOOD, __VA_ARGS__)

#define _CLASS_BASE					\
    public:							\
        virtual WRD_LAZY_METHOD_5(Class&, getClass, const, TClass<This>, WRD_VOID) \
        TStrong<This> clone() const { return _clone(); } \
		virtual TStrong<Instance> _clone() const { \
			return new This(*this);	\
		}
#define WRD_CLASS_2(THIS, SUPER)  	\
    WRD_INHERIT_2(THIS, SUPER)     	\
    _CLASS_BASE
#define WRD_CLASS_1(THIS)			\
    WRD_INHERIT_1(THIS)				\
    _CLASS_BASE
#define WRD_CLASS(...) WRD_OVERLOAD(WRD_CLASS, __VA_ARGS__)
<|endoftext|>


<commit_before>#pragma once

#include <xyz/openbmc_project/Sensor/Value/server.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
#include <sdbusplus/server.hpp>

template <typename T>
using ServerObject = typename sdbusplus::server::object::object<T>;

using ValueInterface = sdbusplus::xyz::openbmc_project::Sensor::server::Value;
using ValueObject = ServerObject<ValueInterface>;
using WarningInterface =
    sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning;
using WarningObject = ServerObject<WarningInterface>;
using CriticalInterface =
    sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical;
using CriticalObject = ServerObject<CriticalInterface>;

enum class InterfaceType
{
    VALUE,
    WARN,
    CRIT,
};

// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
<commit_msg>Fix sdbusplus::server::object template wrapper<commit_after>#pragma once

#include <xyz/openbmc_project/Sensor/Value/server.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
#include <sdbusplus/server.hpp>

template <typename... T>
using ServerObject = typename sdbusplus::server::object::object<T...>;

using ValueInterface = sdbusplus::xyz::openbmc_project::Sensor::server::Value;
using ValueObject = ServerObject<ValueInterface>;
using WarningInterface =
    sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning;
using WarningObject = ServerObject<WarningInterface>;
using CriticalInterface =
    sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical;
using CriticalObject = ServerObject<CriticalInterface>;

enum class InterfaceType
{
    VALUE,
    WARN,
    CRIT,
};

// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
<|endoftext|>


<commit_before>/*
 * CommunityDetectionBenchmark.h
 *
 *  Created on: 16.05.2014
 *      Author: Klara Reichard (klara.reichard@gmail.com), Marvin Ritter (marvin.ritter@gmail.com)
 */

#ifndef NOGTEST

#include <map>

#include "CommunityDetectionBenchmark.h"
#include "../PLP.h"
#include "../PLM.h"
#include "../Modularity.h"
#include "../../centrality/Betweenness.h"
#include "../../centrality/PageRank.h"
#include "../../auxiliary/Timer.h"
#include "../../structures/Partition.h"

namespace NetworKit {

void CommunityDetectionBenchmark::SetUp() {

}

TEST_F(CommunityDetectionBenchmark, timeClusteringAlgos) {
	Aux::Timer timer;
	Modularity mod;

	// std::string graph = "../graphs/uk-2002.graph";
	std::string graph = "../graphs/uk-2007-05.graph";
	printf("Reading graph file %s ...\n", graph.c_str());
	timer.start();
	const Graph G = this->metisReader.read(graph);
	timer.stop();
	printf("Reading graph took %.1f s\n", timer.elapsedMilliseconds() / 1000.0);

	std::map<std::string, CommunityDetectionAlgorithm*> algos = {
		std::make_pair("Parallel Label Propagation", (CommunityDetectionAlgorithm*) new PLP),
		std::make_pair("Parallel Louvain", (CommunityDetectionAlgorithm*) new PLM)
	};

	for (auto it = algos.begin(); it != algos.end(); it++) {
		Graph Gcopy = G;

		printf("Timing %s ...\n", it->first.c_str());
		timer.start();
		Partition zeta = it->second->run(Gcopy);
		timer.stop();

		auto communitySizes = zeta.subsetSizes();

		printf("%s on %s: %.1f s\n\t# communities: %llu\n\tmodularity: %f\n",
			it->first.c_str(), graph.c_str(),
			timer.elapsedMilliseconds() / 1000.0,
			zeta.numberOfSubsets(),
			mod.getQuality(zeta, G));

		delete it->second;
	}
}

TEST_F(CommunityDetectionBenchmark, timeCentralities) {
	Aux::Timer timer;

	std::string graph = "../graphs/cond-mat-2005.graph";
	const Graph G = this->metisReader.read(graph);

	Graph G1 = this->metisReader.read("../graphs/cond-mat.graph");
	Graph G2 = this->metisReader.read("../graphs/uk-2002.graph");
	std::map<std::string, Centrality*> cens = {
		std::make_pair("Betweenness Centrality on cond-mat", (Centrality*) new Betweenness(G1)),
		std::make_pair("Page Rank Centrality on uk-2002", (Centrality*) new PageRank(G2, 1e-6))
	};

	for (auto it = cens.begin(); it != cens.end(); it++) {
		timer.start();
		it->second->run();
		timer.stop();
		auto ranking = it->second->ranking();

		printf("%s: %.1f s\n\tranking: [(%llu: %f), (%llu: %f), ...]\n",
			it->first.c_str(),
			timer.elapsedMilliseconds() / 1000.0,
			ranking[0].first, ranking[0].second,
			ranking[1].first, ranking[1].second);
	}
}

} /* namespace NetworKit */

#endif /*NOGTEST */
<commit_msg>updated benchmark to make multiple runs<commit_after>/*
 * CommunityDetectionBenchmark.h
 *
 *  Created on: 16.05.2014
 *      Author: Klara Reichard (klara.reichard@gmail.com), Marvin Ritter (marvin.ritter@gmail.com)
 */

#ifndef NOGTEST

#include <map>
#include <functional>

#include "CommunityDetectionBenchmark.h"
#include "../PLP.h"
#include "../PLM.h"
#include "../Modularity.h"
#include "../../centrality/Betweenness.h"
#include "../../centrality/PageRank.h"
#include "../../auxiliary/Timer.h"
#include "../../structures/Partition.h"

namespace NetworKit {

constexpr int runs = 20;

void CommunityDetectionBenchmark::SetUp() {

}

TEST_F(CommunityDetectionBenchmark, timeClusteringAlgos) {
	Aux::Timer timer;
	Modularity mod;

	// std::string graph = "../graphs/in-2004.graph";
	// std::string graph = "../graphs/uk-2002.graph";
	std::string graph = "../graphs/uk-2007-05.graph";

	printf("Reading graph file %s ...\n", graph.c_str());
	timer.start();
	const Graph G = this->metisReader.read(graph);
	timer.stop();
	printf("Reading graph took %.1f s\n", timer.elapsedMilliseconds() / 1000.0);

	for (int r = 0; r < runs; r++) {
		Graph Gcopy = G;
		PLP algo;

		timer.start();
		Partition zeta = algo.run(Gcopy);
		timer.stop();

		auto communitySizes = zeta.subsetSizes();

		printf("%s on %s: %.1f s\n\t# communities: %lu\n\tmodularity: %f\n",
			"Parallel Label Propagation", graph.c_str(),
			timer.elapsedMilliseconds() / 1000.0,
			zeta.numberOfSubsets(),
			mod.getQuality(zeta, G));
	}

	for (int r = 0; r < runs; r++) {
		Graph Gcopy = G;
		PLM algo;

		timer.start();
		Partition zeta = algo.run(Gcopy);
		timer.stop();

		auto communitySizes = zeta.subsetSizes();

		printf("%s on %s: %.1f s\n\t# communities: %lu\n\tmodularity: %f\n",
			"Parallel Louvain", graph.c_str(),
			timer.elapsedMilliseconds() / 1000.0,
			zeta.numberOfSubsets(),
			mod.getQuality(zeta, G));
	}
}

TEST_F(CommunityDetectionBenchmark, timePageRankCentrality) {
	Aux::Timer timer;

	std::string graph = "../graphs/uk-2002.graph";
	const Graph G = this->metisReader.read(graph);

	for (int r = 0; r < runs; r++) {
		PageRank cen(G, 1e-6);

		timer.start();
		cen.run();
		timer.stop();
		auto ranking = cen.ranking();

		printf("%s on %s: %.1f s\n\tranking: [(%lu: %f), (%lu: %f), ...]\n",
			"Page Rank Centrality", graph.c_str(),
			timer.elapsedMilliseconds() / 1000.0,
			ranking[0].first, ranking[0].second,
			ranking[1].first, ranking[1].second,
			ranking[2].first, ranking[2].second);
	}
}

TEST_F(CommunityDetectionBenchmark, timeBetweennessCentrality) {
	Aux::Timer timer;

	std::string graph = "../graphs/cond-mat-2005.graph";
	const Graph G = this->metisReader.read(graph);

	for (int r = 0; r < runs; r++) {
		Betweenness cen(G);

		timer.start();
		cen.run();
		timer.stop();
		auto ranking = cen.ranking();

		printf("%s on %s: %.1f s\n\tranking: [(%lu: %f), (%lu: %f), ...]\n",
			"Betweenness Centrality", graph.c_str(),
			timer.elapsedMilliseconds() / 1000.0,
			ranking[0].first, ranking[0].second,
			ranking[1].first, ranking[1].second,
			ranking[2].first, ranking[2].second);
	}
}

} /* namespace NetworKit */

#endif /*NOGTEST */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: testshl_test.cxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: lla $ $Date: 2003-01-09 11:06:19 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>

#ifdef WNT
// #define UNDER_WINDOWS_DEBUGGING
// Nice feature, to debug under windows, install msdev locally and use DebugBreak() to stop a new process at a point you want.
#ifdef UNDER_WINDOWS_DEBUGGING
#include <tools/presys.h>
#include <windows.h>
#include <tools/postsys.h>

#define VCL_NEED_BASETSD

#endif /* UNDER_WINDOWS_DEBUGGING */
#endif /* WNT */

#include <vector>

#ifndef _SAL_TRES_H_
#include <rtl/tres.h>
#endif

#ifndef _TESTSHL_TSTMGR_H_
#include "tstmgr.h"
#endif

#ifndef _RTL_STRING_HXX_
    #include <rtl/string.hxx>
#endif

#include <osl/time.h>

using namespace std;

/**
 * create bitmap of comandline parameters
 */
sal_uInt32 createFlags( vector< sal_Char* > const& cmdln )
{
    sal_uInt32 retflags = rtl_tres_Flag_OK;

    vector< sal_Char* >::const_iterator iter = cmdln.begin();
    while( iter != cmdln.end() )
    {
        fprintf( stderr, "%s\n", *iter );
        if ( *iter[0] == '-' )
        {
            rtl::OString item( *iter );
            if ( item == "-boom" )
                retflags |= rtl_tres_Flag_BOOM;

            if ( item == "-verbose" )
                retflags |= rtl_tres_Flag_VERBOSE;

            if ( item == "-skip" )
                retflags |= rtl_tres_Flag_SKIP;

            if ( item == "-log" )
                retflags |= rtl_tres_Flag_LOG;

            if ( item == "-his" )
                retflags |= rtl_tres_Flag_HIS;

            if ( item == "-time" )
                retflags |= rtl_tres_Flag_TIME;

            if ( item == "-msg" )
                retflags |= rtl_tres_Flag_MSG;
        }
        iter++;
    }

    return retflags;
}

sal_uInt32 createFlags(int argc, char* argv[])
{
    vector< sal_Char* > cmdln;
    sal_Int32 i;

     /* collect comandline */
    for ( i = 1; i < argc; i++ )
         cmdln.push_back( argv[i] );

    return createFlags(cmdln);
}

// -----------------------------------------------------------------------------

/**
 * display usage screen
 */

void usage()
{
    fprintf( stdout,
            "USAGE: testshl shlname scename [-boom][-verbose][-log][-his][-msg]\n" );
    exit(0);
}

#include <fstream>
#include <cppunit/TestFixture.h>
#include <cppunit/TestCaller.h>
#include <cppunit/TestSuite.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestAssert.h>
#include <cppunit/TextTestResult.h>

namespace CppunitTest
{
    class AStringTest : public CppUnit::TestCase
    {
        rtl::OString *m_pStr;
    public:
        AStringTest()
            :m_pStr(NULL) {}

        void setUp()
            {
                m_pStr = new rtl::OString("test1");
                // throw std::exception("initialization failed.");
            }

        void tearDown()
            {
                delete m_pStr;
            }

        void testEquality()
            {
                CPPUNIT_ASSERT( *m_pStr == "test1" );
                CPPUNIT_ASSERT( (*m_pStr).equalsIgnoreAsciiCase("Test1") );
                CPPUNIT_ASSERT( (*m_pStr).equalsIgnoreAsciiCase("Test2") );
                CPPUNIT_ASSERT( *m_pStr == "test1" );
                CPPUNIT_ASSERT( *m_pStr == "must also fail" );
            }
        void testEquality2()
            {
                rtl::OString aStr("test2");
                CPPUNIT_ASSERT( aStr == "test2" );
                CPPUNIT_ASSERT_MESSAGE("ein vergleichstest", aStr == "test2");
                CPPUNIT_ASSERT( aStr == "must also fail" );
            }
        void testThrow()
            {
                throw std::exception("an own exception!");
                CPPUNIT_ASSERT( *m_pStr == "test2" );
            }
    };

    CppUnit::TestSuite *suite1()
    {
        CppUnit::TestSuite *suite = new CppUnit::TestSuite( "AStringTest" );

        // CppUnit::TestSuite suite;
        // CppUnit::TextTestResult result;

        suite->addTest( new CppUnit::TestCaller<AStringTest>( "throw test", &AStringTest::testThrow ));
//      suite->addTest( new CppUnit::TestCaller<AStringTest>( "test op eq", &AStringTest::testEquality ));
//      suite->addTest( new CppUnit::TestCaller<AStringTest>( "test op eq", &AStringTest::testEquality2 ));

        return suite;
    }

    // -----------------------------------------------------------------------------

    class ASimpleTest : public CppUnit::TestCase
    {
    public:
        void testEqual()
            {
                CPPUNIT_ASSERT( 1 == 1 );
            }
    };

    CppUnit::TestSuite *suite2()
    {
        CppUnit::TestSuite *suite = new CppUnit::TestSuite( "A simple test" );

        // CppUnit::TestSuite suite;
        // CppUnit::TextTestResult result;

        suite->addTest( new CppUnit::TestCaller<ASimpleTest>( "1 == 1", &ASimpleTest::testEqual ));

        return suite;
    }

    // -----------------------------------------------------------------------------

    CppUnit::TestSuite *suite()
    {
        CppUnit::TestSuite *suite = new CppUnit::TestSuite( "A simple test" );

        // CppUnit::TestSuite suite;
        // CppUnit::TextTestResult result;

        suite->addTest( suite1() );
//      suite->addTest( suite2() );

        return suite;
    }
}

void cppunitbased_test()
{
    {
        // ofstream out("c:\\temp\\output.txt", ios::out);
        CppUnit::TextTestResult aResult;

        CppUnit::TestSuite* pSuite = CppunitTest::suite();

        int nTests = pSuite->countTestCases();
        pSuite->run(&aResult);

        // aResult.print(out);
        cout << aResult;

        delete pSuite;
    }

    exit(1);
}

// ----------------------------------- Main -----------------------------------
#if (defined UNX) || (defined OS2)
int main( int argc, char* argv[] )
#else
int _cdecl main( int argc, char* argv[] )
#endif
{
    cppunitbased_test();

    tslTestManager hMgr = 0;

    /* show usage screen if too less parameters */
    if ( argc < 3 )
        usage();

#ifdef UNDER_WINDOWS_DEBUGGING
    DebugBreak();
#endif

    sal_uInt32 nCmdlinebitflags = createFlags( argc, argv );

    hMgr = tsl_TestManager_create( argv, argc, nCmdlinebitflags );
    tsl_TestManager_run( hMgr );
    tsl_TestManager_destroy( hMgr );
    return 0;
}
<commit_msg>INTEGRATION: CWS qadev16 (1.1.54); FILE MERGED 2004/02/10 15:06:52 lla 1.1.54.1: #114786# changes to internal tests.<commit_after>/*************************************************************************
 *
 *  $RCSfile: testshl_test.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2004-03-19 14:43:41 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>

#ifdef WNT
// #define UNDER_WINDOWS_DEBUGGING
// Nice feature, to debug under windows, install msdev locally and use DebugBreak() to stop a new process at a point you want.
#ifdef UNDER_WINDOWS_DEBUGGING
#include <tools/presys.h>
#include <windows.h>
#include <tools/postsys.h>

#define VCL_NEED_BASETSD

#endif /* UNDER_WINDOWS_DEBUGGING */
#endif /* WNT */

#include <vector>

#ifndef _SAL_TRES_H_
#include <rtl/tres.h>
#endif

#ifndef _TESTSHL_TSTMGR_H_
#include "tstmgr.h"
#endif

#ifndef _RTL_STRING_HXX_
    #include <rtl/string.hxx>
#endif

#include <osl/time.h>

using namespace std;

/**
 * create bitmap of comandline parameters
 */
sal_uInt32 createFlags( vector< sal_Char* > const& cmdln )
{
    sal_uInt32 retflags = rtl_tres_Flag_OK;

    vector< sal_Char* >::const_iterator iter = cmdln.begin();
    while( iter != cmdln.end() )
    {
        fprintf( stderr, "%s\n", *iter );
        if ( *iter[0] == '-' )
        {
            rtl::OString item( *iter );
            if ( item == "-boom" )
                retflags |= rtl_tres_Flag_BOOM;

            if ( item == "-verbose" )
                retflags |= rtl_tres_Flag_VERBOSE;

            if ( item == "-skip" )
                retflags |= rtl_tres_Flag_SKIP;

            if ( item == "-log" )
                retflags |= rtl_tres_Flag_LOG;

            if ( item == "-his" )
                retflags |= rtl_tres_Flag_HIS;

            if ( item == "-time" )
                retflags |= rtl_tres_Flag_TIME;

            if ( item == "-msg" )
                retflags |= rtl_tres_Flag_MSG;

            if ( item == "-quiet" )
                retflags |= rtl_tres_Flag_QUIET;
        }
        iter++;
    }

    return retflags;
}

sal_uInt32 createFlags(int argc, char* argv[])
{
    vector< sal_Char* > cmdln;
    sal_Int32 i;

     /* collect comandline */
    for ( i = 1; i < argc; i++ )
         cmdln.push_back( argv[i] );

    return createFlags(cmdln);
}

// -----------------------------------------------------------------------------

/**
 * display usage screen
 */

void usage()
{
    fprintf( stdout,
            "USAGE: testshl shlname scename [-boom][-verbose][-log][-his][-msg]\n" );
    exit(0);
}

#include <fstream>
#include <cppunit/TestFixture.h>
#include <cppunit/TestCaller.h>
#include <cppunit/TestSuite.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestAssert.h>
#include <cppunit/TextTestResult.h>

namespace CppunitTest
{
    class AStringTest : public CppUnit::TestCase
    {
        rtl::OString *m_pStr;
    public:
        AStringTest()
            :m_pStr(NULL) {}

        void setUp()
            {
                m_pStr = new rtl::OString("test1");
                // throw std::exception("initialization failed.");
            }

        void tearDown()
            {
                delete m_pStr;
            }

        void testEquality()
            {
                CPPUNIT_ASSERT( *m_pStr == "test1" );
                CPPUNIT_ASSERT( (*m_pStr).equalsIgnoreAsciiCase("Test1") );
                CPPUNIT_ASSERT( (*m_pStr).equalsIgnoreAsciiCase("Test2") );
                CPPUNIT_ASSERT( *m_pStr == "test1" );
                CPPUNIT_ASSERT( *m_pStr == "must also fail" );
            }
        void testEquality2()
            {
                rtl::OString aStr("test2");
                CPPUNIT_ASSERT( aStr == "test2" );
                CPPUNIT_ASSERT_MESSAGE("ein vergleichstest", aStr == "test2");
                CPPUNIT_ASSERT( aStr == "must also fail" );
            }
        void testThrow()
            {
                throw std::exception("an own exception!");
                CPPUNIT_ASSERT( *m_pStr == "test2" );
            }
    };

    CppUnit::TestSuite *suite1()
    {
        CppUnit::TestSuite *suite = new CppUnit::TestSuite( "AStringTest" );

        // CppUnit::TestSuite suite;
        // CppUnit::TextTestResult result;

        suite->addTest( new CppUnit::TestCaller<AStringTest>( "throw test", &AStringTest::testThrow ));
//      suite->addTest( new CppUnit::TestCaller<AStringTest>( "test op eq", &AStringTest::testEquality ));
//      suite->addTest( new CppUnit::TestCaller<AStringTest>( "test op eq", &AStringTest::testEquality2 ));

        return suite;
    }

    // -----------------------------------------------------------------------------

    class ASimpleTest : public CppUnit::TestCase
    {
    public:
        void testEqual()
            {
                CPPUNIT_ASSERT( 1 == 1 );
            }
    };

    CppUnit::TestSuite *suite2()
    {
        CppUnit::TestSuite *suite = new CppUnit::TestSuite( "A simple test" );

        // CppUnit::TestSuite suite;
        // CppUnit::TextTestResult result;

        suite->addTest( new CppUnit::TestCaller<ASimpleTest>( "1 == 1", &ASimpleTest::testEqual ));

        return suite;
    }

    // -----------------------------------------------------------------------------

    CppUnit::TestSuite *suite()
    {
        CppUnit::TestSuite *suite = new CppUnit::TestSuite( "A simple test" );

        // CppUnit::TestSuite suite;
        // CppUnit::TextTestResult result;

        suite->addTest( suite1() );
//      suite->addTest( suite2() );

        return suite;
    }
}

void cppunitbased_test()
{
    {
        // ofstream out("c:\\temp\\output.txt", ios::out);
        CppUnit::TextTestResult aResult;

        CppUnit::TestSuite* pSuite = CppunitTest::suite();

        int nTests = pSuite->countTestCases();
        pSuite->run(&aResult);

        // aResult.print(out);
        cout << aResult;

        delete pSuite;
    }

    exit(1);
}

// ----------------------------------- Main -----------------------------------
#if (defined UNX) || (defined OS2)
int main( int argc, char* argv[] )
#else
int _cdecl main( int argc, char* argv[] )
#endif
{
    cppunitbased_test();

    tslTestManager hMgr = 0;

    /* show usage screen if too less parameters */
    if ( argc < 3 )
        usage();

#ifdef UNDER_WINDOWS_DEBUGGING
    DebugBreak();
#endif

    sal_uInt32 nCmdlinebitflags = createFlags( argc, argv );

    hMgr = tsl_TestManager_create( argv, argc, nCmdlinebitflags );
    tsl_TestManager_run( hMgr );
    tsl_TestManager_destroy( hMgr );
    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: helpagentdispatcher.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 01:19:38 $
 *
 *  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 __FRAMEWORK_DISPATCH_HELPAGENTDISPATCHER_HXX_
#include <dispatch/helpagentdispatcher.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_
#include <threadhelp/resetableguard.hxx>
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _SV_HELP_HXX
#include <vcl/help.hxx>
#endif

#ifndef _COMPHELPER_GUARDING_HXX_
#include <comphelper/guarding.hxx>
#endif

#ifndef INCLUDED_SVTOOLS_HELPOPT_HXX
#include <svtools/helpopt.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
//........................................................................
namespace framework
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::frame;
    using namespace ::com::sun::star::util;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::awt;
    using namespace ::com::sun::star::lang;

    //====================================================================
    //= HelpAgentDispatcher
    //====================================================================
    //--------------------------------------------------------------------
    HelpAgentDispatcher::HelpAgentDispatcher( const Reference< XFrame >& _rxParentFrame )
        :ThreadHelpBase(&Application::GetSolarMutex())
        ,m_pContainerWindow(NULL)
        ,m_pAgentWindow(NULL)
        ,m_xParentFrame(_rxParentFrame)
    {
        OSL_ENSURE(m_xParentFrame.is(), "HelpAgentDispatcher::HelpAgentDispatcher: invalid parent frame!");
    }

    //--------------------------------------------------------------------
    HelpAgentDispatcher::~HelpAgentDispatcher()
    {
        osl_incrementInterlockedCount( &m_refCount );
            // we may create new references to ourself below, so ensure the dtor is not called twice ....
        closeAgentWindow();
        if(m_xAutoCloseTimer.isValid())
            m_xAutoCloseTimer->setListener(NULL);
    }

    //--------------------------------------------------------------------
    sal_Bool HelpAgentDispatcher::ensureContainerWindow()
    {
        if (m_pContainerWindow)
            return sal_True;

        if (!m_xParentFrame.is())
        {
            OSL_ENSURE(sal_False, "HelpAgentDispatcher::ensureContainerWindow: have no explicit container window and no frame to obtain an implicit one!");
            // error condition, already asserted in the ctor
            return sal_False;
        }

        Reference< XWindow > xContainer = m_xParentFrame->getContainerWindow();
        implConstruct(xContainer);

        return (NULL != m_pContainerWindow);
    }

    //--------------------------------------------------------------------
    void HelpAgentDispatcher::implConstruct( const Reference< XWindow >& _rxContainer )
    {
        OSL_ENSURE(!m_pContainerWindow, "HelpAgentDispatcher::implConstruct: not to be called twice!");
        OSL_ENSURE(_rxContainer.is(), "HelpAgentDispatcher::implConstruct: invalid container window given!");

        m_pContainerWindow = VCLUnoHelper::GetWindow(_rxContainer);
        OSL_ENSURE(!_rxContainer.is() || (NULL != m_pContainerWindow), "HelpAgentDispatcher::implConstruct: could not get the implementation of the container!");
    }

    //--------------------------------------------------------------------
    void SAL_CALL HelpAgentDispatcher::dispatch( const URL& _rURL, const Sequence< PropertyValue >& _rArgs ) throw (RuntimeException)
    {
        ResetableGuard aGuard(m_aLock);
        switchURL(_rURL);
    }

    //--------------------------------------------------------------------
    void SAL_CALL HelpAgentDispatcher::addStatusListener( const Reference< XStatusListener >& _rxListener, const URL& _rURL ) throw (RuntimeException)
    {
        // this is pretty simple: we accept _all_ URLs, and we accept them _always_. So simply notify the listener
        // of the initial "available" state and then do nothing.
        if (_rxListener.is())
        {
            FeatureStateEvent aEvent;
            aEvent.FeatureURL = _rURL;
            aEvent.IsEnabled = sal_True;
            aEvent.Requery = sal_False;
            _rxListener->statusChanged(aEvent);
        }
    }

    //--------------------------------------------------------------------
    void SAL_CALL HelpAgentDispatcher::removeStatusListener( const Reference< XStatusListener >& _rxListener, const URL& _rURL ) throw (RuntimeException)
    {
        // nothing to do. see addStatusListener
    }

    //--------------------------------------------------------------------
    void SAL_CALL HelpAgentDispatcher::windowResized( const WindowEvent& _rSource ) throw (RuntimeException)
    {
        positionAgentWindow();
    }

    //--------------------------------------------------------------------
    void SAL_CALL HelpAgentDispatcher::windowMoved( const WindowEvent& _rSource ) throw (RuntimeException)
    {
        // not interested in
    }

    //--------------------------------------------------------------------
    void SAL_CALL HelpAgentDispatcher::windowShown( const EventObject& _rSource ) throw (RuntimeException)
    {
        // not interested in
    }

    //--------------------------------------------------------------------
    void SAL_CALL HelpAgentDispatcher::windowHidden( const EventObject& _rSource ) throw (RuntimeException)
    {
        // not interested in
    }

    //--------------------------------------------------------------------
    void SAL_CALL HelpAgentDispatcher::disposing( const EventObject& _rSource ) throw (RuntimeException)
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xSelfHold( static_cast< ::com::sun::star::frame::XDispatch* >(this), ::com::sun::star::uno::UNO_QUERY );

        // not interested in case the container window is closed (this should be handled by our owner)

        // interested in case our agent window is closed (we're the only instance allowed to close it)
        if (m_pAgentWindow)
        {
            Reference< XWindow > xSource(_rSource.Source, UNO_QUERY);
            Reference< XWindow > xAgentWindow = VCLUnoHelper::GetInterface(m_pAgentWindow);
            if (xSource.get() == xAgentWindow.get())
            {   // somebody closed my agent window, but it was not me
                agentClosedExternally();
            }
        }
    }

    //--------------------------------------------------------------------
    void HelpAgentDispatcher::agentClosedExternally()
    {
        ResetableGuard aGuard(m_aLock);
        stopAutoCloseTimer();
        m_pAgentWindow = NULL;
    }

    //--------------------------------------------------------------------
    sal_Bool HelpAgentDispatcher::approveURLRequest(const URL& _rURL)
    {
        SvtHelpOptions aHelpOptions;
        sal_Int32 nAllowedToIgnore = aHelpOptions.getAgentIgnoreURLCounter(_rURL.Complete);
        return nAllowedToIgnore > 0;
    }

    //--------------------------------------------------------------------
    void HelpAgentDispatcher::switchURL(const URL& _rURL)
    {
        if (!approveURLRequest(_rURL))
            // silently drop the request
            return;

        // show our agent window
        ensureAgentWindow();

        // stop the expiration timer for the old URL
        stopAutoCloseTimer();

        // save the URL
        m_sCurrentURL = _rURL.Complete;

        // start the expiration timer for the new URL
        startAutoCloseTimer();
    }

    //--------------------------------------------------------------------
    void HelpAgentDispatcher::stopAutoCloseTimer()
    {
        if (!m_xAutoCloseTimer.isValid())
            return;

        m_xAutoCloseTimer->stop();
    }

    //--------------------------------------------------------------------
    void HelpAgentDispatcher::startAutoCloseTimer()
    {
        ::vos::TTimeValue aAutoCloseTimeout( SvtHelpOptions().GetHelpAgentTimeoutPeriod(), 0 );
        if (!m_xAutoCloseTimer.isValid())
        {

            m_xAutoCloseTimer = new OTimerHelper(aAutoCloseTimeout);
            m_xAutoCloseTimer->setListener(this);
        }

        m_xAutoCloseTimer->setRemainingTime(aAutoCloseTimeout);
        m_xAutoCloseTimer->start();
    }

    //--------------------------------------------------------------------
    void HelpAgentDispatcher::helpRequested()
    {
        ResetableGuard aGuard(m_aLock);

        // FIRST stop the timer
        stopAutoCloseTimer();

        // reset the ignore counter for this URL
        SvtHelpOptions().resetAgentIgnoreURLCounter(m_sCurrentURL);

        Help* pApplicationHelp = Application::GetHelp();
        OSL_ENSURE(pApplicationHelp, "HelpAgentDispatcher::helpRequested: no help system available!");
        if (pApplicationHelp)
            pApplicationHelp->Start( m_sCurrentURL, NULL );

        aGuard.unlock();
        closeAgentWindow();
    }

    //--------------------------------------------------------------------
    void HelpAgentDispatcher::closeAgent()
    {
        // the hint has been ignored by the user (click the closer)
        markURLIgnored(m_sCurrentURL);
        // close the window
        closeAgentWindow();
    }

    //--------------------------------------------------------------------
    void HelpAgentDispatcher::timerExpired()
    {
        // the hint has been ignored by the user
        markURLIgnored(m_sCurrentURL);
        // close the window
        closeAgentWindow();
    }

    //--------------------------------------------------------------------
    void HelpAgentDispatcher::markURLIgnored( const ::rtl::OUString& _rURL )
    {
        SvtHelpOptions().decAgentIgnoreURLCounter(_rURL);
    }

    //--------------------------------------------------------------------
    void HelpAgentDispatcher::closeAgentWindow()
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xSelfHold( static_cast< ::com::sun::star::frame::XDispatch* >(this), ::com::sun::star::uno::UNO_QUERY );

        // now acquire the SolarMutex ...
        ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
        // ... and our own mutex
        ResetableGuard aGuard(m_aLock);

        stopAutoCloseTimer();

        if (!m_pAgentWindow)
            return;

        if (m_pContainerWindow)
        {
            Reference< XWindow > xContainer = VCLUnoHelper::GetInterface(m_pContainerWindow);
            OSL_ENSURE(xContainer.is(), "HelpAgentDispatcher::closeAgentWindow: no UNO interface for the container window!");
            if (xContainer.is())
                xContainer->removeWindowListener(this);
        }

        if (m_pAgentWindow)
        {
            Reference< XWindow > xAgentWindow = VCLUnoHelper::GetInterface(m_pAgentWindow);
            OSL_ENSURE(xAgentWindow.is(), "HelpAgentDispatcher::closeAgentWindow: no UNO interface for the agent window!");
            if (xAgentWindow.is())
                xAgentWindow->removeWindowListener(this);
        }

        delete m_pAgentWindow;
        m_pAgentWindow = NULL;
    }

    //--------------------------------------------------------------------
    void HelpAgentDispatcher::positionAgentWindow()
    {
        OSL_ENSURE(m_pContainerWindow, "HelpAgentDispatcher::positionAgentWindow: please use ensureContainerWindow!");
        OSL_ENSURE(m_pAgentWindow, "HelpAgentDispatcher::positionAgentWindow: to be called with an existing agent window only!");
        OSL_ENSURE(m_pAgentWindow->GetParent() == m_pContainerWindow, "HelpAgentDispatcher::positionAgentWindow: invalid window hierarchy!");

        const Size aContainerSize = m_pContainerWindow->GetSizePixel();
        const Size aAgentSize = m_pAgentWindow->getPreferredSizePixel();

        const Point aAgentPos   ( aContainerSize.Width() - aAgentSize.Width()
                                , aContainerSize.Height() - aAgentSize.Height() );

        // TODO: use a surrogate if the container window is too small to contain the full-sized agent window

        m_pAgentWindow->SetPosSizePixel(aAgentPos, aAgentSize);
    }

    //--------------------------------------------------------------------
    sal_Bool HelpAgentDispatcher::ensureAgentWindow()
    {
        if (m_pAgentWindow)
            return sal_True;

        ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
        if (!ensureContainerWindow())
            return sal_False;

        // create it
        m_pAgentWindow = new ::svt::HelpAgentWindow(m_pContainerWindow);
        m_pAgentWindow->setCallback(this);

        // add as listener at the agent window in case it is closed by the user (and not by us ourself)
        Reference< XWindow > xAgentWindow = VCLUnoHelper::GetInterface(m_pAgentWindow);
        OSL_ENSURE(xAgentWindow.is(), "HelpAgentDispatcher::ensureAgentWindow: no UNO interface for the agent window!");
        if (xAgentWindow.is())
            xAgentWindow->addWindowListener(this);

        // add as window listener to the container window so we can maintain the property position of the agent window
        Reference< XWindow > xContainer = VCLUnoHelper::GetInterface(m_pContainerWindow);
        OSL_ENSURE(xContainer.is(), "HelpAgentDispatcher::ensureAgentWindow: no container window interface!");
        if (xContainer.is())
            xContainer->addWindowListener(this);

        // position it
        positionAgentWindow();

        // show it
        if (m_pContainerWindow->IsVisible())
            m_pAgentWindow->Show();

        return sal_True;
    }

//........................................................................
}   // namespace framework
//........................................................................

<commit_msg>INTEGRATION: CWS stacks01 (1.7.44); FILE MERGED 2005/11/03 08:08:36 as 1.7.44.1: #114142# HelpAgentDispatcher use ref counted objects instead pointer; it uses vcl timer instead of osl-threaded timer; remove status listener support (not needed)<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: helpagentdispatcher.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-11-10 16:11:57 $
 *
 *  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 __FRAMEWORK_DISPATCH_HELPAGENTDISPATCHER_HXX_
#include <dispatch/helpagentdispatcher.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
#include <threadhelp/readguard.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
#include <threadhelp/writeguard.hxx>
#endif

#ifndef _COM_SUN_STAR_AWT_XWINDOW2_HPP_
#include <com/sun/star/awt/XWindow2.hpp>
#endif

#ifndef _COM_SUN_STAR_AWT_POSSIZE_HPP_
#include <com/sun/star/awt/PosSize.hpp>
#endif

#ifndef _COM_SUN_STAR_AWT_SIZE_HPP_
#include <com/sun/star/awt/Size.hpp>
#endif

#ifndef _COM_SUN_STAR_AWT_RECTANGLE_HPP_
#include <com/sun/star/awt/Rectangle.hpp>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif

#ifndef INCLUDED_SVTOOLS_HELPOPT_HXX
#include <svtools/helpopt.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _SV_HELP_HXX
#include <vcl/help.hxx>
#endif

namespace css = ::com::sun::star;

//........................................................................
namespace framework
{

//-----------------------------------------------
DEFINE_XINTERFACE_4(HelpAgentDispatcher                         ,
                    OWeakObject                                 ,
                    DIRECT_INTERFACE (css::lang::XTypeProvider ),
                    DIRECT_INTERFACE (css::frame::XDispatch    ),
                    DIRECT_INTERFACE (css::awt::XWindowListener),
                    DIRECT_INTERFACE (css::lang::XEventListener))

//-----------------------------------------------
DEFINE_XTYPEPROVIDER_2(HelpAgentDispatcher     ,
                       css::lang::XTypeProvider,
                       css::frame::XDispatch   )

//--------------------------------------------------------------------
HelpAgentDispatcher::HelpAgentDispatcher( const css::uno::Reference< css::frame::XFrame >& xParentFrame)
    : ThreadHelpBase    (&Application::GetSolarMutex())
    , m_sCurrentURL     (                             )
    , m_xContainerWindow(                             )
    , m_xAgentWindow    (                             )
    , m_aTimer          (                             )
    , m_xSelfHold       (                             )
{
    // It's required that this class has to be contructed with a valid frame.
    // And "valid" means: the frame must already bound to a valid container window.
    m_xContainerWindow = xParentFrame->getContainerWindow();
}

//--------------------------------------------------------------------
HelpAgentDispatcher::~HelpAgentDispatcher()
{
    implts_stopTimer();
    implts_ignoreCurrentURL();

    // Needed ... because it was create as "new VCLWindow()" ! Such windows must be disposed explicitly.
    css::uno::Reference< css::lang::XComponent > xAgentWindow(m_xAgentWindow, css::uno::UNO_QUERY);
    if (xAgentWindow.is())
        xAgentWindow->dispose();
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::dispatch(const css::util::URL&                                  aURL ,
                                            const css::uno::Sequence< css::beans::PropertyValue >& lArgs)
    throw(css::uno::RuntimeException)
{
    // silently drop the request if the new URL was marked to be ignored next time.
    sal_Int32 nAllowedToIgnore = SvtHelpOptions().getAgentIgnoreURLCounter(aURL.Complete);
    if (nAllowedToIgnore < 1)
        return;

    // stop the expiration timer for the old URL
    // The timer will add the old URL to the list of ignorable URLs.
    // So m_sCurrentURL must be set AFTER the timer was stopped !!!
    implts_stopTimer();

    // SAFE ->
    WriteGuard aWriteLock(m_aLock);
    m_sCurrentURL = aURL.Complete;
    aWriteLock.unlock();
    // <- SAFE

    // start the expiration timer for the new URL
    implts_startTimer();

    // make sure the agent window is shown
    implts_showAgentWindow();
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
                                                     const css::util::URL&                                     aURL     )
    throw(css::uno::RuntimeException)
{
    // no status available
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
                                                        const css::util::URL&                                     aURL     )
    throw(css::uno::RuntimeException)
{
    // no status available
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::windowResized(const css::awt::WindowEvent& aEvent)
    throw(css::uno::RuntimeException)
{
    implts_positionAgentWindow();
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::windowMoved(const css::awt::WindowEvent& aEvent)
    throw(css::uno::RuntimeException)
{
    implts_positionAgentWindow();
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::windowShown(const css::lang::EventObject& aEvent)
    throw(css::uno::RuntimeException)
{
    implts_showAgentWindow();
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::windowHidden(const css::lang::EventObject& aEvent)
    throw(css::uno::RuntimeException)
{
    implts_hideAgentWindow();
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::disposing(const css::lang::EventObject& aEvent)
    throw(css::uno::RuntimeException)
{
    // SAFE ->
    WriteGuard aWriteLock(m_aLock);

    // Already disposed ?!
    if (! m_xContainerWindow.is())
        return;
    // Wrong broadcaster ?!
    if (aEvent.Source != m_xContainerWindow)
        return;

    css::uno::Reference< css::uno::XInterface > xSelfHoldUntilMethodEnds(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY_THROW);
    m_xSelfHold.clear();

    aWriteLock.unlock();
    // <- SAFE

    implts_stopTimer();
    implts_hideAgentWindow();
    implts_ignoreCurrentURL();

    // SAFE ->
    aWriteLock.lock();
    m_xContainerWindow.clear();
    css::uno::Reference< css::lang::XComponent > xAgentWindow(m_xAgentWindow, css::uno::UNO_QUERY);
    m_xAgentWindow.clear();
    aWriteLock.unlock();
    // <- SAFE

    // Needed ... because it was create as "new VCLWindow()" ! Such windows must be disposed explicitly.
    if (xAgentWindow.is())
        xAgentWindow->dispose();
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::helpRequested()
{
    implts_stopTimer();
    implts_hideAgentWindow();
    implts_acceptCurrentURL();
}

//-----------------------------------------------
void HelpAgentDispatcher::closeAgent()
{
    implts_stopTimer();
    implts_hideAgentWindow();
    implts_ignoreCurrentURL();
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_acceptCurrentURL()
{
    // SAFE ->
    WriteGuard aWriteLock(m_aLock);

    ::rtl::OUString sAcceptedURL  = m_sCurrentURL;
                    m_sCurrentURL = ::rtl::OUString();

    aWriteLock.unlock();
    // <- SAFE

    // We must make sure that this URL isnt marked as ignored by the user.
    // Otherwhise the user wont see the corresponding help content in the future.
    SvtHelpOptions().resetAgentIgnoreURLCounter(sAcceptedURL);

    // show the right help content
    // SOLAR SAFE ->
    {
        ::vos::OGuard aSolarLock(Application::GetSolarMutex());
        Help* pHelp = Application::GetHelp();
        if (pHelp)
            pHelp->Start(sAcceptedURL, NULL);
    }
    // <- SOLAR SAFE
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_ignoreCurrentURL()
{
    // SAFE ->
    WriteGuard aWriteLock(m_aLock);

    ::rtl::OUString sIgnoredURL   = m_sCurrentURL;
                    m_sCurrentURL = ::rtl::OUString();

    aWriteLock.unlock();
    // <- SAFE

    if (sIgnoredURL.getLength())
        SvtHelpOptions().decAgentIgnoreURLCounter(sIgnoredURL);
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_stopTimer()
{
    // SAFE ->
    WriteGuard aWriteLock(m_aLock);
    m_xSelfHold.clear();
    aWriteLock.unlock();
    // <- SAFE

    // SOLAR SAFE ->
    // Timer access needs no "own lock" ! It lives if we live ...
    // But it requires locking of the solar mutex ... because it's a vcl based timer.
    {
        ::vos::OGuard aSolarLock(Application::GetSolarMutex());
        if (! m_aTimer.IsActive())
            return;
        m_aTimer.Stop();
    }
    // <- SOLAR SAFE
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_startTimer()
{
    // SOLAR SAFE ->
    // Timer access needs no "own lock" ! It lives if we live ...
    // But it requires locking of the solar mutex ... because it's a vcl based timer.
    {
        ::vos::OGuard aSolarLock(Application::GetSolarMutex());
        if (m_aTimer.IsActive())
            return;
    }
    // <- SOLAR SAFE

    // SAFE ->
    // Timer uses pointer to this help agent dispatcher ...
    // But normaly we are ref counted. So we must make sure that this
    // dispatcher isnt killed during the timer runs .-)
    WriteGuard aWriteLock(m_aLock);
    m_xSelfHold = css::uno::Reference< css::uno::XInterface >(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY_THROW);
    aWriteLock.unlock();
    // <- SAFE

    sal_Int32 nTime = SvtHelpOptions().GetHelpAgentTimeoutPeriod();

    // SOLAR SAFE ->
    // Timer access needs no "own lock" ! It lives if we live ...
    // But it requires locking of the solar mutex ... because it's a vcl based timer.
    {
        ::vos::OGuard aSolarLock(Application::GetSolarMutex());
        m_aTimer.SetTimeout(nTime*1000); // sec => ms !
        m_aTimer.Start();
    }
}

//-----------------------------------------------
IMPL_LINK(HelpAgentDispatcher, implts_timerExpired, void*, pVoid)
{
    // This method is called by using a pointer to us.
    // But we must be aware that we can be destroyed hardly
    // if our uno reference will be gone!
    // => Hold this object alive till this method finish its work.
    // SAFE ->
    WriteGuard aWriteLock(m_aLock);
    css::uno::Reference< css::uno::XInterface > xSelfHoldUntilMethodEnds(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY_THROW);
    m_xSelfHold.clear();
    aWriteLock.unlock();
    // <- SAFE

    implts_hideAgentWindow();
    implts_ignoreCurrentURL();

    return 0;
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_showAgentWindow()
{
    // SAFE ->
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::awt::XWindow2 > xContainerWindow(m_xContainerWindow, css::uno::UNO_QUERY_THROW);
    aReadLock.unlock();
    // <- SAFE

    css::uno::Reference< css::awt::XWindow > xAgentWindow = implts_ensureAgentWindow();

    if (
        (xContainerWindow.is()        ) &&
        (xAgentWindow.is()            ) &&
        (xContainerWindow->isVisible())
       )
    {
        // make sure that agent window resists at the right place .-)
        implts_positionAgentWindow();
        xAgentWindow->setVisible(sal_True);
    }
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_hideAgentWindow()
{
    css::uno::Reference< css::awt::XWindow > xAgentWindow = implts_ensureAgentWindow();
    if (xAgentWindow.is())
        xAgentWindow->setVisible(sal_False);
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_positionAgentWindow()
{
    // SAFE ->
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
    aReadLock.unlock();
    // <- SAFE

    css::uno::Reference< css::awt::XWindow > xAgentWindow = implts_ensureAgentWindow();
    if (
        (! xContainerWindow.is())  ||
        (! xAgentWindow.is()    )
       )
        return;

          ::svt::HelpAgentWindow* pAgentWindow   = (::svt::HelpAgentWindow*)VCLUnoHelper::GetWindow(xAgentWindow);
    const css::awt::Rectangle     aContainerSize = xContainerWindow->getPosSize();
    const Size                    aAgentSize     = pAgentWindow->getPreferredSizePixel();

    sal_Int32 nW = aAgentSize.Width() ;
    sal_Int32 nH = aAgentSize.Height();

    if (nW < 1)
        nW = 100;
    if (nH < 1)
        nH = 100;

    sal_Int32 nX = aContainerSize.Width  - nW;
    sal_Int32 nY = aContainerSize.Height - nH;

    // TODO: use a surrogate if the container window is too small to contain the full-sized agent window
    xAgentWindow->setPosSize(nX, nY, nW, nH, css::awt::PosSize::POSSIZE);
}

//--------------------------------------------------------------------
css::uno::Reference< css::awt::XWindow > HelpAgentDispatcher::implts_ensureAgentWindow()
{
    // SAFE ->
    ReadGuard aReadLock(m_aLock);
    if (m_xAgentWindow.is())
        return m_xAgentWindow;
    css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
    aReadLock.unlock();
    // <- SAFE

    if (!xContainerWindow.is())
        return css::uno::Reference< css::awt::XWindow >();

    ::svt::HelpAgentWindow* pAgentWindow = 0;
    // SOLAR SAFE ->
    {
        ::vos::OGuard aSolarLock(Application::GetSolarMutex());
        // create the agent window
        Window* pContainerWindow = VCLUnoHelper::GetWindow(xContainerWindow);
                pAgentWindow     = new ::svt::HelpAgentWindow(pContainerWindow);
        pAgentWindow->setCallback(this);
    }
    // <- SOLAR SAFE

    // SAFE ->
    WriteGuard aWriteLock(m_aLock);
    m_xAgentWindow = VCLUnoHelper::GetInterface(pAgentWindow);
    css::uno::Reference< css::awt::XWindow > xAgentWindow = m_xAgentWindow;
    aWriteLock.unlock();
    // <- SAFE

    // add as window listener to the container window so we can maintain the property position of the agent window
    xContainerWindow->addWindowListener(this);

    // SOLAR SAFE ->
    {
        ::vos::OGuard aSolarLock(Application::GetSolarMutex());
        // establish callback for our internal used timer.
        // Note: Its only active, if the timer will be started ...
        m_aTimer.SetTimeoutHdl(LINK(this, HelpAgentDispatcher, implts_timerExpired));
    }
    // <- SOLAR SAFE

    return xAgentWindow;
}

} // namespace framework

<|endoftext|>