/*
* Created on 24-Set-2009
* Copyright (C) 2009 by Andrea Vacondio.
*
* This program 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.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.pdfsam.guiclient.configuration.services.xml;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ResourceBundle;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.pdfsam.console.business.ConsoleServicesFacade;
import org.pdfsam.console.utils.FileUtility;
import org.pdfsam.guiclient.configuration.services.ConfigurationService;
import org.pdfsam.guiclient.configuration.services.xml.strategy.BackwardCompatibilityXmlStrategy;
import org.pdfsam.guiclient.configuration.services.xml.strategy.DefaultXmlStrategy;
import org.pdfsam.guiclient.configuration.services.xml.strategy.XmlConfigStrategy;
import org.pdfsam.guiclient.exceptions.ConfigurationException;
import org.pdfsam.guiclient.l10n.LanguageLoader;
import org.pdfsam.guiclient.utils.ThemeUtility;
import org.pdfsam.guiclient.utils.XmlUtility;
import org.pdfsam.i18n.GettextResource;
/**
* Configuration service that reads the configuration from an xml file
*
* @author Andrea Vacondio
*
*/
public class XmlConfigurationService implements ConfigurationService {
private static final Logger log = Logger.getLogger(XmlConfigurationService.class.getPackage().getName());
private static final String VERSION_XPATH = "/pdfsam/@config-version";
public static final String OLD_CONFIGURATION_FILE_NAME = "config.xml";
public static final String CONFIGURATION_FILE_NAME = "pdfsam-config.xml";
public static final int DEFAULT_POOL_SIZE = 3;
public static final String DEFAULT_CONFIG_DIRECTORY = System.getProperty("user.home") + "/.pdfsam";
private ResourceBundle i18nResourceBundle;
private ConsoleServicesFacade consoleServicesFacade;
private boolean checkForUpdates = true;
private boolean playSounds = true;
private boolean askOverwriteConfirmation = true;
private String defaultWorkingDirectory = null;
private String defaultEnvironment = null;
private int thumbCreatorPoolSize = DEFAULT_POOL_SIZE;
private String thumbnailsCreatorIdentifier = "";
private int loggingLevel;
private int lookAndFeel = 0;
private int theme = 0;
private String language;
private String pluginAbsolutePath;
private String configurationFilePath;
public XmlConfigurationService() throws ConfigurationException {
initializeService();
}
/**
* Initialization
*
* @throws ConfigurationException
*/
private void initializeService() throws ConfigurationException {
log.info("Loading configuration..");
File configurationFile = null;
try {
configurationFile = getConfigurationXmlFile(CONFIGURATION_FILE_NAME);
if(configurationFile == null){
configurationFile = getConfigurationXmlFile(OLD_CONFIGURATION_FILE_NAME);
if(configurationFile == null){
throw new ConfigurationException("Unable to find configuration file");
}
}
configurationFilePath = configurationFile.getAbsolutePath();
Document document = XmlUtility.parseXmlFile(configurationFile);
if (document != null) {
// setting up strategy
XmlConfigStrategy strategy = null;
Node node = document.selectSingleNode(VERSION_XPATH);
if (node != null && "2".equals(node.getText().trim())) {
strategy = new DefaultXmlStrategy(document);
} else {
strategy = new BackwardCompatibilityXmlStrategy(document);
}
initializeLocale(strategy);
initializeLookAndFeel(strategy);
initializeLoggingLevel(strategy);
initializePoolSize(strategy);
defaultWorkingDirectory = strategy.getDefaultWorkingDirectoryValue();
defaultEnvironment = strategy.getDefaultEnvironmentValue();
thumbnailsCreatorIdentifier = strategy.getThumbnailsCreatorIdentifierValue();
checkForUpdates = isValidTrueValue(strategy.getCheckForUpdatesValue());
playSounds = isValidTrueValue(strategy.getPlaySoundsValue());
pluginAbsolutePath = strategy.getPluginAbsolutePath();
askOverwriteConfirmation = isValidTrueValue(strategy.getAskOverwriteConfirmation());
consoleServicesFacade = new ConsoleServicesFacade();
strategy.close();
} else {
throw new ConfigurationException("Unable to parse xml configuration file.");
}
} catch (DocumentException e) {
throw new ConfigurationException(e);
} catch (UnsupportedEncodingException ue) {
throw new ConfigurationException(ue);
}
}
/**
* thread pool size initialization
*
* @param strategy
*/
private void initializePoolSize(XmlConfigStrategy strategy) {
String poolSizeString = strategy.getThreadPoolSizeValue();
if (poolSizeString.length() > 0) {
thumbCreatorPoolSize = Integer.parseInt(poolSizeString);
}
}
/**
* locale initialization
*
* @param strategy
*/
private void initializeLocale(XmlConfigStrategy strategy) {
log.info("Getting language...");
language = strategy.getLocaleValue();
if (language.length() <= 0) {
log.warn("Unable to get language ResourceBudle, setting the default language ("
+ LanguageLoader.DEFAULT_LANGUAGE + ").");
language = LanguageLoader.DEFAULT_LANGUAGE;
}
i18nResourceBundle = new LanguageLoader(language, "org.pdfsam.i18n.resources.Messages").getBundle();
}
/**
* theme, look and feel initialization
*
* @param strategy
*/
private void initializeLookAndFeel(XmlConfigStrategy strategy) {
log.info(GettextResource.gettext(i18nResourceBundle, "Setting look and feel..."));
String lookAndFeelString = strategy.getLookAndFeelValue();
if (lookAndFeelString.length() > 0) {
lookAndFeel = Integer.parseInt(lookAndFeelString);
}
if (ThemeUtility.isPlastic(lookAndFeel)) {
String themeString = strategy.getThemeValue();
if (themeString.length() > 0) {
theme = Integer.parseInt(themeString);
}
}
}
/**
* logging level initlialization
*
* @param strategy
*/
private void initializeLoggingLevel(XmlConfigStrategy strategy) {
log.info(GettextResource.gettext(i18nResourceBundle, "Setting logging level..."));
String logLev = strategy.getLoggingLevelValue();
if (logLev != null && logLev.length() > 0) {
loggingLevel = Integer.parseInt(logLev);
} else {
log.warn(GettextResource.gettext(i18nResourceBundle,
"Unable to find log level, setting to default level (DEBUG)."));
loggingLevel = Level.DEBUG_INT;
}
}
/**
* @param value
* @return true if the input param is "true" or "1"
*/
private boolean isValidTrueValue(String value) {
boolean retVal = Boolean.parseBoolean(value);
if (!retVal) {
retVal = "1".equals(value);
}
return retVal;
}
/**
* It search the config file.
* <ul>
* <li>the first try uses secondaryPath=main jar path</li>
* <li>the second try uses secondaryPath=System.getProperty("user.dir")</li>
* </ul>
*
* @param configurationFileName file name to search
* @return the configuration file
* @throws UnsupportedEncodingException
* @throws ConfigurationException
*/
private File getConfigurationXmlFile(String configurationFileName) throws UnsupportedEncodingException, ConfigurationException {
File retVal = null;
String configSearchPath = new File(URLDecoder.decode(getClass().getProtectionDomain().getCodeSource()
.getLocation().getPath(), "UTF-8")).getParent();
retVal = searchConfigurationFile(configSearchPath, configurationFileName);
if(retVal == null){
log.warn("Unable to find "+configurationFileName+" into " + configSearchPath);
configSearchPath = System.getProperty("user.dir");
log.info("Looking for "+configurationFileName+" into " + configSearchPath);
retVal = searchConfigurationFile(configSearchPath, configurationFileName);
}
return retVal;
}
/**
* Search the configuration file
* <ul>
* <li>in ${user.home}/.pdfsam</li>
* <li>if step 1 fails it search in searchPathIfFails</li>
* <li>if found in step 2 but is write protected it copies the file in
* ${user.home}/.pdfsam</li>
* </ul>
*
* @param searchPathIfFails
* the path to search the configuration file if not found in the
* default path
* @param configurationFileName file name to search
* @return the path of the configuration file
* @throws ConfigurationException
*/
private File searchConfigurationFile(String searchPathIfFails, String configurationFileName) throws ConfigurationException {
File retVal = new File(DEFAULT_CONFIG_DIRECTORY, configurationFileName);
if (!(retVal.exists() && retVal.canWrite())) {
File secondaryPath = new File(searchPathIfFails, configurationFileName);
if (secondaryPath.exists()) {
if (!secondaryPath.canWrite()) {
File defaultPath = new File(DEFAULT_CONFIG_DIRECTORY);
if (defaultPath.mkdirs()) {
log.info("Copying " + configurationFileName + " from " + secondaryPath.getPath() + " to "
+ defaultPath.getPath());
FileUtility.copyFile(secondaryPath, retVal);
} else {
throw new ConfigurationException("Unable to create " + defaultPath);
}
} else {
retVal = secondaryPath;
}
} else {
retVal = null;
}
}
return retVal;
}
public boolean isCheckForUpdates() {
return checkForUpdates;
}
public void setCheckForUpdates(boolean checkForUpdates) {
this.checkForUpdates = checkForUpdates;
}
public boolean isPlaySounds() {
return playSounds;
}
public void setPlaySounds(boolean playSounds) {
this.playSounds = playSounds;
}
public String getDefaultWorkingDirectory() {
return defaultWorkingDirectory;
}
public void setDefaultWorkingDirectory(String defaultWorkingDirectory) {
this.defaultWorkingDirectory = defaultWorkingDirectory;
}
public String getDefaultEnvironment() {
return defaultEnvironment;
}
public void setDefaultEnvironment(String defaultEnvironment) {
this.defaultEnvironment = defaultEnvironment;
}
public int getThumbCreatorPoolSize() {
return thumbCreatorPoolSize;
}
public void setThumbCreatorPoolSize(int thumbCreatorPoolSize) {
this.thumbCreatorPoolSize = thumbCreatorPoolSize;
}
public String getThumbnailsCreatorIdentifier() {
return thumbnailsCreatorIdentifier;
}
public void setThumbnailsCreatorIdentifier(String thumbnailsCreatorIdentifier) {
this.thumbnailsCreatorIdentifier = thumbnailsCreatorIdentifier;
}
public int getLoggingLevel() {
return loggingLevel;
}
public void setLoggingLevel(int loggingLevel) {
this.loggingLevel = loggingLevel;
}
public ResourceBundle getI18nResourceBundle() {
return i18nResourceBundle;
}
public ConsoleServicesFacade getConsoleServicesFacade() {
return consoleServicesFacade;
}
public int getLookAndFeel() {
return lookAndFeel;
}
public void setLookAndFeel(int lookAndFeel) {
this.lookAndFeel = lookAndFeel;
}
public int getTheme() {
return theme;
}
public void setTheme(int theme) {
this.theme = theme;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getConfigurationInformations() {
return configurationFilePath;
}
public String getPluginAbsolutePath() {
return pluginAbsolutePath;
}
public boolean isAskOverwriteConfirmation() {
return askOverwriteConfirmation;
}
public void setAskOverwriteConfirmation(boolean askOverwriteConfirmation) {
this.askOverwriteConfirmation = askOverwriteConfirmation;
}
public void save() throws IOException {
File defaultPath = new File(DEFAULT_CONFIG_DIRECTORY);
if (!defaultPath.exists() || !defaultPath.isDirectory()) {
defaultPath.mkdirs();
}
DefaultXmlStrategy.saveXmlConfigurationFile(new File(defaultPath, CONFIGURATION_FILE_NAME), this);
}
}