PropertiesConfiguration.java
- /*
- * Copyright (c) 2007-2025 MetaSolutions AB
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.entrystore.repository.config;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.entrystore.config.Config;
- import org.entrystore.config.DurationStyle;
- import java.awt.*;
- import java.beans.PropertyChangeListener;
- import java.beans.PropertyChangeSupport;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- import java.net.MalformedURLException;
- import java.net.URI;
- import java.net.URISyntaxException;
- import java.net.URL;
- import java.nio.charset.StandardCharsets;
- import java.nio.file.Files;
- import java.time.Duration;
- import java.util.ArrayList;
- import java.util.Enumeration;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Properties;
- /**
- * Wrapper around Java's Properties.
- * Some methods have been simplified, others just wrapped.<br>
- *
- * <p>
- * See the static methods of the class Configurations for wrappers around the
- * Config interface, e.g., to get synchronized view of the object.
- *
- * <p>
- * If a key maps only to one value, it is done the standard way:<br>
- * <pre>key=value</pre>
- *
- * <p>
- * If a key maps to multiple values, the key is numbered:<br>
- * <pre>key.1=value1</pre>
- * <pre>key.2=value2</pre>
- *
- * @author Hannes Ebner
- * @version $Id$
- * @see org.entrystore.config.Configurations
- * @see org.entrystore.config.Config
- */
- public class PropertiesConfiguration implements Config {
- Log log = LogFactory.getLog(PropertiesConfiguration.class);
- /**
- * The main resource in this object. Contains the configuration.
- */
- private final SortedProperties config;
- private final PropertyChangeSupport pcs;
- private final String configName;
- private boolean modified = false;
- /* Constructors */
- /**
- * Initializes the object with an empty Configuration.
- *
- * @param configName
- * Name of the configuration (appears as comment in the
- * configuration file).
- */
- public PropertiesConfiguration(String configName) {
- this.configName = configName;
- config = new SortedProperties();
- pcs = new PropertyChangeSupport(this);
- }
- /* Generic helpers */
- /**
- * Sets the modified status of this configuration.
- *
- * @param modified
- * Status.
- */
- private void setModified(boolean modified) {
- this.modified = modified;
- }
- private void checkFirePropertyChange(String key, Object oldValue, Object newValue) {
- if ((oldValue == null) && (newValue != null)) {
- pcs.firePropertyChange(key, null, newValue);
- } else if ((oldValue != null) && (!oldValue.equals(newValue))) {
- pcs.firePropertyChange(key, oldValue, newValue);
- }
- }
- /*
- * List helpers
- */
- private String numberedKey(String key, int number) {
- return key + "." + number;
- }
- private int getPropertyValueCount(String key) {
- int valueCount = 0;
- if (config.containsKey(key)) {
- valueCount = 1;
- } else {
- while (config.containsKey(numberedKey(key, valueCount + 1))) {
- valueCount++;
- }
- }
- return valueCount;
- }
- private synchronized void addPropertyValue(String key, Object value) {
- int valueCount = getPropertyValueCount(key);
- if ((valueCount == 1) && config.containsKey(key)) {
- String oldValue = config.getProperty(key);
- config.remove(key);
- config.setProperty(numberedKey(key, 1), oldValue);
- config.setProperty(numberedKey(key, 2), value.toString());
- } else if (valueCount > 1){
- config.setProperty(numberedKey(key, valueCount + 1), value.toString());
- } else if (valueCount == 0) {
- config.setProperty(key, value.toString());
- }
- }
- private void addPropertyValues(String key, List values) {
- addPropertyValues(key, values.iterator());
- }
- private synchronized void addPropertyValues(String key, Iterator it) {
- while (it.hasNext()) {
- addPropertyValue(key, it.next());
- }
- }
- private synchronized List<String> getPropertyValues(String key) {
- int valueCount = getPropertyValueCount(key);
- List<String> result = new ArrayList<>();
- if (valueCount == 1) {
- String value = config.getProperty(key);
- if (value == null) {
- value = config.getProperty(numberedKey(key, 1));
- }
- if (value != null) {
- result.add(value);
- }
- } else {
- for (int i = 1; i <= valueCount; i++) {
- result.add(config.getProperty(numberedKey(key, i)));
- }
- }
- return result;
- }
- private synchronized void clearPropertyValues(String key) {
- int valueCount = getPropertyValueCount(key);
- if (valueCount > 1) {
- for (int i = 1; i <= valueCount; i++) {
- config.remove(numberedKey(key, i));
- }
- }
- config.remove(key);
- }
- private void setPropertyValues(String key, List values) {
- setPropertyValues(key, values.iterator());
- }
- private synchronized void setPropertyValues(String key, Iterator it) {
- clearPropertyValues(key);
- addPropertyValues(key, it);
- }
- /*
- * Interface implementation
- */
- /* Generic */
- @Override
- public void clear() {
- config.clear();
- setModified(true);
- }
- @Override
- public boolean isEmpty() {
- return config.isEmpty();
- }
- @Override
- public boolean isModified() {
- return modified;
- }
- @Override
- public void load(URL configURL) throws IOException {
- InputStreamReader isr = null;
- try {
- URL escapedURL = new URI(configURL.toString().replaceAll(" ", "%20")).toURL();
- isr = new InputStreamReader(escapedURL.openStream(), StandardCharsets.UTF_8);
- config.load(isr);
- } catch (URISyntaxException e) {
- log.error(e.getMessage());
- } finally {
- if (isr != null) {
- isr.close();
- }
- }
- }
- @Override
- public void save(URL configURL) throws IOException {
- try {
- String escapedURL = configURL.toString().replaceAll(" ", "%20");
- URI url = new URI(escapedURL);
- File file = new File(url);
- OutputStreamWriter output = new OutputStreamWriter(Files.newOutputStream(file.toPath()), StandardCharsets.UTF_8);
- config.store(output, configName);
- output.close();
- } catch (URISyntaxException e) {
- throw new IOException(e.getMessage());
- }
- setModified(false);
- }
- /* Property Change Listeners */
- @Override
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(listener);
- }
- @Override
- public void addPropertyChangeListener(String key, PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(key, listener);
- }
- @Override
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(listener);
- }
- @Override
- public void removePropertyChangeListener(String key, PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(key, listener);
- }
- /* Properties / Set Values */
- @Override
- public void clearProperty(String key) {
- int valueCount = getPropertyValueCount(key);
- Object oldValue = null;
- if (valueCount == 0) {
- return;
- } else if (valueCount == 1) {
- oldValue = getString(key);
- } else if (valueCount > 1) {
- oldValue = getStringList(key);
- }
- clearPropertyValues(key);
- setModified(true);
- checkFirePropertyChange(key, oldValue, null);
- }
- @Override
- public void addProperty(String key, Object value) {
- addPropertyValue(key, value);
- setModified(true);
- pcs.firePropertyChange(key, null, value);
- }
- @Override
- public void addProperties(String key, List values) {
- addPropertyValues(key, values);
- setModified(true);
- pcs.firePropertyChange(key, null, values);
- }
- @Override
- public void addProperties(String key, Iterator values) {
- addPropertyValues(key, values);
- setModified(true);
- pcs.firePropertyChange(key, null, values);
- }
- @Override
- public void setProperty(String key, Object value) {
- String oldValue;
- oldValue = getString(key);
- config.setProperty(key, value.toString());
- setModified(true);
- checkFirePropertyChange(key, oldValue, value);
- }
- @Override
- public void setProperties(String key, List values) {
- List<String> oldValues = getStringList(key);
- setPropertyValues(key, values);
- setModified(true);
- checkFirePropertyChange(key, oldValues, values);
- }
- @Override
- public void setProperties(String key, Iterator values) {
- List<String> oldValues = getStringList(key);
- setPropertyValues(key, values);
- setModified(true);
- checkFirePropertyChange(key, oldValues, values);
- }
- /* Keys */
- @Override
- public boolean containsKey(String key) {
- return config.containsKey(key);
- }
- @Override
- public List<String> getKeyList() {
- return getKeyList(null);
- }
- @Override
- public List<String> getKeyList(String prefix) {
- Enumeration keyIterator = config.propertyNames();
- ArrayList<String> result = new ArrayList<>();
- while (keyIterator.hasMoreElements()) {
- String next = (String) keyIterator.nextElement();
- if ((prefix != null) && !next.startsWith(prefix)) {
- continue;
- }
- result.add(next);
- }
- return result;
- }
- /* Get Values */
- @Override
- public String getString(String key) {
- return config.getProperty(key);
- }
- @Override
- public String getString(String key, String defaultValue) {
- return config.getProperty(key, defaultValue);
- }
- @Override
- public List<String> getStringList(String key) {
- return getPropertyValues(key);
- }
- @Override
- public List<String> getStringList(String key, List<String> defaultValues) {
- List<String> result = getPropertyValues(key);
- if (result.isEmpty()) {
- result = defaultValues;
- }
- return result;
- }
- @Override
- public boolean getBoolean(String key) {
- return getBoolean(key, false);
- }
- @Override
- public boolean getBoolean(String key, boolean defaultValue) {
- String strValue = config.getProperty(key);
- if ("on".equalsIgnoreCase(strValue)) {
- return true;
- } else if ("off".equalsIgnoreCase(strValue)) {
- return false;
- }
- if (strValue != null) {
- return Boolean.parseBoolean(strValue);
- } else {
- return defaultValue;
- }
- }
- @Override
- public byte getByte(String key) {
- String strValue = config.getProperty(key);
- byte byteValue = 0;
- if (strValue != null) {
- byteValue = Byte.parseByte(strValue);
- }
- return byteValue;
- }
- @Override
- public byte getByte(String key, byte defaultValue) {
- String strValue = config.getProperty(key);
- byte byteValue;
- if (strValue != null) {
- byteValue = Byte.parseByte(strValue);
- } else {
- byteValue = defaultValue;
- }
- return byteValue;
- }
- @Override
- public double getDouble(String key) {
- String strValue = config.getProperty(key);
- double doubleValue = 0;
- if (strValue != null) {
- doubleValue = Double.parseDouble(strValue);
- }
- return doubleValue;
- }
- @Override
- public double getDouble(String key, double defaultValue) {
- String strValue = config.getProperty(key);
- double doubleValue;
- if (strValue != null) {
- doubleValue = Double.parseDouble(strValue);
- } else {
- doubleValue = defaultValue;
- }
- return doubleValue;
- }
- @Override
- public float getFloat(String key) {
- String strValue = config.getProperty(key);
- float floatValue = 0;
- if (strValue != null) {
- floatValue = Float.parseFloat(strValue);
- }
- return floatValue;
- }
- @Override
- public float getFloat(String key, float defaultValue) {
- String strValue = config.getProperty(key);
- float floatValue;
- if (strValue != null) {
- floatValue = Float.parseFloat(strValue);
- } else {
- floatValue = defaultValue;
- }
- return floatValue;
- }
- @Override
- public int getInt(String key) {
- String strValue = config.getProperty(key);
- int intValue = 0;
- if (strValue != null) {
- intValue = Integer.parseInt(strValue);
- }
- return intValue;
- }
- @Override
- public int getInt(String key, int defaultValue) {
- String strValue = config.getProperty(key);
- int intValue;
- if (strValue != null) {
- intValue = Integer.parseInt(strValue);
- } else {
- intValue = defaultValue;
- }
- return intValue;
- }
- @Override
- public long getLong(String key) {
- String strValue = config.getProperty(key);
- long longValue = 0;
- if (strValue != null) {
- longValue = Long.parseLong(strValue);
- }
- return longValue;
- }
- @Override
- public long getLong(String key, long defaultValue) {
- String strValue = config.getProperty(key);
- long longValue;
- if (strValue != null) {
- longValue = Long.parseLong(strValue);
- } else {
- longValue = defaultValue;
- }
- return longValue;
- }
- @Override
- public short getShort(String key) {
- String strValue = config.getProperty(key);
- short shortValue = 0;
- if (strValue != null) {
- shortValue = Short.parseShort(strValue);
- }
- return shortValue;
- }
- @Override
- public short getShort(String key, short defaultValue) {
- String strValue = config.getProperty(key);
- short shortValue;
- if (strValue != null) {
- shortValue = Short.parseShort(strValue);
- } else {
- shortValue = defaultValue;
- }
- return shortValue;
- }
- @Override
- public URI getURI(String key) {
- try {
- String uri = config.getProperty(key);
- if (uri != null) {
- return new URI(uri);
- }
- } catch (URISyntaxException ignored) {
- }
- return null;
- }
- @Override
- public URI getURI(String key, URI defaultValue) {
- URI result = getURI(key);
- if (result == null) {
- return defaultValue;
- }
- return result;
- }
- @Override
- public URL getURL(String key) {
- try {
- String uri = config.getProperty(key);
- if (uri != null) {
- return new URI(uri).toURL();
- }
- } catch (URISyntaxException | MalformedURLException ignored) {
- }
- return null;
- }
- @Override
- public URL getURL(String key, URL defaultValue) {
- URL result = getURL(key);
- if (result == null) {
- return defaultValue;
- }
- return result;
- }
- @Override
- public Color getColor(String key) {
- Color result = null;
- String value = getString(key);
- if (value != null) {
- try {
- if (!value.startsWith("0x"))
- result = Color.decode(value);
- else {
- int rgb = Long.decode(value).intValue();
- result = new Color(rgb);
- }
- } catch (NumberFormatException ignored) {
- }
- }
- return result;
- }
- @Override
- public Color getColor(String key, Color defaultValue) {
- Color result = getColor(key);
- if (result == null) {
- return defaultValue;
- }
- return result;
- }
- @Override
- public Duration getDuration(String key) {
- String durationString = config.getProperty(key);
- if (durationString == null) {
- return null;
- }
- return DurationStyle.detectAndParse(durationString);
- }
- @Override
- public Duration getDuration(String key, Duration defaultValue) {
- String durationString = config.getProperty(key);
- if (durationString == null) {
- return defaultValue;
- }
- return DurationStyle.detectAndParse(durationString);
- }
- @Override
- public Duration getDuration(String key, String defaultValue) {
- String durationString = config.getProperty(key);
- if (durationString == null) {
- return DurationStyle.detectAndParse(defaultValue);
- }
- return DurationStyle.detectAndParse(durationString);
- }
- @Override
- public Duration getDuration(String key, long defaultValue) {
- String durationString = config.getProperty(key);
- if (durationString == null) {
- return Duration.ofMillis(defaultValue);
- }
- return DurationStyle.detectAndParse(durationString);
- }
- @Override
- public Properties getProperties() {
- return this.config;
- }
- }