001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2009-2010 Sun Microsystems, Inc.
025 *      Portions Copyright 2015 ForgeRock AS.
026 */
027package org.opends.guitools.controlpanel.ui;
028
029import static org.opends.messages.AdminToolMessages.*;
030
031import java.awt.Component;
032import java.awt.GridBagConstraints;
033import java.awt.event.ActionEvent;
034import java.awt.event.ActionListener;
035import java.util.HashSet;
036import java.util.LinkedHashSet;
037import java.util.Set;
038import java.util.SortedSet;
039import java.util.TreeSet;
040
041import javax.swing.Box;
042import javax.swing.JButton;
043import javax.swing.JLabel;
044import javax.swing.JScrollPane;
045import javax.swing.JTable;
046import javax.swing.SwingConstants;
047import javax.swing.table.DefaultTableCellRenderer;
048
049import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
050import org.opends.guitools.controlpanel.datamodel.BackendDescriptor.PluggableType;
051import org.opends.guitools.controlpanel.datamodel.DatabaseMonitoringTableModel;
052import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
053import org.opends.guitools.controlpanel.util.Utilities;
054import org.opends.server.util.ServerConstants;
055
056/** The panel displaying the database monitoring filtered attributes. */
057public class DatabaseMonitoringPanel extends GeneralMonitoringPanel
058{
059  private static final long serialVersionUID = 9031734563723229830L;
060
061  private JTable table;
062  private DatabaseMonitoringTableModel tableModel;
063  private JScrollPane scroll;
064  private JLabel noDBsFound;
065  private JLabel noMonitoringFound;
066  private JButton showFields;
067  private LinkedHashSet<String> attributes = new LinkedHashSet<>();
068  private LinkedHashSet<String> allAttributes = new LinkedHashSet<>();
069
070  private MonitoringAttributesViewPanel<String> fieldsViewPanel;
071  private GenericDialog fieldsViewDlg;
072  private final BackendDescriptor.PluggableType pluggableType;
073
074  /**
075   * Default constructor.
076   * @param type the type of pluggable backend.
077   */
078  public DatabaseMonitoringPanel(BackendDescriptor.PluggableType type)
079  {
080    pluggableType = type;
081    createLayout();
082  }
083
084  @Override
085  public Component getPreferredFocusComponent()
086  {
087    return table;
088  }
089
090  /** Creates the layout of the panel (but the contents are not populated here). */
091  private void createLayout()
092  {
093    GridBagConstraints gbc = new GridBagConstraints();
094    final JLabel lTitle = Utilities.createTitleLabel(
095        PluggableType.JE == pluggableType ? INFO_CTRL_PANEL_JE_DB_INFO.get() : INFO_CTRL_PANEL_PDB_DB_INFO.get());
096    gbc.fill = GridBagConstraints.NONE;
097    gbc.anchor = GridBagConstraints.WEST;
098    gbc.gridwidth = 2;
099    gbc.gridx = 0;
100    gbc.gridy = 0;
101    gbc.insets.top = 5;
102    gbc.insets.bottom = 7;
103    add(lTitle, gbc);
104
105    gbc.insets.bottom = 0;
106    gbc.insets.top = 10;
107    gbc.gridy ++;
108    gbc.anchor = GridBagConstraints.WEST;
109    gbc.gridwidth = 1;
110    showFields = Utilities.createButton(INFO_CTRL_PANEL_OPERATIONS_VIEW.get());
111    showFields.addActionListener(new ActionListener()
112    {
113      @Override
114      public void actionPerformed(ActionEvent ev)
115      {
116        fieldsViewClicked();
117      }
118    });
119    showFields.setVisible(false);
120    gbc.gridx = 0;
121    gbc.weightx = 1.0;
122    gbc.fill = GridBagConstraints.HORIZONTAL;
123    add(Box.createHorizontalGlue(), gbc);
124    gbc.gridx ++;
125    gbc.weightx = 0.0;
126    add(showFields, gbc);
127
128    gbc.gridx = 0;
129    gbc.gridy ++;
130    gbc.gridwidth = 2;
131    tableModel = new DatabaseMonitoringTableModel();
132    tableModel.setAttributes(attributes);
133    table = Utilities.createSortableTable(tableModel, new DefaultTableCellRenderer());
134    scroll = Utilities.createScrollPane(table);
135    updateTableSize();
136    gbc.fill = GridBagConstraints.BOTH;
137    gbc.weightx = 1.0;
138    gbc.weighty = 1.0;
139    add(scroll, gbc);
140    noDBsFound = Utilities.createDefaultLabel(INFO_CTRL_PANEL_NO_DBS_FOUND.get());
141    noDBsFound.setHorizontalAlignment(SwingConstants.CENTER);
142    add(noDBsFound, gbc);
143    noMonitoringFound = Utilities.createDefaultLabel(INFO_CTRL_PANEL_NO_DB_MONITORING_FOUND.get());
144    noMonitoringFound.setHorizontalAlignment(SwingConstants.CENTER);
145    add(noMonitoringFound, gbc);
146
147    setBorder(PANEL_BORDER);
148  }
149
150  /** Updates the contents of the panel.  The code assumes that this is being called from the event thread. */
151  public void updateContents()
152  {
153    boolean backendsFound = false;
154    ServerDescriptor server = null;
155    if (getInfo() != null)
156    {
157      server = getInfo().getServerDescriptor();
158    }
159    Set<BackendDescriptor> dbBackends = new HashSet<>();
160    boolean updateAttributes = allAttributes.isEmpty();
161    SortedSet<String> sortedAttrNames = new TreeSet<>();
162    if (server != null)
163    {
164      for (BackendDescriptor backend : server.getBackends())
165      {
166        if (BackendDescriptor.Type.PLUGGABLE == backend.getType()
167            && pluggableType == backend.getPluggableType())
168        {
169          dbBackends.add(backend);
170          if (updateAttributes)
171          {
172            sortedAttrNames.addAll(getMonitoringAttributes(backend));
173          }
174        }
175      }
176      backendsFound = !dbBackends.isEmpty();
177    }
178    if (updateAttributes)
179    {
180      allAttributes.addAll(sortedAttrNames);
181      for (String attrName : allAttributes)
182      {
183        attributes.add(attrName);
184        if (attributes.size() == 5)
185        {
186          break;
187        }
188      }
189      if (!attributes.isEmpty())
190      {
191        setFieldsToDisplay(attributes);
192        updateTableSize();
193      }
194    }
195    tableModel.setData(dbBackends);
196    showFields.setVisible(backendsFound);
197    scroll.setVisible(backendsFound && !allAttributes.isEmpty());
198    noDBsFound.setVisible(!backendsFound);
199    noMonitoringFound.setVisible(backendsFound && allAttributes.isEmpty());
200    showFields.setVisible(!allAttributes.isEmpty());
201  }
202
203
204  private void updateTableSize()
205  {
206    Utilities.updateTableSizes(table, 8);
207    Utilities.updateScrollMode(scroll, table);
208  }
209
210  /** Displays a dialog allowing the user to select which fields to display. */
211  private void fieldsViewClicked()
212  {
213    if (fieldsViewDlg == null)
214    {
215      fieldsViewPanel = MonitoringAttributesViewPanel.createStringInstance(allAttributes);
216      fieldsViewDlg = new GenericDialog(Utilities.getFrame(this), fieldsViewPanel);
217      fieldsViewDlg.setModal(true);
218      Utilities.centerGoldenMean(fieldsViewDlg, Utilities.getParentDialog(this));
219    }
220    fieldsViewPanel.setSelectedAttributes(attributes);
221    fieldsViewDlg.setVisible(true);
222    if (!fieldsViewPanel.isCanceled())
223    {
224      attributes = fieldsViewPanel.getAttributes();
225      setFieldsToDisplay(attributes);
226      updateTableSize();
227    }
228  }
229
230  private void setFieldsToDisplay(LinkedHashSet<String> attributes)
231  {
232    this.attributes = attributes;
233    tableModel.setAttributes(attributes);
234    tableModel.forceDataStructureChange();
235  }
236
237  private Set<String> getMonitoringAttributes(BackendDescriptor backend)
238  {
239    Set<String> attrNames = new HashSet<>();
240    if (backend.getMonitoringEntry() != null)
241    {
242      Set<String> allNames = backend.getMonitoringEntry().getAttributeNames();
243      for (String attrName : allNames)
244      {
245        if (!attrName.equalsIgnoreCase(ServerConstants.OBJECTCLASS_ATTRIBUTE_TYPE_NAME)
246            && !attrName.equalsIgnoreCase(ServerConstants.ATTR_COMMON_NAME))
247        {
248          attrNames.add(attrName);
249        }
250      }
251    }
252    return attrNames;
253  }
254}