/* * This file is part of DRBD Management Console by LINBIT HA-Solutions GmbH * written by Rasto Levrinc. * * Copyright (C) 2009, LINBIT HA-Solutions GmbH. * Copyright (C) 2011-2012, Rastislav Levrinc. * * DRBD Management Console 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, or (at your option) * any later version. * * DRBD Management Console 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 drbd; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ package lcmc.common.domain.util; import java.awt.Color; import java.awt.Component; import java.awt.Desktop; import java.awt.Dimension; import java.awt.Font; import java.awt.GraphicsConfiguration; import java.awt.Insets; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StringWriter; import java.net.InetAddress; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Random; import java.util.ResourceBundle; import java.util.Set; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.imageio.ImageIO; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPopupMenu; import javax.swing.JTable; import javax.swing.JViewport; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.TitledBorder; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import javax.swing.text.html.HTMLDocument; import com.google.common.base.Optional; import lcmc.Exceptions; import lcmc.cluster.domain.Cluster; import lcmc.common.domain.StringValue; import lcmc.common.domain.Value; import lcmc.common.ui.main.MainPresenter; import lcmc.crm.ui.resource.ServiceInfo; import lcmc.host.domain.Host; import lcmc.logger.Logger; import lcmc.logger.LoggerFactory; /** * This class provides tools, that are not classified. */ public final class Tools { private static final Logger LOG = LoggerFactory.getLogger(Tools.class); private static String release = null; private static final Map<String, ImageIcon> imageIcons = new HashMap<String, ImageIcon>(); /** Resource bundle. */ private static ResourceBundle resource = null; private static ResourceBundle resourceAppDefaults = null; /** Config data object. */ private static final Pattern UNIT_PATTERN = Pattern.compile("(\\d*)(\\D*)"); public static void init() { setDefaults(); } /** * Returns an ImageIcon, or null if the path was invalid. */ public static ImageIcon createImageIcon(final String imageFilename) { final ImageIcon imageIcon = imageIcons.get(imageFilename); if (imageIcon != null) { return imageIcon; } final java.net.URL imgURL = Tools.class.getResource("/images/" + imageFilename); if (imgURL == null) { LOG.appWarning("createImageIcon: couldn't find image: " + imageFilename); return null; } else { final ImageIcon newIcon = new ImageIcon(imgURL); imageIcons.put(imageFilename, newIcon); return newIcon; } } /** Returns the drbd gui release version. */ public static String getRelease() { if (release != null) { return release; } final Properties p = new Properties(); try { p.load(Tools.class.getResourceAsStream("/release.properties")); return p.getProperty("release"); } catch (final IOException e) { LOG.appError("getRelease: cannot open release file", "", e); return "unknown"; } } /** Sets defaults from AppDefaults bundle. */ public static void setDefaults() { LoggerFactory.setDebugLevel(getDefaultInt("DebugLevel")); if (getDefault("AppWarning").equals("y")) { LoggerFactory.setShowAppWarning(true); } if (getDefault("AppError").equals("y")) { LoggerFactory.setShowAppError(true); } } public static String getStackTrace(final Throwable e) { final StringBuilder strace = new StringBuilder(""); if (e != null) { strace.append('\n'); strace.append(e.getMessage()); final StackTraceElement[] st = e.getStackTrace(); for (int i = 0; i < st.length; i++) { strace.append('\n'); strace.append(e.getStackTrace()[i].toString()); } if (e.getCause() != null) { strace.append("\n\ncaused by:"); strace.append(getStackTrace(e.getCause())); } } return strace.toString(); } /** * Checks string if it is an ip. */ public static boolean isIp(final CharSequence ipString) { boolean wasValid = true; // Inet4Address ip; if (ipString == null || "".equals(ipString)) { wasValid = false; } else { final Pattern pattern; try { final String ipPattern = "([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})"; pattern = Pattern.compile(ipPattern); } catch (final PatternSyntaxException exception) { return true; } final Matcher myMatcher = pattern.matcher(ipString); if (myMatcher.matches()) { for (int i = 1; i < 5; i++) { if (Integer.parseInt(myMatcher.group(i)) > 255) { wasValid = false; break; } } } else { wasValid = false; } } return wasValid; } public static void printStackTrace(final String text) { System.out.println(text); printStackTrace(); } public static void printStackTrace() { System.out.println(getStackTrace()); } public static String getStackTrace() { final Throwable th = new Throwable(); final StringWriter sw = new StringWriter(); final PrintWriter pw = new PrintWriter(sw); th.printStackTrace(pw); pw.close(); return sw.toString(); } /** * Loads the save file and returns its content as string. Return null, if * nothing was loaded. */ public static String loadFile(MainPresenter mainPresenter, final String filename, final boolean showError) { BufferedReader in = null; final StringBuilder content = new StringBuilder(""); try { in = new BufferedReader(new InputStreamReader(new FileInputStream(new File(filename)), "UTF-8")); String line; while ((line = in.readLine()) != null) { content.append(line); } } catch (final IOException ex) { if (showError) { mainPresenter.infoDialog("Load Error", "The file " + filename + " failed to load", ex.getMessage()); } return null; } finally { if(in != null) { try { in.close(); } catch (final IOException ex) { LOG.appError("loadFile: could not close: " + filename, ex); } } } return content.toString(); } /** Stops the specified clusters in the gui. */ public static void stopClusters(final Iterable<Cluster> selectedClusters) { for (final Cluster cluster : selectedClusters) { cluster.removeClusterAndDisconnect(); } } /** * Returns default value for option from AppDefaults resource bundle. */ public static String getDefault(final String option) { synchronized (Tools.class) { if (resourceAppDefaults == null) { resourceAppDefaults = ResourceBundle.getBundle("lcmc.configs.AppDefaults"); } } try { return resourceAppDefaults.getString(option); } catch (final Exception e) { LOG.appError("getDefault: unresolved config resource", option, e); return option; } } /** * Returns default color for option from AppDefaults resource bundle. */ public static Color getDefaultColor(final String option) { synchronized (Tools.class) { if (resourceAppDefaults == null) { resourceAppDefaults = ResourceBundle.getBundle("lcmc.configs.AppDefaults"); } } try { return (Color) resourceAppDefaults.getObject(option); } catch (final Exception e) { LOG.appError("getDefaultColor: unresolved config resource", option, e); return Color.WHITE; } } /** * Returns default value for integer option from AppDefaults resource * bundle. */ public static int getDefaultInt(final String option) { synchronized (Tools.class) { if (resourceAppDefaults == null) { resourceAppDefaults = ResourceBundle.getBundle("lcmc.configs.AppDefaults"); } } try { return (Integer) resourceAppDefaults.getObject(option); } catch (final Exception e) { LOG.appError("getDefaultInt: exception", option + ": " + getDefault(option), e); return 0; } } /** * Returns localized string from TextResource resource bundle. * Replace {}s, with replace array in the order as they come. */ public static String getString(final String text, final String[] replace) { String s = getString(text); if (s != null) { for (final String r : replace) { s = s.replaceFirst("\\{\\}", r); } } return s; } /** * Returns localized string from TextResource resource bundle. * Replace {}, with the replace string. */ public static String getString(final String text, final String replace) { final String s = getString(text); if (s != null) { return s.replaceFirst("\\{\\}", replace); } return s; } /** * Returns localized string from TextResource resource bundle. */ public static String getString(final String text) { synchronized (Tools.class) { if (resource == null) { /* set locale */ final Locale currentLocale = Locale.getDefault(); resource = ResourceBundle.getBundle("lcmc.configs.TextResource", currentLocale); } } try { return resource.getString(text); } catch (final Exception e) { LOG.appError("getString: unresolved resource: " + text); return text; } } /** * Returns service definiton from ServiceDefinitions resource bundle. */ public static String[] getServiceDefinition( final String service) { final ResourceBundle resourceSD = ResourceBundle.getBundle("lcmc.configs.ServiceDefinitions"); try { return resourceSD.getStringArray(service); } catch (final Exception e) { LOG.appWarning("getServiceDefinition: cannot get service definition for service: " + service, e); return new String[]{}; } } /** * Joins String array into one string with specified delimiter. */ public static String join(final String delim, final String[] strings) { if (strings == null || strings.length == 0) { return ""; } if (strings.length == 1 && strings[0] == null) { return ""; } final StringBuilder ret = new StringBuilder(""); for (int i = 0; i < strings.length - 1; i++) { if (strings[i] != null) { ret.append(strings[i]); if (delim != null && strings[i + 1] != null) { ret.append(delim); } } } if (strings[strings.length - 1] != null) { ret.append(strings[strings.length - 1]); } return ret.toString(); } /** Joins String list into one string with specified delimiter. */ public static String join(final String delim, final Collection<String> strings) { if (strings == null) { return ""; } return join(delim, strings.toArray(new String[strings.size()])); } /** * Joins String array into one string with specified delimiter. */ public static String join(final String delim, final String[] strings, final int length) { if (strings == null || strings.length == 0 || length <= 0) { return ""; } final StringBuilder ret = new StringBuilder(""); int i; for (i = 0; i < length - 1 && i < strings.length - 1; i++) { ret.append(strings[i]); if (delim != null) { ret.append(delim); } } i++; ret.append(strings[i - 1]); return ret.toString(); } /** Uppercases the first character. */ public static String ucfirst(final String s) { if (s == null || s.isEmpty()) { return s; } final String f = s.substring(0, 1); return s.replaceFirst(".", f.toUpperCase(Locale.US)); } /** * Returns intersection of two string lists as List of string. */ public static Optional<Set<String>> getIntersection( final Optional<Set<String>> setA, final Optional<Set<String>> setB) { final Set<String> resultSet = new TreeSet<String>(); if (!setB.isPresent()) { return setA; } if (!setA.isPresent()) { return setB; } for (final String item : setA.get()) { if (setB.get().contains(item)) { resultSet.add(item); } } return Optional.of(resultSet); } /** * Convert text to html. */ public static String html(final String text) { if (text == null) { return "<html>\n</html>"; } return "<html><p>" + text.replaceAll("\n", "<br>") + "\n</html>"; } /** * Checks if object is of the string class. Returns true if object is null. */ public static boolean isStringClass(final Object o) { return o == null || o instanceof String; } /** Escapes for config file. */ public static String escapeConfig(final String value) { if (value == null) { return null; } if (!value.matches("[\\w-]*")) { return '"' + value.replaceAll("\"", "\\\\\"") + '"'; } return value; } /** Sets fixed size for component. */ public static void setSize(final Component c, final int width, final int height) { final Dimension d = new Dimension(width, height); c.setMaximumSize(new Dimension(Short.MAX_VALUE, height)); c.setMinimumSize(d); c.setPreferredSize(d); } /** * Returns -1 if version1 is smaller that version2, 0 if version1 equals * version2 and 1 if version1 is bigger than version2. */ public static int compareVersions(final String version1, final String version2) throws Exceptions.IllegalVersionException { if (version1 == null || version2 == null) { throw new Exceptions.IllegalVersionException(version1, version2); } final Pattern p = Pattern.compile("(.*\\d+)rc(\\d+)$"); final Matcher m1 = p.matcher(version1); String version1a; int rc1 = Integer.MAX_VALUE; if (m1.matches()) { version1a = m1.group(1); try { rc1 = Integer.parseInt(m1.group(2)); } catch (final java.lang.NumberFormatException e) { LOG.appWarning("cannot parse: " + m1.group(2)); } } else { version1a = version1; } int index = version1a.indexOf('-'); if (index < 0) { index = version1a.indexOf('_'); } if (index >= 0) { version1a = version1a.substring(0, index); } final Matcher m2 = p.matcher(version2); final String version2a; int rc2 = Integer.MAX_VALUE; if (m2.matches()) { version2a = m2.group(1); try { rc2 = Integer.parseInt(m2.group(2)); } catch (final java.lang.NumberFormatException e) { LOG.appWarning("cannot parse: " + m1.group(2)); } } else { version2a = version2; } final String[] v1a = version1a.split("\\."); final String[] v2a = version2a.split("\\."); if (v1a.length < 1 || v2a.length < 1) { throw new Exceptions.IllegalVersionException(version1, version2); } int i = 0; while (true) { if (i >= v1a.length && i >= v2a.length) { break; } else if (i >= v1a.length || i >= v2a.length) { return 0; } int v1i = 0; if (i < v1a.length) { final String v1 = v1a[i]; try { v1i = Integer.parseInt(v1); } catch (final java.lang.NumberFormatException e) { throw new Exceptions.IllegalVersionException(version1); } } int v2i = 0; if (i < v2a.length) { final String v2 = v2a[i]; try { v2i = Integer.parseInt(v2); } catch (final java.lang.NumberFormatException e) { throw new Exceptions.IllegalVersionException(version2); } } if (v1i < v2i) { return -1; } else if (v1i > v2i) { return 1; } i++; } if (rc1 < rc2) { return -1; } else if (rc1 > rc2) { return 1; } return 0; } /** Returns number of characters 'c' in a string 's'. */ public static int charCount(final CharSequence s, final char c) { if (s == null) { return 0; } int count = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == c) { count++; } } return count; } /** * Creates config on all hosts with specified name in the specified * directory. */ public static void createConfigOnAllHosts(final Host[] hosts, final String config, final String fileName, final String dir, final String mode, final boolean makeBackup) { for (final Host host : hosts) { host.getSSH().createConfig(config, fileName, dir, mode, makeBackup, null, null); } } /** Returns border with title. */ public static TitledBorder getBorder(final String text) { final TitledBorder titledBorder = new TitledBorder(BorderFactory.createLineBorder(Color.BLACK, 1), text); titledBorder.setTitleJustification(TitledBorder.LEFT); return titledBorder; } /** Returns whether the computer, where this program is run, is Linux. */ public static boolean isLinux() { return "Linux".equals(System.getProperty("os.name")); } /** Returns whether the computer, where this program is run, is Windows. */ public static boolean isWindows() { return System.getProperty("os.name").indexOf("Windows") == 0; } /** Sets the html font of the editor pane to be the default font. */ public static void setEditorFont(final JEditorPane ep) { final Font font = UIManager.getFont("Label.font"); final String bodyRule = "body { font-family: " + font.getFamily() + "; " + "font-size: " + font.getSize() + "pt; }"; ((HTMLDocument) ep.getDocument()).getStyleSheet().addRule(bodyRule); } /** Reads and returns a content of a text file. */ public static String getFile(final String fileName) { if (fileName == null) { return null; } final URL url = Tools.class.getResource(fileName); if (url == null) { return null; } try { final BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8")); final StringBuilder content = new StringBuilder(""); while (br.ready()) { content.append(br.readLine()); content.append('\n'); } return content.toString(); } catch (final IOException e) { LOG.appError("getFile: could not read: " + fileName, "", e); return null; } } /** Convenience sleep wrapper. */ public static void sleep(final int ms) { try { Thread.sleep(ms); } catch (final InterruptedException ex) { Thread.currentThread().interrupt(); } } /** Convenience sleep wrapper with float argument. */ public static void sleep(final float ms) { sleep((int) ms); } /** Returns the latest version of this application. */ public static String[] getLatestVersion() { String version = null; final Pattern vPattern = Pattern.compile(".*version:\\s+([0-9.]*)"); final Pattern iPattern = Pattern.compile(".*info:\\s+(\\d+)\\s+(.*)"); final int randomInfo = (int) (Math.random() * 100); String info = null; try { final String url = "http://lcmc.sourceforge.net/version.html?lcmc-check-" + getRelease(); final BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(url).openStream(), "UTF-8")); int rate = 0; do { final String line = reader.readLine(); if (line == null) { break; } final Matcher vm = vPattern.matcher(line); if (vm.matches()) { final String v = vm.group(1); try { if (version == null || compareVersions(v, version) > 0) { version = v; } } catch (final Exceptions.IllegalVersionException e) { LOG.appWarning("getLatestVersion: " + e.getMessage(), e); } } else if (info == null) { final Matcher im = iPattern.matcher(line); if (im.matches()) { rate += Integer.parseInt(im.group(1)); if (rate > randomInfo) { info = im.group(2); } } } } while (true); } catch (final MalformedURLException mue) { return new String[]{null, null}; } catch (final IOException ioe) { return new String[]{version, info}; } return new String[]{version, info}; } /** Opens default browser. */ public static void openBrowser(final String url) { try { if (Desktop.isDesktopSupported()) { final Desktop desktop = Desktop.getDesktop(); if (desktop.isSupported(Desktop.Action.BROWSE)) { Desktop.getDesktop().browse(new URI(url)); } } } catch (final IOException e) { LOG.error("openBrowser: can't open: " + url + "; " + e.getMessage()); } catch (final URISyntaxException e) { LOG.error("openBrowser: can't open: " + url + "; " + e.getMessage()); } } /** Check whether the string is number. */ public static boolean isNumber(final String s) { try { Long.parseLong(s); return true; } catch (final NumberFormatException nfe) { return false; } } /** Returns list that is expandable by shell. {'a','b'...} */ public static String shellList(final String[] items) { final StringBuilder list = new StringBuilder(""); if (items == null || items.length == 0) { return null; } else if (items.length == 1) { list.append(items[0]); } else { list.append('{'); for (int i = 0; i < items.length - 1; i++) { list.append('\''); list.append(items[i]); list.append("',"); } if (items.length != 0) { list.append('\''); list.append(items[items.length - 1]); list.append('\''); } list.append('}'); } return list.toString(); } public static <T> boolean areEqual(final T v1, final T v2) { if (v1 == null) { return v2 == null; } else { return v1.equals(v2); } } public static boolean areEqual(final Value v1, final Value v2) { if (v1 != null) { if (v2 == null) { return v1.isNothingSelected(); } else { return Tools.areEqual(v1.getValueForConfig(), v2.getValueForConfig()); } } else if (v2 == null) { return true; } else { return v2.isNothingSelected(); } } /** Returns random secret of the specified lenght. */ public static String getRandomSecret(final int len) { final Random rand = new Random(); final ArrayList<Character> charsL = new ArrayList<Character>(); for (int a = 'a'; a <= 'z'; a++) { charsL.add((char) a); charsL.add(Character.toUpperCase((char) a)); } for (int a = '0'; a <= '9'; a++) { charsL.add((char) a); } final Character[] chars = charsL.toArray(new Character[charsL.size()]); final StringBuilder s = new StringBuilder(len + 1); for (int i = 0; i < len; i++) { s.append(chars[rand.nextInt(chars.length)]); } return s.toString(); } public static boolean isLocalIp(final String ip) { if (ip == null || "127.0.0.1".equals(ip) || "127.0.1.1".equals(ip)) { return true; } try { final String localIp = InetAddress.getLocalHost().getHostAddress(); return ip.equals(localIp); } catch (final java.net.UnknownHostException e) { return false; } } /** Resize table. */ public static void resizeTable(final JTable table, final Map<Integer, Integer> defaultWidths) { if (table == null) { return; } final int margin = 3; for (int i = 0; i < table.getColumnCount(); i++) { final int vColIndex = i; final TableColumnModel colModel = table.getColumnModel(); final TableColumn col = colModel.getColumn(vColIndex); TableCellRenderer renderer = col.getHeaderRenderer(); if (renderer == null) { renderer = table.getTableHeader().getDefaultRenderer(); } if (renderer == null) { continue; } Component comp = renderer.getTableCellRendererComponent(table, col.getHeaderValue(), false, false, 0, 0); Integer dw = null; if (defaultWidths != null) { dw = defaultWidths.get(i); } int width; if (dw == null) { width = comp.getPreferredSize().width; for (int r = 0; r < table.getRowCount(); r++) { renderer = table.getCellRenderer(r, vColIndex); if (renderer == null) { continue; } comp = renderer.getTableCellRendererComponent(table, table.getValueAt(r, vColIndex), false, false, r, vColIndex); width = Math.max(width, comp.getPreferredSize().width); } } else { width = dw; col.setMaxWidth(width); } width += 2 * margin; col.setPreferredWidth(width); } ((JLabel) table.getTableHeader().getDefaultRenderer()) .setHorizontalAlignment(SwingConstants.CENTER); } /** Sets the menu and all its parents visible, not visible. */ public static void setMenuVisible(final JComponent menu, final boolean visible) { JComponent parent = (JComponent) menu.getParent(); if (parent instanceof JViewport) { /* MyList */ parent = (JComponent) parent.getParent(); parent = (JComponent) parent.getParent(); } if (parent instanceof JPopupMenu) { JComponent inv = (JComponent) ((JPopupMenu) parent).getInvoker(); while (inv != null) { final JComponent invP = (JComponent) inv.getParent(); if (!(invP instanceof JPopupMenu)) { break; } invP.setVisible(visible); for (final Component c : invP.getComponents()) { c.setVisible(visible); } final JComponent pp = (JComponent) invP.getParent(); if (pp != null) { pp.setVisible(visible); } inv = (JComponent) ((JPopupMenu) invP).getInvoker(); } menu.setVisible(visible); parent.setVisible(visible); final JComponent pp = (JComponent) parent.getParent(); if (pp != null) { pp.setVisible(visible); } for (final Component c : parent.getComponents()) { c.setVisible(visible); } parent.repaint(); } } /** Sets background color to be opaque or semi-transparent. */ private static void setBGColor(final JComponent c, final boolean opaque) { final Color oc = c.getBackground(); c.setBackground(new Color(oc.getRed(), oc.getGreen(), oc.getBlue(), opaque ? 255 : 120)); } /** Sets the menu and all its parents opaque, transparent. */ public static void setMenuOpaque(final JComponent menu, final boolean opaque) { JComponent parent = (JComponent) menu.getParent(); if (parent instanceof JViewport) { /* MyList */ parent = (JComponent) parent.getParent(); parent = (JComponent) parent.getParent(); } if (parent instanceof JPopupMenu) { JComponent inv = (JComponent) ((JPopupMenu) parent).getInvoker(); while (inv != null) { final JComponent invP = (JComponent) inv.getParent(); if (!(invP instanceof JPopupMenu)) { break; } setBGColor(invP, opaque); for (final Component c : invP.getComponents()) { setBGColor((JComponent) c, opaque); } final JComponent pp = (JComponent) invP.getParent(); if (pp != null) { setBGColor(pp, opaque); } inv = (JComponent) ((JPopupMenu) invP).getInvoker(); } setBGColor(menu, opaque); setBGColor(parent, opaque); final JComponent pp = (JComponent) parent.getParent(); if (pp != null) { setBGColor(pp, opaque); } for (final Component c : parent.getComponents()) { setBGColor((JComponent) c, opaque); } parent.repaint(); } } public static String getUnixPath(final String dir) { if (dir == null) { return null; } String unixPath; if (isWindows()) { unixPath = dir.replaceAll("\\\\", "/"); if (unixPath.length() >= 2 && ":".equalsIgnoreCase(unixPath.substring(1, 2))) { unixPath = unixPath.substring(2); } } else { unixPath = dir; } return unixPath; } /** Returns bounds of the whole screen. */ public static Rectangle getScreenBounds(final JComponent component) { final GraphicsConfiguration gc = component.getGraphicsConfiguration(); final Rectangle sBounds = gc.getBounds(); final Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc); /* Take into account screen insets, decrease viewport */ sBounds.x += screenInsets.left; sBounds.y += screenInsets.top; sBounds.width -= screenInsets.left + screenInsets.right; sBounds.height -= (screenInsets.top + screenInsets.bottom); return sBounds; } /** Compares two Lists with services if thery are equal. The order does not * matter. */ public static boolean serviceInfoListEquals(final Collection<ServiceInfo> l1, final Collection<ServiceInfo> l2) { if (l1 == l2) { return true; } if (l1 == null || l2 == null) { return false; } if (l1.size() != l2.size()) { return false; } for (final ServiceInfo s1 : l1) { if (!l2.contains(s1)) { return false; } } return true; } /** Trims text to have displayable width. */ public static String trimText(final String text) { final int width = 80; if (text == null || text.length() <= width) { return text; } final StringBuilder out = new StringBuilder(text.length() + 10); /* find next space */ String t = text; while (true) { final int pos = t.indexOf(' ', width); if (pos > 0) { out.append(t.substring(0, pos)); out.append('\n'); t = t.substring(pos + 1); } else { break; } } out.append(t); return out.toString(); } /** Return directory part (to the /) of the filename. */ public static String getDirectoryPart(final String filename) { if (filename == null) { return null; } final int i = filename.lastIndexOf('/'); if (i < 0) { return filename; } return filename.substring(0, i + 1); } /** Escapes the quotes for the stacked ssh commands. */ public static String escapeQuotes(final String s, final int count) { if (s == null) { return null; } if (count <= 0) { return s; } final StringBuilder sb = new StringBuilder(""); for (int i = 0; i < s.length(); i++) { final char c = s.charAt(i); if (c == '\\') { sb.append("\\\\"); } else if (c == '"' || c == '$' || c == '`') { sb.append('\\'); sb.append(c); } else if (c == '\n') { sb.append('\n'); } else { sb.append(c); } } return escapeQuotes(sb.toString(), count - 1); } /** Escapes the single quotes. */ public static String escapeSingleQuotes(final String s, final int count) { if (s == null) { return null; } if (count <= 0) { return s; } final StringBuilder sb = new StringBuilder(""); for (int i = 0; i < s.length(); i++) { final char c = s.charAt(i); if (c == '\n') { sb.append('\n'); } else if (c == '\'') { sb.append("'\\''"); } else { sb.append(c); } } return escapeQuotes(sb.toString(), count - 1); } /** Returns array of host checkboxes in the specified cluster. */ public static Map<Host, JCheckBox> getHostCheckBoxes(final Cluster cluster) { final Map<Host, JCheckBox> components = new LinkedHashMap<Host, JCheckBox>(); for (final Host host : cluster.getHosts()) { final JCheckBox button = new JCheckBox(host.getName()); button.setBackground(Tools.getDefaultColor("ConfigDialog.Background.Light")); components.put(host, button); } return components; } /** * Returns true if the hb version on the host is smaller or equal * Heartbeat 2.1.4. */ public static boolean versionBeforePacemaker(final Host host) { final String hbV = host.getHostParser().getHeartbeatVersion(); final String pcmkV = host.getHostParser().getPacemakerVersion(); try { return pcmkV == null && hbV != null && Tools.compareVersions(hbV, "2.99.0") < 0; } catch (final Exceptions.IllegalVersionException e) { LOG.appWarning("versionBeforePacemaker: " + e.getMessage(), e); return false; } } /** Trim the white space (' ', '\n') at the end of the string buffer.*/ public static void chomp(final StringBuffer sb) { final int l = sb.length(); int i = l; while (i > 0 && (sb.charAt(i - 1) == '\n')) { i--; } if (i >= 0 && i < l - 1) { sb.delete(i, l - 1); } } /** Return brigher version of the color (or darker). */ public static Color brighterColor(final Color c, final double x) { double r = c.getRed() * x; if (r > 255) { r = 255; } double g = c.getGreen() * x; if (g > 255) { g = 255; } double b = c.getBlue() * x; if (b > 255) { b = 255; } return new Color((int) r, (int) g, (int) b); } public static String generateVMMacAddress() { final StringBuilder mac = new StringBuilder("52:54:00"); for (int i = 0; i < 3; i++) { mac.append(':'); mac.append(String.format("%02x", (int) (Math.random() * 256))); } return mac.toString(); } private static List<String> getNameParts(final CharSequence name) { final List<String> parts = new ArrayList<String>(); if (name == null) { return parts; } final Pattern p = Pattern.compile("(\\d+|\\D+)"); final Matcher m = p.matcher(name); while (m.find()) { parts.add(m.group()); } return parts; } /** * Compare two names, doing the right thing there are numbers in the * beginning or in the end of the string. */ public static int compareNames(final CharSequence s1, final CharSequence s2) { final List<String> parts1 = getNameParts(s1); final List<String> parts2 = getNameParts(s2); int i = 0; for (final String p1 : parts1) { if (i >= parts2.size()) { return 1; } final String p2 = parts2.get(i); final int res; if (Character.isDigit(p1.charAt(0)) && Character.isDigit(p2.charAt(0))) { res = Integer.parseInt(p1) - Integer.parseInt(p2); } else { res = p1.compareToIgnoreCase(p2); } if (res != 0) { return res; } i++; } if (parts1.size() == parts2.size()) { return 0; } return -1; } public static boolean equalCollections(final Collection<?> collection1, final Collection<?> collection2) { if (collection1.size() != collection2.size()) { return false; } final Iterator<?> iterator1 = collection1.iterator(); final Iterator<?> iterator2 = collection2.iterator(); while (iterator1.hasNext()) { if (!iterator1.next().equals(iterator2.next())) { return false; } } return true; } /** * Returns common file systems on all nodes as StringValue array. * The defaultValue is stored as the first item in the array. */ public static Value[] getCommonFileSystemsWithDefault(final Set<String> commonFileSystems, final Value defaultValue) { final Value[] commonFileSystemItems = new Value[commonFileSystems.size() + 2]; commonFileSystemItems[0] = defaultValue; int i = 1; for (final String commonFileSystem : commonFileSystems) { commonFileSystemItems[i] = new StringValue(commonFileSystem); i++; } commonFileSystemItems[i] = new StringValue("none"); return commonFileSystemItems; } public static void writeImage(final String filename, final BufferedImage image, final String imageType) { File outputfile = new File(filename); try { ImageIO.write(image, imageType, outputfile); } catch (Exception e) { LOG.appError("writeImage: failed", e); } } private Tools() { /* no instantiation possible. */ } }