/* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2008 Sun Microsystems, Inc. * Portions Copyright 2013-2016 ForgeRock AS. */ package org.opends.guitools.controlpanel.datamodel; import static org.opends.messages.AdminToolMessages.*; import java.util.ArrayList; import java.util.Comparator; import java.util.Date; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; import org.opends.guitools.controlpanel.util.Utilities; import org.forgerock.i18n.LocalizableMessage; /** The table model used to display all the base DNs. */ public class BaseDNTableModel extends SortableTableModel implements Comparator { private static final long serialVersionUID = -5650762484071136983L; private HashSet data = new HashSet<>(); private ServerDescriptor.ServerStatus serverStatus; private boolean isAuthenticated; private ArrayList dataArray = new ArrayList<>(); private String[] COLUMN_NAMES; private int sortColumn; private boolean sortAscending = true; private boolean displayReplicationInformation; /** Key value to identify the case of a value not available because the server is down. */ public static String NOT_AVAILABLE_SERVER_DOWN = "NOT_AVAILABLE_SERVER_DOWN"; /** Key value to identify the case of a value not available because authentication is required. */ public static String NOT_AVAILABLE_AUTHENTICATION_REQUIRED = "NOT_AVAILABLE_AUTHENTICATION_REQUIRED"; /** Key value to identify the case of a value not available. */ public static String NOT_AVAILABLE = "NOT_AVAILABLE"; /** * Constructor for this table model. * @param displayReplicationInformation whether to display replication. * monitoring information or not. */ public BaseDNTableModel(boolean displayReplicationInformation) { this(displayReplicationInformation, true); } /** * Constructor for this table model. * @param displayReplicationInformation whether to display replication. * @param wrapHeader whether to wrap the headers or not. * monitoring information or not. */ public BaseDNTableModel(boolean displayReplicationInformation, boolean wrapHeader) { this.displayReplicationInformation = displayReplicationInformation; if (wrapHeader) { COLUMN_NAMES = new String[] { getHeader(INFO_BASEDN_COLUMN.get()), getHeader(INFO_BACKENDID_COLUMN.get()), getHeader(INFO_NUMBER_ENTRIES_COLUMN.get()), getHeader(INFO_REPLICATED_COLUMN.get()), getHeader(INFO_MISSING_CHANGES_COLUMN.get()), getHeader(INFO_AGE_OF_OLDEST_MISSING_CHANGE_COLUMN.get()) }; } else { COLUMN_NAMES = new String[] { INFO_BASEDN_COLUMN.get().toString(), INFO_BACKENDID_COLUMN.get().toString(), INFO_NUMBER_ENTRIES_COLUMN.get().toString(), INFO_REPLICATED_COLUMN.get().toString(), INFO_MISSING_CHANGES_COLUMN.get().toString(), INFO_AGE_OF_OLDEST_MISSING_CHANGE_COLUMN.get().toString() }; } } /** * Sets the data for this table model. * @param newData the data for this table model. * @param status the server status. * @param isAuthenticated whether the user provided authentication or not. */ public void setData(Set newData, ServerDescriptor.ServerStatus status, boolean isAuthenticated) { if (!newData.equals(data) || serverStatus != status || this.isAuthenticated != isAuthenticated) { serverStatus = status; this.isAuthenticated = isAuthenticated; data.clear(); data.addAll(newData); updateDataArray(); fireTableDataChanged(); } } /** * Updates the table model contents and sorts its contents depending on the * sort options set by the user. */ @Override public void forceResort() { updateDataArray(); fireTableDataChanged(); } /** * Comparable implementation. * @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 * base DN 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. */ @Override public int compare(BaseDNDescriptor desc1, BaseDNDescriptor desc2) { int result = 0; if (sortColumn == 0) { result = compareDns(desc1, desc2); if (result == 0) { result = compareBackendIDs(desc1, desc2); } if (result == 0) { result = compareEntries(desc1, desc2); } if (result == 0) { result = compareRepl(desc1, desc2); } if (result == 0) { result = compareMissingChanges(desc1, desc2); } if (result == 0) { 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 = compareRepl(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 = compareRepl(desc1, desc2); } if (result == 0) { result = compareMissingChanges(desc1, desc2); } if (result == 0) { result = compareAgeOfOldestMissingChange(desc1, desc2); } } else if (sortColumn == 3) { result = compareRepl(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 = compareRepl(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 = compareRepl(desc1, desc2); } if (result == 0) { result = compareMissingChanges(desc1, desc2); } } if (!sortAscending) { result = -result; } return result; } @Override public int getColumnCount() { return displayReplicationInformation ? 6 : 4; } @Override public int getRowCount() { return dataArray.size(); } @Override public Object getValueAt(int row, int col) { return dataArray.get(row)[col]; } /** Updates the array data. This includes resorting it. */ private void updateDataArray() { TreeSet sortedSet = new TreeSet<>(this); sortedSet.addAll(data); dataArray.clear(); for (BaseDNDescriptor desc : sortedSet) { dataArray.add(new String[] { Utilities.unescapeUtf8(desc.getDn().toString()), desc.getBackend().getBackendID(), getValueForEntries(desc), getStringForReplState(desc), getValueForMissingChanges(desc), getValueForOldestMissingChange(desc) }); } } @Override public String getColumnName(int col) { return COLUMN_NAMES[col]; } @Override public boolean isSortAscending() { return sortAscending; } @Override public void setSortAscending(boolean sortAscending) { this.sortAscending = sortAscending; } @Override public int getSortColumn() { return sortColumn; } @Override public void setSortColumn(int sortColumn) { this.sortColumn = sortColumn; } /** Several comparison methods to be able to sort the table model. */ private int compareBackendIDs(BaseDNDescriptor desc1, BaseDNDescriptor desc2) { return desc1.getBackend().getBackendID().compareTo( desc2.getBackend().getBackendID()); } private int compareEntries(BaseDNDescriptor desc1, BaseDNDescriptor desc2) { int n1 = desc1.getEntries(); int n2 = desc2.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 compareLongs(long n1, long n2) { if (n1 == n2) { return 0; } if (n1 > n2) { return 1; } return -1; } private int compareDns(BaseDNDescriptor desc1, BaseDNDescriptor desc2) { return Utilities.unescapeUtf8(desc1.getDn().toString()).compareTo( Utilities.unescapeUtf8(desc2.getDn().toString())); } private int compareRepl(BaseDNDescriptor desc1, BaseDNDescriptor desc2) { String val1 = String.valueOf(desc1.getType()); String val2 = String.valueOf(desc2.getType()); return val1.compareTo(val2); } private int compareMissingChanges(BaseDNDescriptor desc1, BaseDNDescriptor desc2) { return compareIntegers(desc1.getMissingChanges(), desc2.getMissingChanges()); } private int compareAgeOfOldestMissingChange(BaseDNDescriptor desc1, BaseDNDescriptor desc2) { return compareLongs(desc1.getAgeOfOldestMissingChange(), desc2.getAgeOfOldestMissingChange()); } /** * Returns the Object describing the number of entries of a given Base DN. * The Object will be an Integer. * @param rep the Base DN object to handle. * @return the Object describing the number of entries of a given Base DN. */ private String getValueForEntries(BaseDNDescriptor rep) { String returnValue; if (serverStatus != ServerDescriptor.ServerStatus.STARTED) { returnValue = NOT_AVAILABLE_SERVER_DOWN; } else if (!isAuthenticated) { returnValue = NOT_AVAILABLE_AUTHENTICATION_REQUIRED; } else { if (rep.getEntries() < 0) { returnValue = NOT_AVAILABLE; } else { returnValue = String.valueOf(rep.getEntries()); } } return returnValue; } /** * 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 * replicated 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 String getValueForMissingChanges(BaseDNDescriptor rep) { String returnValue; if (rep.getType() == BaseDNDescriptor.Type.REPLICATED) { if (serverStatus != ServerDescriptor.ServerStatus.STARTED) { returnValue = NOT_AVAILABLE_SERVER_DOWN; } else if (!isAuthenticated) { returnValue = NOT_AVAILABLE_AUTHENTICATION_REQUIRED; } else { if (rep.getMissingChanges() < 0) { returnValue = NOT_AVAILABLE; } else { returnValue = String.valueOf(rep.getMissingChanges()); } } } else { returnValue = INFO_NOT_APPLICABLE_LABEL.get().toString(); } return returnValue; } /** * 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 * replicated 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 String getValueForOldestMissingChange(BaseDNDescriptor rep) { String returnValue; if (rep.getType() == BaseDNDescriptor.Type.REPLICATED) { if (serverStatus != ServerDescriptor.ServerStatus.STARTED) { returnValue = NOT_AVAILABLE_SERVER_DOWN; } else if (!isAuthenticated) { returnValue = NOT_AVAILABLE_AUTHENTICATION_REQUIRED; } else { long age = rep.getAgeOfOldestMissingChange(); if (age > 0) { Date date = new Date(age); returnValue = date.toString(); } else { // Not available returnValue = NOT_AVAILABLE; } } } else { returnValue = INFO_NOT_APPLICABLE_LABEL.get().toString(); } return returnValue; } /** * Returns the localized String describing the replication state of * a given Base DN. * @param rep the Base DN object to handle. * @return the localized String describing the replication state of * a given Base DN. */ private String getStringForReplState(BaseDNDescriptor rep) { LocalizableMessage s; if (rep.getType() == BaseDNDescriptor.Type.REPLICATED) { s = INFO_BASEDN_REPLICATED_LABEL.get(); } else if (rep.getType() == BaseDNDescriptor.Type.NOT_REPLICATED) { s = INFO_BASEDN_NOT_REPLICATED_LABEL.get(); } else { s = INFO_BASEDN_DISABLED_LABEL.get(); } return s.toString(); } }