Codebase list mozc / 7306a9d config / config_handler.cc
7306a9d

Tree @7306a9d (Download .tar.gz)

config_handler.cc @7306a9draw · history · blame

// Copyright 2010-2012, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Handler of mozc configuration.
#include "config/config_handler.h"

#include "base/config_file_stream.h"
#include "base/singleton.h"
#include "base/version.h"
#include "config/config.pb.h"

#include "base/logging.h"

namespace mozc {
namespace config {

namespace {

static const char kFileNamePrefix[] = "user://config";

void AddCharacterFormRule(config::Config *config,
                          const char *group,
                          config::Config::CharacterForm preedit_form,
                          config::Config::CharacterForm conversion_form) {
  config::Config::CharacterFormRule *rule =
      config->add_character_form_rules();
  rule->set_group(group);
  rule->set_preedit_character_form(preedit_form);
  rule->set_conversion_character_form(conversion_form);
}

class ConfigHandlerImpl {
 public:
  ConfigHandlerImpl() {
    // <user_profile>/config1.db
    filename_ = kFileNamePrefix;
    filename_ += Util::SimpleItoa(CONFIG_VERSION);
    filename_ += ".db";
    Reload();
  }
  virtual ~ConfigHandlerImpl() {}
  const Config &GetConfig() const;
  bool GetConfig(Config *config) const;
  const Config &GetStoredConfig() const;
  bool GetStoredConfig(Config *config) const;
  bool SetConfig(const Config &config);
  void SetImposedConfig(const Config &config);
  bool Reload();
  void SetConfigFileName(const string &filename);
  string GetConfigFileName();

 private:
  // copy config to config_ and do some
  // platform dependent hooks/rewrites
  bool SetConfigInternal(const Config &config);
  void UpdateMergedConfig();

