Skip to content

Commit

Permalink
Adding utils from other projects
Browse files Browse the repository at this point in the history
  • Loading branch information
hohonuuli committed Mar 14, 2024
1 parent 318088e commit 242c8e2
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 0 deletions.
66 changes: 66 additions & 0 deletions jcommons/src/main/java/org/mbari/jcommons/util/CloseableLock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.mbari.jcommons.util;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* A wrapper around a ReentrantLock that allows you to use it in a try-with-resources block.
* {@code
* var lock = new CloseableLock();
* try (lock.lock()) {
* // do something
* }
* }
*
* @see https://debugagent.com/relearning-java-thread-primitives
*/
public class CloseableLock implements AutoCloseable, Lock {
private final Lock lock;

public CloseableLock() {
this.lock = new ReentrantLock();
}

public CloseableLock(boolean fair) {
this.lock = new ReentrantLock(fair);
}


public Lock getLock() {
return lock;
}

@Override
public void close() throws Exception {
lock.unlock();
}

public void lock() {
lock.lock();
}

public void lockInterruptibly() throws InterruptedException {
lock.lock();
}

public void unlock() {
lock.unlock();
}

@Override
public boolean tryLock() {
return lock.tryLock();
}

@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return lock.tryLock(time, unit);
}

@Override
public Condition newCondition() {
return lock.newCondition();
}
}
54 changes: 54 additions & 0 deletions scommons/src/main/scala/org/mbari/scommons/etc/jdk/Images.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.mbari.scommons.etc.jdk

import java.awt.image.{BufferedImage, RenderedImage}
import java.io.{ByteArrayInputStream, ByteArrayOutputStream, IOException}
import java.net.URL
import java.nio.file.{Files, Path}
import java.text.SimpleDateFormat
import java.util.Date
import java.util.TimeZone
import javax.imageio.{IIOImage, ImageIO, ImageTypeSpecifier}

object Images:

/**
* Saves the image to the target file. The format of the saved file is determined by it's extension. Will create the
* parent directories if they do not exist.
*
* @param image
* The image to save
* @param target
* The file to save the image to.
*
* @throws IOException
*/
@throws(classOf[IOException])
def saveImage(image: RenderedImage, target: Path): Unit =
// Extract the type from the extension
val parent = target.getParent
if Files.notExists(parent) then Files.createDirectories(parent)
val path = target.toAbsolutePath.normalize.toString
val dotIdx = path.lastIndexOf(".")
val ext = path.substring(dotIdx + 1)
ImageIO.write(image, ext, target.toFile)

/**
* Convert a buffered image to an array of bytes in JPEG format
* @param image
* @return
*/
def toJpegByteArray(image: BufferedImage): Array[Byte] = toImageByteArray(image, "jpg")

/**
* Convert a buffered image to an array of bytes in PNG format
* @param image
* @return
*/
def toPngByteArray(image: BufferedImage): Array[Byte] = toImageByteArray(image, "png")

private def toImageByteArray(image: BufferedImage, format: String): Array[Byte] =
val os0 = new ByteArrayOutputStream
ImageIO.write(image, format, os0)
val imageBytes = os0.toByteArray
os0.close()
imageBytes
35 changes: 35 additions & 0 deletions scommons/src/main/scala/org/mbari/scommons/etc/jdk/Instants.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.mbari.scommons.etc.jdk

import java.time.Instant
import java.time.format.DateTimeFormatter
import scala.util.Try
import java.time.ZoneOffset
import java.time.temporal.ChronoUnit

object Instants:

private val compactTimeFormatter =
DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX").withZone(java.time.ZoneOffset.UTC)

private val formatters = Seq(
compactTimeFormatter,
DateTimeFormatter.ISO_DATE_TIME,
DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss.SSSX").withZone(java.time.ZoneOffset.UTC),
DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss.SSSSSSX").withZone(java.time.ZoneOffset.UTC),
DateTimeFormatter.ISO_OFFSET_DATE_TIME,
DateTimeFormatter.ISO_INSTANT)

def parseIso8601(s: String): Option[Instant] =
formatters.to(LazyList).flatMap(tryToParse(s, _)).headOption

def compactFormat(instant: Instant): String = compactTimeFormatter.format(instant)

private def tryToParse(s: String, formatter: DateTimeFormatter): Option[Instant] =
Try(Instant.from(formatter.parse(s))).toOption

def roundToHour(i: Instant): Instant =
val z = i.atZone(ZoneOffset.UTC)
val minutes = z.getMinute()
val adjustedTime = if (minutes >= 30) z.plusHours(1) else z
val truncatedTime = adjustedTime.truncatedTo(ChronoUnit.HOURS)
truncatedTime.toInstant()
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.mbari.scommons.etc.jdk

object Strings:

def addTrailingSlash(s: String): String = if s.endsWith("/") then s else s + "/"

def removeTrailingSlash(s: String): String =
if s.endsWith("/") then s.substring(0, s.length - 1) else s

0 comments on commit 242c8e2

Please sign in to comment.