Add resource handling utility class 45/58045/2
authorliamfallon <liam.fallon@ericsson.com>
Mon, 30 Jul 2018 16:13:22 +0000 (17:13 +0100)
committerliamfallon <liam.fallon@ericsson.com>
Tue, 31 Jul 2018 19:34:46 +0000 (20:34 +0100)
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 <liam.fallon@ericsson.com>
utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java [new file with mode: 0644]
utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java [new file with mode: 0644]
utils/src/test/resources/testdir/testfile.xml [new file with mode: 0644]

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 (file)
index 0000000..cca6e62
--- /dev/null
@@ -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 (file)
index 0000000..d1aa59d
--- /dev/null
@@ -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 (file)
index 0000000..4de3db1
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============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=========================================================
+-->