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

#include "chrome/browser/sync/glue/preference_model_associator.h"

#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/values.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/engine/syncapi.h"
#include "chrome/browser/sync/glue/synchronized_preferences.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/protocol/preference_specifics.pb.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"

namespace browser_sync {

PreferenceModelAssociator::PreferenceModelAssociator(
    ProfileSyncService* sync_service)
    : sync_service_(sync_service),
      preferences_node_id_(sync_api::kInvalidId) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(sync_service_);

  // Add the list of kSynchronizedPreferences to our local
  // synced_preferences set, taking care to filter out any preferences
  // that are not registered.
  PrefService* pref_service = sync_service_->profile()->GetPrefs();
  for (size_t i = 0; i < arraysize(kSynchronizedPreferences); ++i) {
    if (pref_service->FindPreference(kSynchronizedPreferences[i]))
      synced_preferences_.insert(kSynchronizedPreferences[i]);
  }
}

PreferenceModelAssociator::~PreferenceModelAssociator() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
}

bool PreferenceModelAssociator::InitPrefNodeAndAssociate(
    sync_api::WriteTransaction* trans,
    const sync_api::BaseNode& root,
    const PrefService::Preference* pref) {
  DCHECK(pref);

  PrefService* pref_service = sync_service_->profile()->GetPrefs();
  base::JSONReader reader;
  std::string tag = pref->name();
  sync_api::WriteNode node(trans);
  if (node.InitByClientTagLookup(syncable::PREFERENCES, tag)) {
    // The server has a value for the preference.
    const sync_pb::PreferenceSpecifics& preference(
        node.GetPreferenceSpecifics());
    DCHECK_EQ(tag, preference.name());

    if (pref->IsUserModifiable()) {
      scoped_ptr<Value> value(
          reader.JsonToValue(preference.value(), false, false));
      std::string pref_name = preference.name();
      if (!value.get()) {
        LOG(ERROR) << "Failed to deserialize preference value: "
                   << reader.GetErrorMessage();
        return false;
      }

      // Merge the server value of this preference with the local value.
      scoped_ptr<Value> new_value(MergePreference(*pref, *value));

      // Update the local preference based on what we got from the
      // sync server.
      if (!pref->GetValue()->Equals(new_value.get()))
        pref_service->Set(pref_name.c_str(), *new_value);

      AfterUpdateOperations(pref_name);

      // If the merge resulted in an updated value, write it back to
      // the sync node.
      if (!value->Equals(new_value.get()) &&
          !WritePreferenceToNode(pref->name(), *new_value, &node))
        return false;
    }
    Associate(pref, node.GetId());
  } else if (pref->IsUserControlled()) {
    // The server doesn't have a value, but we have a user-controlled value,
    // so we push it to the server.
    sync_api::WriteNode write_node(trans);
    if (!write_node.InitUniqueByCreation(syncable::PREFERENCES, root, tag)) {
      LOG(ERROR) << "Failed to create preference sync node.";
      return false;
    }

    // Update the sync node with the local value for this preference.
    if (!WritePreferenceToNode(pref->name(), *pref->GetValue(), &write_node))
      return false;

    Associate(pref, write_node.GetId());
  }

  return true;
}

bool PreferenceModelAssociator::AssociateModels() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));<commit_msg>Handle sync values of wrong type more graceful.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync/glue/preference_model_associator.h"

#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/values.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/engine/syncapi.h"
#include "chrome/browser/sync/glue/synchronized_preferences.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/protocol/preference_specifics.pb.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"

namespace browser_sync {

PreferenceModelAssociator::PreferenceModelAssociator(
    ProfileSyncService* sync_service)
    : sync_service_(sync_service),
      preferences_node_id_(sync_api::kInvalidId) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(sync_service_);

  // Add the list of kSynchronizedPreferences to our local
  // synced_preferences set, taking care to filter out any preferences
  // that are not registered.
  PrefService* pref_service = sync_service_->profile()->GetPrefs();
  for (size_t i = 0; i < arraysize(kSynchronizedPreferences); ++i) {
    if (pref_service->FindPreference(kSynchronizedPreferences[i]))
      synced_preferences_.insert(kSynchronizedPreferences[i]);
  }
}

PreferenceModelAssociator::~PreferenceModelAssociator() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
}

bool PreferenceModelAssociator::InitPrefNodeAndAssociate(
    sync_api::WriteTransaction* trans,
    const sync_api::BaseNode& root,
    const PrefService::Preference* pref) {
  DCHECK(pref);

  PrefService* pref_service = sync_service_->profile()->GetPrefs();
  base::JSONReader reader;
  std::string tag = pref->name();
  sync_api::WriteNode node(trans);
  if (node.InitByClientTagLookup(syncable::PREFERENCES, tag)) {
    // The server has a value for the preference.
    const sync_pb::PreferenceSpecifics& preference(
        node.GetPreferenceSpecifics());
    DCHECK_EQ(tag, preference.name());

    if (pref->IsUserModifiable()) {
      scoped_ptr<Value> value(
          reader.JsonToValue(preference.value(), false, false));
      std::string pref_name = preference.name();
      if (!value.get()) {
        LOG(ERROR) << "Failed to deserialize preference value: "
                   << reader.GetErrorMessage();
        return false;
      }

      // Merge the server value of this preference with the local value.
      scoped_ptr<Value> new_value(MergePreference(*pref, *value));

      // Update the local preference based on what we got from the
      // sync server.
      if (new_value->IsType(Value::TYPE_NULL)) {
        pref_service->ClearPref(pref_name.c_str());
      } else if (!new_value->IsType(pref->GetType())) {
        LOG(WARNING) << "Synced value for " << preference.name()
                     << " is of type " << new_value->GetType()
                     << " which doesn't match pref type " << pref->GetType();
      } else if (!pref->GetValue()->Equals(new_value.get())) {
        pref_service->Set(pref_name.c_str(), *new_value);
      }

      AfterUpdateOperations(pref_name);

      // If the merge resulted in an updated value, write it back to
      // the sync node.
      if (!value->Equals(new_value.get()) &&
          !WritePreferenceToNode(pref->name(), *new_value, &node))
        return false;
    }
    Associate(pref, node.GetId());
  } else if (pref->IsUserControlled()) {
    // The server doesn't have a value, but we have a user-controlled value,
    // so we push it to the server.
    sync_api::WriteNode write_node(trans);
    if (!write_node.InitUniqueByCreation(syncable::PREFERENCES, root, tag)) {
      LOG(ERROR) << "Failed to create preference sync node.";
      return false;
    }

    // Update the sync node with the local value for this preference.
    if (!WritePreferenceToNode(pref->name(), *pref->GetValue(), &write_node))
      return false;

    Associate(pref, write_node.GetId());
  }

  return true;
}

bool PreferenceModelAssociator::AssociateModels() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
{'fraction_non_alphanumeric': 0.12482352941176471, 'fraction_numerical': 0.001176470588235294, 'mean_word_length': 4.060119047619048, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5392056', 'n_tokens_mistral': 2576, 'n_tokens_neox': 2548, 'n_words': 588}