/*
* Freeplane - mind map editor
* Copyright (C) 2008 Joerg Mueller, Daniel Polansky, Christian Foltin, Dimitry Polivaev
*
* This file is created by Dimitry Polivaev in 2008.
*
* 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, or
* (at your option) any later version.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
package org.freeplane.main.application;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Properties;
import org.freeplane.core.resources.IFreeplanePropertyListener;
import org.freeplane.core.resources.ResourceBundles;
import org.freeplane.core.resources.ResourceController;
import org.freeplane.core.util.Compat;
import org.freeplane.core.util.FileUtils;
import org.freeplane.core.util.FreeplaneVersion;
import org.freeplane.features.filter.FilterController;
/**
* @author Dimitry Polivaev
*/
public class ApplicationResourceController extends ResourceController {
private static final String FREEPLANE_MAC_PROPERTIES = "/freeplane_mac.properties";
final private File autoPropertiesFile;
final private Properties defProps;
private LastOpenedList lastOpened;
final private Properties props;
final private ClassLoader urlResourceLoader;
/**
* @param controller
*/
public ApplicationResourceController() {
super();
defProps = readDefaultPreferences();
props = readUsersPreferences(defProps);
final File userDir = createUserDirectory(defProps);
final ArrayList<URL> urls = new ArrayList<URL>(2);
final String resourceBaseDir = getResourceBaseDir();
if (resourceBaseDir != null) {
try {
final File userResourceDir = new File(userDir, "resources");
if (userResourceDir.exists()) {
final URL userResourceUrl = Compat.fileToUrl(userResourceDir);
urls.add(userResourceUrl);
}
final File resourceDir = new File(resourceBaseDir);
if (resourceDir.exists()) {
final URL globalResourceUrl = Compat.fileToUrl(resourceDir);
urls.add(globalResourceUrl);
}
}
catch (final Exception e) {
e.printStackTrace();
}
}
if(urls.size() > 0)
urlResourceLoader = new URLClassLoader(urls.toArray(new URL[]{}), null);
else
urlResourceLoader = null;
setDefaultLocale(props);
autoPropertiesFile = getUserPreferencesFile();
addPropertyChangeListener(new IFreeplanePropertyListener() {
public void propertyChanged(final String propertyName, final String newValue, final String oldValue) {
if (propertyName.equals(ResourceBundles.RESOURCE_LANGUAGE)) {
loadAnotherLanguage();
}
}
});
}
private File createUserDirectory(final Properties pDefaultProperties) {
final File userPropertiesFolder = new File(getFreeplaneUserDirectory());
try {
if (!userPropertiesFolder.exists()) {
userPropertiesFolder.mkdirs();
}
return userPropertiesFolder;
}
catch (final Exception e) {
e.printStackTrace();
System.err.println("Cannot create folder for user properties and logging: '"
+ userPropertiesFolder.getAbsolutePath() + "'");
return null;
}
}
@Override
public String getDefaultProperty(final String key) {
return defProps.getProperty(key);
}
@Override
public String getFreeplaneUserDirectory() {
return Compat.getFreeplaneUserDirectory();
}
public LastOpenedList getLastOpenedList() {
return lastOpened;
}
@Override
public Properties getProperties() {
return props;
}
@Override
public String getProperty(final String key) {
return props.getProperty(key);
}
@Override
public URL getResource(final String name) {
if (urlResourceLoader == null) {
return super.getResource(name);
}
final String relName;
if (name.startsWith("/")) {
relName = name.substring(1);
}
else {
relName = name;
}
URL resource = urlResourceLoader.getResource(relName);
if (resource != null) {
return resource;
}
resource = super.getResource(name);
if (resource != null) {
return resource;
}
if ("/lib/freeplaneviewer.jar".equals(name)) {
final String rootDir = new File(getResourceBaseDir()).getAbsoluteFile().getParent();
try {
final File try1 = new File(rootDir + "/plugins/org.freeplane.core/lib/freeplaneviewer.jar");
if (try1.exists()) {
return try1.toURL();
}
final File try2 = new File(rootDir + "/lib/freeplaneviewer.jar");
if (try2.exists()) {
return try2.toURL();
}
}
catch (final MalformedURLException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public String getResourceBaseDir() {
return FreeplaneStarter.getResourceBaseDir();
}
@Override
public String getInstallationBaseDir() {
return new File(getResourceBaseDir()).getAbsoluteFile().getParent();
}
public static File getUserPreferencesFile() {
final String freeplaneDirectory = Compat.getFreeplaneUserDirectory();
final File userPropertiesFolder = new File(freeplaneDirectory);
final File autoPropertiesFile = new File(userPropertiesFolder, "auto.properties");
return autoPropertiesFile;
}
@Override
public void init() {
lastOpened = new LastOpenedList();
super.init();
}
private Properties readDefaultPreferences() {
final Properties props = new Properties();
readDefaultPreferences(props, ResourceController.FREEPLANE_PROPERTIES);
if (Compat.isMacOsX()) {
readDefaultPreferences(props, FREEPLANE_MAC_PROPERTIES);
}
final String propsLocs = props.getProperty("load_next_properties", "");
readDefaultPreferences(props, propsLocs.split(";"));
return props;
}
private void readDefaultPreferences(final Properties props, final String[] locArray) {
for (final String loc : locArray) {
readDefaultPreferences(props, loc);
}
}
private void readDefaultPreferences(final Properties props, final String propsLoc) {
final URL defaultPropsURL = getResource(propsLoc);
loadProperties(props, defaultPropsURL);
}
private Properties readUsersPreferences(final Properties defaultPreferences) {
final Properties auto = new Properties(defaultPreferences);
InputStream in = null;
try {
final File autoPropertiesFile = getUserPreferencesFile();
in = new FileInputStream(autoPropertiesFile);
auto.load(in);
}
catch (final Exception ex) {
System.err.println("User properties not found, new file created");
}
finally {
FileUtils.silentlyClose(in);
}
return auto;
}
@Override
public void saveProperties() {
lastOpened.saveProperties();
OutputStream out = null;
try {
out = new FileOutputStream(autoPropertiesFile);
final OutputStreamWriter outputStreamWriter = new OutputStreamWriter(out, "8859_1");
outputStreamWriter.write("#Freeplane ");
outputStreamWriter.write(FreeplaneVersion.getVersion().toString());
outputStreamWriter.write('\n');
outputStreamWriter.flush();
props.store(out, null);
}
catch (final Exception ex) {
}
finally {
if (out != null) {
try {
out.close();
}
catch (final IOException e) {
}
}
}
FilterController.getCurrentFilterController().saveConditions();
}
/**
* @param pProperties
*/
private void setDefaultLocale(final Properties pProperties) {
final String lang = pProperties.getProperty(ResourceBundles.RESOURCE_LANGUAGE);
if (lang == null) {
return;
}
Locale localeDef = null;
switch (lang.length()) {
case 2:
localeDef = new Locale(lang);
break;
case 5:
localeDef = new Locale(lang.substring(0, 1), lang.substring(3, 4));
break;
default:
return;
}
Locale.setDefault(localeDef);
}
@Override
public void setDefaultProperty(final String key, final String value) {
defProps.setProperty(key, value);
}
@Override
public void setProperty(final String key, final String value) {
final String oldValue = getProperty(key);
if (oldValue == value) {
return;
}
if (oldValue != null && oldValue.equals(value)) {
return;
}
props.setProperty(key, value);
firePropertyChanged(key, value, oldValue);
}
}