blob: 6434cbf4b3e755e278a99d7a08a2100f11bd1439 [file] [log] [blame]
/*
* Copyright (c) 2015 Eike Stepper (Berlin, Germany) and others.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.userstorage.internal.util;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Locale;
import java.util.Random;
/**
* @author Eike Stepper
*/
public final class StringUtil
{
public static final String EMPTY = ""; //$NON-NLS-1$
public static final String UTF8 = "UTF-8"; //$NON-NLS-1$
private static final byte[] NO_BYTES = {};
private static final byte[] KEY = new byte[256];
private static Random random;
private StringUtil()
{
}
public static boolean isEmpty(String str)
{
return str == null || str.length() == 0;
}
public static String safe(String str)
{
return safe(str, EMPTY);
}
public static String safe(String str, String def)
{
if (str == null)
{
return def;
}
return str;
}
public static String charToHex(char ch)
{
return Integer.toHexString(ch).toUpperCase(Locale.ENGLISH);
}
public static char hexToChar(String s) throws NumberFormatException
{
return (char)Integer.parseInt(s, 16);
}
public static byte[] toUTF(String str) throws RuntimeException
{
if (str == null)
{
return null;
}
if (str.length() == 0)
{
return NO_BYTES;
}
try
{
return str.getBytes(UTF8);
}
catch (UnsupportedEncodingException ex)
{
throw new RuntimeException(ex);
}
}
public static String fromUTF(byte[] bytes) throws RuntimeException
{
if (bytes == null)
{
return null;
}
if (bytes.length == 0)
{
return EMPTY;
}
try
{
return new String(bytes, UTF8);
}
catch (UnsupportedEncodingException ex)
{
throw new RuntimeException(ex);
}
}
public static URI newURI(String uri) throws RuntimeException
{
if (isEmpty(uri))
{
return null;
}
try
{
return new URI(uri);
}
catch (URISyntaxException ex)
{
throw new RuntimeException(ex);
}
}
public static URI newURI(URI uri, String path) throws RuntimeException
{
if (isEmpty(path))
{
return uri;
}
String result = uri.toString();
if (!result.endsWith("/"))
{
result += "/";
}
if (path.startsWith("/"))
{
result += path.substring(1);
}
else
{
result += path;
}
return newURI(result);
}
public static String encodeURI(URI uri)
{
return encodeURI(uri.toString());
}
public static String decodeURI(String encoded)
{
try
{
return URLDecoder.decode(encoded, UTF8);
}
catch (UnsupportedEncodingException ex)
{
// UTF-8 should always be available.
return encoded;
}
}
public static String encodeURI(String uri)
{
try
{
uri = URLEncoder.encode(uri, UTF8);
}
catch (UnsupportedEncodingException ex)
{
// UTF-8 should always be available.
}
return uri;
}
public static byte[] encrypt(String str) throws RuntimeException
{
if (str == null)
{
return null;
}
if (str.length() == 0)
{
return NO_BYTES;
}
byte[] bytes = toUTF(str);
byte[] result = new byte[bytes.length + 1];
synchronized (KEY)
{
if (random == null)
{
random = new Random(System.currentTimeMillis());
random.nextBytes(KEY);
}
}
int j = random.nextInt(KEY.length);
result[bytes.length] = (byte)(j + Byte.MIN_VALUE);
crypt(bytes, result, bytes.length, j);
return result;
}
public static String decrypt(byte[] bytes) throws RuntimeException
{
if (bytes == null)
{
return null;
}
if (bytes.length == 0)
{
return EMPTY;
}
byte[] result = new byte[bytes.length - 1];
int j = bytes[result.length] - Byte.MIN_VALUE;
crypt(bytes, result, result.length, j);
return fromUTF(result);
}
private static void crypt(byte[] bytes, byte[] result, int length, int j)
{
for (int i = 0; i < length; i++)
{
result[i] = (byte)(bytes[i] ^ KEY[j++ % KEY.length]);
}
}
public static String join(String joiner, String... values)
{
if (values.length < 0)
{
return "";
}
else if (values.length == 1)
{
return values[0];
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < values.length; i++)
{
sb.append(values[i]);
if (i + 1 < values.length)
{
sb.append(joiner);
}
}
return sb.toString();
}
public static char[] decryptAsChars(byte[] bytes)
{
if (bytes == null)
{
return null;
}
if (bytes.length == 0)
{
return new char[0];
}
byte[] result = new byte[bytes.length - 1];
int j = bytes[result.length] - Byte.MIN_VALUE;
crypt(bytes, result, result.length, j);
return Charset.forName(UTF8).decode(ByteBuffer.wrap(result)).array();
}
}