DefaultFileSystem.java
- /*
- * 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.io;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.net.URLConnection;
- import org.apache.commons.configuration2.ex.ConfigurationException;
- /**
- * FileSystem that uses java.io.File or HttpClient.
- *
- * @since 1.7
- */
- public class DefaultFileSystem extends FileSystem {
- /**
- * Wraps the output stream so errors can be detected in the HTTP response.
- *
- * @since 1.7
- */
- private static final class HttpOutputStream extends VerifiableOutputStream {
- /** The wrapped OutputStream */
- private final OutputStream stream;
- /** The HttpURLConnection */
- private final HttpURLConnection connection;
- public HttpOutputStream(final OutputStream stream, final HttpURLConnection connection) {
- this.stream = stream;
- this.connection = connection;
- }
- @Override
- public void close() throws IOException {
- stream.close();
- }
- @Override
- public void flush() throws IOException {
- stream.flush();
- }
- @Override
- public String toString() {
- return stream.toString();
- }
- @Override
- public void verify() throws IOException {
- if (connection.getResponseCode() >= HttpURLConnection.HTTP_BAD_REQUEST) {
- throw new IOException("HTTP Error " + connection.getResponseCode() + " " + connection.getResponseMessage());
- }
- }
- @Override
- public void write(final byte[] bytes) throws IOException {
- stream.write(bytes);
- }
- @Override
- public void write(final byte[] bytes, final int i, final int i1) throws IOException {
- stream.write(bytes, i, i1);
- }
- @Override
- public void write(final int i) throws IOException {
- stream.write(i);
- }
- }
- /**
- * Create the path to the specified file.
- *
- * @param file the target file
- * @throws ConfigurationException if the path cannot be created
- */
- private void createPath(final File file) throws ConfigurationException {
- // create the path to the file if the file doesn't exist
- if (file != null && !file.exists()) {
- final File parent = file.getParentFile();
- if (parent != null && !parent.exists() && !parent.mkdirs()) {
- throw new ConfigurationException("Cannot create path: " + parent);
- }
- }
- }
- @Override
- public String getBasePath(final String path) {
- final URL url;
- try {
- url = getURL(null, path);
- return FileLocatorUtils.getBasePath(url);
- } catch (final Exception e) {
- return null;
- }
- }
- @Override
- public String getFileName(final String path) {
- final URL url;
- try {
- url = getURL(null, path);
- return FileLocatorUtils.getFileName(url);
- } catch (final Exception e) {
- return null;
- }
- }
- @Override
- public InputStream getInputStream(final URL url) throws ConfigurationException {
- return getInputStream(url, null);
- }
- @Override
- public InputStream getInputStream(final URL url, final URLConnectionOptions urlConnectionOptions) throws ConfigurationException {
- // throw an exception if the target URL is a directory
- final File file = FileLocatorUtils.fileFromURL(url);
- if (file != null && file.isDirectory()) {
- throw new ConfigurationException("Cannot load a configuration from a directory");
- }
- try {
- return urlConnectionOptions == null ? url.openStream() : urlConnectionOptions.openConnection(url).getInputStream();
- } catch (final Exception e) {
- throw new ConfigurationException("Unable to load the configuration from the URL " + url, e);
- }
- }
- @Override
- public OutputStream getOutputStream(final File file) throws ConfigurationException {
- try {
- // create the file if necessary
- createPath(file);
- return new FileOutputStream(file);
- } catch (final FileNotFoundException e) {
- throw new ConfigurationException("Unable to save to file " + file, e);
- }
- }
- @Override
- public OutputStream getOutputStream(final URL url) throws ConfigurationException {
- // file URLs have to be converted to Files since FileURLConnection is
- // read only (https://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4191800)
- final File file = FileLocatorUtils.fileFromURL(url);
- if (file != null) {
- return getOutputStream(file);
- }
- // for non file URLs save through an URLConnection
- OutputStream out;
- try {
- final URLConnection connection = url.openConnection();
- connection.setDoOutput(true);
- // use the PUT method for http URLs
- if (connection instanceof HttpURLConnection) {
- final HttpURLConnection conn = (HttpURLConnection) connection;
- conn.setRequestMethod("PUT");
- }
- out = connection.getOutputStream();
- // check the response code for http URLs and throw an exception if an error occurred
- if (connection instanceof HttpURLConnection) {
- out = new HttpOutputStream(out, (HttpURLConnection) connection);
- }
- return out;
- } catch (final IOException e) {
- throw new ConfigurationException("Could not save to URL " + url, e);
- }
- }
- @Override
- public String getPath(final File file, final URL url, final String basePath, final String fileName) {
- String path = null;
- // if resource was loaded from jar file may be null
- if (file != null) {
- path = file.getAbsolutePath();
- }
- // try to see if file was loaded from a jar
- if (path == null) {
- if (url != null) {
- path = url.getPath();
- } else {
- try {
- path = getURL(basePath, fileName).getPath();
- } catch (final Exception e) {
- // simply ignore it and return null
- if (getLogger().isDebugEnabled()) {
- getLogger().debug(String.format("Could not determine URL for " + "basePath = %s, fileName = %s: %s", basePath, fileName, e));
- }
- }
- }
- }
- return path;
- }
- @Override
- public URL getURL(final String basePath, final String file) throws MalformedURLException {
- final File f = new File(file);
- // already absolute?
- if (f.isAbsolute()) {
- return FileLocatorUtils.toURL(f);
- }
- try {
- if (basePath == null) {
- return new URL(file);
- }
- final URL base = new URL(basePath);
- return new URL(base, file);
- } catch (final MalformedURLException uex) {
- return FileLocatorUtils.toURL(FileLocatorUtils.constructFile(basePath, file));
- }
- }
- @Override
- public URL locateFromURL(final String basePath, final String fileName) {
- try {
- final URL url;
- if (basePath == null) {
- return new URL(fileName);
- // url = new URL(name);
- }
- final URL baseURL = new URL(basePath);
- url = new URL(baseURL, fileName);
- // check if the file exists
- try (InputStream in = url.openStream()) {
- // nothing
- in.available();
- }
- return url;
- } catch (final IOException e) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Could not locate file " + fileName + " at " + basePath + ": " + e.getMessage());
- }
- return null;
- }
- }
- }