bio.gcat.Utilities.java Source code

Java tutorial

Introduction

Here is the source code for bio.gcat.Utilities.java

Source

/*
 * Copyright [2016] [Mannheim University of Applied Sciences]
 * 
 * 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 bio.gcat;

import static java.lang.Math.PI;

import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Array;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.Position;

import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
import com.google.common.base.CaseFormat;
import com.google.common.util.concurrent.ListenableFuture;

public final class Utilities {
    public static final String EMPTY = "", SPACE = " ", TAB = "\t", NEW_LINE = "\n", WHITESPACE = " \t\n\r\f",
            TRUE = "true", FALSE = "false", CHARSET = "UTF-8";
    public static final double TWO_PI = PI * 2, HALF_PI = PI / 2, QUARTER_PI = PI / 4, EIGHTH_PI = PI / 8,
            SIXTEENTH_PI = PI / 16;

    private static final int BUFFER_SIZE = 8192;
    private static final int TEMP_DIRECTORY_ATTEMPTS = 10000;

    private static final String CONFIGURATION_NAME = "gcat.properties";

    private static Properties configuration;
    private static ClassLoader localClassLoader;
    static {
        localClassLoader = Utilities.class.getClassLoader();
    }

    private static String tempDirectory() {
        return AccessController.doPrivileged(new PrivilegedAction<String>() {
            @Override
            public String run() {
                return System.getProperty("java.io.tmpdir");
            }
        });
    }

    public static URL getResource(String name) {
        if (!name.startsWith("bio/gcat/"))
            name = "bio/gcat" + (name.startsWith("/") ? EMPTY : "/") + name;
        return localClassLoader.getResource(name);
    }

    public static InputStream getResourceAsStream(String name) {
        if (!name.startsWith("bio/gcat/"))
            name = "bio/gcat" + (name.startsWith("/") ? EMPTY : "/") + name;
        return localClassLoader.getResourceAsStream(name);
    }

    private static File configurationFile() {
        return new File(tempDirectory(), CONFIGURATION_NAME);
    }

    private static boolean loadConfiguration() {
        if (configuration != null)
            return true;
        try {
            (configuration = new Properties())
                    .load(new InputStreamReader(new FileInputStream(configurationFile()), CHARSET));
            return true;
        } catch (FileNotFoundException e) {
            configuration = new Properties();
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    private static boolean writeConfiguration() {
        if (configuration == null)
            return true;
        try {
            configuration.store(new OutputStreamWriter(new FileOutputStream(configurationFile()), CHARSET), EMPTY);
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    public static boolean hasConfiguration(String key) {
        return (loadConfiguration() && configuration.containsKey(key));
    }

    public static String getConfiguration(String key) {
        return getConfiguration(key, null);
    }

    public static String getConfiguration(String key, String dfault) {
        if (!loadConfiguration() || !configuration.containsKey(key))
            return dfault;
        return configuration.getProperty(key);
    }

    public static boolean setConfiguration(String key, String value) {
        configuration.setProperty(key, value);
        return writeConfiguration();
    }

    public static URL getLocalPath() {
        URL path = Utilities.class.getProtectionDomain().getCodeSource().getLocation();
        try {
            return new URL(URLDecoder.decode(path.toString(), "UTF-8"));
        } catch (Exception e) {
            return path;
        }
    }

    public static File getFile(URL ressource) {
        StringBuilder file = new StringBuilder();
        String host = ressource.getHost(), path = ressource.getPath();
        if (host != null && !host.isEmpty())
            file.append(File.separatorChar).append(File.separatorChar).append(host);
        return new File(file.append(path.split("!", 2)[0]).toString());
    }

    public static String ellipsisText(String text, int maxLength) {
        return text.length() <= maxLength ? text : text.substring(0, maxLength - 3) + "...";
    }

    public static boolean safeSetSystemProperty(String key, String value) {
        try {
            if (!value.equals(System.getProperty(key)))
                System.setProperty(key, value);
            return true;
        } catch (SecurityException e) {
            return false;
        }
    }

    public static int indexOf(Object[] array, Object object) {
        for (int index = 0; index < array.length; index++)
            if (array[index] == object)
                return index;
        return -1;
    }

    public static <T> T[] add(T[] originalArray, T element) {
        T[] array = Arrays.copyOf(originalArray, originalArray.length + 1);
        array[array.length - 1] = element;
        return array;
    }

    public static <T> T[] reverse(T[] originalArray) {
        T[] array = Arrays.copyOf(originalArray, originalArray.length);
        int indexA = 0, indexB = array.length - 1;
        T temp;
        while (indexB > indexA) {
            temp = array[indexB];
            array[indexB] = array[indexA];
            array[indexA] = temp;
            indexA++;
            indexB--;
        }
        return array;
    }

    public static <T> T[] substitute(T[] originalArray, Map<T, T> substitution) {
        @SuppressWarnings("unchecked")
        T[] array = (T[]) Array.newInstance(originalArray.getClass().getComponentType(), originalArray.length);
        for (int element = 0; element < originalArray.length; element++)
            array[element] = substitution.getOrDefault(originalArray[element], originalArray[element]);
        return array;
    }

    public static <T> boolean contains(T[] array, T search) {
        for (T element : array)
            if (element == search || search != null && search.equals(element))
                return true;
        return false;
    }

    public static <T> boolean contains(Iterable<T> iterable, T search) {
        for (T element : iterable)
            if (element == search || search != null && search.equals(element))
                return true;
        return false;
    }

    public static <T> boolean containsOnly(T[] array, T search) {
        for (T element : array)
            if (element != search && (search == null || !search.equals(element)))
                return false;
        return true;
    }

    public static <T> boolean containsOnly(Iterable<T> iterable, T search) {
        for (T element : iterable)
            if (element != search && (search == null || !search.equals(element)))
                return false;
        return true;
    }

    public static String cropString(String text, int length) {
        if (text.length() <= length)
            return text;
        return text.substring(0, length) + "...";
    }

    public static class RememberFileChooser extends JFileChooser {
        private static final long serialVersionUID = 1l;

        public RememberFileChooser() {
            super(getLastDirectory());
        }

        private static File getLastDirectory() {
            String directory = getConfiguration("directory");
            if (directory != null) {
                File file = new File(directory);
                if (file.exists() && file.isDirectory())
                    return file;
                else
                    return null;
            } else
                return null;
        }

        @Override
        public void approveSelection() {
            File selected = getSelectedFile();
            if (!selected.isDirectory())
                setConfiguration("directory", selected.getParentFile().toString());
            super.approveSelection();
        }
    }

    public static class FileNameExtensionFileChooser extends RememberFileChooser {
        private static final long serialVersionUID = 1l;

        private final FileFilter supportedFileFilter;

        public FileNameExtensionFileChooser(FileNameExtensionFilter... filters) {
            this(filters.length > 1, filters);
        }

        public FileNameExtensionFileChooser(boolean addSupportedFileFilter, FileNameExtensionFilter... filters) {
            supportedFileFilter = supportedFileFilter(filters);
            if (addSupportedFileFilter)
                addChoosableFileFilter(supportedFileFilter);
            for (FileNameExtensionFilter filter : filters)
                addChoosableFileFilter(filter);
            if (addSupportedFileFilter)
                setFileFilter(supportedFileFilter);
            else if (filters.length != 0)
                setFileFilter(filters[0]);
        }

        public FileFilter getSupportedFileFilter() {
            return supportedFileFilter;
        }

        private static FileFilter supportedFileFilter(FileNameExtensionFilter... filters) {
            StringBuilder description = new StringBuilder("All Supported Files (");
            List<String> extensions = new ArrayList<>();
            for (FileNameExtensionFilter filter : filters)
                for (String extension : filter.getExtensions()) {
                    description.append("*.").append(extension).append(';');
                    extensions.add(extension);
                }
            description.deleteCharAt(description.length() - 1);
            if (filters.length != 0)
                description.append(')');
            return new FileNameExtensionFilter(description.toString(), extensions.toArray(new String[0]));
        }

        public FileNameExtensionFilter getFileNameExtensionFilter() {
            FileFilter filter;
            return (filter = getFileFilter()) instanceof FileNameExtensionFilter ? (FileNameExtensionFilter) filter
                    : null;
        }

        @Override
        public void approveSelection() {
            File file = getSelectedFile();
            FileNameExtensionFilter filter = getFileNameExtensionFilter();
            if (filter != null && !supportedFileFilter.accept(file) && !file.exists())
                setSelectedFile(file = new File(file.getAbsolutePath() + '.' + filter.getExtensions()[0]));
            if (getDialogType() == SAVE_DIALOG && file != null && file.exists())
                if (JOptionPane.showOptionDialog(getParent(),
                        String.format("%s already exists.\nDo you want to replace it?", file.getName()),
                        "Confirm Overwrite", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, null,
                        null) != JOptionPane.YES_OPTION)
                    return;
            super.approveSelection();
        }
    }

    public static String[] getFilterExtensions(FileNameExtensionFilter... filters) {
        return filters != null ? Arrays.stream(filters).map(filter -> filter.getExtensions())
                .reduce((extensionsA, extensionsB) -> Stream
                        .concat(Arrays.stream(extensionsA), Arrays.stream(extensionsB)).toArray(String[]::new))
                .get() : null;
    }

    public static Object jsonValueAsObject(JsonValue value) {
        if (value.isBoolean())
            return value.asBoolean();
        else if (value.isNumber())
            return value.asInt();
        else if (value.isString())
            return value.asString();
        else if (value.isArray())
            return jsonArrayAsList(value.asArray());
        else if (value.isObject())
            return jsonObjectAsMap(value.asObject());
        else
            return null;
    }

    public static Set<Object> jsonArrayAsSet(JsonArray array) {
        Set<Object> set = new HashSet<>();
        for (JsonValue value : array)
            set.add(jsonValueAsObject(value));
        return set;
    }

    public static List<Object> jsonArrayAsList(JsonArray array) {
        List<Object> list = new ArrayList<>();
        for (JsonValue value : array)
            list.add(jsonValueAsObject(value));
        return list;
    }

    public static Map<String, Object> jsonObjectAsMap(JsonObject object) {
        Map<String, Object> map = new HashMap<>();
        for (JsonObject.Member member : object)
            map.put(member.getName(), jsonValueAsObject(member.getValue()));
        return map;
    }

    public static byte[] readFile(File file) throws IOException {
        return readStream(new FileInputStream(file));
    }

    public static byte[] readStream(InputStream input) throws IOException {
        return readStream(input, -1, true);
    }

    public static byte[] readStream(InputStream input, int length, boolean readAll) throws IOException {
        byte[] output = {};
        int position = 0;
        if (length == -1)
            length = Integer.MAX_VALUE;
        while (position < length) {
            int bytesToRead;
            if (position >= output.length) { // Only expand when there's no room
                bytesToRead = Math.min(length - position, output.length + 1024);
                if (output.length < position + bytesToRead)
                    output = Arrays.copyOf(output, position + bytesToRead);
            } else
                bytesToRead = output.length - position;
            int bytesRead = input.read(output, position, bytesToRead);
            if (bytesRead < 0) {
                if (!readAll || length == Integer.MAX_VALUE) {
                    if (output.length != position)
                        output = Arrays.copyOf(output, position);
                    break;
                } else
                    throw new EOFException("Detect premature EOF");
            }
            position += bytesRead;
        }
        return output;
    }

    public static URLConnection writeString(URLConnection connection, String string) throws IOException {
        writeString(connection.getOutputStream(), string);
        return connection;
    }

    public static void writeString(OutputStream output, String string) throws IOException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
        writer.write(string);
        writer.flush();
    }

    public static File createTempDirectory(String prefix) {
        String baseName = prefix + Long.toString(System.currentTimeMillis()) + "-";
        File directory = new File(tempDirectory()), tempDirectory;
        for (int counter = 0; counter < TEMP_DIRECTORY_ATTEMPTS; counter++)
            if ((tempDirectory = new File(directory, baseName + counter)).mkdir())
                return tempDirectory;
        throw new IllegalStateException("Failed to create directory within " + TEMP_DIRECTORY_ATTEMPTS
                + " attempts (tried " + baseName + "0 to " + baseName + (TEMP_DIRECTORY_ATTEMPTS - 1) + ')');
    }

    public static void writeFile(String text, File file) throws IOException {
        Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), CHARSET));
        try {
            writer.write(text);
        } finally {
            writer.close();
        }
    }

    public static void writeFile(InputStream input, File file) throws IOException {
        OutputStream output = null;
        try {
            output = new FileOutputStream(file);
            int read;
            byte[] buffer = new byte[BUFFER_SIZE];
            while ((read = input.read(buffer)) > 0)
                output.write(buffer, 0, read);
        } finally {
            if (output != null)
                output.close();
        }
    }

    public static boolean deleteDirectory(File directory) {
        return deleteDirectory(directory, false);
    }

    public static boolean deleteDirectory(File directory, boolean preserveGit) {
        if (directory.exists() && directory.isDirectory() && !(preserveGit && directory.getName().equals(".git"))) {
            boolean deleteDirectory = true;
            for (File file : directory.listFiles())
                if (file.isDirectory()) {
                    if (!deleteDirectory(file, preserveGit))
                        deleteDirectory = false;
                } else
                    file.delete();
            return deleteDirectory ? directory.delete() : false;
        } else
            return false;
    }

    public static boolean isEmpty(String text) {
        return text == null || text.isEmpty();
    }

    public static boolean isNumeric(String number) {
        try {
            Long.parseLong(number);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    public static boolean isDecimal(String number) {
        try {
            Double.parseDouble(number);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    public static int countOccurences(String text, char find) {
        if (isEmpty(text))
            return 0;
        int count = 0, offset = 0;
        while ((offset = text.indexOf(find, offset)) != -1) {
            count++;
            offset++;
        }
        return count;
    }

    public static int countOccurences(String text, String find) {
        if (isEmpty(text))
            return 0;
        int count = 0, offset = 0, length = find.length();
        while ((offset = text.indexOf(find, offset)) != -1) {
            count++;
            offset += length;
        }
        return count;
    }

    public static Position fixPosition(final int position) {
        return new Position() {
            @Override
            public int getOffset() {
                return position;
            }
        };
    }

    public static int pow(int base, int exponent) {
        int result = 1;
        while (exponent != 0) {
            if ((exponent & 1) != 0)
                result *= base;
            exponent >>= 1;
            base *= base;
        }
        return result;
    }

    public static String firstToUpper(String text) {
        if (text == null || text.isEmpty())
            return text;
        else if (text.length() == 1)
            return text.toUpperCase();
        else
            return Character.toUpperCase(text.charAt(0)) + camelCase(text.substring(1).toLowerCase());
    }

    public static String camelCase(String text) {
        return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, text);
    }

    public static class Range {
        public final Position start, end;

        public Range(Position start, Position end) {
            if (start.getOffset() <= end.getOffset()) {
                this.start = start;
                this.end = end;
            } else {
                this.start = end;
                this.end = start;
            }
        }
    }

    public static enum OperatingSystem {
        WINDOWS, MAC, UNIX, SOLARIS;
        private static final OperatingSystem OPERATING_SYSTEM;
        static {
            String name = System.getProperty("os.name").toLowerCase();
            if (name.contains("win"))
                OPERATING_SYSTEM = WINDOWS;
            else if (name.contains("mac"))
                OPERATING_SYSTEM = MAC;
            else if (name.contains("nix") || name.contains("nux") || name.contains("aix"))
                OPERATING_SYSTEM = UNIX;
            else if (name.contains("sunos"))
                OPERATING_SYSTEM = SOLARIS;
            else
                OPERATING_SYSTEM = null;
        }

        public static OperatingSystem currentOperatingSystem() {
            return OPERATING_SYSTEM;
        }
    }

    public static class DefiniteFuture<T> implements Future<T> {
        private T result;

        public DefiniteFuture() {
        }

        public DefiniteFuture(T result) {
            set(result);
        }

        @Override
        public boolean cancel(boolean mayInterruptIfRunning) {
            return true;
        }

        @Override
        public boolean isCancelled() {
            return true;
        }

        @Override
        public boolean isDone() {
            return true;
        }

        @Override
        public T get() {
            return result;
        }

        @Override
        public T get(long timeout, TimeUnit unit) {
            return get();
        }

        public void set(T result) {
            this.result = result;
        }
    }

    public static class DefiniteListenableFuture<T> extends DefiniteFuture<T> implements ListenableFuture<T> {
        public DefiniteListenableFuture(T result) {
            super(result);
        }

        @Override
        public void addListener(Runnable runnable, Executor executor) {
            runnable.run();
        }
    }

    public static class ArrayComparator<T extends Comparable<T>> implements Comparator<T[]> {
        @Override
        public int compare(T[] arrayA, T[] arrayB) {
            if (arrayA == arrayB)
                return 0;
            int compare;
            for (int index = 0; index < arrayA.length; index++)
                if (index < arrayB.length) {
                    if ((compare = arrayA[index].compareTo(arrayB[index])) != 0)
                        return compare;
                } else
                    return 1; //first array is longer
            if (arrayA.length == arrayB.length)
                return 0; //arrays are equal
            else
                return -1; //first array is shorter 
        }
    }
}