PageRenderTime 41ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/LockCrypt.Java/src/com/lime49/lockcrypt/Utils.java

#
Java | 479 lines | 368 code | 21 blank | 90 comment | 132 complexity | 9b4f7abb3dd306b17d5f1098b51065a6 MD5 | raw file
  1. package com.lime49.lockcrypt;
  2. import java.util.*;
  3. import java.security.MessageDigest;
  4. import javax.crypto.spec.SecretKeySpec;
  5. import java.awt.*;
  6. import javax.swing.*;
  7. import javax.swing.table.*;
  8. import javax.swing.plaf.FontUIResource;
  9. import java.awt.GridBagConstraints;
  10. import java.lang.reflect.Method;
  11. import java.net.URL;
  12. public class Utils {
  13. /**
  14. * Converts an array to a String, seperated by separators
  15. * @param ary The array to implode
  16. * @param delim The separator to use
  17. * @return The array as a string
  18. */
  19. public static String implode(String[] ary, String delim) {
  20. StringBuilder out = new StringBuilder();
  21. for(int i=0; i<ary.length; i++) {
  22. if(i!=0) { out.append(delim); }
  23. out.append(ary[i]);
  24. }
  25. return out.toString();
  26. }
  27. /**
  28. * Converts an array to a String, seperated by separators
  29. * @param ary The LinkedHashMap to implode
  30. * @param fields The fields to use to order the string
  31. * @param delim The separator to use
  32. * @return The LinkedHashMap as a string
  33. */
  34. public static String implode(LinkedHashMap ary, String[] fields, String delim) {
  35. StringBuilder out = new StringBuilder();
  36. int i = 0;
  37. for(int j=0;j<fields.length;j++) {
  38. for(Object key : ary.keySet()) {
  39. if(fields[j].equals(key)) {
  40. if(i!=0) {
  41. out.append(delim);
  42. } else {
  43. i++;
  44. }
  45. out.append(ary.get(key));
  46. }
  47. }
  48. }
  49. return out.toString();
  50. }
  51. /**
  52. * Searches haystack for needle, returning true if found, otherwise false
  53. * @param haystack The array to search
  54. * @param needle The string to find
  55. * @return
  56. */
  57. public static boolean in_array(String[] haystack, String needle) {
  58. for(int i=0;i<haystack.length;i++) {
  59. if(haystack[i].equals(needle)) {
  60. return true;
  61. }
  62. }
  63. return false;
  64. }
  65. /**
  66. * Generates an AES SecretKeySpec for use with encryption by first creating an MD5 hash of the key
  67. * @param keystring The string to use
  68. * @return The generated AES SecretKeySpec
  69. * @throws java.lang.Exception
  70. */
  71. public static SecretKeySpec getKeySpec(String keystring) throws Exception {
  72. byte[] key = new byte[16];
  73. MessageDigest digest = MessageDigest.getInstance("MD5");
  74. digest.update(keystring.getBytes("UTF-8"));
  75. byte[] hash = digest.digest();
  76. int len = hash.length;
  77. System.arraycopy(hash, 0, key, 0, len);
  78. return new SecretKeySpec(hash, "AES");
  79. }
  80. public static ResourceBundle getLanguage(String langCode) {
  81. ResourceBundle lang = null;
  82. if(langCode.contains("_")) {
  83. String country = langCode.substring(0,2);
  84. if(country.equals("zh")) {
  85. if(langCode.endsWith("t")) { // chinese tradtional
  86. lang = ResourceBundle.getBundle("com.lime49.lockcrypt.lang.lang", new Locale(country, "TW"));
  87. } else if(langCode.endsWith("s")) { // chinese simplified
  88. lang = ResourceBundle.getBundle("com.lime49.lockcrypt.lang.lang", new Locale(country, "CN"));
  89. } else {
  90. lang = ResourceBundle.getBundle("com.lime49.lockcrypt.lang.lang", new Locale(country, langCode.substring(3)));
  91. }
  92. } else if(country.equals("he")) {
  93. lang = ResourceBundle.getBundle("com.lime49.lockcrypt.lang.lang", new Locale("iw", langCode.substring(3))); // bug as of Java v1.6.7
  94. } else {
  95. lang = ResourceBundle.getBundle("com.lime49.lockcrypt.lang.lang", new Locale(country, langCode.substring(3)));
  96. }
  97. } else if(langCode.equals("ka")) { //georgian
  98. lang = ResourceBundle.getBundle("com.lime49.lockcrypt.lang.lang", new Locale(langCode));
  99. Utils.getSafeFont(langCode, true);
  100. } else {
  101. lang = ResourceBundle.getBundle("com.lime49.lockcrypt.lang.lang", new Locale(langCode));
  102. }
  103. return lang;
  104. }
  105. /**
  106. * Returns a font suitable for rendering the UI language. If the current font is capable, uses that, otherwise tries Arial Unicode MS.
  107. * Also sets the UI default to the safe font found.
  108. * @param lang The launguage code of the language needed
  109. * @param updateUI If true, will also update the UI default to a suitable font
  110. * @return A font capable of displaying the language.
  111. */
  112. public static Font getSafeFont(String lang, boolean updateUI) {
  113. Font font = null;
  114. boolean useDefaultFont = false;
  115. if(lang.startsWith("zh") || lang.startsWith("iw")) { // chinese, hebrew
  116. font = new FontUIResource("Arial Unicode MS", Font.PLAIN, 12);
  117. if(font == null) { // mac OS
  118. font = new FontUIResource("Lucida Unicode", Font.PLAIN, 12);
  119. }
  120. } else if(lang.startsWith("ka")) { // georgian
  121. font = new FontUIResource("Sylfaen", Font.PLAIN, 12);
  122. if(font == null) {
  123. font = new FontUIResource("Arial Unicode MS", Font.PLAIN, 12);
  124. if(font == null) {
  125. font = new FontUIResource("Lucida Unicode", Font.PLAIN, 12);
  126. }
  127. }
  128. } else {
  129. useDefaultFont = true;
  130. }
  131. if(font == null) { // last resort, try arial
  132. font = new FontUIResource("Arial", Font.PLAIN, 12);
  133. }
  134. if(updateUI) {
  135. Enumeration keys = UIManager.getDefaults().keys();
  136. if(useDefaultFont) {
  137. while(keys.hasMoreElements()) {
  138. Object key = keys.nextElement();
  139. Object value = UIManager.get(key);
  140. if(value instanceof FontUIResource) {
  141. UIManager.put (key, value);
  142. }
  143. }
  144. } else {
  145. while(keys.hasMoreElements()) {
  146. Object key = keys.nextElement();
  147. Object value = UIManager.get(key);
  148. if(value instanceof FontUIResource) {
  149. UIManager.put (key, font);
  150. }
  151. }
  152. }
  153. }
  154. return font;
  155. }
  156. /**
  157. * Opens the default browser to the specified URL. Should work on Windows, Linux, Unix and MacOS
  158. * @param url The URL to open
  159. */
  160. public static void openURL(String url) {
  161. // MultiOS browser launch, modified from http://centerkey.com/java/browser/ . Originally by Dem Pilafian
  162. String osName = System.getProperty("os.name");
  163. try {
  164. if(osName.startsWith("Mac OS")) {
  165. //TODO: Fix MacOS support, generated warnings on compile
  166. Class<?> fileMgr = Class.forName("com.apple.eio.FileManager");
  167. Method openURL = fileMgr.getDeclaredMethod("openURL",new Class[] {String.class});
  168. openURL.invoke(null, new Object[] {url});
  169. } else if (osName.startsWith("Windows")) {
  170. Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
  171. } else { //assume Unix or Linux
  172. String[] browsers = { "firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" };
  173. String browser = null;
  174. for(int count = 0; count < browsers.length && browser == null; count++) {
  175. if(Runtime.getRuntime().exec(new String[] {"which", browsers[count]}).waitFor() == 0) {
  176. browser = browsers[count];
  177. }
  178. }
  179. if(browser == null) {
  180. throw new Exception("Could not find web browser");
  181. } else {
  182. Runtime.getRuntime().exec(new String[] {browser, url});
  183. }
  184. }
  185. } catch (Exception e) {
  186. JOptionPane.showMessageDialog(null, "There was a problem launching your browser:" + ":\n" + e.getLocalizedMessage(), "Error", JOptionPane.ERROR_MESSAGE);
  187. }
  188. }
  189. /**
  190. * Sets the parameters of the specified GridBagConstraints
  191. * @param c The constraints to set
  192. * @param row Row number
  193. * @param col Column number
  194. * @param width Grid width
  195. * @param height Grid height
  196. * @param fill NONE, HORIZONTAL, VERTICAL OR BOTH
  197. * @param anchor One of either FIRST_LINE_START, PAGE_START, FIRST_LINE_END, LINE_START, CENTER, LINE_END, LAST_LINE_START, PAGE_END,LAST_LINE_END
  198. * @param weightx
  199. */
  200. public static void setgrid(GridBagConstraints c, int row, int col, int width, int height, int fill, int anchor, double weightx) {
  201. c.gridx = col;
  202. c.gridy = row;
  203. c.gridwidth = width;
  204. c.gridheight = height;
  205. c.fill = fill;
  206. c.anchor = anchor;
  207. c.weightx = weightx;
  208. }
  209. /**
  210. * Convert all applicable characters to HTML entities
  211. * @param text The input text
  212. * @param useUnderscores If true, replaces spaces with underscores
  213. * @return The encoded string
  214. */
  215. public static String HTMLEntities(String text, boolean useUnderscores) {
  216. StringBuffer buf = new StringBuffer();
  217. int len = (text == null ? -1 : text.length());
  218. for(int i = 0;i < len;i++) {
  219. char c = text.charAt(i);
  220. if((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9')) {
  221. buf.append(c);
  222. } else if(c == ' ') {
  223. if(useUnderscores) {
  224. buf.append('_');
  225. } else {
  226. buf.append(' ');
  227. }
  228. } else {
  229. buf.append("&#"+(int)c+";");
  230. }
  231. }
  232. return buf.toString();
  233. }
  234. /**
  235. * Removes all spaces and non alpha-numeric characters and replaces them with underscores
  236. * @param text The input text
  237. * @return The converted string
  238. */
  239. public static String toUnderscores(String text) {
  240. StringBuffer buf = new StringBuffer();
  241. int len = (text == null ? -1 : text.length());
  242. for(int i = 0;i < len;i++) {
  243. char c = text.charAt(i);
  244. if((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9')) {
  245. buf.append(c);
  246. } else {
  247. buf.append('_');
  248. }
  249. }
  250. return buf.toString();
  251. }
  252. /**
  253. * Finds the index in the specified ArrayList where the specified name exists
  254. */
  255. public static int getArrayListIndex(String name, ArrayList<? extends AccountTreeNode> arrayList) {
  256. int numaccounts = arrayList.size();
  257. for(int i=0;i<numaccounts;i++) {
  258. if(arrayList.get(i).getName().equals(name)) {
  259. return i;
  260. }
  261. }
  262. return -1;
  263. }
  264. /**
  265. * Finds the index in the specified tree where the specified name exists
  266. */
  267. public static int getTreeIndex(String name, AccountTree tree) {
  268. for(int i=0;i<tree.getRowCount();i++) {
  269. if(tree.getPathForRow(i).getLastPathComponent().toString().equals(name)) {
  270. return i;
  271. }
  272. }
  273. return -1;
  274. }
  275. /**
  276. * Finds the index in the account ArrayList where the specified account exists
  277. * @param typename The type to search for
  278. * @param location "Tree" or "visible" to search only the type list in the options window, anything else to search the whole list of types (including deleted ones)
  279. * @return
  280. */
  281. public static int getTypeIndex(String typename, ArrayList<AccType> types, String location) {
  282. // returns the index in 'types'/'typeListModel' where 'typename' is stored
  283. if(location.equals("list")) {
  284. int numtypes = types.size();
  285. for(int i=0;i<numtypes;i++) {
  286. if(types.get(i).getName().equals(typename) && !types.get(i).isDeleted) {
  287. return i;
  288. }
  289. }
  290. } else {
  291. int numtypes = types.size();
  292. for(int i=0;i<numtypes;i++) {
  293. if(types.get(i).getName().equals(typename)) {
  294. return i;
  295. }
  296. }
  297. }
  298. return -1;
  299. }
  300. public static class IconRenderer extends DefaultTableCellRenderer implements TableCellRenderer {
  301. @Override
  302. public Component getTableCellRendererComponent(
  303. JTable table, Object img,
  304. boolean isSelected, boolean hasFocus,
  305. int row, int column) {
  306. if(img == null || img.equals("")) {
  307. return null;
  308. } else {
  309. try {
  310. this.setHorizontalAlignment(SwingConstants.CENTER);
  311. this.setVerticalAlignment(SwingConstants.CENTER);
  312. URL iconURL = this.getClass().getResource("images/types/"+img+"_32.png");
  313. ImageIcon imgIcon = new ImageIcon(Toolkit.getDefaultToolkit().getImage(iconURL));
  314. this.setIcon(imgIcon);
  315. this.setText("");
  316. if(isSelected) {
  317. this.setBackground(Color.getHSBColor(0.58f, 0.2f, 1f));
  318. } else {
  319. this.setBackground(Color.WHITE);
  320. }
  321. } catch(Exception ignore) {}
  322. }
  323. return this;
  324. }
  325. }
  326. /**
  327. * Finds the next available name by appending numbers, discounting items which already exist
  328. * @param prefix The prefix to use
  329. * @param location The location to search for items
  330. * @return The next available item name
  331. */
  332. public static String getNextAvailableAccountName(String prefix, ArrayList<? extends AccountTreeNode> location) {
  333. if(Utils.getArrayListIndex(prefix, location) < 0) {
  334. return prefix;
  335. } else {
  336. boolean gotName = false;
  337. int k = 1;
  338. String name = prefix;
  339. while(!gotName) {
  340. if(Utils.getArrayListIndex(prefix+" "+k, location) >= 0) {
  341. k++;
  342. } else {
  343. name = prefix +" "+ k;
  344. gotName = true;
  345. }
  346. }
  347. return name;
  348. }
  349. }
  350. /**
  351. * Generates a (hopefully) unique ID using a combination of 53 (non-HTML safe) or 39 (HTML safe) characters.
  352. * There are 1.74e17 combinations if the ID does not need to be HTML safe, otherwise there are just over 3500 million
  353. * @param HTMLSafe true if the generated ID must be valid in HTML without encoding.</param
  354. */
  355. public static String GenID(boolean HTMLSafe) {
  356. StringBuffer bld = new StringBuffer();
  357. Random seed = new Random();
  358. int len = 6;
  359. if(HTMLSafe) {
  360. String possible = "ABCEDFGHIJKLMNOPQRSTUVWXYZ0123456789~_-",
  361. firstPossible = "ABCEDFGHIJKLMNOPQRSTUVWXYZ"; // make sure the first character isn't a number, which invalidates xhtml
  362. bld.append(possible.charAt(seed.nextInt(firstPossible.length() - 1)));
  363. for(int i = 1; i < len; i++) {
  364. bld.append(possible.charAt(seed.nextInt(possible.length() - 1)));
  365. }
  366. } else {
  367. String possible = "ABCEDFGHIJKLMNOPQRSTUVWXYZ0123456789%ÂŁ$!*/#~][{}|=_-^";
  368. for(int i = 0; i < len; i++) {
  369. bld.append(possible.charAt(seed.nextInt(possible.length() - 1)));
  370. }
  371. }
  372. return bld.toString();
  373. }
  374. /**
  375. * Formats a URL to remove unneeded query strings/protocol information
  376. * @param fullURL The URL to strip
  377. * @param makePretty If true, remove the path and protocol, leaving the domain
  378. * @return The formatted URL
  379. */
  380. public static String stripURL(String fullURL, boolean makePretty) {
  381. StringBuffer ret = new StringBuffer();
  382. try {
  383. URL url = new URL(fullURL);
  384. String protocol = url.getProtocol().toLowerCase();
  385. String host = url.getHost();
  386. if(makePretty) {
  387. if(protocol.equals("file")) {
  388. String fileName = url.getFile();
  389. int questionMark = fileName.indexOf("?");
  390. if(questionMark >= 0) { // query string exists
  391. if(questionMark < fileName.length()-1) { // if there are chars after the ?
  392. fileName = fileName.substring(0,questionMark);
  393. }
  394. }
  395. int lastSlash = fileName.lastIndexOf("/")+1;
  396. if(lastSlash == fileName.length()) {
  397. ret.append(fileName);
  398. } else {
  399. ret.append(fileName.substring(lastSlash));
  400. }
  401. } else {
  402. if(host.startsWith("www.")) {
  403. ret.append(host.substring(4,5).toUpperCase())
  404. .append(host.substring(5));
  405. } else {
  406. ret.append(host.substring(0,1).toUpperCase())
  407. .append(host.substring(1));
  408. }
  409. }
  410. } else {
  411. ret.append(protocol).append("://");
  412. if(protocol.equals("file")) {
  413. ret.append(url.getPath());
  414. } else {
  415. ret.append(url.getHost());
  416. }
  417. }
  418. } catch(Exception ex) { ret.append(fullURL); }
  419. return ret.toString();
  420. }
  421. public static String getJARPath() {
  422. String install_path = LockCrypt.class.getProtectionDomain().getCodeSource().getLocation().toString();
  423. install_path = install_path.replace("\\file:\\", "").
  424. replace("file://", "").
  425. replace("file:/", "");
  426. if(install_path.indexOf("LockCrypt.jar") >= 0)
  427. install_path = install_path.substring(0, install_path.lastIndexOf("LockCrypt.jar"));
  428. return install_path;
  429. }
  430. public static boolean urlMatches(URL url, URL urlToMatch) {
  431. boolean match = false;
  432. if(url.getProtocol().equals("*")) {
  433. String accountHost = url.getHost();
  434. if(accountHost.length() > 0) {
  435. if(accountHost.charAt(0) == '*') {
  436. if(accountHost.charAt(accountHost.length()) == '*') { // *host*
  437. if(accountHost.length() > 2 && urlToMatch.getHost().contains(accountHost.substring(1, accountHost.length()-3).toLowerCase())) {
  438. match = true;
  439. }
  440. } else { // *host
  441. if(accountHost.length() > 1 && urlToMatch.getHost().endsWith(accountHost.substring(1).toLowerCase())) {
  442. match = true;
  443. }
  444. }
  445. } else if(accountHost.charAt(accountHost.length()) == '*') { // host*
  446. if(urlToMatch.getHost().startsWith(accountHost.substring(0, accountHost.length()-2).toLowerCase())) {
  447. match = true;
  448. }
  449. } else if(accountHost.equalsIgnoreCase(urlToMatch.getHost())) { // host
  450. match = true;
  451. }
  452. }
  453. } else if(url.getProtocol().equalsIgnoreCase(urlToMatch.getProtocol())) {
  454. match = true;
  455. }
  456. return match;
  457. }
  458. }