diff --git a/src/main/groovy/net/gleske/jervis/tools/GZip.groovy b/src/main/groovy/net/gleske/jervis/tools/GZip.groovy new file mode 100644 index 00000000..0846ca88 --- /dev/null +++ b/src/main/groovy/net/gleske/jervis/tools/GZip.groovy @@ -0,0 +1,105 @@ +/* + Copyright 2014-2023 Sam Gleske - https://github.com/samrocketman/jervis + + 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. + */ +package net.gleske.jervis.tools + +import java.util.zip.Deflater +import java.util.zip.GZIPOutputStream + + +/** + A class to provide compression features to Jervis, specifically GZip. + GZip provides groovy-like leftShift for compressing strings. This + class also uses maximum compression by default and provides an easy means to + change the compression level. + + +

Sample usage

+

To run this example, clone Jervis and execute ./gradlew console + to bring up a Groovy Console + with the classpath set up.

+ +

Write out a compressed file

+ +

+import net.gleske.jervis.tools.GZip
+
+new File('test.gz').withOutputStream { OutputStream os ->
+    try {
+        (new GZip(os)).withCloseable {
+            it << 'hello world\n\nMy friend\n'
+        }
+    } finally {
+        os.close()
+    }
+}
+
+ +

Upload a compressed file

+

This example uploads compressed data directly to Sonatype Nexus.

+

+import net.gleske.jervis.tools.GZip
+import net.gleske.jervis.tools.SecurityIO
+
+String username = 'your user'
+String password = 'your pass'
+
+URL api_url = new URL('http://localhost:8081/repository/hosted-raw-repo/file.gz')
+HttpURLConnection response = api_url.openConnection().with { conn ->
+    conn.doOutput = true
+    conn.setRequestMethod('PUT')
+    conn.setRequestProperty('Authorization', "Basic " + SecurityIO.encodeBase64("${username}:${password}"))
+    conn.setRequestProperty('Accept', '*/*')
+    conn.setRequestProperty('Expect', '100-continue')
+    conn.outputStream.withCloseable { nexus_os ->
+        new GZip(nexus_os).withCloseable { gzip ->
+            gzip << 'hello world\n\nMy friend\n'
+        }
+    }
+    conn
+}
+// getting the response code completes the setup and makes the network connection
+assert response.responseCode == 201
+
+ */ + + class GZip extends GZIPOutputStream { + + /** + Creates a {@link java.util.zip.GZIPOutputStream} with maximum compression enabled. + @param os An {@link java.io.OutputStream to wrap which will write out compressed data. + @param level A compression level between fastest (1) and best compression (9). + */ + GZip(OutputStream os, Integer level = Deflater.BEST_COMPRESSION) { + super(os) + setLevel(level) + } + + /** + This can change the compression level before you write data to GZip after it was instantiated. + @param level A compression level between fastest (1) and best compression (9). + */ + void setLevel(Integer level) { + this.@def.setLevel(level) + } + + /** + Write a String similar to how you would write to a file with leftShift on a {@link java.io.Writer}. + @param shiftString A string which will be written out after being compressed. + */ + OutputStream leftShift(String shiftString) { + leftShift(shiftString.bytes) + } +} diff --git a/src/test/groovy/net/gleske/jervis/tools/GZipTest.groovy b/src/test/groovy/net/gleske/jervis/tools/GZipTest.groovy new file mode 100644 index 00000000..45e0082e --- /dev/null +++ b/src/test/groovy/net/gleske/jervis/tools/GZipTest.groovy @@ -0,0 +1,54 @@ +/* + Copyright 2014-2023 Sam Gleske - https://github.com/samrocketman/jervis + + 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. + */ +package net.gleske.jervis.tools +//the GZipTest() class automatically sees the GZip() class because they're in the same package + +import java.util.zip.GZIPInputStream +import org.junit.Test + +class GZipTest extends GroovyTestCase { + @Test public void test_GZip_utility_decompression() { + StringWriter stdout = new StringWriter() + StringWriter stderr = new StringWriter() + Process proc = 'gunzip'.execute() + // write to stdin + proc.outputStream.withCloseable { stdin -> + new GZip(stdin).withCloseable { + it << 'hello\n' + } + } + // capture stdout + proc.waitForProcessOutput(stdout, stderr) + // stdout is decompressed data by gunzip + assert stdout.toString() == 'hello\n' + assert stderr.toString() == '' + assert proc.isAlive() == false + assert proc.exitValue() == 0 + } + @Test public void test_GZip_fast_decompression() { + String text_to_compress = '' + ByteArrayOutputStream compressed = new ByteArrayOutputStream() + // fast compression + new GZip(compressed, 0).withCloseable { + it << text_to_compress + } + ByteArrayInputStream is = new ByteArrayInputStream(compressed.toByteArray()) + ByteArrayOutputStream plain = new ByteArrayOutputStream() + GZIPInputStream gunzip = new GZIPInputStream(is) + plain << gunzip + assert plain.toString() == text_to_compress + } +}