This is an automated email from the ASF dual-hosted git repository.

leerho pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/datasketches-characterization.git


The following commit(s) were added to refs/heads/master by this push:
     new d5238f5  Add ResourceFiles to 
src/main/java/org/apache/datasketches/characterization
d5238f5 is described below

commit d5238f5142d38cd6bc0a84eaed5086668e95ea48
Author: Lee Rhodes <[email protected]>
AuthorDate: Wed May 29 10:29:49 2024 -0700

    Add ResourceFiles to
    src/main/java/org/apache/datasketches/characterization
    
    Update pom.
    
    Correct reference in Job to the new ResourceFiles.
---
 pom.xml                                            |   4 +-
 src/main/java/org/apache/datasketches/Job.java     |   2 +-
 .../characterization/ResourceFiles.java            | 239 +++++++++++++++++++++
 3 files changed, 242 insertions(+), 3 deletions(-)

diff --git a/pom.xml b/pom.xml
index 082786f..552da6c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -155,13 +155,13 @@ under the License.
       <!-- <scope>test</scope> remove so we can run from main -->
     </dependency>
 
-    <!-- Test Scope -->
+    <!-- Test Scope 
     <dependency>
       <groupId>org.apache.datasketches</groupId>
       <artifactId>datasketches-java-common</artifactId>
       <version>${datasketches-java-common.version}</version>
       <scope>test</scope>
-    </dependency>
+    </dependency> -->
     
     <dependency>
       <groupId>org.apache.datasketches</groupId>
diff --git a/src/main/java/org/apache/datasketches/Job.java 
b/src/main/java/org/apache/datasketches/Job.java
index f170d42..5332c60 100644
--- a/src/main/java/org/apache/datasketches/Job.java
+++ b/src/main/java/org/apache/datasketches/Job.java
@@ -31,7 +31,7 @@ import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.SimpleTimeZone;
 
