First commit
This commit is contained in:
parent
40bff34006
commit
57d60609e2
179 changed files with 59241 additions and 0 deletions
497
src/lib/Utilities.java
Normal file
497
src/lib/Utilities.java
Normal file
|
@ -0,0 +1,497 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2017 Alistair Neil <info@dazzleships.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package lib;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Formatter;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alistair Neil <info@dazzleships.net>
|
||||
*/
|
||||
public final class Utilities {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Utilities() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Covert list to csv
|
||||
*
|
||||
* @param al
|
||||
* @return String of comma separated values
|
||||
*/
|
||||
public static String getListAsCSV(ArrayList<String> al) {
|
||||
return al.toString().replace("[", "").replace("]", "").replace(" ", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Preloads filechooser in background so it will open instantly when
|
||||
* requested
|
||||
*/
|
||||
public static void preloadFileChooser() {
|
||||
Thread t = new Thread(new java.lang.Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens java file chooser dialog, convenience method. Returns filepath if
|
||||
* successful and null if not
|
||||
*
|
||||
* @param parent
|
||||
* @param folder
|
||||
* @param filter Extension filter
|
||||
* @param mode Fileselection mode
|
||||
* @return String Filepath
|
||||
*/
|
||||
public static String openFileChooser(Frame parent, String folder, FileFilter filter, int mode) {
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setFileSelectionMode(mode);
|
||||
fileChooser.setCurrentDirectory(new File(folder));
|
||||
if (filter != null) {
|
||||
fileChooser.addChoosableFileFilter(filter);
|
||||
}
|
||||
int intReturn = fileChooser.showOpenDialog(parent);
|
||||
if (intReturn == JFileChooser.APPROVE_OPTION) {
|
||||
return fileChooser.getSelectedFile().getAbsolutePath();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for newer appversion
|
||||
*
|
||||
* @param localversion
|
||||
* @param remoteversion
|
||||
* @return True if newer
|
||||
*/
|
||||
public static boolean isNewerVersion(String localversion, String remoteversion) {
|
||||
return convertBuildnumToFloat(remoteversion) > convertBuildnumToFloat(localversion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an debian build number into a floating point number
|
||||
*
|
||||
* @param version
|
||||
* @return Float version
|
||||
*/
|
||||
private static float convertBuildnumToFloat(String version) {
|
||||
|
||||
float result;
|
||||
Pattern p;
|
||||
String[] parts;
|
||||
try {
|
||||
if (version.contains("-")) {
|
||||
// Handling for old non-debian compatible version
|
||||
p = Pattern.compile("-");
|
||||
parts = p.split(version);
|
||||
} else {
|
||||
// Handling for new debian compatible version
|
||||
p = Pattern.compile("\\.");
|
||||
parts = p.split(version);
|
||||
parts[0] = parts[0] + "." + parts[1];
|
||||
parts[1] = parts[2];
|
||||
parts[2] = "";
|
||||
}
|
||||
result = Float.parseFloat(parts[0]);
|
||||
result += (Float.parseFloat(parts[1]) / 100000);
|
||||
} catch (Exception ex) {
|
||||
version = version.replaceAll("[^0-9.]", "");
|
||||
result = convertVersionToFloat(version);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a windows version number into a floating point number
|
||||
*
|
||||
* @param version
|
||||
* @return Float version
|
||||
*/
|
||||
private static float convertVersionToFloat(String version) {
|
||||
|
||||
int c;
|
||||
float f;
|
||||
version = version.toLowerCase();
|
||||
if (version.startsWith("v")) {
|
||||
version = version.substring(1);
|
||||
}
|
||||
try {
|
||||
c = version.charAt(version.length() - 1);
|
||||
if (c > 96) {
|
||||
version = version.substring(0, version.length() - 1);
|
||||
Float fraction = (float) (c - 96) / 10000;
|
||||
f = Float.parseFloat(version) + fraction;
|
||||
} else {
|
||||
f = Float.parseFloat(version);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
f = 0;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the desktop default file editor
|
||||
*
|
||||
* @param path Path to file
|
||||
*/
|
||||
public static void editFile(String path) {
|
||||
if (OSFunction.isLinux()) {
|
||||
OSFunction.launchProcess("xdg-open", path);
|
||||
return;
|
||||
}
|
||||
if (OSFunction.isWindows()) {
|
||||
OSFunction.launchProcess("notepad", path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the desktops default file handling program
|
||||
*
|
||||
* @param strUrl
|
||||
* @return Returns true if successful
|
||||
*/
|
||||
public static boolean openFileExternally(final String strUrl) {
|
||||
String url = strUrl.replace("\\", "/");
|
||||
try {
|
||||
if (OSFunction.isLinux()) {
|
||||
OSFunction.launchProcess("xdg-open", url);
|
||||
} else {
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
Desktop deskSupport = Desktop.getDesktop();
|
||||
if (url.startsWith("http") || url.startsWith("ftp")) {
|
||||
deskSupport.browse(new URI(url));
|
||||
} else {
|
||||
deskSupport.open(new File(url));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (URISyntaxException | IOException ex) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the UI Look and Feel
|
||||
*
|
||||
* @param theme
|
||||
*/
|
||||
public static void loadUIStyle(String theme) {
|
||||
|
||||
try {
|
||||
if (theme == null) {
|
||||
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (theme.contentEquals("Metal")) {
|
||||
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (theme.contentEquals("Nimbus")) {
|
||||
// Switch to Nimbus theme
|
||||
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
|
||||
return;
|
||||
}
|
||||
|
||||
if (theme.contentEquals("System")) {
|
||||
try {
|
||||
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
|
||||
return;
|
||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||
}
|
||||
try {
|
||||
UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
|
||||
return;
|
||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||
}
|
||||
|
||||
// If everything else fails use default cross platform metal
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust specified column width based on the width of a test string
|
||||
*
|
||||
* @param table
|
||||
* @param test
|
||||
*/
|
||||
public static void adjustTableColumnWidth(JTable table, String... test) {
|
||||
FontMetrics ourFontMetrics = table.getFontMetrics(table.getFont());
|
||||
int col = 0;
|
||||
for (String s : test) {
|
||||
table.getColumn(table.getColumnName(col++)).setPreferredWidth(ourFontMetrics.stringWidth(s));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate secret key.
|
||||
*
|
||||
* @param length
|
||||
* @return String key
|
||||
*/
|
||||
public static String generateSecretKey(int length) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
Random random = new Random();
|
||||
String chars = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
int x;
|
||||
try {
|
||||
for (int i = 0; i < length; i++) {
|
||||
x = random.nextInt(chars.length() - 1);
|
||||
buffer.append(chars.substring(x, x + 1));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static String getTorHashPassword(String secret) {
|
||||
byte[] key = S2KRFC2440(secret);
|
||||
return "16:" + byteToHex(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Secret to key, Algorithm info taken from
|
||||
* http://sunsite.icm.edu.pl/gnupg/rfc2440-3.html
|
||||
*
|
||||
* @param secret
|
||||
* @return hashed key for the given secret
|
||||
*/
|
||||
public static byte[] S2KRFC2440(String secret) {
|
||||
|
||||
// Create our message digest for SHA-1
|
||||
MessageDigest md;
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA-1");
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create our random S2K salt, the 9th byte is loaded with the code count which
|
||||
// determines the amount of octet hashing used.
|
||||
// This salt is eventually combined with the secret to prevent dictionary attacks
|
||||
int codecount = 32;
|
||||
byte[] s2ksalt = new byte[9];
|
||||
SecureRandom sr = new SecureRandom();
|
||||
sr.nextBytes(s2ksalt);
|
||||
s2ksalt[8] = (byte) codecount;
|
||||
// The octet hashing count is defined by the following formula where EXPBIAS is 6
|
||||
int octethashcount = (16 + (codecount & 15)) << ((codecount >> 4) + 6);
|
||||
|
||||
// Merge our S2K salt and partialsecret arrays together into one array to
|
||||
// create the full secret key.
|
||||
byte[] partialsecret;
|
||||
try {
|
||||
partialsecret = secret.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
return null;
|
||||
}
|
||||
byte[] fullsecret = new byte[8 + partialsecret.length];
|
||||
System.arraycopy(s2ksalt, 0, fullsecret, 0, 8);
|
||||
System.arraycopy(partialsecret, 0, fullsecret, 8, partialsecret.length);
|
||||
// Do the hashing based on the hashcount
|
||||
while (true) {
|
||||
if (octethashcount < fullsecret.length) {
|
||||
md.update(fullsecret, 0, octethashcount);
|
||||
break;
|
||||
} else {
|
||||
md.update(fullsecret);
|
||||
}
|
||||
octethashcount -= fullsecret.length;
|
||||
}
|
||||
// Create our final key by merging s2kspecifier and digest result
|
||||
byte[] ourkey = new byte[20 + 9];
|
||||
System.arraycopy(md.digest(), 0, ourkey, 9, 20);
|
||||
System.arraycopy(s2ksalt, 0, ourkey, 0, 9);
|
||||
return ourkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SHAHash using given password string
|
||||
*
|
||||
* @param password
|
||||
* @return SHAhash string
|
||||
*/
|
||||
public static String getSHAHash(String password) {
|
||||
String sha1 = "";
|
||||
try {
|
||||
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
|
||||
crypt.reset();
|
||||
crypt.update(password.getBytes("UTF-8"));
|
||||
sha1 = byteToHex(crypt.digest());
|
||||
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
|
||||
}
|
||||
return sha1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert byte to a hex string
|
||||
*
|
||||
* @param hash
|
||||
* @return byte as a hex string
|
||||
*/
|
||||
private static String byteToHex(final byte[] hash) {
|
||||
String result;
|
||||
try (Formatter formatter = new Formatter()) {
|
||||
for (byte b : hash) {
|
||||
formatter.format("%02x", b);
|
||||
}
|
||||
result = formatter.toString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve text from a resource text file
|
||||
*
|
||||
* @param resourcepath
|
||||
* @return String text
|
||||
*/
|
||||
public static String getTextFromResource(String resourcepath) {
|
||||
SimpleFile sf = new SimpleFile(resourcepath);
|
||||
sf.openBufferedResource();
|
||||
String text = sf.readEntireFile();
|
||||
sf.closeFile();
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve text from a text file
|
||||
*
|
||||
* @param filepath
|
||||
* @return String text
|
||||
*/
|
||||
public static String getTextFromFile(String filepath) {
|
||||
SimpleFile sf = new SimpleFile(filepath);
|
||||
String text = "";
|
||||
if (sf.exists()) {
|
||||
sf.openBufferedRead();
|
||||
text = sf.readEntireFile();
|
||||
sf.closeFile();
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the sha1 checksum of a given file
|
||||
*
|
||||
* @param filepath
|
||||
* @return Checksum as a hex string
|
||||
*/
|
||||
public static String getSha1Sum(String filepath) {
|
||||
StringBuilder sb = new StringBuilder("");
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA1");
|
||||
FileInputStream fis = new FileInputStream(filepath);
|
||||
byte[] dataBytes = new byte[1024];
|
||||
int nread;
|
||||
while ((nread = fis.read(dataBytes)) != -1) {
|
||||
md.update(dataBytes, 0, nread);
|
||||
}
|
||||
byte[] mdbytes = md.digest();
|
||||
//convert the byte to hex format
|
||||
for (int i = 0; i < mdbytes.length; i++) {
|
||||
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
|
||||
}
|
||||
} catch (NoSuchAlgorithmException | IOException ex) {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a hidden dummy window for registration to various docks/launchers
|
||||
* Fixes the neverending launching indicator
|
||||
*/
|
||||
public static void registerWindow() {
|
||||
final JFrame jf = new JFrame();
|
||||
|
||||
jf.addWindowListener(new java.awt.event.WindowListener() {
|
||||
@Override
|
||||
public void windowOpened(WindowEvent e) {
|
||||
jf.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowIconified(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeiconified(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowActivated(WindowEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeactivated(WindowEvent e) {
|
||||
}
|
||||
});
|
||||
jf.setUndecorated(true);
|
||||
jf.setBounds(0, 0, 0, 0);
|
||||
jf.setVisible(true);
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue