src/core/net/sf/basedb/util/extensions/manager/Settings.java

Code
Comments
Other
Rev Date Author Line
4168 04 Mar 08 nicklas 1 /**
4478 05 Sep 08 jari 2   $Id$
4168 04 Mar 08 nicklas 3
4168 04 Mar 08 nicklas 4   Copyright (C) Authors contributing to this file.
4168 04 Mar 08 nicklas 5
4168 04 Mar 08 nicklas 6   This file is part of BASE - BioArray Software Environment.
4168 04 Mar 08 nicklas 7   Available at http://base.thep.lu.se/
4168 04 Mar 08 nicklas 8
4168 04 Mar 08 nicklas 9   BASE is free software; you can redistribute it and/or
4168 04 Mar 08 nicklas 10   modify it under the terms of the GNU General Public License
4478 05 Sep 08 jari 11   as published by the Free Software Foundation; either version 3
4168 04 Mar 08 nicklas 12   of the License, or (at your option) any later version.
4168 04 Mar 08 nicklas 13
4168 04 Mar 08 nicklas 14   BASE is distributed in the hope that it will be useful,
4168 04 Mar 08 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
4168 04 Mar 08 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4168 04 Mar 08 nicklas 17   GNU General Public License for more details.
4168 04 Mar 08 nicklas 18
4168 04 Mar 08 nicklas 19   You should have received a copy of the GNU General Public License
4512 11 Sep 08 jari 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
4168 04 Mar 08 nicklas 21 */
5606 14 Apr 11 nicklas 22 package net.sf.basedb.util.extensions.manager;
4168 04 Mar 08 nicklas 23
4168 04 Mar 08 nicklas 24 import java.io.BufferedInputStream;
4168 04 Mar 08 nicklas 25 import java.io.File;
4168 04 Mar 08 nicklas 26 import java.io.FileInputStream;
4168 04 Mar 08 nicklas 27 import java.io.FileOutputStream;
4168 04 Mar 08 nicklas 28 import java.io.IOException;
4168 04 Mar 08 nicklas 29 import java.io.InputStream;
4168 04 Mar 08 nicklas 30 import java.io.OutputStream;
5616 27 Apr 11 nicklas 31 import java.util.ArrayList;
5616 27 Apr 11 nicklas 32 import java.util.List;
4168 04 Mar 08 nicklas 33
8107 23 Jan 23 nicklas 34 import net.sf.basedb.core.Config;
4168 04 Mar 08 nicklas 35 import net.sf.basedb.core.Presets;
4168 04 Mar 08 nicklas 36 import net.sf.basedb.core.Presets.Preset;
5615 19 Apr 11 nicklas 37 import net.sf.basedb.util.Values;
4168 04 Mar 08 nicklas 38 import net.sf.basedb.util.extensions.DefaultFilter;
4168 04 Mar 08 nicklas 39 import net.sf.basedb.util.extensions.Extension;
4168 04 Mar 08 nicklas 40 import net.sf.basedb.util.extensions.ExtensionPoint;
4168 04 Mar 08 nicklas 41 import net.sf.basedb.util.extensions.ExtensionsFilter;
4170 07 Mar 08 nicklas 42 import net.sf.basedb.util.extensions.Registry;
4168 04 Mar 08 nicklas 43
4168 04 Mar 08 nicklas 44 /**
4198 28 Mar 08 nicklas 45   Class for keeping settings for the extensions system. Settings
5606 14 Apr 11 nicklas 46   are kept in the <code>settings.xml</code> file in the plug-ins
5606 14 Apr 11 nicklas 47   directory.
4170 07 Mar 08 nicklas 48   <p>
4170 07 Mar 08 nicklas 49
4170 07 Mar 08 nicklas 50   Extension points and extensions can be disabled/enabled by
4170 07 Mar 08 nicklas 51   {@link #enableExtensionPoint(String, boolean)} and 
4198 28 Mar 08 nicklas 52   {@link #enableExtension(String, boolean)}.
4170 07 Mar 08 nicklas 53   <p>
4198 28 Mar 08 nicklas 54
4170 07 Mar 08 nicklas 55   This class also implements the {@link ExtensionsFilter}
4170 07 Mar 08 nicklas 56   interface, and can be used on the 
4207 04 Apr 08 nicklas 57   {@link Registry#useExtensions(net.sf.basedb.util.extensions.ClientContext, ExtensionsFilter, String...)}
4170 07 Mar 08 nicklas 58   method. This means that disabling/enabling extensions and extension points 
4198 28 Mar 08 nicklas 59   will immediately be visible in the web interface. Sorting is delegated
4198 28 Mar 08 nicklas 60   to the {@link DefaultFilter}.
4170 07 Mar 08 nicklas 61
4170 07 Mar 08 nicklas 62   @author nicklas
4170 07 Mar 08 nicklas 63   @version 2.7
4198 28 Mar 08 nicklas 64   @base.modified $Date:2008-03-20 12:15:25 +0100 (Thu, 20 Mar 2008) $
4168 04 Mar 08 nicklas 65 */
4168 04 Mar 08 nicklas 66 public class Settings 
4168 04 Mar 08 nicklas 67   extends DefaultFilter
4168 04 Mar 08 nicklas 68   implements ExtensionsFilter 
4168 04 Mar 08 nicklas 69 {
4181 18 Mar 08 nicklas 70   
4180 17 Mar 08 nicklas 71   private final File file;
5606 14 Apr 11 nicklas 72   private final ExtensionsManager manager;
8107 23 Jan 23 nicklas 73   private final String pluginsDir;
8107 23 Jan 23 nicklas 74   private final String userFilesDir;
4170 07 Mar 08 nicklas 75   private boolean hasChanged;
4168 04 Mar 08 nicklas 76   private Presets presets;
4168 04 Mar 08 nicklas 77   private Preset settings;
5616 27 Apr 11 nicklas 78   private Preset installedFiles;
7231 16 Nov 16 nicklas 79   private Preset ignoredFiles;
4168 04 Mar 08 nicklas 80   private Preset disabledExtensions;
4168 04 Mar 08 nicklas 81   private Preset disabledExtensionPoints;
4168 04 Mar 08 nicklas 82   
4198 28 Mar 08 nicklas 83   /**
4198 28 Mar 08 nicklas 84     Create a new Settings object. If the given file doesn't exists
4198 28 Mar 08 nicklas 85     it will be created if {@link #save()} is called. The settings file
4198 28 Mar 08 nicklas 86     must be an XML file that can be read by the {@link Presets} class.
5606 14 Apr 11 nicklas 87     @param file The file to load/save settings in. If null, settings only are 
5606 14 Apr 11 nicklas 88       kept in memory and are lost when the server is shutdown.
4198 28 Mar 08 nicklas 89   */
5606 14 Apr 11 nicklas 90   Settings(ExtensionsManager manager, File file)
4168 04 Mar 08 nicklas 91   {
5606 14 Apr 11 nicklas 92     this.manager = manager;
4180 17 Mar 08 nicklas 93     this.file = file;
8107 23 Jan 23 nicklas 94     this.pluginsDir = new File(Config.getString("plugins.dir")).getAbsolutePath();
8107 23 Jan 23 nicklas 95     this.userFilesDir = new File(Config.getString("userfiles")).getAbsolutePath();
4168 04 Mar 08 nicklas 96     this.presets = new Presets();
5606 14 Apr 11 nicklas 97     if (file != null && file.isFile())
4168 04 Mar 08 nicklas 98     {
4180 17 Mar 08 nicklas 99       try
4180 17 Mar 08 nicklas 100       {
4180 17 Mar 08 nicklas 101         InputStream in = new BufferedInputStream(new FileInputStream(file));
4180 17 Mar 08 nicklas 102         presets.loadFrom(in, file.getAbsolutePath());
4180 17 Mar 08 nicklas 103         in.close();
4180 17 Mar 08 nicklas 104       }
4180 17 Mar 08 nicklas 105       catch (IOException ex)
4180 17 Mar 08 nicklas 106       {
4180 17 Mar 08 nicklas 107         throw new RuntimeException(ex);
4180 17 Mar 08 nicklas 108       }
4168 04 Mar 08 nicklas 109     }
4168 04 Mar 08 nicklas 110     this.settings = presets.getDefault();
8107 23 Jan 23 nicklas 111     this.installedFiles = fixPaths(presets.getPreset("installed-files"));
8107 23 Jan 23 nicklas 112     this.ignoredFiles = fixPaths(presets.getPreset("ignored-files"));
4168 04 Mar 08 nicklas 113     this.disabledExtensionPoints = presets.getPreset("disabled-extension-points");
4168 04 Mar 08 nicklas 114     this.disabledExtensions = presets.getPreset("disabled-extensions");
4170 07 Mar 08 nicklas 115     hasChanged = false;
4168 04 Mar 08 nicklas 116   }
4168 04 Mar 08 nicklas 117   
4168 04 Mar 08 nicklas 118   /*
4168 04 Mar 08 nicklas 119     From the ExtensionsFilter interface
4168 04 Mar 08 nicklas 120     -----------------------------------
4168 04 Mar 08 nicklas 121   */
4168 04 Mar 08 nicklas 122   @Override
6875 20 Apr 15 nicklas 123   public boolean isEnabled(ExtensionPoint<?> extensionPoint) 
4168 04 Mar 08 nicklas 124   {
4168 04 Mar 08 nicklas 125     if (extensionPoint == null) return false;
5606 14 Apr 11 nicklas 126     ExtensionsFile xtFile = manager.getFileByObjectKey(new ExtensionPointKey(extensionPoint));
5606 14 Apr 11 nicklas 127     if (xtFile != null && (xtFile.hasError() || !xtFile.isValid())) return false;
4168 04 Mar 08 nicklas 128     return disabledExtensionPoints.getSetting(extensionPoint.getId()) == null;
4168 04 Mar 08 nicklas 129   }
4168 04 Mar 08 nicklas 130
4168 04 Mar 08 nicklas 131   @Override
6875 20 Apr 15 nicklas 132   public boolean isEnabled(Extension<?> extension) 
4168 04 Mar 08 nicklas 133   {
4168 04 Mar 08 nicklas 134     if (extension == null) return false;
5606 14 Apr 11 nicklas 135     ExtensionsFile xtFile = manager.getFileByObjectKey(new ExtensionKey(extension));
5606 14 Apr 11 nicklas 136     if (xtFile != null && (xtFile.hasError() || !xtFile.isValid())) return false;
4168 04 Mar 08 nicklas 137     return disabledExtensions.getSetting(extension.getId()) == null;
4168 04 Mar 08 nicklas 138   }
4168 04 Mar 08 nicklas 139   // --------------------------------------------------
4168 04 Mar 08 nicklas 140
4168 04 Mar 08 nicklas 141   /**
4168 04 Mar 08 nicklas 142     Enable/disable an extension.
4168 04 Mar 08 nicklas 143     @param extensionId The ID of the extension to enable/disable
4168 04 Mar 08 nicklas 144     @param enable TRUE to enable the extension, FALSE to disable it
4168 04 Mar 08 nicklas 145   */
4168 04 Mar 08 nicklas 146   public synchronized void enableExtension(String extensionId, boolean enable)
4168 04 Mar 08 nicklas 147   {
4168 04 Mar 08 nicklas 148     disabledExtensions.setSetting(extensionId, enable ? null : "1");
4170 07 Mar 08 nicklas 149     hasChanged = true;
4168 04 Mar 08 nicklas 150   }
4168 04 Mar 08 nicklas 151   
4168 04 Mar 08 nicklas 152   /**
4168 04 Mar 08 nicklas 153     Enable/disable an extension point.
4168 04 Mar 08 nicklas 154     @param extensionPointId The ID of the extension point to enable/disable
4168 04 Mar 08 nicklas 155     @param enable TRUE to enable the extension point, FALSE to disable it
4168 04 Mar 08 nicklas 156   */
4168 04 Mar 08 nicklas 157   public synchronized void enableExtensionPoint(String extensionPointId, boolean enable)
4168 04 Mar 08 nicklas 158   {
4168 04 Mar 08 nicklas 159     disabledExtensionPoints.setSetting(extensionPointId, enable ? null : "1");
4170 07 Mar 08 nicklas 160     hasChanged = true;
4168 04 Mar 08 nicklas 161   }
4168 04 Mar 08 nicklas 162   
5616 27 Apr 11 nicklas 163   /**
6627 25 Nov 14 nicklas 164     Get a preset containing settings for the given extesion. If no
6627 25 Nov 14 nicklas 165     settings exists, null is returned. Do not make modifications to
6627 25 Nov 14 nicklas 166     the returned preset since the result is undefined. Use
6627 25 Nov 14 nicklas 167     {@link #setSetting(String, String, String)} to set values.
6627 25 Nov 14 nicklas 168     @since 3.4
6627 25 Nov 14 nicklas 169   */
6627 25 Nov 14 nicklas 170   public Preset getSettingsForExtension(String extensionId)
6627 25 Nov 14 nicklas 171   {
6627 25 Nov 14 nicklas 172     return presets.exists(extensionId) ? presets.getPreset(extensionId) : null;
6627 25 Nov 14 nicklas 173   }
6627 25 Nov 14 nicklas 174   
6627 25 Nov 14 nicklas 175   /**
6627 25 Nov 14 nicklas 176     Set a configuration setting for an extension. Do not forget to
6627 25 Nov 14 nicklas 177     {@link #save()}.
6627 25 Nov 14 nicklas 178     @param extensionId The ID of the extension to save a setting for
6627 25 Nov 14 nicklas 179     @param key The name of the setting
6627 25 Nov 14 nicklas 180     @param value The value of the setting, use null to remove
6627 25 Nov 14 nicklas 181     @since 3.4
6627 25 Nov 14 nicklas 182   */
6627 25 Nov 14 nicklas 183   public synchronized void setSetting(String extensionId, String key, String value)
6627 25 Nov 14 nicklas 184   {
6627 25 Nov 14 nicklas 185     if (value == null && !presets.exists(extensionId)) return;
6627 25 Nov 14 nicklas 186     
6627 25 Nov 14 nicklas 187     Preset p = presets.getPreset(extensionId);
6627 25 Nov 14 nicklas 188     p.setSetting(key, value);
6627 25 Nov 14 nicklas 189     if (p.size() == 0) presets.deletePreset(extensionId);
6627 25 Nov 14 nicklas 190     hasChanged = true;
6627 25 Nov 14 nicklas 191   }
6627 25 Nov 14 nicklas 192
6627 25 Nov 14 nicklas 193   /**
6627 25 Nov 14 nicklas 194     Get a configuration setting for an extension.
6627 25 Nov 14 nicklas 195     @param extensionId The ID of the extension to save a setting for
6627 25 Nov 14 nicklas 196     @param key The name of the setting
6627 25 Nov 14 nicklas 197     @return The value or null if it doesn't exists
6627 25 Nov 14 nicklas 198     @since 3.4
6627 25 Nov 14 nicklas 199   */
6627 25 Nov 14 nicklas 200   public String getSetting(String extensionId, String key)
6627 25 Nov 14 nicklas 201   {
6627 25 Nov 14 nicklas 202     Preset p = getSettingsForExtension(extensionId);
6627 25 Nov 14 nicklas 203     return p == null ? null : p.getSetting(key);
6627 25 Nov 14 nicklas 204   }
6627 25 Nov 14 nicklas 205   
6627 25 Nov 14 nicklas 206   /**
8107 23 Jan 23 nicklas 207     A file is typically stored under the absolute path, but
8107 23 Jan 23 nicklas 208     if it matches the plug-ins directory we replace it with {plugins.dir}.
8107 23 Jan 23 nicklas 209     @since 3.19.6
8107 23 Jan 23 nicklas 210   */
8107 23 Jan 23 nicklas 211   private String toKey(File file)
8107 23 Jan 23 nicklas 212   {
8107 23 Jan 23 nicklas 213     String key = file.getAbsolutePath();
8107 23 Jan 23 nicklas 214     if (pluginsDir != null) key = key.replace(pluginsDir, "{plugins.dir}");
8107 23 Jan 23 nicklas 215     if (userFilesDir != null) key = key.replace(userFilesDir, "{userfiles.dir}");
8107 23 Jan 23 nicklas 216     return key;
8107 23 Jan 23 nicklas 217   }
8107 23 Jan 23 nicklas 218   
8107 23 Jan 23 nicklas 219   /**
8107 23 Jan 23 nicklas 220     A file is typically stored under the absolute path, but
8107 23 Jan 23 nicklas 221     if it matches the plug-ins directory we replace it with {plugins.dir}.
8107 23 Jan 23 nicklas 222     @since 3.19.6
8107 23 Jan 23 nicklas 223   */
8107 23 Jan 23 nicklas 224   private File toFile(String key)
8107 23 Jan 23 nicklas 225   {
8107 23 Jan 23 nicklas 226     if (pluginsDir != null) key = key.replace("{plugins.dir}", pluginsDir);
8107 23 Jan 23 nicklas 227     if (userFilesDir != null) key = key.replace("{userfiles.dir}", userFilesDir);
8107 23 Jan 23 nicklas 228     return new File(key);
8107 23 Jan 23 nicklas 229   }
8107 23 Jan 23 nicklas 230   
8107 23 Jan 23 nicklas 231   /**
8107 23 Jan 23 nicklas 232     Fix paths in older config files. This code can be removed some time in the future when
8107 23 Jan 23 nicklas 233     we are sure that everyone has upgraded. Eg. in BASE 3.21 since we must allow upgrades 
8107 23 Jan 23 nicklas 234     between BASE 3.19.x and BASE 3.20.x.
8107 23 Jan 23 nicklas 235   */
8107 23 Jan 23 nicklas 236   private Preset fixPaths(Preset preset)
8107 23 Jan 23 nicklas 237   {
8107 23 Jan 23 nicklas 238     for (String key : preset.getKeys())
8107 23 Jan 23 nicklas 239     {
8107 23 Jan 23 nicklas 240       if (key.contains(pluginsDir))
8107 23 Jan 23 nicklas 241       {
8107 23 Jan 23 nicklas 242         preset.setSetting(key.replace(pluginsDir, "{plugins.dir}"), preset.getSetting(key));
8107 23 Jan 23 nicklas 243         preset.setSetting(key, null);
8107 23 Jan 23 nicklas 244         hasChanged = true;
8107 23 Jan 23 nicklas 245       }
8107 23 Jan 23 nicklas 246       else if (key.contains(userFilesDir))
8107 23 Jan 23 nicklas 247       {
8107 23 Jan 23 nicklas 248         preset.setSetting(key.replace(userFilesDir, "{userfiles.dir}"), preset.getSetting(key));
8107 23 Jan 23 nicklas 249         preset.setSetting(key, null);
8107 23 Jan 23 nicklas 250         hasChanged = true;
8107 23 Jan 23 nicklas 251       }
8107 23 Jan 23 nicklas 252     }
8107 23 Jan 23 nicklas 253     return preset;
8107 23 Jan 23 nicklas 254   }
8107 23 Jan 23 nicklas 255   
8107 23 Jan 23 nicklas 256   /**
5616 27 Apr 11 nicklas 257     Check if the given file is marked as installed.
5616 27 Apr 11 nicklas 258     @since 3.0
5616 27 Apr 11 nicklas 259   */
5616 27 Apr 11 nicklas 260   public boolean isInstalledFile(File file)
5615 19 Apr 11 nicklas 261   {
8107 23 Jan 23 nicklas 262     String key = toKey(file);
8107 23 Jan 23 nicklas 263     return Values.getBoolean(installedFiles.getSetting(key));
5615 19 Apr 11 nicklas 264   }
5615 19 Apr 11 nicklas 265   
5616 27 Apr 11 nicklas 266   /**
5616 27 Apr 11 nicklas 267     Mark the given file as installed by the extension system.
5616 27 Apr 11 nicklas 268     @since 3.0
5616 27 Apr 11 nicklas 269   */
5616 27 Apr 11 nicklas 270   public void setInstalledFile(File file)
5615 19 Apr 11 nicklas 271   {
5616 27 Apr 11 nicklas 272     if (file == null) return;
5615 19 Apr 11 nicklas 273     hasChanged = true;
8107 23 Jan 23 nicklas 274     installedFiles.setSetting(toKey(file), "1");
5615 19 Apr 11 nicklas 275   }
5615 19 Apr 11 nicklas 276   
5616 27 Apr 11 nicklas 277   /**
5616 27 Apr 11 nicklas 278     Mark the given file as uninstalled.
5616 27 Apr 11 nicklas 279     @since 3.0
5616 27 Apr 11 nicklas 280   */
5616 27 Apr 11 nicklas 281   public void setUninstalledFile(File file)
5615 19 Apr 11 nicklas 282   {
5616 27 Apr 11 nicklas 283     if (file == null) return;
5615 19 Apr 11 nicklas 284     hasChanged = true;
8107 23 Jan 23 nicklas 285     installedFiles.setSetting(toKey(file), null);
5615 19 Apr 11 nicklas 286   }
5615 19 Apr 11 nicklas 287   
4198 28 Mar 08 nicklas 288   /**
5616 27 Apr 11 nicklas 289     Get a list with all files that are installed.
5616 27 Apr 11 nicklas 290     @since 3.0
5616 27 Apr 11 nicklas 291   */
5616 27 Apr 11 nicklas 292   public List<File> getInstalledFiles()
5616 27 Apr 11 nicklas 293   {
8107 23 Jan 23 nicklas 294     List<String> keys = installedFiles.getKeys();
8107 23 Jan 23 nicklas 295     List<File> files = new ArrayList<File>(keys.size());
8107 23 Jan 23 nicklas 296     for (String key : keys)
5616 27 Apr 11 nicklas 297     {
8107 23 Jan 23 nicklas 298       files.add(toFile(key));
5616 27 Apr 11 nicklas 299     }
5616 27 Apr 11 nicklas 300     return files;
5616 27 Apr 11 nicklas 301   }
5616 27 Apr 11 nicklas 302   
5616 27 Apr 11 nicklas 303   
5616 27 Apr 11 nicklas 304   /**
7231 16 Nov 16 nicklas 305     Check if the given file is marked as ignored.
7231 16 Nov 16 nicklas 306     @since 3.10
7231 16 Nov 16 nicklas 307   */
7231 16 Nov 16 nicklas 308   public boolean isIgnoredFile(File file)
7231 16 Nov 16 nicklas 309   {
8107 23 Jan 23 nicklas 310     return Values.getBoolean(ignoredFiles.getSetting(toKey(file)));
7231 16 Nov 16 nicklas 311   }
7231 16 Nov 16 nicklas 312   
7231 16 Nov 16 nicklas 313   /**
7231 16 Nov 16 nicklas 314     Mark the given file as ignored/not ignored by the extension system.
7231 16 Nov 16 nicklas 315     @since 3.10
7231 16 Nov 16 nicklas 316   */
7231 16 Nov 16 nicklas 317   public void setIgnoredFile(File file, boolean ignore)
7231 16 Nov 16 nicklas 318   {
7231 16 Nov 16 nicklas 319     if (file == null) return;
7231 16 Nov 16 nicklas 320     hasChanged = true;
8107 23 Jan 23 nicklas 321     ignoredFiles.setSetting(toKey(file), ignore ? "1" :  null);
7231 16 Nov 16 nicklas 322   }
7231 16 Nov 16 nicklas 323   
7231 16 Nov 16 nicklas 324   /**
7231 16 Nov 16 nicklas 325     Get a list with all files that are ignored.
7231 16 Nov 16 nicklas 326     @since 3.10
7231 16 Nov 16 nicklas 327   */
7231 16 Nov 16 nicklas 328   public List<File> getIgnoredFiles()
7231 16 Nov 16 nicklas 329   {
8107 23 Jan 23 nicklas 330     List<String> keys = ignoredFiles.getKeys();
8107 23 Jan 23 nicklas 331     List<File> files = new ArrayList<File>(keys.size());
8107 23 Jan 23 nicklas 332     for (String key : keys)
7231 16 Nov 16 nicklas 333     {
8107 23 Jan 23 nicklas 334       files.add(toFile(key));
7231 16 Nov 16 nicklas 335     }
7231 16 Nov 16 nicklas 336     return files;
7231 16 Nov 16 nicklas 337   }
7231 16 Nov 16 nicklas 338   
7231 16 Nov 16 nicklas 339   /**
4170 07 Mar 08 nicklas 340     Save the settings to disk. If the settings has not been
4170 07 Mar 08 nicklas 341     changed the file is not written.
4170 07 Mar 08 nicklas 342   */
4168 04 Mar 08 nicklas 343   public synchronized void save()
4168 04 Mar 08 nicklas 344   {
5606 14 Apr 11 nicklas 345     if (!hasChanged || file == null) return;
4180 17 Mar 08 nicklas 346     try
4180 17 Mar 08 nicklas 347     {
4180 17 Mar 08 nicklas 348       OutputStream out = new FileOutputStream(file);
4180 17 Mar 08 nicklas 349       presets.writeTo(out);
4180 17 Mar 08 nicklas 350       out.close();
4180 17 Mar 08 nicklas 351     }
4180 17 Mar 08 nicklas 352     catch (IOException ex)
4180 17 Mar 08 nicklas 353     {
4180 17 Mar 08 nicklas 354       throw new RuntimeException(ex);
4180 17 Mar 08 nicklas 355     }
5606 14 Apr 11 nicklas 356     hasChanged = false;
4168 04 Mar 08 nicklas 357   }
4168 04 Mar 08 nicklas 358 }