/* * 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 2008-2010 Sun Microsystems, Inc. * Portions Copyright 2015 ForgeRock AS. */ package org.opends.guitools.controlpanel.util; import java.util.HashSet; import java.util.Set; import javax.naming.NamingEnumeration; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.naming.ldap.InitialLdapContext; import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; import org.opends.guitools.controlpanel.event.EntryReadErrorEvent; import org.opends.guitools.controlpanel.event.EntryReadEvent; import org.opends.guitools.controlpanel.event.EntryReadListener; /** * A class that reads an entry on the background. This is used in the LDAP * entries browser. When the entry is read it notifies to the EntryReadListener * objects that have been registered. * */ public class LDAPEntryReader extends BackgroundTask<CustomSearchResult> { private final String dn; private final InitialLdapContext ctx; private final Set<EntryReadListener> listeners = new HashSet<>(); private boolean isOver; private boolean notifyListeners; /** * Constructor of the entry reader. * @param dn the DN of the entry. * @param ctx the connection to the server. */ public LDAPEntryReader(String dn, InitialLdapContext ctx) { this.dn = dn; this.ctx = ctx; this.notifyListeners = true; } /** {@inheritDoc} */ @Override public CustomSearchResult processBackgroundTask() throws Throwable { isOver = false; NamingEnumeration<SearchResult> en = null; try { SearchControls controls = new SearchControls(); String[] attrs = {"*", "+"}; controls.setReturningAttributes(attrs); controls.setSearchScope(SearchControls.OBJECT_SCOPE); final String filter = "(|(objectclass=*)(objectclass=ldapsubentry))"; en = ctx.search(Utilities.getJNDIName(dn), filter, controls); SearchResult sr = null; while (en.hasMore()) { sr = en.next(); } return new CustomSearchResult(sr, dn); } finally { if (isInterrupted()) { isOver = true; } if (en != null) { en.close(); } } } /** {@inheritDoc} */ @Override public void backgroundTaskCompleted(CustomSearchResult sr, Throwable throwable) { if (!isInterrupted() && isNotifyListeners()) { if (throwable == null) { notifyListeners(sr); } else { notifyListeners(throwable); } } isOver = true; } /** * Returns whether this entry reader will notify the listeners once it is * over. * @return whether this entry reader will notify the listeners once it is * over. */ public boolean isNotifyListeners() { return notifyListeners; } /** * Sets whether this entry reader will notify the listeners once it is * over. * @param notifyListeners whether this entry reader will notify the listeners * once it is over. */ public void setNotifyListeners(boolean notifyListeners) { this.notifyListeners = notifyListeners; } /** * Returns <CODE>true</CODE> if the read process is over and * <CODE>false</CODE> otherwise. * @return <CODE>true</CODE> if the read process is over and * <CODE>false</CODE> otherwise. */ public boolean isOver() { return isOver; } /** * Notifies listeners that a new entry was read. * @param sr the new entry in form of CustomSearchResult. */ private void notifyListeners(CustomSearchResult sr) { EntryReadEvent ev = new EntryReadEvent(this, sr); for (EntryReadListener listener : listeners) { listener.entryRead(ev); } } /** * Notifies the listeners that an error occurred reading an entry. * @param t the error that occurred reading an entry. */ private void notifyListeners(Throwable t) { EntryReadErrorEvent ev = new EntryReadErrorEvent(this, dn, t); for (EntryReadListener listener : listeners) { listener.entryReadError(ev); } } /** * Adds an EntryReadListener. * @param listener the listener. */ public void addEntryReadListener(EntryReadListener listener) { listeners.add(listener); } /** * Removes an EntryReadListener. * @param listener the listener. */ public void removeEntryReadListener(EntryReadListener listener) { listeners.remove(listener); } }