Package com.opera.core.systems.preferences

Source Code of com.opera.core.systems.preferences.OperaFilePreferences

/*
Copyright 2011-2012 Opera Software ASA

Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package com.opera.core.systems.preferences;

import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.common.io.Files;

import org.ini4j.Config;
import org.ini4j.Ini;
import org.ini4j.Profile;
import org.ini4j.Wini;
import org.openqa.selenium.WebDriverException;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import java.util.Map;

/**
* OperaFilePreferences allows updating preferences in an Opera preference file such as
* <code>opera.ini</code> or <code>operaprefs.ini</code>.  The file will be written to upon each
* alteration to any preference.
*/
public class OperaFilePreferences extends AbstractOperaPreferences {

  private File preferenceFile;

  /**
   * Constructs a new representation of Opera's preferences based on the given preference file.
   *
   * @param preferenceFile an INI style preference file
   */
  public OperaFilePreferences(File preferenceFile) {
    this.preferenceFile = preferenceFile;

    // Create new preference file if it doesn't exist
    if (!preferenceFile.exists()) {
      try {
        if (!preferenceFile.createNewFile()) {
          throw new IOException("File exists");
        }
      } catch (IOException e) {
        throw new WebDriverException("Unable to create new preference file: " + e.getMessage());
      }

      return;
    }

    Ini ini = getIniForPreferenceFile(preferenceFile);

    // Add each preference entry
    for (Map.Entry<String, Profile.Section> section : ini.entrySet()) {
      for (Map.Entry<String, String> entry : section.getValue().entrySet()) {
        set(section.getValue().getName(), entry.getKey(), entry.getValue());
      }
    }
  }

  private Ini getIniForPreferenceFile(File preferenceFile) {
    // Due to the sucky nature of Opera's invalid preference files, we are forced to remove the
    // first line of the file.
    //
    // opera.ini looks much like this:
    //
    //   <BOM>
    //   Opera Preferences version 2.1
    //   ; Do not edit this file while Opera is running
    //   ; This file is stored in UTF-8 encoding
    //
    //   [User Prefs]
    //   Language Files Directory=
    //
    //     &c.

    try {
      List<String> lines = Files.readLines(preferenceFile, Charsets.UTF_8);
      Iterable<String> filteredLines = Iterables.filter(lines, new Predicate<String>() {
        public boolean apply(String line) {
          return !line.contains("Opera Preferences version");
        }
      });

      Config config = new Config();
      // This config setting makes sure we can handle pref lines without
      // '=' chars in them. Such prefs will be treated as having value null.
      config.setEmptyOption(true);
      // This config setting makes sure we can handle pref lines with '\' in them.
      config.setEscape(false);
      Ini ini = new Ini();
      ini.setConfig(config);
      ini.load(new StringReader(Joiner.on("\n").join(filteredLines)));
      return ini;
    } catch (IOException e) {
      throw Throwables.propagate(e);
    }
  }

  public void set(String section, String key, Object value) {
    set(new FilePreference(this, section, key, value));
  }

  public void set(OperaPreference preference) {
    if (!(preference instanceof FilePreference)) {
      super.set(FilePreference.convert(this, preference));
    } else {
      super.set(preference);
    }

    write();
  }

  /**
   * Call this to cause the current preferences representation to be written to disk.  This method
   * is called by {@link FilePreference#setValue(Object)} and it is thus not necessary to call this
   * method separately unless you wish to perform a forced write of the cache to disk.
   */
  public void write() {
    try {
      Wini ini = new Wini(preferenceFile);

      for (OperaPreference p : this) {
        ini.put(p.getSection(), p.getKey(), ((AbstractPreference) p).getValue(true));
      }

      ini.store(preferenceFile);
    } catch (IOException e) {
      throw new WebDriverException("Unable to write to preference file: " + e.getMessage());
    }
  }

  /**
   * Allows setting Opera preferences in a preference file (typically <code>opera.ini</code> or
   * <code>operaprefs.ini</code>) as well as keeping the local individual preference cache
   * up-to-date.
   */
  public static class FilePreference extends AbstractPreference {

    private OperaFilePreferences parent;

    public FilePreference(OperaFilePreferences parent, String section, String key, Object value) {
      super(section, key, value);
      this.parent = parent;
    }

    /**
     * Sets the value of this preference to the given value.  Writes the preference to file
     * immediately after updating the local cache.
     *
     * @param value the new value
     */
    public void setValue(Object value) {
      super.setValue(value);
      parent.write();
    }

    public static FilePreference convert(OperaFilePreferences parent,
                                         OperaPreferences.OperaPreference convertee) {
      return new FilePreference(parent,
                                convertee.getSection(),
                                convertee.getKey(),
                                convertee.getValue());
    }

  }

}
TOP

Related Classes of com.opera.core.systems.preferences.OperaFilePreferences

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.