opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/browser/BrowserController.java
@@ -159,7 +159,7 @@ tree.setCellRenderer(new BrowserCellRenderer()); displayFlags = DISPLAY_ACI_COUNT; displayAttribute = RDN_ATTRIBUTE; followReferrals = false; followReferrals = true; sorted = false; showContainerOnly = true; containerClasses = new String[0]; @@ -1436,9 +1436,11 @@ removeOneNode(node); } else { if (oldState == NodeRefresher.State.SOLVING_REFERRAL) { if (oldState == NodeRefresher.State.SOLVING_REFERRAL) { node.setRemoteUrl(task.getRemoteUrl()); if (task.getRemoteEntry() != null) { if (task.getRemoteEntry() != null) { /* This is the case when there are multiple hops in the referral and so we have a remote referral entry but not the entry that it points to */ @@ -1450,6 +1452,7 @@ If this referral entry has children locally (even if this goes against the recommendation of the standards) these children will NOT be displayed. */ node.setLeaf(true); removeAllChildNodes(node, true /* Keep suffixes */); } @@ -1793,7 +1796,7 @@ newIcon = iconPool.getIcon(objectClasses, modifiers); } // Contruct the icon text according the dn, the aci count... // Construct the icon text according the dn, the aci count... StringBuilder sb2 = new StringBuilder(); if (aciCount >= 1) { sb2.append(String.valueOf(aciCount)); opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/browser/IconPool.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2008 Sun Microsystems, Inc. * Copyright 2008-2010 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.browser; @@ -304,7 +304,7 @@ result = getReferralMaskIcon(); } if ((modifiers & MODIFIER_ERROR) != 0) { result = maskedIcon(result, getErrorMaskIcon()); result = getErrorMaskIcon(); } return result; opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/browser/NodeRefresher.java
@@ -22,11 +22,13 @@ * CDDL HEADER END * * * Copyright 2008-2009 Sun Microsystems, Inc. * Copyright 2008-2010 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.browser; import static org.opends.messages.AdminToolMessages.*; import java.util.ArrayList; import java.util.Set; @@ -42,26 +44,29 @@ import javax.swing.SwingUtilities; import javax.swing.tree.TreeNode; import org.opends.admin.ads.ServerDescriptor; import org.opends.admin.ads.util.ConnectionUtils; import org.opends.guitools.controlpanel.ui.nodes.BasicNode; import org.opends.messages.AdminToolMessages; import org.opends.server.types.DN; import org.opends.server.types.DirectoryException; import org.opends.server.types.LDAPURL; import org.opends.server.types.OpenDsException; import org.opends.server.types.RDN; import org.opends.server.types.SearchScope; /** * The class that is in charge of doing the LDAP searches required to update a * node: search the local entry, detect if it has children, retrieve the * attributes required to render the node, etc. */ class NodeRefresher extends AbstractNodeTask { public class NodeRefresher extends AbstractNodeTask { /** * The enumeration containing all the states the refresher can have. * */ enum State public enum State { /** * The refresher is queued, but not started. @@ -464,6 +469,14 @@ InitialLdapContext ctx = null; try { url = LDAPURL.decode(referral[i], false); if (url.getHost() == null) { // Use the local server connection. ctx = controller.getUserDataConnection(); url.setHost(ConnectionUtils.getHostName(ctx)); url.setPort(ConnectionUtils.getPort(ctx)); url.setScheme(ConnectionUtils.isSSL(ctx)?"ldaps":"ldap"); } ctx = connectionPool.getConnection(url); remoteDn = url.getRawBaseDN(); if ((remoteDn == null) || @@ -482,21 +495,39 @@ remoteDn, url.getAttributes(), url.getScope(), url.getRawFilter(), url.getExtensions()); } if (useCustomFilter()) if (useCustomFilter() && url.getScope() == SearchScope.BASE_OBJECT) { // Check that the entry verifies the filter searchForCustomFilter(remoteDn, ctx); } int scope = getJNDIScope(url); String filter = getJNDIFilter(url); SearchControls ctls = controller.getBasicSearchControls(); ctls.setReturningAttributes(controller.getAttrsForBlackSearch()); ctls.setSearchScope(SearchControls.OBJECT_SCOPE); ctls.setSearchScope(scope); ctls.setCountLimit(1); NamingEnumeration<SearchResult> sr = ctx.search(remoteDn, controller.getObjectSearchFilter(), filter, ctls); if (sr.hasMore()) { entry = sr.next(); entry.setName(remoteDn); String name; if (entry.getName().length() == 0) { name = remoteDn; } else { name = unquoteRelativeName(entry.getName())+","+remoteDn; } entry.setName(name); } else { throw new NameNotFoundException(); } throwAbandonIfNeeded(null); } @@ -522,7 +553,17 @@ throw new SearchAbandonException( State.FAILED, lastException, lastExceptionArg); } else { else { if (url.getScope() != SearchScope.BASE_OBJECT) { // The URL is to be transformed: the code assumes that the URL points // to the remote entry. url = new LDAPURL(url.getScheme(), url.getHost(), url.getPort(), entry.getName(), url.getAttributes(), SearchScope.BASE_OBJECT, null, url.getExtensions()); } checkLoopInReferral(url, referral[i-1]); remoteUrl = url; remoteEntry = entry; } @@ -877,7 +918,7 @@ /** * Transform an exception into a TaskAbandonException. * If no exception is passed, the routine checks if the task has * been cancelled and throws an TaskAbandonException accordingly. * been canceled and throws an TaskAbandonException accordingly. * @param x the exception. * @throws SearchAbandonException if the task/refresher must be abandoned. */ @@ -970,4 +1011,110 @@ } return result; } /** * Returns the scope to be used in a JNDI request based on the information * of an LDAP URL. * @param url the LDAP URL. * @return the scope to be used in a JNDI request. */ private int getJNDIScope(LDAPURL url) { int scope; if (url.getScope() != null) { switch (url.getScope()) { case BASE_OBJECT: scope = SearchControls.OBJECT_SCOPE; break; case WHOLE_SUBTREE: scope = SearchControls.SUBTREE_SCOPE; break; case SUBORDINATE_SUBTREE: scope = SearchControls.ONELEVEL_SCOPE; break; case SINGLE_LEVEL: scope = SearchControls.ONELEVEL_SCOPE; break; default: scope = SearchControls.OBJECT_SCOPE; } } else { scope = SearchControls.OBJECT_SCOPE; } return scope; } /** * Returns the filter to be used in a JNDI request based on the information * of an LDAP URL. * @param url the LDAP URL. * @return the filter. */ private String getJNDIFilter(LDAPURL url) { String filter = url.getRawFilter(); if (filter == null) { filter = controller.getObjectSearchFilter(); } return filter; } /** * Check that there is no loop in terms of DIT (the check basically identifies * whether we are pointing to an entry above in the same server). * @param url the URL to the remote entry. It is assumed that the base DN * of the URL points to the remote entry. * @param referral the referral used to retrieve the remote entry. * @throws SearchAbandonException if there is a loop issue (the remoteEntry * is actually an entry in the same server as the local entry but above in the * DIT). */ private void checkLoopInReferral(LDAPURL url, String referral) throws SearchAbandonException { boolean checkSucceeded = true; try { DN dn1 = DN.decode(getNode().getDN()); DN dn2 = url.getBaseDN(); if (dn2.isAncestorOf(dn1)) { String host = url.getHost(); int port = url.getPort(); String adminHost = ConnectionUtils.getHostName( controller.getConfigurationConnection()); int adminPort = ConnectionUtils.getPort(controller.getConfigurationConnection()); checkSucceeded = (port != adminPort) || !adminHost.equalsIgnoreCase(host); if (checkSucceeded) { String hostUserData = ConnectionUtils.getHostName( controller.getUserDataConnection()); int portUserData = ConnectionUtils.getPort(controller.getUserDataConnection()); checkSucceeded = (port != portUserData) || !hostUserData.equalsIgnoreCase(host); } } } catch (OpenDsException odse) { // Ignore } if (!checkSucceeded) { String hostPort = ServerDescriptor.getServerRepresentation(url.getHost(), url.getPort()); throw new SearchAbandonException( State.FAILED, new ReferralLimitExceededException( ERR_CTRL_PANEL_REFERRAL_LOOP.get(url.getRawBaseDN())), referral); } } } opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/browser/ReferralLimitExceededException.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2008 Sun Microsystems, Inc. * Copyright 2008-2010 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.browser; @@ -36,7 +36,7 @@ * following referrals. * */ class ReferralLimitExceededException extends NamingException public class ReferralLimitExceededException extends NamingException { private static final long serialVersionUID = -5640515839144837865L; opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2008-2009 Sun Microsystems, Inc. * Copyright 2008-2010 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.ui; @@ -72,6 +72,7 @@ import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreePath; import org.opends.guitools.controlpanel.browser.NodeRefresher; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; @@ -544,7 +545,19 @@ if (node != null) { String dn; if (controller.getFollowReferrals() && node.getRemoteUrl() != null) if (controller.getFollowReferrals() && node.getReferral() != null && node.getRemoteUrl() == null && node.getError() != null && node.getError().getState() == NodeRefresher.State.SOLVING_REFERRAL) { // We are in the case where we are following referrals but the referral // could not be resolved. Display an error. entryPane.referralSolveError(node.getDN(), node.getReferral(), node.getError()); dn = null; } else if (controller.getFollowReferrals() && node.getRemoteUrl() != null) { dn = node.getRemoteUrl().getRawBaseDN(); } @@ -553,6 +566,8 @@ dn = node.getDN(); } if (dn != null) { try { InitialLdapContext ctx = @@ -574,6 +589,7 @@ } } } } else { stopCurrentReader(); opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ErrorSearchingEntryPanel.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2008 Sun Microsystems, Inc. * Copyright 2008-2010 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.ui; @@ -31,9 +31,18 @@ import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.Insets; import javax.naming.NameNotFoundException; import javax.naming.NamingException; import org.opends.guitools.controlpanel.browser.BasicNodeError; import org.opends.guitools.controlpanel.browser.ReferralLimitExceededException; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.messages.Message; import org.opends.messages.MessageBuilder; import org.opends.quicksetup.util.Utils; import org.opends.server.types.LDAPURL; import org.opends.server.types.OpenDsException; /** @@ -52,7 +61,16 @@ { super(); GridBagConstraints gbc = new GridBagConstraints(); addErrorPane(gbc); gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 1; gbc.gridheight = 1; gbc.weightx = 1.0; gbc.anchor = GridBagConstraints.CENTER; gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(20, 20, 0, 20); createErrorPane(); add(errorPane, gbc); errorPane.setVisible(true); } @@ -109,4 +127,113 @@ updateErrorPane(errorPane, title, ColorAndFontConstants.errorTitleFont, details, ColorAndFontConstants.defaultFont); } /** * Sets the error to be displayed in the panel. * @param dn the DN of the local entry. * @param referrals the list of referrals defined in the entry. * @param error the error that occurred resolving the referral. */ public void setReferralError(String dn, String[] referrals, BasicNodeError error) { Message title = INFO_CTRL_PANEL_ERROR_RESOLVING_REFERRAL_TITLE.get(); MessageBuilder details = new MessageBuilder(); StringBuilder sb = new StringBuilder(); for (String ref: referrals) { if (sb.length() > 0) { sb.append("<br>"); } sb.append(" "+ref); } details.append(INFO_CTRL_PANEL_ERROR_RESOLVING_REFERRAL_MSG.get(dn, sb)); Exception ex = error.getException(); if (ex instanceof NamingException) { Object arg = error.getArg(); Message msg = null; if (arg != null) { // Maybe is the LDAPURL try { LDAPURL url = LDAPURL.decode(arg.toString(), false); if (url.getHost() != null) { String hostPort = url.getHost()+":"+url.getPort(); if (ex instanceof ReferralLimitExceededException) { msg = Message.raw(ex.getLocalizedMessage()); } else if (ex instanceof NameNotFoundException) { msg = ERR_CTRL_PANEL_COULD_NOT_FIND_PROVIDED_ENTRY_IN_REFERRAL.get( arg.toString(), hostPort); } else { msg = Utils.getMessageForException((NamingException)ex, hostPort); } } else { if (ex instanceof ReferralLimitExceededException) { msg = Message.raw(ex.getLocalizedMessage()); } else if (ex instanceof NameNotFoundException) { msg = ERR_CTRL_PANEL_COULD_NOT_FIND_PROVIDED_ENTRY_IN_REFERRAL_NO_HOST.get( arg.toString()); } else { msg = Utils.getMessageForException((NamingException)ex); } } } catch (Throwable t) { } } if (msg == null) { if (ex instanceof ReferralLimitExceededException) { msg = Message.raw(ex.getLocalizedMessage()); } else { msg = Utils.getMessageForException((NamingException)ex); } } if (arg != null) { details.append("<br><br>"+ ERR_CTRL_PANEL_RESOLVING_REFERRAL_DETAILS.get(arg.toString(), msg)); } else { details.append("<br><br>"+INFO_CTRL_PANEL_DETAILS_THROWABLE.get(msg)); } } else if (ex != null) { String msg = ex.getLocalizedMessage(); if (msg == null) { msg = ex.toString(); } details.append("<br><br>"+INFO_CTRL_PANEL_DETAILS_THROWABLE.get(msg)); } details.append("<br><br>"+INFO_CTRL_PANEL_HOW_TO_EDIT_REFERRALS.get()); updateErrorPane(errorPane, title, ColorAndFontConstants.errorTitleFont, details.toMessage(), ColorAndFontConstants.defaultFont); } } opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/LDAPEntryPanel.java
@@ -45,6 +45,7 @@ import javax.swing.border.EmptyBorder; import javax.swing.tree.TreePath; import org.opends.guitools.controlpanel.browser.BasicNodeError; import org.opends.guitools.controlpanel.browser.BrowserController; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; @@ -347,6 +348,27 @@ } /** * Displays a message informing that an error occurred resolving a referral. * @param dn the DN of the local entry. * @param referrals the list of referrals defined in the entry. * @param error the error that occurred resolving the referral. */ public void referralSolveError(String dn, String[] referrals, BasicNodeError error) { searchResult = null; errorSearchingPanel.setReferralError(dn, referrals, error); delete.setVisible(false); saveChanges.setVisible(false); cardLayout.show(mainPanel, ERROR_SEARCHING); displayedEntryPanel = null; } /** * Displays a panel informing that nothing is selected. * */ opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java
@@ -1154,7 +1154,7 @@ protected void displayMessage(Message msg) { message.setText(Utilities.applyFont(msg.toString(), ColorAndFontConstants.progressFont)); ColorAndFontConstants.defaultFont)); cardLayout.show(cardPanel, MESSAGE_PANEL); } opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/nodes/BasicNode.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2008 Sun Microsystems, Inc. * Copyright 2008-2010 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.ui.nodes; @@ -120,9 +120,17 @@ */ public void setRemoteUrl(LDAPURL url) { remoteUrl = url; if (remoteUrl != null) { remoteRdn = extractRDN(remoteUrl.getRawBaseDN()); remoteRdnWithAttributeName = extractRDN(remoteUrl.getRawBaseDN(), true); } else { remoteRdn = null; remoteRdnWithAttributeName = null; } } /** * Sets the remote URL of the node. opendj-sdk/opends/src/messages/messages/admin_tool.properties
@@ -1748,6 +1748,22 @@ INFO_CTRL_PANEL_CONFIRMATION_DELETE_BASE_DNS_DETAILS=The following base DN's \ will be deleted. All the entries defined on the base DN's will be deleted. INFO_CTRL_PANEL_ERROR_SEARCHING_ENTRY_TITLE=Error searching entry INFO_CTRL_PANEL_ERROR_RESOLVING_REFERRAL_TITLE=Error resolving referral INFO_CTRL_PANEL_ERROR_RESOLVING_REFERRAL_MSG=Could not resolve the referrals \ defined in entry '%s'.<br><br>The referrals of the entry are:<br>%s MILD_ERR_CTRL_PANEL_RESOLVING_REFERRAL_DETAILS=The error occurred solving \ referral '%s'.<br>Details: %s MILD_ERR_CTRL_PANEL_COULD_NOT_FIND_PROVIDED_ENTRY_IN_REFERRAL=Could not find \ entry specified in '%s'. Check that the entry exists in server %s. MILD_ERR_CTRL_PANEL_COULD_NOT_FIND_PROVIDED_ENTRY_IN_REFERRAL_NO_HOST=Could \ not find entry specified in '%s'. Check that the entry exists in server. INFO_CTRL_PANEL_HOW_TO_EDIT_REFERRALS=To edit the referral in the entry, \ deselect the 'Follow Referrals' option in the 'View' menu. MILD_ERR_CTRL_PANEL_REFERRAL_LOOP=The selected referral is defined in server \ %s and is referencing to an entry in the same server that is an ascentor of \ the entry. This configuration generates a loop in the DIT structure that \ should be avoided. # # Note that the following property contains line breaks in HTML format (<br>) #