All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.grinder.console.model.ConsoleProperties Maven / Gradle / Ivy

The newest version!
// Copyright (C) 2001 - 2012 Philip Aston
// All rights reserved.
//
// This file is part of The Grinder software distribution. Refer to
// the file LICENSE which is part of The Grinder distribution for
// licensing details. The Grinder distribution is available on the
// Internet at http://grinder.sourceforge.net/
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.

package net.grinder.console.model;

import java.awt.Rectangle;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import net.grinder.common.GrinderProperties;
import net.grinder.communication.CommunicationDefaults;
import net.grinder.console.common.ConsoleException;
import net.grinder.console.common.DisplayMessageConsoleException;
import net.grinder.console.common.Resources;
import net.grinder.util.Directory;


/**
 * Class encapsulating the console options.
 *
 * 

Adds fixed interface and listener mechanism, but delegates to * {@link GrinderProperties} for storage.

* *

Implements the read-only part of {@code Map}.

* * @author Philip Aston */ public final class ConsoleProperties { /** Property name. */ public static final String COLLECT_SAMPLES_PROPERTY = "grinder.console.numberToCollect"; /** Property name. */ public static final String IGNORE_SAMPLES_PROPERTY = "grinder.console.numberToIgnore"; /** Property name. */ public static final String SAMPLE_INTERVAL_PROPERTY = "grinder.console.sampleInterval"; /** Property name. */ public static final String SIG_FIG_PROPERTY = "grinder.console.significantFigures"; /** Property name. */ public static final String CONSOLE_HOST_PROPERTY = "grinder.console.consoleHost"; /** Property name. */ public static final String CONSOLE_PORT_PROPERTY = "grinder.console.consolePort"; /** Property name. */ public static final String HTTP_HOST_PROPERTY = "grinder.console.httpHost"; /** Property name. */ public static final String HTTP_PORT_PROPERTY = "grinder.console.httpPort"; /** Property name. */ public static final String RESET_CONSOLE_WITH_PROCESSES_PROPERTY = "grinder.console.resetConsoleWithProcesses"; /** Property name. */ public static final String RESET_CONSOLE_WITH_PROCESSES_ASK_PROPERTY = "grinder.console.resetConsoleWithProcessesAsk"; /** Property name. */ public static final String PROPERTIES_NOT_SET_ASK_PROPERTY = "grinder.console.propertiesNotSetAsk"; /** Property name. */ public static final String START_WITH_UNSAVED_BUFFERS_ASK_PROPERTY = "grinder.console.startWithUnsavedBuffersAsk"; /** Property name. */ public static final String STOP_PROCESSES_ASK_PROPERTY = "grinder.console.stopProcessesAsk"; /** Property name. */ public static final String DISTRIBUTE_ON_START_ASK_PROPERTY = "grinder.console.distributeAutomaticallyAsk"; /** Property name. */ public static final String PROPERTIES_FILE_PROPERTY = "grinder.console.propertiesFile"; /** Property name. */ public static final String DISTRIBUTION_DIRECTORY_PROPERTY = "grinder.console.scriptDistributionDirectory"; /** Property name. */ public static final String DISTRIBUTION_FILE_FILTER_EXPRESSION_PROPERTY = "grinder.console.distributionFileFilterExpression"; /** * Default regular expression for filtering distribution files. */ public static final String DEFAULT_DISTRIBUTION_FILE_FILTER_EXPRESSION = "^CVS/$|" + "^\\.svn/$|" + "^.*~$|" + "^(out_|error_|data_)\\w+-\\d+\\.log\\d*$"; /** Property name. */ public static final String SCAN_DISTRIBUTION_FILES_PERIOD_PROPERTY = "grinder.console.scanDistributionFilesPeriod"; /** Property name. */ public static final String LOOK_AND_FEEL_PROPERTY = "grinder.console.lookAndFeel"; /** Property name. */ public static final String EXTERNAL_EDITOR_COMMAND_PROPERTY = "grinder.console.externalEditorCommand"; /** Property name. */ public static final String EXTERNAL_EDITOR_ARGUMENTS_PROPERTY = "grinder.console.externalEditorArguments"; /** Property name. */ public static final String FRAME_BOUNDS_PROPERTY = "grinder.console.frameBounds"; /** Property name. */ public static final String SAVE_TOTALS_WITH_RESULTS_PROPERTY = "grinder.console.saveTotalsWithResults"; private final PropertyChangeSupport m_changeSupport = new PropertyChangeSupport(this); private final IntProperty m_collectSampleCount = new IntProperty(COLLECT_SAMPLES_PROPERTY, 0); private final IntProperty m_ignoreSampleCount = new IntProperty(IGNORE_SAMPLES_PROPERTY, 0); private final IntProperty m_sampleInterval = new IntProperty(SAMPLE_INTERVAL_PROPERTY, 1000); private final IntProperty m_significantFigures = new IntProperty(SIG_FIG_PROPERTY, 3); private final BooleanProperty m_resetConsoleWithProcesses = new BooleanProperty(RESET_CONSOLE_WITH_PROCESSES_PROPERTY, false); private final FileProperty m_propertiesFile = new FileProperty(PROPERTIES_FILE_PROPERTY); private final DirectoryProperty m_distributionDirectory = new DirectoryProperty(DISTRIBUTION_DIRECTORY_PROPERTY); private final PatternProperty m_distributionFileFilterPattern = new PatternProperty( DISTRIBUTION_FILE_FILTER_EXPRESSION_PROPERTY, DEFAULT_DISTRIBUTION_FILE_FILTER_EXPRESSION); private final IntProperty m_scanDistributionFilesPeriod = new IntProperty(SCAN_DISTRIBUTION_FILES_PERIOD_PROPERTY, 6000); private final StringProperty m_lookAndFeel = new StringProperty(LOOK_AND_FEEL_PROPERTY, null); private final FileProperty m_externalEditorCommand = new FileProperty(EXTERNAL_EDITOR_COMMAND_PROPERTY); private final StringProperty m_externalEditorArguments = new StringProperty(EXTERNAL_EDITOR_ARGUMENTS_PROPERTY, null); private final RectangleProperty m_frameBounds = new RectangleProperty(FRAME_BOUNDS_PROPERTY); private final BooleanProperty m_resetConsoleWithProcessesAsk = new BooleanProperty(RESET_CONSOLE_WITH_PROCESSES_ASK_PROPERTY, true); private final BooleanProperty m_propertiesNotSetAsk = new BooleanProperty(PROPERTIES_NOT_SET_ASK_PROPERTY, true); private final BooleanProperty m_startWithUnsavedBuffersAsk = new BooleanProperty(START_WITH_UNSAVED_BUFFERS_ASK_PROPERTY, true); private final BooleanProperty m_stopProcessesAsk = new BooleanProperty(STOP_PROCESSES_ASK_PROPERTY, true); private final BooleanProperty m_distributeOnStartAsk = new BooleanProperty(DISTRIBUTE_ON_START_ASK_PROPERTY, true); private final StringProperty m_consoleHost = new StringProperty(CONSOLE_HOST_PROPERTY, CommunicationDefaults.CONSOLE_HOST); private final IntProperty m_consolePort = new IntProperty(CONSOLE_PORT_PROPERTY, CommunicationDefaults.CONSOLE_PORT); private final StringProperty m_httpHost = new StringProperty(HTTP_HOST_PROPERTY, CommunicationDefaults.CONSOLE_HOST); private final IntProperty m_httpPort = new IntProperty(HTTP_PORT_PROPERTY, 6373); private final BooleanProperty m_saveTotalsWithResults = new BooleanProperty(SAVE_TOTALS_WITH_RESULTS_PROPERTY, false); private final Resources m_resources; /** * We delegate to GrinderProperties for storage and the backing file. */ private final GrinderProperties m_backingProperties; /** * Construct a ConsoleProperties backed by the given file. * * @param resources Console resources. * @param file The properties file. * @throws ConsoleException If the properties file * cannot be read or the properties file contains invalid data. * */ public ConsoleProperties(final Resources resources, final File file) throws ConsoleException { m_resources = resources; try { m_backingProperties = new GrinderProperties(file); } catch (final GrinderProperties.PersistenceException e) { throw new DisplayMessageConsoleException( m_resources, "couldNotLoadOptionsError.text", e); } } /** * Copy constructor. Does not copy property change listeners. * * @param properties The properties to copy. */ public ConsoleProperties(final ConsoleProperties properties) { m_resources = properties.m_resources; m_backingProperties = new GrinderProperties(); m_backingProperties.setAssociatedFile( properties.m_backingProperties.getAssociatedFile()); set(properties); } /** * Assignment. Does not copy property change listeners, nor the * associated file. * * @param properties The properties to copy. */ public void set(final ConsoleProperties properties) { m_backingProperties.clear(); m_backingProperties.putAll(properties.m_backingProperties); } /** * Add a {@code PropertyChangeListener}. * * @param listener The listener. */ public void addPropertyChangeListener(final PropertyChangeListener listener) { m_changeSupport.addPropertyChangeListener(listener); } /** * Add a {@code PropertyChangeListener} which listens to a particular * property. * * @param property * The property. * @param listener * The listener. */ public void addPropertyChangeListener( final String property, final PropertyChangeListener listener) { m_changeSupport.addPropertyChangeListener(property, listener); } /** * Save to the associated file. * * @throws ConsoleException If an error occurs. */ public void save() throws ConsoleException { try { m_backingProperties.save(); } catch (final GrinderProperties.PersistenceException e) { throw new DisplayMessageConsoleException( m_resources, "couldNotSaveOptionsError.text", e); } } /** * Get the number of samples to collect. * * @return The number. */ public int getCollectSampleCount() { return m_collectSampleCount.get(); } /** * Set the number of samples to collect. * * @param n The number. 0 => forever. * @throws ConsoleException If the number is negative. */ public void setCollectSampleCount(final int n) throws ConsoleException { if (n < 0) { throw new DisplayMessageConsoleException( m_resources, "collectNegativeError.text"); } m_collectSampleCount.set(n); } /** * Get the number of samples to ignore. * * @return The number. */ public int getIgnoreSampleCount() { return m_ignoreSampleCount.get(); } /** * Set the number of samples to collect. * * @param n The number. Must be positive. * @throws ConsoleException If the number is negative or zero. */ public void setIgnoreSampleCount(final int n) throws ConsoleException { if (n < 0) { throw new DisplayMessageConsoleException( m_resources, "ignoreSamplesNegativeError.text"); } m_ignoreSampleCount.set(n); } /** * Get the sample interval. * * @return The interval in milliseconds. */ public int getSampleInterval() { return m_sampleInterval.get(); } /** * Set the sample interval. * * @param interval The interval in milliseconds. * @throws ConsoleException If the number is negative or zero. */ public void setSampleInterval(final int interval) throws ConsoleException { if (interval <= 0) { throw new DisplayMessageConsoleException( m_resources, "intervalLessThanOneError.text"); } m_sampleInterval.set(interval); } /** * Get the number of significant figures. * * @return The number of significant figures. */ public int getSignificantFigures() { return m_significantFigures.get(); } /** * Set the number of significant figures. * * @param n The number of significant figures. * @throws ConsoleException If the number is negative. */ public void setSignificantFigures(final int n) throws ConsoleException { if (n <= 0) { throw new DisplayMessageConsoleException( m_resources, "significantFiguresNegativeError.text"); } m_significantFigures.set(n); } /** * Get the console host as a string. * * @return The address. */ public String getConsoleHost() { return m_consoleHost.get(); } /** * Validate a unicast IP address. * *

* We treat any address that we can look up as valid. I guess we could also * try binding to it to discover whether it is local, but that could take an * indeterminate amount of time. *

* * @param address The address, as a string. * @throws ConsoleException If the address is invalid. */ private void checkAddress(final String address) throws ConsoleException { if (address.length() > 0) { // Empty string => all local hosts. final InetAddress newAddress; try { newAddress = InetAddress.getByName(address); } catch (final UnknownHostException e) { throw new DisplayMessageConsoleException( m_resources, "unknownHostError.text"); } if (newAddress.isMulticastAddress()) { throw new DisplayMessageConsoleException( m_resources, "invalidHostAddressError.text"); } } } /** * Validate a TCP port. * ** @param port The port. * @throws ConsoleException If the port is invalid. */ private void checkPort(final int port) throws ConsoleException { if (port < CommunicationDefaults.MIN_PORT || port > CommunicationDefaults.MAX_PORT) { throw new DisplayMessageConsoleException( m_resources, "invalidPortNumberError.text", new Object[] { CommunicationDefaults.MIN_PORT, CommunicationDefaults.MAX_PORT, } ); } } /** * Set the console host. * * @param s Either a machine name or the IP address. * @throws ConsoleException If the address is not * valid. */ public void setConsoleHost(final String s) throws ConsoleException { checkAddress(s); m_consoleHost.set(s); } /** * Get the console port. * * @return The port. */ public int getConsolePort() { return m_consolePort.get(); } /** * Set the console port. * * @param i The port number. * @throws ConsoleException If the port number is not sensible. */ public void setConsolePort(final int i) throws ConsoleException { checkPort(i); m_consolePort.set(i); } /** * Get the HTTP host as a string. * * @return The address. */ public String getHttpHost() { return m_httpHost.get(); } /** * Set the HTTP host. * * @param s Either a machine name or the IP address. * @throws ConsoleException If the address is not * valid. */ public void setHttpHost(final String s) throws ConsoleException { checkAddress(s); m_httpHost.set(s); } /** * Get the HTTP port. * * @return The port. */ public int getHttpPort() { return m_httpPort.get(); } /** * Set the HTTP port. * * @param i The port number. * @throws ConsoleException If the port number is not sensible. */ public void setHttpPort(final int i) throws ConsoleException { checkPort(i); m_httpPort.set(i); } /** * Get whether the console should be reset with the worker * processes. * * @return {@code true} => the console should be reset with the * worker processes. */ public boolean getResetConsoleWithProcesses() { return m_resetConsoleWithProcesses.get(); } /** * Set whether the console should be reset with the worker * processes. * * @param b {@code true} => the console should be reset with * the worker processes. */ public void setResetConsoleWithProcesses(final boolean b) { m_resetConsoleWithProcesses.set(b); } /** * Get whether the user wants to be asked if console should be reset * with the worker processes. * * @return {@code true} => the user wants to be asked. */ public boolean getResetConsoleWithProcessesAsk() { return m_resetConsoleWithProcessesAsk.get(); } /** * Set and save whether the user wants to be asked if console should be reset * with the worker processes. * * @param value * {@code true} => the user wants to be asked. * @throws ConsoleException * If the property couldn't be persisted */ public void setResetConsoleWithProcessesAsk(final boolean value) throws ConsoleException { m_resetConsoleWithProcessesAsk.set(value); m_resetConsoleWithProcessesAsk.save(); } /** * Get whether the user wants to be asked if console should be reset * with the worker processes. * * @return {@code true} => the user wants to be asked. */ public boolean getPropertiesNotSetAsk() { return m_propertiesNotSetAsk.get(); } /** * Set and save whether the user wants to be asked if console should be reset * with the worker processes. * * @param value * {@code true} => the user wants to be asked. * @throws ConsoleException * If the property couldn't be persisted. */ public void setPropertiesNotSetAsk(final boolean value) throws ConsoleException { m_propertiesNotSetAsk.set(value); m_propertiesNotSetAsk.save(); } /** * Get whether the user wants to be warned when starting processes with * unsaved buffers. * * @return {@code true} => the user wants to be warned. */ public boolean getStartWithUnsavedBuffersAsk() { return m_startWithUnsavedBuffersAsk.get(); } /** * Set and save whether the user wants to be warned when starting processes * with unsaved buffers. * * @param value * {@code true} => the user wants to be warned. * @throws ConsoleException * If the property couldn't be persisted. */ public void setStartWithUnsavedBuffersAsk(final boolean value) throws ConsoleException { m_startWithUnsavedBuffersAsk.set(value); m_startWithUnsavedBuffersAsk.save(); } /** * Get whether the user wants to be asked to confirm that processes * should be stopped. * * @return {@code true} => the user wants to be asked. */ public boolean getStopProcessesAsk() { return m_stopProcessesAsk.get(); } /** * Set and save whether the user wants to be asked to confirm that processes * should be stopped. * * @param value * {@code true} => the user wants to be asked. * @throws ConsoleException If the property couldn't be persisted. */ public void setStopProcessesAsk(final boolean value) throws ConsoleException { m_stopProcessesAsk.set(value); m_stopProcessesAsk.save(); } /** * Get whether the user wants to distribute files automatically when starting * processes. * * @return {@code true} => the user wants automatic distribution. */ public boolean getDistributeOnStartAsk() { return m_distributeOnStartAsk.get(); } /** * Set and save whether the user wants to distribute files automatically when * starting processes. * * @param value * {@code true} => the user wants automatic distribution. * @throws ConsoleException If the property couldn't be persisted. */ public void setDistributeOnStartAsk(final boolean value) throws ConsoleException { m_distributeOnStartAsk.set(value); m_distributeOnStartAsk.save(); } /** * Get the selected properties file. * * @return The properties file. {@code null} => No file selected. */ public File getPropertiesFile() { return m_propertiesFile.get(); } /** * Set and save the selected properties file. * * @param propertiesFile * The properties file. {@code null} => No file selected. */ public void setPropertiesFile(final File propertiesFile) { m_propertiesFile.set(propertiesFile); } /** * Set and save the properties file. * * @param propertiesFile The properties file. {@code null} => No file * set. * @throws ConsoleException * @throws ConsoleException If the property could not be saved. */ public void setAndSavePropertiesFile(final File propertiesFile) throws ConsoleException { setPropertiesFile(propertiesFile); m_propertiesFile.save(); } /** * Get the script distribution directory. * * @return The directory. */ public Directory getDistributionDirectory() { return m_distributionDirectory.get(); } /** * Set and save the script distribution directory. * * @param distributionDirectory The directory. */ public void setDistributionDirectory(final Directory distributionDirectory) { m_distributionDirectory.set(distributionDirectory); } /** * Set and save the script distribution directory. * * @param distributionDirectory The directory. * @throws ConsoleException If the property could not be saved. */ public void setAndSaveDistributionDirectory( final Directory distributionDirectory) throws ConsoleException { setDistributionDirectory(distributionDirectory); m_distributionDirectory.save(); } /** * Get the distribution file filter pattern. * *

The original regular expression can be obtained with * {@link #getDistributionFileFilterPattern()}.

* * @return The pattern. * @see #setDistributionFileFilterExpression */ public Pattern getDistributionFileFilterPattern() { return m_distributionFileFilterPattern.get(); } /** * Get the distribution file filter pattern. * *

The original regular expression can be obtained with * {@code getDistributionFileFilterPattern().getPattern()}.

* * @return The pattern. * @see #setDistributionFileFilterExpression */ public String getDistributionFileFilterExpression() { return getDistributionFileFilterPattern().pattern(); } /** * Set the distribution file filter regular expression. * *

Files and directory names (not full paths) that match the * regular expression are not distributed. Directory names are * distinguished by a trailing '/'. The expression is in Perl 5 * format.

* * @param expression A Perl 5 format expression. {@code null} * => use default pattern. * @throws ConsoleException If the pattern is invalid. */ public void setDistributionFileFilterExpression(final String expression) throws ConsoleException { m_distributionFileFilterPattern.setExpression(expression); } /** * Get the period at which the distribution files should be scanned. * * @return The period, in milliseconds. */ public int getScanDistributionFilesPeriod() { return m_scanDistributionFilesPeriod.get(); } /** * Set the period at which the distribution files should be scanned. * * @param i The port number. * @throws ConsoleException If the period is negative. */ public void setScanDistributionFilesPeriod(final int i) throws ConsoleException { if (i < 0) { throw new DisplayMessageConsoleException( m_resources, "scanDistributionFilesPeriodNegativeError.text"); } m_scanDistributionFilesPeriod.set(i); } /** * Get the name of the Look and Feel. It is up to the UI * implementation how this is interpreted. * * @return The Look and Feel name. {@code null} => use default. */ public String getLookAndFeel() { return m_lookAndFeel.get(); } /** * Set the name of the Look and Feel. * * @param lookAndFeel The Look and Feel name. {@code null} => * use default. */ public void setLookAndFeel(final String lookAndFeel) { m_lookAndFeel.set(lookAndFeel); } /** * Get the external editor command. * * @return The path to the process to be used for external editing. * {@code null} => no external editor set. */ public File getExternalEditorCommand() { return m_externalEditorCommand.get(); } /** * Set the external editor command. * * @param command The path to the process to be used for external editing. * {@code null} => no external editor set. */ public void setExternalEditorCommand(final File command) { m_externalEditorCommand.set(command); } /** * Get the external editor arguments. * * @return The arguments to be used with the external editor. */ public String getExternalEditorArguments() { return m_externalEditorArguments.get(); } /** * Set the external editor arguments. * * @param arguments The arguments to be used with the external editor. */ public void setExternalEditorArguments(final String arguments) { m_externalEditorArguments.set(arguments); } /** * Get the location and size of the console frame. * * @return The console frame bounds. */ public Rectangle getFrameBounds() { return m_frameBounds.get(); } /** * Set and save the location and size of the console frame. * * @param bounds The console frame bounds. */ public void setFrameBounds(final Rectangle bounds) { m_frameBounds.set(bounds); } /** * Set and save the location and size of the console frame. * * @param bounds The console frame bounds. * @throws ConsoleException If the property couldn't be persisted. */ public void setAndSaveFrameBounds(final Rectangle bounds) throws ConsoleException { setFrameBounds(bounds); m_frameBounds.save(); } /** * Get whether saved results files should include the Totals line. * * @return {@code true} => results files should include totals. */ public boolean getSaveTotalsWithResults() { return m_saveTotalsWithResults.get(); } /** * Set whether saved results files should include the Totals line. * * @param b {@code true} => results files should include totals. * @throws ConsoleException If the property couldn't be persisted. */ public void setSaveTotalsWithResults(final boolean b) throws ConsoleException { m_saveTotalsWithResults.set(b); m_saveTotalsWithResults.save(); } private abstract class Property { private final String m_propertyName; private final T m_defaultValue; Property(final String propertyName, final T defaultValue) { m_propertyName = propertyName; m_defaultValue = defaultValue; } public final void save() throws ConsoleException { try { m_backingProperties.saveSingleProperty(m_propertyName); } catch (final GrinderProperties.PersistenceException e) { throw new DisplayMessageConsoleException( m_resources, "couldNotSaveOptionsError.text", e); } } protected final String getPropertyName() { return m_propertyName; } protected final T getDefaultValue() { return m_defaultValue; } protected abstract T get(); protected abstract void setToStorage(T value); public final void set(final T value) { final T old = get(); final T defaultValue = getDefaultValue(); if (defaultValue == null && value == null || defaultValue != null && defaultValue.equals(value)) { m_backingProperties.remove(m_propertyName); } else { setToStorage(value); } // For some reason, firePropertyChange only suppresses same value // updates when the value is not null. The default L&F is null, // so this prevents UI flicker on each property change. if (old == null && value == null) { return; } m_changeSupport.firePropertyChange(getPropertyName(), old, value); } } private final class StringProperty extends Property { public StringProperty(final String propertyName, final String defaultValue) { super(propertyName, defaultValue); } @Override protected String get() { return m_backingProperties.getProperty(getPropertyName(), getDefaultValue()); } @Override protected void setToStorage(final String value) { m_backingProperties.setProperty(getPropertyName(), value); } } private final class PatternProperty extends Property { public PatternProperty(final String propertyName, final String defaultExpression) { super(propertyName, Pattern.compile(defaultExpression)); } @Override protected Pattern get() { final String expression = m_backingProperties.getProperty(getPropertyName()); if (expression != null) { try { return Pattern.compile(expression); } catch (final PatternSyntaxException e) { // Fall through. } } return getDefaultValue(); } @Override protected void setToStorage(final Pattern value) { m_backingProperties.put(getPropertyName(), value.pattern()); } public void setExpression(final String expression) throws ConsoleException { if (expression == null) { m_backingProperties.remove(getPropertyName()); } else { try { set(Pattern.compile(expression)); } catch (final PatternSyntaxException e) { throw new DisplayMessageConsoleException( m_resources, "regularExpressionError.text", new Object[] { getPropertyName(), }, e); } } } } private final class IntProperty extends Property { public IntProperty(final String propertyName, final int defaultValue) { super(propertyName, defaultValue); } @Override protected Integer get() { return m_backingProperties.getInt(getPropertyName(), getDefaultValue()); } @Override protected void setToStorage(final Integer value) { m_backingProperties.setInt(getPropertyName(), value); } } private final class FileProperty extends Property { public FileProperty(final String propertyName) { super(propertyName, null); } @Override protected File get() { return m_backingProperties.getFile(getPropertyName(), getDefaultValue()); } @Override protected void setToStorage(final File value) { m_backingProperties.setFile(getPropertyName(), value); } } private final class DirectoryProperty extends Property { public DirectoryProperty(final String propertyName) { super(propertyName, new Directory()); } @Override protected Directory get() { final File f = m_backingProperties.getFile(getPropertyName(), null); if (f != null) { try { return new Directory(f); } catch (final Directory.DirectoryException e) { // fall through. } } return new Directory(); } @Override protected void setToStorage(final Directory value) { m_backingProperties.setFile(getPropertyName(), value.getFile()); } } private final class BooleanProperty extends Property { public BooleanProperty(final String propertyName, final boolean defaultValue) { super(propertyName, defaultValue); } @Override protected Boolean get() { return m_backingProperties.getBoolean(getPropertyName(), getDefaultValue()); } @Override protected void setToStorage(final Boolean value) { m_backingProperties.setBoolean(getPropertyName(), value); } } private final class RectangleProperty extends Property { public RectangleProperty(final String propertyName) { super(propertyName, null); } @Override public Rectangle get() { final String property = m_backingProperties.getProperty(getPropertyName(), null); if (property != null) { final StringTokenizer tokenizer = new StringTokenizer(property, ","); try { return new Rectangle(Integer.parseInt(tokenizer.nextToken()), Integer.parseInt(tokenizer.nextToken()), Integer.parseInt(tokenizer.nextToken()), Integer.parseInt(tokenizer.nextToken())); } catch (final NoSuchElementException e) { // Ignore. } catch (final NumberFormatException e) { // Ignore. } } return getDefaultValue(); } @Override public void setToStorage(final Rectangle value) { m_backingProperties.setProperty( getPropertyName(), value.x + "," + value.y + "," + value.width + "," + value.height); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy