es.gob.afirma.keystores.mozilla.NSPreferences Maven / Gradle / Ivy
/* Copyright (C) 2011 [Gobierno de Espana]
* This file is part of "Cliente @Firma".
* "Cliente @Firma" is free software; you can redistribute it and/or modify it under the terms of:
* - the GNU General Public License as published by the Free Software Foundation;
* either version 2 of the License, or (at your option) any later version.
* - or The European Software License; either version 1.1 or (at your option) any later version.
* You may contact the copyright holder at: [email protected]
*/
package es.gob.afirma.keystores.mozilla;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import es.gob.afirma.core.misc.BoundedBufferedReader;
/** Métodos de utilidad para Mozilla Firefox y Nestcape.
* Inspirada en la clase com.sun.deploy.net.proxy.NSPreferences de Sun
* Microsystems. */
final class NSPreferences {
private NSPreferences() {
// No permitimos la instanciacion
}
/** Devuelve el directorio del perfil activo de Firefox. Si no hubiese perfil
* activo, devolvería el directorio del perfil por defecto y si
* tampoco lo hubiese, el del primer perfil encontrado. Si no hubiese
* perfiles configurados, devolvería {@code null}.
* @param iniFile Fichero con la información de los perfiles de Firefox.
* @return Directorio con la información del perfil.
* @throws IOException Cuando ocurre un error abriendo o leyendo el fichero. */
static String getFireFoxUserProfileDirectory(final File iniFile) throws IOException {
if (iniFile == null) {
throw new IllegalArgumentException(
"El fichero INI es nulo y no se podra determinar el directorio del usuario de Firefox" //$NON-NLS-1$
);
}
if (!iniFile.exists() || !iniFile.isFile()) {
throw new IOException(
"No se ha encontrado el fichero con los perfiles de Firefox en: " + iniFile //$NON-NLS-1$
);
}
String currentProfilePath = null;
// Leemos el fichero con la informacion de los perfiles y buscamos el
// activo(el que esta bloqueado)
final FirefoxProfile[] profiles = readProfiles(iniFile);
for (final FirefoxProfile profile : profiles) {
if (isProfileLocked(profile)) {
currentProfilePath = profile.getAbsolutePath();
break;
}
}
// Si no hay ninguno actualmente activo, tomamos el por defecto
if (currentProfilePath == null) {
for (final FirefoxProfile profile : profiles) {
if (profile.isDefault()) {
currentProfilePath = profile.getAbsolutePath();
break;
}
}
}
// Si no hay ninguno por defecto, se toma el primero
if (profiles.length > 0) {
currentProfilePath = profiles[0].getAbsolutePath();
}
return currentProfilePath;
}
/** Analiza la información de los perfiles declarada en el fichero
* "profiles.ini". Para identificar correctamente los perfiles es necesario
* que haya al menos una línea de separación entre los bloques
* de información de cada perfil.
* @param iniFile Fichero con la información de los perfiles.
* @return Listado de perfiles completos encontrados.
* @throws IOException Cuando se produce un error durante la lectura de la
* configuración. */
private static FirefoxProfile[] readProfiles(final File iniFile) throws IOException {
final String nameAtr = "name="; //$NON-NLS-1$
final String isRelativeAtr = "isrelative="; //$NON-NLS-1$
final String pathProfilesAtr = "path="; //$NON-NLS-1$
final String isDefaultAtr = "default="; //$NON-NLS-1$
String line = null;
final List profiles = new ArrayList<>();
try (
final BufferedReader in = new BoundedBufferedReader(
new FileReader(iniFile),
1024, // Maximo 1024 lineas
4096 // Maximo 4KB por linea
);
) {
while ((line = in.readLine()) != null) {
// Buscamos un nuevo bloque de perfil
if (!line.trim().toLowerCase().startsWith("[profile")) { //$NON-NLS-1$
continue;
}
final FirefoxProfile profile = new FirefoxProfile();
while ((line = in.readLine()) != null && line.trim().length() > 0 && !line.trim().toLowerCase().startsWith("[profile")) { //$NON-NLS-1$
if (line.trim().toLowerCase().startsWith(nameAtr)) {
profile.setName(line.trim().substring(nameAtr.length()));
}
else if (line.trim().toLowerCase().startsWith(isRelativeAtr)) {
profile.setRelative(
line.trim().substring(isRelativeAtr.length()).equals("1") //$NON-NLS-1$
);
}
else if (line.trim().toLowerCase().startsWith(pathProfilesAtr)) {
profile.setPath(
line.trim().substring(pathProfilesAtr.length())
);
}
else if (line.trim().toLowerCase().startsWith(isDefaultAtr)) {
profile.setDefault(
line.trim().substring(isDefaultAtr.length()).equals("1") //$NON-NLS-1$
);
}
else {
break;
}
}
// Debemos encontrar al menos el nombre y la ruta del perfil
if (profile.getName() != null || profile.getPath() != null) {
profile.setAbsolutePath(profile.isRelative() ?
new File(iniFile.getParent(), profile.getPath()).toString() :
profile.getPath());
profiles.add(profile);
}
}
}
return profiles.toArray(new FirefoxProfile[profiles.size()]);
}
/** Comprueba si un perfil de Firefox esté bloqueado. Un perfil esta
* bloqueado cuando en su directorio se encuentra el fichero "parent.lock".
* @param profile Información del perfil de Firefox.
* @return Devuelve {@code true} si el perfil esta bloqueado, {@code false} en caso contrario. */
private static boolean isProfileLocked(final FirefoxProfile profile) {
return new File(profile.getAbsolutePath(), "parent.lock").exists() || // En Windows //$NON-NLS-1$
new File(profile.getAbsolutePath(), "lock").exists(); // En UNIX //$NON-NLS-1$
}
/** Almacena la configuración para la identificacion de un
* perfil de Mozilla Firefox. */
static final class FirefoxProfile {
private String name = null;
String getName() {
return this.name;
}
void setName(final String n) {
this.name = n;
}
private boolean relative = true;
boolean isRelative() {
return this.relative;
}
void setRelative(final boolean r) {
this.relative = r;
}
private String path = null;
String getPath() {
return this.path;
}
void setPath(final String p) {
this.path = p;
}
private String absolutePath = null;
String getAbsolutePath() {
return this.absolutePath;
}
void setAbsolutePath(final String ap) {
this.absolutePath = ap;
}
private boolean def = false;
boolean isDefault() {
return this.def;
}
void setDefault(final boolean d) {
this.def = d;
}
}
}