You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2012/10/09 22:16:22 UTC
svn commit: r1396291 - in /commons/proper/configuration/trunk/src:
main/java/org/apache/commons/configuration/builder/FileBasedConfigurationBuilder.java
test/java/org/apache/commons/configuration/builder/TestFileBasedConfigurationBuilder.java
Author: oheger
Date: Tue Oct 9 20:16:20 2012
New Revision: 1396291
URL: http://svn.apache.org/viewvc?rev=1396291&view=rev
Log:
Added FileBasedConfigurationBuilder class.
Added:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedConfigurationBuilder.java (with props)
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestFileBasedConfigurationBuilder.java (with props)
Added: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedConfigurationBuilder.java?rev=1396291&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedConfigurationBuilder.java (added)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedConfigurationBuilder.java Tue Oct 9 20:16:20 2012
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.configuration.builder;
+
+import java.util.Map;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.FileBasedConfiguration;
+import org.apache.commons.configuration.io.FileHandler;
+
+/**
+ * <p>
+ * A specialized {@code ConfigurationBuilder} implementation which can handle
+ * configurations read from a {@link FileHandler}.
+ * </p>
+ * <p>
+ * This class extends its base class by the support of a
+ * {@link FileBasedBuilderParameters} object, and especially of the
+ * {@link FileHandler} contained in this object. When the builder creates a new
+ * object the resulting {@code Configuration} instance is associated with the
+ * {@code FileHandler}. If the {@code FileHandler} has a location set, the
+ * {@code Configuration} is directly loaded from this location.
+ * </p>
+ * <p>
+ * The {@code FileHandler} is kept by this builder and can be queried later on.
+ * It can be used for instance to save the current {@code Configuration} after
+ * it was modified. Some care has to be taken when changing the location of the
+ * {@code FileHandler}: The new location is recorded and also survives an
+ * invocation of the {@code resetResult()} method. However, when the builder's
+ * initialization parameters are reset by calling {@code resetParameters()} the
+ * location is reset, too.
+ * </p>
+ *
+ * @version $Id$
+ * @since 2.0
+ * @param <T> the concrete type of {@code Configuration} objects created by this
+ * builder
+ */
+public class FileBasedConfigurationBuilder<T extends FileBasedConfiguration>
+ extends BasicConfigurationBuilder<T>
+{
+ /** Stores the FileHandler associated with the current configuration. */
+ private FileHandler currentFileHandler;
+
+ /** A flag whether the builder's parameters were reset. */
+ private boolean resetParameters;
+
+ /**
+ * Creates a new instance of {@code FileBasedConfigurationBuilder} which
+ * produces result objects of the specified class.
+ *
+ * @param resCls the result class (must not be <b>null</b>
+ * @throws IllegalArgumentException if the result class is <b>null</b>
+ */
+ public FileBasedConfigurationBuilder(Class<T> resCls)
+ {
+ super(resCls);
+ }
+
+ /**
+ * Creates a new instance of {@code FileBasedConfigurationBuilder} which
+ * produces result objects of the specified class and sets initialization
+ * parameters.
+ *
+ * @param resCls the result class (must not be <b>null</b>
+ * @param params a map with initialization parameters
+ * @throws IllegalArgumentException if the result class is <b>null</b>
+ */
+ public FileBasedConfigurationBuilder(Class<T> resCls,
+ Map<String, Object> params)
+ {
+ super(resCls, params);
+ }
+
+ /**
+ * Returns the {@code FileHandler} associated with this builder. If already
+ * a result object has been created, this {@code FileHandler} can be used to
+ * save it. Otherwise, the {@code FileHandler} from the initialization
+ * parameters is returned (which is not associated with a {@code FileBased}
+ * object). Result is never <b>null</b>.
+ *
+ * @return the {@code FileHandler} associated with this builder
+ */
+ public synchronized FileHandler getFileHandler()
+ {
+ return (currentFileHandler != null) ? currentFileHandler
+ : fetchFileHandlerFromParameters();
+ }
+
+ /**
+ * {@inheritDoc} This implementation just records the fact that new
+ * parameters have been set. This means that the next time a result object
+ * is created, the {@code FileHandler} has to be initialized from
+ * initialization parameters rather than reusing the existing one.
+ */
+ @Override
+ public synchronized BasicConfigurationBuilder<T> setParameters(
+ Map<String, Object> params)
+ {
+ super.setParameters(params);
+ resetParameters = true;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc} This implementation deals with the creation and
+ * initialization of a {@code FileHandler} associated with the new result
+ * object.
+ */
+ @Override
+ protected void initResultInstance(T obj) throws ConfigurationException
+ {
+ FileHandler srcHandler =
+ (currentFileHandler != null && !resetParameters) ? currentFileHandler
+ : fetchFileHandlerFromParameters();
+ currentFileHandler = new FileHandler(obj, srcHandler);
+ initFileHandler(currentFileHandler);
+ resetParameters = false;
+ }
+
+ /**
+ * Initializes the new current {@code FileHandler}. When a new result object
+ * is created, a new {@code FileHandler} is created, too, and associated
+ * with the result object. This new handler is passed to this method. If a
+ * location is defined, the result object is loaded from this location.
+ * Note: This method is called from a synchronized block.
+ *
+ * @param handler the new current {@code FileHandler}
+ * @throws ConfigurationException if an error occurs
+ */
+ protected void initFileHandler(FileHandler handler)
+ throws ConfigurationException
+ {
+ if (handler.isLocationDefined())
+ {
+ handler.load();
+ }
+ }
+
+ /**
+ * Obtains the {@code FileHandler} from this builder's parameters.
+ *
+ * @return the {@code FileHandler} from initialization parameters
+ */
+ private FileHandler fetchFileHandlerFromParameters()
+ {
+ return FileBasedBuilderParameters.fromParameters(getParameters(), true)
+ .getFileHandler();
+ }
+}
Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedConfigurationBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedConfigurationBuilder.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedConfigurationBuilder.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestFileBasedConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestFileBasedConfigurationBuilder.java?rev=1396291&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestFileBasedConfigurationBuilder.java (added)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestFileBasedConfigurationBuilder.java Tue Oct 9 20:16:20 2012
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.configuration.builder;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Test class for {@code FileBasedConfigurationBuilder}.
+ *
+ * @version $Id$
+ */
+public class TestFileBasedConfigurationBuilder
+{
+ /** Constant for a test property name. */
+ private static final String PROP = "testProperty";
+
+ /** Helper object for managing temporary files. */
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ /**
+ * Creates a test properties file with the given property value
+ *
+ * @param value the value for the test property
+ * @return the File object pointing to the test file
+ */
+ private File createTestFile(int value)
+ {
+ Writer out = null;
+ File file;
+ try
+ {
+ file = folder.newFile();
+ out = new FileWriter(file);
+ out.write(String.format("%s=%d", PROP, value));
+ }
+ catch (IOException ioex)
+ {
+ fail("Could not create test file: " + ioex);
+ return null; // cannot happen
+ }
+ finally
+ {
+ if (out != null)
+ {
+ try
+ {
+ out.close();
+ }
+ catch (IOException ioex)
+ {
+ // ignore
+ }
+ }
+ }
+ return file;
+ }
+
+ /**
+ * Tests whether a configuration can be created if no location is set.
+ */
+ @Test
+ public void testGetConfigurationNoLocation() throws ConfigurationException
+ {
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put("throwExceptionOnMissing", Boolean.TRUE);
+ FileBasedConfigurationBuilder<PropertiesConfiguration> builder =
+ new FileBasedConfigurationBuilder<PropertiesConfiguration>(
+ PropertiesConfiguration.class, params);
+ PropertiesConfiguration conf = builder.getConfiguration();
+ assertTrue("Property not set", conf.isThrowExceptionOnMissing());
+ assertTrue("Not empty", conf.isEmpty());
+ }
+
+ /**
+ * Tests whether a configuration is loaded from file if a location is
+ * provided.
+ */
+ @Test
+ public void testGetConfigurationLoadFromFile()
+ throws ConfigurationException
+ {
+ File file = createTestFile(1);
+ FileBasedConfigurationBuilder<PropertiesConfiguration> builder =
+ new FileBasedConfigurationBuilder<PropertiesConfiguration>(
+ PropertiesConfiguration.class);
+ builder.configure(new FileBasedBuilderParameters().setFile(file));
+ PropertiesConfiguration config = builder.getConfiguration();
+ assertEquals("Not read from file", 1, config.getInt(PROP));
+ assertSame("FileHandler not initialized", config, builder
+ .getFileHandler().getContent());
+ }
+
+ /**
+ * Tests that the location in the FileHandler remains the same if the
+ * builder's result is reset.
+ */
+ @Test
+ public void testLocationSurvivesResetResult() throws ConfigurationException
+ {
+ File file = createTestFile(1);
+ FileBasedConfigurationBuilder<PropertiesConfiguration> builder =
+ new FileBasedConfigurationBuilder<PropertiesConfiguration>(
+ PropertiesConfiguration.class);
+ builder.configure(new FileBasedBuilderParameters().setFile(file));
+ PropertiesConfiguration config = builder.getConfiguration();
+ builder.resetResult();
+ PropertiesConfiguration config2 = builder.getConfiguration();
+ assertNotSame("Same configuration", config, config2);
+ assertEquals("Not read from file", 1, config2.getInt(PROP));
+ }
+
+ /**
+ * Tests whether the location can be changed after a configuration has been
+ * created.
+ */
+ @Test
+ public void testChangeLocationAfterCreation() throws ConfigurationException
+ {
+ File file1 = createTestFile(1);
+ File file2 = createTestFile(2);
+ FileBasedConfigurationBuilder<PropertiesConfiguration> builder =
+ new FileBasedConfigurationBuilder<PropertiesConfiguration>(
+ PropertiesConfiguration.class);
+ builder.configure(new FileBasedBuilderParameters().setFile(file1));
+ builder.getConfiguration();
+ builder.getFileHandler().setFile(file2);
+ builder.resetResult();
+ PropertiesConfiguration config = builder.getConfiguration();
+ assertEquals("Not read from file 2", 2, config.getInt(PROP));
+ }
+
+ /**
+ * Tests whether a reset of the builder's initialization parameters also
+ * resets the file location.
+ */
+ @Test
+ public void testResetLocation() throws ConfigurationException
+ {
+ File file = createTestFile(1);
+ FileBasedConfigurationBuilder<PropertiesConfiguration> builder =
+ new FileBasedConfigurationBuilder<PropertiesConfiguration>(
+ PropertiesConfiguration.class);
+ builder.configure(new FileBasedBuilderParameters().setFile(file));
+ builder.getConfiguration();
+ builder.reset();
+ PropertiesConfiguration config = builder.getConfiguration();
+ assertTrue("Configuration was read from file", config.isEmpty());
+ assertFalse("FileHandler has location", builder.getFileHandler()
+ .isLocationDefined());
+ }
+
+ /**
+ * Tests whether it is possible to permanently change the location after a
+ * reset of parameters.
+ */
+ @Test
+ public void testChangeLocationAfterReset() throws ConfigurationException
+ {
+ File file1 = createTestFile(1);
+ File file2 = createTestFile(2);
+ FileBasedConfigurationBuilder<PropertiesConfiguration> builder =
+ new FileBasedConfigurationBuilder<PropertiesConfiguration>(
+ PropertiesConfiguration.class);
+ builder.configure(new FileBasedBuilderParameters().setFile(file1));
+ builder.getConfiguration();
+ builder.getFileHandler().setFile(file2);
+ builder.reset();
+ builder.configure(new FileBasedBuilderParameters().setFile(file1));
+ PropertiesConfiguration config = builder.getConfiguration();
+ assertEquals("Not read from file 1", 1, config.getInt(PROP));
+ builder.getFileHandler().setFile(file2);
+ builder.resetResult();
+ config = builder.getConfiguration();
+ assertEquals("Not read from file 2", 2, config.getInt(PROP));
+ }
+}
Propchange: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestFileBasedConfigurationBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestFileBasedConfigurationBuilder.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestFileBasedConfigurationBuilder.java
------------------------------------------------------------------------------
svn:mime-type = text/plain