The following changes have two main goals:
1. Fix a bug in the status panel code. The status panel code assumes that there is only one base DN per backend and is not able to display several base DNs per database.
2. Extend the information displayed by the status panel in order to show synchronization status. Basically we say if a suffix is synchronized or not and the number of missing changes and the age of the oldest missing change for the synchronized suffixes.
Please note that due to the fact that there is quite a lot of information to be displayed, the output of the status command line has changed. Instead of displaying a table-like layout for the Data Sources, we display the information for a given base DN in a block. This is done mainly because displaying a table with 6 columns in lines of 80 characters is complicated if we do not want to use abreviations.
2 files added
15 files modified
| | |
| | | shutdown-button-label=Shutdown |
| | | continue-button-label=Continue |
| | | continue-button-install-tooltip=Continue with the QuickSetup Tool |
| | | ok-button-label=OK |
| | | |
| | | # |
| | | # Confirmation dialogs |
| | |
| | | upgrade-review-panel-new-version-label=New Version: |
| | | upgrade-review-panel-new-version-tooltip=The target version of the server |
| | | upgrade-review-panel-start-server=Start Server when the Upgrade has Completed |
| | | |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.opends.quicksetup.ui; |
| | | |
| | | import javax.swing.table.TableModel; |
| | | |
| | | /** |
| | | * A generic interface that must implement table models that are sortable. |
| | | */ |
| | | public interface SortableTableModel extends TableModel |
| | | { |
| | | /** |
| | | * Returns whether the sort is ascending or descending. |
| | | * @return <CODE>true</CODE> if the sort is ascending and <CODE>false</CODE> |
| | | * otherwise. |
| | | */ |
| | | public boolean isSortAscending(); |
| | | |
| | | /** |
| | | * Sets whether to sort ascending of descending. |
| | | * @param sortAscending whether to sort ascending or descending. |
| | | */ |
| | | public void setSortAscending(boolean sortAscending); |
| | | |
| | | /** |
| | | * Returns the column index used to sort. |
| | | * @return the column index used to sort. |
| | | */ |
| | | public int getSortColumn(); |
| | | |
| | | /** |
| | | * Sets the column index used to sort. |
| | | * @param sortColumn column index used to sort.. |
| | | */ |
| | | public void setSortColumn(int sortColumn); |
| | | |
| | | /** |
| | | * Updates the table model contents and sorts its contents depending on the |
| | | * sort options set by the user. |
| | | */ |
| | | public void forceResort(); |
| | | } |
| | |
| | | import java.awt.Insets; |
| | | import java.awt.Rectangle; |
| | | import java.awt.Toolkit; |
| | | import java.awt.event.MouseAdapter; |
| | | import java.awt.event.MouseEvent; |
| | | import java.util.HashMap; |
| | | |
| | | |
| | | import javax.swing.*; |
| | | import javax.swing.text.JTextComponent; |
| | | import javax.swing.border.Border; |
| | | import javax.swing.border.EmptyBorder; |
| | | import javax.swing.table.TableCellRenderer; |
| | | import javax.swing.table.TableColumn; |
| | | import javax.swing.table.TableColumnModel; |
| | | |
| | | import org.opends.quicksetup.i18n.ResourceProvider; |
| | | |
| | |
| | | public static final int LEFT_INSET_STEP = 5; |
| | | |
| | | /** |
| | | * Specifies the extra left inset for the sub-steps. |
| | | */ |
| | | public static final int LEFT_INSET_SUBSTEP = 10; |
| | | /** |
| | | * Specifies the top inset for the instructions sub panel. |
| | | */ |
| | | public static final int TOP_INSET_INSTRUCTIONS_SUBPANEL = 10; |
| | | public static final int TOP_INSET_INSTRUCTIONS_SUBPANEL = 5; |
| | | |
| | | /** |
| | | * Specifies the top inset for input subpanel. |
| | |
| | | public static final int LEFT_INSET_COPY_BUTTON = 10; |
| | | |
| | | /** |
| | | * Specifies the left inset for a subordinate subpanel. |
| | | */ |
| | | public static final int LEFT_INSET_SUBPANEL_SUBORDINATE = 30; |
| | | |
| | | /** |
| | | * Specifies the left inset for the progress bar. |
| | | */ |
| | | public static final int BOTTOM_INSET_PROGRESS_BAR = 10; |
| | |
| | | public static final int RELATIVE_PATH_FIELD_SIZE = 10; |
| | | |
| | | /** |
| | | * Specifies the number of columns of a text field for a host name. |
| | | */ |
| | | public static final int HOST_FIELD_SIZE = 20; |
| | | |
| | | /** |
| | | * Specifies the number of columns of a text field for a UID. |
| | | */ |
| | | public static final int UID_FIELD_SIZE = 15; |
| | | |
| | | /** |
| | | * Specifies the number of columns of a text field for a port. |
| | | */ |
| | | public static final int PORT_FIELD_SIZE = 5; |
| | |
| | | * Specifies the font for the instructions of the current panel. |
| | | */ |
| | | public static final Font INSTRUCTIONS_FONT = |
| | | Font.decode("Arial-PLAIN-14"); |
| | | Font.decode("Arial-PLAIN-12"); |
| | | |
| | | /** |
| | | * Specifies the font for the instructions of the current panel. |
| | |
| | | */ |
| | | public static String applyFontToHtml(String html, Font font) |
| | | { |
| | | StringBuffer buf = new StringBuffer(); |
| | | StringBuilder buf = new StringBuilder(); |
| | | |
| | | buf.append("<span style=\"").append(getFontStyle(font)).append("\">") |
| | | .append(html).append(SPAN_CLOSE); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns a table created with the provided model and renderers. |
| | | * @param tableModel the table model. |
| | | * @param renderer the cell renderer. |
| | | * @param headerRenderer the header renderer. |
| | | * @return a table created with the provided model and renderers. |
| | | */ |
| | | public static JTable makeSortableTable(final SortableTableModel tableModel, |
| | | TableCellRenderer renderer, |
| | | TableCellRenderer headerRenderer) |
| | | { |
| | | final JTable table = new JTable(tableModel); |
| | | table.setShowGrid(true); |
| | | table.setGridColor(UIFactory.PANEL_BORDER_COLOR); |
| | | table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); |
| | | table.setBackground(UIFactory.CURRENT_STEP_PANEL_BACKGROUND); |
| | | table.getTableHeader().setBackground(UIFactory.DEFAULT_BACKGROUND); |
| | | table.setRowMargin(0); |
| | | |
| | | for (int i=0; i<tableModel.getColumnCount(); i++) |
| | | { |
| | | TableColumn col = table.getColumn(table.getColumnName(i)); |
| | | col.setCellRenderer(renderer); |
| | | col.setHeaderRenderer(headerRenderer); |
| | | } |
| | | MouseAdapter listMouseListener = new MouseAdapter() { |
| | | public void mouseClicked(MouseEvent e) { |
| | | TableColumnModel columnModel = table.getColumnModel(); |
| | | int viewColumn = columnModel.getColumnIndexAtX(e.getX()); |
| | | int sortedBy = table.convertColumnIndexToModel(viewColumn); |
| | | if (e.getClickCount() == 1 && sortedBy != -1) { |
| | | tableModel.setSortAscending(!tableModel.isSortAscending()); |
| | | tableModel.setSortColumn(sortedBy); |
| | | tableModel.forceResort(); |
| | | } |
| | | } |
| | | }; |
| | | table.getTableHeader().addMouseListener(listMouseListener); |
| | | return table; |
| | | } |
| | | |
| | | /** |
| | | * Creates a header renderer for a JTable with our own look and feel. |
| | | * @return a header renderer for a JTable with our own look and feel. |
| | | */ |
| | | public static TableCellRenderer makeHeaderRenderer() |
| | | { |
| | | return new HeaderRenderer(); |
| | | } |
| | | |
| | | /** |
| | | * Returns a String that contains the html passed as parameter with a div |
| | | * applied. The div style corresponds to the Font specified as parameter. |
| | | * The goal of this method is to be able to specify a font for an HTML string. |
| | |
| | | */ |
| | | public static String applyFontToHtmlWithDiv(String html, Font font) |
| | | { |
| | | StringBuffer buf = new StringBuffer(); |
| | | StringBuilder buf = new StringBuilder(); |
| | | |
| | | buf.append("<div style=\"").append(getFontStyle(font)).append("\">") |
| | | .append(html).append(DIV_CLOSE); |
| | |
| | | */ |
| | | private static String getFontStyle(Font font) |
| | | { |
| | | StringBuffer buf = new StringBuffer(); |
| | | StringBuilder buf = new StringBuilder(); |
| | | |
| | | buf.append("font-family:" + font.getName()).append( |
| | | ";font-size:" + font.getSize() + "pt"); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Class used to render the table headers. |
| | | */ |
| | | class HeaderRenderer extends JLabel implements TableCellRenderer |
| | | { |
| | | private static final long serialVersionUID = -8604332267021523835L; |
| | | |
| | | /** |
| | | * Default constructor. |
| | | */ |
| | | public HeaderRenderer() |
| | | { |
| | | super(); |
| | | UIFactory.setTextStyle(this, UIFactory.TextStyle.PRIMARY_FIELD_VALID); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Component getTableCellRendererComponent(JTable table, Object value, |
| | | boolean isSelected, boolean hasFocus, int row, int column) { |
| | | setText((String)value); |
| | | if (column == 0) |
| | | { |
| | | setBorder(BorderFactory.createCompoundBorder( |
| | | BorderFactory.createMatteBorder(1, 1, 1, 1, |
| | | UIFactory.PANEL_BORDER_COLOR), |
| | | BorderFactory.createEmptyBorder(4, 4, 4, 4))); |
| | | } |
| | | else |
| | | { |
| | | setBorder(BorderFactory.createCompoundBorder( |
| | | BorderFactory.createMatteBorder(1, 0, 1, 1, |
| | | UIFactory.PANEL_BORDER_COLOR), |
| | | BorderFactory.createEmptyBorder(4, 4, 4, 4))); |
| | | } |
| | | return this; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * This class has been written to have a better behaviour with the scroll pane |
| | | * than the one we have by default in the case of the progress panel. |
| | | * |
| | |
| | | */ |
| | | public class Utils |
| | | { |
| | | private static final int DEFAULT_LDAP_CONNECT_TIMEOUT = 3000; |
| | | |
| | | private static final int BUFFER_SIZE = 1024; |
| | | |
| | | private static final int MAX_LINE_WIDTH = 80; |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns a String representation of the OS we are running. |
| | | * @return a String representation of the OS we are running. |
| | | */ |
| | | public static String getOSString() |
| | | { |
| | | return SetupUtils.getOSString(); |
| | | } |
| | | |
| | | /** |
| | | * Returns <CODE>true</CODE> if the parent directory for the provided path |
| | | * exists and <CODE>false</CODE> otherwise. |
| | | * @param path the path that we are analyzing. |
| | |
| | | try |
| | | { |
| | | InitialLdapContext ctx = |
| | | Utils.createLdapContext(ldapUrl, dn, pwd, 3000, null); |
| | | Utils.createLdapContext(ldapUrl, dn, pwd, |
| | | Utils.getDefaultLDAPTimeout(), null); |
| | | |
| | | /* |
| | | * Search for the config to check that it is the directory manager. |
| | |
| | | * Displays an error message dialog. |
| | | * |
| | | * @param parent |
| | | * the parent frame of the error dialog. |
| | | * the parent component of the error dialog. |
| | | * @param msg |
| | | * the error message. |
| | | * @param title |
| | | * the title for the dialog. |
| | | */ |
| | | public static void displayError(JFrame parent, String msg, String title) |
| | | public static void displayError(Component parent, String msg, String title) |
| | | { |
| | | JOptionPane.showMessageDialog(parent, msg, title, |
| | | JOptionPane.ERROR_MESSAGE); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns the default LDAP timeout in milliseconds when we try to connect to |
| | | * a server. |
| | | * @return the default LDAP timeout in milliseconds when we try to connect to |
| | | * a server. |
| | | */ |
| | | public static int getDefaultLDAPTimeout() |
| | | { |
| | | return DEFAULT_LDAP_CONNECT_TIMEOUT; |
| | | } |
| | | |
| | | /** |
| | | * Returns the max size in character of a line to be displayed in the command |
| | | * line. |
| | | * @return the max size in character of a line to be displayed in the command |
| | |
| | | return OperatingSystem.WINDOWS == getOperatingSystem(); |
| | | } |
| | | |
| | | /** |
| | | * Returns a String representation of the OS we are running. |
| | | * @return a String representation of the OS we are running. |
| | | */ |
| | | public static String getOSString() |
| | | { |
| | | return getOperatingSystem().toString(); |
| | | } |
| | | |
| | | /** |
| | | * Commodity method to help identifying the OS we are running on. |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.opends.statuspanel; |
| | | |
| | | import org.opends.quicksetup.util.Utils; |
| | | |
| | | /** |
| | | * This class is used to represent a Base DN / Replica and is aimed to be |
| | | * used by the classes in the DatabasesTableModel class. |
| | | * |
| | | */ |
| | | public class BaseDNDescriptor |
| | | { |
| | | /** |
| | | * An enumeration describing the type of base DN for a given Database. |
| | | */ |
| | | public enum Type |
| | | { |
| | | /** |
| | | * The base DN is not synchronized. |
| | | */ |
| | | NOT_SYNCHRONIZED, |
| | | /** |
| | | * The base DN is synchronized. |
| | | */ |
| | | SYNCHRONIZED |
| | | }; |
| | | |
| | | private int missingChanges; |
| | | private DatabaseDescriptor db; |
| | | private int ageOfOldestMissingChange; |
| | | private Type type; |
| | | private String baseDn; |
| | | |
| | | /** |
| | | * Constructor for this class. |
| | | * @param type the type of synchronization. |
| | | * @param baseDn the base DN associated with the Synchronization. |
| | | * @param db the database containing this base DN. |
| | | * @param ageOfOldestMissingChange the number of missing changes. |
| | | * @param missingChanges the number of missing changes. |
| | | */ |
| | | public BaseDNDescriptor(Type type, String baseDn, DatabaseDescriptor db, |
| | | int ageOfOldestMissingChange, int missingChanges) |
| | | { |
| | | this.baseDn = baseDn; |
| | | this.db = db; |
| | | this.type = type; |
| | | this.ageOfOldestMissingChange = ageOfOldestMissingChange; |
| | | this.missingChanges = missingChanges; |
| | | } |
| | | |
| | | /** |
| | | * Return the String DN associated with the base DN.. |
| | | * @return the String DN associated with the base DN. |
| | | */ |
| | | public String getDn() |
| | | { |
| | | return baseDn; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean equals(Object v) |
| | | { |
| | | boolean equals = false; |
| | | if (this != v) |
| | | { |
| | | if (v instanceof BaseDNDescriptor) |
| | | { |
| | | BaseDNDescriptor desc = (BaseDNDescriptor)v; |
| | | equals = (getType() == desc.getType()) && |
| | | Utils.areDnsEqual(getDn(), desc.getDn()) && |
| | | (getAgeOfOldestMissingChange() == desc.getAgeOfOldestMissingChange()) && |
| | | (getMissingChanges() == desc.getMissingChanges()); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | equals = true; |
| | | } |
| | | return equals; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int hashCode() |
| | | { |
| | | return (getType().toString() + getAgeOfOldestMissingChange() + getDn() + |
| | | getMissingChanges()).hashCode(); |
| | | } |
| | | |
| | | /** |
| | | * Returns the number of missing changes in the synchronization topology for |
| | | * this base DN. |
| | | * @return the number of missing changes in the synchronization topology for |
| | | * this base DN. |
| | | */ |
| | | public int getMissingChanges() |
| | | { |
| | | return missingChanges; |
| | | } |
| | | |
| | | /** |
| | | * Returns the age of the oldest missing change in seconds in the |
| | | * synchronization topology for this base DN. |
| | | * @return the age of the oldest missing change in seconds in the |
| | | * synchronization topology for this base DN. |
| | | */ |
| | | public int getAgeOfOldestMissingChange() |
| | | { |
| | | return ageOfOldestMissingChange; |
| | | } |
| | | |
| | | /** |
| | | * Returns the type for this base DN. |
| | | * @return the type for this base DN. |
| | | */ |
| | | public Type getType() |
| | | { |
| | | return type; |
| | | } |
| | | |
| | | /** |
| | | * Returns the database where this base DN is defined. |
| | | * @return the database where this base DN is defined. |
| | | */ |
| | | public DatabaseDescriptor getDatabase() |
| | | { |
| | | return db; |
| | | } |
| | | |
| | | /** |
| | | * Sets the type of this base DN. |
| | | * @param type the new type for this base DN. |
| | | */ |
| | | void setType(Type type) |
| | | { |
| | | this.type = type; |
| | | } |
| | | |
| | | /** |
| | | * Sets the database containing this base DN. |
| | | * @param db the database containing this base DN. |
| | | */ |
| | | void setDatabase(DatabaseDescriptor db) |
| | | { |
| | | this.db = db; |
| | | } |
| | | } |
| | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.TreeSet; |
| | | |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.util.LDIFException; |
| | |
| | | DirectoryServer.getObjectClass("ds-cfg-backend", true); |
| | | private final ObjectClass administrativeUserOc = |
| | | DirectoryServer.getObjectClass("ds-cfg-root-dn", true); |
| | | private final ObjectClass syncProviderOc = |
| | | DirectoryServer.getObjectClass("ds-cfg-synchronization-provider", true); |
| | | private final ObjectClass syncConfigOc = |
| | | DirectoryServer.getObjectClass("ds-cfg-synchronization-provider-config", |
| | | true); |
| | | |
| | | private HashSet<ListenerDescriptor> listeners = |
| | | new HashSet<ListenerDescriptor>(); |
| | |
| | | new HashSet<DatabaseDescriptor>(); |
| | | private HashSet<String> administrativeUsers = new HashSet<String>(); |
| | | private String errorMessage; |
| | | |
| | | private boolean synchronizationConfigured = false; |
| | | private HashSet<String> synchronizedSuffixes = new HashSet<String>(); |
| | | |
| | | /** |
| | | * Default constructor. |
| | |
| | | public void readConfiguration() |
| | | { |
| | | errorMessage = null; |
| | | listeners.clear(); |
| | | databases.clear(); |
| | | administrativeUsers.clear(); |
| | | synchronizationConfigured = false; |
| | | synchronizedSuffixes.clear(); |
| | | try |
| | | { |
| | | Installation installation = |
| | |
| | | { |
| | | updateConfig(entry); |
| | | } |
| | | updateSynchronization(); |
| | | } |
| | | catch (IOException ioe) |
| | | { |
| | |
| | | { |
| | | updateConfigWithAdministrativeUser(entry); |
| | | } |
| | | else if (entry.hasObjectClass(syncProviderOc)) |
| | | { |
| | | updateConfigWithSyncProviderEntry(entry); |
| | | } |
| | | else if (entry.hasObjectClass(syncConfigOc)) |
| | | { |
| | | updateConfigWithSyncConfig(entry); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | private void updateConfigWithBackend(Entry entry) |
| | | { |
| | | String baseDn = getFirstValue(entry, "ds-cfg-backend-base-dn"); |
| | | String id = getFirstValue(entry, "ds-cfg-backend-id"); |
| | | int nEntries = -1; // Unknown |
| | | |
| | | if (!isConfigBackend(id)) |
| | | { |
| | | databases.add(new DatabaseDescriptor(id, baseDn, nEntries)); |
| | | Set<String> baseDns = new TreeSet<String>(); |
| | | baseDns.addAll(getValues(entry, "ds-cfg-backend-base-dn")); |
| | | Set<BaseDNDescriptor> replicas = new LinkedHashSet<BaseDNDescriptor>(); |
| | | |
| | | for (String baseDn : baseDns) |
| | | { |
| | | replicas.add(getBaseDNDescriptor(entry, baseDn)); |
| | | } |
| | | |
| | | DatabaseDescriptor db = new DatabaseDescriptor(id, replicas, nEntries); |
| | | databases.add(db); |
| | | for (BaseDNDescriptor rep: replicas) |
| | | { |
| | | rep.setDatabase(db); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Updates the synchronization configuration data we expose to the user with |
| | | * the provided entry object. |
| | | * @param entry the entry to analyze. |
| | | */ |
| | | private void updateConfigWithSyncProviderEntry(Entry entry) |
| | | { |
| | | if ("true".equalsIgnoreCase(getFirstValue(entry, |
| | | "ds-cfg-synchronization-provider-enabled"))) |
| | | { |
| | | synchronizationConfigured = true; |
| | | } |
| | | else |
| | | { |
| | | synchronizationConfigured = false; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Updates the databases suffixes with the list of synchronized suffixes |
| | | * found. |
| | | */ |
| | | private void updateSynchronization() |
| | | { |
| | | if (synchronizationConfigured) |
| | | { |
| | | for (String suffixDn: synchronizedSuffixes) |
| | | { |
| | | BaseDNDescriptor replica = null; |
| | | for (DatabaseDescriptor db: databases) |
| | | { |
| | | Set<BaseDNDescriptor> replicas = db.getBaseDns(); |
| | | for (BaseDNDescriptor rep: replicas) |
| | | { |
| | | if (Utils.areDnsEqual(rep.getDn(), suffixDn)) |
| | | { |
| | | replica = rep; |
| | | break; |
| | | } |
| | | } |
| | | if (replica != null) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | if (replica != null) |
| | | { |
| | | replica.setType(BaseDNDescriptor.Type.SYNCHRONIZED); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Updates the synchronization configuration data we expose to the user with |
| | | * the provided entry object. |
| | | * @param entry the entry to analyze. |
| | | */ |
| | | private void updateConfigWithSyncConfig(Entry entry) |
| | | { |
| | | synchronizedSuffixes.addAll(getValues(entry, "ds-cfg-synchronization-dn")); |
| | | } |
| | | |
| | | /** |
| | | * The following three methods are just commodity methods to get localized |
| | | * messages. |
| | | */ |
| | |
| | | } |
| | | return v; |
| | | } |
| | | |
| | | /** |
| | | * Create a non synchronized base DN descriptor. |
| | | */ |
| | | private BaseDNDescriptor getBaseDNDescriptor(Entry entry, String baseDn) |
| | | { |
| | | return new BaseDNDescriptor(BaseDNDescriptor.Type.NOT_SYNCHRONIZED, |
| | | baseDn, null, -1, -1); |
| | | } |
| | | } |
| | |
| | | |
| | | package org.opends.statuspanel; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.Set; |
| | | import java.util.TreeSet; |
| | | |
| | | import javax.naming.NameNotFoundException; |
| | | import javax.naming.NamingEnumeration; |
| | | import javax.naming.NamingException; |
| | | import javax.naming.directory.Attribute; |
| | |
| | | new HashSet<DatabaseDescriptor>(); |
| | | private HashSet<String> administrativeUsers = new HashSet<String>(); |
| | | private String errorMessage; |
| | | private boolean synchronizationConfigured = false; |
| | | private HashSet<String> synchronizedSuffixes = new HashSet<String>(); |
| | | private HashMap<String, Integer> hmMissingChanges = |
| | | new HashMap<String, Integer>(); |
| | | private HashMap<String, Integer> hmAgeOfOldestMissingChanges = |
| | | new HashMap<String, Integer>(); |
| | | |
| | | private String dn; |
| | | private String pwd; |
| | |
| | | listeners.clear(); |
| | | databases.clear(); |
| | | administrativeUsers.clear(); |
| | | synchronizationConfigured = false; |
| | | synchronizedSuffixes.clear(); |
| | | hmMissingChanges.clear(); |
| | | hmAgeOfOldestMissingChanges.clear(); |
| | | javaVersion = null; |
| | | openConnections = -1; |
| | | |
| | |
| | | InitialLdapContext ctx = getDirContext(); |
| | | updateAdministrativeUsers(ctx); |
| | | updateListeners(ctx); |
| | | updateSynchronization(ctx); |
| | | updateDatabases(ctx); |
| | | javaVersion = getJavaVersion(ctx); |
| | | openConnections = getOpenConnections(ctx); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Updates the synchronization configuration data we expose to the user with |
| | | * the provided InitialLdapContext. |
| | | * @param ctx the InitialLdapContext to use to update the configuration. |
| | | * @throws NamingException if there was an error. |
| | | */ |
| | | private void updateSynchronization(InitialLdapContext ctx) |
| | | throws NamingException |
| | | { |
| | | SearchControls ctls = new SearchControls(); |
| | | ctls.setSearchScope(SearchControls.OBJECT_SCOPE); |
| | | ctls.setReturningAttributes( |
| | | new String[] { |
| | | "ds-cfg-synchronization-provider-enabled" |
| | | }); |
| | | String filter = "(objectclass=ds-cfg-synchronization-provider)"; |
| | | |
| | | LdapName jndiName = new LdapName( |
| | | "cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config"); |
| | | |
| | | try |
| | | { |
| | | NamingEnumeration syncProviders = ctx.search(jndiName, filter, ctls); |
| | | |
| | | while(syncProviders.hasMore()) |
| | | { |
| | | SearchResult sr = (SearchResult)syncProviders.next(); |
| | | |
| | | if ("true".equalsIgnoreCase(getFirstValue(sr, |
| | | "ds-cfg-synchronization-provider-enabled"))) |
| | | { |
| | | synchronizationConfigured = true; |
| | | } |
| | | } |
| | | } |
| | | catch (NameNotFoundException nse) |
| | | { |
| | | } |
| | | |
| | | ctls = new SearchControls(); |
| | | ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); |
| | | ctls.setReturningAttributes( |
| | | new String[] { |
| | | "ds-cfg-synchronization-dn" |
| | | }); |
| | | filter = "(objectclass=ds-cfg-synchronization-provider-config)"; |
| | | |
| | | jndiName = new LdapName( |
| | | "cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config"); |
| | | |
| | | try |
| | | { |
| | | NamingEnumeration syncProviders = ctx.search(jndiName, filter, ctls); |
| | | |
| | | while(syncProviders.hasMore()) |
| | | { |
| | | SearchResult sr = (SearchResult)syncProviders.next(); |
| | | |
| | | synchronizedSuffixes.addAll(getValues(sr, "ds-cfg-synchronization-dn")); |
| | | } |
| | | } |
| | | catch (NameNotFoundException nse) |
| | | { |
| | | } |
| | | |
| | | ctls = new SearchControls(); |
| | | ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE); |
| | | ctls.setReturningAttributes( |
| | | new String[] { |
| | | "approximate-delay", "waiting-changes", "base-dn" |
| | | }); |
| | | filter = "(approximate-delay=*)"; |
| | | |
| | | jndiName = new LdapName("cn=monitor"); |
| | | |
| | | if (synchronizedSuffixes.size() > 0) |
| | | { |
| | | try |
| | | { |
| | | NamingEnumeration monitorEntries = ctx.search(jndiName, filter, ctls); |
| | | |
| | | while(monitorEntries.hasMore()) |
| | | { |
| | | SearchResult sr = (SearchResult)monitorEntries.next(); |
| | | |
| | | String dn = getFirstValue(sr, "base-dn"); |
| | | |
| | | for (String baseDn: synchronizedSuffixes) |
| | | { |
| | | |
| | | if (Utils.areDnsEqual(dn, baseDn)) |
| | | { |
| | | try |
| | | { |
| | | hmAgeOfOldestMissingChanges.put(baseDn, |
| | | new Integer(getFirstValue(sr, "approximate-delay"))); |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | } |
| | | try |
| | | { |
| | | hmMissingChanges.put(baseDn, |
| | | new Integer(getFirstValue(sr, "waiting-changes"))); |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (NameNotFoundException nse) |
| | | { |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Updates the database configuration data we expose to the user with the |
| | | * provided InitialLdapContext. |
| | | * @param ctx the InitialLdapContext to use to update the configuration. |
| | |
| | | } |
| | | |
| | | /** |
| | | * Create the base DN descriptor. Assumes that the synchronizedSuffixes Set |
| | | * and synchronizationConfigured have already been initialized. |
| | | */ |
| | | private BaseDNDescriptor getBaseDNDescriptor(InitialLdapContext ctx, |
| | | String baseDn) |
| | | throws NamingException |
| | | { |
| | | BaseDNDescriptor.Type type; |
| | | int missingChanges = -1; |
| | | int ageOfOldestMissingChange = -1; |
| | | String mapSuffixDn = null; |
| | | |
| | | boolean replicated = false; |
| | | if (synchronizationConfigured) |
| | | { |
| | | for (String suffixDn: synchronizedSuffixes) |
| | | { |
| | | if (Utils.areDnsEqual(baseDn, suffixDn)) |
| | | { |
| | | replicated = true; |
| | | mapSuffixDn = suffixDn; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | if (replicated) |
| | | { |
| | | type = BaseDNDescriptor.Type.SYNCHRONIZED; |
| | | |
| | | Integer missing = hmMissingChanges.get(mapSuffixDn); |
| | | Integer age = hmAgeOfOldestMissingChanges.get(mapSuffixDn); |
| | | |
| | | if (age != null) |
| | | { |
| | | ageOfOldestMissingChange = age.intValue(); |
| | | } |
| | | |
| | | if (missing != null) |
| | | { |
| | | missingChanges = missing.intValue(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | type = BaseDNDescriptor.Type.NOT_SYNCHRONIZED; |
| | | } |
| | | |
| | | return new BaseDNDescriptor(type, baseDn, null, ageOfOldestMissingChange, |
| | | missingChanges); |
| | | } |
| | | |
| | | /** |
| | | * Updates the listener configuration data we expose to the user with the |
| | | * provided SearchResult object. |
| | | * @param entry the entry to analyze. |
| | |
| | | InitialLdapContext ctx) |
| | | throws NamingException |
| | | { |
| | | String baseDn = getFirstValue(entry, "ds-cfg-backend-base-dn"); |
| | | String id = getFirstValue(entry, "ds-cfg-backend-id"); |
| | | |
| | | if (!isConfigBackend(id)) |
| | | { |
| | | Set<String> baseDns = new TreeSet<String>(); |
| | | baseDns.addAll(getValues(entry, "ds-cfg-backend-base-dn")); |
| | | Set<BaseDNDescriptor> replicas = new LinkedHashSet<BaseDNDescriptor>(); |
| | | int nEntries = getEntryCount(ctx, id); |
| | | databases.add(new DatabaseDescriptor(id, baseDn, nEntries)); |
| | | |
| | | for (String baseDn : baseDns) |
| | | { |
| | | replicas.add(getBaseDNDescriptor(ctx, baseDn)); |
| | | } |
| | | |
| | | DatabaseDescriptor db = new DatabaseDescriptor(id, replicas, nEntries); |
| | | databases.add(db); |
| | | for (BaseDNDescriptor rep: replicas) |
| | | { |
| | | rep.setDatabase(db); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | package org.opends.statuspanel; |
| | | |
| | | import java.util.Set; |
| | | |
| | | import org.opends.quicksetup.util.Utils; |
| | | |
| | | /** |
| | |
| | | public class DatabaseDescriptor |
| | | { |
| | | private String backendID; |
| | | private String baseDn; |
| | | private Set<BaseDNDescriptor> baseDns; |
| | | private int entries; |
| | | |
| | | /** |
| | | * Constructor for this class. |
| | | * @param backendID the backend ID of the Database. |
| | | * @param baseDn the base DN associated with the Database. |
| | | * @param baseDns the base DNs associated with the Database. |
| | | * @param entries the number of entries in the Database. |
| | | */ |
| | | public DatabaseDescriptor(String backendID, String baseDn, int entries) |
| | | public DatabaseDescriptor(String backendID, Set<BaseDNDescriptor> baseDns, |
| | | int entries) |
| | | { |
| | | this.backendID = backendID; |
| | | this.baseDn = baseDn; |
| | | this.baseDns = baseDns; |
| | | this.entries = entries; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Return the base DN associated with the database. |
| | | * @return the base DN associated with the database. |
| | | * Returns the Base DN objects associated with the database. |
| | | * @return the Base DN objects associated with the database. |
| | | */ |
| | | public String getBaseDn() |
| | | public Set<BaseDNDescriptor> getBaseDns() |
| | | { |
| | | return baseDn; |
| | | return baseDns; |
| | | } |
| | | |
| | | /** |
| | |
| | | { |
| | | DatabaseDescriptor desc = (DatabaseDescriptor)v; |
| | | equals = getBackendID().equals(desc.getBackendID()) && |
| | | Utils.areDnsEqual(getBaseDn(), desc.getBaseDn()) && |
| | | (getEntries() == desc.getEntries()); |
| | | |
| | | if (equals) |
| | | { |
| | | for (BaseDNDescriptor baseDn1 : baseDns) |
| | | { |
| | | boolean found = false; |
| | | for (BaseDNDescriptor baseDn2 : desc.getBaseDns()) |
| | | { |
| | | found = Utils.areDnsEqual(baseDn1.getDn(), |
| | | baseDn2.getDn()); |
| | | if (found) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | if (!found) |
| | | { |
| | | equals = false; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | |
| | | */ |
| | | public int hashCode() |
| | | { |
| | | return (getBackendID() + getBaseDn() + getEntries()).hashCode(); |
| | | StringBuilder buf = new StringBuilder(); |
| | | for (BaseDNDescriptor rep: getBaseDns()) |
| | | { |
| | | buf.append(rep.getDn()); |
| | | } |
| | | return (getBackendID() + buf.toString() + getEntries()).hashCode(); |
| | | } |
| | | } |
| | |
| | | import java.io.File; |
| | | import java.io.FileReader; |
| | | import java.util.ArrayList; |
| | | import java.util.HashSet; |
| | | import java.util.Iterator; |
| | | import java.util.Set; |
| | | import java.util.TreeSet; |
| | |
| | | else |
| | | { |
| | | DatabasesTableModel databasesTableModel = new DatabasesTableModel(); |
| | | databasesTableModel.setData(desc.getDatabases()); |
| | | Set<BaseDNDescriptor> replicas = new HashSet<BaseDNDescriptor>(); |
| | | Set<DatabaseDescriptor> dbs = desc.getDatabases(); |
| | | for (DatabaseDescriptor db: dbs) |
| | | { |
| | | replicas.addAll(db.getBaseDns()); |
| | | } |
| | | databasesTableModel.setData(replicas); |
| | | |
| | | writeTableModel(databasesTableModel, desc); |
| | | writeDatabasesTableModel(databasesTableModel, desc); |
| | | } |
| | | } |
| | | |
| | |
| | | return getMsg("not-available-label", false); |
| | | } |
| | | |
| | | /** |
| | | * Writes the contents of the provided table model simulating a table layout |
| | | * using text. |
| | | * @param tableModel the TableModel. |
| | | * @param desc the Server Status descriptor. |
| | | */ |
| | | private void writeTableModel(TableModel tableModel, |
| | | ServerStatusDescriptor desc) |
| | | { |
| | |
| | | totalWidth += maxWidths[i]; |
| | | } |
| | | |
| | | StringBuffer headerLine = new StringBuffer(); |
| | | StringBuilder headerLine = new StringBuilder(); |
| | | for (int i=0; i<maxWidths.length; i++) |
| | | { |
| | | String header = tableModel.getColumnName(i); |
| | |
| | | } |
| | | } |
| | | System.out.println(wrap(headerLine.toString())); |
| | | StringBuffer t = new StringBuffer(); |
| | | StringBuilder t = new StringBuilder(); |
| | | for (int i=0; i<headerLine.length(); i++) |
| | | { |
| | | t.append("="); |
| | |
| | | |
| | | for (int i=0; i<tableModel.getRowCount(); i++) |
| | | { |
| | | StringBuffer line = new StringBuffer(); |
| | | StringBuilder line = new StringBuilder(); |
| | | for (int j=0; j<tableModel.getColumnCount(); j++) |
| | | { |
| | | int extra = maxWidths[j]; |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Writes the contents of the provided database table model. Every base DN |
| | | * is written in a block containing pairs of labels and values. |
| | | * @param tableModel the TableModel. |
| | | * @param desc the Server Status descriptor. |
| | | */ |
| | | private void writeDatabasesTableModel(DatabasesTableModel tableModel, |
| | | ServerStatusDescriptor desc) |
| | | { |
| | | boolean isRunning = |
| | | desc.getStatus() == ServerStatusDescriptor.ServerStatus.STARTED; |
| | | |
| | | int labelWidth = 0; |
| | | String[] labels = new String[tableModel.getColumnCount()]; |
| | | for (int i=0; i<tableModel.getColumnCount(); i++) |
| | | { |
| | | String header; |
| | | if (i == 5) |
| | | { |
| | | header = getMsg("age-of-oldest-missing-change-column-cli", false); |
| | | } |
| | | else |
| | | { |
| | | header = tableModel.getColumnName(i); |
| | | } |
| | | labels[i] = header+":"; |
| | | labelWidth = Math.max(labelWidth, labels[i].length()); |
| | | } |
| | | |
| | | String synchronizedLabel = getMsg("suffix-synchronized-label", false); |
| | | for (int i=0; i<tableModel.getRowCount(); i++) |
| | | { |
| | | if (i > 0) |
| | | { |
| | | System.out.println(); |
| | | } |
| | | for (int j=0; j<tableModel.getColumnCount(); j++) |
| | | { |
| | | String value; |
| | | Object v = tableModel.getValueAt(i, j); |
| | | if (v != null) |
| | | { |
| | | if (v instanceof String) |
| | | { |
| | | value = (String)v; |
| | | } |
| | | else if (v instanceof Integer) |
| | | { |
| | | int nEntries = ((Integer)v).intValue(); |
| | | if (nEntries >= 0) |
| | | { |
| | | value = String.valueOf(nEntries); |
| | | } |
| | | else |
| | | { |
| | | if (!isRunning) |
| | | { |
| | | value = getNotAvailableBecauseServerIsDownText(); |
| | | } |
| | | if (!desc.isAuthenticated()) |
| | | { |
| | | value = getNotAvailableBecauseAuthenticationIsRequiredText(); |
| | | } |
| | | else |
| | | { |
| | | value = getNotAvailableText(); |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | throw new IllegalStateException("Unknown object type: "+v); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | value = ""; |
| | | } |
| | | |
| | | if (value.equals(getNotAvailableText())) |
| | | { |
| | | if (!isRunning) |
| | | { |
| | | value = getNotAvailableBecauseServerIsDownText(); |
| | | } |
| | | if (!desc.isAuthenticated()) |
| | | { |
| | | value = getNotAvailableBecauseAuthenticationIsRequiredText(); |
| | | } |
| | | } |
| | | |
| | | boolean doWrite = true; |
| | | if ((j == 4) || (j == 5)) |
| | | { |
| | | // If the suffix is not replicated we do not have to display these |
| | | // lines. |
| | | if (!synchronizedLabel.equals(tableModel.getValueAt(i, 3))) |
| | | { |
| | | doWrite = false; |
| | | } |
| | | } |
| | | if (doWrite) |
| | | { |
| | | writeLabelValue(labels[j], value, labelWidth); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void writeLabelValue(String label, String value, int maxLabelWidth) |
| | | { |
| | | StringBuffer buf = new StringBuffer(); |
| | | StringBuilder buf = new StringBuilder(); |
| | | buf.append(label); |
| | | |
| | | int extra = maxLabelWidth - label.length(); |
| | |
| | | String centered; |
| | | if (text.length() <= Utils.getCommandLineMaxLineWidth() - 8) |
| | | { |
| | | StringBuffer buf = new StringBuffer(); |
| | | StringBuilder buf = new StringBuilder(); |
| | | int extra = Math.min(10, |
| | | (Utils.getCommandLineMaxLineWidth() - 8 - text.length()) / 2); |
| | | for (int i=0; i<extra; i++) |
| | |
| | | String line = reader.readLine(); |
| | | while (line != null) |
| | | { |
| | | StringBuffer buf = new StringBuffer(); |
| | | StringBuilder buf = new StringBuilder(); |
| | | if (!isFirstLine) |
| | | { |
| | | buf.append(formatter.getLineBreak()); |
| | |
| | | * |
| | | * This code also assumes that if the call to SplashWindow.main worked (and |
| | | * the splash screen was displayed) we will never get out of it (we will call |
| | | * a System.exit() when we close the graphical uninstall dialog). |
| | | * a System.exit() when we close the graphical status dialog). |
| | | * |
| | | * @params String[] args the arguments used to call the SplashWindow main |
| | | * method |
| | |
| | | backendid-column=Backend ID |
| | | basedn-column=Base DN |
| | | number-entries-column=Entries |
| | | synchronized-column=Synchronization |
| | | missing-changes-column=Missing Changes |
| | | age-of-oldest-missing-change-column=<html>Age of Oldest<br>Missing \ |
| | | Change (hh:mm:ss) |
| | | age-of-oldest-missing-change-column-cli=Age of Oldest Missing Change (hh:mm:ss) |
| | | enabled-label=Enabled |
| | | disabled-label=Disabled |
| | | unknown-label=-- |
| | | not-applicable-label=-- |
| | | ldap-protocol-label=LDAP |
| | | ldaps-protocol-label=LDAPS |
| | | jmx-protocol-label=JMX |
| | |
| | | This could be caused because there is not an enabled LDAP port to retrieve \ |
| | | monitoring information or because you do not have read rights on the \ |
| | | configuration file. |
| | | number-entries-multiple-suffixes-in-db={0} (for all base DNs in {1}) |
| | | error-reading-config-ldap=Error reading data from server. Try \ |
| | | re-authenticating.\nDetails: {0} |
| | | no-dbs-found=-No LDAP Databases Found- |
| | | no-listeners-found=-No Listener Ports Found- |
| | | suffix-synchronized-label=Enabled |
| | | suffix-not-synchronized-label=Disabled |
| | | |
| | | # |
| | | # Progress Dialog |
| | |
| | | login-pwd-label=Administrative User Password: |
| | | login-pwd-tooltip=Enter the password of the \ |
| | | Administrative User account that will used to retrieve monitoring information |
| | | ok-button-label=OK |
| | | login-dialog-server-not-running-msg=The Directory Server is not running. \ |
| | | Click OK to continue to the Status Panel. |
| | | login-dialog-server-not-running-title=Directory Server not Running |
| | |
| | | |
| | | import javax.swing.table.AbstractTableModel; |
| | | |
| | | import org.opends.statuspanel.DatabaseDescriptor; |
| | | import org.opends.quicksetup.ui.SortableTableModel; |
| | | import org.opends.statuspanel.BaseDNDescriptor; |
| | | import org.opends.statuspanel.i18n.ResourceProvider; |
| | | |
| | | /** |
| | |
| | | * |
| | | */ |
| | | public class DatabasesTableModel extends AbstractTableModel |
| | | implements SortableTableModel, Comparator<DatabaseDescriptor> |
| | | implements SortableTableModel, Comparator<BaseDNDescriptor> |
| | | { |
| | | private static final long serialVersionUID = -5650762484071136983L; |
| | | private HashSet<DatabaseDescriptor> data = new HashSet<DatabaseDescriptor>(); |
| | | private ArrayList<DatabaseDescriptor> dataArray = |
| | | new ArrayList<DatabaseDescriptor>(); |
| | | private HashSet<BaseDNDescriptor> data = new HashSet<BaseDNDescriptor>(); |
| | | private ArrayList<BaseDNDescriptor> dataArray = |
| | | new ArrayList<BaseDNDescriptor>(); |
| | | private final String[] COLUMN_NAMES = { |
| | | getMsg("backendid-column"), |
| | | getMsg("basedn-column"), |
| | | getMsg("number-entries-column") |
| | | getMsg("backendid-column"), |
| | | getMsg("number-entries-column"), |
| | | getMsg("synchronized-column"), |
| | | getMsg("missing-changes-column"), |
| | | getMsg("age-of-oldest-missing-change-column") |
| | | }; |
| | | private int sortColumn = 0; |
| | | private boolean sortAscending = true; |
| | |
| | | * Sets the data for this table model. |
| | | * @param newData the data for this table model. |
| | | */ |
| | | public void setData(Set<DatabaseDescriptor> newData) |
| | | public void setData(Set<BaseDNDescriptor> newData) |
| | | { |
| | | if (!newData.equals(data)) |
| | | { |
| | | data.clear(); |
| | | data.addAll(newData); |
| | | dataArray.clear(); |
| | | TreeSet<DatabaseDescriptor> sortedSet = |
| | | new TreeSet<DatabaseDescriptor>(this); |
| | | TreeSet<BaseDNDescriptor> sortedSet = |
| | | new TreeSet<BaseDNDescriptor>(this); |
| | | sortedSet.addAll(data); |
| | | dataArray.addAll(sortedSet); |
| | | fireTableDataChanged(); |
| | |
| | | public void forceResort() |
| | | { |
| | | dataArray.clear(); |
| | | TreeSet<DatabaseDescriptor> sortedSet = |
| | | new TreeSet<DatabaseDescriptor>(this); |
| | | TreeSet<BaseDNDescriptor> sortedSet = |
| | | new TreeSet<BaseDNDescriptor>(this); |
| | | sortedSet.addAll(data); |
| | | dataArray.addAll(sortedSet); |
| | | fireTableDataChanged(); |
| | |
| | | |
| | | /** |
| | | * Comparable implementation. |
| | | * @param desc1 the first database descriptor to compare. |
| | | * @param desc2 the second database descriptor to compare. |
| | | * @param desc1 the first replica descriptor to compare. |
| | | * @param desc2 the second replica descriptor to compare. |
| | | * @return 1 if according to the sorting options set by the user the first |
| | | * database descriptor must be put before the second descriptor, 0 if they |
| | | * are equivalent in terms of sorting and -1 if the second descriptor must |
| | | * be put before the first descriptor. |
| | | */ |
| | | public int compare(DatabaseDescriptor desc1, DatabaseDescriptor desc2) |
| | | public int compare(BaseDNDescriptor desc1, BaseDNDescriptor desc2) |
| | | { |
| | | int result = 0; |
| | | if (sortColumn == 0) |
| | | { |
| | | result = desc1.getBackendID().compareTo(desc2.getBackendID()); |
| | | result = compareDns(desc1, desc2); |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = desc1.getBaseDn().compareTo(desc2.getBaseDn()); |
| | | result = compareBackendIDs(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | if (desc1.getEntries() > desc2.getEntries()) |
| | | { |
| | | result = 1; |
| | | } |
| | | else if (desc1.getEntries() < desc2.getEntries()) |
| | | { |
| | | result = -1; |
| | | } |
| | | } |
| | | } |
| | | else if (sortColumn == 1) |
| | | { |
| | | result = desc1.getBaseDn().compareTo(desc2.getBaseDn()); |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = desc1.getBackendID().compareTo(desc2.getBackendID()); |
| | | result = compareEntries(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | if (desc1.getEntries() > desc2.getEntries()) |
| | | { |
| | | result = 1; |
| | | } |
| | | else if (desc1.getEntries() < desc2.getEntries()) |
| | | { |
| | | result = -1; |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (desc1.getEntries() > desc2.getEntries()) |
| | | { |
| | | result = 1; |
| | | } |
| | | else if (desc1.getEntries() < desc2.getEntries()) |
| | | { |
| | | result = -1; |
| | | result = compareSync(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = desc1.getBackendID().compareTo(desc2.getBackendID()); |
| | | result = compareMissingChanges(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = desc1.getBaseDn().compareTo(desc2.getBaseDn()); |
| | | result = compareAgeOfOldestMissingChange(desc1, desc2); |
| | | } |
| | | } |
| | | |
| | | if (sortColumn == 1) |
| | | { |
| | | result = compareBackendIDs(desc1, desc2); |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareDns(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareEntries(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareSync(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareMissingChanges(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareAgeOfOldestMissingChange(desc1, desc2); |
| | | } |
| | | } |
| | | else if (sortColumn == 2) |
| | | { |
| | | result = compareEntries(desc1, desc2); |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareBackendIDs(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareDns(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareSync(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareMissingChanges(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareAgeOfOldestMissingChange(desc1, desc2); |
| | | } |
| | | } |
| | | else if (sortColumn == 3) |
| | | { |
| | | result = compareSync(desc1, desc2); |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareBackendIDs(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareDns(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareEntries(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareMissingChanges(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareAgeOfOldestMissingChange(desc1, desc2); |
| | | } |
| | | } |
| | | else if (sortColumn == 4) |
| | | { |
| | | result = compareMissingChanges(desc1, desc2); |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareBackendIDs(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareDns(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareEntries(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareSync(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareAgeOfOldestMissingChange(desc1, desc2); |
| | | } |
| | | } |
| | | else if (sortColumn == 5) |
| | | { |
| | | result = compareAgeOfOldestMissingChange(desc1, desc2); |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareBackendIDs(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareDns(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareEntries(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareSync(desc1, desc2); |
| | | } |
| | | |
| | | if (result == 0) |
| | | { |
| | | result = compareMissingChanges(desc1, desc2); |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | public int getColumnCount() |
| | | { |
| | | return 3; |
| | | return 6; |
| | | } |
| | | |
| | | /** |
| | |
| | | public Object getValueAt(int row, int col) |
| | | { |
| | | Object v; |
| | | DatabaseDescriptor desc = dataArray.get(row); |
| | | BaseDNDescriptor desc = dataArray.get(row); |
| | | if (col == 0) |
| | | { |
| | | v = desc.getBackendID(); |
| | | v = desc.getDn(); |
| | | } |
| | | else if (col == 1) |
| | | { |
| | | v = desc.getBaseDn(); |
| | | v = desc.getDatabase().getBackendID(); |
| | | } |
| | | else if (col == 2) |
| | | { |
| | | v = getValueForEntries(desc); |
| | | } |
| | | else if (col == 3) |
| | | { |
| | | v = getStringForSyncState(desc); |
| | | } |
| | | else if (col == 4) |
| | | { |
| | | v = getValueForMissingChanges(desc); |
| | | } |
| | | else if (col == 5) |
| | | { |
| | | v = getValueForOldestMissingChange(desc); |
| | | } |
| | | else |
| | | { |
| | | v = new Integer(desc.getEntries()); |
| | | throw new IllegalArgumentException("Invalid col number: "+col); |
| | | } |
| | | return v; |
| | | } |
| | |
| | | this.sortColumn = sortColumn; |
| | | } |
| | | |
| | | /* |
| | | * Several comparison methods to be able to sort the table model. |
| | | */ |
| | | private int compareBackendIDs(BaseDNDescriptor desc1, BaseDNDescriptor desc2) |
| | | { |
| | | return desc1.getDatabase().getBackendID().compareTo( |
| | | desc2.getDatabase().getBackendID()); |
| | | } |
| | | |
| | | private int compareEntries(BaseDNDescriptor desc1, BaseDNDescriptor desc2) |
| | | { |
| | | int n1 = desc1.getDatabase().getEntries(); |
| | | int n2 = desc2.getDatabase().getEntries(); |
| | | return compareIntegers(n1, n2); |
| | | } |
| | | |
| | | private int compareIntegers(int n1, int n2) |
| | | { |
| | | if (n1 == n2) |
| | | { |
| | | return 0; |
| | | } |
| | | if (n1 > n2) |
| | | { |
| | | return 1; |
| | | } |
| | | return -1; |
| | | } |
| | | |
| | | private int compareDns(BaseDNDescriptor desc1, BaseDNDescriptor desc2) |
| | | { |
| | | return desc1.getDn().compareTo(desc2.getDn()); |
| | | } |
| | | |
| | | private int compareSync(BaseDNDescriptor desc1, BaseDNDescriptor desc2) |
| | | { |
| | | return (String.valueOf(desc1.getType()).compareTo( |
| | | String.valueOf(desc2.getType()))); |
| | | } |
| | | |
| | | private int compareMissingChanges(BaseDNDescriptor desc1, |
| | | BaseDNDescriptor desc2) |
| | | { |
| | | return compareIntegers(desc1.getMissingChanges(), |
| | | desc2.getMissingChanges()); |
| | | } |
| | | |
| | | private int compareAgeOfOldestMissingChange(BaseDNDescriptor desc1, |
| | | BaseDNDescriptor desc2) |
| | | { |
| | | return compareIntegers(desc1.getAgeOfOldestMissingChange(), |
| | | desc2.getAgeOfOldestMissingChange()); |
| | | } |
| | | |
| | | /** |
| | | * Returns the Object describing the number of entries of a given Base DN. |
| | | * The Object will be an Integer unless the database of the Base DN contains |
| | | * several Base DNs. In this case we return a String. |
| | | * @param rep the Base DN object to handle. |
| | | * @return the Object describing the number of entries of a given Base DN. |
| | | */ |
| | | private Object getValueForEntries(BaseDNDescriptor rep) |
| | | { |
| | | Object v; |
| | | int nEntries = rep.getDatabase().getEntries(); |
| | | if ((rep.getDatabase().getBaseDns().size() > 1) && |
| | | (nEntries >= 0)) |
| | | { |
| | | String[] args = { |
| | | String.valueOf(nEntries), |
| | | rep.getDatabase().getBackendID() |
| | | }; |
| | | v = getMsg("number-entries-multiple-suffixes-in-db", args); |
| | | } |
| | | else |
| | | { |
| | | v = new Integer(nEntries); |
| | | } |
| | | return v; |
| | | } |
| | | |
| | | /** |
| | | * Returns the Object describing the number of missing changes of a given Base |
| | | * DN. The Object will be a String unless the base DN is |
| | | * synchronized and we could not find a valid value (in this case we return |
| | | * an Integer with the invalid value). |
| | | * @param rep the Base DN object to handle. |
| | | * @return the Object describing the number of missing changes of |
| | | * a given Base DN. |
| | | */ |
| | | private Object getValueForMissingChanges(BaseDNDescriptor rep) |
| | | { |
| | | Object v; |
| | | if (rep.getType() == BaseDNDescriptor.Type.SYNCHRONIZED) |
| | | { |
| | | v = new Integer(rep.getMissingChanges()); |
| | | } |
| | | else |
| | | { |
| | | v = getMsg("not-applicable-label"); |
| | | } |
| | | return v; |
| | | } |
| | | |
| | | /** |
| | | * Returns the Object describing the age of oldest missing change of |
| | | * a given Base DN. The Object will be a String unless the base DN is |
| | | * synchronized and we could not find a valid value (in this case we return |
| | | * an Integer with the invalid value). |
| | | * @param rep the Base DN object to handle. |
| | | * @return the Object describing the age of oldest missing change of |
| | | * a given Base DN. |
| | | */ |
| | | private Object getValueForOldestMissingChange(BaseDNDescriptor rep) |
| | | { |
| | | Object v; |
| | | if (rep.getType() == BaseDNDescriptor.Type.SYNCHRONIZED) |
| | | { |
| | | int age = rep.getAgeOfOldestMissingChange(); |
| | | if (age >= 0) |
| | | { |
| | | int remainingSeconds = age % 60; |
| | | int minutes = age / 60; |
| | | int remainingMinutes = minutes % 60; |
| | | int hours = minutes / 60; |
| | | |
| | | String sMinutes = (remainingMinutes>=10)? |
| | | String.valueOf(remainingMinutes) : "0"+remainingMinutes; |
| | | |
| | | String sSeconds = (remainingSeconds>=10)? |
| | | String.valueOf(remainingSeconds) : "0"+remainingSeconds; |
| | | |
| | | String sHours = (hours>=10)?String.valueOf(hours):"0"+hours; |
| | | |
| | | v = sHours+":"+sMinutes+":"+sSeconds; |
| | | } |
| | | else |
| | | { |
| | | v = new Integer(age); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | v = getMsg("not-applicable-label"); |
| | | } |
| | | return v; |
| | | } |
| | | |
| | | /** |
| | | * Returns the localized String describing the synchronization state of |
| | | * a given Base DN. |
| | | * @param rep the Base DN object to handle. |
| | | * @return the localized String describing the synchronization state of |
| | | * a given Base DN. |
| | | */ |
| | | private String getStringForSyncState(BaseDNDescriptor rep) |
| | | { |
| | | String s; |
| | | if (rep.getType() == BaseDNDescriptor.Type.SYNCHRONIZED) |
| | | { |
| | | s = getMsg("suffix-synchronized-label"); |
| | | } |
| | | else |
| | | { |
| | | s = getMsg("suffix-not-synchronized-label"); |
| | | } |
| | | return s; |
| | | } |
| | | |
| | | /** |
| | | * The following three methods are just commodity methods to get localized |
| | |
| | | return getI18n().getMsg(key); |
| | | } |
| | | |
| | | private String getMsg(String key, String[] args) |
| | | { |
| | | return getI18n().getMsg(key, args); |
| | | } |
| | | |
| | | private ResourceProvider getI18n() |
| | | { |
| | | return ResourceProvider.getInstance(); |
| | |
| | | |
| | | import javax.swing.table.AbstractTableModel; |
| | | |
| | | import org.opends.quicksetup.ui.SortableTableModel; |
| | | import org.opends.statuspanel.ListenerDescriptor; |
| | | import org.opends.statuspanel.i18n.ResourceProvider; |
| | | |
| | |
| | | if (ldapUrl != null) |
| | | { |
| | | ctx = Utils.createLdapContext(ldapUrl, tfDn.getText(), |
| | | tfPwd.getText(), 3000, null); |
| | | tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null); |
| | | } |
| | | else |
| | | { |
| | |
| | | import java.awt.event.WindowEvent; |
| | | import java.io.File; |
| | | import java.util.HashSet; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.Set; |
| | | import java.util.TreeSet; |
| | | |
| | |
| | | import javax.swing.PopupFactory; |
| | | import javax.swing.SwingConstants; |
| | | import javax.swing.ToolTipManager; |
| | | import javax.swing.table.JTableHeader; |
| | | import javax.swing.table.TableCellRenderer; |
| | | import javax.swing.table.TableColumn; |
| | | import javax.swing.table.TableColumnModel; |
| | | |
| | | import org.opends.quicksetup.event.MinimumSizeComponentListener; |
| | | import org.opends.quicksetup.ui.UIFactory; |
| | | import org.opends.quicksetup.util.HtmlProgressMessageFormatter; |
| | | import org.opends.quicksetup.util.Utils; |
| | | |
| | | import org.opends.statuspanel.DatabaseDescriptor; |
| | | import org.opends.statuspanel.BaseDNDescriptor; |
| | | import org.opends.statuspanel.ServerStatusDescriptor; |
| | | import org.opends.statuspanel.event.StatusPanelButtonListener; |
| | | import org.opends.statuspanel.i18n.ResourceProvider; |
| | |
| | | int minWidth = Math.min(packedMinWidth, MAXIMAL_WIDTH); |
| | | int minHeight = Math.min(packedMinHeight, MAXIMAL_HEIGHT); |
| | | |
| | | |
| | | addComponentListener(new MinimumSizeComponentListener(this, |
| | | minWidth, minHeight)); |
| | | if ((minWidth != packedMinWidth) || (minHeight != packedMinHeight)) |
| | |
| | | p.add(createSubsectionTitle(getMsg("listeners-title")), gbc); |
| | | |
| | | listenersTableModel = new ListenersTableModel(); |
| | | listenersTable = createTable(listenersTableModel, |
| | | listenersTable = UIFactory.makeSortableTable(listenersTableModel, |
| | | new ListenersCellRenderer(), |
| | | new HeaderRenderer()); |
| | | UIFactory.makeHeaderRenderer()); |
| | | |
| | | gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD; |
| | | p.add(listenersTable.getTableHeader(), gbc); |
| | |
| | | p.add(createSubsectionTitle(getMsg("databases-title")), gbc); |
| | | |
| | | dbTableModel = new DatabasesTableModel(); |
| | | dbTable = createTable(dbTableModel, new DatabasesCellRenderer(), |
| | | new HeaderRenderer()); |
| | | dbTable = UIFactory.makeSortableTable(dbTableModel, |
| | | new DatabasesCellRenderer(), |
| | | UIFactory.makeHeaderRenderer()); |
| | | toolTipManager.registerComponent(dbTable); |
| | | |
| | | gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD; |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns a table created with the provided model and renderers. |
| | | * @param tableModel the table model. |
| | | * @param renderer the cell renderer. |
| | | * @param headerRenderer the header renderer. |
| | | * @return a table created with the provided model and renderers. |
| | | */ |
| | | private JTable createTable(final SortableTableModel tableModel, |
| | | TableCellRenderer renderer, |
| | | TableCellRenderer headerRenderer) |
| | | { |
| | | final JTable table = new JTable(tableModel); |
| | | table.setShowGrid(true); |
| | | table.setGridColor(UIFactory.PANEL_BORDER_COLOR); |
| | | table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); |
| | | table.setBackground(UIFactory.CURRENT_STEP_PANEL_BACKGROUND); |
| | | table.getTableHeader().setBackground(UIFactory.DEFAULT_BACKGROUND); |
| | | table.setRowMargin(0); |
| | | |
| | | for (int i=0; i<tableModel.getColumnCount(); i++) |
| | | { |
| | | TableColumn col = table.getColumn(table.getColumnName(i)); |
| | | col.setCellRenderer(renderer); |
| | | col.setHeaderRenderer(headerRenderer); |
| | | } |
| | | MouseAdapter listMouseListener = new MouseAdapter() { |
| | | public void mouseClicked(MouseEvent e) { |
| | | TableColumnModel columnModel = table.getColumnModel(); |
| | | int viewColumn = columnModel.getColumnIndexAtX(e.getX()); |
| | | int sortedBy = table.convertColumnIndexToModel(viewColumn); |
| | | if (e.getClickCount() == 1 && sortedBy != -1) { |
| | | tableModel.setSortAscending(!tableModel.isSortAscending()); |
| | | tableModel.setSortColumn(sortedBy); |
| | | tableModel.forceResort(); |
| | | } |
| | | } |
| | | }; |
| | | table.getTableHeader().addMouseListener(listMouseListener); |
| | | return table; |
| | | } |
| | | |
| | | /** |
| | | * Updates the status contents displaying with what is specified in the |
| | | * provided ServerStatusDescriptor object. |
| | | * This method must be called from the event thread. |
| | |
| | | } |
| | | |
| | | setTextValue(lAdministrativeUsers,"<html>"+ |
| | | Utils.getStringFromCollection(ordered, "<br>")); |
| | | UIFactory.applyFontToHtml( |
| | | Utils.getStringFromCollection(ordered, "<br>"), |
| | | UIFactory.READ_ONLY_FONT)); |
| | | } |
| | | else |
| | | { |
| | |
| | | */ |
| | | private void updateDatabaseContents(ServerStatusDescriptor desc) |
| | | { |
| | | dbTableModel.setData(desc.getDatabases()); |
| | | Set<BaseDNDescriptor> replicas = new HashSet<BaseDNDescriptor>(); |
| | | Set<DatabaseDescriptor> dbs = desc.getDatabases(); |
| | | for (DatabaseDescriptor db: dbs) |
| | | { |
| | | replicas.addAll(db.getBaseDns()); |
| | | } |
| | | dbTableModel.setData(replicas); |
| | | |
| | | if (dbTableModel.getRowCount() == 0) |
| | | { |
| | |
| | | dbTable.setVisible(true); |
| | | dbTable.getTableHeader().setVisible(true); |
| | | lDbTableEmpty.setVisible(false); |
| | | updateTableSizes(dbTable); |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Updates the size of the table rows according to the size of the |
| | | * rendered component. |
| | | * @param table the table to handle. |
| | | */ |
| | | private void updateTableSizes(JTable table) |
| | | { |
| | | updateTableColumnWidth(table); |
| | | updateTableRowHeight(table); |
| | | |
| | | /* |
| | | int totalWidth = 0; |
| | | int colMargin = table.getColumnModel().getColumnMargin(); |
| | | |
| | | int totalHeight = 0; |
| | | |
| | | TableColumn tcol = table.getColumnModel().getColumn(0); |
| | | TableCellRenderer renderer = tcol.getHeaderRenderer(); |
| | | Component comp = renderer.getTableCellRendererComponent(table, |
| | | table.getModel().getColumnName(0), false, false, 0, 0); |
| | | totalHeight = (int)comp.getPreferredSize().getHeight(); |
| | | for (int row=0; row<table.getRowCount(); row++) |
| | | { |
| | | totalHeight += table.getRowHeight(row); |
| | | } |
| | | |
| | | for (int col=0; col<table.getColumnCount(); col++) |
| | | { |
| | | tcol = table.getColumnModel().getColumn(col); |
| | | totalWidth += tcol.getPreferredWidth() + colMargin; |
| | | } |
| | | |
| | | table.setPreferredScrollableViewportSize( |
| | | new Dimension(totalWidth, totalHeight)); |
| | | */ |
| | | } |
| | | |
| | | /** |
| | | * Updates the height of the table rows according to the size of the |
| | | * rendered component. |
| | | * @param table the table to handle. |
| | | */ |
| | | private void updateTableRowHeight(JTable table) |
| | | { |
| | | int headerMaxHeight = 0; |
| | | |
| | | for (int col=0; col<table.getColumnCount(); col++) |
| | | { |
| | | TableColumn tcol = table.getColumnModel().getColumn(col); |
| | | TableCellRenderer renderer = tcol.getHeaderRenderer(); |
| | | Component comp = renderer.getTableCellRendererComponent(table, |
| | | table.getModel().getColumnName(col), false, false, 0, col); |
| | | int colHeight = (int)comp.getPreferredSize().getHeight(); |
| | | headerMaxHeight = Math.max(headerMaxHeight, colHeight); |
| | | } |
| | | JTableHeader header = table.getTableHeader(); |
| | | header.setPreferredSize(new Dimension( |
| | | (int)header.getPreferredSize().getWidth(), |
| | | headerMaxHeight)); |
| | | |
| | | for (int row=0; row<table.getRowCount(); row++) |
| | | { |
| | | int rowMaxHeight = table.getRowHeight(); |
| | | for (int col=0; col<table.getColumnCount(); col++) |
| | | { |
| | | TableCellRenderer renderer = table.getCellRenderer(row, col); |
| | | Component comp = table.prepareRenderer(renderer, row, col); |
| | | int colHeight = (int)comp.getPreferredSize().getHeight(); |
| | | rowMaxHeight = Math.max(rowMaxHeight, colHeight); |
| | | } |
| | | table.setRowHeight(row, rowMaxHeight); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Updates the height of the table columns according to the size of the |
| | | * rendered component. |
| | | * @param table the table to handle. |
| | | */ |
| | | private void updateTableColumnWidth(JTable table) |
| | | { |
| | | |
| | | int margin = table.getIntercellSpacing().width; |
| | | for (int col=0; col<table.getColumnCount(); col++) |
| | | { |
| | | int colMaxWidth; |
| | | TableColumn tcol = table.getColumnModel().getColumn(col); |
| | | TableCellRenderer renderer = tcol.getHeaderRenderer(); |
| | | Component comp = renderer.getTableCellRendererComponent(table, |
| | | table.getModel().getColumnName(col), false, false, 0, col); |
| | | colMaxWidth = (int)comp.getPreferredSize().getWidth(); |
| | | for (int row=0; row<table.getRowCount(); row++) |
| | | { |
| | | renderer = table.getCellRenderer(row, col); |
| | | comp = table.prepareRenderer(renderer, row, col); |
| | | int colWidth = (int)comp.getPreferredSize().getWidth() + (2 * margin); |
| | | colMaxWidth = Math.max(colMaxWidth, colWidth); |
| | | } |
| | | tcol.setPreferredWidth(colMaxWidth); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Method written for testing purposes. |
| | | * @param args the arguments to be passed to the test program. |
| | | */ |
| | |
| | | { |
| | | setTextValue(this, (String)value); |
| | | } |
| | | else if (value instanceof Set) |
| | | { |
| | | LinkedHashSet<String> baseDns = new LinkedHashSet<String>(); |
| | | for (Object v : (Set)value) |
| | | { |
| | | baseDns.add((String)v); |
| | | } |
| | | setTextValue(this, "<html>" + |
| | | UIFactory.applyFontToHtml(Utils.getStringFromCollection( |
| | | baseDns, "<br>"), |
| | | UIFactory.SECONDARY_FIELD_VALID_FONT)); |
| | | } |
| | | else |
| | | { |
| | | /* Is the number of entries: check if it is available or not */ |
| | |
| | | return this; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Class used to render the table headers. |
| | | */ |
| | | class HeaderRenderer extends JLabel implements TableCellRenderer |
| | | { |
| | | private static final long serialVersionUID = -8604332267021523835L; |
| | | |
| | | /** |
| | | * Default constructor. |
| | | */ |
| | | public HeaderRenderer() |
| | | { |
| | | super(); |
| | | UIFactory.setTextStyle(this, UIFactory.TextStyle.PRIMARY_FIELD_VALID); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Component getTableCellRendererComponent(JTable table, Object value, |
| | | boolean isSelected, boolean hasFocus, int row, int column) { |
| | | setTextValue(this, (String)value); |
| | | if (column == 0) |
| | | { |
| | | setBorder(BorderFactory.createCompoundBorder( |
| | | BorderFactory.createMatteBorder(1, 1, 1, 1, |
| | | UIFactory.PANEL_BORDER_COLOR), |
| | | BorderFactory.createEmptyBorder(4, 4, 4, 4))); |
| | | } |
| | | else |
| | | { |
| | | setBorder(BorderFactory.createCompoundBorder( |
| | | BorderFactory.createMatteBorder(1, 0, 1, 1, |
| | | UIFactory.PANEL_BORDER_COLOR), |
| | | BorderFactory.createEmptyBorder(4, 4, 4, 4))); |
| | | } |
| | | return this; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |