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

org.eclipse.rdf4j.rio.RioConfig Maven / Gradle / Ivy

There is a newer version: 5.0.2
Show newest version
/*******************************************************************************
 * Copyright (c) 2015 Eclipse RDF4J contributors, Aduna, and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Distribution License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *******************************************************************************/
package org.eclipse.rdf4j.rio;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.eclipse.rdf4j.rio.helpers.RioConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Superclass for {@link ParserConfig} and {@link WriterConfig}.
 * 

* A RioConfig is a container for several {@link RioSetting} objects, each of which has a default value. You can * override the default value for a {@link RioSetting} in one of two ways: *

    *
  1. You can programmatically set its value using {@link RioConfig#set(RioSetting, Object)}
  2. *
  3. You can set a Java system property (e.g. by means of a -D jvm command line switch). The property * name should corresponds to the {@link RioSetting#getKey() key} of the setting. Note that this method is not supported * by every type of {@link RioSetting}: boolean values, strings, and numeric (long) values are supported, but more * complex types are not
  4. *
* * @author Peter Ansell * @see RioSetting */ public class RioConfig implements Serializable { /** * */ private static final long serialVersionUID = 2714L; /** * A map containing mappings from settings to their values. */ protected final ConcurrentMap, Object> settings = new ConcurrentHashMap<>(); /** * A map containing mappings from settings to system properties that have been discovered since the last call to * {@link #useDefaults()}. */ protected final ConcurrentMap, Object> systemPropertyCache = new ConcurrentHashMap<>(); protected final Logger log = LoggerFactory.getLogger(this.getClass()); /** * */ public RioConfig() { super(); } /** * Return the value for a given {@link RioSetting} or the default value if it has not been set. * * @param setting The {@link RioSetting} to fetch a value for. * @return The value for the parser setting, or the default value if it is not set. */ @SuppressWarnings("unchecked") public T get(RioSetting setting) { Object result = settings.get(setting); if (result == null) { result = systemPropertyCache.get(setting); } if (result == null) { String stringRepresentation = System.getProperty(setting.getKey()); if (stringRepresentation != null) { try { T typesafeSystemProperty = setting.convert(stringRepresentation); systemPropertyCache.put((RioSetting) setting, typesafeSystemProperty); return typesafeSystemProperty; } catch (RioConfigurationException e) { log.trace(e.getMessage(), e); } } } if (result == null) { return setting.getDefaultValue(); } return (T) result; } /** * Sets a {@link RioSetting} to have a new value. If the value is null, the parser setting is removed and the * default will be used instead. * * @param setting The setting to set a new value for. * @param value The value for the parser setting, or null to reset the parser setting to use the default value. * @return Either a copy of this config, if it is immutable, or this object, to allow chaining of method calls. */ @SuppressWarnings("unchecked") public RioConfig set(RioSetting setting, T value) { if (value == null) { settings.remove(setting); } else { Object putIfAbsent = settings.putIfAbsent((RioSetting) setting, value); if (putIfAbsent != null) { // override the previous setting anyway, putIfAbsent just gives us // information about whether it was previously set or not settings.put((RioSetting) setting, value); // this.log.trace("Overriding previous setting for {}", // setting.getKey()); } } return this; } /** * Checks for whether a {@link RioSetting} has been explicitly set by a user. *

* A setting can be set via {@link RioConfig#set(RioSetting, Object)}, or via use of a system property. * * @param setting The setting to check for. * @return True if the setting has been explicitly set, or false otherwise. */ public boolean isSet(RioSetting setting) { return settings.containsKey(setting) || systemPropertyCache.containsKey(setting) || hasSystemPropertyOverride(setting); } private boolean hasSystemPropertyOverride(RioSetting setting) { return Objects.nonNull(System.getProperty(setting.getKey())); } /** * Resets all settings back to their default values. * * @return Either a copy of this config, if it is immutable, or this object, to allow chaining of method calls. */ public RioConfig useDefaults() { settings.clear(); systemPropertyCache.clear(); return this; } public Map, Object> getSettings() { return Collections.unmodifiableMap(new HashMap<>(settings)); } }