org.apache.jena.atlas.lib.Lib Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jena-base Show documentation
Show all versions of jena-base Show documentation
This module contains non-RDF library code and the common system runtime.
/*
* 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.jena.atlas.lib;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Stream;
import java.util.zip.Adler32;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import org.apache.commons.codec.digest.MurmurHash3;
import org.apache.commons.lang3.StringUtils;
import org.apache.jena.atlas.logging.Log;
public class Lib
{
private Lib() {}
/**
* Concatenate two "/" delimited path names.
*
* - If path (second argument) starts with "/", it is assumed to be absolute and path is returned.
* - If path (second argument) is "", return the directory.
* - Otherwise the arguments are concatenated ensuring there is a "/" between them.
*
*/
public static String concatPaths(String directory, String path) {
Objects.requireNonNull(directory);
Objects.requireNonNull(path);
if ( path.startsWith("/") )
return path;
if ( path.isEmpty())
return directory;
if ( directory.endsWith("/") )
return directory+path;
else
return directory+"/"+path;
}
/** Stream to {@link List} */
public static List toList(Stream stream) {
// Findability.
return StreamOps.toList(stream);
}
/** "ConcurrentHashSet" */
public static final Set concurrentHashSet() {
return SetUtils.concurrentHashSet();
}
public static final void sync(Object object) {
if ( object instanceof Sync syncobj )
syncobj.sync();
}
/**
* Return true if obj1 and obj are both null or are .equals, else return false
* Prefer {@link Objects#equals(Object, Object)}
*/
public static final boolean equals(T obj1, T obj2) {
// Include because other equals* operations are here.
return Objects.equals(obj1, obj2);
}
/** Return true if obj1 and obj are both null or are .equals, else return false */
public static final boolean equalsIgnoreCase(String str1, String str2) {
if ( str1 == null )
return str2 == null;
return str1.equalsIgnoreCase(str2);
}
/** Return true if obj1 and obj are not equal */
public static final boolean notEqual(T obj1, T obj2) {
return !Objects.equals(obj1, obj2);
}
/** Safely return the class short name for an object -- obj.getClass().getSimpleName() */
static public final String className(Object obj) {
if ( obj == null )
return "null";
return classShortName(obj.getClass());
}
/** Safely return the class short name for a class */
static public final String classShortName(Class > cls) {
if ( cls == null )
return "null";
return cls.getSimpleName();
}
/** Create {@link UnsupportedOperationException} with formatted message. */
static public UnsupportedOperationException unsupportedMethod(Object object, String method) {
return new UnsupportedOperationException(Lib.className(object) + "." + method);
}
/** Do two lists have the same elements without considering the order of the lists nor duplicates? */
public static boolean equalsListAsSet(List list1, List list2) {
if ( list1 == null && list2 == null )
return true;
if ( list1 == null ) return false;
if ( list2 == null ) return false;
return list1.containsAll(list2) && list2.containsAll(list1);
}
/** HashCode - allow nulls */
public static final int hashCodeObject(Object obj) { return hashCodeObject(obj, -4); }
/** HashCode - allow nulls */
public static final int hashCodeObject(Object obj, int nullHashCode) {
if ( obj == null )
return nullHashCode;
return obj.hashCode();
}
public static boolean isEmpty(CharSequence cs) {
// Hide implementation
return StringUtils.isEmpty(cs);
}
/** Non-locale lowercase {@link Locale#ROOT} */
public static String lowercase(String string) {
// Hide implementation
return string.toLowerCase(Locale.ROOT);
}
/** Non-locale uppercase {@link Locale#ROOT} */
public static String uppercase(String string) {
// Hide implementation
return string.toUpperCase(Locale.ROOT);
}
public static final void sleep(int milliSeconds) {
try { Thread.sleep(milliSeconds); }
catch (InterruptedException ex) { Log.warn(Lib.class, "interrupted", ex); }
}
/** Get an environment variable value; if not found try in the system properties. */
public static String getenv(String name) {
return getenv(name, name);
}
/**
* Get system properties (argument sysPropName) or if not found, read an
* environment variable value (argument envName).
*/
public static String getenv(String sysPropName, String envName) {
String x = System.getProperty(sysPropName);
if ( x == null )
x = System.getenv(envName);
return x;
}
/** Test whether a property (environment variable or system property) is true. */
public static boolean isPropertyOrEnvVarSetToTrue(String name) {
return isPropertyOrEnvVarSetToTrue(name, name);
}
/**
* Test whether a property (argument sysPropName) or an environment variable
* (argument envName) is true.
*/
public static boolean isPropertyOrEnvVarSetToTrue(String sysPropName, String envName) {
String value = getenv(sysPropName, envName);
if ( value == null )
return false;
return value.equalsIgnoreCase("true");
}
/**
* Read thread local, assuming that "null" means it does not exist for this thread.
* If null is read, the thread local is removed.
*/
public static X readThreadLocal(ThreadLocal threadLocal) {
X x = threadLocal.get();
if ( x == null )
threadLocal.remove();
return x;
}
/**
* @see CRC32
*/
public static long crc32(byte[] bytes)
{
return crc(new CRC32(), bytes);
}
/** Faster than CRC32, nearly as good.
* @see Adler32
*/
public static long adler32(byte[] bytes) {
return crc(new Adler32(), bytes);
}
private static long crc(Checksum alg, byte[] bytes) {
alg.reset();
alg.update(bytes, 0, bytes.length);
return alg.getValue();
}
/** Calculate the Murmur3 hash of a string, and return it as a hex-encoded string. */
public static String murmurHashHex(String string) {
byte[] input = string.getBytes(StandardCharsets.UTF_8);
long[] x = MurmurHash3.hash128x64(input);
// Important to do long to hex in lo to hi byte order. Then, it agrees with the Guava function
// To put it another way, a hash value is bytes, not longs (in Java long is hi-lo byte order).
// String xs = String.format("%016x%016x", Long.reverseBytes(x[0]), Long.reverseBytes(x[1]));
char[] chars = new char[32];
longAsHexLC(x[0], chars, 0);
longAsHexLC(x[1], chars, 16);
return new String(chars);
}
/** Long to hex (lower case) chars with low byte first. */
private static void longAsHexLC(long value, char[] chars, int start) {
// Avoiding generating intermediate strings from e.g. Bytes.asHexLC
// Byte loop.
// Bytes get encoded "high bits first". "AF" is value A*16+F
for ( int idx = 0; idx < 8; idx++ ) {
int i = idx * 8;
int bValue = (int)((value >> i) & 0xFF);
// Keep order of the byte - high nibble, low nibble.
int hi = (bValue & 0xF0) >> 4;
int lo = (bValue & 0x0F);
char chHi = Chars.hexDigitsLC[hi];
char chLo = Chars.hexDigitsLC[lo];
chars[start + 2 * idx] = chHi;
chars[start + 2 * idx + 1] = chLo;
}
}
// Powerset (returned as a list).
// Calculate 2^N then loop i on 0 to 2^n-1
// create the set for this entry.
// for the j-th element of the input
// include the element if the j-th bit is set in i.
// See also Guava.Sets.powerSet
/** PowerSet */
public static Set> powerSet(Set elts) {
List list = new ArrayList<>(elts);
int size = list.size();
long N = (long) Math.pow(2, list.size());
Set> output = new HashSet<>();
for (int i = 0; i < N; i++) {
// This elements.
Set elt = new HashSet<>();
// for every bit in N
for (int j = 0; j < size; j++) {
int x = (1<