/* * 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 legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * 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 legal-notices/CDDLv1_0.txt. * 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 * * * Copyright 2007-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2015 ForgeRock AS */ package org.opends.server.tools.status; import static com.forgerock.opendj.cli.ArgumentConstants.*; import static com.forgerock.opendj.cli.CliMessages.*; import static com.forgerock.opendj.cli.Utils.*; import static org.forgerock.opendj.ldap.LDAPConnectionFactory.*; import static org.forgerock.util.Utils.*; import static org.opends.messages.AdminToolMessages.*; import static org.opends.messages.QuickSetupMessages.INFO_ERROR_READING_SERVER_CONFIGURATION; import static org.opends.messages.QuickSetupMessages.INFO_NOT_AVAILABLE_LABEL; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.net.URI; import java.security.GeneralSecurityException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; import java.util.concurrent.TimeUnit; import javax.naming.AuthenticationException; import javax.naming.NamingException; import javax.naming.ldap.InitialLdapContext; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLException; import javax.net.ssl.TrustManager; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageBuilder; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.config.LDAPProfile; import org.forgerock.opendj.config.client.ManagementContext; import org.forgerock.opendj.config.client.ldap.LDAPManagementContext; import org.forgerock.opendj.config.server.ConfigException; import org.forgerock.opendj.ldap.AuthorizationException; import org.forgerock.opendj.ldap.Connection; import org.forgerock.opendj.ldap.LDAPConnectionFactory; import org.forgerock.opendj.ldap.LdapException; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.SSLContextBuilder; import org.forgerock.opendj.ldap.TrustManagers; import org.forgerock.util.Options; import org.opends.admin.ads.util.ApplicationTrustManager; import org.opends.guitools.controlpanel.datamodel.BackendDescriptor; import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor; import org.opends.guitools.controlpanel.datamodel.BaseDNTableModel; import org.opends.guitools.controlpanel.datamodel.ConfigReadException; import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor; import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerTableModel; import org.opends.guitools.controlpanel.datamodel.ConnectionProtocolPolicy; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; import org.opends.guitools.controlpanel.util.ControlPanelLog; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.server.admin.client.cli.SecureConnectionCliArgs; import org.opends.server.types.DN; import org.opends.server.types.InitializationException; import org.opends.server.types.NullOutputStream; import org.opends.server.types.OpenDsException; import org.opends.server.util.BuildVersion; import org.opends.server.util.StaticUtils; import org.opends.server.util.cli.LDAPConnectionConsoleInteraction; import com.forgerock.opendj.cli.ArgumentException; import com.forgerock.opendj.cli.CliConstants; import com.forgerock.opendj.cli.ClientException; import com.forgerock.opendj.cli.ConsoleApplication; import com.forgerock.opendj.cli.ReturnCode; import com.forgerock.opendj.cli.TableBuilder; import com.forgerock.opendj.cli.TextTablePrinter; /** * The class used to provide some CLI interface to display status. * This class basically is in charge of parsing the data provided by the * user in the command line. */ public class StatusCli extends ConsoleApplication { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); private boolean displayMustAuthenticateLegend; private boolean displayMustStartLegend; /** Prefix for log files. */ public static final String LOG_FILE_PREFIX = "opendj-status-"; /** Suffix for log files. */ public static final String LOG_FILE_SUFFIX = ".log"; private ApplicationTrustManager interactiveTrustManager; private boolean useInteractiveTrustManager; /** The argument parser. */ private StatusCliArgumentParser argParser; /** * Constructor for the status cli object. * * @param out * The print stream to use for standard output. * @param err * The print stream to use for standard error. * @param in * The input stream to use for standard input. */ public StatusCli(PrintStream out, PrintStream err, InputStream in) { super(out, err); } /** * The main method for the status CLI tool. * * @param args The command-line arguments provided to this program. */ public static void main(String[] args) { int retCode = mainCLI(args, true, System.out, System.err, System.in); if(retCode != 0) { System.exit(retCode); } } /** * Parses the provided command-line arguments and uses that information to * run the status tool. * * @param args the command-line arguments provided to this program. * * @return The return code. */ public static int mainCLI(String[] args) { return mainCLI(args, true, System.out, System.err, System.in); } /** * Parses the provided command-line arguments and uses that information to run * the status tool. * * @param args * The command-line arguments provided to this program. * @param initializeServer * Indicates whether to initialize the server. * @param outStream * The output stream to use for standard output, or {@code null} * if standard output is not needed. * @param errStream * The output stream to use for standard error, or {@code null} * if standard error is not needed. * @param inStream * The input stream to use for standard input. * @return The return code. */ public static int mainCLI(String[] args, boolean initializeServer, OutputStream outStream, OutputStream errStream, InputStream inStream) { PrintStream out = NullOutputStream.wrapOrNullStream(outStream); PrintStream err = NullOutputStream.wrapOrNullStream(errStream); try { ControlPanelLog.initLogFileHandler( File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX)); ControlPanelLog.initPackage("org.opends.server.tools.status"); } catch (Throwable t) { System.err.println("Unable to initialize log"); t.printStackTrace(); } final StatusCli statusCli = new StatusCli(out, err, inStream); return statusCli.execute(args); } /** * Parses the provided command-line arguments and uses that information to run * the status CLI. * * @param args * The command-line arguments provided to this program. * @return The return code of the process. */ public int execute(String[] args) { argParser = new StatusCliArgumentParser(StatusCli.class.getName()); try { argParser.initializeGlobalArguments(getOutputStream()); } catch (ArgumentException ae) { println(ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage())); return ReturnCode.CLIENT_SIDE_PARAM_ERROR.get(); } try { argParser.getSecureArgsList().initArgumentsWithConfiguration(); } catch (ConfigException ce) { // Ignore. } // Validate user provided data try { argParser.parseArguments(args); } catch (ArgumentException ae) { argParser.displayMessageAndUsageReference(getErrStream(), ERR_ERROR_PARSING_ARGS.get(ae.getMessage())); return ReturnCode.CLIENT_SIDE_PARAM_ERROR.get(); } // If we should just display usage or version information, // then print it and exit. if (argParser.usageOrVersionDisplayed()) { return ReturnCode.SUCCESS.get(); } // Checks the version - if upgrade required, the tool is unusable try { BuildVersion.checkVersionMismatch(); } catch (InitializationException e) { println(e.getMessageObject()); return 1; } int v = argParser.validateGlobalOptions(getErrorStream()); if (v != ReturnCode.SUCCESS.get()) { println(LocalizableMessage.raw(argParser.getUsage())); return v; } final ControlPanelInfo controlInfo = ControlPanelInfo.getInstance(); controlInfo.setTrustManager(getTrustManager()); controlInfo.setConnectTimeout(argParser.getConnectTimeout()); controlInfo.regenerateDescriptor(); if (controlInfo.getServerDescriptor().getStatus() == ServerDescriptor.ServerStatus.STARTED) { String bindDn = null; String bindPwd = null; ManagementContext mContext = null; // This is done because we do not need to ask the user about these // parameters. We force their presence in the // LDAPConnectionConsoleInteraction, this done, it will not prompt // the user for them. final SecureConnectionCliArgs secureArgsList = argParser.getSecureArgsList(); controlInfo.setConnectionPolicy(ConnectionProtocolPolicy.USE_ADMIN); int port = CliConstants.DEFAULT_ADMINISTRATION_CONNECTOR_PORT; controlInfo.setConnectionPolicy(ConnectionProtocolPolicy.USE_ADMIN); String ldapUrl = controlInfo.getURLToConnect(); try { final URI uri = new URI(ldapUrl); port = uri.getPort(); } catch (Throwable t) { logger.error(LocalizableMessage.raw("Error parsing url: " + ldapUrl)); } secureArgsList.hostNameArg.setPresent(true); secureArgsList.portArg.setPresent(true); secureArgsList.hostNameArg.addValue(secureArgsList.hostNameArg.getDefaultValue()); secureArgsList.portArg.addValue(Integer.toString(port)); // We already know if SSL or StartTLS can be used. If we cannot // use them we will not propose them in the connection parameters // and if none of them can be used we will just not ask for the // protocol to be used. final LDAPConnectionConsoleInteraction ci = new LDAPConnectionConsoleInteraction(this, argParser.getSecureArgsList()); try { ci.run(false); } catch (ArgumentException e) { argParser.displayMessageAndUsageReference(getErrStream(), e.getMessageObject()); return ReturnCode.CLIENT_SIDE_PARAM_ERROR.get(); } try { if (argParser.isInteractive()) { bindDn = ci.getBindDN(); bindPwd = ci.getBindPassword(); } else { bindDn = argParser.getBindDN(); bindPwd = argParser.getBindPassword(); } if (bindPwd != null && !bindPwd.isEmpty()) { mContext = getManagementContextFromConnection(ci); interactiveTrustManager = ci.getTrustManager(); controlInfo.setTrustManager(interactiveTrustManager); useInteractiveTrustManager = true; } } catch (ClientException e) { println(e.getMessageObject()); return ReturnCode.CLIENT_SIDE_PARAM_ERROR.get(); } finally { closeSilently(mContext); } if (mContext != null) { InitialLdapContext ctx = null; try { ctx = Utilities.getAdminDirContext(controlInfo, bindDn, bindPwd); controlInfo.setDirContext(ctx); controlInfo.regenerateDescriptor(); writeStatus(controlInfo); if (!controlInfo.getServerDescriptor().getExceptions().isEmpty()) { return ReturnCode.ERROR_INITIALIZING_SERVER.get(); } } catch (NamingException ne) { // This should not happen but this is useful information to // diagnose the error. println(); println(INFO_ERROR_READING_SERVER_CONFIGURATION.get(ne)); return ReturnCode.ERROR_INITIALIZING_SERVER.get(); } catch (ConfigReadException cre) { // This should not happen but this is useful information to // diagnose the error. println(); println(cre.getMessageObject()); return ReturnCode.ERROR_INITIALIZING_SERVER.get(); } finally { StaticUtils.close(ctx); } } else { // The user did not provide authentication: just display the // information we can get reading the config file. writeStatus(controlInfo); return ReturnCode.ERROR_USER_CANCELLED.get(); } } else { writeStatus(controlInfo); } return ReturnCode.SUCCESS.get(); } private void writeStatus(ControlPanelInfo controlInfo) { if (controlInfo.getServerDescriptor() == null) { controlInfo.regenerateDescriptor(); } writeStatus(controlInfo.getServerDescriptor()); int period = argParser.getRefreshPeriod(); boolean first = true; while (period > 0) { long timeToSleep = period * 1000; if (!first) { long t1 = System.currentTimeMillis(); controlInfo.regenerateDescriptor(); long t2 = System.currentTimeMillis(); timeToSleep = timeToSleep - t2 + t1; } if (timeToSleep > 0) { StaticUtils.sleep(timeToSleep); } println(); println(LocalizableMessage.raw(" ---------------------")); println(); writeStatus(controlInfo.getServerDescriptor()); first = false; } } private void writeStatus(ServerDescriptor desc) { LocalizableMessage[] labels = { INFO_SERVER_STATUS_LABEL.get(), INFO_CONNECTIONS_LABEL.get(), INFO_HOSTNAME_LABEL.get(), INFO_ADMINISTRATIVE_USERS_LABEL.get(), INFO_INSTALLATION_PATH_LABEL.get(), INFO_OPENDS_VERSION_LABEL.get(), INFO_JAVA_VERSION_LABEL.get(), INFO_CTRL_PANEL_ADMIN_CONNECTOR_LABEL.get() }; int labelWidth = 0; LocalizableMessage title = INFO_SERVER_STATUS_TITLE.get(); if (!isScriptFriendly()) { for (LocalizableMessage label : labels) { labelWidth = Math.max(labelWidth, label.length()); } println(); println(centerTitle(title)); } writeStatusContents(desc, labelWidth); writeCurrentConnectionContents(desc, labelWidth); if (!isScriptFriendly()) { println(); } title = INFO_SERVER_DETAILS_TITLE.get(); if (!isScriptFriendly()) { println(centerTitle(title)); } writeHostnameContents(desc, labelWidth); writeAdministrativeUserContents(desc, labelWidth); writeInstallPathContents(desc, labelWidth); boolean sameInstallAndInstance = desc.sameInstallAndInstance(); if (!sameInstallAndInstance) { writeInstancePathContents(desc, labelWidth); } writeVersionContents(desc, labelWidth); writeJavaVersionContents(desc, labelWidth); writeAdminConnectorContents(desc, labelWidth); if (!isScriptFriendly()) { println(); } writeListenerContents(desc); if (!isScriptFriendly()) { println(); } writeBaseDNContents(desc); writeErrorContents(desc); if (!isScriptFriendly()) { if (displayMustStartLegend) { println(); println(INFO_NOT_AVAILABLE_SERVER_DOWN_CLI_LEGEND.get()); } else if (displayMustAuthenticateLegend) { println(); println(INFO_NOT_AVAILABLE_AUTHENTICATION_REQUIRED_CLI_LEGEND.get()); } } println(); } /** * Writes the status contents displaying with what is specified in the * provided ServerDescriptor object. * * @param desc * The ServerStatusDescriptor object. */ private void writeStatusContents(ServerDescriptor desc, int maxLabelWidth) { writeLabelValue(INFO_SERVER_STATUS_LABEL.get(), getStatus(desc).toString(), maxLabelWidth); } private LocalizableMessage getStatus(ServerDescriptor desc) { switch (desc.getStatus()) { case STARTED: return INFO_SERVER_STARTED_LABEL.get(); case STOPPED: return INFO_SERVER_STOPPED_LABEL.get(); case STARTING: return INFO_SERVER_STARTING_LABEL.get(); case STOPPING: return INFO_SERVER_STOPPING_LABEL.get(); case NOT_CONNECTED_TO_REMOTE: return INFO_SERVER_NOT_CONNECTED_TO_REMOTE_STATUS_LABEL.get(); case UNKNOWN: return INFO_SERVER_UNKNOWN_STATUS_LABEL.get(); default: throw new IllegalStateException("Unknown status: "+desc.getStatus()); } } /** * Writes the current connection contents displaying with what is specified in * the provided ServerDescriptor object. * * @param desc * The ServerDescriptor object. */ private void writeCurrentConnectionContents(ServerDescriptor desc, int maxLabelWidth) { writeLabelValue(INFO_CONNECTIONS_LABEL.get(), getNbConnection(desc), maxLabelWidth); } private String getNbConnection(ServerDescriptor desc) { if (desc.getStatus() == ServerDescriptor.ServerStatus.STARTED) { final int nConn = desc.getOpenConnections(); if (nConn >= 0) { return String.valueOf(nConn); } else if (!desc.isAuthenticated() || !desc.getExceptions().isEmpty()) { return getNotAvailableBecauseAuthenticationIsRequiredText(); } else { return getNotAvailableText(); } } return getNotAvailableBecauseServerIsDownText(); } /** * Writes the host name contents. * * @param desc * The ServerDescriptor object. * @param maxLabelWidth * The maximum label width of the left label. */ private void writeHostnameContents(ServerDescriptor desc, int maxLabelWidth) { writeLabelValue(INFO_HOSTNAME_LABEL.get(), desc.getHostname(), maxLabelWidth); } /** * Writes the administrative user contents displaying with what is specified * in the provided ServerStatusDescriptor object. * * @param desc * The ServerStatusDescriptor object. * @param maxLabelWidth * The maximum label width of the left label. */ private void writeAdministrativeUserContents(ServerDescriptor desc, int maxLabelWidth) { Set administrators = desc.getAdministrativeUsers(); if (!administrators.isEmpty()) { TreeSet ordered = new TreeSet<>(administrators); for (DN dn : ordered) { writeLabelValue(INFO_ADMINISTRATIVE_USERS_LABEL.get(), dn.toString(), maxLabelWidth); } } else { writeLabelValue(INFO_ADMINISTRATIVE_USERS_LABEL.get(), getErrorText(desc), maxLabelWidth); } } private String getErrorText(ServerDescriptor desc) { if (desc.getStatus() == ServerDescriptor.ServerStatus.STARTED && (!desc.isAuthenticated() || !desc.getExceptions().isEmpty())) { return getNotAvailableBecauseAuthenticationIsRequiredText(); } return getNotAvailableText(); } /** * Writes the install path contents displaying with what is specified in the * provided ServerDescriptor object. * * @param desc * The ServerDescriptor object. * @param maxLabelWidth * The maximum label width of the left label. */ private void writeInstallPathContents(ServerDescriptor desc, int maxLabelWidth) { writeLabelValue(INFO_INSTALLATION_PATH_LABEL.get(), desc.getInstallPath(), maxLabelWidth); } /** * Writes the instance path contents displaying with what is specified in the * provided ServerDescriptor object. * * @param desc * The ServerDescriptor object. * @param maxLabelWidth * The maximum label width of the left label. */ private void writeInstancePathContents(ServerDescriptor desc, int maxLabelWidth) { writeLabelValue(INFO_CTRL_PANEL_INSTANCE_PATH_LABEL.get(), desc.getInstancePath(), maxLabelWidth); } /** * Updates the server version contents displaying with what is specified in * the provided ServerDescriptor object. This method must be called from the * event thread. * * @param desc * The ServerDescriptor object. */ private void writeVersionContents(ServerDescriptor desc, int maxLabelWidth) { writeLabelValue(INFO_OPENDS_VERSION_LABEL.get(), desc.getOpenDSVersion(), maxLabelWidth); } /** * Updates the java version contents displaying with what is specified in the * provided ServerDescriptor object. This method must be called from the event * thread. * * @param desc * The ServerDescriptor object. * @param maxLabelWidth * The maximum label width of the left label. */ private void writeJavaVersionContents(ServerDescriptor desc, int maxLabelWidth) { writeLabelValue(INFO_JAVA_VERSION_LABEL.get(), getJavaVersion(desc), maxLabelWidth); } private String getJavaVersion(ServerDescriptor desc) { if (desc.getStatus() == ServerDescriptor.ServerStatus.STARTED) { if (!desc.isAuthenticated() || !desc.getExceptions().isEmpty()) { return getNotAvailableBecauseAuthenticationIsRequiredText(); } return desc.getJavaVersion(); } return getNotAvailableBecauseServerIsDownText(); } /** * Updates the admin connector contents displaying with what is specified in * the provided ServerDescriptor object. This method must be called from the * event thread. * * @param desc * The ServerDescriptor object. * @param maxLabelWidth * The maximum label width of the left label. */ private void writeAdminConnectorContents(ServerDescriptor desc, int maxLabelWidth) { ConnectionHandlerDescriptor adminConnector = desc.getAdminConnector(); LocalizableMessage text = adminConnector != null ? INFO_CTRL_PANEL_ADMIN_CONNECTOR_DESCRIPTION.get(adminConnector.getPort()) : INFO_NOT_AVAILABLE_SHORT_LABEL.get(); writeLabelValue(INFO_CTRL_PANEL_ADMIN_CONNECTOR_LABEL.get(), text.toString(), maxLabelWidth); } /** * Writes the listeners contents displaying with what is specified in the * provided ServerDescriptor object. * * @param desc * The ServerDescriptor object. */ private void writeListenerContents(ServerDescriptor desc) { if (!isScriptFriendly()) { LocalizableMessage title = INFO_LISTENERS_TITLE.get(); println(centerTitle(title)); } Set allHandlers = desc.getConnectionHandlers(); if (allHandlers.isEmpty()) { if (desc.getStatus() == ServerDescriptor.ServerStatus.STARTED) { if (!desc.isAuthenticated()) { println(INFO_NOT_AVAILABLE_AUTHENTICATION_REQUIRED_CLI_LABEL.get()); } else { println(INFO_NO_LISTENERS_FOUND.get()); } } else { println(INFO_NO_LISTENERS_FOUND.get()); } } else { ConnectionHandlerTableModel connHandlersTableModel = new ConnectionHandlerTableModel(false); connHandlersTableModel.setData(allHandlers); writeConnectionHandlersTableModel(connHandlersTableModel, desc); } } /** * Writes the base DN contents displaying with what is specified in the * provided ServerDescriptor object. * * @param desc * The ServerDescriptor object. */ private void writeBaseDNContents(ServerDescriptor desc) { LocalizableMessage title = INFO_DATABASES_TITLE.get(); if (!isScriptFriendly()) { println(centerTitle(title)); } Set replicas = new HashSet<>(); Set bs = desc.getBackends(); for (BackendDescriptor backend: bs) { if (!backend.isConfigBackend()) { replicas.addAll(backend.getBaseDns()); } } if (replicas.isEmpty()) { if (desc.getStatus() == ServerDescriptor.ServerStatus.STARTED) { if (!desc.isAuthenticated()) { println(INFO_NOT_AVAILABLE_AUTHENTICATION_REQUIRED_CLI_LABEL.get()); } else { println(INFO_NO_DBS_FOUND.get()); } } else { println(INFO_NO_DBS_FOUND.get()); } } else { BaseDNTableModel baseDNTableModel = new BaseDNTableModel(true, false); baseDNTableModel.setData(replicas, desc.getStatus(), desc.isAuthenticated()); writeBaseDNTableModel(baseDNTableModel, desc); } } /** * Writes the error label contents displaying with what is specified in the * provided ServerDescriptor object. * * @param desc * The ServerDescriptor object. */ private void writeErrorContents(ServerDescriptor desc) { for (OpenDsException ex : desc.getExceptions()) { LocalizableMessage errorMsg = ex.getMessageObject(); if (errorMsg != null) { println(); println(errorMsg); } } } /** * Returns the not available text explaining that the data is not available * because the server is down. * * @return the text. */ private String getNotAvailableBecauseServerIsDownText() { displayMustStartLegend = true; return INFO_NOT_AVAILABLE_SERVER_DOWN_CLI_LABEL.get().toString(); } /** * Returns the not available text explaining that the data is not available * because authentication is required. * * @return the text. */ private String getNotAvailableBecauseAuthenticationIsRequiredText() { displayMustAuthenticateLegend = true; return INFO_NOT_AVAILABLE_AUTHENTICATION_REQUIRED_CLI_LABEL.get().toString(); } /** * Returns the not available text explaining that the data is not available. * * @return the text. */ private String getNotAvailableText() { return INFO_NOT_AVAILABLE_LABEL.get().toString(); } /** * Writes the contents of the provided table model simulating a table layout * using text. * * @param tableModel * The connection handler table model. * @param desc * The Server Status descriptor. */ private void writeConnectionHandlersTableModel( ConnectionHandlerTableModel tableModel, ServerDescriptor desc) { if (isScriptFriendly()) { for (int i=0; i"); } private String getCellValue(Object v, ServerDescriptor desc) { if (v != null) { if (v instanceof String) { return (String) v; } else if (v instanceof Integer) { int nEntries = ((Integer)v).intValue(); if (nEntries >= 0) { return String.valueOf(nEntries); } else if (!desc.isAuthenticated() || !desc.getExceptions().isEmpty()) { return getNotAvailableBecauseAuthenticationIsRequiredText(); } else { return getNotAvailableText(); } } else { throw new IllegalStateException("Unknown object type: "+v); } } return getNotAvailableText(); } /** * Writes the contents of the provided base DN 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 writeBaseDNTableModel(BaseDNTableModel tableModel, ServerDescriptor desc) { boolean isRunning = desc.getStatus() == ServerDescriptor.ServerStatus.STARTED; int labelWidth = 0; int labelWidthWithoutReplicated = 0; LocalizableMessage[] labels = new LocalizableMessage[tableModel.getColumnCount()]; for (int i=0; i 0) { println(); } for (int j=0; j= 0) { return String.valueOf(nEntries); } return getNotAvailableText(desc, isRunning); } else { throw new IllegalStateException("Unknown object type: " + v); } } return ""; } private String getNotAvailableText(ServerDescriptor desc, boolean isRunning) { if (!isRunning) { return getNotAvailableBecauseServerIsDownText(); } if (!desc.isAuthenticated() || !desc.getExceptions().isEmpty()) { return getNotAvailableBecauseAuthenticationIsRequiredText(); } return getNotAvailableText(); } private void writeLabelValue(final LocalizableMessage label, final String value, final int maxLabelWidth) { final LocalizableMessageBuilder buf = new LocalizableMessageBuilder(); buf.append(label); int extra = maxLabelWidth - label.length(); for (int i = 0; i