Author: oheger
Date: Mon Oct 12 20:35:07 2009
New Revision: 824486
URL: http://svn.apache.org/viewvc?rev=824486&view=rev
Log:
Added a default implementation for the LocatorSupport interface.
Added:
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/DefaultLocatorSupport.java
(with props)
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestDefaultLocatorSupport.java
(with props)
Added:
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/DefaultLocatorSupport.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/DefaultLocatorSupport.java?rev=824486&view=auto
==============================================================================
---
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/DefaultLocatorSupport.java
(added)
+++
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/DefaultLocatorSupport.java
Mon Oct 12 20:35:07 2009
@@ -0,0 +1,439 @@
+/*
+ * 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.configuration2.base;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+
+import org.apache.commons.configuration2.ConfigurationException;
+import org.apache.commons.configuration2.fs.FileSystem;
+import org.apache.commons.configuration2.fs.FileSystemBased;
+import org.apache.commons.configuration2.fs.Locator;
+
+/**
+ * <p>
+ * A default implementation of the {...@code LocatorSupport} interface.
+ * </p>
+ * <p>
+ * This class implements all the various load() and save() methods defined by
+ * the {...@code LocatorSupport} interface by delegating to a
+ * {...@link StreamBasedSource} instance that was passed at construction time.
This
+ * basically means that all load() operations are eventually mapped to a
{...@code
+ * Reader}, and all save() operations are eventually mapped to a {...@code
Writer}.
+ * The encoding and a default {...@link Locator} are also maintained as member
+ * fields.
+ * </p>
+ * <p>
+ * {...@code DefaultLocatorSupport} implements the {...@link FileSystemBased}
+ * interface. Thus a specific {...@link FileSystem} can be set which is used
for
+ * resolving the URLs obtained from {...@link Locator} instances. By providing
+ * corresponding {...@link FileSystem} implementations various types of URLs
can be
+ * supported.
+ * </p>
+ * <p>
+ * Using this class greatly simplifies adding support for enhanced file
+ * operations to different {...@link ConfigurationSource} implementations.
Because
+ * the delegation principle is used no complex inheritance structures are
+ * necessary.
+ * </p>
+ *
+ * @author Commons Configuration team
+ * @version $Id$
+ */
+public class DefaultLocatorSupport implements LocatorSupport, FileSystemBased
+{
+ /** Stores the underlying stream-based source. */
+ private final StreamBasedSource streamBasedSource;
+
+ /** Stores the default locator. */
+ private Locator locator;
+
+ /** The file system used by this object. */
+ private FileSystem fileSystem = FileSystem.getDefaultFileSystem();
+
+ /** Stores the default encoding. */
+ private String encoding;
+
+ /**
+ * Creates a new instance of {...@code DefaultLocatorSupport} and
initializes
+ * it with the specified {...@code StreamBasedSource}. All load() and
save()
+ * operations performed on this instance are eventually delegated to this
+ * source.
+ *
+ * @param source the {...@code StreamBasedSource} (must not be <b>null</b>)
+ * @throws IllegalArgumentException if the {...@code StreamBasedSource} is
+ * <b>null</b>
+ */
+ public DefaultLocatorSupport(StreamBasedSource source)
+ {
+ if (source == null)
+ {
+ throw new IllegalArgumentException(
+ "StreamBasedSource must not be null!");
+ }
+ streamBasedSource = source;
+ }
+
+ /**
+ * Returns the underlying {...@code StreamBasedSource}.
+ *
+ * @return the {...@code StreamBasedSource}
+ */
+ public StreamBasedSource getStreamBasedSource()
+ {
+ return streamBasedSource;
+ }
+
+ /**
+ * Returns the encoding.
+ *
+ * @return the encoding
+ */
+ public String getEncoding()
+ {
+ return encoding;
+ }
+
+ /**
+ * Returns the default {...@code Locator}.
+ *
+ * @return the {...@code Locator}
+ */
+ public Locator getLocator()
+ {
+ return locator;
+ }
+
+ /**
+ * Loads data from the default {...@code Locator}. The {...@link Locator}
must
+ * have been set before using the {...@link #setLocator(Locator)} method;
+ * otherwise an exception is thrown.
+ *
+ * @throws ConfigurationException in case of an error
+ * @throws IllegalStateException if no {...@link Locator} has been set
+ */
+ public void load() throws ConfigurationException
+ {
+ if (getLocator() == null)
+ {
+ throw new IllegalStateException(
+ "A default Locator must be set before calling load()!");
+ }
+
+ load(getLocator());
+ }
+
+ /**
+ * Loads data from the specified {...@code Locator}. This implementation
+ * obtains the input URL from the {...@code Locator}. It then uses the
{...@code
+ * FileSystem} to obtain an input stream for this URL. This stream is then
+ * loaded.
+ *
+ * @param loc the {...@code Locator} to load from (must not be <b>null</b>)
+ * @throws ConfigurationException if an error occurs
+ * @throws IllegalArgumentException if the {...@code Locator} is
<b>null</b>
+ */
+ public void load(Locator loc) throws ConfigurationException
+ {
+ if (loc == null)
+ {
+ throw new IllegalArgumentException("Locator must not be null!");
+ }
+
+ InputStream in = getFileSystem().getInputStream(loc.getURL(false));
+ try
+ {
+ load(in);
+ }
+ finally
+ {
+ close(in);
+ }
+ }
+
+ /**
+ * Loads data from the specified {...@code Reader}. This implementation
+ * directly delegates to the underlying {...@code StreamBasedSource}.
+ *
+ * @param reader the reader to read from
+ * @throws ConfigurationException if an error occurs
+ */
+ public void load(Reader reader) throws ConfigurationException
+ {
+ try
+ {
+ getStreamBasedSource().load(reader);
+ }
+ catch (IOException ioex)
+ {
+ throw new ConfigurationException(ioex);
+ }
+ }
+
+ /**
+ * Loads data from the specified {...@code InputStream} using the given
+ * encoding. This implementation creates a {...@code Reader} for the
specified
+ * stream and delegates to {...@link #load(Reader)}.
+ *
+ * @param in the input stream
+ * @param encoding the encoding (can be <b>null</b>), then no specific
+ * encoding is set
+ * @throws ConfigurationException if an error occurs
+ */
+ public void load(InputStream in, String encoding)
+ throws ConfigurationException
+ {
+ Reader reader = null;
+
+ if (encoding != null)
+ {
+ try
+ {
+ reader = new InputStreamReader(in, encoding);
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new ConfigurationException(
+ "The requested encoding is not supported, try the
default encoding.",
+ e);
+ }
+ }
+
+ if (reader == null)
+ {
+ reader = new InputStreamReader(in);
+ }
+
+ load(reader);
+ }
+
+ /**
+ * Loads data from the specified {...@code InputStream} using the default
+ * encoding. This implementation calls {...@link #getEncoding()} to obtain
the
+ * current default encoding (which may be undefined) and then delegates to
+ * {...@link #load(InputStream, String)}.
+ *
+ * @param in the input stream
+ * @throws ConfigurationException if an error occurs
+ */
+ public void load(InputStream in) throws ConfigurationException
+ {
+ load(in, getEncoding());
+ }
+
+ /**
+ * Saves data to the default {...@link Locator}. A {...@link Locator} must
have
+ * been set using {...@link #setLocator(Locator)}; otherwise an exception
is
+ * thrown.
+ *
+ * @throws ConfigurationException if an error occurs
+ * @throws IllegalStateException if no {...@link Locator} is set
+ */
+ public void save() throws ConfigurationException
+ {
+ if (getLocator() == null)
+ {
+ throw new IllegalStateException(
+ "A default Locator must be set before calling save()!");
+ }
+
+ save(getLocator());
+ }
+
+ /**
+ * Saves data to the specified {...@code Locator}. This implementation
obtains
+ * the output URL from the given {...@code Locator} and uses the
+ * {...@link FileSystem} to create an output stream for it. Then it
delegates
+ * to {...@link #save(OutputStream)}.
+ *
+ * @param loc the {...@code Locator} (must not be <b>null</b>)
+ * @throws ConfigurationException if an error occurs
+ * @throws IllegalArgumentException if the {...@code Locator} is
<b>null</b>
+ */
+ public void save(Locator loc) throws ConfigurationException
+ {
+ if (loc == null)
+ {
+ throw new IllegalArgumentException("Locator must not be null!");
+ }
+
+ OutputStream out = getFileSystem().getOutputStream(loc.getURL(true));
+ try
+ {
+ save(out);
+ }
+ finally
+ {
+ close(out);
+ }
+ }
+
+ /**
+ * Saves data to the specified {...@code Writer}. This implementation
directly
+ * delegates to the underlying {...@code StreamBasedSource}.
+ *
+ * @param writer the writer
+ * @throws ConfigurationException if an error occurs
+ * @see StreamBasedSource#save(Writer)
+ */
+ public void save(Writer writer) throws ConfigurationException
+ {
+ try
+ {
+ getStreamBasedSource().save(writer);
+ }
+ catch (IOException ioex)
+ {
+ throw new ConfigurationException(ioex);
+ }
+ }
+
+ /**
+ * Saves data to the specified output stream using the given encoding. This
+ * implementation creates a writer for this output stream and delegates to
+ * {...@link #save(Writer)}.
+ *
+ * @param out the output stream
+ * @param encoding the encoding (can be <b>null</b>, then the
+ * platform-specific default encoding is used)
+ * @throws ConfigurationException if an error occurs
+ */
+ public void save(OutputStream out, String encoding)
+ throws ConfigurationException
+ {
+ Writer writer = null;
+
+ if (encoding != null)
+ {
+ try
+ {
+ writer = new OutputStreamWriter(out, encoding);
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new ConfigurationException(
+ "The requested encoding is not supported, try the
default encoding.",
+ e);
+ }
+ }
+
+ if (writer == null)
+ {
+ writer = new OutputStreamWriter(out);
+ }
+
+ save(writer);
+ }
+
+ /**
+ * Saves data to the specified output stream using the default encoding.
+ * This method calls {...@link #getEncoding()} to obtain the default
encoding
+ * (which may be undefined). Then it delegates to
+ * {...@link #save(OutputStream, String)}.
+ *
+ * @param out the output stream
+ * @throws ConfigurationException if an error occurs
+ */
+ public void save(OutputStream out) throws ConfigurationException
+ {
+ save(out, getEncoding());
+ }
+
+ /**
+ * Sets the default encoding. This encoding is used when reading data from
+ * streams and no explicit encoding is specified.
+ *
+ * @param the default encoding
+ */
+ public void setEncoding(String enc)
+ {
+ encoding = enc;
+ }
+
+ /**
+ * Sets the {...@code Locator}. This {...@code Locator} is used by the
{...@code
+ * load()} method that takes no arguments.
+ *
+ * @param locator the {...@code Locator}
+ */
+ public void setLocator(Locator locator)
+ {
+ this.locator = locator;
+ }
+
+ /**
+ * Returns the {...@code FileSystem} used by this object.
+ *
+ * @return the {...@code FileSyste}
+ */
+ public FileSystem getFileSystem()
+ {
+ return fileSystem;
+ }
+
+ /**
+ * Resets the {...@code FileSystem} used by this object to the default
{...@code
+ * FileSystem}.
+ */
+ public void resetFileSystem()
+ {
+ fileSystem = FileSystem.getDefaultFileSystem();
+ }
+
+ /**
+ * Sets the {...@code FileSystem} to be used by this object. The {...@code
+ * FileSystem} is used for resolving URLs returned by {...@code Locator}
+ * objects.
+ *
+ * @param fileSystem the new {...@code FileSystem} (must not be
<b>null</b>)
+ * @throws IllegalArgumentException if the {...@code FileSystem} is
<b>null</b>
+ */
+ public void setFileSystem(FileSystem fileSystem)
+ {
+ if (fileSystem == null)
+ {
+ throw new IllegalArgumentException("FileSystem must not be null!");
+ }
+ this.fileSystem = fileSystem;
+ }
+
+ /**
+ * Helper method for closing the specified object. Exceptions are rethrown
+ * as configuration exceptions.
+ *
+ * @param c the object to be closed
+ * @throws ConfigurationException if an I/O error occurs
+ */
+ static void close(Closeable c) throws ConfigurationException
+ {
+ try
+ {
+ c.close();
+ }
+ catch (IOException ioex)
+ {
+ throw new ConfigurationException("Error when closing stream",
ioex);
+ }
+ }
+}
Propchange:
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/DefaultLocatorSupport.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/DefaultLocatorSupport.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange:
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/base/DefaultLocatorSupport.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestDefaultLocatorSupport.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestDefaultLocatorSupport.java?rev=824486&view=auto
==============================================================================
---
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestDefaultLocatorSupport.java
(added)
+++
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestDefaultLocatorSupport.java
Mon Oct 12 20:35:07 2009
@@ -0,0 +1,660 @@
+/*
+ * 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.configuration2.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.Charset;
+
+import org.apache.commons.configuration2.ConfigurationAssert;
+import org.apache.commons.configuration2.ConfigurationException;
+import org.apache.commons.configuration2.fs.FileSystem;
+import org.apache.commons.configuration2.fs.Locator;
+import org.apache.commons.configuration2.fs.URLLocator;
+import org.apache.commons.configuration2.fs.VFSFileSystem;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test class for {...@code DefaultLocatorSupport}.
+ *
+ * @author Commons Configuration team
+ * @version $Id$
+ */
+public class TestDefaultLocatorSupport
+{
+ /** Constant defining some test data to be loaded or stored. */
+ private static final String TEST_DATA = "Test data for
TestDefaultLocatorSupport";
+
+ /** Constant for the name of the test file. */
+ private static final String TEST_FILE = "TestDefaultLocatorSupport.txt";
+
+ /** Constant for the encoding. */
+ private static final String ENCODING = "UTF8";
+
+ /** The input locator to the test file. */
+ private static Locator inputLocator;
+
+ /** The output locator for the test file. */
+ private static Locator outputLocator;
+
+ /** The stream based source used for testing. */
+ private StreamBasedSourceTestImpl source;
+
+ /** The object to be tested. */
+ private DefaultLocatorSupport locatorSupport;
+
+ /** A test file. */
+ private File testFile;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception
+ {
+ URL url = ConfigurationAssert.getOutURL(TEST_FILE);
+ URL urlNonExisting = ConfigurationAssert
+ .getOutURL("NonExistingFile.txt");
+ inputLocator = new URLLocator(url, urlNonExisting);
+ outputLocator = new URLLocator(urlNonExisting, url);
+ }
+
+ @Before
+ public void setUp() throws Exception
+ {
+ testFile = ConfigurationAssert.getOutFile(TEST_FILE);
+ source = new StreamBasedSourceTestImpl();
+ locatorSupport = new DefaultLocatorSupport(source);
+ }
+
+ /**
+ * Performs cleanup. Removes the test file if it exists.
+ */
+ @After
+ public void tearDown() throws Exception
+ {
+ if (testFile != null && testFile.exists())
+ {
+ assertTrue("Cannot remove test file", testFile.delete());
+ }
+ }
+
+ /**
+ * Helper method for reading the content of a reader into a string.
+ *
+ * @param reader the reader to read
+ * @return the content of the reader as string
+ * @throws IOException if an I/O error occurs
+ */
+ private static String read(Reader reader) throws IOException
+ {
+ StringBuilder buf = new StringBuilder();
+ BufferedReader in = new BufferedReader(reader);
+ String line;
+ while ((line = in.readLine()) != null)
+ {
+ buf.append(line);
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Helper method for writing test data into the given writer.
+ *
+ * @param writer the writer
+ * @throws IOException if an I/O error occurs
+ */
+ private static void write(Writer writer) throws IOException
+ {
+ PrintWriter out = new PrintWriter(writer);
+ out.print(TEST_DATA);
+ out.flush();
+ }
+
+ /**
+ * Helper method for checking the encoding that was passed to the source.
+ *
+ * @param expEnc the expected encoding
+ */
+ private void checkEncoding(String expEnc)
+ {
+ Charset expected = (expEnc == null) ? Charset.defaultCharset()
+ : Charset.forName(expEnc);
+ Charset actual = Charset.forName(source.encoding);
+ assertEquals("Wrong encoding", expected, actual);
+ }
+
+ /**
+ * Tests whether the test file was correctly written.
+ *
+ * @throws IOException if an error occurs
+ */
+ private void checkTestFile() throws IOException
+ {
+ FileReader in = new FileReader(testFile);
+ try
+ {
+ assertEquals("Wrong content of file", TEST_DATA, read(in));
+ }
+ finally
+ {
+ in.close();
+ }
+ }
+
+ /**
+ * Creates a test file with test data.
+ *
+ * @throws IOException if an I/O error occurs
+ */
+ private void createTestFile() throws IOException
+ {
+ FileWriter writer = new FileWriter(testFile);
+ try
+ {
+ write(writer);
+ }
+ finally
+ {
+ writer.close();
+ }
+ }
+
+ /**
+ * Tries to create an instance without a source. This should cause an
+ * exception.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testInitNoSource()
+ {
+ new DefaultLocatorSupport(null);
+ }
+
+ /**
+ * Tests a newly created instance.
+ */
+ @Test
+ public void testInit()
+ {
+ assertNull("Got an encoding", locatorSupport.getEncoding());
+ assertNull("Got a locator", locatorSupport.getLocator());
+ assertEquals("Wrong file system", FileSystem.getDefaultFileSystem(),
+ locatorSupport.getFileSystem());
+ }
+
+ /**
+ * Tests whether a file system can be set.
+ */
+ @Test
+ public void testSetFileSystem()
+ {
+ VFSFileSystem fs = new VFSFileSystem();
+ locatorSupport.setFileSystem(fs);
+ assertEquals("FileSystem not changed", fs, locatorSupport
+ .getFileSystem());
+ }
+
+ /**
+ * Tries to set a null file system. This should cause an exception.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetFileSystemNull()
+ {
+ locatorSupport.setFileSystem(null);
+ }
+
+ /**
+ * Tests whether the file system can be reset to the default one.
+ */
+ @Test
+ public void testResetFileSystem()
+ {
+ locatorSupport.setFileSystem(new VFSFileSystem());
+ locatorSupport.resetFileSystem();
+ assertEquals("Wrong file system", FileSystem.getDefaultFileSystem(),
+ locatorSupport.getFileSystem());
+ }
+
+ /**
+ * Tests the close() method if an exception occurs.
+ */
+ @Test
+ public void testCloseEx() throws IOException
+ {
+ Closeable c = EasyMock.createMock(Closeable.class);
+ c.close();
+ IOException ioex = new IOException();
+ EasyMock.expectLastCall().andThrow(ioex);
+ EasyMock.replay(c);
+ try
+ {
+ DefaultLocatorSupport.close(c);
+ fail("Exception not thrown!");
+ }
+ catch (ConfigurationException cex)
+ {
+ assertEquals("Wrong cause", ioex, cex.getCause());
+ EasyMock.verify(c);
+ }
+ }
+
+ /**
+ * Helper method for testing the results of a load operation.
+ *
+ * @param expEnc the expected encoding
+ */
+ private void checkLoad(String expEnc)
+ {
+ assertEquals("Wrong data", TEST_DATA, source.loadData);
+ checkEncoding(expEnc);
+ }
+
+ /**
+ * Tests the load() method if no locator was set. This should cause an
+ * exception.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testLoadNoLocator() throws ConfigurationException
+ {
+ locatorSupport.load();
+ }
+
+ /**
+ * Tests loading data from the default locator.
+ */
+ @Test
+ public void testLoadDefLocator() throws IOException, ConfigurationException
+ {
+ createTestFile();
+ locatorSupport.setLocator(inputLocator);
+ locatorSupport.load();
+ checkLoad(null);
+ }
+
+ /**
+ * Tests whether data from a specific locator can be loaded.
+ */
+ @Test
+ public void testLoadSpecificLocator() throws IOException,
+ ConfigurationException
+ {
+ Locator defloc = EasyMock.createMock(Locator.class);
+ EasyMock.replay(defloc);
+ locatorSupport.setLocator(defloc);
+ createTestFile();
+ locatorSupport.load(inputLocator);
+ checkLoad(null);
+ EasyMock.verify(defloc);
+ }
+
+ /**
+ * Tests whether the encoding is taken into account when loading from a
+ * locator.
+ */
+ @Test
+ public void testLoadLocatorEnc() throws IOException, ConfigurationException
+ {
+ createTestFile();
+ locatorSupport.setEncoding(ENCODING);
+ locatorSupport.setLocator(inputLocator);
+ locatorSupport.load();
+ checkLoad(ENCODING);
+ }
+
+ /**
+ * Tries to load data from a null locator. This should cause an exception.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testLoadLocatorNull() throws ConfigurationException
+ {
+ locatorSupport.load((Locator) null);
+ }
+
+ /**
+ * Tests whether exceptions are correctly handled when loading data from a
+ * locator.
+ */
+ @Test
+ public void testLoadLocatorEx() throws IOException, ConfigurationException
+ {
+ createTestFile();
+ source.ex = new IOException();
+ try
+ {
+ locatorSupport.load(inputLocator);
+ fail("Exception not thrown!");
+ }
+ catch (ConfigurationException cex)
+ {
+ assertEquals("Wrong cause", source.ex, cex.getCause());
+ }
+ }
+
+ /**
+ * Tests whether a stream can be loaded if the encoding is specified.
+ */
+ @Test
+ public void testLoadStreamEnc() throws ConfigurationException, IOException
+ {
+ createTestFile();
+ FileInputStream in = new FileInputStream(testFile);
+ try
+ {
+ locatorSupport.load(in, ENCODING);
+ checkLoad(ENCODING);
+ }
+ finally
+ {
+ in.close();
+ }
+ }
+
+ /**
+ * Tests whether a stream can be loaded with the default encoding.
+ */
+ @Test
+ public void testLoadStreamDefEnc() throws IOException,
+ ConfigurationException
+ {
+ createTestFile();
+ locatorSupport.setEncoding(ENCODING);
+ FileInputStream in = new FileInputStream(testFile);
+ try
+ {
+ locatorSupport.load(in);
+ checkLoad(ENCODING);
+ }
+ finally
+ {
+ in.close();
+ }
+ }
+
+ /**
+ * Tries to load data using an unsupported encoding.
+ */
+ @Test
+ public void testLoadStreamUnsupportedEnc() throws IOException,
+ ConfigurationException
+ {
+ createTestFile();
+ locatorSupport.setEncoding("an unsupported encoding!");
+ FileInputStream in = new FileInputStream(testFile);
+ try
+ {
+ locatorSupport.load(in);
+ fail("Unsupported encoding not detected!");
+ }
+ catch (ConfigurationException cex)
+ {
+ // ok
+ }
+ finally
+ {
+ in.close();
+ }
+ }
+
+ /**
+ * Tests whether IOExceptions thrown by the source on reading are converted
+ * to configuration exceptions.
+ */
+ @Test
+ public void testLoadReaderEx()
+ {
+ source.ex = new IOException();
+ try
+ {
+ locatorSupport.load(new StringReader(TEST_DATA));
+ fail("Exception not thrown!");
+ }
+ catch (ConfigurationException cex)
+ {
+ assertEquals("Wrong cause", source.ex, cex.getCause());
+ }
+ }
+
+ /**
+ * Tests whether IOExceptions thrown by the source on writing are converted
+ * to configuration exceptions.
+ */
+ @Test
+ public void testSaveWriterEx()
+ {
+ source.ex = new IOException();
+ try
+ {
+ locatorSupport.save(new StringWriter());
+ fail("Exception not thrown!");
+ }
+ catch (ConfigurationException cex)
+ {
+ assertEquals("Wrong cause", source.ex, cex.getCause());
+ }
+ }
+
+ /**
+ * Tests whether data can be saved to a stream if the encoding is
specified.
+ */
+ @Test
+ public void testSaveStreamEnc() throws IOException, ConfigurationException
+ {
+ FileOutputStream out = new FileOutputStream(testFile);
+ try
+ {
+ locatorSupport.save(out, ENCODING);
+ }
+ finally
+ {
+ out.close();
+ }
+ checkTestFile();
+ checkEncoding(ENCODING);
+ }
+
+ /**
+ * Tests whether the default encoding is taken into account when saving to
a
+ * stream.
+ */
+ @Test
+ public void testSaveStreamDefEnc() throws IOException,
+ ConfigurationException
+ {
+ locatorSupport.setEncoding(ENCODING);
+ FileOutputStream out = new FileOutputStream(testFile);
+ try
+ {
+ locatorSupport.save(out);
+ }
+ finally
+ {
+ out.close();
+ }
+ checkTestFile();
+ checkEncoding(ENCODING);
+ }
+
+ /**
+ * Tries to save to a stream with an unsupported encoding. This should
cause
+ * an exception.
+ */
+ @Test
+ public void testSaveStreamUnsupportedEnc() throws IOException,
+ ConfigurationException
+ {
+ FileOutputStream out = new FileOutputStream(testFile);
+ try
+ {
+ locatorSupport.save(out, "an unknown encoding!");
+ fail("Unsupported encoding not detected!");
+ }
+ catch (ConfigurationException cex)
+ {
+ // ok
+ }
+ finally
+ {
+ out.close();
+ }
+ }
+
+ /**
+ * Tries to save data is no locator is specified. This should cause an
+ * exception.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testSaveNoLocator() throws ConfigurationException
+ {
+ locatorSupport.save();
+ }
+
+ /**
+ * Tries to save data to a null locator. This should cause an exception.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testSaveLocatorNull() throws ConfigurationException
+ {
+ locatorSupport.save((Locator) null);
+ }
+
+ /**
+ * Tests the behavior of save(Locator) if an exception is thrown.
+ */
+ @Test
+ public void testSaveLocatorEx()
+ {
+ locatorSupport.setLocator(outputLocator);
+ source.ex = new IOException();
+ try
+ {
+ locatorSupport.save();
+ fail("Exception not thrown!");
+ }
+ catch (ConfigurationException cex)
+ {
+ assertEquals("Wrong cause", source.ex, cex.getCause());
+ }
+ }
+
+ /**
+ * Tests whether data can be saved using the default locator.
+ */
+ @Test
+ public void testSaveDefLocator() throws ConfigurationException, IOException
+ {
+ locatorSupport.setLocator(outputLocator);
+ locatorSupport.save();
+ checkTestFile();
+ checkEncoding(null);
+ }
+
+ /**
+ * Tests whether data can be saved using a specific locator.
+ */
+ @Test
+ public void testSaveSpecificLocator() throws ConfigurationException,
+ IOException
+ {
+ Locator defLoc = EasyMock.createMock(Locator.class);
+ EasyMock.replay(defLoc);
+ locatorSupport.setLocator(defLoc);
+ locatorSupport.save(outputLocator);
+ checkTestFile();
+ checkEncoding(null);
+ EasyMock.verify(defLoc);
+ }
+
+ /**
+ * Tests whether the encoding is taken into account when saving to a
+ * locator.
+ */
+ @Test
+ public void testSaveLocatorEnc() throws ConfigurationException, IOException
+ {
+ locatorSupport.setLocator(outputLocator);
+ locatorSupport.setEncoding(ENCODING);
+ locatorSupport.save();
+ checkTestFile();
+ checkEncoding(ENCODING);
+ }
+
+ /**
+ * A simple test implementation of the {...@code StreamBasedSource}
interface.
+ * This implementation implements the load() operation by the reading in an
+ * internal buffer. save() is implemented by writing a test text into the
+ * writer.
+ */
+ private static class StreamBasedSourceTestImpl implements StreamBasedSource
+ {
+ /** Stores text read by the load() method. */
+ String loadData;
+
+ /** Stores the encoding used by load() or save(). */
+ String encoding;
+
+ /** An exception to be thrown. */
+ IOException ex;
+
+ public void load(Reader reader) throws ConfigurationException,
+ IOException
+ {
+ if (ex != null)
+ {
+ throw ex;
+ }
+ loadData = read(reader);
+ if (reader instanceof InputStreamReader)
+ {
+ encoding = ((InputStreamReader) reader).getEncoding();
+ }
+ }
+
+ public void save(Writer writer) throws ConfigurationException,
+ IOException
+ {
+ if (ex != null)
+ {
+ throw ex;
+ }
+ write(writer);
+ if (writer instanceof OutputStreamWriter)
+ {
+ encoding = ((OutputStreamWriter) writer).getEncoding();
+ }
+ }
+ }
+}
Propchange:
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestDefaultLocatorSupport.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestDefaultLocatorSupport.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange:
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/base/TestDefaultLocatorSupport.java
------------------------------------------------------------------------------
svn:mime-type = text/plain