From 1b6404f2ab7fe93ecc0c7e4c91bc90c7aa94b42f Mon Sep 17 00:00:00 2001 From: liamfallon Date: Mon, 30 Jul 2018 17:13:22 +0100 Subject: Add resource handling utility class Add ResourceUtils, a class that provides utility methods for dealing with Java resources on the classpath. Change-Id: Ie4df249315ad145aabdfb35bb827ffbf6d79e095 Issue-ID: POLICY-922 Signed-off-by: liamfallon --- .../common/utils/resources/ResourceUtils.java | 214 ++++++++++++++ .../common/utils/resources/ResourceUtilsTest.java | 307 +++++++++++++++++++++ utils/src/test/resources/testdir/testfile.xml | 20 ++ 3 files changed, 541 insertions(+) create mode 100644 utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java create mode 100644 utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java create mode 100644 utils/src/test/resources/testdir/testfile.xml diff --git a/utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java b/utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java new file mode 100644 index 00000000..cca6e626 --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java @@ -0,0 +1,214 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.resources; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This is common utility class with static methods for handling Java resources on the class path. It is an abstract + * class to prevent any direct instantiation and private constructor to prevent extending this class. + */ +public abstract class ResourceUtils { + // Get a reference to the logger + private static final Logger LOGGER = LoggerFactory.getLogger(ResourceUtils.class); + + // The length of byte buffers used to read resources into strings + private static final int BYTE_BUFFER_LENGH = 1024; + + /** + * Private constructor used to prevent sub class instantiation. + */ + private ResourceUtils() { + // Prevent construction of this class + } + + /** + * Method to resolve a resource; the local file system is checked first and then the class path is checked. + * + * @param resourceName The resource name + * @return A URL to a resource + */ + public static URL getUrl4Resource(final String resourceName) { + // Check the local fine system first + final URL urlToResource = getLocalFile(resourceName); + + // Check if this is a local file + if (urlToResource != null) { + return urlToResource; + } else { + // Resort to the class path + return getUrlResource(resourceName); + } + } + + /** + * Method to return a resource as a string. The resource can be on the local file system or in the class path. The + * resource is resolved and loaded into a string. + * + * @param resourceName The resource name + * @return A string containing the resource + */ + public static String getResourceAsString(final String resourceName) { + // Get the resource as a stream, we'll convert it to a string then + final InputStream resourceStream = getResourceAsStream(resourceName); + if (resourceStream == null) { + return null; + } + + // Read the stream contents in to an output stream + final ByteArrayOutputStream resourceOutputStreamBuffer = new ByteArrayOutputStream(); + final byte[] resourceBuffer = new byte[BYTE_BUFFER_LENGH]; + int length; + try { + while ((length = resourceStream.read(resourceBuffer)) != -1) { + resourceOutputStreamBuffer.write(resourceBuffer, 0, length); + } + } catch (final IOException e) { + LOGGER.debug("error reading resource stream \"{}\" : " + e.getMessage(), resourceName, e); + return null; + } + + return resourceOutputStreamBuffer.toString(); + } + + /** + * Method to return a resource as a stream. The resource can be on the local file system or in the class path. The + * resource is resolved and returned as a stream. + * + * @param resourceName The resource name + * @return A stream attached to the resource + */ + public static InputStream getResourceAsStream(final String resourceName) { + // Find a URL to the resource first + final URL urlToResource = getUrl4Resource(resourceName); + + // Check if the resource exists + if (urlToResource == null) { + // No resource found + LOGGER.debug("cound not find resource \"{}\" : ", resourceName); + return null; + } + + // Read the resource into a string + try { + return urlToResource.openStream(); + } catch (final IOException e) { + // Any of many IO exceptions such as the resource is a directory + LOGGER.debug("error attaching resource \"{}\" to stream : " + e.getMessage(), resourceName, e); + return null; + } + } + + /** + * Method to get a URL resource from the class path. + * + * @param resourceName The resource name + * @return The URL to the resource + */ + public static URL getUrlResource(final String resourceName) { + try { + final ClassLoader classLoader = ResourceUtils.class.getClassLoader(); + + final String[] fileParts = resourceName.split("/"); + // Read the resource + URL url = classLoader.getResource(resourceName); + + // Check if the resource is defined + if (url != null) { + // Return the resource as a file name + LOGGER.debug("found URL resource \"{}\" : ", url); + return url; + } else { + url = classLoader.getResource(fileParts[fileParts.length - 1]); + if (url == null) { + LOGGER.debug("cound not find URL resource \"{}\" : ", resourceName); + return null; + } + LOGGER.debug("found URL resource \"{}\" : ", url); + return url; + } + } catch (final Exception e) { + LOGGER.debug("error getting URL resource \"{}\" : " + e.getMessage(), e); + return null; + } + } + + /** + * Method to get a URL resource from the local machine. + * + * @param resourceName The resource name + * @return The URL to the resource + */ + public static URL getLocalFile(final String resourceName) { + try { + // Input might already be in URL format + final URL ret = new URL(resourceName); + final File f = new File(ret.toURI()); + if (f.exists()) { + return ret; + } + } catch (final Exception ignore) { + // We ignore exceptions here and catch them below + } + + try { + final File f = new File(resourceName); + // Check if the file exists + if (f.exists()) { + final URL urlret = f.toURI().toURL(); + LOGGER.debug("resource \"{}\" was found on the local file system", f.toURI().toURL()); + return urlret; + } else { + LOGGER.debug("resource \"{}\" does not exist on the local file system", resourceName); + return null; + } + } catch (final Exception e) { + LOGGER.debug("error finding resource \"{}\" : " + e.getMessage(), e); + return null; + } + } + + /** + * Gets the file path for a resource on the local file system or on the class path. + * + * @param resource the resource to the get the file path for + * @return the resource file path + */ + public static String getFilePath4Resource(final String resource) { + if (resource == null) { + return null; + } + + URL modelFileUrl = getUrl4Resource(resource); + if (modelFileUrl != null) { + return modelFileUrl.getPath(); + } else { + return resource; + } + } +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java new file mode 100644 index 00000000..d1aa59d5 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java @@ -0,0 +1,307 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.resources; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * The Class ResourceUtilsTest. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ResourceUtilsTest { + private File tmpDir = null; + private File tmpEmptyFile = null; + private File tmpUsedFile = null; + + private String jarDirResource = null; + private String jarFileResource = null; + + private final String pathDirResource = "testdir"; + private final String pathFileResource = "testdir/testfile.xml"; + + private final String nonExistantResource = "somewhere/over/the/rainbow"; + private final String invalidResource = "@%%%\\\\_:::DESD"; + + /** + * Setup resource utils test. + * + * @throws IOException Signals that an I/O exception has occurred. + */ + @Before + public void setupResourceUtilsTest() throws IOException { + tmpDir = new File(System.getProperty("java.io.tmpdir")); + tmpEmptyFile = File.createTempFile(this.getClass().getName(), ".tmp"); + tmpUsedFile = File.createTempFile(this.getClass().getName(), ".tmp"); + + jarDirResource = "META-INF"; + jarFileResource = "META-INF/MANIFEST.MF"; + + final FileWriter fileWriter = new FileWriter(tmpUsedFile); + fileWriter.write("Bluebirds fly over the rainbow"); + fileWriter.close(); + } + + /** + * Test get url resource. + */ + @Test + public void testgetUrlResource() { + URL theUrl = ResourceUtils.getUrlResource(tmpDir.getAbsolutePath()); + assertNull(theUrl); + + theUrl = ResourceUtils.getUrlResource(tmpEmptyFile.getAbsolutePath()); + assertNull(theUrl); + + theUrl = ResourceUtils.getUrlResource(tmpUsedFile.getAbsolutePath()); + assertNull(theUrl); + + theUrl = ResourceUtils.getUrlResource(jarDirResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrlResource(jarFileResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrlResource(pathDirResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrlResource(pathFileResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrlResource("file:///" + pathDirResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getLocalFile("src/test/resources/" + pathDirResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getLocalFile("src/test/resources/" + pathFileResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrlResource(nonExistantResource); + assertNull(theUrl); + + theUrl = ResourceUtils.getUrlResource(invalidResource); + assertNull(theUrl); + + theUrl = ResourceUtils.getUrlResource(null); + assertNull(theUrl); + } + + /** + * Test get local file. + */ + @Test + public void testGetLocalFile() { + URL theUrl = ResourceUtils.getLocalFile(tmpDir.getAbsolutePath()); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getLocalFile(tmpEmptyFile.getAbsolutePath()); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getLocalFile(tmpUsedFile.getAbsolutePath()); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getLocalFile(jarDirResource); + assertNull(theUrl); + + theUrl = ResourceUtils.getLocalFile(jarFileResource); + assertNull(theUrl); + + theUrl = ResourceUtils.getLocalFile(pathDirResource); + assertNull(theUrl); + + theUrl = ResourceUtils.getLocalFile(pathFileResource); + assertNull(theUrl); + + theUrl = ResourceUtils.getLocalFile("src/test/resources/" + pathDirResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getLocalFile("src/test/resources/" + pathFileResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getLocalFile(nonExistantResource); + assertNull(theUrl); + + theUrl = ResourceUtils.getLocalFile(invalidResource); + assertNull(theUrl); + + theUrl = ResourceUtils.getLocalFile("file:///"); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getLocalFile("file:///testdir/testfile.xml"); + assertNull(theUrl); + + theUrl = ResourceUtils.getLocalFile(null); + assertNull(theUrl); + } + + /** + * Test get resource as stream. + */ + @Test + public void testGetResourceAsStream() { + InputStream theStream = ResourceUtils.getResourceAsStream(tmpDir.getAbsolutePath()); + assertNotNull(theStream); + + theStream = ResourceUtils.getResourceAsStream(tmpEmptyFile.getAbsolutePath()); + assertNotNull(theStream); + + theStream = ResourceUtils.getResourceAsStream(tmpUsedFile.getAbsolutePath()); + assertNotNull(theStream); + + theStream = ResourceUtils.getResourceAsStream(jarDirResource); + assertNotNull(theStream); + + theStream = ResourceUtils.getResourceAsStream(jarFileResource); + assertNotNull(theStream); + + theStream = ResourceUtils.getResourceAsStream(pathDirResource); + assertNotNull(theStream); + + theStream = ResourceUtils.getResourceAsStream(pathFileResource); + assertNotNull(theStream); + + theStream = ResourceUtils.getResourceAsStream("src/test/resources/" + pathDirResource); + assertNotNull(theStream); + + theStream = ResourceUtils.getResourceAsStream("src/test/resources/" + pathFileResource); + assertNotNull(theStream); + + theStream = ResourceUtils.getResourceAsStream(nonExistantResource); + assertNull(theStream); + + theStream = ResourceUtils.getResourceAsStream(invalidResource); + assertNull(theStream); + + theStream = ResourceUtils.getResourceAsStream(null); + assertNull(null); + + theStream = ResourceUtils.getResourceAsStream(""); + assertNull(null); + } + + /** + * Test get resource as string. + */ + @Test + public void testGetResourceAsString() { + String theString = ResourceUtils.getResourceAsString(tmpDir.getAbsolutePath()); + assertNotNull(theString); + + theString = ResourceUtils.getResourceAsString(tmpEmptyFile.getAbsolutePath()); + assertTrue(theString.equals("")); + + theString = ResourceUtils.getResourceAsString(tmpUsedFile.getAbsolutePath()); + assertTrue(theString.equals("Bluebirds fly over the rainbow")); + + theString = ResourceUtils.getResourceAsString(jarFileResource); + assertNotNull(theString); + + theString = ResourceUtils.getResourceAsString(pathDirResource); + assertNotNull(theString); + + theString = ResourceUtils.getResourceAsString(pathFileResource); + assertNotNull(theString); + + theString = ResourceUtils.getResourceAsString("src/test/resources/" + pathDirResource); + assertNotNull(theString); + + theString = ResourceUtils.getResourceAsString("src/test/resources/" + pathFileResource); + assertNotNull(theString); + + theString = ResourceUtils.getResourceAsString(nonExistantResource); + assertNull(theString); + + theString = ResourceUtils.getResourceAsString(invalidResource); + assertNull(theString); + + theString = ResourceUtils.getResourceAsString(null); + assertNull(theString); + + theString = ResourceUtils.getResourceAsString(""); + assertEquals("org\ntestdir\n", theString); + } + + @Test + public void testgetUrl4Resource() { + URL theUrl = ResourceUtils.getUrl4Resource(tmpDir.getAbsolutePath()); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrl4Resource(tmpEmptyFile.getAbsolutePath()); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrl4Resource(tmpUsedFile.getAbsolutePath()); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrl4Resource(jarDirResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrl4Resource(jarFileResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrl4Resource(pathDirResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrl4Resource(pathFileResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrl4Resource("src/test/resources/" + pathDirResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrl4Resource("src/test/resources/" + pathFileResource); + assertNotNull(theUrl); + + theUrl = ResourceUtils.getUrl4Resource(nonExistantResource); + assertNull(theUrl); + + theUrl = ResourceUtils.getUrl4Resource(invalidResource); + assertNull(theUrl); + } + + @Test + public void testGetFilePath4Resource() { + assertNull(ResourceUtils.getFilePath4Resource(null)); + assertEquals("/something/else", ResourceUtils.getFilePath4Resource("/something/else")); + assertTrue(ResourceUtils.getFilePath4Resource("xml/example.xml").endsWith("xml/example.xml")); + } + + /** + * Cleandown resource utils test. + */ + @After + public void cleandownResourceUtilsTest() { + tmpEmptyFile.delete(); + tmpUsedFile.delete(); + } +} diff --git a/utils/src/test/resources/testdir/testfile.xml b/utils/src/test/resources/testdir/testfile.xml new file mode 100644 index 00000000..4de3db14 --- /dev/null +++ b/utils/src/test/resources/testdir/testfile.xml @@ -0,0 +1,20 @@ + + -- cgit 1.2.3-korg