-import org.apache.datasketches.common.test.ResourceFiles;
+import org.apache.datasketches.characterization.ResourceFiles;
 
 /**
  * This class parses an input string job file, which contains properties for a 
specific
diff --git 
a/src/main/java/org/apache/datasketches/characterization/ResourceFiles.java 
b/src/main/java/org/apache/datasketches/characterization/ResourceFiles.java
new file mode 100644
index 0000000..d08c60d
--- /dev/null
+++ b/src/main/java/org/apache/datasketches/characterization/ResourceFiles.java
@@ -0,0 +1,239 @@
+/*
+ * 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.datasketches.characterization;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Common utilities for testing
+ *
+ * @author Lee Rhodes
+ */
+public class ResourceFiles {
+  private static final String LS = System.getProperty("line.separator");
+
+  //Get Resources
+
+  private static final int BUF_SIZE = 1 << 13;
+
+
+  /**
+   * Gets the file defined by the given resource file's shortFileName.
+   * @param shortFileName the last name in the pathname's name sequence.
+   * @return the file defined by the given resource file's shortFileName.
+   */
+  @SuppressWarnings("resource")
+  public static File getResourceFile(final String shortFileName) {
+    Objects.requireNonNull(shortFileName, "input parameter 'String 
shortFileName' cannot be null.");
+    final String slashName = (shortFileName.charAt(0) == '/') ? shortFileName 
: '/' + shortFileName;
+    final URL url = ResourceFiles.class.getResource(slashName);
+    Objects.requireNonNull(url, "resource " + slashName + " returns null 
URL.");
+    File file;
+    file = createTempFile(slashName);
+    if (url.getProtocol().equals("jar")) { //definitely a jar
+      try (final InputStream input = 
ResourceFiles.class.getResourceAsStream(slashName);
+        final OutputStream out = new FileOutputStream(file)) {
+        Objects.requireNonNull(input, "InputStream  is null.");
+        int numRead = 0;
+        final byte[] buf = new byte[1024];
+        while ((numRead = input.read(buf)) != -1) { out.write(buf, 0, 
numRead); }
+      } catch (final IOException e ) { throw new RuntimeException(e); }
+    } else { //protocol says resource is not a jar, must be a file
+      file = new File(getResourcePath(url));
+    }
+    if (!file.setReadable(false, true)) {
+      throw new IllegalStateException("Failed to set owner only 'Readable' on 
file");
+    }
+    if (!file.setWritable(false, false)) {
+      throw new IllegalStateException("Failed to set everyone 'Not Writable' 
on file");
+    }
+    return file;
+  }
+
+  /**
+   * Returns a byte array of the contents of the file defined by the given 
resource file's shortFileName.
+   * @param shortFileName the last name in the pathname's name sequence.
+   * @return a byte array of the contents of the file defined by the given 
resource file's shortFileName.
+   * @throws IllegalArgumentException if resource cannot be read.
+   */
+  public static byte[] getResourceBytes(final String shortFileName) {
+    Objects.requireNonNull(shortFileName, "input parameter 'String 
shortFileName' cannot be null.");
+    final String slashName = (shortFileName.charAt(0) == '/') ? shortFileName 
: '/' + shortFileName;
+    final URL url = ResourceFiles.class.getResource(slashName);
+    Objects.requireNonNull(url, "resource " + slashName + " returns null 
URL.");
+    final byte[] out;
+    if (url.getProtocol().equals("jar")) { //definitely a jar
+      try (final InputStream input = 
ResourceFiles.class.getResourceAsStream(slashName)) {
+        out = readAllBytesFromInputStream(input);
+      } catch (final IOException e) { throw new RuntimeException(e); }
+    } else { //protocol says resource is not a jar, must be a file
+      try {
+        out = Files.readAllBytes(Paths.get(getResourcePath(url)));
+      } catch (final IOException e) { throw new RuntimeException(e); }
+    }
+    return out;
+  }
+
+  /**
+   * Note: This is only needed in Java 8 as it is part of Java 9+.
+   * Read all bytes from the given <i>InputStream</i>.
+   * This is limited to streams that are no longer than the maximum 
allocatable byte array determined by the VM.
+   * This may be a little smaller than <i>Integer.MAX_VALUE</i>.
+   * @param in the Input Stream
+   * @return byte array
+   */
+  public static byte[] readAllBytesFromInputStream(final InputStream in) {
+    return readBytesFromInputStream(Integer.MAX_VALUE, in);
+  }
+
+  /**
+   * Note: This is only needed in Java 8 as is part of Java 9+.
+   * Read <i>numBytesToRead</i> bytes from an input stream into a single byte 
array.
+   * This is limited to streams that are no longer than the maximum 
allocatable byte array determined by the VM.
+   * This may be a little smaller than <i>Integer.MAX_VALUE</i>.
+   * @param numBytesToRead number of bytes to read
+   * @param in the InputStream
+   * @return the filled byte array from the input stream
+   * @throws IllegalArgumentException if array size grows larger than what can 
be safely allocated by some VMs.
+
+   */
+  public static byte[] readBytesFromInputStream(final int numBytesToRead, 
final InputStream in) {
+    if (numBytesToRead < 0) { throw new 
IllegalArgumentException("numBytesToRead must be positive or zero."); }
+
+    List<byte[]> buffers = null;
+    byte[] result = null;
+    int totalBytesRead = 0;
+    int remaining = numBytesToRead;
+    int chunkCnt;
+    do {
+        final byte[] partialBuffer = new byte[Math.min(remaining, BUF_SIZE)];
+        int numRead = 0;
+
+        try {
+          // reads input stream in chunks of partial buffers, stops at EOF or 
when remaining is zero.
+          while ((chunkCnt =
+                in.read(partialBuffer, numRead, Math.min(partialBuffer.length 
- numRead, remaining))) > 0) {
+              numRead += chunkCnt;
+              remaining -= chunkCnt;
+          }
+        } catch (final IOException e) { throw new RuntimeException(e); }
+
+        if (numRead > 0) {
+            if (Integer.MAX_VALUE - Long.BYTES - totalBytesRead < numRead) {
+              throw new IllegalArgumentException(
+                  "Input stream is larger than what can be safely allocated as 
a byte[] in some VMs."); }
+            totalBytesRead += numRead;
+            if (result == null) {
+                result = partialBuffer;
+            } else {
+                if (buffers == null) {
+                    buffers = new ArrayList<>();
+                    buffers.add(result);
+                }
+                buffers.add(partialBuffer);
+            }
+        }
+    } while (chunkCnt >= 0 && remaining > 0);
+
+    final byte[] out;
+    if (buffers == null) {
+        if (result == null) {
+          out = new byte[0];
+        } else {
+          out = result.length == totalBytesRead ? result : 
Arrays.copyOf(result, totalBytesRead);
+        }
+        return out;
+    }
+
+    result = new byte[totalBytesRead];
+    int offset = 0;
+    remaining = totalBytesRead;
+    for (byte[] b : buffers) {
+        final int count = Math.min(b.length, remaining);
+        System.arraycopy(b, 0, result, offset, count);
+        offset += count;
+        remaining -= count;
+    }
+    return result;
+  }
+
+  private static String getResourcePath(final URL url) { //must not be null
+    try {
+      final URI uri = url.toURI();
+      //decodes any special characters
+      final String path = uri.isAbsolute() ? 
Paths.get(uri).toAbsolutePath().toString() : uri.getPath();
+      return path;
+    } catch (final URISyntaxException e) {
+      throw new IllegalArgumentException("Cannot find resource: " + 
url.toString() + LS + e);
+    }
+  }
+
+  /**
+   * Create an empty temporary file.
+   * On a Mac these files are stored at the system variable $TMPDIR.  They 
should be cleared on a reboot.
+   * @param shortFileName the name before prefixes and suffixes are added here 
and by the OS.
+   * The final extension will be the current extension. The prefix "temp_" is 
added here.
+   * @return a temp file,which will be eventually deleted by the OS
+   */
+  private static File createTempFile(final String shortFileName) {
+    //remove any leading slash
+    final String resName = (shortFileName.charAt(0) == '/') ? 
shortFileName.substring(1) : shortFileName;
+    final String suffix;
+    final String name;
+    final int  lastIdx = resName.length() - 1;
+    final int lastIdxOfDot = resName.lastIndexOf('.');
+    if (lastIdxOfDot == -1) {
+      suffix = ".tmp";
+      name = resName;
+    } else if (lastIdxOfDot == lastIdx) {
+      suffix = ".tmp";
+      name = resName.substring(0, lastIdxOfDot);
+    } else { //has a real suffix
+      suffix = resName.substring(lastIdxOfDot);
+      name = resName.substring(0, lastIdxOfDot);
+    }
+    final File file;
+    try {
+      file = File.createTempFile("temp_" + name, suffix);
+      if (!file.setReadable(false, true)) {
+        throw new IllegalStateException("Failed to set only owner 'Readable' 
on file");
+      }
+      if (!file.setWritable(false, true)) {
+        throw new IllegalStateException("Failed to set only owner 'Writable' 
on file");
+      }
+
+    } catch (final IOException e) { throw new RuntimeException(e); }
+    return file;
+  }
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to