mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

jvergara
13.19.2010 9b4ec2d522a8feda97e582a5fab9c9a12214d35d
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(),
              ctls);
            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);
    }
  }
}