  string filename_;
  mozc::config::Config stored_config_;
  mozc::config::Config imposed_config_;
  // equals to config_.MergeFrom(imposed_config_)
  mozc::config::Config merged_config_;
};

ConfigHandlerImpl *GetConfigHandlerImpl() {
  return Singleton<ConfigHandlerImpl>::get();
}

const Config &ConfigHandlerImpl::GetConfig() const {
  return merged_config_;
}

// return current Config
bool ConfigHandlerImpl::GetConfig(Config *config) const {
  config->CopyFrom(merged_config_);
  return true;
}

const Config &ConfigHandlerImpl::GetStoredConfig() const {
  return stored_config_;
}

// return stored Config
bool ConfigHandlerImpl::GetStoredConfig(Config *config) const {
  config->CopyFrom(stored_config_);
  return true;
}

// set config and rewirte internal data
bool ConfigHandlerImpl::SetConfigInternal(const Config &config) {
  stored_config_.CopyFrom(config);

#ifdef NO_LOGGING
  // Delete the optional field from the config.
  stored_config_.clear_verbose_level();
  // Fall back if the default value is not the expected value.
  if (stored_config_.verbose_level() != 0) {
    stored_config_.set_verbose_level(0);
  }
#endif

  Logging::SetConfigVerboseLevel(stored_config_.verbose_level());

  // Initialize platform specific configuration.
  if (stored_config_.session_keymap() == Config::NONE) {
#ifdef OS_MACOSX
    stored_config_.set_session_keymap(Config::KOTOERI);
#else  // OS_MACOSX
    stored_config_.set_session_keymap(Config::MSIME);
#endif  // OS_MACOSX
  }

#ifdef CHANNEL_DEV
#endif  // CHANNEL_DEV

  UpdateMergedConfig();

  return true;
}

void ConfigHandlerImpl::UpdateMergedConfig() {
  merged_config_.CopyFrom(stored_config_);
  merged_config_.MergeFrom(imposed_config_);
}

bool ConfigHandlerImpl::SetConfig(const Config &config) {
  Config output_config;
  output_config.CopyFrom(config);

  ConfigHandler::SetMetaData(&output_config);

  VLOG(1) << "Setting new config: " << filename_;
  ConfigFileStream::AtomicUpdate(filename_, output_config.SerializeAsString());

#ifdef DEBUG
  string debug_content(
      "# This is a text-based config file for debugging.\n"
      "# Nothing happens when you edit this file manually.\n");
  debug_content += output_config.DebugString();
  ConfigFileStream::AtomicUpdate(filename_ + ".txt", debug_content);
#endif  // DEBUG

  return SetConfigInternal(output_config);
}

void ConfigHandlerImpl::SetImposedConfig(const Config &config) {
  VLOG(1) << "Setting new overriding config";
  imposed_config_.CopyFrom(config);

#ifdef DEBUG
  string debug_content(
      "# This is a text-based config file for debugging.\n"
      "# Nothing happens when you edit this file manually.\n");
  debug_content += config.DebugString();
  ConfigFileStream::AtomicUpdate(filename_ + ".overriding.txt", debug_content);
#endif  // DEBUG
  UpdateMergedConfig();
}

// Reload from file
bool ConfigHandlerImpl::Reload() {
  VLOG(1) << "Reloading config file: " << filename_;
  scoped_ptr<istream> is(ConfigFileStream::Open(
                             filename_,
                             ios::in | ios::binary));
  Config input_proto;
  bool ret_code = true;

  if (is.get() == NULL) {
    LOG(ERROR) << filename_ << " is not found";
    ret_code = false;
  } else if (!input_proto.ParseFromIstream(is.get())) {
    LOG(ERROR) << filename_ << " is broken";
    input_proto.Clear();   // revert to default setting
    ret_code = false;
  }

  // we set default config when file is broekn
  ret_code |= SetConfigInternal(input_proto);

  return ret_code;
}

void ConfigHandlerImpl::SetConfigFileName(const string &filename) {
  VLOG(1) << "set new config file name: " << filename;
  filename_ = filename;
  Reload();
}

string ConfigHandlerImpl::GetConfigFileName() {
  return filename_;
}
}  // namespace

const Config &ConfigHandler::GetConfig() {
  return GetConfigHandlerImpl()->GetConfig();
}

// return current Config
bool ConfigHandler::GetConfig(Config *config) {
  return GetConfigHandlerImpl()->GetConfig(config);
}

const Config &ConfigHandler::GetStoredConfig() {
  return GetConfigHandlerImpl()->GetStoredConfig();
}

// return Stored Config
bool ConfigHandler::GetStoredConfig(Config *config) {
  return GetConfigHandlerImpl()->GetStoredConfig(config);
}

// set config
bool ConfigHandler::SetConfig(const Config &config) {
  return GetConfigHandlerImpl()->SetConfig(config);
}

// set overriding config
void ConfigHandler::SetImposedConfig(const Config &config) {
  GetConfigHandlerImpl()->SetImposedConfig(config);
}

void ConfigHandler::GetDefaultConfig(Config *config) {
  config->Clear();
#ifdef OS_MACOSX
  config->set_session_keymap(Config::KOTOERI);
#else  // OS_MACOSX
  config->set_session_keymap(Config::MSIME);
#endif  // OS_MACOSX

  // "ア"
  AddCharacterFormRule(config, "\xE3\x82\xA2",
                       config::Config::FULL_WIDTH, config::Config::FULL_WIDTH);
  AddCharacterFormRule(config, "A",
                       config::Config::FULL_WIDTH, config::Config::LAST_FORM);
  AddCharacterFormRule(config, "0",
                       config::Config::FULL_WIDTH, config::Config::LAST_FORM);
  AddCharacterFormRule(config, "(){}[]",
                       config::Config::FULL_WIDTH, config::Config::LAST_FORM);
  AddCharacterFormRule(config, ".,",
                       config::Config::FULL_WIDTH, config::Config::LAST_FORM);
  // "。、",
  AddCharacterFormRule(config, "\xE3\x80\x82\xE3\x80\x81",
                       config::Config::FULL_WIDTH, config::Config::FULL_WIDTH);
  // "・「」"
  AddCharacterFormRule(config, "\xE3\x83\xBB\xE3\x80\x8C\xE3\x80\x8D",
                       config::Config::FULL_WIDTH, config::Config::FULL_WIDTH);
  AddCharacterFormRule(config, "\"'",
                       config::Config::FULL_WIDTH, config::Config::LAST_FORM);
  AddCharacterFormRule(config, ":;",
                       config::Config::FULL_WIDTH, config::Config::LAST_FORM);
  AddCharacterFormRule(config, "#%&@$^_|`\\",
                       config::Config::FULL_WIDTH, config::Config::LAST_FORM);
  AddCharacterFormRule(config, "~",
                       config::Config::FULL_WIDTH, config::Config::LAST_FORM);
  AddCharacterFormRule(config, "<>=+-/*",
                       config::Config::FULL_WIDTH, config::Config::LAST_FORM);
  AddCharacterFormRule(config, "?!",
                       config::Config::FULL_WIDTH, config::Config::LAST_FORM);

#ifdef CHANNEL_DEV
#endif  // CHANNEL_DEV
}

// Reload from file
bool ConfigHandler::Reload() {
  return GetConfigHandlerImpl()->Reload();
}

void ConfigHandler::SetConfigFileName(const string &filename) {
  GetConfigHandlerImpl()->SetConfigFileName(filename);
}

string ConfigHandler::GetConfigFileName() {
  return GetConfigHandlerImpl()->GetConfigFileName();
}

// static
void ConfigHandler::SetMetaData(Config *config) {
  GeneralConfig *general_config = config->mutable_general_config();
  general_config->set_config_version(CONFIG_VERSION);
  general_config->set_last_modified_time(Util::GetTime());
  general_config->set_last_modified_product_version(Version::GetMozcVersion());
  general_config->set_platform(Util::GetOSVersionString());
}

}  // config
}  // mozc