This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-configuration.git
commit 688f77d5d9fad1ab591caa799789979d8eb63536 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Tue Jul 2 19:01:24 2024 -0400 Reduce internal code duplication --- src/conf/checkstyle-suppressions.xml | 2 + .../configuration2/AbstractConfiguration.java | 146 ++++++++++----------- .../AbstractHierarchicalConfiguration.java | 66 +++------- .../BaseHierarchicalConfiguration.java | 48 ++----- .../configuration2/CompositeConfiguration.java | 45 ++----- .../commons/configuration2/INIConfiguration.java | 62 +++------ .../configuration2/PropertiesConfiguration.java | 28 +--- .../commons/configuration2/XMLConfiguration.java | 54 +++----- .../configuration2/TestCombinedConfiguration.java | 2 + 9 files changed, 144 insertions(+), 309 deletions(-) diff --git a/src/conf/checkstyle-suppressions.xml b/src/conf/checkstyle-suppressions.xml index fd47dcf0..d096b185 100644 --- a/src/conf/checkstyle-suppressions.xml +++ b/src/conf/checkstyle-suppressions.xml @@ -46,4 +46,6 @@ <suppress checks="SuperClone" files="src[/\\]test[/\\]java[/\\]org[/\\]apache[/\\]commons[/\\]configuration2[/\\]TestConfigurationUtils.java" /> <!-- Class can't be final for Mockito --> <suppress checks="FinalClass" files="src[/\\]test[/\\]java[/\\]org[/\\]apache[/\\]commons[/\\]configuration2[/\\]io[/\\]TestFileHandler.java" /> + <!-- False positive --> + <suppress checks="SuperClone" files="AbstractHierarchicalConfiguration.java" lines="412"/> </suppressions> diff --git a/src/main/java/org/apache/commons/configuration2/AbstractConfiguration.java b/src/main/java/org/apache/commons/configuration2/AbstractConfiguration.java index c91953cc..0b078eb7 100644 --- a/src/main/java/org/apache/commons/configuration2/AbstractConfiguration.java +++ b/src/main/java/org/apache/commons/configuration2/AbstractConfiguration.java @@ -53,6 +53,8 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.function.FailableRunnable; +import org.apache.commons.lang3.function.FailableSupplier; /** * <p> @@ -226,14 +228,11 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C @Override public final void addProperty(final String key, final Object value) { - beginWrite(false); - try { + syncWrite(() -> { fireEvent(ConfigurationEvent.ADD_PROPERTY, key, value, true); addPropertyInternal(key, value); fireEvent(ConfigurationEvent.ADD_PROPERTY, key, value, false); - } finally { - endWrite(); - } + }, false); } /** @@ -265,16 +264,16 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C * structure (i.e. the parent-child-relationships will get lost). So when dealing with hierarchical configuration * objects their {@link BaseHierarchicalConfiguration#clone() clone()} methods should be used. * - * @param c the configuration to be appended (can be <b>null</b>, then this operation will have no effect) + * @param configuration the configuration to be appended (can be <b>null</b>, then this operation will have no effect) * @since 1.5 */ - public void append(final Configuration c) { - if (c != null) { - c.lock(LockMode.READ); + public void append(final Configuration configuration) { + if (configuration != null) { + configuration.lock(LockMode.READ); try { - c.getKeys().forEachRemaining(key -> addProperty(key, encodeForCopy(c.getProperty(key)))); + configuration.getKeys().forEachRemaining(key -> addProperty(key, encodeForCopy(configuration.getProperty(key)))); } finally { - c.unlock(LockMode.READ); + configuration.unlock(LockMode.READ); } } } @@ -314,14 +313,11 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C @Override public final void clear() { - beginWrite(false); - try { + syncWrite(() -> { fireEvent(ConfigurationEvent.CLEAR, null, null, true); clearInternal(); fireEvent(ConfigurationEvent.CLEAR, null, null, false); - } finally { - endWrite(); - } + }, false); } /** @@ -368,14 +364,11 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C */ @Override public final void clearProperty(final String key) { - beginWrite(false); - try { + syncWrite(() -> { fireEvent(ConfigurationEvent.CLEAR_PROPERTY, key, null, true); clearPropertyDirect(key); fireEvent(ConfigurationEvent.CLEAR_PROPERTY, key, null, false); - } finally { - endWrite(); - } + }, false); } /** @@ -433,12 +426,7 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C */ @Override public final boolean containsKey(final String key) { - beginRead(false); - try { - return containsKeyInternal(key); - } finally { - endRead(); - } + return syncRead(() -> containsKeyInternal(key), false); } /** @@ -457,12 +445,7 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C */ @Override public final boolean containsValue(final Object value) { - beginRead(false); - try { - return containsValueInternal(value); - } finally { - endRead(); - } + return syncRead(() -> containsValueInternal(value), false); } /** @@ -535,16 +518,16 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C * hierarchical configuration objects their {@link BaseHierarchicalConfiguration#clone() clone()} methods should be * used. * - * @param c the configuration to copy (can be <b>null</b>, then this operation will have no effect) + * @param configuration the configuration to copy (can be <b>null</b>, then this operation will have no effect) * @since 1.5 */ - public void copy(final Configuration c) { - if (c != null) { - c.lock(LockMode.READ); + public void copy(final Configuration configuration) { + if (configuration != null) { + configuration.lock(LockMode.READ); try { - c.getKeys().forEachRemaining(key -> setProperty(key, encodeForCopy(c.getProperty(key)))); + configuration.getKeys().forEachRemaining(key -> setProperty(key, encodeForCopy(configuration.getProperty(key)))); } finally { - c.unlock(LockMode.READ); + configuration.unlock(LockMode.READ); } } } @@ -885,12 +868,7 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C */ @Override public final Iterator<String> getKeys() { - beginRead(false); - try { - return getKeysInternal(); - } finally { - endRead(); - } + return syncRead(() -> getKeysInternal(), false); } /** @@ -900,12 +878,7 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C */ @Override public final Iterator<String> getKeys(final String prefix) { - beginRead(false); - try { - return getKeysInternal(prefix); - } finally { - endRead(); - } + return syncRead(() -> getKeysInternal(prefix), false); } /** @@ -915,12 +888,7 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C */ @Override public final Iterator<String> getKeys(final String prefix, final String delimiter) { - beginRead(false); - try { - return getKeysInternal(prefix, delimiter); - } finally { - endRead(); - } + return syncRead(() -> getKeysInternal(prefix, delimiter), false); } /** @@ -1104,12 +1072,7 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C */ @Override public final Object getProperty(final String key) { - beginRead(false); - try { - return getPropertyInternal(key); - } finally { - endRead(); - } + return syncRead(() -> getPropertyInternal(key), false); } /** @@ -1275,12 +1238,7 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C */ @Override public final boolean isEmpty() { - beginRead(false); - try { - return isEmptyInternal(); - } finally { - endRead(); - } + return syncRead(() -> isEmptyInternal(), false); } /** @@ -1488,14 +1446,11 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C @Override public final void setProperty(final String key, final Object value) { - beginWrite(false); - try { + syncWrite(() -> { fireEvent(ConfigurationEvent.SET_PROPERTY, key, value, true); setPropertyInternal(key, value); fireEvent(ConfigurationEvent.SET_PROPERTY, key, value, false); - } finally { - endWrite(); - } + }, false); } /** @@ -1548,12 +1503,7 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C */ @Override public final int size() { - beginRead(false); - try { - return sizeInternal(); - } finally { - endRead(); - } + return syncRead(this::sizeInternal, false); } /** @@ -1576,6 +1526,42 @@ public abstract class AbstractConfiguration extends BaseEventSource implements C return new SubsetConfiguration(this, prefix, DELIMITER); } + void syncRead(final Runnable runnable, final boolean optimize) { + beginRead(optimize); + try { + runnable.run(); + } finally { + endRead(); + } + } + + <T, E extends Throwable> T syncRead(final FailableSupplier<T, E> supplier, final boolean optimize) throws E { + beginRead(optimize); + try { + return supplier.get(); + } finally { + endRead(); + } + } + + <T> T syncReadValue(final T value, final boolean optimize) { + beginRead(optimize); + try { + return value; + } finally { + endRead(); + } + } + + <E extends Throwable> void syncWrite(final FailableRunnable<E> runnable, final boolean optimize) throws E { + beginWrite(optimize); + try { + runnable.run(); + } finally { + endWrite(); + } + } + /** * {@inheritDoc} This implementation delegates to {@code endRead()} or {@code endWrite()}, depending on the * {@code LockMode} argument. Subclasses can override these protected methods to perform additional steps when a diff --git a/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalConfiguration.java b/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalConfiguration.java index b7b2fd04..84531d9b 100644 --- a/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalConfiguration.java +++ b/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalConfiguration.java @@ -299,15 +299,11 @@ public abstract class AbstractHierarchicalConfiguration<T> extends AbstractConfi if (nodes == null || nodes.isEmpty()) { return; } - - beginWrite(false); - try { + syncWrite(() -> { fireEvent(ConfigurationEvent.ADD_NODES, key, nodes, true); addNodesInternal(key, nodes); fireEvent(ConfigurationEvent.ADD_NODES, key, nodes, false); - } finally { - endWrite(); - } + }, false); } /** @@ -384,13 +380,10 @@ public abstract class AbstractHierarchicalConfiguration<T> extends AbstractConfi */ @Override public final void clearTree(final String key) { - beginWrite(false); - try { + syncWrite(() -> { fireEvent(ConfigurationEvent.CLEAR_TREE, key, null, true); fireEvent(ConfigurationEvent.CLEAR_TREE, key, clearTreeInternal(key), false); - } finally { - endWrite(); - } + }, false); } /** @@ -414,24 +407,22 @@ public abstract class AbstractHierarchicalConfiguration<T> extends AbstractConfi * @return the copy * @since 1.2 */ + @SuppressWarnings("unchecked") @Override public Object clone() { - beginRead(false); - try { - @SuppressWarnings("unchecked") // clone returns the same type - final AbstractHierarchicalConfiguration<T> copy = (AbstractHierarchicalConfiguration<T>) super.clone(); - copy.setSynchronizer(NoOpSynchronizer.INSTANCE); - copy.cloneInterpolator(this); - copy.setSynchronizer(ConfigurationUtils.cloneSynchronizer(getSynchronizer())); - copy.nodeModel = cloneNodeModel(); - - return copy; - } catch (final CloneNotSupportedException cex) { - // should not happen - throw new ConfigurationRuntimeException(cex); - } finally { - endRead(); - } + return syncRead(() -> { + try { + AbstractHierarchicalConfiguration<T> copy = (AbstractHierarchicalConfiguration<T>) AbstractHierarchicalConfiguration.super.clone(); + copy.setSynchronizer(NoOpSynchronizer.INSTANCE); + copy.cloneInterpolator(this); + copy.setSynchronizer(ConfigurationUtils.cloneSynchronizer(getSynchronizer())); + copy.nodeModel = cloneNodeModel(); + return copy; + } catch (final CloneNotSupportedException cex) { + // should not happen + throw new ConfigurationRuntimeException(cex); + } + }, false); } /** @@ -553,12 +544,7 @@ public abstract class AbstractHierarchicalConfiguration<T> extends AbstractConfi */ @Override public final int getMaxIndex(final String key) { - beginRead(false); - try { - return getMaxIndexInternal(key); - } finally { - endRead(); - } + return syncRead(() -> getMaxIndexInternal(key), false); } /** @@ -590,12 +576,7 @@ public abstract class AbstractHierarchicalConfiguration<T> extends AbstractConfi */ @Override public NodeModel<T> getNodeModel() { - beginRead(false); - try { - return getModel(); - } finally { - endRead(); - } + return syncRead(this::getModel, false); } /** @@ -625,12 +606,7 @@ public abstract class AbstractHierarchicalConfiguration<T> extends AbstractConfi */ @Override public final String getRootElementName() { - beginRead(false); - try { - return getRootElementNameInternal(); - } finally { - endRead(); - } + return syncRead(this::getRootElementNameInternal, false); } /** diff --git a/src/main/java/org/apache/commons/configuration2/BaseHierarchicalConfiguration.java b/src/main/java/org/apache/commons/configuration2/BaseHierarchicalConfiguration.java index 281fd293..941991b8 100644 --- a/src/main/java/org/apache/commons/configuration2/BaseHierarchicalConfiguration.java +++ b/src/main/java/org/apache/commons/configuration2/BaseHierarchicalConfiguration.java @@ -386,18 +386,10 @@ public class BaseHierarchicalConfiguration extends AbstractHierarchicalConfigura */ @Override public List<HierarchicalConfiguration<ImmutableNode>> childConfigurationsAt(final String key) { - List<ImmutableNode> nodes; - beginRead(false); - try { - nodes = fetchFilteredNodeResults(key); - } finally { - endRead(); - } - + List<ImmutableNode> nodes = syncRead(() -> fetchFilteredNodeResults(key), false); if (nodes.size() != 1) { return Collections.emptyList(); } - return nodes.get(0).stream().map(this::createIndependentSubConfigurationForNode).collect(Collectors.toList()); } @@ -450,12 +442,7 @@ public class BaseHierarchicalConfiguration extends AbstractHierarchicalConfigura */ @Override public HierarchicalConfiguration<ImmutableNode> configurationAt(final String key, final boolean supportUpdates) { - beginRead(false); - try { - return supportUpdates ? createConnectedSubConfiguration(key) : createIndependentSubConfiguration(key); - } finally { - endRead(); - } + return syncRead(() -> supportUpdates ? createConnectedSubConfiguration(key) : createIndependentSubConfiguration(key), false); } /** @@ -464,13 +451,7 @@ public class BaseHierarchicalConfiguration extends AbstractHierarchicalConfigura */ @Override public List<HierarchicalConfiguration<ImmutableNode>> configurationsAt(final String key) { - List<ImmutableNode> nodes; - beginRead(false); - try { - nodes = fetchFilteredNodeResults(key); - } finally { - endRead(); - } + List<ImmutableNode> nodes = syncRead(() -> fetchFilteredNodeResults(key), false); return nodes.stream().map(this::createIndependentSubConfigurationForNode).collect(Collectors.toList()); } @@ -483,17 +464,8 @@ public class BaseHierarchicalConfiguration extends AbstractHierarchicalConfigura if (!supportUpdates) { return configurationsAt(key); } - - InMemoryNodeModel parentModel; - beginRead(false); - try { - parentModel = getSubConfigurationParentModel(); - } finally { - endRead(); - } - - final Collection<NodeSelector> selectors = parentModel.selectAndTrackNodes(key, this); - return createConnectedSubConfigurations(this, selectors); + final InMemoryNodeModel parentModel = syncRead(this::getSubConfigurationParentModel, false); + return createConnectedSubConfigurations(this, parentModel.selectAndTrackNodes(key, this)); } /** @@ -764,15 +736,14 @@ public class BaseHierarchicalConfiguration extends AbstractHierarchicalConfigura */ @Override public Configuration subset(final String prefix) { - beginRead(false); - try { + return syncRead(() -> { final List<QueryResult<ImmutableNode>> results = fetchNodeList(prefix); if (results.isEmpty()) { return new BaseHierarchicalConfiguration(); } - final BaseHierarchicalConfiguration parent = this; final BaseHierarchicalConfiguration result = new BaseHierarchicalConfiguration() { + @Override public ConfigurationInterpolator getInterpolator() { return parent.getInterpolator(); @@ -785,14 +756,11 @@ public class BaseHierarchicalConfiguration extends AbstractHierarchicalConfigura } }; result.getModel().setRootNode(createSubsetRootNode(results)); - if (result.isEmpty()) { return new BaseHierarchicalConfiguration(); } result.setSynchronizer(getSynchronizer()); return result; - } finally { - endRead(); - } + }, false); } } diff --git a/src/main/java/org/apache/commons/configuration2/CompositeConfiguration.java b/src/main/java/org/apache/commons/configuration2/CompositeConfiguration.java index 5c8f10c9..66cb9748 100644 --- a/src/main/java/org/apache/commons/configuration2/CompositeConfiguration.java +++ b/src/main/java/org/apache/commons/configuration2/CompositeConfiguration.java @@ -142,14 +142,12 @@ public class CompositeConfiguration extends AbstractConfiguration implements Clo * @since 1.8 */ public void addConfiguration(final Configuration config, final boolean asInMemory) { - beginWrite(false); - try { + syncWrite(() -> { if (!configList.contains(config)) { if (asInMemory) { replaceInMemoryConfiguration(config); inMemoryConfigIsChild = true; } - if (!inMemoryConfigIsChild) { // As the inMemoryConfiguration contains all manually added // keys, we must make sure that it is always last. "Normal", non @@ -161,14 +159,11 @@ public class CompositeConfiguration extends AbstractConfiguration implements Clo // only the order in which child configurations are added is relevant configList.add(config); } - if (config instanceof AbstractConfiguration) { ((AbstractConfiguration) config).setThrowExceptionOnMissing(isThrowExceptionOnMissing()); } } - } finally { - endWrite(); - } + }, false); } /** @@ -194,22 +189,18 @@ public class CompositeConfiguration extends AbstractConfiguration implements Clo * @since 2.3 */ public void addConfigurationFirst(final Configuration config, final boolean asInMemory) { - beginWrite(false); - try { + syncWrite(() -> { if (!configList.contains(config)) { if (asInMemory) { replaceInMemoryConfiguration(config); inMemoryConfigIsChild = true; } configList.add(0, config); - if (config instanceof AbstractConfiguration) { ((AbstractConfiguration) config).setThrowExceptionOnMissing(isThrowExceptionOnMissing()); } } - } finally { - endWrite(); - } + }, false); } /** @@ -315,12 +306,7 @@ public class CompositeConfiguration extends AbstractConfiguration implements Clo * @return the configuration at this index */ public Configuration getConfiguration(final int index) { - beginRead(false); - try { - return configList.get(index); - } finally { - endRead(); - } + return syncRead(() -> configList.get(index), false); } /** @@ -329,12 +315,7 @@ public class CompositeConfiguration extends AbstractConfiguration implements Clo * @return the in memory configuration */ public Configuration getInMemoryConfiguration() { - beginRead(false); - try { - return inMemoryConfiguration; - } finally { - endRead(); - } + return syncReadValue(inMemoryConfiguration, false); } @Override @@ -395,12 +376,7 @@ public class CompositeConfiguration extends AbstractConfiguration implements Clo * @return the number of configuration */ public int getNumberOfConfigurations() { - beginRead(false); - try { - return configList.size(); - } finally { - endRead(); - } + return syncRead(configList::size, false); } /** @@ -474,16 +450,13 @@ public class CompositeConfiguration extends AbstractConfiguration implements Clo * @param config The configuration to remove */ public void removeConfiguration(final Configuration config) { - beginWrite(false); - try { + syncWrite(() -> { // Make sure that you can't remove the inMemoryConfiguration from // the CompositeConfiguration object if (!config.equals(inMemoryConfiguration)) { configList.remove(config); } - } finally { - endWrite(); - } + }, false); } /** diff --git a/src/main/java/org/apache/commons/configuration2/INIConfiguration.java b/src/main/java/org/apache/commons/configuration2/INIConfiguration.java index 62198516..6d2f7d1c 100644 --- a/src/main/java/org/apache/commons/configuration2/INIConfiguration.java +++ b/src/main/java/org/apache/commons/configuration2/INIConfiguration.java @@ -602,12 +602,7 @@ public class INIConfiguration extends BaseHierarchicalConfiguration implements F * @since 2.5 */ public String getCommentLeadingCharsUsedInInput() { - beginRead(false); - try { - return commentCharsUsedInInput; - } finally { - endRead(); - } + return syncReadValue(commentCharsUsedInInput, false); } /** @@ -660,18 +655,16 @@ public class INIConfiguration extends BaseHierarchicalConfiguration implements F } /** - * Gets a set containing the sections in this ini configuration. Note that changes to this set do not affect the + * Gets a set containing the sections in this INI configuration. Note that changes to this set do not affect the * configuration. * * @return a set containing the sections. */ public Set<String> getSections() { - final Set<String> sections = new LinkedHashSet<>(); - boolean globalSection = false; - boolean inSection = false; - - beginRead(false); - try { + return syncRead(() -> { + final Set<String> sections = new LinkedHashSet<>(); + boolean globalSection = false; + boolean inSection = false; for (final ImmutableNode node : getModel().getNodeHandler().getRootNode().getChildren()) { if (isSectionNode(node)) { inSection = true; @@ -681,11 +674,8 @@ public class INIConfiguration extends BaseHierarchicalConfiguration implements F sections.add(null); } } - } finally { - endRead(); - } - - return sections; + return sections; + }, false); } /** @@ -695,12 +685,7 @@ public class INIConfiguration extends BaseHierarchicalConfiguration implements F * @since 2.5 */ public String getSeparatorUsedInInput() { - beginRead(false); - try { - return separatorUsedInInput; - } finally { - endRead(); - } + return syncReadValue(separatorUsedInInput, false); } /** @@ -710,12 +695,7 @@ public class INIConfiguration extends BaseHierarchicalConfiguration implements F * @since 2.2 */ public String getSeparatorUsedInOutput() { - beginRead(false); - try { - return separatorUsedInOutput; - } finally { - endRead(); - } + return syncReadValue(separatorUsedInOutput, false); } /** @@ -923,12 +903,7 @@ public class INIConfiguration extends BaseHierarchicalConfiguration implements F * @since 2.2 */ public void setSeparatorUsedInOutput(final String separator) { - beginWrite(false); - try { - this.separatorUsedInOutput = separator; - } finally { - endWrite(); - } + syncWrite(() -> this.separatorUsedInOutput = separator, false); } /** @@ -940,12 +915,10 @@ public class INIConfiguration extends BaseHierarchicalConfiguration implements F */ @Override public void write(final Writer writer) throws ConfigurationException, IOException { - final PrintWriter out = new PrintWriter(writer); - boolean first = true; - final String separator = getSeparatorUsedInOutput(); - - beginRead(false); - try { + syncRead(() -> { + final PrintWriter out = new PrintWriter(writer); + boolean first = true; + final String separator = getSeparatorUsedInOutput(); for (final ImmutableNode node : getModel().getNodeHandler().getRootNode().getChildren()) { if (isSectionNode(node)) { if (!first) { @@ -964,9 +937,8 @@ public class INIConfiguration extends BaseHierarchicalConfiguration implements F } out.println(); out.flush(); - } finally { - endRead(); - } + + }, false); } /** diff --git a/src/main/java/org/apache/commons/configuration2/PropertiesConfiguration.java b/src/main/java/org/apache/commons/configuration2/PropertiesConfiguration.java index 5ee9d653..7d8a0491 100644 --- a/src/main/java/org/apache/commons/configuration2/PropertiesConfiguration.java +++ b/src/main/java/org/apache/commons/configuration2/PropertiesConfiguration.java @@ -1286,12 +1286,7 @@ public class PropertiesConfiguration extends BaseConfiguration implements FileBa * @since 2.0 */ public String getFooter() { - beginRead(false); - try { - return getLayout().getFooterComment(); - } finally { - endRead(); - } + return syncRead(() -> getLayout().getFooterComment(), false); } /** @@ -1301,12 +1296,7 @@ public class PropertiesConfiguration extends BaseConfiguration implements FileBa * @since 1.1 */ public String getHeader() { - beginRead(false); - try { - return getLayout().getHeaderComment(); - } finally { - endRead(); - } + return syncRead(() -> getLayout().getHeaderComment(), false); } /** @@ -1507,12 +1497,7 @@ public class PropertiesConfiguration extends BaseConfiguration implements FileBa * @since 2.0 */ public void setFooter(final String footer) { - beginWrite(false); - try { - getLayout().setFooterComment(footer); - } finally { - endWrite(); - } + syncWrite(() -> getLayout().setFooterComment(footer), false); } /** @@ -1522,12 +1507,7 @@ public class PropertiesConfiguration extends BaseConfiguration implements FileBa * @since 1.1 */ public void setHeader(final String header) { - beginWrite(false); - try { - getLayout().setHeaderComment(header); - } finally { - endWrite(); - } + syncWrite(() -> getLayout().setHeaderComment(header), false); } /** diff --git a/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java b/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java index ed465733..4f0d7f3c 100644 --- a/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java +++ b/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java @@ -798,12 +798,7 @@ public class XMLConfiguration extends BaseHierarchicalConfiguration implements F * @since 1.3 */ public String getPublicID() { - beginRead(false); - try { - return publicID; - } finally { - endRead(); - } + return syncReadValue(publicID, false); } /** @@ -839,12 +834,7 @@ public class XMLConfiguration extends BaseHierarchicalConfiguration implements F * @since 1.3 */ public String getSystemID() { - beginRead(false); - try { - return systemID; - } finally { - endRead(); - } + return syncReadValue(systemID, false); } /** @@ -1006,12 +996,7 @@ public class XMLConfiguration extends BaseHierarchicalConfiguration implements F * @since 1.3 */ public void setPublicID(final String publicID) { - beginWrite(false); - try { - this.publicID = publicID; - } finally { - endWrite(); - } + syncWrite(() -> this.publicID = publicID, false); } /** @@ -1058,12 +1043,7 @@ public class XMLConfiguration extends BaseHierarchicalConfiguration implements F * @since 1.3 */ public void setSystemID(final String systemID) { - beginWrite(false); - try { - this.systemID = systemID; - } finally { - endWrite(); - } + syncWrite(() -> this.systemID = systemID, false); } /** @@ -1085,21 +1065,17 @@ public class XMLConfiguration extends BaseHierarchicalConfiguration implements F * @throws ConfigurationException if the validation fails. */ public void validate() throws ConfigurationException { - beginWrite(false); - try { - final Transformer transformer = createTransformer(); - final Source source = new DOMSource(createDocument()); - final StringWriter writer = new StringWriter(); - final Result result = new StreamResult(writer); - XMLDocumentHelper.transform(transformer, source, result); - final Reader reader = new StringReader(writer.getBuffer().toString()); - final DocumentBuilder builder = createDocumentBuilder(); - builder.parse(new InputSource(reader)); - } catch (final SAXException | IOException | ParserConfigurationException pce) { - throw new ConfigurationException("Validation failed", pce); - } finally { - endWrite(); - } + syncWrite(() -> { + try { + final StringWriter writer = new StringWriter(); + final Result result = new StreamResult(writer); + XMLDocumentHelper.transform(createTransformer(), new DOMSource(createDocument()), result); + final Reader reader = new StringReader(writer.getBuffer().toString()); + createDocumentBuilder().parse(new InputSource(reader)); + } catch (final SAXException | IOException | ParserConfigurationException pce) { + throw new ConfigurationException("Validation failed", pce); + } + }, false); } /** diff --git a/src/test/java/org/apache/commons/configuration2/TestCombinedConfiguration.java b/src/test/java/org/apache/commons/configuration2/TestCombinedConfiguration.java index 876aba39..3489e39d 100644 --- a/src/test/java/org/apache/commons/configuration2/TestCombinedConfiguration.java +++ b/src/test/java/org/apache/commons/configuration2/TestCombinedConfiguration.java @@ -766,9 +766,11 @@ public class TestCombinedConfiguration { final BaseConfiguration conf1 = new BaseConfiguration(); final String key = "x1"; conf1.addProperty(key, 1); + assertEquals(1, conf1.getProperty(key)); final CombinedConfiguration conf2 = new CombinedConfiguration(); conf2.addConfiguration(conf1, null, ""); + assertEquals(conf1, conf2.getConfiguration(0)); // Actual test final Iterator<String> keys = conf2.getKeys();